Merge analyzer branch into master
Some work on the Dart analyzer was done on a branch, to avoid disrupting
others, and is landed with this commit. It is a merge, in order to
preserve the history of work on that branch.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7ea8989..c3a62fd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,14 @@
+##
+
+### Tool Changes
+
+#### Analyzer
+
+* Support for `declarations-casts` has been removed and the `implicit-casts`
+ option now has the combined semantics of both options. This means that users
+ that disable `implicit-casts` might now see errors that were not previously
+ being reported.
+
## 2.2.0-dev.XX.0
(Add new changes here, and they will be copied to the change section for the
next dev version)
diff --git a/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart b/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
index e1e4b90..200607c 100644
--- a/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/lsp_protocol/protocol_generated.dart
@@ -6,9 +6,18 @@
// To regenerate the file, use the script
// "pkg/analysis_server/tool/lsp_spec/generate_all.dart".
+// ignore_for_file: deprecated_member_use
+// ignore_for_file: unnecessary_brace_in_string_interps
+
import 'dart:core' hide deprecated;
import 'dart:core' as core show deprecated;
+import 'dart:convert' show JsonEncoder;
import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/protocol/protocol_internal.dart'
+ show listEqual, mapEqual;
+import 'package:analyzer/src/generated/utilities_general.dart';
+
+const jsonEncoder = const JsonEncoder.withIndent(' ');
class ApplyWorkspaceEditParams implements ToJsonable {
ApplyWorkspaceEditParams(this.label, this.edit) {
@@ -16,10 +25,10 @@
throw 'edit is required but was not provided';
}
}
- factory ApplyWorkspaceEditParams.fromJson(Map<String, dynamic> json) {
+ static ApplyWorkspaceEditParams fromJson(Map<String, dynamic> json) {
final label = json['label'];
final edit =
- json['edit'] != null ? new WorkspaceEdit.fromJson(json['edit']) : null;
+ json['edit'] != null ? WorkspaceEdit.fromJson(json['edit']) : null;
return new ApplyWorkspaceEditParams(label, edit);
}
@@ -44,6 +53,25 @@
obj.containsKey('edit') &&
WorkspaceEdit.canParse(obj['edit']);
}
+
+ @override
+ bool operator ==(other) {
+ if (other is ApplyWorkspaceEditParams) {
+ return label == other.label && edit == other.edit && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, label.hashCode);
+ hash = JenkinsSmiHash.combine(hash, edit.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class ApplyWorkspaceEditResponse implements ToJsonable {
@@ -52,7 +80,7 @@
throw 'applied is required but was not provided';
}
}
- factory ApplyWorkspaceEditResponse.fromJson(Map<String, dynamic> json) {
+ static ApplyWorkspaceEditResponse fromJson(Map<String, dynamic> json) {
final applied = json['applied'];
return new ApplyWorkspaceEditResponse(applied);
}
@@ -72,6 +100,24 @@
obj.containsKey('applied') &&
obj['applied'] is bool;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is ApplyWorkspaceEditResponse) {
+ return applied == other.applied && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, applied.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class CancelParams implements ToJsonable {
@@ -80,12 +126,12 @@
throw 'id is required but was not provided';
}
}
- factory CancelParams.fromJson(Map<String, dynamic> json) {
+ static CancelParams fromJson(Map<String, dynamic> json) {
final id = json['id'] is num
? new Either2<num, String>.t1(json['id'])
: (json['id'] is String
? new Either2<num, String>.t2(json['id'])
- : (throw '''${json['id']} was not one of (number, string)'''));
+ : (throw '''${json['id']} was not one of (num, String)'''));
return new CancelParams(id);
}
@@ -103,16 +149,34 @@
obj.containsKey('id') &&
(obj['id'] is num || obj['id'] is String);
}
+
+ @override
+ bool operator ==(other) {
+ if (other is CancelParams) {
+ return id == other.id && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, id.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class ClientCapabilities implements ToJsonable {
ClientCapabilities(this.workspace, this.textDocument, this.experimental);
- factory ClientCapabilities.fromJson(Map<String, dynamic> json) {
+ static ClientCapabilities fromJson(Map<String, dynamic> json) {
final workspace = json['workspace'] != null
- ? new WorkspaceClientCapabilities.fromJson(json['workspace'])
+ ? WorkspaceClientCapabilities.fromJson(json['workspace'])
: null;
final textDocument = json['textDocument'] != null
- ? new TextDocumentClientCapabilities.fromJson(json['textDocument'])
+ ? TextDocumentClientCapabilities.fromJson(json['textDocument'])
: null;
final experimental = json['experimental'];
return new ClientCapabilities(workspace, textDocument, experimental);
@@ -144,6 +208,29 @@
static bool canParse(Object obj) {
return obj is Map<String, dynamic>;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is ClientCapabilities) {
+ return workspace == other.workspace &&
+ textDocument == other.textDocument &&
+ experimental == other.experimental &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, workspace.hashCode);
+ hash = JenkinsSmiHash.combine(hash, textDocument.hashCode);
+ hash = JenkinsSmiHash.combine(hash, experimental.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// A code action represents a change that can be performed in code, e.g. to fix
@@ -157,17 +244,18 @@
throw 'title is required but was not provided';
}
}
- factory CodeAction.fromJson(Map<String, dynamic> json) {
+ static CodeAction fromJson(Map<String, dynamic> json) {
final title = json['title'];
- final kind = json['kind'];
+ final kind =
+ json['kind'] != null ? CodeActionKind.fromJson(json['kind']) : null;
final diagnostics = json['diagnostics']
- ?.map((item) => item != null ? new Diagnostic.fromJson(item) : null)
+ ?.map((item) => item != null ? Diagnostic.fromJson(item) : null)
?.cast<Diagnostic>()
?.toList();
final edit =
- json['edit'] != null ? new WorkspaceEdit.fromJson(json['edit']) : null;
+ json['edit'] != null ? WorkspaceEdit.fromJson(json['edit']) : null;
final command =
- json['command'] != null ? new Command.fromJson(json['command']) : null;
+ json['command'] != null ? Command.fromJson(json['command']) : null;
return new CodeAction(title, kind, diagnostics, edit, command);
}
@@ -184,7 +272,7 @@
/// The kind of the code action.
///
/// Used to filter code actions.
- final String kind;
+ final CodeActionKind kind;
/// A short, human-readable, title for this code action.
final String title;
@@ -212,6 +300,34 @@
obj.containsKey('title') &&
obj['title'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is CodeAction) {
+ return title == other.title &&
+ kind == other.kind &&
+ listEqual(diagnostics, other.diagnostics,
+ (Diagnostic a, Diagnostic b) => a == b) &&
+ edit == other.edit &&
+ command == other.command &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, title.hashCode);
+ hash = JenkinsSmiHash.combine(hash, kind.hashCode);
+ hash = JenkinsSmiHash.combine(hash, diagnostics.hashCode);
+ hash = JenkinsSmiHash.combine(hash, edit.hashCode);
+ hash = JenkinsSmiHash.combine(hash, command.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// Contains additional diagnostic information about the context in which a code
@@ -222,12 +338,15 @@
throw 'diagnostics is required but was not provided';
}
}
- factory CodeActionContext.fromJson(Map<String, dynamic> json) {
+ static CodeActionContext fromJson(Map<String, dynamic> json) {
final diagnostics = json['diagnostics']
- ?.map((item) => item != null ? new Diagnostic.fromJson(item) : null)
+ ?.map((item) => item != null ? Diagnostic.fromJson(item) : null)
?.cast<Diagnostic>()
?.toList();
- final only = json['only']?.map((item) => item)?.cast<String>()?.toList();
+ final only = json['only']
+ ?.map((item) => item != null ? CodeActionKind.fromJson(item) : null)
+ ?.cast<CodeActionKind>()
+ ?.toList();
return new CodeActionContext(diagnostics, only);
}
@@ -238,7 +357,7 @@
///
/// Actions not of this kind are filtered out by the client before being
/// shown. So servers can omit computing them.
- final List<String> only;
+ final List<CodeActionKind> only;
Map<String, dynamic> toJson() {
Map<String, dynamic> __result = {};
@@ -257,15 +376,47 @@
(obj['diagnostics'].length == 0 ||
obj['diagnostics'].every((item) => Diagnostic.canParse(item))));
}
+
+ @override
+ bool operator ==(other) {
+ if (other is CodeActionContext) {
+ return listEqual(diagnostics, other.diagnostics,
+ (Diagnostic a, Diagnostic b) => a == b) &&
+ listEqual(only, other.only,
+ (CodeActionKind a, CodeActionKind b) => a == b) &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, diagnostics.hashCode);
+ hash = JenkinsSmiHash.combine(hash, only.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// A set of predefined code action kinds
-abstract class CodeActionKind {
+class CodeActionKind {
+ const CodeActionKind(this._value);
+ const CodeActionKind.fromJson(this._value);
+
+ final String _value;
+
+ static bool canParse(Object obj) {
+ return obj is String;
+ }
+
/// Base kind for quickfix actions: 'quickfix'
- static const QuickFix = 'quickfix';
+ static const QuickFix = const CodeActionKind('quickfix');
/// Base kind for refactoring actions: 'refactor'
- static const Refactor = 'refactor';
+ static const Refactor = const CodeActionKind('refactor');
/// Base kind for refactoring extraction actions: 'refactor.extract'
///
@@ -276,7 +427,7 @@
/// - Extract variable
/// - Extract interface from class
/// - ...
- static const RefactorExtract = 'refactor.extract';
+ static const RefactorExtract = const CodeActionKind('refactor.extract');
/// Base kind for refactoring inline actions: 'refactor.inline'
///
@@ -286,7 +437,7 @@
/// - Inline variable
/// - Inline constant
/// - ...
- static const RefactorInline = 'refactor.inline';
+ static const RefactorInline = const CodeActionKind('refactor.inline');
/// Base kind for refactoring rewrite actions: 'refactor.rewrite'
///
@@ -298,23 +449,36 @@
/// - Make method static
/// - Move method to base class
/// - ...
- static const RefactorRewrite = 'refactor.rewrite';
+ static const RefactorRewrite = const CodeActionKind('refactor.rewrite');
/// Base kind for source actions: `source`
///
/// Source code actions apply to the entire file.
- static const Source = 'source';
+ static const Source = const CodeActionKind('source');
/// Base kind for an organize imports source action: `source.organizeImports`
- static const SourceOrganizeImports = 'source.organizeImports';
+ static const SourceOrganizeImports =
+ const CodeActionKind('source.organizeImports');
+
+ Object toJson() => _value;
+
+ @override
+ String toString() => _value.toString();
+
+ @override
+ get hashCode => _value.hashCode;
+
+ bool operator ==(o) => o is CodeActionKind && o._value == _value;
}
/// Code Action options.
class CodeActionOptions implements ToJsonable {
CodeActionOptions(this.codeActionKinds);
- factory CodeActionOptions.fromJson(Map<String, dynamic> json) {
- final codeActionKinds =
- json['codeActionKinds']?.map((item) => item)?.cast<String>()?.toList();
+ static CodeActionOptions fromJson(Map<String, dynamic> json) {
+ final codeActionKinds = json['codeActionKinds']
+ ?.map((item) => item != null ? CodeActionKind.fromJson(item) : null)
+ ?.cast<CodeActionKind>()
+ ?.toList();
return new CodeActionOptions(codeActionKinds);
}
@@ -322,7 +486,7 @@
///
/// The list of kinds may be generic, such as `CodeActionKind.Refactor`, or
/// the server may list out every specific kind they provide.
- final List<String> codeActionKinds;
+ final List<CodeActionKind> codeActionKinds;
Map<String, dynamic> toJson() {
Map<String, dynamic> __result = {};
@@ -335,6 +499,26 @@
static bool canParse(Object obj) {
return obj is Map<String, dynamic>;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is CodeActionOptions) {
+ return listEqual(codeActionKinds, other.codeActionKinds,
+ (CodeActionKind a, CodeActionKind b) => a == b) &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, codeActionKinds.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// Params for the CodeActionRequest
@@ -350,14 +534,13 @@
throw 'context is required but was not provided';
}
}
- factory CodeActionParams.fromJson(Map<String, dynamic> json) {
+ static CodeActionParams fromJson(Map<String, dynamic> json) {
final textDocument = json['textDocument'] != null
- ? new TextDocumentIdentifier.fromJson(json['textDocument'])
+ ? TextDocumentIdentifier.fromJson(json['textDocument'])
: null;
- final range =
- json['range'] != null ? new Range.fromJson(json['range']) : null;
+ final range = json['range'] != null ? Range.fromJson(json['range']) : null;
final context = json['context'] != null
- ? new CodeActionContext.fromJson(json['context'])
+ ? CodeActionContext.fromJson(json['context'])
: null;
return new CodeActionParams(textDocument, range, context);
}
@@ -390,18 +573,43 @@
obj.containsKey('context') &&
CodeActionContext.canParse(obj['context']);
}
+
+ @override
+ bool operator ==(other) {
+ if (other is CodeActionParams) {
+ return textDocument == other.textDocument &&
+ range == other.range &&
+ context == other.context &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, textDocument.hashCode);
+ hash = JenkinsSmiHash.combine(hash, range.hashCode);
+ hash = JenkinsSmiHash.combine(hash, context.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class CodeActionRegistrationOptions
implements TextDocumentRegistrationOptions, CodeActionOptions, ToJsonable {
CodeActionRegistrationOptions(this.documentSelector, this.codeActionKinds);
- factory CodeActionRegistrationOptions.fromJson(Map<String, dynamic> json) {
+ static CodeActionRegistrationOptions fromJson(Map<String, dynamic> json) {
final documentSelector = json['documentSelector']
- ?.map((item) => item != null ? new DocumentFilter.fromJson(item) : null)
+ ?.map((item) => item != null ? DocumentFilter.fromJson(item) : null)
?.cast<DocumentFilter>()
?.toList();
- final codeActionKinds =
- json['codeActionKinds']?.map((item) => item)?.cast<String>()?.toList();
+ final codeActionKinds = json['codeActionKinds']
+ ?.map((item) => item != null ? CodeActionKind.fromJson(item) : null)
+ ?.cast<CodeActionKind>()
+ ?.toList();
return new CodeActionRegistrationOptions(documentSelector, codeActionKinds);
}
@@ -409,7 +617,7 @@
///
/// The list of kinds may be generic, such as `CodeActionKind.Refactor`, or
/// the server may list out every specific kind they provide.
- final List<String> codeActionKinds;
+ final List<CodeActionKind> codeActionKinds;
/// A document selector to identify the scope of the registration. If set to
/// null the document selector provided on the client side will be used.
@@ -432,6 +640,28 @@
obj['documentSelector']
.every((item) => DocumentFilter.canParse(item))));
}
+
+ @override
+ bool operator ==(other) {
+ if (other is CodeActionRegistrationOptions) {
+ return documentSelector == other.documentSelector &&
+ listEqual(codeActionKinds, other.codeActionKinds,
+ (CodeActionKind a, CodeActionKind b) => a == b) &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, documentSelector.hashCode);
+ hash = JenkinsSmiHash.combine(hash, codeActionKinds.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// A code lens represents a command that should be shown along with source
@@ -446,11 +676,10 @@
throw 'range is required but was not provided';
}
}
- factory CodeLens.fromJson(Map<String, dynamic> json) {
- final range =
- json['range'] != null ? new Range.fromJson(json['range']) : null;
+ static CodeLens fromJson(Map<String, dynamic> json) {
+ final range = json['range'] != null ? Range.fromJson(json['range']) : null;
final command =
- json['command'] != null ? new Command.fromJson(json['command']) : null;
+ json['command'] != null ? Command.fromJson(json['command']) : null;
final data = json['data'];
return new CodeLens(range, command, data);
}
@@ -483,12 +712,35 @@
obj.containsKey('range') &&
Range.canParse(obj['range']);
}
+
+ @override
+ bool operator ==(other) {
+ if (other is CodeLens) {
+ return range == other.range &&
+ command == other.command &&
+ data == other.data &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, range.hashCode);
+ hash = JenkinsSmiHash.combine(hash, command.hashCode);
+ hash = JenkinsSmiHash.combine(hash, data.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// Code Lens options.
class CodeLensOptions implements ToJsonable {
CodeLensOptions(this.resolveProvider);
- factory CodeLensOptions.fromJson(Map<String, dynamic> json) {
+ static CodeLensOptions fromJson(Map<String, dynamic> json) {
final resolveProvider = json['resolveProvider'];
return new CodeLensOptions(resolveProvider);
}
@@ -507,6 +759,24 @@
static bool canParse(Object obj) {
return obj is Map<String, dynamic>;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is CodeLensOptions) {
+ return resolveProvider == other.resolveProvider && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, resolveProvider.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class CodeLensParams implements ToJsonable {
@@ -515,9 +785,9 @@
throw 'textDocument is required but was not provided';
}
}
- factory CodeLensParams.fromJson(Map<String, dynamic> json) {
+ static CodeLensParams fromJson(Map<String, dynamic> json) {
final textDocument = json['textDocument'] != null
- ? new TextDocumentIdentifier.fromJson(json['textDocument'])
+ ? TextDocumentIdentifier.fromJson(json['textDocument'])
: null;
return new CodeLensParams(textDocument);
}
@@ -537,15 +807,33 @@
obj.containsKey('textDocument') &&
TextDocumentIdentifier.canParse(obj['textDocument']);
}
+
+ @override
+ bool operator ==(other) {
+ if (other is CodeLensParams) {
+ return textDocument == other.textDocument && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, textDocument.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class CodeLensRegistrationOptions
implements TextDocumentRegistrationOptions, ToJsonable {
CodeLensRegistrationOptions(this.resolveProvider, this.documentSelector);
- factory CodeLensRegistrationOptions.fromJson(Map<String, dynamic> json) {
+ static CodeLensRegistrationOptions fromJson(Map<String, dynamic> json) {
final resolveProvider = json['resolveProvider'];
final documentSelector = json['documentSelector']
- ?.map((item) => item != null ? new DocumentFilter.fromJson(item) : null)
+ ?.map((item) => item != null ? DocumentFilter.fromJson(item) : null)
?.cast<DocumentFilter>()
?.toList();
return new CodeLensRegistrationOptions(resolveProvider, documentSelector);
@@ -575,6 +863,27 @@
obj['documentSelector']
.every((item) => DocumentFilter.canParse(item))));
}
+
+ @override
+ bool operator ==(other) {
+ if (other is CodeLensRegistrationOptions) {
+ return resolveProvider == other.resolveProvider &&
+ documentSelector == other.documentSelector &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, resolveProvider.hashCode);
+ hash = JenkinsSmiHash.combine(hash, documentSelector.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// Represents a color in RGBA space.
@@ -593,7 +902,7 @@
throw 'alpha is required but was not provided';
}
}
- factory Color.fromJson(Map<String, dynamic> json) {
+ static Color fromJson(Map<String, dynamic> json) {
final red = json['red'];
final green = json['green'];
final blue = json['blue'];
@@ -601,9 +910,16 @@
return new Color(red, green, blue, alpha);
}
+ /// The alpha component of this color in the range [0-1].
final num alpha;
+
+ /// The blue component of this color in the range [0-1].
final num blue;
+
+ /// The green component of this color in the range [0-1].
final num green;
+
+ /// The red component of this color in the range [0-1].
final num red;
Map<String, dynamic> toJson() {
@@ -626,6 +942,31 @@
obj.containsKey('alpha') &&
obj['alpha'] is num;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is Color) {
+ return red == other.red &&
+ green == other.green &&
+ blue == other.blue &&
+ alpha == other.alpha &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, red.hashCode);
+ hash = JenkinsSmiHash.combine(hash, green.hashCode);
+ hash = JenkinsSmiHash.combine(hash, blue.hashCode);
+ hash = JenkinsSmiHash.combine(hash, alpha.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class ColorInformation implements ToJsonable {
@@ -637,11 +978,9 @@
throw 'color is required but was not provided';
}
}
- factory ColorInformation.fromJson(Map<String, dynamic> json) {
- final range =
- json['range'] != null ? new Range.fromJson(json['range']) : null;
- final color =
- json['color'] != null ? new Color.fromJson(json['color']) : null;
+ static ColorInformation fromJson(Map<String, dynamic> json) {
+ final range = json['range'] != null ? Range.fromJson(json['range']) : null;
+ final color = json['color'] != null ? Color.fromJson(json['color']) : null;
return new ColorInformation(range, color);
}
@@ -665,6 +1004,25 @@
obj.containsKey('color') &&
Color.canParse(obj['color']);
}
+
+ @override
+ bool operator ==(other) {
+ if (other is ColorInformation) {
+ return range == other.range && color == other.color && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, range.hashCode);
+ hash = JenkinsSmiHash.combine(hash, color.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class ColorPresentation implements ToJsonable {
@@ -673,13 +1031,12 @@
throw 'label is required but was not provided';
}
}
- factory ColorPresentation.fromJson(Map<String, dynamic> json) {
+ static ColorPresentation fromJson(Map<String, dynamic> json) {
final label = json['label'];
- final textEdit = json['textEdit'] != null
- ? new TextEdit.fromJson(json['textEdit'])
- : null;
+ final textEdit =
+ json['textEdit'] != null ? TextEdit.fromJson(json['textEdit']) : null;
final additionalTextEdits = json['additionalTextEdits']
- ?.map((item) => item != null ? new TextEdit.fromJson(item) : null)
+ ?.map((item) => item != null ? TextEdit.fromJson(item) : null)
?.cast<TextEdit>()
?.toList();
return new ColorPresentation(label, textEdit, additionalTextEdits);
@@ -717,6 +1074,30 @@
obj.containsKey('label') &&
obj['label'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is ColorPresentation) {
+ return label == other.label &&
+ textEdit == other.textEdit &&
+ listEqual(additionalTextEdits, other.additionalTextEdits,
+ (TextEdit a, TextEdit b) => a == b) &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, label.hashCode);
+ hash = JenkinsSmiHash.combine(hash, textEdit.hashCode);
+ hash = JenkinsSmiHash.combine(hash, additionalTextEdits.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class ColorPresentationParams implements ToJsonable {
@@ -731,14 +1112,12 @@
throw 'range is required but was not provided';
}
}
- factory ColorPresentationParams.fromJson(Map<String, dynamic> json) {
+ static ColorPresentationParams fromJson(Map<String, dynamic> json) {
final textDocument = json['textDocument'] != null
- ? new TextDocumentIdentifier.fromJson(json['textDocument'])
+ ? TextDocumentIdentifier.fromJson(json['textDocument'])
: null;
- final color =
- json['color'] != null ? new Color.fromJson(json['color']) : null;
- final range =
- json['range'] != null ? new Range.fromJson(json['range']) : null;
+ final color = json['color'] != null ? Color.fromJson(json['color']) : null;
+ final range = json['range'] != null ? Range.fromJson(json['range']) : null;
return new ColorPresentationParams(textDocument, color, range);
}
@@ -769,10 +1148,37 @@
obj.containsKey('range') &&
Range.canParse(obj['range']);
}
+
+ @override
+ bool operator ==(other) {
+ if (other is ColorPresentationParams) {
+ return textDocument == other.textDocument &&
+ color == other.color &&
+ range == other.range &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, textDocument.hashCode);
+ hash = JenkinsSmiHash.combine(hash, color.hashCode);
+ hash = JenkinsSmiHash.combine(hash, range.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// Color provider options.
class ColorProviderOptions implements ToJsonable {
+ static ColorProviderOptions fromJson(Map<String, dynamic> json) {
+ return new ColorProviderOptions();
+ }
+
Map<String, dynamic> toJson() {
Map<String, dynamic> __result = {};
return __result;
@@ -781,6 +1187,23 @@
static bool canParse(Object obj) {
return obj is Map<String, dynamic>;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is ColorProviderOptions) {
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class Command implements ToJsonable {
@@ -792,7 +1215,7 @@
throw 'command is required but was not provided';
}
}
- factory Command.fromJson(Map<String, dynamic> json) {
+ static Command fromJson(Map<String, dynamic> json) {
final title = json['title'];
final command = json['command'];
final arguments =
@@ -827,6 +1250,30 @@
obj.containsKey('command') &&
obj['command'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is Command) {
+ return title == other.title &&
+ command == other.command &&
+ listEqual(
+ arguments, other.arguments, (dynamic a, dynamic b) => a == b) &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, title.hashCode);
+ hash = JenkinsSmiHash.combine(hash, command.hashCode);
+ hash = JenkinsSmiHash.combine(hash, arguments.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// Contains additional information about the context in which a completion
@@ -837,9 +1284,9 @@
throw 'triggerKind is required but was not provided';
}
}
- factory CompletionContext.fromJson(Map<String, dynamic> json) {
+ static CompletionContext fromJson(Map<String, dynamic> json) {
final triggerKind = json['triggerKind'] != null
- ? new CompletionTriggerKind.fromJson(json['triggerKind'])
+ ? CompletionTriggerKind.fromJson(json['triggerKind'])
: null;
final triggerCharacter = json['triggerCharacter'];
return new CompletionContext(triggerKind, triggerCharacter);
@@ -865,8 +1312,29 @@
static bool canParse(Object obj) {
return obj is Map<String, dynamic> &&
obj.containsKey('triggerKind') &&
- CompletionTriggerKind.canParse(obj['triggerKind']);
+ obj['triggerKind'] is num;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is CompletionContext) {
+ return triggerKind == other.triggerKind &&
+ triggerCharacter == other.triggerCharacter &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, triggerKind.hashCode);
+ hash = JenkinsSmiHash.combine(hash, triggerCharacter.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class CompletionItem implements ToJsonable {
@@ -890,39 +1358,39 @@
throw 'label is required but was not provided';
}
}
- factory CompletionItem.fromJson(Map<String, dynamic> json) {
+ static CompletionItem fromJson(Map<String, dynamic> json) {
final label = json['label'];
- final kind = json['kind'] != null
- ? new CompletionItemKind.fromJson(json['kind'])
- : null;
+ final kind =
+ json['kind'] != null ? CompletionItemKind.fromJson(json['kind']) : null;
final detail = json['detail'];
final documentation = json['documentation'] is String
? new Either2<String, MarkupContent>.t1(json['documentation'])
: (MarkupContent.canParse(json['documentation'])
? new Either2<String, MarkupContent>.t2(
json['documentation'] != null
- ? new MarkupContent.fromJson(json['documentation'])
+ ? MarkupContent.fromJson(json['documentation'])
: null)
- : (throw '''${json['documentation']} was not one of (string, MarkupContent)'''));
+ : (json['documentation'] == null
+ ? null
+ : (throw '''${json['documentation']} was not one of (String, MarkupContent)''')));
final deprecated = json['deprecated'];
final preselect = json['preselect'];
final sortText = json['sortText'];
final filterText = json['filterText'];
final insertText = json['insertText'];
final insertTextFormat = json['insertTextFormat'] != null
- ? new InsertTextFormat.fromJson(json['insertTextFormat'])
+ ? InsertTextFormat.fromJson(json['insertTextFormat'])
: null;
- final textEdit = json['textEdit'] != null
- ? new TextEdit.fromJson(json['textEdit'])
- : null;
+ final textEdit =
+ json['textEdit'] != null ? TextEdit.fromJson(json['textEdit']) : null;
final additionalTextEdits = json['additionalTextEdits']
- ?.map((item) => item != null ? new TextEdit.fromJson(item) : null)
+ ?.map((item) => item != null ? TextEdit.fromJson(item) : null)
?.cast<TextEdit>()
?.toList();
final commitCharacters =
json['commitCharacters']?.map((item) => item)?.cast<String>()?.toList();
final command =
- json['command'] != null ? new Command.fromJson(json['command']) : null;
+ json['command'] != null ? Command.fromJson(json['command']) : null;
final data = json['data'];
return new CompletionItem(
label,
@@ -1047,9 +1515,7 @@
if (filterText != null) {
__result['filterText'] = filterText;
}
- // ignore: deprecated_member_use
if (insertText != null) {
- // ignore: deprecated_member_use
__result['insertText'] = insertText;
}
if (insertTextFormat != null) {
@@ -1078,6 +1544,55 @@
obj.containsKey('label') &&
obj['label'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is CompletionItem) {
+ return label == other.label &&
+ kind == other.kind &&
+ detail == other.detail &&
+ documentation == other.documentation &&
+ deprecated == other.deprecated &&
+ preselect == other.preselect &&
+ sortText == other.sortText &&
+ filterText == other.filterText &&
+ insertText == other.insertText &&
+ insertTextFormat == other.insertTextFormat &&
+ textEdit == other.textEdit &&
+ listEqual(additionalTextEdits, other.additionalTextEdits,
+ (TextEdit a, TextEdit b) => a == b) &&
+ listEqual(commitCharacters, other.commitCharacters,
+ (String a, String b) => a == b) &&
+ command == other.command &&
+ data == other.data &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, label.hashCode);
+ hash = JenkinsSmiHash.combine(hash, kind.hashCode);
+ hash = JenkinsSmiHash.combine(hash, detail.hashCode);
+ hash = JenkinsSmiHash.combine(hash, documentation.hashCode);
+ hash = JenkinsSmiHash.combine(hash, deprecated.hashCode);
+ hash = JenkinsSmiHash.combine(hash, preselect.hashCode);
+ hash = JenkinsSmiHash.combine(hash, sortText.hashCode);
+ hash = JenkinsSmiHash.combine(hash, filterText.hashCode);
+ hash = JenkinsSmiHash.combine(hash, insertText.hashCode);
+ hash = JenkinsSmiHash.combine(hash, insertTextFormat.hashCode);
+ hash = JenkinsSmiHash.combine(hash, textEdit.hashCode);
+ hash = JenkinsSmiHash.combine(hash, additionalTextEdits.hashCode);
+ hash = JenkinsSmiHash.combine(hash, commitCharacters.hashCode);
+ hash = JenkinsSmiHash.combine(hash, command.hashCode);
+ hash = JenkinsSmiHash.combine(hash, data.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// The kind of a completion entry.
@@ -1085,7 +1600,7 @@
const CompletionItemKind._(this._value);
const CompletionItemKind.fromJson(this._value);
- final Object _value;
+ final num _value;
static bool canParse(Object obj) {
switch (obj) {
@@ -1167,10 +1682,10 @@
throw 'items is required but was not provided';
}
}
- factory CompletionList.fromJson(Map<String, dynamic> json) {
+ static CompletionList fromJson(Map<String, dynamic> json) {
final isIncomplete = json['isIncomplete'];
final items = json['items']
- ?.map((item) => item != null ? new CompletionItem.fromJson(item) : null)
+ ?.map((item) => item != null ? CompletionItem.fromJson(item) : null)
?.cast<CompletionItem>()
?.toList();
return new CompletionList(isIncomplete, items);
@@ -1200,12 +1715,34 @@
(obj['items'].length == 0 ||
obj['items'].every((item) => CompletionItem.canParse(item))));
}
+
+ @override
+ bool operator ==(other) {
+ if (other is CompletionList) {
+ return isIncomplete == other.isIncomplete &&
+ listEqual(items, other.items,
+ (CompletionItem a, CompletionItem b) => a == b) &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, isIncomplete.hashCode);
+ hash = JenkinsSmiHash.combine(hash, items.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// Completion options.
class CompletionOptions implements ToJsonable {
CompletionOptions(this.resolveProvider, this.triggerCharacters);
- factory CompletionOptions.fromJson(Map<String, dynamic> json) {
+ static CompletionOptions fromJson(Map<String, dynamic> json) {
final resolveProvider = json['resolveProvider'];
final triggerCharacters = json['triggerCharacters']
?.map((item) => item)
@@ -1235,6 +1772,28 @@
static bool canParse(Object obj) {
return obj is Map<String, dynamic>;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is CompletionOptions) {
+ return resolveProvider == other.resolveProvider &&
+ listEqual(triggerCharacters, other.triggerCharacters,
+ (String a, String b) => a == b) &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, resolveProvider.hashCode);
+ hash = JenkinsSmiHash.combine(hash, triggerCharacters.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class CompletionParams implements TextDocumentPositionParams, ToJsonable {
@@ -1246,22 +1805,21 @@
throw 'position is required but was not provided';
}
}
- factory CompletionParams.fromJson(Map<String, dynamic> json) {
+ static CompletionParams fromJson(Map<String, dynamic> json) {
final context = json['context'] != null
- ? new CompletionContext.fromJson(json['context'])
+ ? CompletionContext.fromJson(json['context'])
: null;
final textDocument = json['textDocument'] != null
- ? new TextDocumentIdentifier.fromJson(json['textDocument'])
+ ? TextDocumentIdentifier.fromJson(json['textDocument'])
: null;
- final position = json['position'] != null
- ? new Position.fromJson(json['position'])
- : null;
+ final position =
+ json['position'] != null ? Position.fromJson(json['position']) : null;
return new CompletionParams(context, textDocument, position);
}
- /// The completion context. This is only available if the client specifies
- /// to send this using
- /// `ClientCapabilities.textDocument.completion.contextSupport === true`
+ /// The completion context. This is only available if the client specifies to
+ /// send this using `ClientCapabilities.textDocument.completion.contextSupport
+ /// === true`
final CompletionContext context;
/// The position inside the text document.
@@ -1289,20 +1847,43 @@
obj.containsKey('position') &&
Position.canParse(obj['position']);
}
+
+ @override
+ bool operator ==(other) {
+ if (other is CompletionParams) {
+ return context == other.context &&
+ textDocument == other.textDocument &&
+ position == other.position &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, context.hashCode);
+ hash = JenkinsSmiHash.combine(hash, textDocument.hashCode);
+ hash = JenkinsSmiHash.combine(hash, position.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class CompletionRegistrationOptions
implements TextDocumentRegistrationOptions, ToJsonable {
CompletionRegistrationOptions(
this.triggerCharacters, this.resolveProvider, this.documentSelector);
- factory CompletionRegistrationOptions.fromJson(Map<String, dynamic> json) {
+ static CompletionRegistrationOptions fromJson(Map<String, dynamic> json) {
final triggerCharacters = json['triggerCharacters']
?.map((item) => item)
?.cast<String>()
?.toList();
final resolveProvider = json['resolveProvider'];
final documentSelector = json['documentSelector']
- ?.map((item) => item != null ? new DocumentFilter.fromJson(item) : null)
+ ?.map((item) => item != null ? DocumentFilter.fromJson(item) : null)
?.cast<DocumentFilter>()
?.toList();
return new CompletionRegistrationOptions(
@@ -1318,11 +1899,11 @@
final bool resolveProvider;
/// Most tools trigger completion request automatically without explicitly
- /// requesting it using a keyboard shortcut (e.g. Ctrl+Space). Typically
- /// they do so when the user starts to type an identifier. For example if
- /// the user types `c` in a JavaScript file code complete will automatically
- /// pop up present `console` besides others as a completion item. Characters
- /// that make up identifiers don't need to be listed here.
+ /// requesting it using a keyboard shortcut (e.g. Ctrl+Space). Typically they
+ /// do so when the user starts to type an identifier. For example if the user
+ /// types `c` in a JavaScript file code complete will automatically pop up
+ /// present `console` besides others as a completion item. Characters that
+ /// make up identifiers don't need to be listed here.
///
/// If code complete should automatically be trigger on characters not being
/// valid inside an identifier (for example `.` in JavaScript) list them in
@@ -1349,6 +1930,30 @@
obj['documentSelector']
.every((item) => DocumentFilter.canParse(item))));
}
+
+ @override
+ bool operator ==(other) {
+ if (other is CompletionRegistrationOptions) {
+ return listEqual(triggerCharacters, other.triggerCharacters,
+ (String a, String b) => a == b) &&
+ resolveProvider == other.resolveProvider &&
+ documentSelector == other.documentSelector &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, triggerCharacters.hashCode);
+ hash = JenkinsSmiHash.combine(hash, resolveProvider.hashCode);
+ hash = JenkinsSmiHash.combine(hash, documentSelector.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// How a completion was triggered
@@ -1356,7 +1961,7 @@
const CompletionTriggerKind._(this._value);
const CompletionTriggerKind.fromJson(this._value);
- final Object _value;
+ final num _value;
static bool canParse(Object obj) {
switch (obj) {
@@ -1376,8 +1981,7 @@
/// `triggerCharacters` properties of the `CompletionRegistrationOptions`.
static const TriggerCharacter = const CompletionTriggerKind._(2);
- /// Completion was re-triggered as the current completion list is
- /// incomplete.
+ /// Completion was re-triggered as the current completion list is incomplete.
static const TriggerForIncompleteCompletions =
const CompletionTriggerKind._(3);
@@ -1394,7 +1998,7 @@
class ConfigurationItem implements ToJsonable {
ConfigurationItem(this.scopeUri, this.section);
- factory ConfigurationItem.fromJson(Map<String, dynamic> json) {
+ static ConfigurationItem fromJson(Map<String, dynamic> json) {
final scopeUri = json['scopeUri'];
final section = json['section'];
return new ConfigurationItem(scopeUri, section);
@@ -1420,6 +2024,25 @@
static bool canParse(Object obj) {
return obj is Map<String, dynamic>;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is ConfigurationItem) {
+ return scopeUri == other.scopeUri && section == other.section && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, scopeUri.hashCode);
+ hash = JenkinsSmiHash.combine(hash, section.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class ConfigurationParams implements ToJsonable {
@@ -1428,10 +2051,9 @@
throw 'items is required but was not provided';
}
}
- factory ConfigurationParams.fromJson(Map<String, dynamic> json) {
+ static ConfigurationParams fromJson(Map<String, dynamic> json) {
final items = json['items']
- ?.map((item) =>
- item != null ? new ConfigurationItem.fromJson(item) : null)
+ ?.map((item) => item != null ? ConfigurationItem.fromJson(item) : null)
?.cast<ConfigurationItem>()
?.toList();
return new ConfigurationParams(items);
@@ -1453,23 +2075,50 @@
obj['items']
.every((item) => ConfigurationItem.canParse(item))));
}
+
+ @override
+ bool operator ==(other) {
+ if (other is ConfigurationParams) {
+ return listEqual(items, other.items,
+ (ConfigurationItem a, ConfigurationItem b) => a == b) &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, items.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// Create file operation
-class CreateFile implements FileOperation, ToJsonable {
- CreateFile(this.uri, this.options) {
+class CreateFile implements ToJsonable {
+ CreateFile(this.kind, this.uri, this.options) {
+ if (kind == null) {
+ throw 'kind is required but was not provided';
+ }
if (uri == null) {
throw 'uri is required but was not provided';
}
}
- factory CreateFile.fromJson(Map<String, dynamic> json) {
+ static CreateFile fromJson(Map<String, dynamic> json) {
+ final kind = json['kind'];
final uri = json['uri'];
final options = json['options'] != null
- ? new CreateFileOptions.fromJson(json['options'])
+ ? CreateFileOptions.fromJson(json['options'])
: null;
- return new CreateFile(uri, options);
+ return new CreateFile(kind, uri, options);
}
+ /// A create
+ final String kind;
+
/// Additional options
final CreateFileOptions options;
@@ -1478,6 +2127,7 @@
Map<String, dynamic> toJson() {
Map<String, dynamic> __result = {};
+ __result['kind'] = kind ?? (throw 'kind is required but was not set');
__result['uri'] = uri ?? (throw 'uri is required but was not set');
if (options != null) {
__result['options'] = options;
@@ -1487,15 +2137,40 @@
static bool canParse(Object obj) {
return obj is Map<String, dynamic> &&
+ obj.containsKey('kind') &&
+ obj['kind'] is String &&
obj.containsKey('uri') &&
obj['uri'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is CreateFile) {
+ return kind == other.kind &&
+ uri == other.uri &&
+ options == other.options &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, kind.hashCode);
+ hash = JenkinsSmiHash.combine(hash, uri.hashCode);
+ hash = JenkinsSmiHash.combine(hash, options.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// Options to create a file.
class CreateFileOptions implements ToJsonable {
CreateFileOptions(this.overwrite, this.ignoreIfExists);
- factory CreateFileOptions.fromJson(Map<String, dynamic> json) {
+ static CreateFileOptions fromJson(Map<String, dynamic> json) {
final overwrite = json['overwrite'];
final ignoreIfExists = json['ignoreIfExists'];
return new CreateFileOptions(overwrite, ignoreIfExists);
@@ -1521,23 +2196,51 @@
static bool canParse(Object obj) {
return obj is Map<String, dynamic>;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is CreateFileOptions) {
+ return overwrite == other.overwrite &&
+ ignoreIfExists == other.ignoreIfExists &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, overwrite.hashCode);
+ hash = JenkinsSmiHash.combine(hash, ignoreIfExists.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// Delete file operation
-class DeleteFile implements FileOperation, ToJsonable {
- DeleteFile(this.uri, this.options) {
+class DeleteFile implements ToJsonable {
+ DeleteFile(this.kind, this.uri, this.options) {
+ if (kind == null) {
+ throw 'kind is required but was not provided';
+ }
if (uri == null) {
throw 'uri is required but was not provided';
}
}
- factory DeleteFile.fromJson(Map<String, dynamic> json) {
+ static DeleteFile fromJson(Map<String, dynamic> json) {
+ final kind = json['kind'];
final uri = json['uri'];
final options = json['options'] != null
- ? new DeleteFileOptions.fromJson(json['options'])
+ ? DeleteFileOptions.fromJson(json['options'])
: null;
- return new DeleteFile(uri, options);
+ return new DeleteFile(kind, uri, options);
}
+ /// A delete
+ final String kind;
+
/// Delete options.
final DeleteFileOptions options;
@@ -1546,6 +2249,7 @@
Map<String, dynamic> toJson() {
Map<String, dynamic> __result = {};
+ __result['kind'] = kind ?? (throw 'kind is required but was not set');
__result['uri'] = uri ?? (throw 'uri is required but was not set');
if (options != null) {
__result['options'] = options;
@@ -1555,15 +2259,40 @@
static bool canParse(Object obj) {
return obj is Map<String, dynamic> &&
+ obj.containsKey('kind') &&
+ obj['kind'] is String &&
obj.containsKey('uri') &&
obj['uri'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is DeleteFile) {
+ return kind == other.kind &&
+ uri == other.uri &&
+ options == other.options &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, kind.hashCode);
+ hash = JenkinsSmiHash.combine(hash, uri.hashCode);
+ hash = JenkinsSmiHash.combine(hash, options.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// Delete file options
class DeleteFileOptions implements ToJsonable {
DeleteFileOptions(this.recursive, this.ignoreIfNotExists);
- factory DeleteFileOptions.fromJson(Map<String, dynamic> json) {
+ static DeleteFileOptions fromJson(Map<String, dynamic> json) {
final recursive = json['recursive'];
final ignoreIfNotExists = json['ignoreIfNotExists'];
return new DeleteFileOptions(recursive, ignoreIfNotExists);
@@ -1589,6 +2318,27 @@
static bool canParse(Object obj) {
return obj is Map<String, dynamic>;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is DeleteFileOptions) {
+ return recursive == other.recursive &&
+ ignoreIfNotExists == other.ignoreIfNotExists &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, recursive.hashCode);
+ hash = JenkinsSmiHash.combine(hash, ignoreIfNotExists.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class Diagnostic implements ToJsonable {
@@ -1601,23 +2351,17 @@
throw 'message is required but was not provided';
}
}
- factory Diagnostic.fromJson(Map<String, dynamic> json) {
- final range =
- json['range'] != null ? new Range.fromJson(json['range']) : null;
+ static Diagnostic fromJson(Map<String, dynamic> json) {
+ final range = json['range'] != null ? Range.fromJson(json['range']) : null;
final severity = json['severity'] != null
- ? new DiagnosticSeverity.fromJson(json['severity'])
+ ? DiagnosticSeverity.fromJson(json['severity'])
: null;
- final code = json['code'] is num
- ? new Either2<num, String>.t1(json['code'])
- : (json['code'] is String
- ? new Either2<num, String>.t2(json['code'])
- : (throw '''${json['code']} was not one of (number, string)'''));
+ final code = json['code'];
final source = json['source'];
final message = json['message'];
final relatedInformation = json['relatedInformation']
- ?.map((item) => item != null
- ? new DiagnosticRelatedInformation.fromJson(item)
- : null)
+ ?.map((item) =>
+ item != null ? DiagnosticRelatedInformation.fromJson(item) : null)
?.cast<DiagnosticRelatedInformation>()
?.toList();
return new Diagnostic(
@@ -1625,7 +2369,7 @@
}
/// The diagnostic's code, which might appear in the user interface.
- final Either2<num, String> code;
+ final String code;
/// The diagnostic's message.
final String message;
@@ -1633,9 +2377,8 @@
/// The range at which the message applies.
final Range range;
- /// An array of related diagnostic information, e.g. when symbol-names
- /// within a scope collide all definitions can be marked via this
- /// property.
+ /// An array of related diagnostic information, e.g. when symbol-names within
+ /// a scope collide all definitions can be marked via this property.
final List<DiagnosticRelatedInformation> relatedInformation;
/// The diagnostic's severity. Can be omitted. If omitted it is up to the
@@ -1673,11 +2416,45 @@
obj.containsKey('message') &&
obj['message'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is Diagnostic) {
+ return range == other.range &&
+ severity == other.severity &&
+ code == other.code &&
+ source == other.source &&
+ message == other.message &&
+ listEqual(
+ relatedInformation,
+ other.relatedInformation,
+ (DiagnosticRelatedInformation a,
+ DiagnosticRelatedInformation b) =>
+ a == b) &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, range.hashCode);
+ hash = JenkinsSmiHash.combine(hash, severity.hashCode);
+ hash = JenkinsSmiHash.combine(hash, code.hashCode);
+ hash = JenkinsSmiHash.combine(hash, source.hashCode);
+ hash = JenkinsSmiHash.combine(hash, message.hashCode);
+ hash = JenkinsSmiHash.combine(hash, relatedInformation.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
-/// Represents a related message and source code location for a diagnostic.
-/// This should be used to point to code locations that cause or related to
-/// a diagnostics, e.g when duplicating a symbol in a scope.
+/// Represents a related message and source code location for a diagnostic. This
+/// should be used to point to code locations that cause or related to a
+/// diagnostics, e.g when duplicating a symbol in a scope.
class DiagnosticRelatedInformation implements ToJsonable {
DiagnosticRelatedInformation(this.location, this.message) {
if (location == null) {
@@ -1687,10 +2464,9 @@
throw 'message is required but was not provided';
}
}
- factory DiagnosticRelatedInformation.fromJson(Map<String, dynamic> json) {
- final location = json['location'] != null
- ? new Location.fromJson(json['location'])
- : null;
+ static DiagnosticRelatedInformation fromJson(Map<String, dynamic> json) {
+ final location =
+ json['location'] != null ? Location.fromJson(json['location']) : null;
final message = json['message'];
return new DiagnosticRelatedInformation(location, message);
}
@@ -1717,13 +2493,32 @@
obj.containsKey('message') &&
obj['message'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is DiagnosticRelatedInformation) {
+ return location == other.location && message == other.message && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, location.hashCode);
+ hash = JenkinsSmiHash.combine(hash, message.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class DiagnosticSeverity {
const DiagnosticSeverity._(this._value);
const DiagnosticSeverity.fromJson(this._value);
- final Object _value;
+ final num _value;
static bool canParse(Object obj) {
switch (obj) {
@@ -1765,7 +2560,7 @@
throw 'settings is required but was not provided';
}
}
- factory DidChangeConfigurationParams.fromJson(Map<String, dynamic> json) {
+ static DidChangeConfigurationParams fromJson(Map<String, dynamic> json) {
final settings = json['settings'];
return new DidChangeConfigurationParams(settings);
}
@@ -1783,6 +2578,24 @@
static bool canParse(Object obj) {
return obj is Map<String, dynamic> && obj.containsKey('settings') && true;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is DidChangeConfigurationParams) {
+ return settings == other.settings && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, settings.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class DidChangeTextDocumentParams implements ToJsonable {
@@ -1794,27 +2607,25 @@
throw 'contentChanges is required but was not provided';
}
}
- factory DidChangeTextDocumentParams.fromJson(Map<String, dynamic> json) {
+ static DidChangeTextDocumentParams fromJson(Map<String, dynamic> json) {
final textDocument = json['textDocument'] != null
- ? new VersionedTextDocumentIdentifier.fromJson(json['textDocument'])
+ ? VersionedTextDocumentIdentifier.fromJson(json['textDocument'])
: null;
final contentChanges = json['contentChanges']
- ?.map((item) => item != null
- ? new TextDocumentContentChangeEvent.fromJson(item)
- : null)
+ ?.map((item) =>
+ item != null ? TextDocumentContentChangeEvent.fromJson(item) : null)
?.cast<TextDocumentContentChangeEvent>()
?.toList();
return new DidChangeTextDocumentParams(textDocument, contentChanges);
}
- /// The actual content changes. The content changes describe single
- /// state changes to the document. So if there are two content changes
- /// c1 and c2 for a document in state S then c1 move the document to S'
- /// and c2 to S''.
+ /// The actual content changes. The content changes describe single state
+ /// changes to the document. So if there are two content changes c1 and c2 for
+ /// a document in state S then c1 move the document to S' and c2 to S''.
final List<TextDocumentContentChangeEvent> contentChanges;
- /// The document that did change. The version number points to the
- /// version after all provided content changes have been applied.
+ /// The document that did change. The version number points to the version
+ /// after all provided content changes have been applied.
final VersionedTextDocumentIdentifier textDocument;
Map<String, dynamic> toJson() {
@@ -1836,6 +2647,32 @@
obj['contentChanges'].every(
(item) => TextDocumentContentChangeEvent.canParse(item))));
}
+
+ @override
+ bool operator ==(other) {
+ if (other is DidChangeTextDocumentParams) {
+ return textDocument == other.textDocument &&
+ listEqual(
+ contentChanges,
+ other.contentChanges,
+ (TextDocumentContentChangeEvent a,
+ TextDocumentContentChangeEvent b) =>
+ a == b) &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, textDocument.hashCode);
+ hash = JenkinsSmiHash.combine(hash, contentChanges.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class DidChangeWatchedFilesParams implements ToJsonable {
@@ -1844,9 +2681,9 @@
throw 'changes is required but was not provided';
}
}
- factory DidChangeWatchedFilesParams.fromJson(Map<String, dynamic> json) {
+ static DidChangeWatchedFilesParams fromJson(Map<String, dynamic> json) {
final changes = json['changes']
- ?.map((item) => item != null ? new FileEvent.fromJson(item) : null)
+ ?.map((item) => item != null ? FileEvent.fromJson(item) : null)
?.cast<FileEvent>()
?.toList();
return new DidChangeWatchedFilesParams(changes);
@@ -1869,6 +2706,26 @@
(obj['changes'].length == 0 ||
obj['changes'].every((item) => FileEvent.canParse(item))));
}
+
+ @override
+ bool operator ==(other) {
+ if (other is DidChangeWatchedFilesParams) {
+ return listEqual(
+ changes, other.changes, (FileEvent a, FileEvent b) => a == b) &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, changes.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// Describe options to be used when registering for text document change
@@ -1879,11 +2736,10 @@
throw 'watchers is required but was not provided';
}
}
- factory DidChangeWatchedFilesRegistrationOptions.fromJson(
+ static DidChangeWatchedFilesRegistrationOptions fromJson(
Map<String, dynamic> json) {
final watchers = json['watchers']
- ?.map((item) =>
- item != null ? new FileSystemWatcher.fromJson(item) : null)
+ ?.map((item) => item != null ? FileSystemWatcher.fromJson(item) : null)
?.cast<FileSystemWatcher>()
?.toList();
return new DidChangeWatchedFilesRegistrationOptions(watchers);
@@ -1907,6 +2763,26 @@
obj['watchers']
.every((item) => FileSystemWatcher.canParse(item))));
}
+
+ @override
+ bool operator ==(other) {
+ if (other is DidChangeWatchedFilesRegistrationOptions) {
+ return listEqual(watchers, other.watchers,
+ (FileSystemWatcher a, FileSystemWatcher b) => a == b) &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, watchers.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class DidChangeWorkspaceFoldersParams implements ToJsonable {
@@ -1915,9 +2791,9 @@
throw 'event is required but was not provided';
}
}
- factory DidChangeWorkspaceFoldersParams.fromJson(Map<String, dynamic> json) {
+ static DidChangeWorkspaceFoldersParams fromJson(Map<String, dynamic> json) {
final event = json['event'] != null
- ? new WorkspaceFoldersChangeEvent.fromJson(json['event'])
+ ? WorkspaceFoldersChangeEvent.fromJson(json['event'])
: null;
return new DidChangeWorkspaceFoldersParams(event);
}
@@ -1936,6 +2812,24 @@
obj.containsKey('event') &&
WorkspaceFoldersChangeEvent.canParse(obj['event']);
}
+
+ @override
+ bool operator ==(other) {
+ if (other is DidChangeWorkspaceFoldersParams) {
+ return event == other.event && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, event.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class DidCloseTextDocumentParams implements ToJsonable {
@@ -1944,9 +2838,9 @@
throw 'textDocument is required but was not provided';
}
}
- factory DidCloseTextDocumentParams.fromJson(Map<String, dynamic> json) {
+ static DidCloseTextDocumentParams fromJson(Map<String, dynamic> json) {
final textDocument = json['textDocument'] != null
- ? new TextDocumentIdentifier.fromJson(json['textDocument'])
+ ? TextDocumentIdentifier.fromJson(json['textDocument'])
: null;
return new DidCloseTextDocumentParams(textDocument);
}
@@ -1966,6 +2860,24 @@
obj.containsKey('textDocument') &&
TextDocumentIdentifier.canParse(obj['textDocument']);
}
+
+ @override
+ bool operator ==(other) {
+ if (other is DidCloseTextDocumentParams) {
+ return textDocument == other.textDocument && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, textDocument.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class DidOpenTextDocumentParams implements ToJsonable {
@@ -1974,9 +2886,9 @@
throw 'textDocument is required but was not provided';
}
}
- factory DidOpenTextDocumentParams.fromJson(Map<String, dynamic> json) {
+ static DidOpenTextDocumentParams fromJson(Map<String, dynamic> json) {
final textDocument = json['textDocument'] != null
- ? new TextDocumentItem.fromJson(json['textDocument'])
+ ? TextDocumentItem.fromJson(json['textDocument'])
: null;
return new DidOpenTextDocumentParams(textDocument);
}
@@ -1996,6 +2908,24 @@
obj.containsKey('textDocument') &&
TextDocumentItem.canParse(obj['textDocument']);
}
+
+ @override
+ bool operator ==(other) {
+ if (other is DidOpenTextDocumentParams) {
+ return textDocument == other.textDocument && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, textDocument.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class DidSaveTextDocumentParams implements ToJsonable {
@@ -2004,16 +2934,16 @@
throw 'textDocument is required but was not provided';
}
}
- factory DidSaveTextDocumentParams.fromJson(Map<String, dynamic> json) {
+ static DidSaveTextDocumentParams fromJson(Map<String, dynamic> json) {
final textDocument = json['textDocument'] != null
- ? new TextDocumentIdentifier.fromJson(json['textDocument'])
+ ? TextDocumentIdentifier.fromJson(json['textDocument'])
: null;
final text = json['text'];
return new DidSaveTextDocumentParams(textDocument, text);
}
- /// Optional the content when saved. Depends on the includeText value
- /// when the save notification was requested.
+ /// Optional the content when saved. Depends on the includeText value when the
+ /// save notification was requested.
final String text;
/// The document that was saved.
@@ -2034,11 +2964,30 @@
obj.containsKey('textDocument') &&
TextDocumentIdentifier.canParse(obj['textDocument']);
}
+
+ @override
+ bool operator ==(other) {
+ if (other is DidSaveTextDocumentParams) {
+ return textDocument == other.textDocument && text == other.text && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, textDocument.hashCode);
+ hash = JenkinsSmiHash.combine(hash, text.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class DocumentFilter implements ToJsonable {
DocumentFilter(this.language, this.scheme, this.pattern);
- factory DocumentFilter.fromJson(Map<String, dynamic> json) {
+ static DocumentFilter fromJson(Map<String, dynamic> json) {
final language = json['language'];
final scheme = json['scheme'];
final pattern = json['pattern'];
@@ -2071,6 +3020,29 @@
static bool canParse(Object obj) {
return obj is Map<String, dynamic>;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is DocumentFilter) {
+ return language == other.language &&
+ scheme == other.scheme &&
+ pattern == other.pattern &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, language.hashCode);
+ hash = JenkinsSmiHash.combine(hash, scheme.hashCode);
+ hash = JenkinsSmiHash.combine(hash, pattern.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class DocumentFormattingParams implements ToJsonable {
@@ -2082,12 +3054,12 @@
throw 'options is required but was not provided';
}
}
- factory DocumentFormattingParams.fromJson(Map<String, dynamic> json) {
+ static DocumentFormattingParams fromJson(Map<String, dynamic> json) {
final textDocument = json['textDocument'] != null
- ? new TextDocumentIdentifier.fromJson(json['textDocument'])
+ ? TextDocumentIdentifier.fromJson(json['textDocument'])
: null;
final options = json['options'] != null
- ? new FormattingOptions.fromJson(json['options'])
+ ? FormattingOptions.fromJson(json['options'])
: null;
return new DocumentFormattingParams(textDocument, options);
}
@@ -2114,22 +3086,42 @@
obj.containsKey('options') &&
FormattingOptions.canParse(obj['options']);
}
+
+ @override
+ bool operator ==(other) {
+ if (other is DocumentFormattingParams) {
+ return textDocument == other.textDocument &&
+ options == other.options &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, textDocument.hashCode);
+ hash = JenkinsSmiHash.combine(hash, options.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// A document highlight is a range inside a text document which deserves
-/// special attention. Usually a document highlight is visualized by
-/// changing the background color of its range.
+/// special attention. Usually a document highlight is visualized by changing
+/// the background color of its range.
class DocumentHighlight implements ToJsonable {
DocumentHighlight(this.range, this.kind) {
if (range == null) {
throw 'range is required but was not provided';
}
}
- factory DocumentHighlight.fromJson(Map<String, dynamic> json) {
- final range =
- json['range'] != null ? new Range.fromJson(json['range']) : null;
+ static DocumentHighlight fromJson(Map<String, dynamic> json) {
+ final range = json['range'] != null ? Range.fromJson(json['range']) : null;
final kind = json['kind'] != null
- ? new DocumentHighlightKind.fromJson(json['kind'])
+ ? DocumentHighlightKind.fromJson(json['kind'])
: null;
return new DocumentHighlight(range, kind);
}
@@ -2154,6 +3146,25 @@
obj.containsKey('range') &&
Range.canParse(obj['range']);
}
+
+ @override
+ bool operator ==(other) {
+ if (other is DocumentHighlight) {
+ return range == other.range && kind == other.kind && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, range.hashCode);
+ hash = JenkinsSmiHash.combine(hash, kind.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// A document highlight kind.
@@ -2161,7 +3172,7 @@
const DocumentHighlightKind._(this._value);
const DocumentHighlightKind.fromJson(this._value);
- final Object _value;
+ final num _value;
static bool canParse(Object obj) {
switch (obj) {
@@ -2193,18 +3204,16 @@
bool operator ==(o) => o is DocumentHighlightKind && o._value == _value;
}
-/// A document link is a range in a text document that links to an
-/// internal or external resource, like another text document or a web
-/// site.
+/// A document link is a range in a text document that links to an internal or
+/// external resource, like another text document or a web site.
class DocumentLink implements ToJsonable {
DocumentLink(this.range, this.target, this.data) {
if (range == null) {
throw 'range is required but was not provided';
}
}
- factory DocumentLink.fromJson(Map<String, dynamic> json) {
- final range =
- json['range'] != null ? new Range.fromJson(json['range']) : null;
+ static DocumentLink fromJson(Map<String, dynamic> json) {
+ final range = json['range'] != null ? Range.fromJson(json['range']) : null;
final target = json['target'];
final data = json['data'];
return new DocumentLink(range, target, data);
@@ -2217,8 +3226,7 @@
/// The range this link applies to.
final Range range;
- /// The uri this link points to. If missing a resolve request is sent
- /// later.
+ /// The uri this link points to. If missing a resolve request is sent later.
final String target;
Map<String, dynamic> toJson() {
@@ -2238,12 +3246,35 @@
obj.containsKey('range') &&
Range.canParse(obj['range']);
}
+
+ @override
+ bool operator ==(other) {
+ if (other is DocumentLink) {
+ return range == other.range &&
+ target == other.target &&
+ data == other.data &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, range.hashCode);
+ hash = JenkinsSmiHash.combine(hash, target.hashCode);
+ hash = JenkinsSmiHash.combine(hash, data.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// Document link options.
class DocumentLinkOptions implements ToJsonable {
DocumentLinkOptions(this.resolveProvider);
- factory DocumentLinkOptions.fromJson(Map<String, dynamic> json) {
+ static DocumentLinkOptions fromJson(Map<String, dynamic> json) {
final resolveProvider = json['resolveProvider'];
return new DocumentLinkOptions(resolveProvider);
}
@@ -2262,6 +3293,24 @@
static bool canParse(Object obj) {
return obj is Map<String, dynamic>;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is DocumentLinkOptions) {
+ return resolveProvider == other.resolveProvider && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, resolveProvider.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class DocumentLinkParams implements ToJsonable {
@@ -2270,9 +3319,9 @@
throw 'textDocument is required but was not provided';
}
}
- factory DocumentLinkParams.fromJson(Map<String, dynamic> json) {
+ static DocumentLinkParams fromJson(Map<String, dynamic> json) {
final textDocument = json['textDocument'] != null
- ? new TextDocumentIdentifier.fromJson(json['textDocument'])
+ ? TextDocumentIdentifier.fromJson(json['textDocument'])
: null;
return new DocumentLinkParams(textDocument);
}
@@ -2292,24 +3341,41 @@
obj.containsKey('textDocument') &&
TextDocumentIdentifier.canParse(obj['textDocument']);
}
+
+ @override
+ bool operator ==(other) {
+ if (other is DocumentLinkParams) {
+ return textDocument == other.textDocument && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, textDocument.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class DocumentLinkRegistrationOptions
implements TextDocumentRegistrationOptions, ToJsonable {
DocumentLinkRegistrationOptions(this.resolveProvider, this.documentSelector);
- factory DocumentLinkRegistrationOptions.fromJson(Map<String, dynamic> json) {
+ static DocumentLinkRegistrationOptions fromJson(Map<String, dynamic> json) {
final resolveProvider = json['resolveProvider'];
final documentSelector = json['documentSelector']
- ?.map((item) => item != null ? new DocumentFilter.fromJson(item) : null)
+ ?.map((item) => item != null ? DocumentFilter.fromJson(item) : null)
?.cast<DocumentFilter>()
?.toList();
return new DocumentLinkRegistrationOptions(
resolveProvider, documentSelector);
}
- /// A document selector to identify the scope of the registration. If
- /// set to null the document selector provided on the client side will
- /// be used.
+ /// A document selector to identify the scope of the registration. If set to
+ /// null the document selector provided on the client side will be used.
final List<DocumentFilter> documentSelector;
/// Document links have a resolve provider as well.
@@ -2332,6 +3398,27 @@
obj['documentSelector']
.every((item) => DocumentFilter.canParse(item))));
}
+
+ @override
+ bool operator ==(other) {
+ if (other is DocumentLinkRegistrationOptions) {
+ return resolveProvider == other.resolveProvider &&
+ documentSelector == other.documentSelector &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, resolveProvider.hashCode);
+ hash = JenkinsSmiHash.combine(hash, documentSelector.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// Format document on type options.
@@ -2342,7 +3429,7 @@
throw 'firstTriggerCharacter is required but was not provided';
}
}
- factory DocumentOnTypeFormattingOptions.fromJson(Map<String, dynamic> json) {
+ static DocumentOnTypeFormattingOptions fromJson(Map<String, dynamic> json) {
final firstTriggerCharacter = json['firstTriggerCharacter'];
final moreTriggerCharacter = json['moreTriggerCharacter']
?.map((item) => item)
@@ -2373,6 +3460,28 @@
obj.containsKey('firstTriggerCharacter') &&
obj['firstTriggerCharacter'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is DocumentOnTypeFormattingOptions) {
+ return firstTriggerCharacter == other.firstTriggerCharacter &&
+ listEqual(moreTriggerCharacter, other.moreTriggerCharacter,
+ (String a, String b) => a == b) &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, firstTriggerCharacter.hashCode);
+ hash = JenkinsSmiHash.combine(hash, moreTriggerCharacter.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class DocumentOnTypeFormattingParams implements ToJsonable {
@@ -2391,16 +3500,15 @@
throw 'options is required but was not provided';
}
}
- factory DocumentOnTypeFormattingParams.fromJson(Map<String, dynamic> json) {
+ static DocumentOnTypeFormattingParams fromJson(Map<String, dynamic> json) {
final textDocument = json['textDocument'] != null
- ? new TextDocumentIdentifier.fromJson(json['textDocument'])
+ ? TextDocumentIdentifier.fromJson(json['textDocument'])
: null;
- final position = json['position'] != null
- ? new Position.fromJson(json['position'])
- : null;
+ final position =
+ json['position'] != null ? Position.fromJson(json['position']) : null;
final ch = json['ch'];
final options = json['options'] != null
- ? new FormattingOptions.fromJson(json['options'])
+ ? FormattingOptions.fromJson(json['options'])
: null;
return new DocumentOnTypeFormattingParams(
textDocument, position, ch, options);
@@ -2441,6 +3549,31 @@
obj.containsKey('options') &&
FormattingOptions.canParse(obj['options']);
}
+
+ @override
+ bool operator ==(other) {
+ if (other is DocumentOnTypeFormattingParams) {
+ return textDocument == other.textDocument &&
+ position == other.position &&
+ ch == other.ch &&
+ options == other.options &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, textDocument.hashCode);
+ hash = JenkinsSmiHash.combine(hash, position.hashCode);
+ hash = JenkinsSmiHash.combine(hash, ch.hashCode);
+ hash = JenkinsSmiHash.combine(hash, options.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class DocumentOnTypeFormattingRegistrationOptions
@@ -2451,7 +3584,7 @@
throw 'firstTriggerCharacter is required but was not provided';
}
}
- factory DocumentOnTypeFormattingRegistrationOptions.fromJson(
+ static DocumentOnTypeFormattingRegistrationOptions fromJson(
Map<String, dynamic> json) {
final firstTriggerCharacter = json['firstTriggerCharacter'];
final moreTriggerCharacter = json['moreTriggerCharacter']
@@ -2459,16 +3592,15 @@
?.cast<String>()
?.toList();
final documentSelector = json['documentSelector']
- ?.map((item) => item != null ? new DocumentFilter.fromJson(item) : null)
+ ?.map((item) => item != null ? DocumentFilter.fromJson(item) : null)
?.cast<DocumentFilter>()
?.toList();
return new DocumentOnTypeFormattingRegistrationOptions(
firstTriggerCharacter, moreTriggerCharacter, documentSelector);
}
- /// A document selector to identify the scope of the registration. If
- /// set to null the document selector provided on the client side will
- /// be used.
+ /// A document selector to identify the scope of the registration. If set to
+ /// null the document selector provided on the client side will be used.
final List<DocumentFilter> documentSelector;
/// A character on which formatting should be triggered, like `}`.
@@ -2498,6 +3630,30 @@
obj['documentSelector']
.every((item) => DocumentFilter.canParse(item))));
}
+
+ @override
+ bool operator ==(other) {
+ if (other is DocumentOnTypeFormattingRegistrationOptions) {
+ return firstTriggerCharacter == other.firstTriggerCharacter &&
+ listEqual(moreTriggerCharacter, other.moreTriggerCharacter,
+ (String a, String b) => a == b) &&
+ documentSelector == other.documentSelector &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, firstTriggerCharacter.hashCode);
+ hash = JenkinsSmiHash.combine(hash, moreTriggerCharacter.hashCode);
+ hash = JenkinsSmiHash.combine(hash, documentSelector.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class DocumentRangeFormattingParams implements ToJsonable {
@@ -2512,14 +3668,13 @@
throw 'options is required but was not provided';
}
}
- factory DocumentRangeFormattingParams.fromJson(Map<String, dynamic> json) {
+ static DocumentRangeFormattingParams fromJson(Map<String, dynamic> json) {
final textDocument = json['textDocument'] != null
- ? new TextDocumentIdentifier.fromJson(json['textDocument'])
+ ? TextDocumentIdentifier.fromJson(json['textDocument'])
: null;
- final range =
- json['range'] != null ? new Range.fromJson(json['range']) : null;
+ final range = json['range'] != null ? Range.fromJson(json['range']) : null;
final options = json['options'] != null
- ? new FormattingOptions.fromJson(json['options'])
+ ? FormattingOptions.fromJson(json['options'])
: null;
return new DocumentRangeFormattingParams(textDocument, range, options);
}
@@ -2552,13 +3707,35 @@
obj.containsKey('options') &&
FormattingOptions.canParse(obj['options']);
}
+
+ @override
+ bool operator ==(other) {
+ if (other is DocumentRangeFormattingParams) {
+ return textDocument == other.textDocument &&
+ range == other.range &&
+ options == other.options &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, textDocument.hashCode);
+ hash = JenkinsSmiHash.combine(hash, range.hashCode);
+ hash = JenkinsSmiHash.combine(hash, options.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
-/// Represents programming constructs like variables, classes,
-/// interfaces etc. that appear in a document. Document symbols can be
-/// hierarchical and they have two ranges: one that encloses its
-/// definition and one that points to its most interesting range, e.g.
-/// the range of an identifier.
+/// Represents programming constructs like variables, classes, interfaces etc.
+/// that appear in a document. Document symbols can be hierarchical and they
+/// have two ranges: one that encloses its definition and one that points to its
+/// most interesting range, e.g. the range of an identifier.
class DocumentSymbol implements ToJsonable {
DocumentSymbol(this.name, this.detail, this.kind, this.deprecated, this.range,
this.selectionRange, this.children) {
@@ -2575,19 +3752,18 @@
throw 'selectionRange is required but was not provided';
}
}
- factory DocumentSymbol.fromJson(Map<String, dynamic> json) {
+ static DocumentSymbol fromJson(Map<String, dynamic> json) {
final name = json['name'];
final detail = json['detail'];
final kind =
- json['kind'] != null ? new SymbolKind.fromJson(json['kind']) : null;
+ json['kind'] != null ? SymbolKind.fromJson(json['kind']) : null;
final deprecated = json['deprecated'];
- final range =
- json['range'] != null ? new Range.fromJson(json['range']) : null;
+ final range = json['range'] != null ? Range.fromJson(json['range']) : null;
final selectionRange = json['selectionRange'] != null
- ? new Range.fromJson(json['selectionRange'])
+ ? Range.fromJson(json['selectionRange'])
: null;
final children = json['children']
- ?.map((item) => item != null ? new DocumentSymbol.fromJson(item) : null)
+ ?.map((item) => item != null ? DocumentSymbol.fromJson(item) : null)
?.cast<DocumentSymbol>()
?.toList();
return new DocumentSymbol(
@@ -2609,15 +3785,14 @@
/// The name of this symbol.
final String name;
- /// The range enclosing this symbol not including leading/trailing
- /// whitespace but everything else like comments. This information is
- /// typically used to determine if the clients cursor is inside the
- /// symbol to reveal in the symbol in the UI.
+ /// The range enclosing this symbol not including leading/trailing whitespace
+ /// but everything else like comments. This information is typically used to
+ /// determine if the clients cursor is inside the symbol to reveal in the
+ /// symbol in the UI.
final Range range;
- /// The range that should be selected and revealed when this symbol is
- /// being picked, e.g the name of a function. Must be contained by the
- /// `range`.
+ /// The range that should be selected and revealed when this symbol is being
+ /// picked, e.g the name of a function. Must be contained by the `range`.
final Range selectionRange;
Map<String, dynamic> toJson() {
@@ -2650,6 +3825,38 @@
obj.containsKey('selectionRange') &&
Range.canParse(obj['selectionRange']);
}
+
+ @override
+ bool operator ==(other) {
+ if (other is DocumentSymbol) {
+ return name == other.name &&
+ detail == other.detail &&
+ kind == other.kind &&
+ deprecated == other.deprecated &&
+ range == other.range &&
+ selectionRange == other.selectionRange &&
+ listEqual(children, other.children,
+ (DocumentSymbol a, DocumentSymbol b) => a == b) &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, name.hashCode);
+ hash = JenkinsSmiHash.combine(hash, detail.hashCode);
+ hash = JenkinsSmiHash.combine(hash, kind.hashCode);
+ hash = JenkinsSmiHash.combine(hash, deprecated.hashCode);
+ hash = JenkinsSmiHash.combine(hash, range.hashCode);
+ hash = JenkinsSmiHash.combine(hash, selectionRange.hashCode);
+ hash = JenkinsSmiHash.combine(hash, children.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class DocumentSymbolParams implements ToJsonable {
@@ -2658,9 +3865,9 @@
throw 'textDocument is required but was not provided';
}
}
- factory DocumentSymbolParams.fromJson(Map<String, dynamic> json) {
+ static DocumentSymbolParams fromJson(Map<String, dynamic> json) {
final textDocument = json['textDocument'] != null
- ? new TextDocumentIdentifier.fromJson(json['textDocument'])
+ ? TextDocumentIdentifier.fromJson(json['textDocument'])
: null;
return new DocumentSymbolParams(textDocument);
}
@@ -2680,19 +3887,59 @@
obj.containsKey('textDocument') &&
TextDocumentIdentifier.canParse(obj['textDocument']);
}
+
+ @override
+ bool operator ==(other) {
+ if (other is DocumentSymbolParams) {
+ return textDocument == other.textDocument && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, textDocument.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
-abstract class ErrorCodes {
- static const InternalError = -32603;
- static const InvalidParams = -32602;
- static const InvalidRequest = -32600;
- static const MethodNotFound = -32601;
- static const ParseError = -32700;
- static const RequestCancelled = -32800;
- static const ServerNotInitialized = -32002;
- static const UnknownErrorCode = -32001;
- static const serverErrorEnd = -32000;
- static const serverErrorStart = -32099;
+class ErrorCodes {
+ const ErrorCodes(this._value);
+ const ErrorCodes.fromJson(this._value);
+
+ final num _value;
+
+ static bool canParse(Object obj) {
+ return obj is num;
+ }
+
+ /// Defined by JSON RPC
+ static const ParseError = const ErrorCodes(-32700);
+ static const InvalidRequest = const ErrorCodes(-32600);
+ static const MethodNotFound = const ErrorCodes(-32601);
+ static const InvalidParams = const ErrorCodes(-32602);
+ static const InternalError = const ErrorCodes(-32603);
+ static const serverErrorStart = const ErrorCodes(-32099);
+ static const serverErrorEnd = const ErrorCodes(-32000);
+ static const ServerNotInitialized = const ErrorCodes(-32002);
+ static const UnknownErrorCode = const ErrorCodes(-32001);
+
+ /// Defined by the protocol.
+ static const RequestCancelled = const ErrorCodes(-32800);
+
+ Object toJson() => _value;
+
+ @override
+ String toString() => _value.toString();
+
+ @override
+ get hashCode => _value.hashCode;
+
+ bool operator ==(o) => o is ErrorCodes && o._value == _value;
}
/// Execute command options.
@@ -2702,7 +3949,7 @@
throw 'commands is required but was not provided';
}
}
- factory ExecuteCommandOptions.fromJson(Map<String, dynamic> json) {
+ static ExecuteCommandOptions fromJson(Map<String, dynamic> json) {
final commands =
json['commands']?.map((item) => item)?.cast<String>()?.toList();
return new ExecuteCommandOptions(commands);
@@ -2725,6 +3972,26 @@
(obj['commands'].length == 0 ||
obj['commands'].every((item) => item is String)));
}
+
+ @override
+ bool operator ==(other) {
+ if (other is ExecuteCommandOptions) {
+ return listEqual(
+ commands, other.commands, (String a, String b) => a == b) &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, commands.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class ExecuteCommandParams implements ToJsonable {
@@ -2733,7 +4000,7 @@
throw 'command is required but was not provided';
}
}
- factory ExecuteCommandParams.fromJson(Map<String, dynamic> json) {
+ static ExecuteCommandParams fromJson(Map<String, dynamic> json) {
final command = json['command'];
final arguments =
json['arguments']?.map((item) => item)?.cast<dynamic>()?.toList();
@@ -2761,6 +4028,28 @@
obj.containsKey('command') &&
obj['command'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is ExecuteCommandParams) {
+ return command == other.command &&
+ listEqual(
+ arguments, other.arguments, (dynamic a, dynamic b) => a == b) &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, command.hashCode);
+ hash = JenkinsSmiHash.combine(hash, arguments.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// Execute command registration options.
@@ -2770,8 +4059,7 @@
throw 'commands is required but was not provided';
}
}
- factory ExecuteCommandRegistrationOptions.fromJson(
- Map<String, dynamic> json) {
+ static ExecuteCommandRegistrationOptions fromJson(Map<String, dynamic> json) {
final commands =
json['commands']?.map((item) => item)?.cast<String>()?.toList();
return new ExecuteCommandRegistrationOptions(commands);
@@ -2794,13 +4082,33 @@
(obj['commands'].length == 0 ||
obj['commands'].every((item) => item is String)));
}
+
+ @override
+ bool operator ==(other) {
+ if (other is ExecuteCommandRegistrationOptions) {
+ return listEqual(
+ commands, other.commands, (String a, String b) => a == b) &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, commands.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class FailureHandlingKind {
const FailureHandlingKind._(this._value);
const FailureHandlingKind.fromJson(this._value);
- final Object _value;
+ final String _value;
static bool canParse(Object obj) {
switch (obj) {
@@ -2813,25 +4121,23 @@
return false;
}
- /// Applying the workspace change is simply aborted if one of the
- /// changes provided fails. All operations executed before the
- /// failing operation stay executed.
+ /// Applying the workspace change is simply aborted if one of the changes
+ /// provided fails. All operations executed before the failing operation stay
+ /// executed.
static const Abort = const FailureHandlingKind._('abort');
- /// All operations are executed transactional. That means they
- /// either all succeed or no changes at all are applied to the
- /// workspace.
+ /// All operations are executed transactional. That means they either all
+ /// succeed or no changes at all are applied to the workspace.
static const Transactional = const FailureHandlingKind._('transactional');
- /// If the workspace edit contains only textual file changes they
- /// are executed transactional. If resource changes (create, rename
- /// or delete file) are part of the change the failure handling
- /// startegy is abort.
+ /// If the workspace edit contains only textual file changes they are executed
+ /// transactional. If resource changes (create, rename or delete file) are
+ /// part of the change the failure handling strategy is abort.
static const TextOnlyTransactional =
const FailureHandlingKind._('textOnlyTransactional');
- /// The client tries to undo the operations already executed. But
- /// there is no guaruntee that this is succeeding.
+ /// The client tries to undo the operations already executed. But there is no
+ /// guarantee that this is succeeding.
static const Undo = const FailureHandlingKind._('undo');
Object toJson() => _value;
@@ -2850,7 +4156,7 @@
const FileChangeType._(this._value);
const FileChangeType.fromJson(this._value);
- final Object _value;
+ final num _value;
static bool canParse(Object obj) {
switch (obj) {
@@ -2892,7 +4198,7 @@
throw 'type is required but was not provided';
}
}
- factory FileEvent.fromJson(Map<String, dynamic> json) {
+ static FileEvent fromJson(Map<String, dynamic> json) {
final uri = json['uri'];
final type = json['type'];
return new FileEvent(uri, type);
@@ -2918,6 +4224,25 @@
obj.containsKey('type') &&
obj['type'] is num;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is FileEvent) {
+ return uri == other.uri && type == other.type && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, uri.hashCode);
+ hash = JenkinsSmiHash.combine(hash, type.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class FileSystemWatcher implements ToJsonable {
@@ -2926,19 +4251,17 @@
throw 'globPattern is required but was not provided';
}
}
- factory FileSystemWatcher.fromJson(Map<String, dynamic> json) {
+ static FileSystemWatcher fromJson(Map<String, dynamic> json) {
final globPattern = json['globPattern'];
- final kind =
- json['kind'] != null ? new WatchKind.fromJson(json['kind']) : null;
+ final kind = json['kind'] != null ? WatchKind.fromJson(json['kind']) : null;
return new FileSystemWatcher(globPattern, kind);
}
/// The glob pattern to watch
final String globPattern;
- /// The kind of events of interest. If omitted it defaults to
- /// WatchKind.Create | WatchKind.Change | WatchKind.Delete which
- /// is 7.
+ /// The kind of events of interest. If omitted it defaults to WatchKind.Create
+ /// | WatchKind.Change | WatchKind.Delete which is 7.
final WatchKind kind;
Map<String, dynamic> toJson() {
@@ -2956,6 +4279,25 @@
obj.containsKey('globPattern') &&
obj['globPattern'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is FileSystemWatcher) {
+ return globPattern == other.globPattern && kind == other.kind && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, globPattern.hashCode);
+ hash = JenkinsSmiHash.combine(hash, kind.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// Represents a folding range.
@@ -2969,34 +4311,32 @@
throw 'endLine is required but was not provided';
}
}
- factory FoldingRange.fromJson(Map<String, dynamic> json) {
+ static FoldingRange fromJson(Map<String, dynamic> json) {
final startLine = json['startLine'];
final startCharacter = json['startCharacter'];
final endLine = json['endLine'];
final endCharacter = json['endCharacter'];
- final kind = json['kind'] != null
- ? new FoldingRangeKind.fromJson(json['kind'])
- : null;
+ final kind =
+ json['kind'] != null ? FoldingRangeKind.fromJson(json['kind']) : null;
return new FoldingRange(
startLine, startCharacter, endLine, endCharacter, kind);
}
- /// The zero-based character offset before the folded range ends.
- /// If not defined, defaults to the length of the end line.
+ /// The zero-based character offset before the folded range ends. If not
+ /// defined, defaults to the length of the end line.
final num endCharacter;
/// The zero-based line number where the folded range ends.
final num endLine;
- /// Describes the kind of the folding range such as `comment' or
- /// 'region'. The kind is used to categorize folding ranges and
- /// used by commands like 'Fold all comments'. See
- /// [FoldingRangeKind] for an enumeration of standardized kinds.
+ /// Describes the kind of the folding range such as `comment' or 'region'. The
+ /// kind is used to categorize folding ranges and used by commands like 'Fold
+ /// all comments'. See [FoldingRangeKind] for an enumeration of standardized
+ /// kinds.
final FoldingRangeKind kind;
- /// The zero-based character offset from where the folded range
- /// starts. If not defined, defaults to the length of the start
- /// line.
+ /// The zero-based character offset from where the folded range starts. If not
+ /// defined, defaults to the length of the start line.
final num startCharacter;
/// The zero-based line number from where the folded range starts.
@@ -3027,6 +4367,33 @@
obj.containsKey('endLine') &&
obj['endLine'] is num;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is FoldingRange) {
+ return startLine == other.startLine &&
+ startCharacter == other.startCharacter &&
+ endLine == other.endLine &&
+ endCharacter == other.endCharacter &&
+ kind == other.kind &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, startLine.hashCode);
+ hash = JenkinsSmiHash.combine(hash, startCharacter.hashCode);
+ hash = JenkinsSmiHash.combine(hash, endLine.hashCode);
+ hash = JenkinsSmiHash.combine(hash, endCharacter.hashCode);
+ hash = JenkinsSmiHash.combine(hash, kind.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// Enum of known range kinds
@@ -3034,26 +4401,26 @@
const FoldingRangeKind._(this._value);
const FoldingRangeKind.fromJson(this._value);
- final Object _value;
+ final String _value;
static bool canParse(Object obj) {
switch (obj) {
- case 'comment':
- case 'imports':
- case 'region':
+ case r'comment':
+ case r'imports':
+ case r'region':
return true;
}
return false;
}
/// Folding range for a comment
- static const Comment = const FoldingRangeKind._('comment');
+ static const Comment = const FoldingRangeKind._(r'comment');
/// Folding range for a imports or includes
- static const Imports = const FoldingRangeKind._('imports');
+ static const Imports = const FoldingRangeKind._(r'imports');
/// Folding range for a region (e.g. `#region`)
- static const Region = const FoldingRangeKind._('region');
+ static const Region = const FoldingRangeKind._(r'region');
Object toJson() => _value;
@@ -3072,9 +4439,9 @@
throw 'textDocument is required but was not provided';
}
}
- factory FoldingRangeParams.fromJson(Map<String, dynamic> json) {
+ static FoldingRangeParams fromJson(Map<String, dynamic> json) {
final textDocument = json['textDocument'] != null
- ? new TextDocumentIdentifier.fromJson(json['textDocument'])
+ ? TextDocumentIdentifier.fromJson(json['textDocument'])
: null;
return new FoldingRangeParams(textDocument);
}
@@ -3094,10 +4461,32 @@
obj.containsKey('textDocument') &&
TextDocumentIdentifier.canParse(obj['textDocument']);
}
+
+ @override
+ bool operator ==(other) {
+ if (other is FoldingRangeParams) {
+ return textDocument == other.textDocument && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, textDocument.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// Folding range provider options.
class FoldingRangeProviderOptions implements ToJsonable {
+ static FoldingRangeProviderOptions fromJson(Map<String, dynamic> json) {
+ return new FoldingRangeProviderOptions();
+ }
+
Map<String, dynamic> toJson() {
Map<String, dynamic> __result = {};
return __result;
@@ -3106,6 +4495,23 @@
static bool canParse(Object obj) {
return obj is Map<String, dynamic>;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is FoldingRangeProviderOptions) {
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// Value-object describing what options formatting should use.
@@ -3118,7 +4524,7 @@
throw 'insertSpaces is required but was not provided';
}
}
- factory FormattingOptions.fromJson(Map<String, dynamic> json) {
+ static FormattingOptions fromJson(Map<String, dynamic> json) {
final tabSize = json['tabSize'];
final insertSpaces = json['insertSpaces'];
return new FormattingOptions(tabSize, insertSpaces);
@@ -3146,6 +4552,27 @@
obj.containsKey('insertSpaces') &&
obj['insertSpaces'] is bool;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is FormattingOptions) {
+ return tabSize == other.tabSize &&
+ insertSpaces == other.insertSpaces &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, tabSize.hashCode);
+ hash = JenkinsSmiHash.combine(hash, insertSpaces.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// The result of a hover request.
@@ -3155,38 +4582,23 @@
throw 'contents is required but was not provided';
}
}
- factory Hover.fromJson(Map<String, dynamic> json) {
- final contents = MarkedString.canParse(json['contents'])
- ? new Either3<MarkedString, List<MarkedString>, MarkupContent>.t1(
- json['contents'] != null
- ? new MarkedString.fromJson(json['contents'])
+ static Hover fromJson(Map<String, dynamic> json) {
+ final contents = json['contents'] is String
+ ? new Either2<String, MarkupContent>.t1(json['contents'])
+ : (MarkupContent.canParse(json['contents'])
+ ? new Either2<String, MarkupContent>.t2(json['contents'] != null
+ ? MarkupContent.fromJson(json['contents'])
: null)
- : ((json['contents'] is List &&
- (json['contents'].length == 0 ||
- json['contents']
- .every((item) => MarkedString.canParse(item))))
- ? new Either3<MarkedString, List<MarkedString>, MarkupContent>.t2(json['contents']
- ?.map((item) =>
- item != null ? new MarkedString.fromJson(item) : null)
- ?.cast<MarkedString>()
- ?.toList())
- : (MarkupContent.canParse(json['contents'])
- ? new Either3<MarkedString, List<MarkedString>, MarkupContent>.t3(
- json['contents'] != null
- ? new MarkupContent.fromJson(json['contents'])
- : null)
- : (throw '''${json['contents']} was not one of (MarkedString, MarkedString[], MarkupContent)''')));
- final range =
- json['range'] != null ? new Range.fromJson(json['range']) : null;
+ : (throw '''${json['contents']} was not one of (String, MarkupContent)'''));
+ final range = json['range'] != null ? Range.fromJson(json['range']) : null;
return new Hover(contents, range);
}
/// The hover's content
- final Either3<MarkedString, List<MarkedString>, MarkupContent> contents;
+ final Either2<String, MarkupContent> contents;
- /// An optional range is a range inside a text document that is
- /// used to visualize a hover, e.g. by changing the background
- /// color.
+ /// An optional range is a range inside a text document that is used to
+ /// visualize a hover, e.g. by changing the background color.
final Range range;
Map<String, dynamic> toJson() {
@@ -3202,37 +4614,57 @@
static bool canParse(Object obj) {
return obj is Map<String, dynamic> &&
obj.containsKey('contents') &&
- (MarkedString.canParse(obj['contents']) ||
- (obj['contents'] is List &&
- (obj['contents'].length == 0 ||
- obj['contents']
- .every((item) => MarkedString.canParse(item)))) ||
- MarkupContent.canParse(obj['contents']));
+ (obj['contents'] is String || MarkupContent.canParse(obj['contents']));
}
+
+ @override
+ bool operator ==(other) {
+ if (other is Hover) {
+ return contents == other.contents && range == other.range && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, contents.hashCode);
+ hash = JenkinsSmiHash.combine(hash, range.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class InitializeParams implements ToJsonable {
- InitializeParams(this.processId, this.rootPath, this.rootUri,
- this.initializationOptions, this.capabilities, this.workspaceFolders) {
+ InitializeParams(
+ this.processId,
+ this.rootPath,
+ this.rootUri,
+ this.initializationOptions,
+ this.capabilities,
+ this.trace,
+ this.workspaceFolders) {
if (capabilities == null) {
throw 'capabilities is required but was not provided';
}
}
- factory InitializeParams.fromJson(Map<String, dynamic> json) {
+ static InitializeParams fromJson(Map<String, dynamic> json) {
final processId = json['processId'];
final rootPath = json['rootPath'];
final rootUri = json['rootUri'];
final initializationOptions = json['initializationOptions'];
final capabilities = json['capabilities'] != null
- ? new ClientCapabilities.fromJson(json['capabilities'])
+ ? ClientCapabilities.fromJson(json['capabilities'])
: null;
+ final trace = json['trace'];
final workspaceFolders = json['workspaceFolders']
- ?.map(
- (item) => item != null ? new WorkspaceFolder.fromJson(item) : null)
+ ?.map((item) => item != null ? WorkspaceFolder.fromJson(item) : null)
?.cast<WorkspaceFolder>()
?.toList();
return new InitializeParams(processId, rootPath, rootUri,
- initializationOptions, capabilities, workspaceFolders);
+ initializationOptions, capabilities, trace, workspaceFolders);
}
/// The capabilities provided by the client (editor or tool)
@@ -3241,10 +4673,10 @@
/// User provided initialization options.
final dynamic initializationOptions;
- /// The process Id of the parent process that started the
- /// server. Is null if the process has not been started by
- /// another process. If the parent process is not alive then the
- /// server should exit (see exit notification) its process.
+ /// The process Id of the parent process that started the server. Is null if
+ /// the process has not been started by another process. If the parent process
+ /// is not alive then the server should exit (see exit notification) its
+ /// process.
final num processId;
/// The rootPath of the workspace. Is null if no folder is open.
@@ -3252,14 +4684,17 @@
@core.deprecated
final String rootPath;
- /// The rootUri of the workspace. Is null if no folder is open.
- /// If both `rootPath` and `rootUri` are set `rootUri` wins.
+ /// The rootUri of the workspace. Is null if no folder is open. If both
+ /// `rootPath` and `rootUri` are set `rootUri` wins.
final String rootUri;
- /// The workspace folders configured in the client when the
- /// server starts. This property is only available if the client
- /// supports workspace folders. It can be `null` if the client
- /// supports workspace folders but none are configured.
+ /// The initial trace setting. If omitted trace is disabled ('off').
+ final String trace;
+
+ /// The workspace folders configured in the client when the server starts.
+ /// This property is only available if the client supports workspace folders.
+ /// It can be `null` if the client supports workspace folders but none are
+ /// configured.
///
/// Since 3.6.0
final List<WorkspaceFolder> workspaceFolders;
@@ -3267,9 +4702,7 @@
Map<String, dynamic> toJson() {
Map<String, dynamic> __result = {};
__result['processId'] = processId;
- // ignore: deprecated_member_use
if (rootPath != null) {
- // ignore: deprecated_member_use
__result['rootPath'] = rootPath;
}
__result['rootUri'] = rootUri;
@@ -3278,6 +4711,9 @@
}
__result['capabilities'] =
capabilities ?? (throw 'capabilities is required but was not set');
+ if (trace != null) {
+ __result['trace'] = trace;
+ }
if (workspaceFolders != null) {
__result['workspaceFolders'] = workspaceFolders;
}
@@ -3293,6 +4729,38 @@
obj.containsKey('capabilities') &&
ClientCapabilities.canParse(obj['capabilities']);
}
+
+ @override
+ bool operator ==(other) {
+ if (other is InitializeParams) {
+ return processId == other.processId &&
+ rootPath == other.rootPath &&
+ rootUri == other.rootUri &&
+ initializationOptions == other.initializationOptions &&
+ capabilities == other.capabilities &&
+ trace == other.trace &&
+ listEqual(workspaceFolders, other.workspaceFolders,
+ (WorkspaceFolder a, WorkspaceFolder b) => a == b) &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, processId.hashCode);
+ hash = JenkinsSmiHash.combine(hash, rootPath.hashCode);
+ hash = JenkinsSmiHash.combine(hash, rootUri.hashCode);
+ hash = JenkinsSmiHash.combine(hash, initializationOptions.hashCode);
+ hash = JenkinsSmiHash.combine(hash, capabilities.hashCode);
+ hash = JenkinsSmiHash.combine(hash, trace.hashCode);
+ hash = JenkinsSmiHash.combine(hash, workspaceFolders.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class InitializeResult implements ToJsonable {
@@ -3301,9 +4769,9 @@
throw 'capabilities is required but was not provided';
}
}
- factory InitializeResult.fromJson(Map<String, dynamic> json) {
+ static InitializeResult fromJson(Map<String, dynamic> json) {
final capabilities = json['capabilities'] != null
- ? new ServerCapabilities.fromJson(json['capabilities'])
+ ? ServerCapabilities.fromJson(json['capabilities'])
: null;
return new InitializeResult(capabilities);
}
@@ -3323,9 +4791,31 @@
obj.containsKey('capabilities') &&
ServerCapabilities.canParse(obj['capabilities']);
}
+
+ @override
+ bool operator ==(other) {
+ if (other is InitializeResult) {
+ return capabilities == other.capabilities && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, capabilities.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class InitializedParams implements ToJsonable {
+ static InitializedParams fromJson(Map<String, dynamic> json) {
+ return new InitializedParams();
+ }
+
Map<String, dynamic> toJson() {
Map<String, dynamic> __result = {};
return __result;
@@ -3334,15 +4824,32 @@
static bool canParse(Object obj) {
return obj is Map<String, dynamic>;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is InitializedParams) {
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
-/// Defines whether the insert text in a completion item should be
-/// interpreted as plain text or a snippet.
+/// Defines whether the insert text in a completion item should be interpreted
+/// as plain text or a snippet.
class InsertTextFormat {
const InsertTextFormat._(this._value);
const InsertTextFormat.fromJson(this._value);
- final Object _value;
+ final num _value;
static bool canParse(Object obj) {
switch (obj) {
@@ -3353,17 +4860,15 @@
return false;
}
- /// The primary text to be inserted is treated as a plain
- /// string.
+ /// The primary text to be inserted is treated as a plain string.
static const PlainText = const InsertTextFormat._(1);
/// The primary text to be inserted is treated as a snippet.
///
- /// A snippet can define tab stops and placeholders with `$1`,
- /// `$2` and `${3:foo}`. `$0` defines the final tab stop, it
- /// defaults to the end of the snippet. Placeholders with
- /// equal identifiers are linked, that is typing in one will
- /// update others too.
+ /// A snippet can define tab stops and placeholders with `$1`, `$2` and
+ /// `${3:foo}`. `$0` defines the final tab stop, it defaults to the end of the
+ /// snippet. Placeholders with equal identifiers are linked, that is typing in
+ /// one will update others too.
static const Snippet = const InsertTextFormat._(2);
Object toJson() => _value;
@@ -3386,10 +4891,9 @@
throw 'range is required but was not provided';
}
}
- factory Location.fromJson(Map<String, dynamic> json) {
+ static Location fromJson(Map<String, dynamic> json) {
final uri = json['uri'];
- final range =
- json['range'] != null ? new Range.fromJson(json['range']) : null;
+ final range = json['range'] != null ? Range.fromJson(json['range']) : null;
return new Location(uri, range);
}
@@ -3410,6 +4914,25 @@
obj.containsKey('range') &&
Range.canParse(obj['range']);
}
+
+ @override
+ bool operator ==(other) {
+ if (other is Location) {
+ return uri == other.uri && range == other.range && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, uri.hashCode);
+ hash = JenkinsSmiHash.combine(hash, range.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class LogMessageParams implements ToJsonable {
@@ -3421,9 +4944,9 @@
throw 'message is required but was not provided';
}
}
- factory LogMessageParams.fromJson(Map<String, dynamic> json) {
+ static LogMessageParams fromJson(Map<String, dynamic> json) {
final type =
- json['type'] != null ? new MessageType.fromJson(json['type']) : null;
+ json['type'] != null ? MessageType.fromJson(json['type']) : null;
final message = json['message'];
return new LogMessageParams(type, message);
}
@@ -3449,55 +4972,37 @@
obj.containsKey('message') &&
obj['message'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is LogMessageParams) {
+ return type == other.type && message == other.message && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, type.hashCode);
+ hash = JenkinsSmiHash.combine(hash, message.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
-class MarkedString implements ToJsonable {
- MarkedString(this.language, this.value) {
- if (language == null) {
- throw 'language is required but was not provided';
- }
- if (value == null) {
- throw 'value is required but was not provided';
- }
- }
- factory MarkedString.fromJson(Map<String, dynamic> json) {
- final language = json['language'];
- final value = json['value'];
- return new MarkedString(language, value);
- }
-
- final String language;
- final String value;
-
- Map<String, dynamic> toJson() {
- Map<String, dynamic> __result = {};
- __result['language'] =
- language ?? (throw 'language is required but was not set');
- __result['value'] = value ?? (throw 'value is required but was not set');
- return __result;
- }
-
- static bool canParse(Object obj) {
- return obj is Map<String, dynamic> &&
- obj.containsKey('language') &&
- obj['language'] is String &&
- obj.containsKey('value') &&
- obj['value'] is String;
- }
-}
-
-/// A `MarkupContent` literal represents a string value which
-/// content is interpreted base on its kind flag. Currently the
-/// protocol supports `plaintext` and `markdown` as markup
-/// kinds.
+/// A `MarkupContent` literal represents a string value which content is
+/// interpreted base on its kind flag. Currently the protocol supports
+/// `plaintext` and `markdown` as markup kinds.
///
-/// If the kind is `markdown` then the value can contain fenced
-/// code blocks like in GitHub issues. See
+/// If the kind is `markdown` then the value can contain fenced code blocks like
+/// in GitHub issues. See
/// https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting
///
-/// Here is an example how such a string can be constructed
-/// using JavaScript / TypeScript: ```ts let markdown:
-/// MarkdownContent = {
+/// Here is an example how such a string can be constructed using JavaScript /
+/// TypeScript: ```ts let markdown: MarkdownContent = {
///
/// kind: MarkupKind.Markdown,
/// value: [
@@ -3508,9 +5013,8 @@
/// '```'
/// ].join('\n') }; ```
///
-/// *Please Note* that clients might sanitize the return
-/// markdown. A client could decide to remove HTML from the
-/// markdown to avoid script execution.
+/// *Please Note* that clients might sanitize the return markdown. A client
+/// could decide to remove HTML from the markdown to avoid script execution.
class MarkupContent implements ToJsonable {
MarkupContent(this.kind, this.value) {
if (kind == null) {
@@ -3520,9 +5024,9 @@
throw 'value is required but was not provided';
}
}
- factory MarkupContent.fromJson(Map<String, dynamic> json) {
+ static MarkupContent fromJson(Map<String, dynamic> json) {
final kind =
- json['kind'] != null ? new MarkupKind.fromJson(json['kind']) : null;
+ json['kind'] != null ? MarkupKind.fromJson(json['kind']) : null;
final value = json['value'];
return new MarkupContent(kind, value);
}
@@ -3543,38 +5047,56 @@
static bool canParse(Object obj) {
return obj is Map<String, dynamic> &&
obj.containsKey('kind') &&
- MarkupKind.canParse(obj['kind']) &&
+ obj['kind'] is String &&
obj.containsKey('value') &&
obj['value'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is MarkupContent) {
+ return kind == other.kind && value == other.value && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, kind.hashCode);
+ hash = JenkinsSmiHash.combine(hash, value.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
-/// Describes the content type that a client supports in various
-/// result literals like `Hover`, `ParameterInfo` or
-/// `CompletionItem`.
+/// Describes the content type that a client supports in various result literals
+/// like `Hover`, `ParameterInfo` or `CompletionItem`.
///
-/// Please note that `MarkupKinds` must not start with a `$`.
-/// This kinds are reserved for internal usage.
+/// Please note that `MarkupKinds` must not start with a `$`. This kinds are
+/// reserved for internal usage.
class MarkupKind {
const MarkupKind._(this._value);
const MarkupKind.fromJson(this._value);
- final Object _value;
+ final String _value;
static bool canParse(Object obj) {
switch (obj) {
- case 'plaintext':
- case 'markdown':
+ case r'plaintext':
+ case r'markdown':
return true;
}
return false;
}
/// Plain text is supported as a content format
- static const PlainText = const MarkupKind._('plaintext');
+ static const PlainText = const MarkupKind._(r'plaintext');
/// Markdown is supported as a content format
- static const Markdown = const MarkupKind._('markdown');
+ static const Markdown = const MarkupKind._(r'markdown');
Object toJson() => _value;
@@ -3593,7 +5115,7 @@
throw 'jsonrpc is required but was not provided';
}
}
- factory Message.fromJson(Map<String, dynamic> json) {
+ static Message fromJson(Map<String, dynamic> json) {
final jsonrpc = json['jsonrpc'];
return new Message(jsonrpc);
}
@@ -3612,6 +5134,24 @@
obj.containsKey('jsonrpc') &&
obj['jsonrpc'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is Message) {
+ return jsonrpc == other.jsonrpc && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, jsonrpc.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class MessageActionItem implements ToJsonable {
@@ -3620,7 +5160,7 @@
throw 'title is required but was not provided';
}
}
- factory MessageActionItem.fromJson(Map<String, dynamic> json) {
+ static MessageActionItem fromJson(Map<String, dynamic> json) {
final title = json['title'];
return new MessageActionItem(title);
}
@@ -3639,13 +5179,31 @@
obj.containsKey('title') &&
obj['title'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is MessageActionItem) {
+ return title == other.title && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, title.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class MessageType {
const MessageType._(this._value);
const MessageType.fromJson(this._value);
- final Object _value;
+ final num _value;
static bool canParse(Object obj) {
switch (obj) {
@@ -3681,7 +5239,214 @@
bool operator ==(o) => o is MessageType && o._value == _value;
}
-class NotificationMessage implements Message, ToJsonable {
+/// Valid LSP methods known at the time of code generation from the spec.
+class Method {
+ const Method._(this._value);
+ const Method.fromJson(this._value);
+
+ final String _value;
+
+ static bool canParse(Object obj) {
+ switch (obj) {
+ case r'$/cancelRequest':
+ case r'initialize':
+ case r'initialized':
+ case r'shutdown':
+ case r'exit':
+ case r'window/showMessage':
+ case r'window/showMessageRequest':
+ case r'window/logMessage':
+ case r'telemetry/event':
+ case r'client/registerCapability':
+ case r'client/unregisterCapability':
+ case r'workspace/didChangeWatchedFiles':
+ case r'workspace/symbol':
+ case r'workspace/executeCommand':
+ case r'workspace/applyEdit':
+ case r'textDocument/didOpen':
+ case r'textDocument/didChange':
+ case r'textDocument/willSave':
+ case r'textDocument/willSaveWaitUntil':
+ case r'textDocument/didClose':
+ case r'textDocument/publishDiagnostics':
+ case r'textDocument/completion':
+ case r'completionItem/resolve':
+ case r'textDocument/hover':
+ case r'textDocument/signatureHelp':
+ case r'textDocument/definition':
+ case r'textDocument/typeDefinition':
+ case r'textDocument/implementation':
+ case r'textDocument/references':
+ case r'textDocument/documentHighlight':
+ case r'textDocument/documentSymbol':
+ case r'textDocument/codeAction':
+ case r'textDocument/codeLens':
+ case r'codeLens/resolve':
+ case r'textDocument/documentLink':
+ case r'documentLink/resolve':
+ case r'textDocument/formatting':
+ case r'textDocument/onTypeFormatting':
+ case r'textDocument/rename':
+ case r'textDocument/prepareRename':
+ return true;
+ }
+ return false;
+ }
+
+ /// Constant for the '$/cancelRequest' method.
+ static const cancelRequest = const Method._(r'$/cancelRequest');
+
+ /// Constant for the 'initialize' method.
+ static const initialize = const Method._(r'initialize');
+
+ /// Constant for the 'initialized' method.
+ static const initialized = const Method._(r'initialized');
+
+ /// Constant for the 'shutdown' method.
+ static const shutdown = const Method._(r'shutdown');
+
+ /// Constant for the 'exit' method.
+ static const exit = const Method._(r'exit');
+
+ /// Constant for the 'window/showMessage' method.
+ static const window_showMessage = const Method._(r'window/showMessage');
+
+ /// Constant for the 'window/showMessageRequest' method.
+ static const window_showMessageRequest =
+ const Method._(r'window/showMessageRequest');
+
+ /// Constant for the 'window/logMessage' method.
+ static const window_logMessage = const Method._(r'window/logMessage');
+
+ /// Constant for the 'telemetry/event' method.
+ static const telemetry_event = const Method._(r'telemetry/event');
+
+ /// Constant for the 'client/registerCapability' method.
+ static const client_registerCapability =
+ const Method._(r'client/registerCapability');
+
+ /// Constant for the 'client/unregisterCapability' method.
+ static const client_unregisterCapability =
+ const Method._(r'client/unregisterCapability');
+
+ /// Constant for the 'workspace/didChangeWatchedFiles' method.
+ static const workspace_didChangeWatchedFiles =
+ const Method._(r'workspace/didChangeWatchedFiles');
+
+ /// Constant for the 'workspace/symbol' method.
+ static const workspace_symbol = const Method._(r'workspace/symbol');
+
+ /// Constant for the 'workspace/executeCommand' method.
+ static const workspace_executeCommand =
+ const Method._(r'workspace/executeCommand');
+
+ /// Constant for the 'workspace/applyEdit' method.
+ static const workspace_applyEdit = const Method._(r'workspace/applyEdit');
+
+ /// Constant for the 'textDocument/didOpen' method.
+ static const textDocument_didOpen = const Method._(r'textDocument/didOpen');
+
+ /// Constant for the 'textDocument/didChange' method.
+ static const textDocument_didChange =
+ const Method._(r'textDocument/didChange');
+
+ /// Constant for the 'textDocument/willSave' method.
+ static const textDocument_willSave = const Method._(r'textDocument/willSave');
+
+ /// Constant for the 'textDocument/willSaveWaitUntil' method.
+ static const textDocument_willSaveWaitUntil =
+ const Method._(r'textDocument/willSaveWaitUntil');
+
+ /// Constant for the 'textDocument/didClose' method.
+ static const textDocument_didClose = const Method._(r'textDocument/didClose');
+
+ /// Constant for the 'textDocument/publishDiagnostics' method.
+ static const textDocument_publishDiagnostics =
+ const Method._(r'textDocument/publishDiagnostics');
+
+ /// Constant for the 'textDocument/completion' method.
+ static const textDocument_completion =
+ const Method._(r'textDocument/completion');
+
+ /// Constant for the 'completionItem/resolve' method.
+ static const completionItem_resolve =
+ const Method._(r'completionItem/resolve');
+
+ /// Constant for the 'textDocument/hover' method.
+ static const textDocument_hover = const Method._(r'textDocument/hover');
+
+ /// Constant for the 'textDocument/signatureHelp' method.
+ static const textDocument_signatureHelp =
+ const Method._(r'textDocument/signatureHelp');
+
+ /// Constant for the 'textDocument/definition' method.
+ static const textDocument_definition =
+ const Method._(r'textDocument/definition');
+
+ /// Constant for the 'textDocument/typeDefinition' method.
+ static const textDocument_typeDefinition =
+ const Method._(r'textDocument/typeDefinition');
+
+ /// Constant for the 'textDocument/implementation' method.
+ static const textDocument_implementation =
+ const Method._(r'textDocument/implementation');
+
+ /// Constant for the 'textDocument/references' method.
+ static const textDocument_references =
+ const Method._(r'textDocument/references');
+
+ /// Constant for the 'textDocument/documentHighlight' method.
+ static const textDocument_documentHighlight =
+ const Method._(r'textDocument/documentHighlight');
+
+ /// Constant for the 'textDocument/documentSymbol' method.
+ static const textDocument_documentSymbol =
+ const Method._(r'textDocument/documentSymbol');
+
+ /// Constant for the 'textDocument/codeAction' method.
+ static const textDocument_codeAction =
+ const Method._(r'textDocument/codeAction');
+
+ /// Constant for the 'textDocument/codeLens' method.
+ static const textDocument_codeLens = const Method._(r'textDocument/codeLens');
+
+ /// Constant for the 'codeLens/resolve' method.
+ static const codeLens_resolve = const Method._(r'codeLens/resolve');
+
+ /// Constant for the 'textDocument/documentLink' method.
+ static const textDocument_documentLink =
+ const Method._(r'textDocument/documentLink');
+
+ /// Constant for the 'documentLink/resolve' method.
+ static const documentLink_resolve = const Method._(r'documentLink/resolve');
+
+ /// Constant for the 'textDocument/formatting' method.
+ static const textDocument_formatting =
+ const Method._(r'textDocument/formatting');
+
+ /// Constant for the 'textDocument/onTypeFormatting' method.
+ static const textDocument_onTypeFormatting =
+ const Method._(r'textDocument/onTypeFormatting');
+
+ /// Constant for the 'textDocument/rename' method.
+ static const textDocument_rename = const Method._(r'textDocument/rename');
+
+ /// Constant for the 'textDocument/prepareRename' method.
+ static const textDocument_prepareRename =
+ const Method._(r'textDocument/prepareRename');
+
+ Object toJson() => _value;
+
+ @override
+ String toString() => _value.toString();
+
+ @override
+ get hashCode => _value.hashCode;
+
+ bool operator ==(o) => o is Method && o._value == _value;
+}
+
+class NotificationMessage implements Message, IncomingMessage, ToJsonable {
NotificationMessage(this.method, this.params, this.jsonrpc) {
if (method == null) {
throw 'method is required but was not provided';
@@ -3690,14 +5455,10 @@
throw 'jsonrpc is required but was not provided';
}
}
- factory NotificationMessage.fromJson(Map<String, dynamic> json) {
- final method = json['method'];
- final params = (json['params'] is List &&
- (json['params'].length == 0 ||
- json['params'].every((item) => true)))
- ? new Either2<List<dynamic>, dynamic>.t1(
- json['params']?.map((item) => item)?.cast<dynamic>()?.toList())
- : (new Either2<List<dynamic>, dynamic>.t2(json['params']));
+ static NotificationMessage fromJson(Map<String, dynamic> json) {
+ final method =
+ json['method'] != null ? Method.fromJson(json['method']) : null;
+ final params = json['params'];
final jsonrpc = json['jsonrpc'];
return new NotificationMessage(method, params, jsonrpc);
}
@@ -3705,10 +5466,10 @@
final String jsonrpc;
/// The method to be invoked.
- final String method;
+ final Method method;
/// The notification's params.
- final Either2<List<dynamic>, dynamic> params;
+ final dynamic params;
Map<String, dynamic> toJson() {
Map<String, dynamic> __result = {};
@@ -3724,35 +5485,60 @@
static bool canParse(Object obj) {
return obj is Map<String, dynamic> &&
obj.containsKey('method') &&
- obj['method'] is String &&
+ Method.canParse(obj['method']) &&
obj.containsKey('jsonrpc') &&
obj['jsonrpc'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is NotificationMessage) {
+ return method == other.method &&
+ params == other.params &&
+ jsonrpc == other.jsonrpc &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, method.hashCode);
+ hash = JenkinsSmiHash.combine(hash, params.hashCode);
+ hash = JenkinsSmiHash.combine(hash, jsonrpc.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
-/// Represents a parameter of a callable-signature. A
-/// parameter can have a label and a doc-comment.
+/// Represents a parameter of a callable-signature. A parameter can have a label
+/// and a doc-comment.
class ParameterInformation implements ToJsonable {
ParameterInformation(this.label, this.documentation) {
if (label == null) {
throw 'label is required but was not provided';
}
}
- factory ParameterInformation.fromJson(Map<String, dynamic> json) {
+ static ParameterInformation fromJson(Map<String, dynamic> json) {
final label = json['label'];
final documentation = json['documentation'] is String
? new Either2<String, MarkupContent>.t1(json['documentation'])
: (MarkupContent.canParse(json['documentation'])
? new Either2<String, MarkupContent>.t2(
json['documentation'] != null
- ? new MarkupContent.fromJson(json['documentation'])
+ ? MarkupContent.fromJson(json['documentation'])
: null)
- : (throw '''${json['documentation']} was not one of (string, MarkupContent)'''));
+ : (json['documentation'] == null
+ ? null
+ : (throw '''${json['documentation']} was not one of (String, MarkupContent)''')));
return new ParameterInformation(label, documentation);
}
- /// The human-readable doc-comment of this parameter. Will
- /// be shown in the UI but can be omitted.
+ /// The human-readable doc-comment of this parameter. Will be shown in the UI
+ /// but can be omitted.
final Either2<String, MarkupContent> documentation;
/// The label of this parameter. Will be shown in the UI.
@@ -3772,6 +5558,27 @@
obj.containsKey('label') &&
obj['label'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is ParameterInformation) {
+ return label == other.label &&
+ documentation == other.documentation &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, label.hashCode);
+ hash = JenkinsSmiHash.combine(hash, documentation.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class Position implements ToJsonable {
@@ -3783,19 +5590,18 @@
throw 'character is required but was not provided';
}
}
- factory Position.fromJson(Map<String, dynamic> json) {
+ static Position fromJson(Map<String, dynamic> json) {
final line = json['line'];
final character = json['character'];
return new Position(line, character);
}
- /// Character offset on a line in a document (zero-based).
- /// Assuming that the line is represented as a string, the
- /// `character` value represents the gap between the
- /// `character` and `character + 1`.
+ /// Character offset on a line in a document (zero-based). Assuming that the
+ /// line is represented as a string, the `character` value represents the gap
+ /// between the `character` and `character + 1`.
///
- /// If the character value is greater than the line length
- /// it defaults back to the line length.
+ /// If the character value is greater than the line length it defaults back to
+ /// the line length.
final num character;
/// Line position in a document (zero-based).
@@ -3816,6 +5622,25 @@
obj.containsKey('character') &&
obj['character'] is num;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is Position) {
+ return line == other.line && character == other.character && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, line.hashCode);
+ hash = JenkinsSmiHash.combine(hash, character.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class PublishDiagnosticsParams implements ToJsonable {
@@ -3827,10 +5652,10 @@
throw 'diagnostics is required but was not provided';
}
}
- factory PublishDiagnosticsParams.fromJson(Map<String, dynamic> json) {
+ static PublishDiagnosticsParams fromJson(Map<String, dynamic> json) {
final uri = json['uri'];
final diagnostics = json['diagnostics']
- ?.map((item) => item != null ? new Diagnostic.fromJson(item) : null)
+ ?.map((item) => item != null ? Diagnostic.fromJson(item) : null)
?.cast<Diagnostic>()
?.toList();
return new PublishDiagnosticsParams(uri, diagnostics);
@@ -3859,6 +5684,28 @@
(obj['diagnostics'].length == 0 ||
obj['diagnostics'].every((item) => Diagnostic.canParse(item))));
}
+
+ @override
+ bool operator ==(other) {
+ if (other is PublishDiagnosticsParams) {
+ return uri == other.uri &&
+ listEqual(diagnostics, other.diagnostics,
+ (Diagnostic a, Diagnostic b) => a == b) &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, uri.hashCode);
+ hash = JenkinsSmiHash.combine(hash, diagnostics.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class Range implements ToJsonable {
@@ -3870,10 +5717,10 @@
throw 'end is required but was not provided';
}
}
- factory Range.fromJson(Map<String, dynamic> json) {
+ static Range fromJson(Map<String, dynamic> json) {
final start =
- json['start'] != null ? new Position.fromJson(json['start']) : null;
- final end = json['end'] != null ? new Position.fromJson(json['end']) : null;
+ json['start'] != null ? Position.fromJson(json['start']) : null;
+ final end = json['end'] != null ? Position.fromJson(json['end']) : null;
return new Range(start, end);
}
@@ -3897,6 +5744,25 @@
obj.containsKey('end') &&
Position.canParse(obj['end']);
}
+
+ @override
+ bool operator ==(other) {
+ if (other is Range) {
+ return start == other.start && end == other.end && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, start.hashCode);
+ hash = JenkinsSmiHash.combine(hash, end.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class ReferenceContext implements ToJsonable {
@@ -3905,7 +5771,7 @@
throw 'includeDeclaration is required but was not provided';
}
}
- factory ReferenceContext.fromJson(Map<String, dynamic> json) {
+ static ReferenceContext fromJson(Map<String, dynamic> json) {
final includeDeclaration = json['includeDeclaration'];
return new ReferenceContext(includeDeclaration);
}
@@ -3925,6 +5791,24 @@
obj.containsKey('includeDeclaration') &&
obj['includeDeclaration'] is bool;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is ReferenceContext) {
+ return includeDeclaration == other.includeDeclaration && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, includeDeclaration.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class ReferenceParams implements TextDocumentPositionParams, ToJsonable {
@@ -3939,16 +5823,15 @@
throw 'position is required but was not provided';
}
}
- factory ReferenceParams.fromJson(Map<String, dynamic> json) {
+ static ReferenceParams fromJson(Map<String, dynamic> json) {
final context = json['context'] != null
- ? new ReferenceContext.fromJson(json['context'])
+ ? ReferenceContext.fromJson(json['context'])
: null;
final textDocument = json['textDocument'] != null
- ? new TextDocumentIdentifier.fromJson(json['textDocument'])
+ ? TextDocumentIdentifier.fromJson(json['textDocument'])
: null;
- final position = json['position'] != null
- ? new Position.fromJson(json['position'])
- : null;
+ final position =
+ json['position'] != null ? Position.fromJson(json['position']) : null;
return new ReferenceParams(context, textDocument, position);
}
@@ -3980,6 +5863,29 @@
obj.containsKey('position') &&
Position.canParse(obj['position']);
}
+
+ @override
+ bool operator ==(other) {
+ if (other is ReferenceParams) {
+ return context == other.context &&
+ textDocument == other.textDocument &&
+ position == other.position &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, context.hashCode);
+ hash = JenkinsSmiHash.combine(hash, textDocument.hashCode);
+ hash = JenkinsSmiHash.combine(hash, position.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// General parameters to register for a capability.
@@ -3992,15 +5898,15 @@
throw 'method is required but was not provided';
}
}
- factory Registration.fromJson(Map<String, dynamic> json) {
+ static Registration fromJson(Map<String, dynamic> json) {
final id = json['id'];
final method = json['method'];
final registerOptions = json['registerOptions'];
return new Registration(id, method, registerOptions);
}
- /// The id used to register the request. The id can be
- /// used to deregister the request again.
+ /// The id used to register the request. The id can be used to deregister the
+ /// request again.
final String id;
/// The method / capability to register for.
@@ -4026,6 +5932,29 @@
obj.containsKey('method') &&
obj['method'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is Registration) {
+ return id == other.id &&
+ method == other.method &&
+ registerOptions == other.registerOptions &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, id.hashCode);
+ hash = JenkinsSmiHash.combine(hash, method.hashCode);
+ hash = JenkinsSmiHash.combine(hash, registerOptions.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class RegistrationParams implements ToJsonable {
@@ -4034,9 +5963,9 @@
throw 'registrations is required but was not provided';
}
}
- factory RegistrationParams.fromJson(Map<String, dynamic> json) {
+ static RegistrationParams fromJson(Map<String, dynamic> json) {
final registrations = json['registrations']
- ?.map((item) => item != null ? new Registration.fromJson(item) : null)
+ ?.map((item) => item != null ? Registration.fromJson(item) : null)
?.cast<Registration>()
?.toList();
return new RegistrationParams(registrations);
@@ -4059,11 +5988,34 @@
obj['registrations']
.every((item) => Registration.canParse(item))));
}
+
+ @override
+ bool operator ==(other) {
+ if (other is RegistrationParams) {
+ return listEqual(registrations, other.registrations,
+ (Registration a, Registration b) => a == b) &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, registrations.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// Rename file operation
-class RenameFile implements FileOperation, ToJsonable {
- RenameFile(this.oldUri, this.newUri, this.options) {
+class RenameFile implements ToJsonable {
+ RenameFile(this.kind, this.oldUri, this.newUri, this.options) {
+ if (kind == null) {
+ throw 'kind is required but was not provided';
+ }
if (oldUri == null) {
throw 'oldUri is required but was not provided';
}
@@ -4071,15 +6023,19 @@
throw 'newUri is required but was not provided';
}
}
- factory RenameFile.fromJson(Map<String, dynamic> json) {
+ static RenameFile fromJson(Map<String, dynamic> json) {
+ final kind = json['kind'];
final oldUri = json['oldUri'];
final newUri = json['newUri'];
final options = json['options'] != null
- ? new RenameFileOptions.fromJson(json['options'])
+ ? RenameFileOptions.fromJson(json['options'])
: null;
- return new RenameFile(oldUri, newUri, options);
+ return new RenameFile(kind, oldUri, newUri, options);
}
+ /// A rename
+ final String kind;
+
/// The new location.
final String newUri;
@@ -4091,6 +6047,7 @@
Map<String, dynamic> toJson() {
Map<String, dynamic> __result = {};
+ __result['kind'] = kind ?? (throw 'kind is required but was not set');
__result['oldUri'] = oldUri ?? (throw 'oldUri is required but was not set');
__result['newUri'] = newUri ?? (throw 'newUri is required but was not set');
if (options != null) {
@@ -4101,17 +6058,44 @@
static bool canParse(Object obj) {
return obj is Map<String, dynamic> &&
+ obj.containsKey('kind') &&
+ obj['kind'] is String &&
obj.containsKey('oldUri') &&
obj['oldUri'] is String &&
obj.containsKey('newUri') &&
obj['newUri'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is RenameFile) {
+ return kind == other.kind &&
+ oldUri == other.oldUri &&
+ newUri == other.newUri &&
+ options == other.options &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, kind.hashCode);
+ hash = JenkinsSmiHash.combine(hash, oldUri.hashCode);
+ hash = JenkinsSmiHash.combine(hash, newUri.hashCode);
+ hash = JenkinsSmiHash.combine(hash, options.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// Rename file options
class RenameFileOptions implements ToJsonable {
RenameFileOptions(this.overwrite, this.ignoreIfExists);
- factory RenameFileOptions.fromJson(Map<String, dynamic> json) {
+ static RenameFileOptions fromJson(Map<String, dynamic> json) {
final overwrite = json['overwrite'];
final ignoreIfExists = json['ignoreIfExists'];
return new RenameFileOptions(overwrite, ignoreIfExists);
@@ -4120,8 +6104,7 @@
/// Ignores if target exists.
final bool ignoreIfExists;
- /// Overwrite target if existing. Overwrite wins over
- /// `ignoreIfExists`
+ /// Overwrite target if existing. Overwrite wins over `ignoreIfExists`
final bool overwrite;
Map<String, dynamic> toJson() {
@@ -4138,18 +6121,38 @@
static bool canParse(Object obj) {
return obj is Map<String, dynamic>;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is RenameFileOptions) {
+ return overwrite == other.overwrite &&
+ ignoreIfExists == other.ignoreIfExists &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, overwrite.hashCode);
+ hash = JenkinsSmiHash.combine(hash, ignoreIfExists.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// Rename options
class RenameOptions implements ToJsonable {
RenameOptions(this.prepareProvider);
- factory RenameOptions.fromJson(Map<String, dynamic> json) {
+ static RenameOptions fromJson(Map<String, dynamic> json) {
final prepareProvider = json['prepareProvider'];
return new RenameOptions(prepareProvider);
}
- /// Renames should be checked and tested before being
- /// executed.
+ /// Renames should be checked and tested before being executed.
final bool prepareProvider;
Map<String, dynamic> toJson() {
@@ -4163,6 +6166,24 @@
static bool canParse(Object obj) {
return obj is Map<String, dynamic>;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is RenameOptions) {
+ return prepareProvider == other.prepareProvider && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, prepareProvider.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class RenameParams implements ToJsonable {
@@ -4177,20 +6198,18 @@
throw 'newName is required but was not provided';
}
}
- factory RenameParams.fromJson(Map<String, dynamic> json) {
+ static RenameParams fromJson(Map<String, dynamic> json) {
final textDocument = json['textDocument'] != null
- ? new TextDocumentIdentifier.fromJson(json['textDocument'])
+ ? TextDocumentIdentifier.fromJson(json['textDocument'])
: null;
- final position = json['position'] != null
- ? new Position.fromJson(json['position'])
- : null;
+ final position =
+ json['position'] != null ? Position.fromJson(json['position']) : null;
final newName = json['newName'];
return new RenameParams(textDocument, position, newName);
}
- /// The new name of the symbol. If the given name is not
- /// valid the request must return a [ResponseError] with
- /// an appropriate message set.
+ /// The new name of the symbol. If the given name is not valid the request
+ /// must return a [ResponseError] with an appropriate message set.
final String newName;
/// The position at which this request was sent.
@@ -4219,27 +6238,48 @@
obj.containsKey('newName') &&
obj['newName'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is RenameParams) {
+ return textDocument == other.textDocument &&
+ position == other.position &&
+ newName == other.newName &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, textDocument.hashCode);
+ hash = JenkinsSmiHash.combine(hash, position.hashCode);
+ hash = JenkinsSmiHash.combine(hash, newName.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class RenameRegistrationOptions
implements TextDocumentRegistrationOptions, ToJsonable {
RenameRegistrationOptions(this.prepareProvider, this.documentSelector);
- factory RenameRegistrationOptions.fromJson(Map<String, dynamic> json) {
+ static RenameRegistrationOptions fromJson(Map<String, dynamic> json) {
final prepareProvider = json['prepareProvider'];
final documentSelector = json['documentSelector']
- ?.map((item) => item != null ? new DocumentFilter.fromJson(item) : null)
+ ?.map((item) => item != null ? DocumentFilter.fromJson(item) : null)
?.cast<DocumentFilter>()
?.toList();
return new RenameRegistrationOptions(prepareProvider, documentSelector);
}
- /// A document selector to identify the scope of the
- /// registration. If set to null the document selector
- /// provided on the client side will be used.
+ /// A document selector to identify the scope of the registration. If set to
+ /// null the document selector provided on the client side will be used.
final List<DocumentFilter> documentSelector;
- /// Renames should be checked and tested for validity
- /// before being executed.
+ /// Renames should be checked and tested for validity before being executed.
final bool prepareProvider;
Map<String, dynamic> toJson() {
@@ -4259,9 +6299,30 @@
obj['documentSelector']
.every((item) => DocumentFilter.canParse(item))));
}
+
+ @override
+ bool operator ==(other) {
+ if (other is RenameRegistrationOptions) {
+ return prepareProvider == other.prepareProvider &&
+ documentSelector == other.documentSelector &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, prepareProvider.hashCode);
+ hash = JenkinsSmiHash.combine(hash, documentSelector.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
-class RequestMessage implements Message, ToJsonable {
+class RequestMessage implements Message, IncomingMessage, ToJsonable {
RequestMessage(this.id, this.method, this.params, this.jsonrpc) {
if (id == null) {
throw 'id is required but was not provided';
@@ -4273,19 +6334,15 @@
throw 'jsonrpc is required but was not provided';
}
}
- factory RequestMessage.fromJson(Map<String, dynamic> json) {
+ static RequestMessage fromJson(Map<String, dynamic> json) {
final id = json['id'] is num
? new Either2<num, String>.t1(json['id'])
: (json['id'] is String
? new Either2<num, String>.t2(json['id'])
- : (throw '''${json['id']} was not one of (number, string)'''));
- final method = json['method'];
- final params = (json['params'] is List &&
- (json['params'].length == 0 ||
- json['params'].every((item) => true)))
- ? new Either2<List<dynamic>, dynamic>.t1(
- json['params']?.map((item) => item)?.cast<dynamic>()?.toList())
- : (new Either2<List<dynamic>, dynamic>.t2(json['params']));
+ : (throw '''${json['id']} was not one of (num, String)'''));
+ final method =
+ json['method'] != null ? Method.fromJson(json['method']) : null;
+ final params = json['params'];
final jsonrpc = json['jsonrpc'];
return new RequestMessage(id, method, params, jsonrpc);
}
@@ -4295,10 +6352,10 @@
final String jsonrpc;
/// The method to be invoked.
- final String method;
+ final Method method;
/// The method's params.
- final Either2<List<dynamic>, dynamic> params;
+ final dynamic params;
Map<String, dynamic> toJson() {
Map<String, dynamic> __result = {};
@@ -4317,17 +6374,42 @@
obj.containsKey('id') &&
(obj['id'] is num || obj['id'] is String) &&
obj.containsKey('method') &&
- obj['method'] is String &&
+ Method.canParse(obj['method']) &&
obj.containsKey('jsonrpc') &&
obj['jsonrpc'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is RequestMessage) {
+ return id == other.id &&
+ method == other.method &&
+ params == other.params &&
+ jsonrpc == other.jsonrpc &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, id.hashCode);
+ hash = JenkinsSmiHash.combine(hash, method.hashCode);
+ hash = JenkinsSmiHash.combine(hash, params.hashCode);
+ hash = JenkinsSmiHash.combine(hash, jsonrpc.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class ResourceOperationKind {
const ResourceOperationKind._(this._value);
const ResourceOperationKind.fromJson(this._value);
- final Object _value;
+ final String _value;
static bool canParse(Object obj) {
switch (obj) {
@@ -4368,19 +6450,19 @@
throw 'message is required but was not provided';
}
}
- factory ResponseError.fromJson(Map<String, dynamic> json) {
- final code = json['code'];
+ static ResponseError<D> fromJson<D>(Map<String, dynamic> json) {
+ final code =
+ json['code'] != null ? ErrorCodes.fromJson(json['code']) : null;
final message = json['message'];
final data = json['data'];
return new ResponseError<D>(code, message, data);
}
/// A number indicating the error type that occurred.
- final num code;
+ final ErrorCodes code;
- /// A Primitive or Structured value that contains
- /// additional information about the error. Can be
- /// omitted.
+ /// A Primitive or Structured value that contains additional information about
+ /// the error. Can be omitted.
final D data;
/// A string providing a short description of the error.
@@ -4400,10 +6482,33 @@
static bool canParse(Object obj) {
return obj is Map<String, dynamic> &&
obj.containsKey('code') &&
- obj['code'] is num &&
+ ErrorCodes.canParse(obj['code']) &&
obj.containsKey('message') &&
obj['message'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is ResponseError) {
+ return code == other.code &&
+ message == other.message &&
+ data == other.data &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, code.hashCode);
+ hash = JenkinsSmiHash.combine(hash, message.hashCode);
+ hash = JenkinsSmiHash.combine(hash, data.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class ResponseMessage implements Message, ToJsonable {
@@ -4412,14 +6517,18 @@
throw 'jsonrpc is required but was not provided';
}
}
- factory ResponseMessage.fromJson(Map<String, dynamic> json) {
+ static ResponseMessage fromJson(Map<String, dynamic> json) {
final id = json['id'] is num
? new Either2<num, String>.t1(json['id'])
: (json['id'] is String
? new Either2<num, String>.t2(json['id'])
- : (throw '''${json['id']} was not one of (number, string)'''));
+ : (json['id'] == null
+ ? null
+ : (throw '''${json['id']} was not one of (num, String)''')));
final result = json['result'];
- final error = json['error'];
+ final error = json['error'] != null
+ ? ResponseError.fromJson<dynamic>(json['error'])
+ : null;
final jsonrpc = json['jsonrpc'];
return new ResponseMessage(id, result, error, jsonrpc);
}
@@ -4431,8 +6540,7 @@
final Either2<num, String> id;
final String jsonrpc;
- /// The result of a request. This can be omitted in the
- /// case of an error.
+ /// The result of a request. This can be omitted in the case of an error.
final dynamic result;
Map<String, dynamic> toJson() {
@@ -4456,18 +6564,42 @@
obj.containsKey('jsonrpc') &&
obj['jsonrpc'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is ResponseMessage) {
+ return id == other.id &&
+ result == other.result &&
+ error == other.error &&
+ jsonrpc == other.jsonrpc &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, id.hashCode);
+ hash = JenkinsSmiHash.combine(hash, result.hashCode);
+ hash = JenkinsSmiHash.combine(hash, error.hashCode);
+ hash = JenkinsSmiHash.combine(hash, jsonrpc.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// Save options.
class SaveOptions implements ToJsonable {
SaveOptions(this.includeText);
- factory SaveOptions.fromJson(Map<String, dynamic> json) {
+ static SaveOptions fromJson(Map<String, dynamic> json) {
final includeText = json['includeText'];
return new SaveOptions(includeText);
}
- /// The client is supposed to include the content on
- /// save.
+ /// The client is supposed to include the content on save.
final bool includeText;
Map<String, dynamic> toJson() {
@@ -4481,6 +6613,24 @@
static bool canParse(Object obj) {
return obj is Map<String, dynamic>;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is SaveOptions) {
+ return includeText == other.includeText && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, includeText.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class ServerCapabilities implements ToJsonable {
@@ -4490,6 +6640,8 @@
this.completionProvider,
this.signatureHelpProvider,
this.definitionProvider,
+ this.typeDefinitionProvider,
+ this.implementationProvider,
this.referencesProvider,
this.documentHighlightProvider,
this.documentSymbolProvider,
@@ -4501,28 +6653,38 @@
this.documentOnTypeFormattingProvider,
this.renameProvider,
this.documentLinkProvider,
+ this.colorProvider,
+ this.foldingRangeProvider,
this.executeCommandProvider,
- this.supported,
- this.changeNotifications);
- factory ServerCapabilities.fromJson(Map<String, dynamic> json) {
+ this.workspace,
+ this.experimental);
+ static ServerCapabilities fromJson(Map<String, dynamic> json) {
final textDocumentSync = TextDocumentSyncOptions.canParse(
json['textDocumentSync'])
? new Either2<TextDocumentSyncOptions, num>.t1(
json['textDocumentSync'] != null
- ? new TextDocumentSyncOptions.fromJson(json['textDocumentSync'])
+ ? TextDocumentSyncOptions.fromJson(json['textDocumentSync'])
: null)
: (json['textDocumentSync'] is num
? new Either2<TextDocumentSyncOptions, num>.t2(
json['textDocumentSync'])
- : (throw '''${json['textDocumentSync']} was not one of (TextDocumentSyncOptions, number)'''));
+ : (json['textDocumentSync'] == null
+ ? null
+ : (throw '''${json['textDocumentSync']} was not one of (TextDocumentSyncOptions, num)''')));
final hoverProvider = json['hoverProvider'];
final completionProvider = json['completionProvider'] != null
- ? new CompletionOptions.fromJson(json['completionProvider'])
+ ? CompletionOptions.fromJson(json['completionProvider'])
: null;
final signatureHelpProvider = json['signatureHelpProvider'] != null
- ? new SignatureHelpOptions.fromJson(json['signatureHelpProvider'])
+ ? SignatureHelpOptions.fromJson(json['signatureHelpProvider'])
: null;
final definitionProvider = json['definitionProvider'];
+ final typeDefinitionProvider = json['typeDefinitionProvider'] is bool
+ ? new Either2<bool, dynamic>.t1(json['typeDefinitionProvider'])
+ : (new Either2<bool, dynamic>.t2(json['typeDefinitionProvider']));
+ final implementationProvider = json['implementationProvider'] is bool
+ ? new Either2<bool, dynamic>.t1(json['implementationProvider'])
+ : (new Either2<bool, dynamic>.t2(json['implementationProvider']));
final referencesProvider = json['referencesProvider'];
final documentHighlightProvider = json['documentHighlightProvider'];
final documentSymbolProvider = json['documentSymbolProvider'];
@@ -4532,45 +6694,70 @@
: (CodeActionOptions.canParse(json['codeActionProvider'])
? new Either2<bool, CodeActionOptions>.t2(
json['codeActionProvider'] != null
- ? new CodeActionOptions.fromJson(json['codeActionProvider'])
+ ? CodeActionOptions.fromJson(json['codeActionProvider'])
: null)
- : (throw '''${json['codeActionProvider']} was not one of (boolean, CodeActionOptions)'''));
+ : (json['codeActionProvider'] == null
+ ? null
+ : (throw '''${json['codeActionProvider']} was not one of (bool, CodeActionOptions)''')));
final codeLensProvider = json['codeLensProvider'] != null
- ? new CodeLensOptions.fromJson(json['codeLensProvider'])
+ ? CodeLensOptions.fromJson(json['codeLensProvider'])
: null;
final documentFormattingProvider = json['documentFormattingProvider'];
final documentRangeFormattingProvider =
json['documentRangeFormattingProvider'];
final documentOnTypeFormattingProvider =
json['documentOnTypeFormattingProvider'] != null
- ? new DocumentOnTypeFormattingOptions.fromJson(
+ ? DocumentOnTypeFormattingOptions.fromJson(
json['documentOnTypeFormattingProvider'])
: null;
final renameProvider = json['renameProvider'] is bool
? new Either2<bool, RenameOptions>.t1(json['renameProvider'])
: (RenameOptions.canParse(json['renameProvider'])
? new Either2<bool, RenameOptions>.t2(json['renameProvider'] != null
- ? new RenameOptions.fromJson(json['renameProvider'])
+ ? RenameOptions.fromJson(json['renameProvider'])
: null)
- : (throw '''${json['renameProvider']} was not one of (boolean, RenameOptions)'''));
+ : (json['renameProvider'] == null
+ ? null
+ : (throw '''${json['renameProvider']} was not one of (bool, RenameOptions)''')));
final documentLinkProvider = json['documentLinkProvider'] != null
- ? new DocumentLinkOptions.fromJson(json['documentLinkProvider'])
+ ? DocumentLinkOptions.fromJson(json['documentLinkProvider'])
: null;
+ final colorProvider = json['colorProvider'] is bool
+ ? new Either3<bool, ColorProviderOptions, dynamic>.t1(
+ json['colorProvider'])
+ : (ColorProviderOptions.canParse(json['colorProvider'])
+ ? new Either3<bool, ColorProviderOptions, dynamic>.t2(
+ json['colorProvider'] != null
+ ? ColorProviderOptions.fromJson(json['colorProvider'])
+ : null)
+ : (new Either3<bool, ColorProviderOptions, dynamic>.t3(
+ json['colorProvider'])));
+ final foldingRangeProvider = json['foldingRangeProvider'] is bool
+ ? new Either3<bool, FoldingRangeProviderOptions, dynamic>.t1(
+ json['foldingRangeProvider'])
+ : (FoldingRangeProviderOptions.canParse(json['foldingRangeProvider'])
+ ? new Either3<bool, FoldingRangeProviderOptions, dynamic>.t2(
+ json['foldingRangeProvider'] != null
+ ? FoldingRangeProviderOptions.fromJson(
+ json['foldingRangeProvider'])
+ : null)
+ : (new Either3<bool, FoldingRangeProviderOptions, dynamic>.t3(
+ json['foldingRangeProvider'])));
final executeCommandProvider = json['executeCommandProvider'] != null
- ? new ExecuteCommandOptions.fromJson(json['executeCommandProvider'])
+ ? ExecuteCommandOptions.fromJson(json['executeCommandProvider'])
: null;
- final supported = json['supported'];
- final changeNotifications = json['changeNotifications'] is String
- ? new Either2<String, bool>.t1(json['changeNotifications'])
- : (json['changeNotifications'] is bool
- ? new Either2<String, bool>.t2(json['changeNotifications'])
- : (throw '''${json['changeNotifications']} was not one of (string, boolean)'''));
+ final workspace = json['workspace'] != null
+ ? ServerCapabilitiesWorkspace.fromJson(json['workspace'])
+ : null;
+ final experimental = json['experimental'];
return new ServerCapabilities(
textDocumentSync,
hoverProvider,
completionProvider,
signatureHelpProvider,
definitionProvider,
+ typeDefinitionProvider,
+ implementationProvider,
referencesProvider,
documentHighlightProvider,
documentSymbolProvider,
@@ -4582,31 +6769,26 @@
documentOnTypeFormattingProvider,
renameProvider,
documentLinkProvider,
+ colorProvider,
+ foldingRangeProvider,
executeCommandProvider,
- supported,
- changeNotifications);
+ workspace,
+ experimental);
}
- /// Whether the server wants to receive workspace folder
- /// change notifications.
- ///
- /// If a strings is provided the string is treated as a
- /// ID under which the notification is registered on the
- /// client side. The ID can be used to unregister for
- /// these events using the `client/unregisterCapability`
- /// request.
- final Either2<String, bool> changeNotifications;
-
- /// The server provides code actions. The
- /// `CodeActionOptions` return type is only valid if the
- /// client signals code action literal support via the
- /// property
- /// `textDocument.codeAction.codeActionLiteralSupport`.
+ /// The server provides code actions. The `CodeActionOptions` return type is
+ /// only valid if the client signals code action literal support via the
+ /// property `textDocument.codeAction.codeActionLiteralSupport`.
final Either2<bool, CodeActionOptions> codeActionProvider;
/// The server provides code lens.
final CodeLensOptions codeLensProvider;
+ /// The server provides color provider support.
+ ///
+ /// Since 3.6.0
+ final Either3<bool, ColorProviderOptions, dynamic> colorProvider;
+
/// The server provides completion support.
final CompletionOptions completionProvider;
@@ -4634,31 +6816,48 @@
/// The server provides execute command support.
final ExecuteCommandOptions executeCommandProvider;
+ /// Experimental server capabilities.
+ final dynamic experimental;
+
+ /// The server provides folding provider support.
+ ///
+ /// Since 3.10.0
+ final Either3<bool, FoldingRangeProviderOptions, dynamic>
+ foldingRangeProvider;
+
/// The server provides hover support.
final bool hoverProvider;
+ /// The server provides Goto Implementation support.
+ ///
+ /// Since 3.6.0
+ final Either2<bool, dynamic> implementationProvider;
+
/// The server provides find references support.
final bool referencesProvider;
- /// The server provides rename support. RenameOptions
- /// may only be specified if the client states that it
- /// supports `prepareSupport` in its initial
+ /// The server provides rename support. RenameOptions may only be specified if
+ /// the client states that it supports `prepareSupport` in its initial
/// `initialize` request.
final Either2<bool, RenameOptions> renameProvider;
/// The server provides signature help support.
final SignatureHelpOptions signatureHelpProvider;
- /// The server has support for workspace folders
- final bool supported;
-
- /// Defines how text documents are synced. Is either a
- /// detailed structure defining each notification or for
- /// backwards compatibility the TextDocumentSyncKind
- /// number. If omitted it defaults to
+ /// Defines how text documents are synced. Is either a detailed structure
+ /// defining each notification or for backwards compatibility the
+ /// TextDocumentSyncKind number. If omitted it defaults to
/// `TextDocumentSyncKind.None`.
final Either2<TextDocumentSyncOptions, num> textDocumentSync;
+ /// The server provides Goto Type Definition support.
+ ///
+ /// Since 3.6.0
+ final Either2<bool, dynamic> typeDefinitionProvider;
+
+ /// Workspace specific server capabilities
+ final ServerCapabilitiesWorkspace workspace;
+
/// The server provides workspace symbol support.
final bool workspaceSymbolProvider;
@@ -4679,6 +6878,12 @@
if (definitionProvider != null) {
__result['definitionProvider'] = definitionProvider;
}
+ if (typeDefinitionProvider != null) {
+ __result['typeDefinitionProvider'] = typeDefinitionProvider;
+ }
+ if (implementationProvider != null) {
+ __result['implementationProvider'] = implementationProvider;
+ }
if (referencesProvider != null) {
__result['referencesProvider'] = referencesProvider;
}
@@ -4714,9 +6919,170 @@
if (documentLinkProvider != null) {
__result['documentLinkProvider'] = documentLinkProvider;
}
+ if (colorProvider != null) {
+ __result['colorProvider'] = colorProvider;
+ }
+ if (foldingRangeProvider != null) {
+ __result['foldingRangeProvider'] = foldingRangeProvider;
+ }
if (executeCommandProvider != null) {
__result['executeCommandProvider'] = executeCommandProvider;
}
+ if (workspace != null) {
+ __result['workspace'] = workspace;
+ }
+ if (experimental != null) {
+ __result['experimental'] = experimental;
+ }
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic>;
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is ServerCapabilities) {
+ return textDocumentSync == other.textDocumentSync &&
+ hoverProvider == other.hoverProvider &&
+ completionProvider == other.completionProvider &&
+ signatureHelpProvider == other.signatureHelpProvider &&
+ definitionProvider == other.definitionProvider &&
+ typeDefinitionProvider == other.typeDefinitionProvider &&
+ implementationProvider == other.implementationProvider &&
+ referencesProvider == other.referencesProvider &&
+ documentHighlightProvider == other.documentHighlightProvider &&
+ documentSymbolProvider == other.documentSymbolProvider &&
+ workspaceSymbolProvider == other.workspaceSymbolProvider &&
+ codeActionProvider == other.codeActionProvider &&
+ codeLensProvider == other.codeLensProvider &&
+ documentFormattingProvider == other.documentFormattingProvider &&
+ documentRangeFormattingProvider ==
+ other.documentRangeFormattingProvider &&
+ documentOnTypeFormattingProvider ==
+ other.documentOnTypeFormattingProvider &&
+ renameProvider == other.renameProvider &&
+ documentLinkProvider == other.documentLinkProvider &&
+ colorProvider == other.colorProvider &&
+ foldingRangeProvider == other.foldingRangeProvider &&
+ executeCommandProvider == other.executeCommandProvider &&
+ workspace == other.workspace &&
+ experimental == other.experimental &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, textDocumentSync.hashCode);
+ hash = JenkinsSmiHash.combine(hash, hoverProvider.hashCode);
+ hash = JenkinsSmiHash.combine(hash, completionProvider.hashCode);
+ hash = JenkinsSmiHash.combine(hash, signatureHelpProvider.hashCode);
+ hash = JenkinsSmiHash.combine(hash, definitionProvider.hashCode);
+ hash = JenkinsSmiHash.combine(hash, typeDefinitionProvider.hashCode);
+ hash = JenkinsSmiHash.combine(hash, implementationProvider.hashCode);
+ hash = JenkinsSmiHash.combine(hash, referencesProvider.hashCode);
+ hash = JenkinsSmiHash.combine(hash, documentHighlightProvider.hashCode);
+ hash = JenkinsSmiHash.combine(hash, documentSymbolProvider.hashCode);
+ hash = JenkinsSmiHash.combine(hash, workspaceSymbolProvider.hashCode);
+ hash = JenkinsSmiHash.combine(hash, codeActionProvider.hashCode);
+ hash = JenkinsSmiHash.combine(hash, codeLensProvider.hashCode);
+ hash = JenkinsSmiHash.combine(hash, documentFormattingProvider.hashCode);
+ hash =
+ JenkinsSmiHash.combine(hash, documentRangeFormattingProvider.hashCode);
+ hash =
+ JenkinsSmiHash.combine(hash, documentOnTypeFormattingProvider.hashCode);
+ hash = JenkinsSmiHash.combine(hash, renameProvider.hashCode);
+ hash = JenkinsSmiHash.combine(hash, documentLinkProvider.hashCode);
+ hash = JenkinsSmiHash.combine(hash, colorProvider.hashCode);
+ hash = JenkinsSmiHash.combine(hash, foldingRangeProvider.hashCode);
+ hash = JenkinsSmiHash.combine(hash, executeCommandProvider.hashCode);
+ hash = JenkinsSmiHash.combine(hash, workspace.hashCode);
+ hash = JenkinsSmiHash.combine(hash, experimental.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+class ServerCapabilitiesWorkspace implements ToJsonable {
+ ServerCapabilitiesWorkspace(this.workspaceFolders);
+ static ServerCapabilitiesWorkspace fromJson(Map<String, dynamic> json) {
+ final workspaceFolders = json['workspaceFolders'] != null
+ ? ServerCapabilitiesWorkspaceFolders.fromJson(json['workspaceFolders'])
+ : null;
+ return new ServerCapabilitiesWorkspace(workspaceFolders);
+ }
+
+ /// The server supports workspace folder.
+ ///
+ /// Since 3.6.0
+ final ServerCapabilitiesWorkspaceFolders workspaceFolders;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
+ if (workspaceFolders != null) {
+ __result['workspaceFolders'] = workspaceFolders;
+ }
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic>;
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is ServerCapabilitiesWorkspace) {
+ return workspaceFolders == other.workspaceFolders && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, workspaceFolders.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+class ServerCapabilitiesWorkspaceFolders implements ToJsonable {
+ ServerCapabilitiesWorkspaceFolders(this.supported, this.changeNotifications);
+ static ServerCapabilitiesWorkspaceFolders fromJson(
+ Map<String, dynamic> json) {
+ final supported = json['supported'];
+ final changeNotifications = json['changeNotifications'] is String
+ ? new Either2<String, bool>.t1(json['changeNotifications'])
+ : (json['changeNotifications'] is bool
+ ? new Either2<String, bool>.t2(json['changeNotifications'])
+ : (json['changeNotifications'] == null
+ ? null
+ : (throw '''${json['changeNotifications']} was not one of (String, bool)''')));
+ return new ServerCapabilitiesWorkspaceFolders(
+ supported, changeNotifications);
+ }
+
+ /// Whether the server wants to receive workspace folder change notifications.
+ ///
+ /// If a strings is provided the string is treated as a ID under which the
+ /// notification is registered on the client side. The ID can be used to
+ /// unregister for these events using the `client/unregisterCapability`
+ /// request.
+ final Either2<String, bool> changeNotifications;
+
+ /// The server has support for workspace folders
+ final bool supported;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
if (supported != null) {
__result['supported'] = supported;
}
@@ -4729,6 +7095,27 @@
static bool canParse(Object obj) {
return obj is Map<String, dynamic>;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is ServerCapabilitiesWorkspaceFolders) {
+ return supported == other.supported &&
+ changeNotifications == other.changeNotifications &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, supported.hashCode);
+ hash = JenkinsSmiHash.combine(hash, changeNotifications.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class ShowMessageParams implements ToJsonable {
@@ -4740,9 +7127,9 @@
throw 'message is required but was not provided';
}
}
- factory ShowMessageParams.fromJson(Map<String, dynamic> json) {
+ static ShowMessageParams fromJson(Map<String, dynamic> json) {
final type =
- json['type'] != null ? new MessageType.fromJson(json['type']) : null;
+ json['type'] != null ? MessageType.fromJson(json['type']) : null;
final message = json['message'];
return new ShowMessageParams(type, message);
}
@@ -4768,6 +7155,25 @@
obj.containsKey('message') &&
obj['message'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is ShowMessageParams) {
+ return type == other.type && message == other.message && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, type.hashCode);
+ hash = JenkinsSmiHash.combine(hash, message.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class ShowMessageRequestParams implements ToJsonable {
@@ -4779,13 +7185,12 @@
throw 'message is required but was not provided';
}
}
- factory ShowMessageRequestParams.fromJson(Map<String, dynamic> json) {
+ static ShowMessageRequestParams fromJson(Map<String, dynamic> json) {
final type =
- json['type'] != null ? new MessageType.fromJson(json['type']) : null;
+ json['type'] != null ? MessageType.fromJson(json['type']) : null;
final message = json['message'];
final actions = json['actions']
- ?.map((item) =>
- item != null ? new MessageActionItem.fromJson(item) : null)
+ ?.map((item) => item != null ? MessageActionItem.fromJson(item) : null)
?.cast<MessageActionItem>()
?.toList();
return new ShowMessageRequestParams(type, message, actions);
@@ -4818,21 +7223,44 @@
obj.containsKey('message') &&
obj['message'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is ShowMessageRequestParams) {
+ return type == other.type &&
+ message == other.message &&
+ listEqual(actions, other.actions,
+ (MessageActionItem a, MessageActionItem b) => a == b) &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, type.hashCode);
+ hash = JenkinsSmiHash.combine(hash, message.hashCode);
+ hash = JenkinsSmiHash.combine(hash, actions.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
-/// Signature help represents the signature of something
-/// callable. There can be multiple signature but only one
-/// active and only one active parameter.
+/// Signature help represents the signature of something callable. There can be
+/// multiple signature but only one active and only one active parameter.
class SignatureHelp implements ToJsonable {
SignatureHelp(this.signatures, this.activeSignature, this.activeParameter) {
if (signatures == null) {
throw 'signatures is required but was not provided';
}
}
- factory SignatureHelp.fromJson(Map<String, dynamic> json) {
+ static SignatureHelp fromJson(Map<String, dynamic> json) {
final signatures = json['signatures']
- ?.map((item) =>
- item != null ? new SignatureInformation.fromJson(item) : null)
+ ?.map(
+ (item) => item != null ? SignatureInformation.fromJson(item) : null)
?.cast<SignatureInformation>()
?.toList();
final activeSignature = json['activeSignature'];
@@ -4840,24 +7268,20 @@
return new SignatureHelp(signatures, activeSignature, activeParameter);
}
- /// The active parameter of the active signature. If
- /// omitted or the value lies outside the range of
- /// `signatures[activeSignature].parameters` defaults to
- /// 0 if the active signature has parameters. If the
- /// active signature has no parameters it is ignored. In
- /// future version of the protocol this property might
- /// become mandatory to better express the active
- /// parameter if the active signature does have any.
+ /// The active parameter of the active signature. If omitted or the value lies
+ /// outside the range of `signatures[activeSignature].parameters` defaults to
+ /// 0 if the active signature has parameters. If the active signature has no
+ /// parameters it is ignored. In future version of the protocol this property
+ /// might become mandatory to better express the active parameter if the
+ /// active signature does have any.
final num activeParameter;
- /// The active signature. If omitted or the value lies
- /// outside the range of `signatures` the value defaults
- /// to zero or is ignored if `signatures.length === 0`.
- /// Whenever possible implementors should make an active
- /// decision about the active signature and shouldn't
- /// rely on a default value. In future version of the
- /// protocol this property might become mandatory to
- /// better express this.
+ /// The active signature. If omitted or the value lies outside the range of
+ /// `signatures` the value defaults to zero or is ignored if
+ /// `signatures.length === 0`. Whenever possible implementors should make an
+ /// active decision about the active signature and shouldn't rely on a default
+ /// value. In future version of the protocol this property might become
+ /// mandatory to better express this.
final num activeSignature;
/// One or more signatures.
@@ -4884,12 +7308,36 @@
obj['signatures']
.every((item) => SignatureInformation.canParse(item))));
}
+
+ @override
+ bool operator ==(other) {
+ if (other is SignatureHelp) {
+ return listEqual(signatures, other.signatures,
+ (SignatureInformation a, SignatureInformation b) => a == b) &&
+ activeSignature == other.activeSignature &&
+ activeParameter == other.activeParameter &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, signatures.hashCode);
+ hash = JenkinsSmiHash.combine(hash, activeSignature.hashCode);
+ hash = JenkinsSmiHash.combine(hash, activeParameter.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// Signature help options.
class SignatureHelpOptions implements ToJsonable {
SignatureHelpOptions(this.triggerCharacters);
- factory SignatureHelpOptions.fromJson(Map<String, dynamic> json) {
+ static SignatureHelpOptions fromJson(Map<String, dynamic> json) {
final triggerCharacters = json['triggerCharacters']
?.map((item) => item)
?.cast<String>()
@@ -4897,8 +7345,7 @@
return new SignatureHelpOptions(triggerCharacters);
}
- /// The characters that trigger signature help
- /// automatically.
+ /// The characters that trigger signature help automatically.
final List<String> triggerCharacters;
Map<String, dynamic> toJson() {
@@ -4912,32 +7359,50 @@
static bool canParse(Object obj) {
return obj is Map<String, dynamic>;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is SignatureHelpOptions) {
+ return listEqual(triggerCharacters, other.triggerCharacters,
+ (String a, String b) => a == b) &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, triggerCharacters.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class SignatureHelpRegistrationOptions
implements TextDocumentRegistrationOptions, ToJsonable {
SignatureHelpRegistrationOptions(
this.triggerCharacters, this.documentSelector);
- factory SignatureHelpRegistrationOptions.fromJson(Map<String, dynamic> json) {
+ static SignatureHelpRegistrationOptions fromJson(Map<String, dynamic> json) {
final triggerCharacters = json['triggerCharacters']
?.map((item) => item)
?.cast<String>()
?.toList();
final documentSelector = json['documentSelector']
- ?.map((item) => item != null ? new DocumentFilter.fromJson(item) : null)
+ ?.map((item) => item != null ? DocumentFilter.fromJson(item) : null)
?.cast<DocumentFilter>()
?.toList();
return new SignatureHelpRegistrationOptions(
triggerCharacters, documentSelector);
}
- /// A document selector to identify the scope of the
- /// registration. If set to null the document selector
- /// provided on the client side will be used.
+ /// A document selector to identify the scope of the registration. If set to
+ /// null the document selector provided on the client side will be used.
final List<DocumentFilter> documentSelector;
- /// The characters that trigger signature help
- /// automatically.
+ /// The characters that trigger signature help automatically.
final List<String> triggerCharacters;
Map<String, dynamic> toJson() {
@@ -4957,41 +7422,63 @@
obj['documentSelector']
.every((item) => DocumentFilter.canParse(item))));
}
+
+ @override
+ bool operator ==(other) {
+ if (other is SignatureHelpRegistrationOptions) {
+ return listEqual(triggerCharacters, other.triggerCharacters,
+ (String a, String b) => a == b) &&
+ documentSelector == other.documentSelector &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, triggerCharacters.hashCode);
+ hash = JenkinsSmiHash.combine(hash, documentSelector.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
-/// Represents the signature of something callable. A
-/// signature can have a label, like a function-name, a
-/// doc-comment, and a set of parameters.
+/// Represents the signature of something callable. A signature can have a
+/// label, like a function-name, a doc-comment, and a set of parameters.
class SignatureInformation implements ToJsonable {
SignatureInformation(this.label, this.documentation, this.parameters) {
if (label == null) {
throw 'label is required but was not provided';
}
}
- factory SignatureInformation.fromJson(Map<String, dynamic> json) {
+ static SignatureInformation fromJson(Map<String, dynamic> json) {
final label = json['label'];
final documentation = json['documentation'] is String
? new Either2<String, MarkupContent>.t1(json['documentation'])
: (MarkupContent.canParse(json['documentation'])
? new Either2<String, MarkupContent>.t2(
json['documentation'] != null
- ? new MarkupContent.fromJson(json['documentation'])
+ ? MarkupContent.fromJson(json['documentation'])
: null)
- : (throw '''${json['documentation']} was not one of (string, MarkupContent)'''));
+ : (json['documentation'] == null
+ ? null
+ : (throw '''${json['documentation']} was not one of (String, MarkupContent)''')));
final parameters = json['parameters']
- ?.map((item) =>
- item != null ? new ParameterInformation.fromJson(item) : null)
+ ?.map(
+ (item) => item != null ? ParameterInformation.fromJson(item) : null)
?.cast<ParameterInformation>()
?.toList();
return new SignatureInformation(label, documentation, parameters);
}
- /// The human-readable doc-comment of this signature.
- /// Will be shown in the UI but can be omitted.
+ /// The human-readable doc-comment of this signature. Will be shown in the UI
+ /// but can be omitted.
final Either2<String, MarkupContent> documentation;
- /// The label of this signature. Will be shown in the
- /// UI.
+ /// The label of this signature. Will be shown in the UI.
final String label;
/// The parameters of this signature.
@@ -5014,20 +7501,42 @@
obj.containsKey('label') &&
obj['label'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is SignatureInformation) {
+ return label == other.label &&
+ documentation == other.documentation &&
+ listEqual(parameters, other.parameters,
+ (ParameterInformation a, ParameterInformation b) => a == b) &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, label.hashCode);
+ hash = JenkinsSmiHash.combine(hash, documentation.hashCode);
+ hash = JenkinsSmiHash.combine(hash, parameters.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
-/// Static registration options to be returned in the
-/// initialize request.
+/// Static registration options to be returned in the initialize request.
class StaticRegistrationOptions implements ToJsonable {
StaticRegistrationOptions(this.id);
- factory StaticRegistrationOptions.fromJson(Map<String, dynamic> json) {
+ static StaticRegistrationOptions fromJson(Map<String, dynamic> json) {
final id = json['id'];
return new StaticRegistrationOptions(id);
}
- /// The id used to register the request. The id can be
- /// used to deregister the request again. See also
- /// Registration#id.
+ /// The id used to register the request. The id can be used to deregister the
+ /// request again. See also Registration#id.
final String id;
Map<String, dynamic> toJson() {
@@ -5041,10 +7550,28 @@
static bool canParse(Object obj) {
return obj is Map<String, dynamic>;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is StaticRegistrationOptions) {
+ return id == other.id && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, id.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
-/// Represents information about programming constructs
-/// like variables, classes, interfaces etc.
+/// Represents information about programming constructs like variables, classes,
+/// interfaces etc.
class SymbolInformation implements ToJsonable {
SymbolInformation(this.name, this.kind, this.deprecated, this.location,
this.containerName) {
@@ -5058,43 +7585,39 @@
throw 'location is required but was not provided';
}
}
- factory SymbolInformation.fromJson(Map<String, dynamic> json) {
+ static SymbolInformation fromJson(Map<String, dynamic> json) {
final name = json['name'];
- final kind = json['kind'];
+ final kind =
+ json['kind'] != null ? SymbolKind.fromJson(json['kind']) : null;
final deprecated = json['deprecated'];
- final location = json['location'] != null
- ? new Location.fromJson(json['location'])
- : null;
+ final location =
+ json['location'] != null ? Location.fromJson(json['location']) : null;
final containerName = json['containerName'];
return new SymbolInformation(
name, kind, deprecated, location, containerName);
}
- /// The name of the symbol containing this symbol. This
- /// information is for user interface purposes (e.g. to
- /// render a qualifier in the user interface if
- /// necessary). It can't be used to re-infer a hierarchy
- /// for the document symbols.
+ /// The name of the symbol containing this symbol. This information is for
+ /// user interface purposes (e.g. to render a qualifier in the user interface
+ /// if necessary). It can't be used to re-infer a hierarchy for the document
+ /// symbols.
final String containerName;
/// Indicates if this symbol is deprecated.
final bool deprecated;
/// The kind of this symbol.
- final num kind;
+ final SymbolKind kind;
- /// The location of this symbol. The location's range is
- /// used by a tool to reveal the location in the editor.
- /// If the symbol is selected in the tool the range's
- /// start information is used to position the cursor. So
- /// the range usually spans more then the actual
- /// symbol's name and does normally include things like
- /// visibility modifiers.
+ /// The location of this symbol. The location's range is used by a tool to
+ /// reveal the location in the editor. If the symbol is selected in the tool
+ /// the range's start information is used to position the cursor. So the range
+ /// usually spans more then the actual symbol's name and does normally include
+ /// things like visibility modifiers.
///
- /// The range doesn't have to denote a node range in the
- /// sense of a abstract syntax tree. It can therefore
- /// not be used to re-construct a hierarchy of the
- /// symbols.
+ /// The range doesn't have to denote a node range in the sense of a abstract
+ /// syntax tree. It can therefore not be used to re-construct a hierarchy of
+ /// the symbols.
final Location location;
/// The name of this symbol.
@@ -5120,10 +7643,37 @@
obj.containsKey('name') &&
obj['name'] is String &&
obj.containsKey('kind') &&
- obj['kind'] is num &&
+ SymbolKind.canParse(obj['kind']) &&
obj.containsKey('location') &&
Location.canParse(obj['location']);
}
+
+ @override
+ bool operator ==(other) {
+ if (other is SymbolInformation) {
+ return name == other.name &&
+ kind == other.kind &&
+ deprecated == other.deprecated &&
+ location == other.location &&
+ containerName == other.containerName &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, name.hashCode);
+ hash = JenkinsSmiHash.combine(hash, kind.hashCode);
+ hash = JenkinsSmiHash.combine(hash, deprecated.hashCode);
+ hash = JenkinsSmiHash.combine(hash, location.hashCode);
+ hash = JenkinsSmiHash.combine(hash, containerName.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// A symbol kind.
@@ -5131,7 +7681,7 @@
const SymbolKind._(this._value);
const SymbolKind.fromJson(this._value);
- final Object _value;
+ final num _value;
static bool canParse(Object obj) {
switch (obj) {
@@ -5204,8 +7754,8 @@
bool operator ==(o) => o is SymbolKind && o._value == _value;
}
-/// Describe options to be used when registering for
-/// text document change events.
+/// Describe options to be used when registering for text document change
+/// events.
class TextDocumentChangeRegistrationOptions
implements TextDocumentRegistrationOptions, ToJsonable {
TextDocumentChangeRegistrationOptions(this.syncKind, this.documentSelector) {
@@ -5213,24 +7763,22 @@
throw 'syncKind is required but was not provided';
}
}
- factory TextDocumentChangeRegistrationOptions.fromJson(
+ static TextDocumentChangeRegistrationOptions fromJson(
Map<String, dynamic> json) {
final syncKind = json['syncKind'];
final documentSelector = json['documentSelector']
- ?.map((item) => item != null ? new DocumentFilter.fromJson(item) : null)
+ ?.map((item) => item != null ? DocumentFilter.fromJson(item) : null)
?.cast<DocumentFilter>()
?.toList();
return new TextDocumentChangeRegistrationOptions(
syncKind, documentSelector);
}
- /// A document selector to identify the scope of the
- /// registration. If set to null the document selector
- /// provided on the client side will be used.
+ /// A document selector to identify the scope of the registration. If set to
+ /// null the document selector provided on the client side will be used.
final List<DocumentFilter> documentSelector;
- /// How documents are synced to the server. See
- /// TextDocumentSyncKind.Full and
+ /// How documents are synced to the server. See TextDocumentSyncKind.Full and
/// TextDocumentSyncKind.Incremental.
final num syncKind;
@@ -5252,35 +7800,1651 @@
obj['documentSelector']
.every((item) => DocumentFilter.canParse(item))));
}
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentChangeRegistrationOptions) {
+ return syncKind == other.syncKind &&
+ documentSelector == other.documentSelector &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, syncKind.hashCode);
+ hash = JenkinsSmiHash.combine(hash, documentSelector.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// Text document specific client capabilities.
class TextDocumentClientCapabilities implements ToJsonable {
- TextDocumentClientCapabilities(this.dynamicRegistration, this.willSave,
- this.willSaveWaitUntil, this.didSave);
- factory TextDocumentClientCapabilities.fromJson(Map<String, dynamic> json) {
+ TextDocumentClientCapabilities(
+ this.synchronization,
+ this.completion,
+ this.hover,
+ this.signatureHelp,
+ this.references,
+ this.documentHighlight,
+ this.documentSymbol,
+ this.formatting,
+ this.rangeFormatting,
+ this.onTypeFormatting,
+ this.definition,
+ this.typeDefinition,
+ this.implementation,
+ this.codeAction,
+ this.codeLens,
+ this.documentLink,
+ this.colorProvider,
+ this.rename,
+ this.publishDiagnostics,
+ this.foldingRange);
+ static TextDocumentClientCapabilities fromJson(Map<String, dynamic> json) {
+ final synchronization = json['synchronization'] != null
+ ? TextDocumentClientCapabilitiesSynchronization.fromJson(
+ json['synchronization'])
+ : null;
+ final completion = json['completion'] != null
+ ? TextDocumentClientCapabilitiesCompletion.fromJson(json['completion'])
+ : null;
+ final hover = json['hover'] != null
+ ? TextDocumentClientCapabilitiesHover.fromJson(json['hover'])
+ : null;
+ final signatureHelp = json['signatureHelp'] != null
+ ? TextDocumentClientCapabilitiesSignatureHelp.fromJson(
+ json['signatureHelp'])
+ : null;
+ final references = json['references'] != null
+ ? TextDocumentClientCapabilitiesReferences.fromJson(json['references'])
+ : null;
+ final documentHighlight = json['documentHighlight'] != null
+ ? TextDocumentClientCapabilitiesDocumentHighlight.fromJson(
+ json['documentHighlight'])
+ : null;
+ final documentSymbol = json['documentSymbol'] != null
+ ? TextDocumentClientCapabilitiesDocumentSymbol.fromJson(
+ json['documentSymbol'])
+ : null;
+ final formatting = json['formatting'] != null
+ ? TextDocumentClientCapabilitiesFormatting.fromJson(json['formatting'])
+ : null;
+ final rangeFormatting = json['rangeFormatting'] != null
+ ? TextDocumentClientCapabilitiesRangeFormatting.fromJson(
+ json['rangeFormatting'])
+ : null;
+ final onTypeFormatting = json['onTypeFormatting'] != null
+ ? TextDocumentClientCapabilitiesOnTypeFormatting.fromJson(
+ json['onTypeFormatting'])
+ : null;
+ final definition = json['definition'] != null
+ ? TextDocumentClientCapabilitiesDefinition.fromJson(json['definition'])
+ : null;
+ final typeDefinition = json['typeDefinition'] != null
+ ? TextDocumentClientCapabilitiesTypeDefinition.fromJson(
+ json['typeDefinition'])
+ : null;
+ final implementation = json['implementation'] != null
+ ? TextDocumentClientCapabilitiesImplementation.fromJson(
+ json['implementation'])
+ : null;
+ final codeAction = json['codeAction'] != null
+ ? TextDocumentClientCapabilitiesCodeAction.fromJson(json['codeAction'])
+ : null;
+ final codeLens = json['codeLens'] != null
+ ? TextDocumentClientCapabilitiesCodeLens.fromJson(json['codeLens'])
+ : null;
+ final documentLink = json['documentLink'] != null
+ ? TextDocumentClientCapabilitiesDocumentLink.fromJson(
+ json['documentLink'])
+ : null;
+ final colorProvider = json['colorProvider'] != null
+ ? TextDocumentClientCapabilitiesColorProvider.fromJson(
+ json['colorProvider'])
+ : null;
+ final rename = json['rename'] != null
+ ? TextDocumentClientCapabilitiesRename.fromJson(json['rename'])
+ : null;
+ final publishDiagnostics = json['publishDiagnostics'] != null
+ ? TextDocumentClientCapabilitiesPublishDiagnostics.fromJson(
+ json['publishDiagnostics'])
+ : null;
+ final foldingRange = json['foldingRange'] != null
+ ? TextDocumentClientCapabilitiesFoldingRange.fromJson(
+ json['foldingRange'])
+ : null;
+ return new TextDocumentClientCapabilities(
+ synchronization,
+ completion,
+ hover,
+ signatureHelp,
+ references,
+ documentHighlight,
+ documentSymbol,
+ formatting,
+ rangeFormatting,
+ onTypeFormatting,
+ definition,
+ typeDefinition,
+ implementation,
+ codeAction,
+ codeLens,
+ documentLink,
+ colorProvider,
+ rename,
+ publishDiagnostics,
+ foldingRange);
+ }
+
+ /// Capabilities specific to the `textDocument/codeAction`
+ final TextDocumentClientCapabilitiesCodeAction codeAction;
+
+ /// Capabilities specific to the `textDocument/codeLens`
+ final TextDocumentClientCapabilitiesCodeLens codeLens;
+
+ /// Capabilities specific to the `textDocument/documentColor` and the
+ /// `textDocument/colorPresentation` request.
+ ///
+ /// Since 3.6.0
+ final TextDocumentClientCapabilitiesColorProvider colorProvider;
+
+ /// Capabilities specific to the `textDocument/completion`
+ final TextDocumentClientCapabilitiesCompletion completion;
+
+ /// Capabilities specific to the `textDocument/definition`
+ final TextDocumentClientCapabilitiesDefinition definition;
+
+ /// Capabilities specific to the `textDocument/documentHighlight`
+ final TextDocumentClientCapabilitiesDocumentHighlight documentHighlight;
+
+ /// Capabilities specific to the `textDocument/documentLink`
+ final TextDocumentClientCapabilitiesDocumentLink documentLink;
+
+ /// Capabilities specific to the `textDocument/documentSymbol`
+ final TextDocumentClientCapabilitiesDocumentSymbol documentSymbol;
+
+ /// Capabilities specific to `textDocument/foldingRange` requests.
+ ///
+ /// Since 3.10.0
+ final TextDocumentClientCapabilitiesFoldingRange foldingRange;
+
+ /// Capabilities specific to the `textDocument/formatting`
+ final TextDocumentClientCapabilitiesFormatting formatting;
+
+ /// Capabilities specific to the `textDocument/hover`
+ final TextDocumentClientCapabilitiesHover hover;
+
+ /// Capabilities specific to the `textDocument/implementation`.
+ ///
+ /// Since 3.6.0
+ final TextDocumentClientCapabilitiesImplementation implementation;
+
+ /// Capabilities specific to the `textDocument/onTypeFormatting`
+ final TextDocumentClientCapabilitiesOnTypeFormatting onTypeFormatting;
+
+ /// Capabilities specific to `textDocument/publishDiagnostics`.
+ final TextDocumentClientCapabilitiesPublishDiagnostics publishDiagnostics;
+
+ /// Capabilities specific to the `textDocument/rangeFormatting`
+ final TextDocumentClientCapabilitiesRangeFormatting rangeFormatting;
+
+ /// Capabilities specific to the `textDocument/references`
+ final TextDocumentClientCapabilitiesReferences references;
+
+ /// Capabilities specific to the `textDocument/rename`
+ final TextDocumentClientCapabilitiesRename rename;
+
+ /// Capabilities specific to the `textDocument/signatureHelp`
+ final TextDocumentClientCapabilitiesSignatureHelp signatureHelp;
+ final TextDocumentClientCapabilitiesSynchronization synchronization;
+
+ /// Capabilities specific to the `textDocument/typeDefinition`
+ ///
+ /// Since 3.6.0
+ final TextDocumentClientCapabilitiesTypeDefinition typeDefinition;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
+ if (synchronization != null) {
+ __result['synchronization'] = synchronization;
+ }
+ if (completion != null) {
+ __result['completion'] = completion;
+ }
+ if (hover != null) {
+ __result['hover'] = hover;
+ }
+ if (signatureHelp != null) {
+ __result['signatureHelp'] = signatureHelp;
+ }
+ if (references != null) {
+ __result['references'] = references;
+ }
+ if (documentHighlight != null) {
+ __result['documentHighlight'] = documentHighlight;
+ }
+ if (documentSymbol != null) {
+ __result['documentSymbol'] = documentSymbol;
+ }
+ if (formatting != null) {
+ __result['formatting'] = formatting;
+ }
+ if (rangeFormatting != null) {
+ __result['rangeFormatting'] = rangeFormatting;
+ }
+ if (onTypeFormatting != null) {
+ __result['onTypeFormatting'] = onTypeFormatting;
+ }
+ if (definition != null) {
+ __result['definition'] = definition;
+ }
+ if (typeDefinition != null) {
+ __result['typeDefinition'] = typeDefinition;
+ }
+ if (implementation != null) {
+ __result['implementation'] = implementation;
+ }
+ if (codeAction != null) {
+ __result['codeAction'] = codeAction;
+ }
+ if (codeLens != null) {
+ __result['codeLens'] = codeLens;
+ }
+ if (documentLink != null) {
+ __result['documentLink'] = documentLink;
+ }
+ if (colorProvider != null) {
+ __result['colorProvider'] = colorProvider;
+ }
+ if (rename != null) {
+ __result['rename'] = rename;
+ }
+ if (publishDiagnostics != null) {
+ __result['publishDiagnostics'] = publishDiagnostics;
+ }
+ if (foldingRange != null) {
+ __result['foldingRange'] = foldingRange;
+ }
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic>;
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentClientCapabilities) {
+ return synchronization == other.synchronization &&
+ completion == other.completion &&
+ hover == other.hover &&
+ signatureHelp == other.signatureHelp &&
+ references == other.references &&
+ documentHighlight == other.documentHighlight &&
+ documentSymbol == other.documentSymbol &&
+ formatting == other.formatting &&
+ rangeFormatting == other.rangeFormatting &&
+ onTypeFormatting == other.onTypeFormatting &&
+ definition == other.definition &&
+ typeDefinition == other.typeDefinition &&
+ implementation == other.implementation &&
+ codeAction == other.codeAction &&
+ codeLens == other.codeLens &&
+ documentLink == other.documentLink &&
+ colorProvider == other.colorProvider &&
+ rename == other.rename &&
+ publishDiagnostics == other.publishDiagnostics &&
+ foldingRange == other.foldingRange &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, synchronization.hashCode);
+ hash = JenkinsSmiHash.combine(hash, completion.hashCode);
+ hash = JenkinsSmiHash.combine(hash, hover.hashCode);
+ hash = JenkinsSmiHash.combine(hash, signatureHelp.hashCode);
+ hash = JenkinsSmiHash.combine(hash, references.hashCode);
+ hash = JenkinsSmiHash.combine(hash, documentHighlight.hashCode);
+ hash = JenkinsSmiHash.combine(hash, documentSymbol.hashCode);
+ hash = JenkinsSmiHash.combine(hash, formatting.hashCode);
+ hash = JenkinsSmiHash.combine(hash, rangeFormatting.hashCode);
+ hash = JenkinsSmiHash.combine(hash, onTypeFormatting.hashCode);
+ hash = JenkinsSmiHash.combine(hash, definition.hashCode);
+ hash = JenkinsSmiHash.combine(hash, typeDefinition.hashCode);
+ hash = JenkinsSmiHash.combine(hash, implementation.hashCode);
+ hash = JenkinsSmiHash.combine(hash, codeAction.hashCode);
+ hash = JenkinsSmiHash.combine(hash, codeLens.hashCode);
+ hash = JenkinsSmiHash.combine(hash, documentLink.hashCode);
+ hash = JenkinsSmiHash.combine(hash, colorProvider.hashCode);
+ hash = JenkinsSmiHash.combine(hash, rename.hashCode);
+ hash = JenkinsSmiHash.combine(hash, publishDiagnostics.hashCode);
+ hash = JenkinsSmiHash.combine(hash, foldingRange.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+class TextDocumentClientCapabilitiesCodeAction implements ToJsonable {
+ TextDocumentClientCapabilitiesCodeAction(
+ this.dynamicRegistration, this.codeActionLiteralSupport);
+ static TextDocumentClientCapabilitiesCodeAction fromJson(
+ Map<String, dynamic> json) {
+ final dynamicRegistration = json['dynamicRegistration'];
+ final codeActionLiteralSupport = json['codeActionLiteralSupport'] != null
+ ? TextDocumentClientCapabilitiesCodeActionLiteralSupport.fromJson(
+ json['codeActionLiteralSupport'])
+ : null;
+ return new TextDocumentClientCapabilitiesCodeAction(
+ dynamicRegistration, codeActionLiteralSupport);
+ }
+
+ /// The client support code action literals as a valid response of the
+ /// `textDocument/codeAction` request.
+ ///
+ /// Since 3.8.0
+ final TextDocumentClientCapabilitiesCodeActionLiteralSupport
+ codeActionLiteralSupport;
+
+ /// Whether code action supports dynamic registration.
+ final bool dynamicRegistration;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
+ if (dynamicRegistration != null) {
+ __result['dynamicRegistration'] = dynamicRegistration;
+ }
+ if (codeActionLiteralSupport != null) {
+ __result['codeActionLiteralSupport'] = codeActionLiteralSupport;
+ }
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic>;
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentClientCapabilitiesCodeAction) {
+ return dynamicRegistration == other.dynamicRegistration &&
+ codeActionLiteralSupport == other.codeActionLiteralSupport &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, dynamicRegistration.hashCode);
+ hash = JenkinsSmiHash.combine(hash, codeActionLiteralSupport.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+class TextDocumentClientCapabilitiesCodeActionKind implements ToJsonable {
+ TextDocumentClientCapabilitiesCodeActionKind(this.valueSet) {
+ if (valueSet == null) {
+ throw 'valueSet is required but was not provided';
+ }
+ }
+ static TextDocumentClientCapabilitiesCodeActionKind fromJson(
+ Map<String, dynamic> json) {
+ final valueSet = json['valueSet']
+ ?.map((item) => item != null ? CodeActionKind.fromJson(item) : null)
+ ?.cast<CodeActionKind>()
+ ?.toList();
+ return new TextDocumentClientCapabilitiesCodeActionKind(valueSet);
+ }
+
+ /// The code action kind values the client supports. When this property exists
+ /// the client also guarantees that it will handle values outside its set
+ /// gracefully and falls back to a default value when unknown.
+ final List<CodeActionKind> valueSet;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
+ __result['valueSet'] =
+ valueSet ?? (throw 'valueSet is required but was not set');
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic> &&
+ obj.containsKey('valueSet') &&
+ (obj['valueSet'] is List &&
+ (obj['valueSet'].length == 0 ||
+ obj['valueSet'].every((item) => item is String)));
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentClientCapabilitiesCodeActionKind) {
+ return listEqual(valueSet, other.valueSet,
+ (CodeActionKind a, CodeActionKind b) => a == b) &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, valueSet.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+class TextDocumentClientCapabilitiesCodeActionLiteralSupport
+ implements ToJsonable {
+ TextDocumentClientCapabilitiesCodeActionLiteralSupport(this.codeActionKind) {
+ if (codeActionKind == null) {
+ throw 'codeActionKind is required but was not provided';
+ }
+ }
+ static TextDocumentClientCapabilitiesCodeActionLiteralSupport fromJson(
+ Map<String, dynamic> json) {
+ final codeActionKind = json['codeActionKind'] != null
+ ? TextDocumentClientCapabilitiesCodeActionKind.fromJson(
+ json['codeActionKind'])
+ : null;
+ return new TextDocumentClientCapabilitiesCodeActionLiteralSupport(
+ codeActionKind);
+ }
+
+ /// The code action kind is support with the following value set.
+ final TextDocumentClientCapabilitiesCodeActionKind codeActionKind;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
+ __result['codeActionKind'] =
+ codeActionKind ?? (throw 'codeActionKind is required but was not set');
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic> &&
+ obj.containsKey('codeActionKind') &&
+ TextDocumentClientCapabilitiesCodeActionKind.canParse(
+ obj['codeActionKind']);
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentClientCapabilitiesCodeActionLiteralSupport) {
+ return codeActionKind == other.codeActionKind && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, codeActionKind.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+class TextDocumentClientCapabilitiesCodeLens implements ToJsonable {
+ TextDocumentClientCapabilitiesCodeLens(this.dynamicRegistration);
+ static TextDocumentClientCapabilitiesCodeLens fromJson(
+ Map<String, dynamic> json) {
+ final dynamicRegistration = json['dynamicRegistration'];
+ return new TextDocumentClientCapabilitiesCodeLens(dynamicRegistration);
+ }
+
+ /// Whether code lens supports dynamic registration.
+ final bool dynamicRegistration;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
+ if (dynamicRegistration != null) {
+ __result['dynamicRegistration'] = dynamicRegistration;
+ }
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic>;
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentClientCapabilitiesCodeLens) {
+ return dynamicRegistration == other.dynamicRegistration && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, dynamicRegistration.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+class TextDocumentClientCapabilitiesColorProvider implements ToJsonable {
+ TextDocumentClientCapabilitiesColorProvider(this.dynamicRegistration);
+ static TextDocumentClientCapabilitiesColorProvider fromJson(
+ Map<String, dynamic> json) {
+ final dynamicRegistration = json['dynamicRegistration'];
+ return new TextDocumentClientCapabilitiesColorProvider(dynamicRegistration);
+ }
+
+ /// Whether colorProvider supports dynamic registration. If this is set to
+ /// `true` the client supports the new `(ColorProviderOptions &
+ /// TextDocumentRegistrationOptions & StaticRegistrationOptions)` return value
+ /// for the corresponding server capability as well.
+ final bool dynamicRegistration;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
+ if (dynamicRegistration != null) {
+ __result['dynamicRegistration'] = dynamicRegistration;
+ }
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic>;
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentClientCapabilitiesColorProvider) {
+ return dynamicRegistration == other.dynamicRegistration && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, dynamicRegistration.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+class TextDocumentClientCapabilitiesCompletion implements ToJsonable {
+ TextDocumentClientCapabilitiesCompletion(this.dynamicRegistration,
+ this.completionItem, this.completionItemKind, this.contextSupport);
+ static TextDocumentClientCapabilitiesCompletion fromJson(
+ Map<String, dynamic> json) {
+ final dynamicRegistration = json['dynamicRegistration'];
+ final completionItem = json['completionItem'] != null
+ ? TextDocumentClientCapabilitiesCompletionItem.fromJson(
+ json['completionItem'])
+ : null;
+ final completionItemKind = json['completionItemKind'] != null
+ ? TextDocumentClientCapabilitiesCompletionItemKind.fromJson(
+ json['completionItemKind'])
+ : null;
+ final contextSupport = json['contextSupport'];
+ return new TextDocumentClientCapabilitiesCompletion(dynamicRegistration,
+ completionItem, completionItemKind, contextSupport);
+ }
+
+ /// The client supports the following `CompletionItem` specific capabilities.
+ final TextDocumentClientCapabilitiesCompletionItem completionItem;
+ final TextDocumentClientCapabilitiesCompletionItemKind completionItemKind;
+
+ /// The client supports to send additional context information for a
+ /// `textDocument/completion` request.
+ final bool contextSupport;
+
+ /// Whether completion supports dynamic registration.
+ final bool dynamicRegistration;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
+ if (dynamicRegistration != null) {
+ __result['dynamicRegistration'] = dynamicRegistration;
+ }
+ if (completionItem != null) {
+ __result['completionItem'] = completionItem;
+ }
+ if (completionItemKind != null) {
+ __result['completionItemKind'] = completionItemKind;
+ }
+ if (contextSupport != null) {
+ __result['contextSupport'] = contextSupport;
+ }
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic>;
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentClientCapabilitiesCompletion) {
+ return dynamicRegistration == other.dynamicRegistration &&
+ completionItem == other.completionItem &&
+ completionItemKind == other.completionItemKind &&
+ contextSupport == other.contextSupport &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, dynamicRegistration.hashCode);
+ hash = JenkinsSmiHash.combine(hash, completionItem.hashCode);
+ hash = JenkinsSmiHash.combine(hash, completionItemKind.hashCode);
+ hash = JenkinsSmiHash.combine(hash, contextSupport.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+class TextDocumentClientCapabilitiesCompletionItem implements ToJsonable {
+ TextDocumentClientCapabilitiesCompletionItem(
+ this.snippetSupport,
+ this.commitCharactersSupport,
+ this.documentationFormat,
+ this.deprecatedSupport,
+ this.preselectSupport);
+ static TextDocumentClientCapabilitiesCompletionItem fromJson(
+ Map<String, dynamic> json) {
+ final snippetSupport = json['snippetSupport'];
+ final commitCharactersSupport = json['commitCharactersSupport'];
+ final documentationFormat = json['documentationFormat']
+ ?.map((item) => item != null ? MarkupKind.fromJson(item) : null)
+ ?.cast<MarkupKind>()
+ ?.toList();
+ final deprecatedSupport = json['deprecatedSupport'];
+ final preselectSupport = json['preselectSupport'];
+ return new TextDocumentClientCapabilitiesCompletionItem(
+ snippetSupport,
+ commitCharactersSupport,
+ documentationFormat,
+ deprecatedSupport,
+ preselectSupport);
+ }
+
+ /// The client supports commit characters on a completion item.
+ final bool commitCharactersSupport;
+
+ /// The client supports the deprecated property on a completion item.
+ final bool deprecatedSupport;
+
+ /// The client supports the following content formats for the documentation
+ /// property. The order describes the preferred format of the client.
+ final List<MarkupKind> documentationFormat;
+
+ /// The client supports the preselect property on a completion item.
+ final bool preselectSupport;
+
+ /// The client supports snippets as insert text.
+ ///
+ /// A snippet can define tab stops and placeholders with `$1`, `$2` and
+ /// `${3:foo}`. `$0` defines the final tab stop, it defaults to the end of the
+ /// snippet. Placeholders with equal identifiers are linked, that is typing in
+ /// one will update others too.
+ final bool snippetSupport;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
+ if (snippetSupport != null) {
+ __result['snippetSupport'] = snippetSupport;
+ }
+ if (commitCharactersSupport != null) {
+ __result['commitCharactersSupport'] = commitCharactersSupport;
+ }
+ if (documentationFormat != null) {
+ __result['documentationFormat'] = documentationFormat;
+ }
+ if (deprecatedSupport != null) {
+ __result['deprecatedSupport'] = deprecatedSupport;
+ }
+ if (preselectSupport != null) {
+ __result['preselectSupport'] = preselectSupport;
+ }
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic>;
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentClientCapabilitiesCompletionItem) {
+ return snippetSupport == other.snippetSupport &&
+ commitCharactersSupport == other.commitCharactersSupport &&
+ listEqual(documentationFormat, other.documentationFormat,
+ (MarkupKind a, MarkupKind b) => a == b) &&
+ deprecatedSupport == other.deprecatedSupport &&
+ preselectSupport == other.preselectSupport &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, snippetSupport.hashCode);
+ hash = JenkinsSmiHash.combine(hash, commitCharactersSupport.hashCode);
+ hash = JenkinsSmiHash.combine(hash, documentationFormat.hashCode);
+ hash = JenkinsSmiHash.combine(hash, deprecatedSupport.hashCode);
+ hash = JenkinsSmiHash.combine(hash, preselectSupport.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+class TextDocumentClientCapabilitiesCompletionItemKind implements ToJsonable {
+ TextDocumentClientCapabilitiesCompletionItemKind(this.valueSet);
+ static TextDocumentClientCapabilitiesCompletionItemKind fromJson(
+ Map<String, dynamic> json) {
+ final valueSet = json['valueSet']
+ ?.map((item) => item != null ? CompletionItemKind.fromJson(item) : null)
+ ?.cast<CompletionItemKind>()
+ ?.toList();
+ return new TextDocumentClientCapabilitiesCompletionItemKind(valueSet);
+ }
+
+ /// The completion item kind values the client supports. When this property
+ /// exists the client also guarantees that it will handle values outside its
+ /// set gracefully and falls back to a default value when unknown.
+ ///
+ /// If this property is not present the client only supports the completion
+ /// items kinds from `Text` to `Reference` as defined in the initial version
+ /// of the protocol.
+ final List<CompletionItemKind> valueSet;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
+ if (valueSet != null) {
+ __result['valueSet'] = valueSet;
+ }
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic>;
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentClientCapabilitiesCompletionItemKind) {
+ return listEqual(valueSet, other.valueSet,
+ (CompletionItemKind a, CompletionItemKind b) => a == b) &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, valueSet.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+class TextDocumentClientCapabilitiesDefinition implements ToJsonable {
+ TextDocumentClientCapabilitiesDefinition(this.dynamicRegistration);
+ static TextDocumentClientCapabilitiesDefinition fromJson(
+ Map<String, dynamic> json) {
+ final dynamicRegistration = json['dynamicRegistration'];
+ return new TextDocumentClientCapabilitiesDefinition(dynamicRegistration);
+ }
+
+ /// Whether definition supports dynamic registration.
+ final bool dynamicRegistration;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
+ if (dynamicRegistration != null) {
+ __result['dynamicRegistration'] = dynamicRegistration;
+ }
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic>;
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentClientCapabilitiesDefinition) {
+ return dynamicRegistration == other.dynamicRegistration && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, dynamicRegistration.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+class TextDocumentClientCapabilitiesDocumentHighlight implements ToJsonable {
+ TextDocumentClientCapabilitiesDocumentHighlight(this.dynamicRegistration);
+ static TextDocumentClientCapabilitiesDocumentHighlight fromJson(
+ Map<String, dynamic> json) {
+ final dynamicRegistration = json['dynamicRegistration'];
+ return new TextDocumentClientCapabilitiesDocumentHighlight(
+ dynamicRegistration);
+ }
+
+ /// Whether document highlight supports dynamic registration.
+ final bool dynamicRegistration;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
+ if (dynamicRegistration != null) {
+ __result['dynamicRegistration'] = dynamicRegistration;
+ }
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic>;
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentClientCapabilitiesDocumentHighlight) {
+ return dynamicRegistration == other.dynamicRegistration && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, dynamicRegistration.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+class TextDocumentClientCapabilitiesDocumentLink implements ToJsonable {
+ TextDocumentClientCapabilitiesDocumentLink(this.dynamicRegistration);
+ static TextDocumentClientCapabilitiesDocumentLink fromJson(
+ Map<String, dynamic> json) {
+ final dynamicRegistration = json['dynamicRegistration'];
+ return new TextDocumentClientCapabilitiesDocumentLink(dynamicRegistration);
+ }
+
+ /// Whether document link supports dynamic registration.
+ final bool dynamicRegistration;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
+ if (dynamicRegistration != null) {
+ __result['dynamicRegistration'] = dynamicRegistration;
+ }
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic>;
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentClientCapabilitiesDocumentLink) {
+ return dynamicRegistration == other.dynamicRegistration && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, dynamicRegistration.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+class TextDocumentClientCapabilitiesDocumentSymbol implements ToJsonable {
+ TextDocumentClientCapabilitiesDocumentSymbol(this.dynamicRegistration,
+ this.symbolKind, this.hierarchicalDocumentSymbolSupport);
+ static TextDocumentClientCapabilitiesDocumentSymbol fromJson(
+ Map<String, dynamic> json) {
+ final dynamicRegistration = json['dynamicRegistration'];
+ final symbolKind = json['symbolKind'] != null
+ ? TextDocumentClientCapabilitiesSymbolKind.fromJson(json['symbolKind'])
+ : null;
+ final hierarchicalDocumentSymbolSupport =
+ json['hierarchicalDocumentSymbolSupport'];
+ return new TextDocumentClientCapabilitiesDocumentSymbol(
+ dynamicRegistration, symbolKind, hierarchicalDocumentSymbolSupport);
+ }
+
+ /// Whether document symbol supports dynamic registration.
+ final bool dynamicRegistration;
+
+ /// The client supports hierarchical document symbols.
+ final bool hierarchicalDocumentSymbolSupport;
+
+ /// Specific capabilities for the `SymbolKind`.
+ final TextDocumentClientCapabilitiesSymbolKind symbolKind;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
+ if (dynamicRegistration != null) {
+ __result['dynamicRegistration'] = dynamicRegistration;
+ }
+ if (symbolKind != null) {
+ __result['symbolKind'] = symbolKind;
+ }
+ if (hierarchicalDocumentSymbolSupport != null) {
+ __result['hierarchicalDocumentSymbolSupport'] =
+ hierarchicalDocumentSymbolSupport;
+ }
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic>;
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentClientCapabilitiesDocumentSymbol) {
+ return dynamicRegistration == other.dynamicRegistration &&
+ symbolKind == other.symbolKind &&
+ hierarchicalDocumentSymbolSupport ==
+ other.hierarchicalDocumentSymbolSupport &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, dynamicRegistration.hashCode);
+ hash = JenkinsSmiHash.combine(hash, symbolKind.hashCode);
+ hash = JenkinsSmiHash.combine(
+ hash, hierarchicalDocumentSymbolSupport.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+class TextDocumentClientCapabilitiesFoldingRange implements ToJsonable {
+ TextDocumentClientCapabilitiesFoldingRange(
+ this.dynamicRegistration, this.rangeLimit, this.lineFoldingOnly);
+ static TextDocumentClientCapabilitiesFoldingRange fromJson(
+ Map<String, dynamic> json) {
+ final dynamicRegistration = json['dynamicRegistration'];
+ final rangeLimit = json['rangeLimit'];
+ final lineFoldingOnly = json['lineFoldingOnly'];
+ return new TextDocumentClientCapabilitiesFoldingRange(
+ dynamicRegistration, rangeLimit, lineFoldingOnly);
+ }
+
+ /// Whether implementation supports dynamic registration for folding range
+ /// providers. If this is set to `true` the client supports the new
+ /// `(FoldingRangeProviderOptions & TextDocumentRegistrationOptions &
+ /// StaticRegistrationOptions)` return value for the corresponding server
+ /// capability as well.
+ final bool dynamicRegistration;
+
+ /// If set, the client signals that it only supports folding complete lines.
+ /// If set, client will ignore specified `startCharacter` and `endCharacter`
+ /// properties in a FoldingRange.
+ final bool lineFoldingOnly;
+
+ /// The maximum number of folding ranges that the client prefers to receive
+ /// per document. The value serves as a hint, servers are free to follow the
+ /// limit.
+ final num rangeLimit;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
+ if (dynamicRegistration != null) {
+ __result['dynamicRegistration'] = dynamicRegistration;
+ }
+ if (rangeLimit != null) {
+ __result['rangeLimit'] = rangeLimit;
+ }
+ if (lineFoldingOnly != null) {
+ __result['lineFoldingOnly'] = lineFoldingOnly;
+ }
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic>;
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentClientCapabilitiesFoldingRange) {
+ return dynamicRegistration == other.dynamicRegistration &&
+ rangeLimit == other.rangeLimit &&
+ lineFoldingOnly == other.lineFoldingOnly &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, dynamicRegistration.hashCode);
+ hash = JenkinsSmiHash.combine(hash, rangeLimit.hashCode);
+ hash = JenkinsSmiHash.combine(hash, lineFoldingOnly.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+class TextDocumentClientCapabilitiesFormatting implements ToJsonable {
+ TextDocumentClientCapabilitiesFormatting(this.dynamicRegistration);
+ static TextDocumentClientCapabilitiesFormatting fromJson(
+ Map<String, dynamic> json) {
+ final dynamicRegistration = json['dynamicRegistration'];
+ return new TextDocumentClientCapabilitiesFormatting(dynamicRegistration);
+ }
+
+ /// Whether formatting supports dynamic registration.
+ final bool dynamicRegistration;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
+ if (dynamicRegistration != null) {
+ __result['dynamicRegistration'] = dynamicRegistration;
+ }
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic>;
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentClientCapabilitiesFormatting) {
+ return dynamicRegistration == other.dynamicRegistration && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, dynamicRegistration.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+class TextDocumentClientCapabilitiesHover implements ToJsonable {
+ TextDocumentClientCapabilitiesHover(
+ this.dynamicRegistration, this.contentFormat);
+ static TextDocumentClientCapabilitiesHover fromJson(
+ Map<String, dynamic> json) {
+ final dynamicRegistration = json['dynamicRegistration'];
+ final contentFormat = json['contentFormat']
+ ?.map((item) => item != null ? MarkupKind.fromJson(item) : null)
+ ?.cast<MarkupKind>()
+ ?.toList();
+ return new TextDocumentClientCapabilitiesHover(
+ dynamicRegistration, contentFormat);
+ }
+
+ /// The client supports the follow content formats for the content property.
+ /// The order describes the preferred format of the client.
+ final List<MarkupKind> contentFormat;
+
+ /// Whether hover supports dynamic registration.
+ final bool dynamicRegistration;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
+ if (dynamicRegistration != null) {
+ __result['dynamicRegistration'] = dynamicRegistration;
+ }
+ if (contentFormat != null) {
+ __result['contentFormat'] = contentFormat;
+ }
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic>;
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentClientCapabilitiesHover) {
+ return dynamicRegistration == other.dynamicRegistration &&
+ listEqual(contentFormat, other.contentFormat,
+ (MarkupKind a, MarkupKind b) => a == b) &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, dynamicRegistration.hashCode);
+ hash = JenkinsSmiHash.combine(hash, contentFormat.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+class TextDocumentClientCapabilitiesImplementation implements ToJsonable {
+ TextDocumentClientCapabilitiesImplementation(this.dynamicRegistration);
+ static TextDocumentClientCapabilitiesImplementation fromJson(
+ Map<String, dynamic> json) {
+ final dynamicRegistration = json['dynamicRegistration'];
+ return new TextDocumentClientCapabilitiesImplementation(
+ dynamicRegistration);
+ }
+
+ /// Whether implementation supports dynamic registration. If this is set to
+ /// `true` the client supports the new `(TextDocumentRegistrationOptions &
+ /// StaticRegistrationOptions)` return value for the corresponding server
+ /// capability as well.
+ final bool dynamicRegistration;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
+ if (dynamicRegistration != null) {
+ __result['dynamicRegistration'] = dynamicRegistration;
+ }
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic>;
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentClientCapabilitiesImplementation) {
+ return dynamicRegistration == other.dynamicRegistration && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, dynamicRegistration.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+class TextDocumentClientCapabilitiesOnTypeFormatting implements ToJsonable {
+ TextDocumentClientCapabilitiesOnTypeFormatting(this.dynamicRegistration);
+ static TextDocumentClientCapabilitiesOnTypeFormatting fromJson(
+ Map<String, dynamic> json) {
+ final dynamicRegistration = json['dynamicRegistration'];
+ return new TextDocumentClientCapabilitiesOnTypeFormatting(
+ dynamicRegistration);
+ }
+
+ /// Whether on type formatting supports dynamic registration.
+ final bool dynamicRegistration;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
+ if (dynamicRegistration != null) {
+ __result['dynamicRegistration'] = dynamicRegistration;
+ }
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic>;
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentClientCapabilitiesOnTypeFormatting) {
+ return dynamicRegistration == other.dynamicRegistration && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, dynamicRegistration.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+class TextDocumentClientCapabilitiesPublishDiagnostics implements ToJsonable {
+ TextDocumentClientCapabilitiesPublishDiagnostics(this.relatedInformation);
+ static TextDocumentClientCapabilitiesPublishDiagnostics fromJson(
+ Map<String, dynamic> json) {
+ final relatedInformation = json['relatedInformation'];
+ return new TextDocumentClientCapabilitiesPublishDiagnostics(
+ relatedInformation);
+ }
+
+ /// Whether the clients accepts diagnostics with related information.
+ final bool relatedInformation;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
+ if (relatedInformation != null) {
+ __result['relatedInformation'] = relatedInformation;
+ }
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic>;
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentClientCapabilitiesPublishDiagnostics) {
+ return relatedInformation == other.relatedInformation && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, relatedInformation.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+class TextDocumentClientCapabilitiesRangeFormatting implements ToJsonable {
+ TextDocumentClientCapabilitiesRangeFormatting(this.dynamicRegistration);
+ static TextDocumentClientCapabilitiesRangeFormatting fromJson(
+ Map<String, dynamic> json) {
+ final dynamicRegistration = json['dynamicRegistration'];
+ return new TextDocumentClientCapabilitiesRangeFormatting(
+ dynamicRegistration);
+ }
+
+ /// Whether range formatting supports dynamic registration.
+ final bool dynamicRegistration;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
+ if (dynamicRegistration != null) {
+ __result['dynamicRegistration'] = dynamicRegistration;
+ }
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic>;
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentClientCapabilitiesRangeFormatting) {
+ return dynamicRegistration == other.dynamicRegistration && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, dynamicRegistration.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+class TextDocumentClientCapabilitiesReferences implements ToJsonable {
+ TextDocumentClientCapabilitiesReferences(this.dynamicRegistration);
+ static TextDocumentClientCapabilitiesReferences fromJson(
+ Map<String, dynamic> json) {
+ final dynamicRegistration = json['dynamicRegistration'];
+ return new TextDocumentClientCapabilitiesReferences(dynamicRegistration);
+ }
+
+ /// Whether references supports dynamic registration.
+ final bool dynamicRegistration;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
+ if (dynamicRegistration != null) {
+ __result['dynamicRegistration'] = dynamicRegistration;
+ }
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic>;
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentClientCapabilitiesReferences) {
+ return dynamicRegistration == other.dynamicRegistration && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, dynamicRegistration.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+class TextDocumentClientCapabilitiesRename implements ToJsonable {
+ TextDocumentClientCapabilitiesRename(
+ this.dynamicRegistration, this.prepareSupport);
+ static TextDocumentClientCapabilitiesRename fromJson(
+ Map<String, dynamic> json) {
+ final dynamicRegistration = json['dynamicRegistration'];
+ final prepareSupport = json['prepareSupport'];
+ return new TextDocumentClientCapabilitiesRename(
+ dynamicRegistration, prepareSupport);
+ }
+
+ /// Whether rename supports dynamic registration.
+ final bool dynamicRegistration;
+
+ /// The client supports testing for validity of rename operations before
+ /// execution.
+ final bool prepareSupport;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
+ if (dynamicRegistration != null) {
+ __result['dynamicRegistration'] = dynamicRegistration;
+ }
+ if (prepareSupport != null) {
+ __result['prepareSupport'] = prepareSupport;
+ }
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic>;
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentClientCapabilitiesRename) {
+ return dynamicRegistration == other.dynamicRegistration &&
+ prepareSupport == other.prepareSupport &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, dynamicRegistration.hashCode);
+ hash = JenkinsSmiHash.combine(hash, prepareSupport.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+class TextDocumentClientCapabilitiesSignatureHelp implements ToJsonable {
+ TextDocumentClientCapabilitiesSignatureHelp(
+ this.dynamicRegistration, this.signatureInformation);
+ static TextDocumentClientCapabilitiesSignatureHelp fromJson(
+ Map<String, dynamic> json) {
+ final dynamicRegistration = json['dynamicRegistration'];
+ final signatureInformation = json['signatureInformation'] != null
+ ? TextDocumentClientCapabilitiesSignatureInformation.fromJson(
+ json['signatureInformation'])
+ : null;
+ return new TextDocumentClientCapabilitiesSignatureHelp(
+ dynamicRegistration, signatureInformation);
+ }
+
+ /// Whether signature help supports dynamic registration.
+ final bool dynamicRegistration;
+
+ /// The client supports the following `SignatureInformation` specific
+ /// properties.
+ final TextDocumentClientCapabilitiesSignatureInformation signatureInformation;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
+ if (dynamicRegistration != null) {
+ __result['dynamicRegistration'] = dynamicRegistration;
+ }
+ if (signatureInformation != null) {
+ __result['signatureInformation'] = signatureInformation;
+ }
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic>;
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentClientCapabilitiesSignatureHelp) {
+ return dynamicRegistration == other.dynamicRegistration &&
+ signatureInformation == other.signatureInformation &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, dynamicRegistration.hashCode);
+ hash = JenkinsSmiHash.combine(hash, signatureInformation.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+class TextDocumentClientCapabilitiesSignatureInformation implements ToJsonable {
+ TextDocumentClientCapabilitiesSignatureInformation(this.documentationFormat);
+ static TextDocumentClientCapabilitiesSignatureInformation fromJson(
+ Map<String, dynamic> json) {
+ final documentationFormat = json['documentationFormat']
+ ?.map((item) => item != null ? MarkupKind.fromJson(item) : null)
+ ?.cast<MarkupKind>()
+ ?.toList();
+ return new TextDocumentClientCapabilitiesSignatureInformation(
+ documentationFormat);
+ }
+
+ /// The client supports the follow content formats for the documentation
+ /// property. The order describes the preferred format of the client.
+ final List<MarkupKind> documentationFormat;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
+ if (documentationFormat != null) {
+ __result['documentationFormat'] = documentationFormat;
+ }
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic>;
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentClientCapabilitiesSignatureInformation) {
+ return listEqual(documentationFormat, other.documentationFormat,
+ (MarkupKind a, MarkupKind b) => a == b) &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, documentationFormat.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+class TextDocumentClientCapabilitiesSymbolKind implements ToJsonable {
+ TextDocumentClientCapabilitiesSymbolKind(this.valueSet);
+ static TextDocumentClientCapabilitiesSymbolKind fromJson(
+ Map<String, dynamic> json) {
+ final valueSet = json['valueSet']
+ ?.map((item) => item != null ? SymbolKind.fromJson(item) : null)
+ ?.cast<SymbolKind>()
+ ?.toList();
+ return new TextDocumentClientCapabilitiesSymbolKind(valueSet);
+ }
+
+ /// The symbol kind values the client supports. When this property exists the
+ /// client also guarantees that it will handle values outside its set
+ /// gracefully and falls back to a default value when unknown.
+ ///
+ /// If this property is not present the client only supports the symbol kinds
+ /// from `File` to `Array` as defined in the initial version of the protocol.
+ final List<SymbolKind> valueSet;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
+ if (valueSet != null) {
+ __result['valueSet'] = valueSet;
+ }
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic>;
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentClientCapabilitiesSymbolKind) {
+ return listEqual(valueSet, other.valueSet,
+ (SymbolKind a, SymbolKind b) => a == b) &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, valueSet.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+class TextDocumentClientCapabilitiesSynchronization implements ToJsonable {
+ TextDocumentClientCapabilitiesSynchronization(this.dynamicRegistration,
+ this.willSave, this.willSaveWaitUntil, this.didSave);
+ static TextDocumentClientCapabilitiesSynchronization fromJson(
+ Map<String, dynamic> json) {
final dynamicRegistration = json['dynamicRegistration'];
final willSave = json['willSave'];
final willSaveWaitUntil = json['willSaveWaitUntil'];
final didSave = json['didSave'];
- return new TextDocumentClientCapabilities(
+ return new TextDocumentClientCapabilitiesSynchronization(
dynamicRegistration, willSave, willSaveWaitUntil, didSave);
}
/// The client supports did save notifications.
final bool didSave;
- /// Whether text document synchronization supports
- /// dynamic registration.
+ /// Whether text document synchronization supports dynamic registration.
final bool dynamicRegistration;
- /// The client supports sending will save
- /// notifications.
+ /// The client supports sending will save notifications.
final bool willSave;
- /// The client supports sending a will save request
- /// and waits for a response providing text edits
- /// which will be applied to the document before it is
+ /// The client supports sending a will save request and waits for a response
+ /// providing text edits which will be applied to the document before it is
/// saved.
final bool willSaveWaitUntil;
@@ -5304,20 +9468,90 @@
static bool canParse(Object obj) {
return obj is Map<String, dynamic>;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentClientCapabilitiesSynchronization) {
+ return dynamicRegistration == other.dynamicRegistration &&
+ willSave == other.willSave &&
+ willSaveWaitUntil == other.willSaveWaitUntil &&
+ didSave == other.didSave &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, dynamicRegistration.hashCode);
+ hash = JenkinsSmiHash.combine(hash, willSave.hashCode);
+ hash = JenkinsSmiHash.combine(hash, willSaveWaitUntil.hashCode);
+ hash = JenkinsSmiHash.combine(hash, didSave.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
-/// An event describing a change to a text document. If
-/// range and rangeLength are omitted the new text is
-/// considered to be the full content of the document.
+class TextDocumentClientCapabilitiesTypeDefinition implements ToJsonable {
+ TextDocumentClientCapabilitiesTypeDefinition(this.dynamicRegistration);
+ static TextDocumentClientCapabilitiesTypeDefinition fromJson(
+ Map<String, dynamic> json) {
+ final dynamicRegistration = json['dynamicRegistration'];
+ return new TextDocumentClientCapabilitiesTypeDefinition(
+ dynamicRegistration);
+ }
+
+ /// Whether typeDefinition supports dynamic registration. If this is set to
+ /// `true` the client supports the new `(TextDocumentRegistrationOptions &
+ /// StaticRegistrationOptions)` return value for the corresponding server
+ /// capability as well.
+ final bool dynamicRegistration;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
+ if (dynamicRegistration != null) {
+ __result['dynamicRegistration'] = dynamicRegistration;
+ }
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic>;
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentClientCapabilitiesTypeDefinition) {
+ return dynamicRegistration == other.dynamicRegistration && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, dynamicRegistration.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+/// An event describing a change to a text document. If range and rangeLength
+/// are omitted the new text is considered to be the full content of the
+/// document.
class TextDocumentContentChangeEvent implements ToJsonable {
TextDocumentContentChangeEvent(this.range, this.rangeLength, this.text) {
if (text == null) {
throw 'text is required but was not provided';
}
}
- factory TextDocumentContentChangeEvent.fromJson(Map<String, dynamic> json) {
- final range =
- json['range'] != null ? new Range.fromJson(json['range']) : null;
+ static TextDocumentContentChangeEvent fromJson(Map<String, dynamic> json) {
+ final range = json['range'] != null ? Range.fromJson(json['range']) : null;
final rangeLength = json['rangeLength'];
final text = json['text'];
return new TextDocumentContentChangeEvent(range, rangeLength, text);
@@ -5349,9 +9583,32 @@
obj.containsKey('text') &&
obj['text'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentContentChangeEvent) {
+ return range == other.range &&
+ rangeLength == other.rangeLength &&
+ text == other.text &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, range.hashCode);
+ hash = JenkinsSmiHash.combine(hash, rangeLength.hashCode);
+ hash = JenkinsSmiHash.combine(hash, text.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
-class TextDocumentEdit implements FileOperation, ToJsonable {
+class TextDocumentEdit implements ToJsonable {
TextDocumentEdit(this.textDocument, this.edits) {
if (textDocument == null) {
throw 'textDocument is required but was not provided';
@@ -5360,12 +9617,12 @@
throw 'edits is required but was not provided';
}
}
- factory TextDocumentEdit.fromJson(Map<String, dynamic> json) {
+ static TextDocumentEdit fromJson(Map<String, dynamic> json) {
final textDocument = json['textDocument'] != null
- ? new VersionedTextDocumentIdentifier.fromJson(json['textDocument'])
+ ? VersionedTextDocumentIdentifier.fromJson(json['textDocument'])
: null;
final edits = json['edits']
- ?.map((item) => item != null ? new TextEdit.fromJson(item) : null)
+ ?.map((item) => item != null ? TextEdit.fromJson(item) : null)
?.cast<TextEdit>()
?.toList();
return new TextDocumentEdit(textDocument, edits);
@@ -5394,6 +9651,27 @@
(obj['edits'].length == 0 ||
obj['edits'].every((item) => TextEdit.canParse(item))));
}
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentEdit) {
+ return textDocument == other.textDocument &&
+ listEqual(edits, other.edits, (TextEdit a, TextEdit b) => a == b) &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, textDocument.hashCode);
+ hash = JenkinsSmiHash.combine(hash, edits.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class TextDocumentIdentifier implements ToJsonable {
@@ -5402,7 +9680,7 @@
throw 'uri is required but was not provided';
}
}
- factory TextDocumentIdentifier.fromJson(Map<String, dynamic> json) {
+ static TextDocumentIdentifier fromJson(Map<String, dynamic> json) {
final uri = json['uri'];
return new TextDocumentIdentifier(uri);
}
@@ -5421,6 +9699,24 @@
obj.containsKey('uri') &&
obj['uri'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentIdentifier) {
+ return uri == other.uri && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, uri.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class TextDocumentItem implements ToJsonable {
@@ -5438,7 +9734,7 @@
throw 'text is required but was not provided';
}
}
- factory TextDocumentItem.fromJson(Map<String, dynamic> json) {
+ static TextDocumentItem fromJson(Map<String, dynamic> json) {
final uri = json['uri'];
final languageId = json['languageId'];
final version = json['version'];
@@ -5455,8 +9751,8 @@
/// The text document's URI.
final String uri;
- /// The version number of this document (it will
- /// increase after each change, including undo/redo).
+ /// The version number of this document (it will increase after each change,
+ /// including undo/redo).
final num version;
Map<String, dynamic> toJson() {
@@ -5481,6 +9777,31 @@
obj.containsKey('text') &&
obj['text'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentItem) {
+ return uri == other.uri &&
+ languageId == other.languageId &&
+ version == other.version &&
+ text == other.text &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, uri.hashCode);
+ hash = JenkinsSmiHash.combine(hash, languageId.hashCode);
+ hash = JenkinsSmiHash.combine(hash, version.hashCode);
+ hash = JenkinsSmiHash.combine(hash, text.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class TextDocumentPositionParams implements ToJsonable {
@@ -5492,13 +9813,12 @@
throw 'position is required but was not provided';
}
}
- factory TextDocumentPositionParams.fromJson(Map<String, dynamic> json) {
+ static TextDocumentPositionParams fromJson(Map<String, dynamic> json) {
final textDocument = json['textDocument'] != null
- ? new TextDocumentIdentifier.fromJson(json['textDocument'])
+ ? TextDocumentIdentifier.fromJson(json['textDocument'])
: null;
- final position = json['position'] != null
- ? new Position.fromJson(json['position'])
- : null;
+ final position =
+ json['position'] != null ? Position.fromJson(json['position']) : null;
return new TextDocumentPositionParams(textDocument, position);
}
@@ -5524,21 +9844,41 @@
obj.containsKey('position') &&
Position.canParse(obj['position']);
}
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentPositionParams) {
+ return textDocument == other.textDocument &&
+ position == other.position &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, textDocument.hashCode);
+ hash = JenkinsSmiHash.combine(hash, position.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class TextDocumentRegistrationOptions implements ToJsonable {
TextDocumentRegistrationOptions(this.documentSelector);
- factory TextDocumentRegistrationOptions.fromJson(Map<String, dynamic> json) {
+ static TextDocumentRegistrationOptions fromJson(Map<String, dynamic> json) {
final documentSelector = json['documentSelector']
- ?.map((item) => item != null ? new DocumentFilter.fromJson(item) : null)
+ ?.map((item) => item != null ? DocumentFilter.fromJson(item) : null)
?.cast<DocumentFilter>()
?.toList();
return new TextDocumentRegistrationOptions(documentSelector);
}
- /// A document selector to identify the scope of the
- /// registration. If set to null the document selector
- /// provided on the client side will be used.
+ /// A document selector to identify the scope of the registration. If set to
+ /// null the document selector provided on the client side will be used.
final List<DocumentFilter> documentSelector;
Map<String, dynamic> toJson() {
@@ -5555,6 +9895,24 @@
obj['documentSelector']
.every((item) => DocumentFilter.canParse(item))));
}
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentRegistrationOptions) {
+ return documentSelector == other.documentSelector && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, documentSelector.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// Represents reasons why a text document is saved.
@@ -5562,7 +9920,7 @@
const TextDocumentSaveReason._(this._value);
const TextDocumentSaveReason.fromJson(this._value);
- final Object _value;
+ final num _value;
static bool canParse(Object obj) {
switch (obj) {
@@ -5574,8 +9932,8 @@
return false;
}
- /// Manually triggered, e.g. by the user pressing
- /// save, by starting debugging, or by an API call.
+ /// Manually triggered, e.g. by the user pressing save, by starting debugging,
+ /// or by an API call.
static const Manual = const TextDocumentSaveReason._(1);
/// Automatic after a delay.
@@ -5598,25 +9956,22 @@
class TextDocumentSaveRegistrationOptions
implements TextDocumentRegistrationOptions, ToJsonable {
TextDocumentSaveRegistrationOptions(this.includeText, this.documentSelector);
- factory TextDocumentSaveRegistrationOptions.fromJson(
+ static TextDocumentSaveRegistrationOptions fromJson(
Map<String, dynamic> json) {
final includeText = json['includeText'];
final documentSelector = json['documentSelector']
- ?.map((item) => item != null ? new DocumentFilter.fromJson(item) : null)
+ ?.map((item) => item != null ? DocumentFilter.fromJson(item) : null)
?.cast<DocumentFilter>()
?.toList();
return new TextDocumentSaveRegistrationOptions(
includeText, documentSelector);
}
- /// A document selector to identify the scope of the
- /// registration. If set to null the document
- /// selector provided on the client side will be
- /// used.
+ /// A document selector to identify the scope of the registration. If set to
+ /// null the document selector provided on the client side will be used.
final List<DocumentFilter> documentSelector;
- /// The client is supposed to include the content on
- /// save.
+ /// The client is supposed to include the content on save.
final bool includeText;
Map<String, dynamic> toJson() {
@@ -5636,15 +9991,36 @@
obj['documentSelector']
.every((item) => DocumentFilter.canParse(item))));
}
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentSaveRegistrationOptions) {
+ return includeText == other.includeText &&
+ documentSelector == other.documentSelector &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, includeText.hashCode);
+ hash = JenkinsSmiHash.combine(hash, documentSelector.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
-/// Defines how the host (editor) should sync document
-/// changes to the language server.
+/// Defines how the host (editor) should sync document changes to the language
+/// server.
class TextDocumentSyncKind {
const TextDocumentSyncKind._(this._value);
const TextDocumentSyncKind.fromJson(this._value);
- final Object _value;
+ final num _value;
static bool canParse(Object obj) {
switch (obj) {
@@ -5659,13 +10035,11 @@
/// Documents should not be synced at all.
static const None = const TextDocumentSyncKind._(0);
- /// Documents are synced by always sending the
- /// full content of the document.
+ /// Documents are synced by always sending the full content of the document.
static const Full = const TextDocumentSyncKind._(1);
- /// Documents are synced by sending the full
- /// content on open. After that only incremental
- /// updates to the document are send.
+ /// Documents are synced by sending the full content on open. After that only
+ /// incremental updates to the document are send.
static const Incremental = const TextDocumentSyncKind._(2);
Object toJson() => _value;
@@ -5682,39 +10056,35 @@
class TextDocumentSyncOptions implements ToJsonable {
TextDocumentSyncOptions(this.openClose, this.change, this.willSave,
this.willSaveWaitUntil, this.save);
- factory TextDocumentSyncOptions.fromJson(Map<String, dynamic> json) {
+ static TextDocumentSyncOptions fromJson(Map<String, dynamic> json) {
final openClose = json['openClose'];
final change = json['change'] != null
- ? new TextDocumentSyncKind.fromJson(json['change'])
+ ? TextDocumentSyncKind.fromJson(json['change'])
: null;
final willSave = json['willSave'];
final willSaveWaitUntil = json['willSaveWaitUntil'];
final save =
- json['save'] != null ? new SaveOptions.fromJson(json['save']) : null;
+ json['save'] != null ? SaveOptions.fromJson(json['save']) : null;
return new TextDocumentSyncOptions(
openClose, change, willSave, willSaveWaitUntil, save);
}
- /// Change notifications are sent to the server.
- /// See TextDocumentSyncKind.None,
- /// TextDocumentSyncKind.Full and
- /// TextDocumentSyncKind.Incremental. If omitted
- /// it defaults to TextDocumentSyncKind.None.
+ /// Change notifications are sent to the server. See
+ /// TextDocumentSyncKind.None, TextDocumentSyncKind.Full and
+ /// TextDocumentSyncKind.Incremental. If omitted it defaults to
+ /// TextDocumentSyncKind.None.
final TextDocumentSyncKind change;
- /// Open and close notifications are sent to the
- /// server.
+ /// Open and close notifications are sent to the server.
final bool openClose;
/// Save notifications are sent to the server.
final SaveOptions save;
- /// Will save notifications are sent to the
- /// server.
+ /// Will save notifications are sent to the server.
final bool willSave;
- /// Will save wait until requests are sent to the
- /// server.
+ /// Will save wait until requests are sent to the server.
final bool willSaveWaitUntil;
Map<String, dynamic> toJson() {
@@ -5740,6 +10110,33 @@
static bool canParse(Object obj) {
return obj is Map<String, dynamic>;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is TextDocumentSyncOptions) {
+ return openClose == other.openClose &&
+ change == other.change &&
+ willSave == other.willSave &&
+ willSaveWaitUntil == other.willSaveWaitUntil &&
+ save == other.save &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, openClose.hashCode);
+ hash = JenkinsSmiHash.combine(hash, change.hashCode);
+ hash = JenkinsSmiHash.combine(hash, willSave.hashCode);
+ hash = JenkinsSmiHash.combine(hash, willSaveWaitUntil.hashCode);
+ hash = JenkinsSmiHash.combine(hash, save.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class TextEdit implements ToJsonable {
@@ -5751,20 +10148,17 @@
throw 'newText is required but was not provided';
}
}
- factory TextEdit.fromJson(Map<String, dynamic> json) {
- final range =
- json['range'] != null ? new Range.fromJson(json['range']) : null;
+ static TextEdit fromJson(Map<String, dynamic> json) {
+ final range = json['range'] != null ? Range.fromJson(json['range']) : null;
final newText = json['newText'];
return new TextEdit(range, newText);
}
- /// The string to be inserted. For delete
- /// operations use an empty string.
+ /// The string to be inserted. For delete operations use an empty string.
final String newText;
- /// The range of the text document to be
- /// manipulated. To insert text into a document
- /// create a range where start === end.
+ /// The range of the text document to be manipulated. To insert text into a
+ /// document create a range where start === end.
final Range range;
Map<String, dynamic> toJson() {
@@ -5782,6 +10176,25 @@
obj.containsKey('newText') &&
obj['newText'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is TextEdit) {
+ return range == other.range && newText == other.newText && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, range.hashCode);
+ hash = JenkinsSmiHash.combine(hash, newText.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// General parameters to unregister a capability.
@@ -5794,15 +10207,14 @@
throw 'method is required but was not provided';
}
}
- factory Unregistration.fromJson(Map<String, dynamic> json) {
+ static Unregistration fromJson(Map<String, dynamic> json) {
final id = json['id'];
final method = json['method'];
return new Unregistration(id, method);
}
- /// The id used to unregister the request or
- /// notification. Usually an id provided during
- /// the register request.
+ /// The id used to unregister the request or notification. Usually an id
+ /// provided during the register request.
final String id;
/// The method / capability to unregister for.
@@ -5822,6 +10234,25 @@
obj.containsKey('method') &&
obj['method'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is Unregistration) {
+ return id == other.id && method == other.method && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, id.hashCode);
+ hash = JenkinsSmiHash.combine(hash, method.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class UnregistrationParams implements ToJsonable {
@@ -5830,9 +10261,9 @@
throw 'unregisterations is required but was not provided';
}
}
- factory UnregistrationParams.fromJson(Map<String, dynamic> json) {
+ static UnregistrationParams fromJson(Map<String, dynamic> json) {
final unregisterations = json['unregisterations']
- ?.map((item) => item != null ? new Unregistration.fromJson(item) : null)
+ ?.map((item) => item != null ? Unregistration.fromJson(item) : null)
?.cast<Unregistration>()
?.toList();
return new UnregistrationParams(unregisterations);
@@ -5855,6 +10286,26 @@
obj['unregisterations']
.every((item) => Unregistration.canParse(item))));
}
+
+ @override
+ bool operator ==(other) {
+ if (other is UnregistrationParams) {
+ return listEqual(unregisterations, other.unregisterations,
+ (Unregistration a, Unregistration b) => a == b) &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, unregisterations.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class VersionedTextDocumentIdentifier
@@ -5864,7 +10315,7 @@
throw 'uri is required but was not provided';
}
}
- factory VersionedTextDocumentIdentifier.fromJson(Map<String, dynamic> json) {
+ static VersionedTextDocumentIdentifier fromJson(Map<String, dynamic> json) {
final version = json['version'];
final uri = json['uri'];
return new VersionedTextDocumentIdentifier(version, uri);
@@ -5873,19 +10324,14 @@
/// The text document's URI.
final String uri;
- /// The version number of this document. If a
- /// versioned text document identifier is sent
- /// from the server to the client and the file is
- /// not open in the editor (the server has not
- /// received an open notification before) the
- /// server can send `null` to indicate that the
- /// version is known and the content on disk is
- /// the truth (as speced with document content
- /// ownership).
+ /// The version number of this document. If a versioned text document
+ /// identifier is sent from the server to the client and the file is not open
+ /// in the editor (the server has not received an open notification before)
+ /// the server can send `null` to indicate that the version is known and the
+ /// content on disk is the truth (as speced with document content ownership).
///
- /// The version number of a document will increase
- /// after each change, including undo/redo. The
- /// number doesn't need to be consecutive.
+ /// The version number of a document will increase after each change,
+ /// including undo/redo. The number doesn't need to be consecutive.
final num version;
Map<String, dynamic> toJson() {
@@ -5902,13 +10348,32 @@
obj.containsKey('uri') &&
obj['uri'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is VersionedTextDocumentIdentifier) {
+ return version == other.version && uri == other.uri && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, version.hashCode);
+ hash = JenkinsSmiHash.combine(hash, uri.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class WatchKind {
const WatchKind._(this._value);
const WatchKind.fromJson(this._value);
- final Object _value;
+ final num _value;
static bool canParse(Object obj) {
switch (obj) {
@@ -5940,8 +10405,7 @@
bool operator ==(o) => o is WatchKind && o._value == _value;
}
-/// The parameters send in a will save text
-/// document notification.
+/// The parameters send in a will save text document notification.
class WillSaveTextDocumentParams implements ToJsonable {
WillSaveTextDocumentParams(this.textDocument, this.reason) {
if (textDocument == null) {
@@ -5951,9 +10415,9 @@
throw 'reason is required but was not provided';
}
}
- factory WillSaveTextDocumentParams.fromJson(Map<String, dynamic> json) {
+ static WillSaveTextDocumentParams fromJson(Map<String, dynamic> json) {
final textDocument = json['textDocument'] != null
- ? new TextDocumentIdentifier.fromJson(json['textDocument'])
+ ? TextDocumentIdentifier.fromJson(json['textDocument'])
: null;
final reason = json['reason'];
return new WillSaveTextDocumentParams(textDocument, reason);
@@ -5980,50 +10444,439 @@
obj.containsKey('reason') &&
obj['reason'] is num;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is WillSaveTextDocumentParams) {
+ return textDocument == other.textDocument &&
+ reason == other.reason &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, textDocument.hashCode);
+ hash = JenkinsSmiHash.combine(hash, reason.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// Workspace specific client capabilities.
class WorkspaceClientCapabilities implements ToJsonable {
- WorkspaceClientCapabilities(this.applyEdit, this.documentChanges,
- this.resourceOperations, this.failureHandling);
- factory WorkspaceClientCapabilities.fromJson(Map<String, dynamic> json) {
+ WorkspaceClientCapabilities(
+ this.applyEdit,
+ this.workspaceEdit,
+ this.didChangeConfiguration,
+ this.didChangeWatchedFiles,
+ this.symbol,
+ this.executeCommand,
+ this.workspaceFolders,
+ this.configuration);
+ static WorkspaceClientCapabilities fromJson(Map<String, dynamic> json) {
final applyEdit = json['applyEdit'];
- final documentChanges = json['documentChanges'];
- final resourceOperations = json['resourceOperations']
- ?.map((item) =>
- item != null ? new ResourceOperationKind.fromJson(item) : null)
- ?.cast<ResourceOperationKind>()
- ?.toList();
- final failureHandling = json['failureHandling'] != null
- ? new FailureHandlingKind.fromJson(json['failureHandling'])
+ final workspaceEdit = json['workspaceEdit'] != null
+ ? WorkspaceClientCapabilitiesWorkspaceEdit.fromJson(
+ json['workspaceEdit'])
: null;
+ final didChangeConfiguration = json['didChangeConfiguration'] != null
+ ? WorkspaceClientCapabilitiesDidChangeConfiguration.fromJson(
+ json['didChangeConfiguration'])
+ : null;
+ final didChangeWatchedFiles = json['didChangeWatchedFiles'] != null
+ ? WorkspaceClientCapabilitiesDidChangeWatchedFiles.fromJson(
+ json['didChangeWatchedFiles'])
+ : null;
+ final symbol = json['symbol'] != null
+ ? WorkspaceClientCapabilitiesSymbol.fromJson(json['symbol'])
+ : null;
+ final executeCommand = json['executeCommand'] != null
+ ? WorkspaceClientCapabilitiesExecuteCommand.fromJson(
+ json['executeCommand'])
+ : null;
+ final workspaceFolders = json['workspaceFolders'];
+ final configuration = json['configuration'];
return new WorkspaceClientCapabilities(
- applyEdit, documentChanges, resourceOperations, failureHandling);
+ applyEdit,
+ workspaceEdit,
+ didChangeConfiguration,
+ didChangeWatchedFiles,
+ symbol,
+ executeCommand,
+ workspaceFolders,
+ configuration);
}
- /// The client supports applying batch edits to
- /// the workspace by supporting the request
- /// 'workspace/applyEdit'
+ /// The client supports applying batch edits to the workspace by supporting
+ /// the request 'workspace/applyEdit'
final bool applyEdit;
- /// The client supports versioned document
- /// changes in `WorkspaceEdit`s
- final bool documentChanges;
+ /// The client supports `workspace/configuration` requests.
+ ///
+ /// Since 3.6.0
+ final bool configuration;
- /// The failure handling strategy of a client if
- /// applying the workspace edit failes.
- final FailureHandlingKind failureHandling;
+ /// Capabilities specific to the `workspace/didChangeConfiguration`
+ /// notification.
+ final WorkspaceClientCapabilitiesDidChangeConfiguration
+ didChangeConfiguration;
- /// The resource operations the client supports.
- /// Clients should at least support 'create',
- /// 'rename' and 'delete' files and folders.
- final List<ResourceOperationKind> resourceOperations;
+ /// Capabilities specific to the `workspace/didChangeWatchedFiles`
+ /// notification.
+ final WorkspaceClientCapabilitiesDidChangeWatchedFiles didChangeWatchedFiles;
+
+ /// Capabilities specific to the `workspace/executeCommand` request.
+ final WorkspaceClientCapabilitiesExecuteCommand executeCommand;
+
+ /// Capabilities specific to the `workspace/symbol` request.
+ final WorkspaceClientCapabilitiesSymbol symbol;
+
+ /// Capabilities specific to `WorkspaceEdit`s
+ final WorkspaceClientCapabilitiesWorkspaceEdit workspaceEdit;
+
+ /// The client has support for workspace folders.
+ ///
+ /// Since 3.6.0
+ final bool workspaceFolders;
Map<String, dynamic> toJson() {
Map<String, dynamic> __result = {};
if (applyEdit != null) {
__result['applyEdit'] = applyEdit;
}
+ if (workspaceEdit != null) {
+ __result['workspaceEdit'] = workspaceEdit;
+ }
+ if (didChangeConfiguration != null) {
+ __result['didChangeConfiguration'] = didChangeConfiguration;
+ }
+ if (didChangeWatchedFiles != null) {
+ __result['didChangeWatchedFiles'] = didChangeWatchedFiles;
+ }
+ if (symbol != null) {
+ __result['symbol'] = symbol;
+ }
+ if (executeCommand != null) {
+ __result['executeCommand'] = executeCommand;
+ }
+ if (workspaceFolders != null) {
+ __result['workspaceFolders'] = workspaceFolders;
+ }
+ if (configuration != null) {
+ __result['configuration'] = configuration;
+ }
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic>;
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is WorkspaceClientCapabilities) {
+ return applyEdit == other.applyEdit &&
+ workspaceEdit == other.workspaceEdit &&
+ didChangeConfiguration == other.didChangeConfiguration &&
+ didChangeWatchedFiles == other.didChangeWatchedFiles &&
+ symbol == other.symbol &&
+ executeCommand == other.executeCommand &&
+ workspaceFolders == other.workspaceFolders &&
+ configuration == other.configuration &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, applyEdit.hashCode);
+ hash = JenkinsSmiHash.combine(hash, workspaceEdit.hashCode);
+ hash = JenkinsSmiHash.combine(hash, didChangeConfiguration.hashCode);
+ hash = JenkinsSmiHash.combine(hash, didChangeWatchedFiles.hashCode);
+ hash = JenkinsSmiHash.combine(hash, symbol.hashCode);
+ hash = JenkinsSmiHash.combine(hash, executeCommand.hashCode);
+ hash = JenkinsSmiHash.combine(hash, workspaceFolders.hashCode);
+ hash = JenkinsSmiHash.combine(hash, configuration.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+class WorkspaceClientCapabilitiesDidChangeConfiguration implements ToJsonable {
+ WorkspaceClientCapabilitiesDidChangeConfiguration(this.dynamicRegistration);
+ static WorkspaceClientCapabilitiesDidChangeConfiguration fromJson(
+ Map<String, dynamic> json) {
+ final dynamicRegistration = json['dynamicRegistration'];
+ return new WorkspaceClientCapabilitiesDidChangeConfiguration(
+ dynamicRegistration);
+ }
+
+ /// Did change configuration notification supports dynamic registration.
+ final bool dynamicRegistration;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
+ if (dynamicRegistration != null) {
+ __result['dynamicRegistration'] = dynamicRegistration;
+ }
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic>;
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is WorkspaceClientCapabilitiesDidChangeConfiguration) {
+ return dynamicRegistration == other.dynamicRegistration && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, dynamicRegistration.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+class WorkspaceClientCapabilitiesDidChangeWatchedFiles implements ToJsonable {
+ WorkspaceClientCapabilitiesDidChangeWatchedFiles(this.dynamicRegistration);
+ static WorkspaceClientCapabilitiesDidChangeWatchedFiles fromJson(
+ Map<String, dynamic> json) {
+ final dynamicRegistration = json['dynamicRegistration'];
+ return new WorkspaceClientCapabilitiesDidChangeWatchedFiles(
+ dynamicRegistration);
+ }
+
+ /// Did change watched files notification supports dynamic registration.
+ final bool dynamicRegistration;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
+ if (dynamicRegistration != null) {
+ __result['dynamicRegistration'] = dynamicRegistration;
+ }
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic>;
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is WorkspaceClientCapabilitiesDidChangeWatchedFiles) {
+ return dynamicRegistration == other.dynamicRegistration && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, dynamicRegistration.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+class WorkspaceClientCapabilitiesExecuteCommand implements ToJsonable {
+ WorkspaceClientCapabilitiesExecuteCommand(this.dynamicRegistration);
+ static WorkspaceClientCapabilitiesExecuteCommand fromJson(
+ Map<String, dynamic> json) {
+ final dynamicRegistration = json['dynamicRegistration'];
+ return new WorkspaceClientCapabilitiesExecuteCommand(dynamicRegistration);
+ }
+
+ /// Execute command supports dynamic registration.
+ final bool dynamicRegistration;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
+ if (dynamicRegistration != null) {
+ __result['dynamicRegistration'] = dynamicRegistration;
+ }
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic>;
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is WorkspaceClientCapabilitiesExecuteCommand) {
+ return dynamicRegistration == other.dynamicRegistration && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, dynamicRegistration.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+class WorkspaceClientCapabilitiesSymbol implements ToJsonable {
+ WorkspaceClientCapabilitiesSymbol(this.dynamicRegistration, this.symbolKind);
+ static WorkspaceClientCapabilitiesSymbol fromJson(Map<String, dynamic> json) {
+ final dynamicRegistration = json['dynamicRegistration'];
+ final symbolKind = json['symbolKind'] != null
+ ? WorkspaceClientCapabilitiesSymbolKind.fromJson(json['symbolKind'])
+ : null;
+ return new WorkspaceClientCapabilitiesSymbol(
+ dynamicRegistration, symbolKind);
+ }
+
+ /// Symbol request supports dynamic registration.
+ final bool dynamicRegistration;
+
+ /// Specific capabilities for the `SymbolKind` in the `workspace/symbol`
+ /// request.
+ final WorkspaceClientCapabilitiesSymbolKind symbolKind;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
+ if (dynamicRegistration != null) {
+ __result['dynamicRegistration'] = dynamicRegistration;
+ }
+ if (symbolKind != null) {
+ __result['symbolKind'] = symbolKind;
+ }
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic>;
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is WorkspaceClientCapabilitiesSymbol) {
+ return dynamicRegistration == other.dynamicRegistration &&
+ symbolKind == other.symbolKind &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, dynamicRegistration.hashCode);
+ hash = JenkinsSmiHash.combine(hash, symbolKind.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+class WorkspaceClientCapabilitiesSymbolKind implements ToJsonable {
+ WorkspaceClientCapabilitiesSymbolKind(this.valueSet);
+ static WorkspaceClientCapabilitiesSymbolKind fromJson(
+ Map<String, dynamic> json) {
+ final valueSet = json['valueSet']
+ ?.map((item) => item != null ? SymbolKind.fromJson(item) : null)
+ ?.cast<SymbolKind>()
+ ?.toList();
+ return new WorkspaceClientCapabilitiesSymbolKind(valueSet);
+ }
+
+ /// The symbol kind values the client supports. When this property exists the
+ /// client also guarantees that it will handle values outside its set
+ /// gracefully and falls back to a default value when unknown.
+ ///
+ /// If this property is not present the client only supports the symbol kinds
+ /// from `File` to `Array` as defined in the initial version of the protocol.
+ final List<SymbolKind> valueSet;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
+ if (valueSet != null) {
+ __result['valueSet'] = valueSet;
+ }
+ return __result;
+ }
+
+ static bool canParse(Object obj) {
+ return obj is Map<String, dynamic>;
+ }
+
+ @override
+ bool operator ==(other) {
+ if (other is WorkspaceClientCapabilitiesSymbolKind) {
+ return listEqual(valueSet, other.valueSet,
+ (SymbolKind a, SymbolKind b) => a == b) &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, valueSet.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
+}
+
+class WorkspaceClientCapabilitiesWorkspaceEdit implements ToJsonable {
+ WorkspaceClientCapabilitiesWorkspaceEdit(
+ this.documentChanges, this.resourceOperations, this.failureHandling);
+ static WorkspaceClientCapabilitiesWorkspaceEdit fromJson(
+ Map<String, dynamic> json) {
+ final documentChanges = json['documentChanges'];
+ final resourceOperations = json['resourceOperations']
+ ?.map((item) =>
+ item != null ? ResourceOperationKind.fromJson(item) : null)
+ ?.cast<ResourceOperationKind>()
+ ?.toList();
+ final failureHandling = json['failureHandling'] != null
+ ? FailureHandlingKind.fromJson(json['failureHandling'])
+ : null;
+ return new WorkspaceClientCapabilitiesWorkspaceEdit(
+ documentChanges, resourceOperations, failureHandling);
+ }
+
+ /// The client supports versioned document changes in `WorkspaceEdit`s
+ final bool documentChanges;
+
+ /// The failure handling strategy of a client if applying the workspace edit
+ /// fails.
+ final FailureHandlingKind failureHandling;
+
+ /// The resource operations the client supports. Clients should at least
+ /// support 'create', 'rename' and 'delete' files and folders.
+ final List<ResourceOperationKind> resourceOperations;
+
+ Map<String, dynamic> toJson() {
+ Map<String, dynamic> __result = {};
if (documentChanges != null) {
__result['documentChanges'] = documentChanges;
}
@@ -6039,16 +10892,61 @@
static bool canParse(Object obj) {
return obj is Map<String, dynamic>;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is WorkspaceClientCapabilitiesWorkspaceEdit) {
+ return documentChanges == other.documentChanges &&
+ listEqual(resourceOperations, other.resourceOperations,
+ (ResourceOperationKind a, ResourceOperationKind b) => a == b) &&
+ failureHandling == other.failureHandling &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, documentChanges.hashCode);
+ hash = JenkinsSmiHash.combine(hash, resourceOperations.hashCode);
+ hash = JenkinsSmiHash.combine(hash, failureHandling.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class WorkspaceEdit implements ToJsonable {
WorkspaceEdit(this.changes, this.documentChanges);
- factory WorkspaceEdit.fromJson(Map<String, dynamic> json) {
- final changes = json['changes'];
- final documentChanges = json['documentChanges']
- ?.map((item) => item)
- ?.cast<FileOperation>()
- ?.toList();
+ static WorkspaceEdit fromJson(Map<String, dynamic> json) {
+ final changes = json['changes']
+ ?.map((key, value) => new MapEntry(
+ key,
+ value
+ ?.map((item) => item != null ? TextEdit.fromJson(item) : null)
+ ?.cast<TextEdit>()
+ ?.toList()))
+ ?.cast<String, List<TextEdit>>();
+ final documentChanges = (json['documentChanges'] is List && (json['documentChanges'].length == 0 || json['documentChanges'].every((item) => TextDocumentEdit.canParse(item))))
+ ? new Either2<List<TextDocumentEdit>, List<Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>>>.t1(json['documentChanges']
+ ?.map(
+ (item) => item != null ? TextDocumentEdit.fromJson(item) : null)
+ ?.cast<TextDocumentEdit>()
+ ?.toList())
+ : ((json['documentChanges'] is List && (json['documentChanges'].length == 0 || json['documentChanges'].every((item) => (TextDocumentEdit.canParse(item) || CreateFile.canParse(item) || RenameFile.canParse(item) || DeleteFile.canParse(item)))))
+ ? new Either2<List<TextDocumentEdit>, List<Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>>>.t2(json['documentChanges']
+ ?.map((item) => TextDocumentEdit.canParse(item)
+ ? new Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>.t1(
+ item != null ? TextDocumentEdit.fromJson(item) : null)
+ : (CreateFile.canParse(item)
+ ? new Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>.t2(
+ item != null ? CreateFile.fromJson(item) : null)
+ : (RenameFile.canParse(item) ? new Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>.t3(item != null ? RenameFile.fromJson(item) : null) : (DeleteFile.canParse(item) ? new Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>.t4(item != null ? DeleteFile.fromJson(item) : null) : (item == null ? null : (throw '''${item} was not one of (TextDocumentEdit, CreateFile, RenameFile, DeleteFile)'''))))))
+ ?.cast<Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>>()
+ ?.toList())
+ : (json['documentChanges'] == null ? null : (throw '''${json['documentChanges']} was not one of (List<TextDocumentEdit>, List<Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>>)''')));
return new WorkspaceEdit(changes, documentChanges);
}
@@ -6056,26 +10954,21 @@
final Map<String, List<TextEdit>> changes;
/// Depending on the client capability
- /// `workspace.workspaceEdit.resourceOperations`
- /// document changes are either an array of
- /// `TextDocumentEdit`s to express changes to n
- /// different text documents where each text
- /// document edit addresses a specific version
- /// of a text document. Or it can contain above
- /// `TextDocumentEdit`s mixed with create,
- /// rename and delete file / folder operations.
+ /// `workspace.workspaceEdit.resourceOperations` document changes are either
+ /// an array of `TextDocumentEdit`s to express changes to n different text
+ /// documents where each text document edit addresses a specific version of a
+ /// text document. Or it can contain above `TextDocumentEdit`s mixed with
+ /// create, rename and delete file / folder operations.
///
- /// Whether a client supports versioned document
- /// edits is expressed via
- /// `workspace.workspaceEdit.documentChanges`
- /// client capability.
+ /// Whether a client supports versioned document edits is expressed via
+ /// `workspace.workspaceEdit.documentChanges` client capability.
///
- /// If a client neither supports
- /// `documentChanges` nor
- /// `workspace.workspaceEdit.resourceOperations`
- /// then only plain `TextEdit`s using the
- /// `changes` property are supported.
- final List<FileOperation> documentChanges;
+ /// If a client neither supports `documentChanges` nor
+ /// `workspace.workspaceEdit.resourceOperations` then only plain `TextEdit`s
+ /// using the `changes` property are supported.
+ final Either2<List<TextDocumentEdit>,
+ List<Either4<TextDocumentEdit, CreateFile, RenameFile, DeleteFile>>>
+ documentChanges;
Map<String, dynamic> toJson() {
Map<String, dynamic> __result = {};
@@ -6091,6 +10984,28 @@
static bool canParse(Object obj) {
return obj is Map<String, dynamic>;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is WorkspaceEdit) {
+ return mapEqual(changes, other.changes,
+ (List<TextEdit> a, List<TextEdit> b) => a == b) &&
+ documentChanges == other.documentChanges &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, changes.hashCode);
+ hash = JenkinsSmiHash.combine(hash, documentChanges.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
class WorkspaceFolder implements ToJsonable {
@@ -6102,18 +11017,16 @@
throw 'name is required but was not provided';
}
}
- factory WorkspaceFolder.fromJson(Map<String, dynamic> json) {
+ static WorkspaceFolder fromJson(Map<String, dynamic> json) {
final uri = json['uri'];
final name = json['name'];
return new WorkspaceFolder(uri, name);
}
- /// The name of the workspace folder. Defaults
- /// to the uri's basename.
+ /// The name of the workspace folder. Defaults to the uri's basename.
final String name;
- /// The associated URI for this workspace
- /// folder.
+ /// The associated URI for this workspace folder.
final String uri;
Map<String, dynamic> toJson() {
@@ -6130,6 +11043,25 @@
obj.containsKey('name') &&
obj['name'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is WorkspaceFolder) {
+ return uri == other.uri && name == other.name && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, uri.hashCode);
+ hash = JenkinsSmiHash.combine(hash, name.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// The workspace folder change event.
@@ -6142,15 +11074,13 @@
throw 'removed is required but was not provided';
}
}
- factory WorkspaceFoldersChangeEvent.fromJson(Map<String, dynamic> json) {
+ static WorkspaceFoldersChangeEvent fromJson(Map<String, dynamic> json) {
final added = json['added']
- ?.map(
- (item) => item != null ? new WorkspaceFolder.fromJson(item) : null)
+ ?.map((item) => item != null ? WorkspaceFolder.fromJson(item) : null)
?.cast<WorkspaceFolder>()
?.toList();
final removed = json['removed']
- ?.map(
- (item) => item != null ? new WorkspaceFolder.fromJson(item) : null)
+ ?.map((item) => item != null ? WorkspaceFolder.fromJson(item) : null)
?.cast<WorkspaceFolder>()
?.toList();
return new WorkspaceFoldersChangeEvent(added, removed);
@@ -6183,6 +11113,29 @@
obj['removed']
.every((item) => WorkspaceFolder.canParse(item))));
}
+
+ @override
+ bool operator ==(other) {
+ if (other is WorkspaceFoldersChangeEvent) {
+ return listEqual(added, other.added,
+ (WorkspaceFolder a, WorkspaceFolder b) => a == b) &&
+ listEqual(removed, other.removed,
+ (WorkspaceFolder a, WorkspaceFolder b) => a == b) &&
+ true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, added.hashCode);
+ hash = JenkinsSmiHash.combine(hash, removed.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
/// The parameters of a Workspace Symbol Request.
@@ -6192,7 +11145,7 @@
throw 'query is required but was not provided';
}
}
- factory WorkspaceSymbolParams.fromJson(Map<String, dynamic> json) {
+ static WorkspaceSymbolParams fromJson(Map<String, dynamic> json) {
final query = json['query'];
return new WorkspaceSymbolParams(query);
}
@@ -6211,4 +11164,22 @@
obj.containsKey('query') &&
obj['query'] is String;
}
+
+ @override
+ bool operator ==(other) {
+ if (other is WorkspaceSymbolParams) {
+ return query == other.query && true;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode {
+ int hash = 0;
+ hash = JenkinsSmiHash.combine(hash, query.hashCode);
+ return JenkinsSmiHash.finish(hash);
+ }
+
+ @override
+ String toString() => jsonEncoder.convert(toJson());
}
diff --git a/pkg/analysis_server/lib/lsp_protocol/protocol_special.dart b/pkg/analysis_server/lib/lsp_protocol/protocol_special.dart
index 35ae774..fd526fe 100644
--- a/pkg/analysis_server/lib/lsp_protocol/protocol_special.dart
+++ b/pkg/analysis_server/lib/lsp_protocol/protocol_special.dart
@@ -2,6 +2,12 @@
// 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/lsp_protocol/protocol_generated.dart';
+
+const jsonRpcVersion = '2.0';
+
Object id(Object obj) => obj;
Object specToJson(Object obj) {
@@ -145,7 +151,54 @@
map((t) => t == o, (t) => t == o, (t) => t == o, (t) => t == o);
}
-class FileOperation {}
+class ErrorOr<T> extends Either2<ResponseError, T> {
+ ErrorOr.error(ResponseError error) : super.t1(error);
+ ErrorOr.success([T result]) : super.t2(result);
+
+ /// Returns the error or throws if object is not an error. Check [isError]
+ /// before accessing [error].
+ ResponseError get error {
+ return _which == 1 ? _t1 : (throw 'Value is not an error');
+ }
+
+ /// Returns true if this object is an error, false if it is a result. Prefer
+ /// [mapResult] instead of checking this flag if [errors] will simply be
+ /// propagated as-is.
+ bool get isError => _which == 1;
+
+ /// Returns the result or throws if this object is an error. Check [isError]
+ /// before accessing [result]. It is valid for this to return null is the
+ /// object does not represent an error but the resulting value was null.
+ T get result {
+ return _which == 2 ? _t2 : (throw 'Value is not a result');
+ }
+
+ /// If this object is a result, maps [result] through [f], otherwise returns
+ /// a new error object representing [error].
+ FutureOr<ErrorOr<N>> mapResult<N>(FutureOr<ErrorOr<N>> Function(T) f) {
+ return isError
+ // Re-wrap the error using our new type arg
+ ? new ErrorOr<N>.error(error)
+ // Otherwise call the map function
+ : f(result);
+ }
+}
+
+/// A base class containing the fields common to RequestMessage and
+/// NotificationMessage to simplify handling.
+abstract class IncomingMessage {
+ Method get method;
+ dynamic get params;
+}
+
+abstract class ServerErrorCodes {
+ // JSON-RPC reserves -32000 to -32099 for implementation-defined server-errors.
+ static const ServerAlreadyStarted = const ErrorCodes(-32000);
+ static const UnhandledError = const ErrorCodes(-32001);
+ static const ServerAlreadyInitialized = const ErrorCodes(-32002);
+ static const InvalidFilePath = const ErrorCodes(-32003);
+ static const InvalidFileLineCol = const ErrorCodes(-32004);
+}
abstract class ToJsonable {
Object toJson();
diff --git a/pkg/analysis_server/lib/plugin/edit/assist/assist_dart.dart b/pkg/analysis_server/lib/plugin/edit/assist/assist_dart.dart
index 6e7020e..f338cc5 100644
--- a/pkg/analysis_server/lib/plugin/edit/assist/assist_dart.dart
+++ b/pkg/analysis_server/lib/plugin/edit/assist/assist_dart.dart
@@ -2,9 +2,7 @@
// 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:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
-import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/dart/analysis/results.dart';
/**
* An object used to provide context information for Dart assist contributors.
@@ -13,9 +11,9 @@
*/
abstract class DartAssistContext {
/**
- * The analysis driver used to access analysis results.
+ * The resolution result in which assist operates.
*/
- AnalysisDriver get analysisDriver;
+ ResolvedUnitResult get resolveResult;
/**
* The length of the selection.
@@ -26,14 +24,4 @@
* The start of the selection.
*/
int get selectionOffset;
-
- /**
- * The source to get assists in.
- */
- Source get source;
-
- /**
- * The [CompilationUnit] to compute assists in.
- */
- CompilationUnit get unit;
}
diff --git a/pkg/analysis_server/lib/plugin/edit/fix/fix_core.dart b/pkg/analysis_server/lib/plugin/edit/fix/fix_core.dart
index af303ec..ccc79a9 100644
--- a/pkg/analysis_server/lib/plugin/edit/fix/fix_core.dart
+++ b/pkg/analysis_server/lib/plugin/edit/fix/fix_core.dart
@@ -5,8 +5,6 @@
import 'dart:async';
import 'package:analyzer/error/error.dart';
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart'
show SourceChange;
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
@@ -64,25 +62,9 @@
*/
abstract class FixContext {
/**
- * The analysis driver used to access analysis results.
- */
- AnalysisDriver get analysisDriver;
-
- /**
- * The error to fix, should be reported by the given [analysisDriver].
+ * The error to fix.
*/
AnalysisError get error;
-
- /**
- * All of the errors in the file. This is used to compute additional fixes
- * such "Fix all instances in file."
- */
- List<AnalysisError> get errors;
-
- /**
- * The [ResourceProvider] to access files and folders.
- */
- ResourceProvider get resourceProvider;
}
/**
@@ -96,5 +78,5 @@
/**
* Return a list of fixes for the given [context].
*/
- Future<List<Fix>> computeFixes(FixContext context);
+ Future<List<Fix>> computeFixes(covariant FixContext context);
}
diff --git a/pkg/analysis_server/lib/plugin/edit/fix/fix_dart.dart b/pkg/analysis_server/lib/plugin/edit/fix/fix_dart.dart
index c4d54d1..2ac36c5 100644
--- a/pkg/analysis_server/lib/plugin/edit/fix/fix_dart.dart
+++ b/pkg/analysis_server/lib/plugin/edit/fix/fix_dart.dart
@@ -2,24 +2,8 @@
// 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/plugin/edit/fix/fix_core.dart';
-import 'package:analysis_server/src/services/correction/fix_internal.dart'
- show DartFixContextImpl;
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/src/dart/analysis/ast_provider_driver.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
-import 'package:analyzer/src/dart/analysis/top_level_declaration.dart';
-import 'package:analyzer/src/dart/element/ast_provider.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/source.dart';
-
-/**
- * Complete with top-level declarations with the given [name].
- */
-typedef Future<List<TopLevelDeclarationInSource>> GetTopLevelDeclarations(
- String name);
+import 'package:analyzer/dart/analysis/results.dart';
/**
* An object used to provide context information for [DartFixContributor]s.
@@ -28,48 +12,7 @@
*/
abstract class DartFixContext implements FixContext {
/**
- * The provider for parsed or resolved ASTs.
+ * The resolution result in which fix operates.
*/
- AstProvider get astProvider;
-
- /**
- * The function to get top-level declarations from.
- */
- GetTopLevelDeclarations get getTopLevelDeclarations;
-
- /**
- * The [CompilationUnit] to compute fixes in.
- */
- CompilationUnit get unit;
-}
-
-/**
- * A [FixContributor] that can be used to contribute fixes for errors in Dart
- * files.
- *
- * Clients may extend this class when implementing plugins.
- */
-abstract class DartFixContributor implements FixContributor {
- @override
- Future<List<Fix>> computeFixes(FixContext context) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
- AnalysisDriver driver = context.analysisDriver;
- Source source = context.error.source;
- if (!AnalysisEngine.isDartFileName(source.fullName)) {
- return const <Fix>[];
- }
- CompilationUnit unit = (await driver.getResult(source.fullName)).unit;
- if (unit == null) {
- return const <Fix>[];
- }
- DartFixContext dartContext =
- new DartFixContextImpl(context, new AstProviderForDriver(driver), unit);
- return internalComputeFixes(dartContext);
- }
-
- /**
- * Return a list of fixes for the given [context].
- */
- Future<List<Fix>> internalComputeFixes(DartFixContext context);
+ ResolvedUnitResult get resolveResult;
}
diff --git a/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart b/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
index e4ab6d5..cab3a80 100644
--- a/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
+++ b/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
@@ -64,6 +64,9 @@
if (kind == engine.ElementKind.FUNCTION_TYPE_ALIAS) {
return ElementKind.FUNCTION_TYPE_ALIAS;
}
+ if (kind == engine.ElementKind.GENERIC_FUNCTION_TYPE) {
+ return ElementKind.FUNCTION_TYPE_ALIAS;
+ }
if (kind == engine.ElementKind.GETTER) {
return ElementKind.GETTER;
}
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index ae93b77..ff16acf 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -14,6 +14,7 @@
import 'package:analysis_server/protocol/protocol_generated.dart'
hide AnalysisOptions;
import 'package:analysis_server/src/analysis_logger.dart';
+import 'package:analysis_server/src/analysis_server_abstract.dart';
import 'package:analysis_server/src/channel/channel.dart';
import 'package:analysis_server/src/collections.dart';
import 'package:analysis_server/src/computer/computer_highlights.dart';
@@ -42,36 +43,28 @@
import 'package:analysis_server/src/search/search_domain.dart';
import 'package:analysis_server/src/server/detachable_filesystem_manager.dart';
import 'package:analysis_server/src/server/diagnostic_server.dart';
-import 'package:analysis_server/src/services/correction/namespace.dart';
-import 'package:analysis_server/src/services/search/element_visitors.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
import 'package:analysis_server/src/services/search/search_engine_internal.dart';
import 'package:analysis_server/src/utilities/null_string_sink.dart';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/src/context/builder.dart';
import 'package:analyzer/src/context/context_root.dart';
-import 'package:analyzer/src/dart/analysis/ast_provider_driver.dart';
import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/driver.dart' as nd;
-import 'package:analyzer/src/dart/analysis/file_byte_store.dart'
- show EvictingFileByteStore;
import 'package:analyzer/src/dart/analysis/file_state.dart' as nd;
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/dart/analysis/status.dart' as nd;
-import 'package:analyzer/src/dart/ast/utilities.dart';
-import 'package:analyzer/src/dart/element/ast_provider.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/generated/utilities_general.dart';
import 'package:analyzer/src/plugin/resolver_provider.dart';
-import 'package:analyzer/src/util/glob.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element;
import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
import 'package:telemetry/crash_reporting.dart';
@@ -80,179 +73,99 @@
typedef void OptionUpdater(AnalysisOptionsImpl options);
-/**
- * Instances of the class [AnalysisServer] implement a server that listens on a
- * [CommunicationChannel] for analysis requests and process them.
- */
-class AnalysisServer {
- /**
- * The options of this server instance.
- */
+/// Instances of the class [AnalysisServer] implement a server that listens on a
+/// [CommunicationChannel] for analysis requests and process them.
+class AnalysisServer extends AbstractAnalysisServer {
+ /// The options of this server instance.
AnalysisServerOptions options;
- /**
- * The channel from which requests are received and to which responses should
- * be sent.
- */
+ /// The channel from which requests are received and to which responses should
+ /// be sent.
final ServerCommunicationChannel channel;
- /**
- * The object used to manage sending a subset of notifications to the client.
- * The subset of notifications are those to which plugins may contribute.
- * This field is `null` when the new plugin support is disabled.
- */
+ /// The object used to manage sending a subset of notifications to the client.
+ /// The subset of notifications are those to which plugins may contribute.
+ /// This field is `null` when the new plugin support is disabled.
final NotificationManager notificationManager;
- /**
- * The object used to manage the execution of plugins.
- */
+ /// The object used to manage the execution of plugins.
PluginManager pluginManager;
- /**
- * The [ResourceProvider] using which paths are converted into [Resource]s.
- */
- final ResourceProvider resourceProvider;
-
- /**
- * The [SearchEngine] for this server, may be `null` if indexing is disabled.
- */
+ /// The [SearchEngine] for this server, may be `null` if indexing is disabled.
SearchEngine searchEngine;
- /**
- * A list of the globs used to determine which files should be analyzed. The
- * list is lazily created and should be accessed using [analyzedFilesGlobs].
- */
- List<Glob> _analyzedFilesGlobs = null;
-
- /**
- * The [ContextManager] that handles the mapping from analysis roots to
- * context directories.
- */
- ContextManager contextManager;
-
- /**
- * A flag indicating whether the server is running. When false, contexts
- * will no longer be added to [contextWorkQueue], and [performOperation] will
- * discard any tasks it finds on [contextWorkQueue].
- */
- bool running;
-
- /**
- * A flag indicating the value of the 'analyzing' parameter sent in the last
- * status message to the client.
- */
+ /// A flag indicating the value of the 'analyzing' parameter sent in the last
+ /// status message to the client.
bool statusAnalyzing = false;
- /**
- * A list of the request handlers used to handle the requests sent to this
- * server.
- */
+ /// A list of the request handlers used to handle the requests sent to this
+ /// server.
List<RequestHandler> handlers;
- /**
- * The object used to manage the SDK's known to this server.
- */
+ /// The object used to manage the SDK's known to this server.
final DartSdkManager sdkManager;
- /**
- * The instrumentation service that is to be used by this analysis server.
- */
+ /// The instrumentation service that is to be used by this analysis server.
final InstrumentationService instrumentationService;
- /**
- * A set of the [ServerService]s to send notifications for.
- */
+ /// A set of the [ServerService]s to send notifications for.
Set<ServerService> serverServices = new HashSet<ServerService>();
- /**
- * A set of the [GeneralAnalysisService]s to send notifications for.
- */
+ /// A set of the [GeneralAnalysisService]s to send notifications for.
Set<GeneralAnalysisService> generalAnalysisServices =
new HashSet<GeneralAnalysisService>();
- /**
- * A table mapping [AnalysisService]s to the file paths for which these
- * notifications should be sent.
- */
+ /// A table mapping [AnalysisService]s to the file paths for which these
+ /// notifications should be sent.
Map<AnalysisService, Set<String>> analysisServices =
new HashMap<AnalysisService, Set<String>>();
- /**
- * A table mapping [FlutterService]s to the file paths for which these
- * notifications should be sent.
- */
+ /// A table mapping [FlutterService]s to the file paths for which these
+ /// notifications should be sent.
Map<FlutterService, Set<String>> flutterServices = {};
- /**
- * Performance information before initial analysis is complete.
- */
+ /// Performance information before initial analysis is complete.
final ServerPerformance performanceDuringStartup = new ServerPerformance();
- /**
- * Performance information after initial analysis is complete
- * or `null` if the initial analysis is not yet complete
- */
+ /// Performance information after initial analysis is complete
+ /// or `null` if the initial analysis is not yet complete
ServerPerformance performanceAfterStartup;
- /**
- * A [RecentBuffer] of the most recent exceptions encountered by the analysis
- * server.
- */
+ /// A [RecentBuffer] of the most recent exceptions encountered by the analysis
+ /// server.
final RecentBuffer<ServerException> exceptions = new RecentBuffer(10);
- /**
- * The class into which performance information is currently being recorded.
- * During startup, this will be the same as [performanceDuringStartup]
- * and after startup is complete, this switches to [performanceAfterStartup].
- */
+ /// The class into which performance information is currently being recorded.
+ /// During startup, this will be the same as [performanceDuringStartup]
+ /// and after startup is complete, this switches to [performanceAfterStartup].
ServerPerformance _performance;
- /**
- * The [Completer] that completes when analysis is complete.
- */
+ /// The [Completer] that completes when analysis is complete.
Completer _onAnalysisCompleteCompleter;
- /**
- * The controller that is notified when analysis is started.
- */
+ /// The controller that is notified when analysis is started.
StreamController<bool> _onAnalysisStartedController;
- /**
- * The content overlay for all analysis drivers.
- */
+ /// The content overlay for all analysis drivers.
final nd.FileContentOverlay fileContentOverlay = new nd.FileContentOverlay();
- /**
- * The current state of overlays from the client. This is used as the
- * content cache for all contexts.
- */
- final ContentCache overlayState = new ContentCache();
-
- /**
- * If the "analysis.analyzedFiles" notification is currently being subscribed
- * to (see [generalAnalysisServices]), and at least one such notification has
- * been sent since the subscription was enabled, the set of analyzed files
- * that was delivered in the most recently sent notification. Otherwise
- * `null`.
- */
+ /// If the "analysis.analyzedFiles" notification is currently being subscribed
+ /// to (see [generalAnalysisServices]), and at least one such notification has
+ /// been sent since the subscription was enabled, the set of analyzed files
+ /// that was delivered in the most recently sent notification. Otherwise
+ /// `null`.
Set<String> prevAnalyzedFiles;
- /**
- * The default options used to create new analysis contexts. This object is
- * also referenced by the ContextManager.
- */
+ /// The default options used to create new analysis contexts. This object is
+ /// also referenced by the ContextManager.
final AnalysisOptionsImpl defaultContextOptions = new AnalysisOptionsImpl();
- /**
- * The file resolver provider used to override the way file URI's are
- * resolved in some contexts.
- */
+ /// The file resolver provider used to override the way file URI's are
+ /// resolved in some contexts.
ResolverProvider fileResolverProvider;
- /**
- * The package resolver provider used to override the way package URI's are
- * resolved in some contexts.
- */
+ /// The package resolver provider used to override the way package URI's are
+ /// resolved in some contexts.
ResolverProvider packageResolverProvider;
PerformanceLog _analysisPerformanceLogger;
@@ -260,38 +173,27 @@
ByteStore byteStore;
nd.AnalysisDriverScheduler analysisDriverScheduler;
- /**
- * The controller for [onAnalysisSetChanged].
- */
+ /// The controller for [onAnalysisSetChanged].
final StreamController _onAnalysisSetChangedController =
new StreamController.broadcast(sync: true);
- /**
- * The set of the files that are currently priority.
- */
- final Set<String> priorityFiles = new Set<String>();
-
- /**
- * The DiagnosticServer for this AnalysisServer. If available, it can be used
- * to start an http diagnostics server or return the port for an existing
- * server.
- */
+ /// The DiagnosticServer for this AnalysisServer. If available, it can be used
+ /// to start an http diagnostics server or return the port for an existing
+ /// server.
final DiagnosticServer diagnosticServer;
final DetachableFileSystemManager detachableFileSystemManager;
- /**
- * Initialize a newly created server to receive requests from and send
- * responses to the given [channel].
- *
- * If [rethrowExceptions] is true, then any exceptions thrown by analysis are
- * propagated up the call stack. The default is true to allow analysis
- * exceptions to show up in unit tests, but it should be set to false when
- * running a full analysis server.
- */
+ /// Initialize a newly created server to receive requests from and send
+ /// responses to the given [channel].
+ ///
+ /// If [rethrowExceptions] is true, then any exceptions thrown by analysis are
+ /// propagated up the call stack. The default is true to allow analysis
+ /// exceptions to show up in unit tests, but it should be set to false when
+ /// running a full analysis server.
AnalysisServer(
this.channel,
- this.resourceProvider,
+ ResourceProvider resourceProvider,
this.options,
this.sdkManager,
this.instrumentationService, {
@@ -299,8 +201,9 @@
ResolverProvider fileResolverProvider: null,
ResolverProvider packageResolverProvider: null,
this.detachableFileSystemManager: null,
- }) : notificationManager =
- new NotificationManager(channel, resourceProvider) {
+ }) : notificationManager =
+ new NotificationManager(channel, resourceProvider),
+ super(resourceProvider) {
_performance = performanceDuringStartup;
pluginManager = new PluginManager(
@@ -328,7 +231,7 @@
}
_analysisPerformanceLogger = new PerformanceLog(sink);
}
- byteStore = _createByteStore();
+ byteStore = createByteStore(resourceProvider);
analysisDriverScheduler = new nd.AnalysisDriverScheduler(
_analysisPerformanceLogger,
driverWatcher: pluginWatcher);
@@ -350,7 +253,6 @@
contextManager.callbacks = contextManagerCallbacks;
AnalysisEngine.instance.logger = new AnalysisLogger(this);
_onAnalysisStartedController = new StreamController.broadcast();
- running = true;
onAnalysisStarted.first.then((_) {
onAnalysisComplete.then((_) {
performanceAfterStartup = new ServerPerformance();
@@ -378,47 +280,10 @@
];
}
- /**
- * The analytics instance; note, this object can be `null`.
- */
+ /// The analytics instance; note, this object can be `null`.
telemetry.Analytics get analytics => options.analytics;
- /**
- * Return a list of the globs used to determine which files should be analyzed.
- */
- List<Glob> get analyzedFilesGlobs {
- if (_analyzedFilesGlobs == null) {
- _analyzedFilesGlobs = <Glob>[];
- List<String> patterns = <String>[
- '**/*.${AnalysisEngine.SUFFIX_DART}',
- '**/*.${AnalysisEngine.SUFFIX_HTML}',
- '**/*.${AnalysisEngine.SUFFIX_HTM}',
- '**/${AnalysisEngine.ANALYSIS_OPTIONS_FILE}',
- '**/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}',
- '**/${AnalysisEngine.PUBSPEC_YAML_FILE}'
- ];
- for (String pattern in patterns) {
- try {
- _analyzedFilesGlobs
- .add(new Glob(resourceProvider.pathContext.separator, pattern));
- } catch (exception, stackTrace) {
- AnalysisEngine.instance.logger.logError(
- 'Invalid glob pattern: "$pattern"',
- new CaughtException(exception, stackTrace));
- }
- }
- }
- return _analyzedFilesGlobs;
- }
-
- /**
- * A table mapping [Folder]s to the [AnalysisDriver]s associated with them.
- */
- Map<Folder, nd.AnalysisDriver> get driverMap => contextManager.driverMap;
-
- /**
- * The [Future] that completes when analysis is complete.
- */
+ /// The [Future] that completes when analysis is complete.
Future get onAnalysisComplete {
if (isAnalysisComplete()) {
return new Future.value();
@@ -429,50 +294,34 @@
return _onAnalysisCompleteCompleter.future;
}
- /**
- * The stream that is notified when the analysis set is changed - this might
- * be a change to a file, external via a watch event, or internal via
- * overlay. This means that the resolved world might have changed.
- *
- * The type of produced elements is not specified and should not be used.
- */
+ /// The stream that is notified when the analysis set is changed - this might
+ /// be a change to a file, external via a watch event, or internal via
+ /// overlay. This means that the resolved world might have changed.
+ ///
+ /// The type of produced elements is not specified and should not be used.
Stream get onAnalysisSetChanged => _onAnalysisSetChangedController.stream;
- /**
- * The stream that is notified with `true` when analysis is started.
- */
+ /// The stream that is notified with `true` when analysis is started.
Stream<bool> get onAnalysisStarted {
return _onAnalysisStartedController.stream;
}
- /**
- * Return the total time the server's been alive.
- */
+ /// Return the total time the server's been alive.
Duration get uptime {
DateTime start = new DateTime.fromMillisecondsSinceEpoch(
performanceDuringStartup.startTime);
return new DateTime.now().difference(start);
}
- /**
- * The socket from which requests are being read has been closed.
- */
- void done() {
- running = false;
- }
+ /// The socket from which requests are being read has been closed.
+ void done() {}
- /**
- * There was an error related to the socket from which requests are being
- * read.
- */
- void error(argument) {
- running = false;
- }
+ /// There was an error related to the socket from which requests are being
+ /// read.
+ void error(argument) {}
- /**
- * Return one of the SDKs that has been created, or `null` if no SDKs have
- * been created yet.
- */
+ /// Return one of the SDKs that has been created, or `null` if no SDKs have
+ /// been created yet.
DartSdk findSdk() {
DartSdk sdk = sdkManager.anySdk;
if (sdk != null) {
@@ -482,64 +331,9 @@
return null;
}
- /**
- * Return an analysis driver to which the file with the given [path] is
- * added if one exists, otherwise a driver in which the file was analyzed if
- * one exists, otherwise the first driver, otherwise `null`.
- */
- nd.AnalysisDriver getAnalysisDriver(String path) {
- List<nd.AnalysisDriver> drivers = driverMap.values.toList();
- if (drivers.isNotEmpty) {
- // Sort the drivers so that more deeply nested contexts will be checked
- // before enclosing contexts.
- drivers.sort((first, second) =>
- second.contextRoot.root.length - first.contextRoot.root.length);
- nd.AnalysisDriver driver = drivers.firstWhere(
- (driver) => driver.contextRoot.containsFile(path),
- orElse: () => null);
- driver ??= drivers.firstWhere(
- (driver) => driver.knownFiles.contains(path),
- orElse: () => null);
- driver ??= drivers.first;
- return driver;
- }
- return null;
- }
-
- /**
- * Return the analysis result for the file with the given [path]. The file is
- * analyzed in one of the analysis drivers to which the file was added,
- * otherwise in the first driver, otherwise `null` is returned.
- */
- Future<nd.AnalysisResult> getAnalysisResult(String path,
- {bool sendCachedToStream: false}) {
- if (!AnalysisEngine.isDartFileName(path)) {
- return null;
- }
-
- nd.AnalysisDriver driver = getAnalysisDriver(path);
- if (driver == null) {
- return new Future.value();
- }
-
- return driver
- .getResult(path, sendCachedToStream: sendCachedToStream)
- .catchError((_) => null);
- }
-
- /**
- * Return the [AstProvider] for the given [path].
- */
- AstProvider getAstProvider(String path) {
- nd.AnalysisDriver analysisDriver = getAnalysisDriver(path);
- return new AstProviderForDriver(analysisDriver);
- }
-
- /**
- * Return the cached analysis result for the file with the given [path].
- * If there is no cached result, return `null`.
- */
- nd.AnalysisResult getCachedAnalysisResult(String path) {
+ /// Return the cached analysis result for the file with the given [path].
+ /// If there is no cached result, return `null`.
+ ResolvedUnitResult getCachedResolvedUnit(String path) {
if (!AnalysisEngine.isDartFileName(path)) {
return null;
}
@@ -548,90 +342,7 @@
return driver?.getCachedResult(path);
}
- /**
- * Return a [Future] that completes with the [Element] at the given
- * [offset] of the given [file], or with `null` if there is no node at the
- * [offset] or the node does not have an element.
- */
- Future<Element> getElementAtOffset(String file, int offset) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
- if (!priorityFiles.contains(file)) {
- var driver = getAnalysisDriver(file);
- if (driver == null) {
- return null;
- }
-
- var unitElementResult = await driver.getUnitElement(file);
- if (unitElementResult == null) {
- return null;
- }
-
- var element = findElementByNameOffset(unitElementResult.element, offset);
- if (element != null) {
- return element;
- }
- }
-
- AstNode node = await getNodeAtOffset(file, offset);
- return getElementOfNode(node);
- }
-
- /**
- * Return the [Element] of the given [node], or `null` if [node] is `null` or
- * does not have an element.
- */
- Element getElementOfNode(AstNode node) {
- if (node == null) {
- return null;
- }
- if (node is SimpleIdentifier && node.parent is LibraryIdentifier) {
- node = node.parent;
- }
- if (node is LibraryIdentifier) {
- node = node.parent;
- }
- if (node is StringLiteral && node.parent is UriBasedDirective) {
- return null;
- }
- Element element = ElementLocator.locate(node);
- if (node is SimpleIdentifier && element is PrefixElement) {
- element = getImportElement(node);
- }
- return element;
- }
-
- /**
- * Return a [Future] that completes with the resolved [AstNode] at the
- * given [offset] of the given [file], or with `null` if there is no node as
- * the [offset].
- */
- Future<AstNode> getNodeAtOffset(String file, int offset) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
- nd.AnalysisResult result = await getAnalysisResult(file);
- CompilationUnit unit = result?.unit;
- if (unit != null) {
- return new NodeLocator(offset).searchWithin(unit);
- }
- return null;
- }
-
- /**
- * Return a [Future] that completes with the resolved [CompilationUnit] for
- * the Dart file with the given [path], or with `null` if the file is not a
- * Dart file or cannot be resolved.
- */
- Future<CompilationUnit> getResolvedCompilationUnit(String path) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
- nd.AnalysisResult result = await getAnalysisResult(path);
- return result?.unit;
- }
-
- /**
- * Handle a [request] that was read from the communication channel.
- */
+ /// Handle a [request] that was read from the communication channel.
void handleRequest(Request request) {
_performance.logRequest(request);
runZoned(() {
@@ -672,50 +383,38 @@
});
}
- /**
- * Return `true` if analysis is complete.
- */
+ /// Return `true` if analysis is complete.
bool isAnalysisComplete() {
return !analysisDriverScheduler.isAnalyzing;
}
- /**
- * Return `true` if the given path is a valid `FilePath`.
- *
- * This means that it is absolute and normalized.
- */
+ /// Return `true` if the given path is a valid `FilePath`.
+ ///
+ /// This means that it is absolute and normalized.
bool isValidFilePath(String path) {
return resourceProvider.pathContext.isAbsolute(path) &&
resourceProvider.pathContext.normalize(path) == path;
}
- /**
- * Trigger reanalysis of all files in the given list of analysis [roots], or
- * everything if the analysis roots is `null`.
- */
+ /// Trigger reanalysis of all files in the given list of analysis [roots], or
+ /// everything if the analysis roots is `null`.
void reanalyze(List<Resource> roots) {
// Instruct the contextDirectoryManager to rebuild all contexts from
// scratch.
contextManager.refresh(roots);
}
- /**
- * Send the given [notification] to the client.
- */
+ /// Send the given [notification] to the client.
void sendNotification(Notification notification) {
channel.sendNotification(notification);
}
- /**
- * Send the given [response] to the client.
- */
+ /// Send the given [response] to the client.
void sendResponse(Response response) {
channel.sendResponse(response);
}
- /**
- * Sends a `server.error` notification.
- */
+ /// Sends a `server.error` notification.
void sendServerErrorNotification(
String message,
dynamic exception,
@@ -761,10 +460,8 @@
));
}
- /**
- * Send status notification to the client. The state of analysis is given by
- * the [status] information.
- */
+ /// Send status notification to the client. The state of analysis is given by
+ /// the [status] information.
void sendStatusNotificationNew(nd.AnalysisStatus status) {
if (status.isAnalyzing) {
_onAnalysisStartedController.add(true);
@@ -795,18 +492,16 @@
new ServerStatusParams(analysis: analysis).toNotification());
}
- /**
- * Implementation for `analysis.setAnalysisRoots`.
- *
- * TODO(scheglov) implement complete projects/contexts semantics.
- *
- * The current implementation is intentionally simplified and expected
- * that only folders are given each given folder corresponds to the exactly
- * one context.
- *
- * So, we can start working in parallel on adding services and improving
- * projects/contexts support.
- */
+ /// Implementation for `analysis.setAnalysisRoots`.
+ ///
+ /// TODO(scheglov) implement complete projects/contexts semantics.
+ ///
+ /// The current implementation is intentionally simplified and expected
+ /// that only folders are given each given folder corresponds to the exactly
+ /// one context.
+ ///
+ /// So, we can start working in parallel on adding services and improving
+ /// projects/contexts support.
void setAnalysisRoots(String requestId, List<String> includedPaths,
List<String> excludedPaths, Map<String, String> packageRoots) {
if (notificationManager != null) {
@@ -820,9 +515,7 @@
}
}
- /**
- * Implementation for `analysis.setSubscriptions`.
- */
+ /// Implementation for `analysis.setSubscriptions`.
void setAnalysisSubscriptions(
Map<AnalysisService, Set<String>> subscriptions) {
if (notificationManager != null) {
@@ -836,14 +529,12 @@
// the fully resolved unit, and processed with sending analysis
// notifications as it happens after content changes.
if (AnalysisEngine.isDartFileName(file)) {
- getAnalysisResult(file, sendCachedToStream: true);
+ getResolvedUnit(file, sendCachedToStream: true);
}
}
}
- /**
- * Implementation for `flutter.setSubscriptions`.
- */
+ /// Implementation for `flutter.setSubscriptions`.
void setFlutterSubscriptions(Map<FlutterService, Set<String>> subscriptions) {
this.flutterServices = subscriptions;
Set<String> allNewFiles =
@@ -853,14 +544,12 @@
// the fully resolved unit, and processed with sending analysis
// notifications as it happens after content changes.
if (AnalysisEngine.isDartFileName(file)) {
- getAnalysisResult(file, sendCachedToStream: true);
+ getResolvedUnit(file, sendCachedToStream: true);
}
}
}
- /**
- * Implementation for `analysis.setGeneralSubscriptions`.
- */
+ /// Implementation for `analysis.setGeneralSubscriptions`.
void setGeneralAnalysisSubscriptions(
List<GeneralAnalysisService> subscriptions) {
Set<GeneralAnalysisService> newServices = subscriptions.toSet();
@@ -877,9 +566,7 @@
generalAnalysisServices = newServices;
}
- /**
- * Set the priority files to the given [files].
- */
+ /// Set the priority files to the given [files].
void setPriorityFiles(String requestId, List<String> files) {
priorityFiles.clear();
priorityFiles.addAll(files);
@@ -889,17 +576,13 @@
});
}
- /**
- * Returns `true` if errors should be reported for [file] with the given
- * absolute path.
- */
+ /// Returns `true` if errors should be reported for [file] with the given
+ /// absolute path.
bool shouldSendErrorsNotificationFor(String file) {
return contextManager.isInAnalysisRoot(file);
}
Future<void> shutdown() {
- running = false;
-
if (options.analytics != null) {
options.analytics
.waitForLastPing(timeout: new Duration(milliseconds: 200))
@@ -922,9 +605,7 @@
return new Future.value();
}
- /**
- * Implementation for `analysis.updateContent`.
- */
+ /// Implementation for `analysis.updateContent`.
void updateContent(String id, Map<String, dynamic> changes) {
_onAnalysisSetChangedController.add(null);
changes.forEach((file, change) {
@@ -969,10 +650,8 @@
});
}
- /**
- * Use the given updaters to update the values of the options in every
- * existing analysis context.
- */
+ /// Use the given updaters to update the values of the options in every
+ /// existing analysis context.
void updateOptions(List<OptionUpdater> optionUpdaters) {
// TODO(scheglov) implement for the new analysis driver
// //
@@ -996,32 +675,8 @@
// });
}
- /**
- * If the state location can be accessed, return the file byte store,
- * otherwise return the memory byte store.
- */
- ByteStore _createByteStore() {
- const int M = 1024 * 1024 /*1 MiB*/;
- const int G = 1024 * 1024 * 1024 /*1 GiB*/;
-
- const int memoryCacheSize = 128 * M;
-
- if (resourceProvider is PhysicalResourceProvider) {
- Folder stateLocation =
- resourceProvider.getStateLocation('.analysis-driver');
- if (stateLocation != null) {
- return new MemoryCachingByteStore(
- new EvictingFileByteStore(stateLocation.path, G), memoryCacheSize);
- }
- }
-
- return new MemoryCachingByteStore(new NullByteStore(), memoryCacheSize);
- }
-
- /**
- * Return the path to the location of the byte store on disk, or `null` if
- * there is no on-disk byte store.
- */
+ /// Return the path to the location of the byte store on disk, or `null` if
+ /// there is no on-disk byte store.
String _getByteStorePath() {
if (resourceProvider is PhysicalResourceProvider) {
Folder stateLocation =
@@ -1033,10 +688,8 @@
return null;
}
- /**
- * Returns `true` if there is a subscription for the given [service] and
- * [file].
- */
+ /// Returns `true` if there is a subscription for the given [service] and
+ /// [file].
bool _hasAnalysisServiceSubscription(AnalysisService service, String file) {
return analysisServices[service]?.contains(file) ?? false;
}
@@ -1055,9 +708,7 @@
}
}
-/**
- * Various IDE options.
- */
+/// Various IDE options.
class AnalysisServerOptions {
bool useAnalysisHighlight2 = false;
@@ -1067,48 +718,37 @@
String clientId;
String clientVersion;
- /**
- * Base path where to cache data.
- */
+ /// Base path where to cache data.
String cacheFolder;
- /**
- * The analytics instance; note, this object can be `null`, and should be
- * accessed via a null-aware operator.
- */
+ /// The analytics instance; note, this object can be `null`, and should be
+ /// accessed via a null-aware operator.
telemetry.Analytics analytics;
- /**
- * The crash report sender instance; note, this object can be `null`, and
- * should be accessed via a null-aware operator.
- */
+ /// The crash report sender instance; note, this object can be `null`, and
+ /// should be accessed via a null-aware operator.
CrashReportSender crashReportSender;
- /**
- * Whether to enable parsing via the Fasta parser.
- */
+ /// Whether to use the Language Server Protocol.
+ bool useLanguageServerProtocol = false;
+
+ /// Whether to enable parsing via the Fasta parser.
bool useFastaParser = true;
- /**
- * User Experience, Experiment #1. This experiment changes the notion of
- * what analysis roots are and priority files: the analysis root is set to be
- * the priority files' containing directory.
- */
+ /// User Experience, Experiment #1. This experiment changes the notion of
+ /// what analysis roots are and priority files: the analysis root is set to be
+ /// the priority files' containing directory.
bool enableUXExperiment1 = false;
- /**
- * User Experience, Experiment #2. This experiment introduces the notion of an
- * intermittent file system.
- */
+ /// User Experience, Experiment #2. This experiment introduces the notion of
+ /// an intermittent file system.
bool enableUXExperiment2 = false;
}
class ServerContextManagerCallbacks extends ContextManagerCallbacks {
final AnalysisServer analysisServer;
- /**
- * The [ResourceProvider] by which paths are converted into [Resource]s.
- */
+ /// The [ResourceProvider] by which paths are converted into [Resource]s.
final ResourceProvider resourceProvider;
ServerContextManagerCallbacks(this.analysisServer, this.resourceProvider);
@@ -1132,7 +772,7 @@
NotificationManager.serverId,
path,
server.doAnalysisError_listFromEngine(
- result.driver.analysisOptions,
+ result.session.analysisContext.analysisOptions,
result.lineInfo,
result.errors));
} else {
@@ -1232,8 +872,8 @@
if (analysisServer._hasFlutterServiceSubscription(
FlutterService.OUTLINE, path)) {
_runDelayed(() {
- sendFlutterNotificationOutline(
- analysisServer, path, result.content, result.lineInfo, unit);
+ sendFlutterNotificationOutline(analysisServer, path, result.content,
+ result.lineInfo, unit, result.typeProvider);
});
}
// TODO(scheglov) Implement notifications for AnalysisService.IMPLEMENTED.
@@ -1303,14 +943,15 @@
builderOptions.defaultOptions = options;
builderOptions.defaultPackageFilePath = defaultPackageFilePath;
builderOptions.defaultPackagesDirectoryPath = defaultPackagesDirectoryPath;
- ContextBuilder builder = new ContextBuilder(resourceProvider,
- analysisServer.sdkManager, analysisServer.overlayState,
+ ContextBuilder builder = new ContextBuilder(
+ resourceProvider, analysisServer.sdkManager, null,
options: builderOptions);
builder.fileResolverProvider = analysisServer.fileResolverProvider;
builder.packageResolverProvider = analysisServer.packageResolverProvider;
builder.analysisDriverScheduler = analysisServer.analysisDriverScheduler;
builder.performanceLog = analysisServer._analysisPerformanceLogger;
builder.byteStore = analysisServer.byteStore;
+ builder.enableIndex = true;
builder.fileContentOverlay = analysisServer.fileContentOverlay;
return builder;
}
@@ -1347,7 +988,7 @@
server.AnalysisNavigationParams _computeNavigationParams(
String path, CompilationUnit unit) {
NavigationCollectorImpl collector = new NavigationCollectorImpl();
- computeDartNavigation(collector, unit, null, null);
+ computeDartNavigation(resourceProvider, collector, unit, null, null);
collector.createRegions();
return new server.AnalysisNavigationParams(
path, collector.regions, collector.targets, collector.files);
@@ -1382,29 +1023,25 @@
libraryName: libraryName);
}
- /**
- * Run [f] in a new [Future].
- *
- * This method is used to delay sending notifications. If there is a more
- * important consumer of an analysis results, specifically a code completion
- * computer, we want it to run before spending time of sending notifications.
- *
- * TODO(scheglov) Consider replacing this with full priority based scheduler.
- *
- * TODO(scheglov) Alternatively, if code completion work in a way that does
- * not produce (at first) fully resolved unit, but only part of it - a single
- * method, or a top-level declaration, we would not have this problem - the
- * completion computer would be the only consumer of the partial analysis
- * result.
- */
+ /// Run [f] in a new [Future].
+ ///
+ /// This method is used to delay sending notifications. If there is a more
+ /// important consumer of an analysis results, specifically a code completion
+ /// computer, we want it to run before spending time of sending notifications.
+ ///
+ /// TODO(scheglov) Consider replacing this with full priority based scheduler.
+ ///
+ /// TODO(scheglov) Alternatively, if code completion work in a way that does
+ /// not produce (at first) fully resolved unit, but only part of it - a single
+ /// method, or a top-level declaration, we would not have this problem - the
+ /// completion computer would be the only consumer of the partial analysis
+ /// result.
void _runDelayed(f()) {
new Future(f);
}
}
-/**
- * Used to record server exceptions.
- */
+/// Used to record server exceptions.
class ServerException {
final String message;
final dynamic exception;
@@ -1417,40 +1054,26 @@
String toString() => message;
}
-/**
- * A class used by [AnalysisServer] to record performance information
- * such as request latency.
- */
+/// A class used by [AnalysisServer] to record performance information
+/// such as request latency.
class ServerPerformance {
- /**
- * The creation time and the time when performance information
- * started to be recorded here.
- */
+ /// The creation time and the time when performance information
+ /// started to be recorded here.
final int startTime = new DateTime.now().millisecondsSinceEpoch;
- /**
- * The number of requests.
- */
+ /// The number of requests.
int requestCount = 0;
- /**
- * The total latency (milliseconds) for all recorded requests.
- */
+ /// The total latency (milliseconds) for all recorded requests.
int requestLatency = 0;
- /**
- * The maximum latency (milliseconds) for all recorded requests.
- */
+ /// The maximum latency (milliseconds) for all recorded requests.
int maxLatency = 0;
- /**
- * The number of requests with latency > 150 milliseconds.
- */
+ /// The number of requests with latency > 150 milliseconds.
int slowRequestCount = 0;
- /**
- * Log performance information about the given request.
- */
+ /// Log performance information about the given request.
void logRequest(Request request) {
++requestCount;
if (request.clientRequestTime != null) {
@@ -1465,34 +1088,22 @@
}
}
-/**
- * Container with global [AnalysisServer] performance statistics.
- */
+/// Container with global [AnalysisServer] performance statistics.
class ServerPerformanceStatistics {
- /**
- * The [PerformanceTag] for `package:analysis_server`.
- */
+ /// The [PerformanceTag] for `package:analysis_server`.
static final PerformanceTag server = new PerformanceTag('server');
- /**
- * The [PerformanceTag] for time spent between calls to
- * AnalysisServer.performOperation when the server is idle.
- */
+ /// The [PerformanceTag] for time spent between calls to
+ /// AnalysisServer.performOperation when the server is idle.
static final PerformanceTag idle = new PerformanceTag('idle');
- /**
- * The [PerformanceTag] for time spent in
- * PerformAnalysisOperation._sendNotices.
- */
+ /// The [PerformanceTag] for time spent in
+ /// PerformAnalysisOperation._sendNotices.
static final PerformanceTag notices = server.createChild('notices');
- /**
- * The [PerformanceTag] for time spent in server communication channels.
- */
+ /// The [PerformanceTag] for time spent in server communication channels.
static final PerformanceTag serverChannel = server.createChild('channel');
- /**
- * The [PerformanceTag] for time spent in server request handlers.
- */
+ /// The [PerformanceTag] for time spent in server request handlers.
static final PerformanceTag serverRequests = server.createChild('requests');
}
diff --git a/pkg/analysis_server/lib/src/analysis_server_abstract.dart b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
new file mode 100644
index 0000000..20a6559
--- /dev/null
+++ b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
@@ -0,0 +1,200 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:core';
+
+import 'package:analysis_server/src/context_manager.dart';
+import 'package:analysis_server/src/services/correction/namespace.dart';
+import 'package:analysis_server/src/services/search/element_visitors.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/exception/exception.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/dart/analysis/byte_store.dart';
+import 'package:analyzer/src/dart/analysis/driver.dart' as nd;
+import 'package:analyzer/src/dart/analysis/file_byte_store.dart'
+ show EvictingFileByteStore;
+import 'package:analyzer/src/dart/analysis/file_state.dart' as nd;
+import 'package:analyzer/src/dart/analysis/status.dart' as nd;
+import 'package:analyzer/src/dart/ast/utilities.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/util/glob.dart';
+
+/// Implementations of [AbstractAnalysisServer] implement a server that listens
+/// on a [CommunicationChannel] for analysis messages and process them.
+abstract class AbstractAnalysisServer {
+ /// The [ContextManager] that handles the mapping from analysis roots to
+ /// context directories.
+ ContextManager contextManager;
+
+ /// The set of the files that are currently priority.
+ final Set<String> priorityFiles = new Set<String>();
+
+ final List<String> analyzableFilePatterns = <String>[
+ '**/*.${AnalysisEngine.SUFFIX_DART}',
+ '**/*.${AnalysisEngine.SUFFIX_HTML}',
+ '**/*.${AnalysisEngine.SUFFIX_HTM}',
+ '**/${AnalysisEngine.ANALYSIS_OPTIONS_FILE}',
+ '**/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}',
+ '**/${AnalysisEngine.PUBSPEC_YAML_FILE}'
+ ];
+
+ /// The [ResourceProvider] using which paths are converted into [Resource]s.
+ final ResourceProvider resourceProvider;
+
+ /// A list of the globs used to determine which files should be analyzed. The
+ /// list is lazily created and should be accessed using [analyzedFilesGlobs].
+ List<Glob> _analyzedFilesGlobs = null;
+
+ AbstractAnalysisServer(this.resourceProvider);
+
+ /// Return a list of the globs used to determine which files should be
+ /// analyzed.
+ List<Glob> get analyzedFilesGlobs {
+ if (_analyzedFilesGlobs == null) {
+ _analyzedFilesGlobs = <Glob>[];
+ for (String pattern in analyzableFilePatterns) {
+ try {
+ _analyzedFilesGlobs
+ .add(new Glob(resourceProvider.pathContext.separator, pattern));
+ } catch (exception, stackTrace) {
+ AnalysisEngine.instance.logger.logError(
+ 'Invalid glob pattern: "$pattern"',
+ new CaughtException(exception, stackTrace));
+ }
+ }
+ }
+ return _analyzedFilesGlobs;
+ }
+
+ /// A table mapping [Folder]s to the [AnalysisDriver]s associated with them.
+ Map<Folder, nd.AnalysisDriver> get driverMap => contextManager.driverMap;
+
+ /// If the state location can be accessed, return the file byte store,
+ /// otherwise return the memory byte store.
+ ByteStore createByteStore(ResourceProvider resourceProvider) {
+ const int M = 1024 * 1024 /*1 MiB*/;
+ const int G = 1024 * 1024 * 1024 /*1 GiB*/;
+
+ const int memoryCacheSize = 128 * M;
+
+ if (resourceProvider is PhysicalResourceProvider) {
+ Folder stateLocation =
+ resourceProvider.getStateLocation('.analysis-driver');
+ if (stateLocation != null) {
+ return new MemoryCachingByteStore(
+ new EvictingFileByteStore(stateLocation.path, G), memoryCacheSize);
+ }
+ }
+
+ return new MemoryCachingByteStore(new NullByteStore(), memoryCacheSize);
+ }
+
+ /// Return an analysis driver to which the file with the given [path] is
+ /// added if one exists, otherwise a driver in which the file was analyzed if
+ /// one exists, otherwise the first driver, otherwise `null`.
+ nd.AnalysisDriver getAnalysisDriver(String path) {
+ List<nd.AnalysisDriver> drivers = driverMap.values.toList();
+ if (drivers.isNotEmpty) {
+ // Sort the drivers so that more deeply nested contexts will be checked
+ // before enclosing contexts.
+ drivers.sort((first, second) =>
+ second.contextRoot.root.length - first.contextRoot.root.length);
+ nd.AnalysisDriver driver = drivers.firstWhere(
+ (driver) => driver.contextRoot.containsFile(path),
+ orElse: () => null);
+ driver ??= drivers.firstWhere(
+ (driver) => driver.knownFiles.contains(path),
+ orElse: () => null);
+ driver ??= drivers.first;
+ return driver;
+ }
+ return null;
+ }
+
+ /// Return a [Future] that completes with the [Element] at the given
+ /// [offset] of the given [file], or with `null` if there is no node at the
+ /// [offset] or the node does not have an element.
+ Future<Element> getElementAtOffset(String file, int offset) async {
+ // TODO(brianwilkerson) Determine whether this await is necessary.
+ await null;
+ if (!priorityFiles.contains(file)) {
+ var driver = getAnalysisDriver(file);
+ if (driver == null) {
+ return null;
+ }
+
+ var unitElementResult = await driver.getUnitElement(file);
+ if (unitElementResult == null) {
+ return null;
+ }
+
+ var element = findElementByNameOffset(unitElementResult.element, offset);
+ if (element != null) {
+ return element;
+ }
+ }
+
+ AstNode node = await getNodeAtOffset(file, offset);
+ return getElementOfNode(node);
+ }
+
+ /// Return the [Element] of the given [node], or `null` if [node] is `null` or
+ /// does not have an element.
+ Element getElementOfNode(AstNode node) {
+ if (node == null) {
+ return null;
+ }
+ if (node is SimpleIdentifier && node.parent is LibraryIdentifier) {
+ node = node.parent;
+ }
+ if (node is LibraryIdentifier) {
+ node = node.parent;
+ }
+ if (node is StringLiteral && node.parent is UriBasedDirective) {
+ return null;
+ }
+ Element element = ElementLocator.locate(node);
+ if (node is SimpleIdentifier && element is PrefixElement) {
+ element = getImportElement(node);
+ }
+ return element;
+ }
+
+ /// Return a [Future] that completes with the resolved [AstNode] at the
+ /// given [offset] of the given [file], or with `null` if there is no node as
+ /// the [offset].
+ Future<AstNode> getNodeAtOffset(String file, int offset) async {
+ // TODO(brianwilkerson) Determine whether this await is necessary.
+ await null;
+ ResolvedUnitResult result = await getResolvedUnit(file);
+ CompilationUnit unit = result?.unit;
+ if (unit != null) {
+ return new NodeLocator(offset).searchWithin(unit);
+ }
+ return null;
+ }
+
+ /// Return the resolved unit for the file with the given [path]. The file is
+ /// analyzed in one of the analysis drivers to which the file was added,
+ /// otherwise in the first driver, otherwise `null` is returned.
+ Future<ResolvedUnitResult> getResolvedUnit(String path,
+ {bool sendCachedToStream: false}) {
+ if (!AnalysisEngine.isDartFileName(path)) {
+ return null;
+ }
+
+ nd.AnalysisDriver driver = getAnalysisDriver(path);
+ if (driver == null) {
+ return new Future.value();
+ }
+
+ return driver
+ .getResult(path, sendCachedToStream: sendCachedToStream)
+ .catchError((_) => null);
+ }
+}
diff --git a/pkg/analysis_server/lib/src/computer/computer_closingLabels.dart b/pkg/analysis_server/lib/src/computer/computer_closingLabels.dart
index d1fe2d4..19ff554 100644
--- a/pkg/analysis_server/lib/src/computer/computer_closingLabels.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_closingLabels.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// 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.
@@ -45,8 +45,7 @@
/**
* An AST visitor for [DartUnitClosingLabelsComputer].
*/
-class _DartUnitClosingLabelsComputerVisitor
- extends RecursiveAstVisitor<Object> {
+class _DartUnitClosingLabelsComputerVisitor extends RecursiveAstVisitor<void> {
final DartUnitClosingLabelsComputer computer;
int interpolatedStringsEntered = 0;
@@ -57,7 +56,7 @@
ClosingLabel get _currentLabel => labelStack.isEmpty ? null : labelStack.last;
@override
- Object visitInstanceCreationExpression(InstanceCreationExpression node) {
+ void visitInstanceCreationExpression(InstanceCreationExpression node) {
ClosingLabel label;
if (node.argumentList != null) {
@@ -75,14 +74,14 @@
if (label != null) _pushLabel(label);
try {
- return super.visitInstanceCreationExpression(node);
+ super.visitInstanceCreationExpression(node);
} finally {
if (label != null) _popLabel();
}
}
@override
- Object visitListLiteral(ListLiteral node) {
+ void visitListLiteral(ListLiteral node) {
final NodeList<TypeAnnotation> args = node.typeArguments?.arguments;
final String typeName = args != null ? args[0]?.toString() : null;
@@ -95,17 +94,17 @@
if (label != null) _pushLabel(label);
try {
- return super.visitListLiteral(node);
+ super.visitListLiteral(node);
} finally {
if (label != null) _popLabel();
}
}
@override
- Object visitStringInterpolation(StringInterpolation node) {
+ void visitStringInterpolation(StringInterpolation node) {
interpolatedStringsEntered++;
try {
- return super.visitStringInterpolation(node);
+ super.visitStringInterpolation(node);
} finally {
interpolatedStringsEntered--;
}
diff --git a/pkg/analysis_server/lib/src/computer/computer_folding.dart b/pkg/analysis_server/lib/src/computer/computer_folding.dart
index 9488775..4edf2fc 100644
--- a/pkg/analysis_server/lib/src/computer/computer_folding.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_folding.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2018, 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.
@@ -105,129 +105,129 @@
/**
* An AST visitor for [DartUnitFoldingComputer].
*/
-class _DartUnitFoldingComputerVisitor extends RecursiveAstVisitor<Object> {
+class _DartUnitFoldingComputerVisitor extends RecursiveAstVisitor<void> {
final DartUnitFoldingComputer _computer;
_DartUnitFoldingComputerVisitor(this._computer);
@override
- Object visitBlockFunctionBody(BlockFunctionBody node) {
+ void visitBlockFunctionBody(BlockFunctionBody node) {
_computer._addRegion(node.block.leftBracket.end,
node.block.rightBracket.offset, FoldingKind.FUNCTION_BODY);
- return super.visitBlockFunctionBody(node);
+ super.visitBlockFunctionBody(node);
}
@override
- Object visitClassDeclaration(ClassDeclaration node) {
+ void visitClassDeclaration(ClassDeclaration node) {
_computer._addRegionForAnnotations(node.metadata);
_computer._addRegion(
node.leftBracket.end, node.rightBracket.offset, FoldingKind.CLASS_BODY);
- return super.visitClassDeclaration(node);
+ super.visitClassDeclaration(node);
}
@override
- Object visitComment(Comment node) {
+ void visitComment(Comment node) {
if (node.isDocumentation) {
_computer._addRegion(
node.offset, node.end, FoldingKind.DOCUMENTATION_COMMENT);
}
- return super.visitComment(node);
+ super.visitComment(node);
}
@override
- Object visitConstructorDeclaration(ConstructorDeclaration node) {
+ void visitConstructorDeclaration(ConstructorDeclaration node) {
_computer._addRegionForAnnotations(node.metadata);
- return super.visitConstructorDeclaration(node);
+ super.visitConstructorDeclaration(node);
}
@override
- Object visitExportDirective(ExportDirective node) {
+ void visitExportDirective(ExportDirective node) {
_computer._recordDirective(node);
- return super.visitExportDirective(node);
+ super.visitExportDirective(node);
}
@override
- Object visitFieldDeclaration(FieldDeclaration node) {
+ void visitFieldDeclaration(FieldDeclaration node) {
_computer._addRegionForAnnotations(node.metadata);
- return super.visitFieldDeclaration(node);
+ super.visitFieldDeclaration(node);
}
@override
- Object visitFunctionDeclaration(FunctionDeclaration node) {
+ void visitFunctionDeclaration(FunctionDeclaration node) {
_computer._addRegionForAnnotations(node.metadata);
- return super.visitFunctionDeclaration(node);
+ super.visitFunctionDeclaration(node);
}
@override
- Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+ void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
_computer._addRegion(node.argumentList.leftParenthesis.end,
node.argumentList.rightParenthesis.offset, FoldingKind.INVOCATION);
- return super.visitFunctionExpressionInvocation(node);
+ super.visitFunctionExpressionInvocation(node);
}
@override
- visitImportDirective(ImportDirective node) {
+ void visitImportDirective(ImportDirective node) {
_computer._recordDirective(node);
- return super.visitImportDirective(node);
+ super.visitImportDirective(node);
}
@override
- Object visitInstanceCreationExpression(InstanceCreationExpression node) {
+ void visitInstanceCreationExpression(InstanceCreationExpression node) {
_computer._addRegion(node.argumentList.leftParenthesis.end,
node.argumentList.rightParenthesis.offset, FoldingKind.INVOCATION);
- return super.visitInstanceCreationExpression(node);
+ super.visitInstanceCreationExpression(node);
}
@override
- Object visitLibraryDirective(LibraryDirective node) {
+ void visitLibraryDirective(LibraryDirective node) {
_computer._recordDirective(node);
- return super.visitLibraryDirective(node);
+ super.visitLibraryDirective(node);
}
@override
- Object visitListLiteral(ListLiteral node) {
+ void visitListLiteral(ListLiteral node) {
_computer._addRegion(
node.leftBracket.end, node.rightBracket.offset, FoldingKind.LITERAL);
- return super.visitListLiteral(node);
+ super.visitListLiteral(node);
}
@override
- Object visitMapLiteral(MapLiteral node) {
+ void visitMapLiteral(MapLiteral node) {
_computer._addRegion(
node.leftBracket.end, node.rightBracket.offset, FoldingKind.LITERAL);
- return super.visitMapLiteral(node);
+ super.visitMapLiteral(node);
}
@override
- Object visitMethodDeclaration(MethodDeclaration node) {
+ void visitMethodDeclaration(MethodDeclaration node) {
_computer._addRegionForAnnotations(node.metadata);
- return super.visitMethodDeclaration(node);
+ super.visitMethodDeclaration(node);
}
@override
- Object visitMethodInvocation(MethodInvocation node) {
+ void visitMethodInvocation(MethodInvocation node) {
_computer._addRegion(node.argumentList.leftParenthesis.end,
node.argumentList.rightParenthesis.offset, FoldingKind.INVOCATION);
- return super.visitMethodInvocation(node);
+ super.visitMethodInvocation(node);
}
@override
- Object visitMixinDeclaration(MixinDeclaration node) {
+ void visitMixinDeclaration(MixinDeclaration node) {
_computer._addRegionForAnnotations(node.metadata);
// TODO(brianwilkerson) Define `FoldingKind.MIXIN_BODY`?
_computer._addRegion(
node.leftBracket.end, node.rightBracket.offset, FoldingKind.CLASS_BODY);
- return super.visitMixinDeclaration(node);
+ super.visitMixinDeclaration(node);
}
@override
- Object visitPartDirective(PartDirective node) {
+ void visitPartDirective(PartDirective node) {
_computer._recordDirective(node);
- return super.visitPartDirective(node);
+ super.visitPartDirective(node);
}
@override
- Object visitPartOfDirective(PartOfDirective node) {
+ void visitPartOfDirective(PartOfDirective node) {
_computer._recordDirective(node);
- return super.visitPartOfDirective(node);
+ super.visitPartOfDirective(node);
}
}
diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights.dart b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
index b0b5d40..39c1e8e 100644
--- a/pkg/analysis_server/lib/src/computer/computer_highlights.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -344,251 +344,251 @@
/**
* An AST visitor for [DartUnitHighlightsComputer].
*/
-class _DartUnitHighlightsComputerVisitor extends RecursiveAstVisitor<Object> {
+class _DartUnitHighlightsComputerVisitor extends RecursiveAstVisitor<void> {
final DartUnitHighlightsComputer computer;
_DartUnitHighlightsComputerVisitor(this.computer);
@override
- Object visitAnnotation(Annotation node) {
+ void visitAnnotation(Annotation node) {
computer._addIdentifierRegion_annotation(node);
- return super.visitAnnotation(node);
+ super.visitAnnotation(node);
}
@override
- Object visitAsExpression(AsExpression node) {
+ void visitAsExpression(AsExpression node) {
computer._addRegion_token(node.asOperator, HighlightRegionType.BUILT_IN);
- return super.visitAsExpression(node);
+ super.visitAsExpression(node);
}
@override
- Object visitAssertStatement(AssertStatement node) {
+ void visitAssertStatement(AssertStatement node) {
computer._addRegion_token(node.assertKeyword, HighlightRegionType.KEYWORD);
- return super.visitAssertStatement(node);
+ super.visitAssertStatement(node);
}
@override
- Object visitAwaitExpression(AwaitExpression node) {
+ void visitAwaitExpression(AwaitExpression node) {
computer._addRegion_token(node.awaitKeyword, HighlightRegionType.BUILT_IN);
- return super.visitAwaitExpression(node);
+ super.visitAwaitExpression(node);
}
@override
- Object visitBlockFunctionBody(BlockFunctionBody node) {
+ void visitBlockFunctionBody(BlockFunctionBody node) {
_addRegions_functionBody(node);
- return super.visitBlockFunctionBody(node);
+ super.visitBlockFunctionBody(node);
}
@override
- Object visitBooleanLiteral(BooleanLiteral node) {
+ void visitBooleanLiteral(BooleanLiteral node) {
computer._addRegion_node(node, HighlightRegionType.KEYWORD);
computer._addRegion_node(node, HighlightRegionType.LITERAL_BOOLEAN);
- return super.visitBooleanLiteral(node);
+ super.visitBooleanLiteral(node);
}
@override
- Object visitBreakStatement(BreakStatement node) {
+ void visitBreakStatement(BreakStatement node) {
computer._addRegion_token(node.breakKeyword, HighlightRegionType.KEYWORD);
- return super.visitBreakStatement(node);
+ super.visitBreakStatement(node);
}
@override
- Object visitCatchClause(CatchClause node) {
+ void visitCatchClause(CatchClause node) {
computer._addRegion_token(node.catchKeyword, HighlightRegionType.KEYWORD);
computer._addRegion_token(node.onKeyword, HighlightRegionType.BUILT_IN);
- return super.visitCatchClause(node);
+ super.visitCatchClause(node);
}
@override
- Object visitClassDeclaration(ClassDeclaration node) {
+ void visitClassDeclaration(ClassDeclaration node) {
computer._addRegion_token(node.classKeyword, HighlightRegionType.KEYWORD);
computer._addRegion_token(
node.abstractKeyword, HighlightRegionType.BUILT_IN);
- return super.visitClassDeclaration(node);
+ super.visitClassDeclaration(node);
}
@override
- Object visitClassTypeAlias(ClassTypeAlias node) {
+ void visitClassTypeAlias(ClassTypeAlias node) {
computer._addRegion_token(
node.abstractKeyword, HighlightRegionType.BUILT_IN);
- return super.visitClassTypeAlias(node);
+ super.visitClassTypeAlias(node);
}
@override
- Object visitConstructorDeclaration(ConstructorDeclaration node) {
+ void visitConstructorDeclaration(ConstructorDeclaration node) {
computer._addRegion_token(
node.externalKeyword, HighlightRegionType.BUILT_IN);
computer._addRegion_token(
node.factoryKeyword, HighlightRegionType.BUILT_IN);
- return super.visitConstructorDeclaration(node);
+ super.visitConstructorDeclaration(node);
}
@override
- Object visitContinueStatement(ContinueStatement node) {
+ void visitContinueStatement(ContinueStatement node) {
computer._addRegion_token(
node.continueKeyword, HighlightRegionType.KEYWORD);
- return super.visitContinueStatement(node);
+ super.visitContinueStatement(node);
}
@override
- Object visitDoStatement(DoStatement node) {
+ void visitDoStatement(DoStatement node) {
computer._addRegion_token(node.doKeyword, HighlightRegionType.KEYWORD);
computer._addRegion_token(node.whileKeyword, HighlightRegionType.KEYWORD);
- return super.visitDoStatement(node);
+ super.visitDoStatement(node);
}
@override
- Object visitDoubleLiteral(DoubleLiteral node) {
+ void visitDoubleLiteral(DoubleLiteral node) {
computer._addRegion_node(node, HighlightRegionType.LITERAL_DOUBLE);
- return super.visitDoubleLiteral(node);
+ super.visitDoubleLiteral(node);
}
@override
- Object visitEnumDeclaration(EnumDeclaration node) {
+ void visitEnumDeclaration(EnumDeclaration node) {
computer._addRegion_token(node.enumKeyword, HighlightRegionType.KEYWORD);
- return super.visitEnumDeclaration(node);
+ super.visitEnumDeclaration(node);
}
@override
- Object visitExportDirective(ExportDirective node) {
+ void visitExportDirective(ExportDirective node) {
computer._addRegion_node(node, HighlightRegionType.DIRECTIVE);
computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN);
- return super.visitExportDirective(node);
+ super.visitExportDirective(node);
}
@override
- Object visitExpressionFunctionBody(ExpressionFunctionBody node) {
+ void visitExpressionFunctionBody(ExpressionFunctionBody node) {
_addRegions_functionBody(node);
- return super.visitExpressionFunctionBody(node);
+ super.visitExpressionFunctionBody(node);
}
@override
- Object visitExtendsClause(ExtendsClause node) {
+ void visitExtendsClause(ExtendsClause node) {
computer._addRegion_token(node.extendsKeyword, HighlightRegionType.KEYWORD);
- return super.visitExtendsClause(node);
+ super.visitExtendsClause(node);
}
@override
- Object visitFieldDeclaration(FieldDeclaration node) {
+ void visitFieldDeclaration(FieldDeclaration node) {
computer._addRegion_token(node.staticKeyword, HighlightRegionType.BUILT_IN);
- return super.visitFieldDeclaration(node);
+ super.visitFieldDeclaration(node);
}
@override
- Object visitForEachStatement(ForEachStatement node) {
+ void visitForEachStatement(ForEachStatement node) {
computer._addRegion_token(node.awaitKeyword, HighlightRegionType.BUILT_IN);
computer._addRegion_token(node.forKeyword, HighlightRegionType.KEYWORD);
computer._addRegion_token(node.inKeyword, HighlightRegionType.KEYWORD);
- return super.visitForEachStatement(node);
+ super.visitForEachStatement(node);
}
@override
- Object visitForStatement(ForStatement node) {
+ void visitForStatement(ForStatement node) {
computer._addRegion_token(node.forKeyword, HighlightRegionType.KEYWORD);
- return super.visitForStatement(node);
+ super.visitForStatement(node);
}
@override
- Object visitFunctionDeclaration(FunctionDeclaration node) {
+ void visitFunctionDeclaration(FunctionDeclaration node) {
computer._addRegion_token(
node.externalKeyword, HighlightRegionType.BUILT_IN);
computer._addRegion_token(
node.propertyKeyword, HighlightRegionType.BUILT_IN);
- return super.visitFunctionDeclaration(node);
+ super.visitFunctionDeclaration(node);
}
@override
- Object visitFunctionTypeAlias(FunctionTypeAlias node) {
+ void visitFunctionTypeAlias(FunctionTypeAlias node) {
computer._addRegion_token(
node.typedefKeyword, HighlightRegionType.BUILT_IN);
- return super.visitFunctionTypeAlias(node);
+ super.visitFunctionTypeAlias(node);
}
@override
- Object visitGenericFunctionType(GenericFunctionType node) {
+ void visitGenericFunctionType(GenericFunctionType node) {
computer._addRegion_token(
node.functionKeyword, HighlightRegionType.KEYWORD);
- return super.visitGenericFunctionType(node);
+ super.visitGenericFunctionType(node);
}
@override
- Object visitGenericTypeAlias(GenericTypeAlias node) {
+ void visitGenericTypeAlias(GenericTypeAlias node) {
computer._addRegion_token(node.typedefKeyword, HighlightRegionType.KEYWORD);
- return super.visitGenericTypeAlias(node);
+ super.visitGenericTypeAlias(node);
}
@override
- Object visitHideCombinator(HideCombinator node) {
+ void visitHideCombinator(HideCombinator node) {
computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN);
- return super.visitHideCombinator(node);
+ super.visitHideCombinator(node);
}
@override
- Object visitIfStatement(IfStatement node) {
+ void visitIfStatement(IfStatement node) {
computer._addRegion_token(node.ifKeyword, HighlightRegionType.KEYWORD);
- return super.visitIfStatement(node);
+ super.visitIfStatement(node);
}
@override
- Object visitImplementsClause(ImplementsClause node) {
+ void visitImplementsClause(ImplementsClause node) {
computer._addRegion_token(
node.implementsKeyword, HighlightRegionType.BUILT_IN);
- return super.visitImplementsClause(node);
+ super.visitImplementsClause(node);
}
@override
- Object visitImportDirective(ImportDirective node) {
+ void visitImportDirective(ImportDirective node) {
computer._addRegion_node(node, HighlightRegionType.DIRECTIVE);
computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN);
computer._addRegion_token(
node.deferredKeyword, HighlightRegionType.BUILT_IN);
computer._addRegion_token(node.asKeyword, HighlightRegionType.BUILT_IN);
- return super.visitImportDirective(node);
+ super.visitImportDirective(node);
}
@override
- Object visitInstanceCreationExpression(InstanceCreationExpression node) {
+ void visitInstanceCreationExpression(InstanceCreationExpression node) {
if (node.keyword != null) {
computer._addRegion_token(node.keyword, HighlightRegionType.KEYWORD);
}
- return super.visitInstanceCreationExpression(node);
+ super.visitInstanceCreationExpression(node);
}
@override
- Object visitIntegerLiteral(IntegerLiteral node) {
+ void visitIntegerLiteral(IntegerLiteral node) {
computer._addRegion_node(node, HighlightRegionType.LITERAL_INTEGER);
- return super.visitIntegerLiteral(node);
+ super.visitIntegerLiteral(node);
}
@override
- Object visitIsExpression(IsExpression node) {
+ void visitIsExpression(IsExpression node) {
computer._addRegion_token(node.isOperator, HighlightRegionType.KEYWORD);
- return super.visitIsExpression(node);
+ super.visitIsExpression(node);
}
@override
- Object visitLibraryDirective(LibraryDirective node) {
+ void visitLibraryDirective(LibraryDirective node) {
computer._addRegion_node(node, HighlightRegionType.DIRECTIVE);
computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN);
- return super.visitLibraryDirective(node);
+ super.visitLibraryDirective(node);
}
@override
- Object visitListLiteral(ListLiteral node) {
+ void visitListLiteral(ListLiteral node) {
computer._addRegion_node(node, HighlightRegionType.LITERAL_LIST);
computer._addRegion_token(node.constKeyword, HighlightRegionType.KEYWORD);
- return super.visitListLiteral(node);
+ super.visitListLiteral(node);
}
@override
- Object visitMapLiteral(MapLiteral node) {
+ void visitMapLiteral(MapLiteral node) {
computer._addRegion_node(node, HighlightRegionType.LITERAL_MAP);
computer._addRegion_token(node.constKeyword, HighlightRegionType.KEYWORD);
- return super.visitMapLiteral(node);
+ super.visitMapLiteral(node);
}
@override
- Object visitMethodDeclaration(MethodDeclaration node) {
+ void visitMethodDeclaration(MethodDeclaration node) {
computer._addRegion_token(
node.externalKeyword, HighlightRegionType.BUILT_IN);
computer._addRegion_token(
@@ -597,117 +597,117 @@
node.operatorKeyword, HighlightRegionType.BUILT_IN);
computer._addRegion_token(
node.propertyKeyword, HighlightRegionType.BUILT_IN);
- return super.visitMethodDeclaration(node);
+ super.visitMethodDeclaration(node);
}
@override
- Object visitMixinDeclaration(MixinDeclaration node) {
+ void visitMixinDeclaration(MixinDeclaration node) {
computer._addRegion_token(node.mixinKeyword, HighlightRegionType.BUILT_IN);
- return super.visitMixinDeclaration(node);
+ super.visitMixinDeclaration(node);
}
@override
- Object visitNativeClause(NativeClause node) {
+ void visitNativeClause(NativeClause node) {
computer._addRegion_token(node.nativeKeyword, HighlightRegionType.BUILT_IN);
- return super.visitNativeClause(node);
+ super.visitNativeClause(node);
}
@override
- Object visitNativeFunctionBody(NativeFunctionBody node) {
+ void visitNativeFunctionBody(NativeFunctionBody node) {
computer._addRegion_token(node.nativeKeyword, HighlightRegionType.BUILT_IN);
- return super.visitNativeFunctionBody(node);
+ super.visitNativeFunctionBody(node);
}
@override
- Object visitOnClause(OnClause node) {
+ void visitOnClause(OnClause node) {
computer._addRegion_token(node.onKeyword, HighlightRegionType.BUILT_IN);
- return super.visitOnClause(node);
+ super.visitOnClause(node);
}
@override
- Object visitPartDirective(PartDirective node) {
+ void visitPartDirective(PartDirective node) {
computer._addRegion_node(node, HighlightRegionType.DIRECTIVE);
computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN);
- return super.visitPartDirective(node);
+ super.visitPartDirective(node);
}
@override
- Object visitPartOfDirective(PartOfDirective node) {
+ void visitPartOfDirective(PartOfDirective node) {
computer._addRegion_node(node, HighlightRegionType.DIRECTIVE);
computer._addRegion_tokenStart_tokenEnd(
node.partKeyword, node.ofKeyword, HighlightRegionType.BUILT_IN);
- return super.visitPartOfDirective(node);
+ super.visitPartOfDirective(node);
}
@override
- Object visitRethrowExpression(RethrowExpression node) {
+ void visitRethrowExpression(RethrowExpression node) {
computer._addRegion_token(node.rethrowKeyword, HighlightRegionType.KEYWORD);
- return super.visitRethrowExpression(node);
+ super.visitRethrowExpression(node);
}
@override
- Object visitReturnStatement(ReturnStatement node) {
+ void visitReturnStatement(ReturnStatement node) {
computer._addRegion_token(node.returnKeyword, HighlightRegionType.KEYWORD);
- return super.visitReturnStatement(node);
+ super.visitReturnStatement(node);
}
@override
- Object visitShowCombinator(ShowCombinator node) {
+ void visitShowCombinator(ShowCombinator node) {
computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN);
- return super.visitShowCombinator(node);
+ super.visitShowCombinator(node);
}
@override
- Object visitSimpleIdentifier(SimpleIdentifier node) {
+ void visitSimpleIdentifier(SimpleIdentifier node) {
computer._addIdentifierRegion(node);
- return super.visitSimpleIdentifier(node);
+ super.visitSimpleIdentifier(node);
}
@override
- Object visitSimpleStringLiteral(SimpleStringLiteral node) {
+ void visitSimpleStringLiteral(SimpleStringLiteral node) {
computer._addRegion_node(node, HighlightRegionType.LITERAL_STRING);
- return super.visitSimpleStringLiteral(node);
+ super.visitSimpleStringLiteral(node);
}
@override
- Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+ void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
computer._addRegion_token(node.superKeyword, HighlightRegionType.KEYWORD);
- return super.visitSuperConstructorInvocation(node);
+ super.visitSuperConstructorInvocation(node);
}
@override
- Object visitSwitchCase(SwitchCase node) {
+ void visitSwitchCase(SwitchCase node) {
computer._addRegion_token(node.keyword, HighlightRegionType.KEYWORD);
- return super.visitSwitchCase(node);
+ super.visitSwitchCase(node);
}
@override
- Object visitSwitchDefault(SwitchDefault node) {
+ void visitSwitchDefault(SwitchDefault node) {
computer._addRegion_token(node.keyword, HighlightRegionType.KEYWORD);
- return super.visitSwitchDefault(node);
+ super.visitSwitchDefault(node);
}
@override
- Object visitSwitchStatement(SwitchStatement node) {
+ void visitSwitchStatement(SwitchStatement node) {
computer._addRegion_token(node.switchKeyword, HighlightRegionType.KEYWORD);
- return super.visitSwitchStatement(node);
+ super.visitSwitchStatement(node);
}
@override
- Object visitThisExpression(ThisExpression node) {
+ void visitThisExpression(ThisExpression node) {
computer._addRegion_token(node.thisKeyword, HighlightRegionType.KEYWORD);
- return super.visitThisExpression(node);
+ super.visitThisExpression(node);
}
@override
- Object visitTryStatement(TryStatement node) {
+ void visitTryStatement(TryStatement node) {
computer._addRegion_token(node.tryKeyword, HighlightRegionType.KEYWORD);
computer._addRegion_token(node.finallyKeyword, HighlightRegionType.KEYWORD);
- return super.visitTryStatement(node);
+ super.visitTryStatement(node);
}
@override
- Object visitTypeName(TypeName node) {
+ void visitTypeName(TypeName node) {
DartType type = node.type;
if (type != null) {
if (type.isDynamic && node.name.name == "dynamic") {
@@ -715,35 +715,35 @@
return null;
}
}
- return super.visitTypeName(node);
+ super.visitTypeName(node);
}
@override
- Object visitVariableDeclarationList(VariableDeclarationList node) {
+ void visitVariableDeclarationList(VariableDeclarationList node) {
computer._addRegion_token(node.keyword, HighlightRegionType.KEYWORD);
- return super.visitVariableDeclarationList(node);
+ super.visitVariableDeclarationList(node);
}
@override
- Object visitWhileStatement(WhileStatement node) {
+ void visitWhileStatement(WhileStatement node) {
computer._addRegion_token(node.whileKeyword, HighlightRegionType.KEYWORD);
- return super.visitWhileStatement(node);
+ super.visitWhileStatement(node);
}
@override
- Object visitWithClause(WithClause node) {
+ void visitWithClause(WithClause node) {
computer._addRegion_token(node.withKeyword, HighlightRegionType.KEYWORD);
- return super.visitWithClause(node);
+ super.visitWithClause(node);
}
@override
- Object visitYieldStatement(YieldStatement node) {
+ void visitYieldStatement(YieldStatement node) {
Token keyword = node.yieldKeyword;
Token star = node.star;
int offset = keyword.offset;
int end = star != null ? star.end : keyword.end;
computer._addRegion(offset, end - offset, HighlightRegionType.BUILT_IN);
- return super.visitYieldStatement(node);
+ super.visitYieldStatement(node);
}
void _addRegions_functionBody(FunctionBody node) {
diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights2.dart b/pkg/analysis_server/lib/src/computer/computer_highlights2.dart
index dad226c..6ae85e2 100644
--- a/pkg/analysis_server/lib/src/computer/computer_highlights2.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_highlights2.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -435,257 +435,257 @@
/**
* An AST visitor for [DartUnitHighlightsComputer2].
*/
-class _DartUnitHighlightsComputerVisitor2 extends RecursiveAstVisitor<Object> {
+class _DartUnitHighlightsComputerVisitor2 extends RecursiveAstVisitor<void> {
final DartUnitHighlightsComputer2 computer;
_DartUnitHighlightsComputerVisitor2(this.computer);
@override
- Object visitAnnotation(Annotation node) {
+ void visitAnnotation(Annotation node) {
computer._addIdentifierRegion_annotation(node);
- return super.visitAnnotation(node);
+ super.visitAnnotation(node);
}
@override
- Object visitAsExpression(AsExpression node) {
+ void visitAsExpression(AsExpression node) {
computer._addRegion_token(node.asOperator, HighlightRegionType.BUILT_IN);
- return super.visitAsExpression(node);
+ super.visitAsExpression(node);
}
@override
- Object visitAssertStatement(AssertStatement node) {
+ void visitAssertStatement(AssertStatement node) {
computer._addRegion_token(node.assertKeyword, HighlightRegionType.KEYWORD);
- return super.visitAssertStatement(node);
+ super.visitAssertStatement(node);
}
@override
- Object visitAwaitExpression(AwaitExpression node) {
+ void visitAwaitExpression(AwaitExpression node) {
computer._addRegion_token(node.awaitKeyword, HighlightRegionType.BUILT_IN);
- return super.visitAwaitExpression(node);
+ super.visitAwaitExpression(node);
}
@override
- Object visitBlockFunctionBody(BlockFunctionBody node) {
+ void visitBlockFunctionBody(BlockFunctionBody node) {
_addRegions_functionBody(node);
- return super.visitBlockFunctionBody(node);
+ super.visitBlockFunctionBody(node);
}
@override
- Object visitBooleanLiteral(BooleanLiteral node) {
+ void visitBooleanLiteral(BooleanLiteral node) {
computer._addRegion_node(node, HighlightRegionType.KEYWORD);
computer._addRegion_node(node, HighlightRegionType.LITERAL_BOOLEAN);
- return super.visitBooleanLiteral(node);
+ super.visitBooleanLiteral(node);
}
@override
- Object visitBreakStatement(BreakStatement node) {
+ void visitBreakStatement(BreakStatement node) {
computer._addRegion_token(node.breakKeyword, HighlightRegionType.KEYWORD);
- return super.visitBreakStatement(node);
+ super.visitBreakStatement(node);
}
@override
- Object visitCatchClause(CatchClause node) {
+ void visitCatchClause(CatchClause node) {
computer._addRegion_token(node.catchKeyword, HighlightRegionType.KEYWORD);
computer._addRegion_token(node.onKeyword, HighlightRegionType.BUILT_IN);
- return super.visitCatchClause(node);
+ super.visitCatchClause(node);
}
@override
- Object visitClassDeclaration(ClassDeclaration node) {
+ void visitClassDeclaration(ClassDeclaration node) {
computer._addRegion_token(node.classKeyword, HighlightRegionType.KEYWORD);
computer._addRegion_token(
node.abstractKeyword, HighlightRegionType.BUILT_IN);
- return super.visitClassDeclaration(node);
+ super.visitClassDeclaration(node);
}
@override
- Object visitClassTypeAlias(ClassTypeAlias node) {
+ void visitClassTypeAlias(ClassTypeAlias node) {
computer._addRegion_token(
node.abstractKeyword, HighlightRegionType.BUILT_IN);
- return super.visitClassTypeAlias(node);
+ super.visitClassTypeAlias(node);
}
@override
- Object visitConstructorDeclaration(ConstructorDeclaration node) {
+ void visitConstructorDeclaration(ConstructorDeclaration node) {
computer._addRegion_token(
node.externalKeyword, HighlightRegionType.BUILT_IN);
computer._addRegion_token(
node.factoryKeyword, HighlightRegionType.BUILT_IN);
- return super.visitConstructorDeclaration(node);
+ super.visitConstructorDeclaration(node);
}
@override
- Object visitContinueStatement(ContinueStatement node) {
+ void visitContinueStatement(ContinueStatement node) {
computer._addRegion_token(
node.continueKeyword, HighlightRegionType.KEYWORD);
- return super.visitContinueStatement(node);
+ super.visitContinueStatement(node);
}
@override
- Object visitDoStatement(DoStatement node) {
+ void visitDoStatement(DoStatement node) {
computer._addRegion_token(node.doKeyword, HighlightRegionType.KEYWORD);
computer._addRegion_token(node.whileKeyword, HighlightRegionType.KEYWORD);
- return super.visitDoStatement(node);
+ super.visitDoStatement(node);
}
@override
- Object visitDoubleLiteral(DoubleLiteral node) {
+ void visitDoubleLiteral(DoubleLiteral node) {
computer._addRegion_node(node, HighlightRegionType.LITERAL_DOUBLE);
- return super.visitDoubleLiteral(node);
+ super.visitDoubleLiteral(node);
}
@override
- Object visitEnumDeclaration(EnumDeclaration node) {
+ void visitEnumDeclaration(EnumDeclaration node) {
computer._addRegion_token(node.enumKeyword, HighlightRegionType.KEYWORD);
- return super.visitEnumDeclaration(node);
+ super.visitEnumDeclaration(node);
}
@override
- Object visitExportDirective(ExportDirective node) {
+ void visitExportDirective(ExportDirective node) {
computer._addRegion_node(node, HighlightRegionType.DIRECTIVE);
computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN);
- return super.visitExportDirective(node);
+ super.visitExportDirective(node);
}
@override
- Object visitExpressionFunctionBody(ExpressionFunctionBody node) {
+ void visitExpressionFunctionBody(ExpressionFunctionBody node) {
_addRegions_functionBody(node);
- return super.visitExpressionFunctionBody(node);
+ super.visitExpressionFunctionBody(node);
}
@override
- Object visitExtendsClause(ExtendsClause node) {
+ void visitExtendsClause(ExtendsClause node) {
computer._addRegion_token(node.extendsKeyword, HighlightRegionType.KEYWORD);
- return super.visitExtendsClause(node);
+ super.visitExtendsClause(node);
}
@override
- Object visitFieldDeclaration(FieldDeclaration node) {
+ void visitFieldDeclaration(FieldDeclaration node) {
computer._addRegion_token(node.staticKeyword, HighlightRegionType.BUILT_IN);
- return super.visitFieldDeclaration(node);
+ super.visitFieldDeclaration(node);
}
@override
- Object visitForEachStatement(ForEachStatement node) {
+ void visitForEachStatement(ForEachStatement node) {
computer._addRegion_token(node.awaitKeyword, HighlightRegionType.BUILT_IN);
computer._addRegion_token(node.forKeyword, HighlightRegionType.KEYWORD);
computer._addRegion_token(node.inKeyword, HighlightRegionType.KEYWORD);
- return super.visitForEachStatement(node);
+ super.visitForEachStatement(node);
}
@override
- Object visitForStatement(ForStatement node) {
+ void visitForStatement(ForStatement node) {
computer._addRegion_token(node.forKeyword, HighlightRegionType.KEYWORD);
- return super.visitForStatement(node);
+ super.visitForStatement(node);
}
@override
- Object visitFunctionDeclaration(FunctionDeclaration node) {
+ void visitFunctionDeclaration(FunctionDeclaration node) {
computer._addRegion_token(
node.externalKeyword, HighlightRegionType.BUILT_IN);
computer._addRegion_token(
node.propertyKeyword, HighlightRegionType.BUILT_IN);
- return super.visitFunctionDeclaration(node);
+ super.visitFunctionDeclaration(node);
}
@override
- Object visitFunctionTypeAlias(FunctionTypeAlias node) {
+ void visitFunctionTypeAlias(FunctionTypeAlias node) {
computer._addRegion_token(
node.typedefKeyword, HighlightRegionType.BUILT_IN);
- return super.visitFunctionTypeAlias(node);
+ super.visitFunctionTypeAlias(node);
}
@override
- Object visitGenericFunctionType(GenericFunctionType node) {
+ void visitGenericFunctionType(GenericFunctionType node) {
computer._addRegion_token(
node.functionKeyword, HighlightRegionType.KEYWORD);
- return super.visitGenericFunctionType(node);
+ super.visitGenericFunctionType(node);
}
@override
- Object visitGenericTypeAlias(GenericTypeAlias node) {
+ void visitGenericTypeAlias(GenericTypeAlias node) {
computer._addRegion_token(node.typedefKeyword, HighlightRegionType.KEYWORD);
- return super.visitGenericTypeAlias(node);
+ super.visitGenericTypeAlias(node);
}
@override
- Object visitHideCombinator(HideCombinator node) {
+ void visitHideCombinator(HideCombinator node) {
computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN);
- return super.visitHideCombinator(node);
+ super.visitHideCombinator(node);
}
@override
- Object visitIfStatement(IfStatement node) {
+ void visitIfStatement(IfStatement node) {
computer._addRegion_token(node.ifKeyword, HighlightRegionType.KEYWORD);
- return super.visitIfStatement(node);
+ super.visitIfStatement(node);
}
@override
- Object visitImplementsClause(ImplementsClause node) {
+ void visitImplementsClause(ImplementsClause node) {
computer._addRegion_token(
node.implementsKeyword, HighlightRegionType.BUILT_IN);
- return super.visitImplementsClause(node);
+ super.visitImplementsClause(node);
}
@override
- Object visitImportDirective(ImportDirective node) {
+ void visitImportDirective(ImportDirective node) {
computer._addRegion_node(node, HighlightRegionType.DIRECTIVE);
computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN);
computer._addRegion_token(
node.deferredKeyword, HighlightRegionType.BUILT_IN);
computer._addRegion_token(node.asKeyword, HighlightRegionType.BUILT_IN);
- return super.visitImportDirective(node);
+ super.visitImportDirective(node);
}
@override
- Object visitInstanceCreationExpression(InstanceCreationExpression node) {
+ void visitInstanceCreationExpression(InstanceCreationExpression node) {
if (node.keyword != null) {
computer._addRegion_token(node.keyword, HighlightRegionType.KEYWORD);
}
- return super.visitInstanceCreationExpression(node);
+ super.visitInstanceCreationExpression(node);
}
@override
- Object visitIntegerLiteral(IntegerLiteral node) {
+ void visitIntegerLiteral(IntegerLiteral node) {
computer._addRegion_node(node, HighlightRegionType.LITERAL_INTEGER);
- return super.visitIntegerLiteral(node);
+ super.visitIntegerLiteral(node);
}
@override
- Object visitIsExpression(IsExpression node) {
+ void visitIsExpression(IsExpression node) {
computer._addRegion_token(node.isOperator, HighlightRegionType.KEYWORD);
- return super.visitIsExpression(node);
+ super.visitIsExpression(node);
}
@override
- Object visitLibraryDirective(LibraryDirective node) {
+ void visitLibraryDirective(LibraryDirective node) {
computer._addRegion_node(node, HighlightRegionType.DIRECTIVE);
computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN);
- return super.visitLibraryDirective(node);
+ super.visitLibraryDirective(node);
}
@override
- Object visitLibraryIdentifier(LibraryIdentifier node) {
+ void visitLibraryIdentifier(LibraryIdentifier node) {
computer._addRegion_node(node, HighlightRegionType.LIBRARY_NAME);
- return null;
+ null;
}
@override
- Object visitListLiteral(ListLiteral node) {
+ void visitListLiteral(ListLiteral node) {
computer._addRegion_node(node, HighlightRegionType.LITERAL_LIST);
computer._addRegion_token(node.constKeyword, HighlightRegionType.KEYWORD);
- return super.visitListLiteral(node);
+ super.visitListLiteral(node);
}
@override
- Object visitMapLiteral(MapLiteral node) {
+ void visitMapLiteral(MapLiteral node) {
computer._addRegion_node(node, HighlightRegionType.LITERAL_MAP);
computer._addRegion_token(node.constKeyword, HighlightRegionType.KEYWORD);
- return super.visitMapLiteral(node);
+ super.visitMapLiteral(node);
}
@override
- Object visitMethodDeclaration(MethodDeclaration node) {
+ void visitMethodDeclaration(MethodDeclaration node) {
computer._addRegion_token(
node.externalKeyword, HighlightRegionType.BUILT_IN);
computer._addRegion_token(
@@ -694,117 +694,117 @@
node.operatorKeyword, HighlightRegionType.BUILT_IN);
computer._addRegion_token(
node.propertyKeyword, HighlightRegionType.BUILT_IN);
- return super.visitMethodDeclaration(node);
+ super.visitMethodDeclaration(node);
}
@override
- Object visitMixinDeclaration(MixinDeclaration node) {
+ void visitMixinDeclaration(MixinDeclaration node) {
computer._addRegion_token(node.mixinKeyword, HighlightRegionType.BUILT_IN);
- return super.visitMixinDeclaration(node);
+ super.visitMixinDeclaration(node);
}
@override
- Object visitNativeClause(NativeClause node) {
+ void visitNativeClause(NativeClause node) {
computer._addRegion_token(node.nativeKeyword, HighlightRegionType.BUILT_IN);
- return super.visitNativeClause(node);
+ super.visitNativeClause(node);
}
@override
- Object visitNativeFunctionBody(NativeFunctionBody node) {
+ void visitNativeFunctionBody(NativeFunctionBody node) {
computer._addRegion_token(node.nativeKeyword, HighlightRegionType.BUILT_IN);
- return super.visitNativeFunctionBody(node);
+ super.visitNativeFunctionBody(node);
}
@override
- Object visitOnClause(OnClause node) {
+ void visitOnClause(OnClause node) {
computer._addRegion_token(node.onKeyword, HighlightRegionType.BUILT_IN);
- return super.visitOnClause(node);
+ super.visitOnClause(node);
}
@override
- Object visitPartDirective(PartDirective node) {
+ void visitPartDirective(PartDirective node) {
computer._addRegion_node(node, HighlightRegionType.DIRECTIVE);
computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN);
- return super.visitPartDirective(node);
+ super.visitPartDirective(node);
}
@override
- Object visitPartOfDirective(PartOfDirective node) {
+ void visitPartOfDirective(PartOfDirective node) {
computer._addRegion_node(node, HighlightRegionType.DIRECTIVE);
computer._addRegion_tokenStart_tokenEnd(
node.partKeyword, node.ofKeyword, HighlightRegionType.BUILT_IN);
- return super.visitPartOfDirective(node);
+ super.visitPartOfDirective(node);
}
@override
- Object visitRethrowExpression(RethrowExpression node) {
+ void visitRethrowExpression(RethrowExpression node) {
computer._addRegion_token(node.rethrowKeyword, HighlightRegionType.KEYWORD);
- return super.visitRethrowExpression(node);
+ super.visitRethrowExpression(node);
}
@override
- Object visitReturnStatement(ReturnStatement node) {
+ void visitReturnStatement(ReturnStatement node) {
computer._addRegion_token(node.returnKeyword, HighlightRegionType.KEYWORD);
- return super.visitReturnStatement(node);
+ super.visitReturnStatement(node);
}
@override
- Object visitShowCombinator(ShowCombinator node) {
+ void visitShowCombinator(ShowCombinator node) {
computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN);
- return super.visitShowCombinator(node);
+ super.visitShowCombinator(node);
}
@override
- Object visitSimpleIdentifier(SimpleIdentifier node) {
+ void visitSimpleIdentifier(SimpleIdentifier node) {
computer._addIdentifierRegion(node);
- return super.visitSimpleIdentifier(node);
+ super.visitSimpleIdentifier(node);
}
@override
- Object visitSimpleStringLiteral(SimpleStringLiteral node) {
+ void visitSimpleStringLiteral(SimpleStringLiteral node) {
computer._addRegion_node(node, HighlightRegionType.LITERAL_STRING);
- return super.visitSimpleStringLiteral(node);
+ super.visitSimpleStringLiteral(node);
}
@override
- Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+ void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
computer._addRegion_token(node.superKeyword, HighlightRegionType.KEYWORD);
- return super.visitSuperConstructorInvocation(node);
+ super.visitSuperConstructorInvocation(node);
}
@override
- Object visitSwitchCase(SwitchCase node) {
+ void visitSwitchCase(SwitchCase node) {
computer._addRegion_token(node.keyword, HighlightRegionType.KEYWORD);
- return super.visitSwitchCase(node);
+ super.visitSwitchCase(node);
}
@override
- Object visitSwitchDefault(SwitchDefault node) {
+ void visitSwitchDefault(SwitchDefault node) {
computer._addRegion_token(node.keyword, HighlightRegionType.KEYWORD);
- return super.visitSwitchDefault(node);
+ super.visitSwitchDefault(node);
}
@override
- Object visitSwitchStatement(SwitchStatement node) {
+ void visitSwitchStatement(SwitchStatement node) {
computer._addRegion_token(node.switchKeyword, HighlightRegionType.KEYWORD);
- return super.visitSwitchStatement(node);
+ super.visitSwitchStatement(node);
}
@override
- Object visitThisExpression(ThisExpression node) {
+ void visitThisExpression(ThisExpression node) {
computer._addRegion_token(node.thisKeyword, HighlightRegionType.KEYWORD);
- return super.visitThisExpression(node);
+ super.visitThisExpression(node);
}
@override
- Object visitTryStatement(TryStatement node) {
+ void visitTryStatement(TryStatement node) {
computer._addRegion_token(node.tryKeyword, HighlightRegionType.KEYWORD);
computer._addRegion_token(node.finallyKeyword, HighlightRegionType.KEYWORD);
- return super.visitTryStatement(node);
+ super.visitTryStatement(node);
}
@override
- Object visitTypeName(TypeName node) {
+ void visitTypeName(TypeName node) {
DartType type = node.type;
if (type != null) {
if (type.isDynamic && node.name.name == "dynamic") {
@@ -812,35 +812,35 @@
return null;
}
}
- return super.visitTypeName(node);
+ super.visitTypeName(node);
}
@override
- Object visitVariableDeclarationList(VariableDeclarationList node) {
+ void visitVariableDeclarationList(VariableDeclarationList node) {
computer._addRegion_token(node.keyword, HighlightRegionType.KEYWORD);
- return super.visitVariableDeclarationList(node);
+ super.visitVariableDeclarationList(node);
}
@override
- Object visitWhileStatement(WhileStatement node) {
+ void visitWhileStatement(WhileStatement node) {
computer._addRegion_token(node.whileKeyword, HighlightRegionType.KEYWORD);
- return super.visitWhileStatement(node);
+ super.visitWhileStatement(node);
}
@override
- Object visitWithClause(WithClause node) {
+ void visitWithClause(WithClause node) {
computer._addRegion_token(node.withKeyword, HighlightRegionType.KEYWORD);
- return super.visitWithClause(node);
+ super.visitWithClause(node);
}
@override
- Object visitYieldStatement(YieldStatement node) {
+ void visitYieldStatement(YieldStatement node) {
Token keyword = node.yieldKeyword;
Token star = node.star;
int offset = keyword.offset;
int end = star != null ? star.end : keyword.end;
computer._addRegion(offset, end - offset, HighlightRegionType.BUILT_IN);
- return super.visitYieldStatement(node);
+ super.visitYieldStatement(node);
}
void _addRegions_functionBody(FunctionBody node) {
diff --git a/pkg/analysis_server/lib/src/computer/computer_outline.dart b/pkg/analysis_server/lib/src/computer/computer_outline.dart
index 490f5b5..24af9ba 100644
--- a/pkg/analysis_server/lib/src/computer/computer_outline.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_outline.dart
@@ -63,6 +63,9 @@
} else if (unitMember is FunctionTypeAlias) {
FunctionTypeAlias alias = unitMember;
unitContents.add(_newFunctionTypeAliasOutline(alias));
+ } else if (unitMember is GenericTypeAlias) {
+ GenericTypeAlias alias = unitMember;
+ unitContents.add(_newGenericTypeAliasOutline(alias));
}
}
Outline unitOutline = _newUnitOutline(unitContents);
@@ -224,6 +227,27 @@
return _nodeOutline(node, element);
}
+ Outline _newGenericTypeAliasOutline(GenericTypeAlias node) {
+ var functionType = node.functionType;
+ TypeAnnotation returnType = functionType.returnType;
+ SimpleIdentifier nameNode = node.name;
+ String name = nameNode.name;
+ FormalParameterList parameters = functionType.parameters;
+ String parametersStr = _safeToSource(parameters);
+ String returnTypeStr = _safeToSource(returnType);
+ Element element = new Element(
+ ElementKind.FUNCTION_TYPE_ALIAS,
+ name,
+ Element.makeFlags(
+ isPrivate: Identifier.isPrivateName(name),
+ isDeprecated: _isDeprecated(node)),
+ location: _getLocationNode(nameNode),
+ parameters: parametersStr,
+ returnType: returnTypeStr,
+ typeParameters: _getTypeParametersStr(node.typeParameters));
+ return _nodeOutline(node, element);
+ }
+
Outline _newMethodOutline(MethodDeclaration method) {
TypeAnnotation returnType = method.returnType;
SimpleIdentifier nameNode = method.name;
diff --git a/pkg/analysis_server/lib/src/computer/import_elements_computer.dart b/pkg/analysis_server/lib/src/computer/import_elements_computer.dart
index 292b748..7973eed 100644
--- a/pkg/analysis_server/lib/src/computer/import_elements_computer.dart
+++ b/pkg/analysis_server/lib/src/computer/import_elements_computer.dart
@@ -38,7 +38,7 @@
* The resolution result associated with the defining compilation unit of the
* library to which imports might be added.
*/
- final ResolveResult libraryResult;
+ final ResolvedUnitResult libraryResult;
/**
* Initialize a newly created builder.
diff --git a/pkg/analysis_server/lib/src/computer/imported_elements_computer.dart b/pkg/analysis_server/lib/src/computer/imported_elements_computer.dart
index 6150a2c..a587098 100644
--- a/pkg/analysis_server/lib/src/computer/imported_elements_computer.dart
+++ b/pkg/analysis_server/lib/src/computer/imported_elements_computer.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// 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.
@@ -50,7 +50,7 @@
* The visitor used by an [ImportedElementsComputer] to record the names of all
* imported elements.
*/
-class _Visitor extends UnifyingAstVisitor<Object> {
+class _Visitor extends UnifyingAstVisitor<void> {
/**
* The element representing the library containing the code being visited.
*/
@@ -79,15 +79,14 @@
_Visitor(this.containingLibrary, this.startOffset, this.endOffset);
@override
- Object visitNode(AstNode node) {
+ void visitNode(AstNode node) {
if (node.offset <= endOffset && node.end >= startOffset) {
node.visitChildren(this);
}
- return null;
}
@override
- Object visitSimpleIdentifier(SimpleIdentifier node) {
+ void visitSimpleIdentifier(SimpleIdentifier node) {
if (!node.inDeclarationContext() &&
node.offset <= endOffset &&
node.end >= startOffset &&
@@ -119,7 +118,6 @@
}
}
}
- return null;
}
static bool _isConstructorDeclarationReturnType(SimpleIdentifier node) {
diff --git a/pkg/analysis_server/lib/src/computer/new_notifications.dart b/pkg/analysis_server/lib/src/computer/new_notifications.dart
index 0e11991..06aabc7 100644
--- a/pkg/analysis_server/lib/src/computer/new_notifications.dart
+++ b/pkg/analysis_server/lib/src/computer/new_notifications.dart
@@ -8,15 +8,16 @@
import 'package:analysis_server/src/domains/analysis/occurrences.dart';
import 'package:analysis_server/src/domains/analysis/occurrences_dart.dart';
import 'package:analysis_server/src/protocol_server.dart' as protocol;
-import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
void new_sendDartNotificationNavigation(
- AnalysisServer analysisServer, AnalysisResult result) {
+ AnalysisServer analysisServer, ResolvedUnitResult result) {
var unit = result.unit;
if (unit != null) {
NavigationCollectorImpl collector = new NavigationCollectorImpl();
- computeDartNavigation(collector, unit, null, null);
+ computeDartNavigation(
+ analysisServer.resourceProvider, collector, unit, null, null);
collector.createRegions();
var params = new protocol.AnalysisNavigationParams(
result.path, collector.regions, collector.targets, collector.files);
@@ -25,7 +26,7 @@
}
void new_sendDartNotificationOccurrences(
- AnalysisServer analysisServer, AnalysisResult result) {
+ AnalysisServer analysisServer, ResolvedUnitResult result) {
var unit = result.unit;
if (unit != null) {
OccurrencesCollectorImpl collector = new OccurrencesCollectorImpl();
@@ -37,9 +38,12 @@
}
void new_sendErrorNotification(
- AnalysisServer analysisServer, AnalysisResult result) {
+ AnalysisServer analysisServer, ResolvedUnitResult result) {
var serverErrors = protocol.doAnalysisError_listFromEngine(
- result.driver.analysisOptions, result.lineInfo, result.errors);
+ result.session.analysisContext.analysisOptions,
+ result.lineInfo,
+ result.errors,
+ );
var params = new protocol.AnalysisErrorsParams(result.path, serverErrors);
analysisServer.sendNotification(params.toNotification());
}
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index 32c9e00..f38b989 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -899,8 +899,7 @@
convertedErrors ?? <protocol.AnalysisError>[]);
}
- void _checkForAnalysisOptionsUpdate(
- String path, ContextInfo info, ChangeType changeType) {
+ void _checkForAnalysisOptionsUpdate(String path, ContextInfo info) {
if (AnalysisEngine.isAnalysisOptionsFileName(path, pathContext)) {
AnalysisDriver driver = info.analysisDriver;
if (driver == null) {
@@ -909,39 +908,29 @@
// yet created a driver for that context.
return;
}
- String contextRoot = info.folder.path;
- ContextBuilder builder =
- callbacks.createContextBuilder(info.folder, defaultContextOptions);
- AnalysisOptions options = builder.getAnalysisOptions(contextRoot,
- contextRoot: driver.contextRoot);
- SourceFactory factory = builder.createSourceFactory(contextRoot, options);
- driver.configure(analysisOptions: options, sourceFactory: factory);
// TODO(brianwilkerson) Set exclusion patterns.
_analyzeAnalysisOptionsFile(driver, path);
+ _updateAnalysisOptions(info);
}
}
- void _checkForPackagespecUpdate(
- String path, ContextInfo info, Folder folder) {
+ void _checkForPackagespecUpdate(String path, ContextInfo info) {
// Check to see if this is the .packages file for this context and if so,
// update the context's source factory.
if (pathContext.basename(path) == PACKAGE_SPEC_NAME) {
- String contextRoot = info.folder.path;
- ContextBuilder builder =
- callbacks.createContextBuilder(info.folder, defaultContextOptions);
AnalysisDriver driver = info.analysisDriver;
- if (driver != null) {
- AnalysisOptions options = builder.getAnalysisOptions(contextRoot,
- contextRoot: driver.contextRoot);
- SourceFactory factory =
- builder.createSourceFactory(contextRoot, options);
- driver.configure(analysisOptions: options, sourceFactory: factory);
+ if (driver == null) {
+ // I suspect that this happens as a result of a race condition: server
+ // has determined that the file (at [path]) is in a context, but hasn't
+ // yet created a driver for that context.
+ return;
}
+
+ _updateAnalysisOptions(info);
}
}
- void _checkForPubspecUpdate(
- String path, ContextInfo info, ChangeType changeType) {
+ void _checkForPubspecUpdate(String path, ContextInfo info) {
if (_isPubspec(path)) {
AnalysisDriver driver = info.analysisDriver;
if (driver == null) {
@@ -951,6 +940,7 @@
return;
}
_analyzePubspecFile(driver, path);
+ _updateAnalysisOptions(info);
}
}
@@ -1424,9 +1414,9 @@
}
}
}
- _checkForPackagespecUpdate(path, info, info.folder);
- _checkForAnalysisOptionsUpdate(path, info, type);
- _checkForPubspecUpdate(path, info, type);
+ _checkForPackagespecUpdate(path, info);
+ _checkForAnalysisOptionsUpdate(path, info);
+ _checkForPubspecUpdate(path, info);
}
/**
@@ -1555,6 +1545,17 @@
return false;
}
+ void _updateAnalysisOptions(ContextInfo info) {
+ AnalysisDriver driver = info.analysisDriver;
+ String contextRoot = info.folder.path;
+ ContextBuilder builder =
+ callbacks.createContextBuilder(info.folder, defaultContextOptions);
+ AnalysisOptions options = builder.getAnalysisOptions(contextRoot,
+ contextRoot: driver.contextRoot);
+ SourceFactory factory = builder.createSourceFactory(contextRoot, options);
+ driver.configure(analysisOptions: options, sourceFactory: factory);
+ }
+
void _updateContextPackageUriResolver(Folder contextFolder) {
ContextInfo info = getContextInfoFor(contextFolder);
AnalysisDriver driver = info.analysisDriver;
diff --git a/pkg/analysis_server/lib/src/domain_analysis.dart b/pkg/analysis_server/lib/src/domain_analysis.dart
index a3e3257..d9d7164 100644
--- a/pkg/analysis_server/lib/src/domain_analysis.dart
+++ b/pkg/analysis_server/lib/src/domain_analysis.dart
@@ -17,12 +17,12 @@
import 'package:analysis_server/src/plugin/result_merger.dart';
import 'package:analysis_server/src/protocol/protocol_internal.dart';
import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/error/error.dart' as engine;
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/generated/engine.dart' as engine;
-import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analyzer_plugin/protocol/protocol_constants.dart' as plugin;
@@ -47,24 +47,21 @@
* Implement the `analysis.getErrors` request.
*/
Future<void> getErrors(Request request) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
String file = new AnalysisGetErrorsParams.fromRequest(request).file;
+ ResolvedUnitResult result = await server.getResolvedUnit(file);
- void send(engine.AnalysisOptions analysisOptions, LineInfo lineInfo,
- List<engine.AnalysisError> errors) {
- if (lineInfo == null) {
- server.sendResponse(new Response.getErrorsInvalidFile(request));
- } else {
- List<AnalysisError> protocolErrors =
- doAnalysisError_listFromEngine(analysisOptions, lineInfo, errors);
- server.sendResponse(
- new AnalysisGetErrorsResult(protocolErrors).toResponse(request.id));
- }
+ if (result?.state != ResultState.VALID) {
+ server.sendResponse(new Response.getErrorsInvalidFile(request));
+ return;
}
- AnalysisResult result = await server.getAnalysisResult(file);
- send(result?.driver?.analysisOptions, result?.lineInfo, result?.errors);
+ List<AnalysisError> protocolErrors = doAnalysisError_listFromEngine(
+ result.session.analysisContext.analysisOptions,
+ result.lineInfo,
+ result.errors,
+ );
+ server.sendResponse(
+ new AnalysisGetErrorsResult(protocolErrors).toResponse(request.id));
}
/**
@@ -76,7 +73,7 @@
var params = new AnalysisGetHoverParams.fromRequest(request);
// Prepare the resolved units.
- AnalysisResult result = await server.getAnalysisResult(params.file);
+ ResolvedUnitResult result = await server.getResolvedUnit(params.file);
CompilationUnit unit = result?.unit;
// Prepare the hovers.
@@ -105,9 +102,10 @@
//
// Prepare the resolved unit.
//
- AnalysisResult result = await server.getAnalysisResult(params.file);
- if (result == null) {
+ ResolvedUnitResult result = await server.getResolvedUnit(params.file);
+ if (result?.state != ResultState.VALID) {
server.sendResponse(new Response.getImportedElementsInvalidFile(request));
+ return;
}
List<ImportedElements> elements;
@@ -179,11 +177,12 @@
// Compute navigation data generated by server.
//
List<AnalysisNavigationParams> allResults = <AnalysisNavigationParams>[];
- AnalysisResult result = await server.getAnalysisResult(file);
- CompilationUnit unit = result?.unit;
- if (unit != null && result.exists) {
+ ResolvedUnitResult result = await server.getResolvedUnit(file);
+ if (result?.state == ResultState.VALID) {
+ CompilationUnit unit = result?.unit;
NavigationCollectorImpl collector = new NavigationCollectorImpl();
- computeDartNavigation(collector, unit, offset, length);
+ computeDartNavigation(
+ server.resourceProvider, collector, unit, offset, length);
collector.createRegions();
allResults.add(new AnalysisNavigationParams(
file, collector.regions, collector.targets, collector.files));
@@ -246,14 +245,15 @@
var params = new AnalysisGetSignatureParams.fromRequest(request);
// Prepare the resolved units.
- AnalysisResult result = await server.getAnalysisResult(params.file);
- CompilationUnit unit = result?.unit;
- if (unit == null) {
+ ResolvedUnitResult result = await server.getResolvedUnit(params.file);
+
+ if (result?.state != ResultState.VALID) {
server.sendResponse(new Response.getSignatureInvalidFile(request));
return;
}
// Ensure the offset provided is a valid location in the file.
+ final unit = result.unit;
final computer = new DartUnitSignatureComputer(unit, params.offset);
if (!computer.offsetIsValid) {
server.sendResponse(new Response.getSignatureInvalidOffset(request));
diff --git a/pkg/analysis_server/lib/src/domain_completion.dart b/pkg/analysis_server/lib/src/domain_completion.dart
index 10597e3..ce73d98 100644
--- a/pkg/analysis_server/lib/src/domain_completion.dart
+++ b/pkg/analysis_server/lib/src/domain_completion.dart
@@ -15,6 +15,7 @@
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:analyzer/dart/analysis/results.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
import 'package:analyzer_plugin/protocol/protocol_common.dart';
@@ -172,9 +173,9 @@
String filePath = params.file;
int offset = params.offset;
- AnalysisResult result = await server.getAnalysisResult(filePath);
+ ResolvedUnitResult result = await server.getResolvedUnit(filePath);
- if (result != null && result.exists) {
+ if (result?.state == ResultState.VALID) {
if (offset < 0 || offset > result.content.length) {
server.sendResponse(new Response.invalidParameter(
request,
diff --git a/pkg/analysis_server/lib/src/domain_kythe.dart b/pkg/analysis_server/lib/src/domain_kythe.dart
index c4fceb6..2bfc8c0 100644
--- a/pkg/analysis_server/lib/src/domain_kythe.dart
+++ b/pkg/analysis_server/lib/src/domain_kythe.dart
@@ -13,7 +13,7 @@
import 'package:analysis_server/src/plugin/plugin_manager.dart';
import 'package:analysis_server/src/plugin/result_merger.dart';
import 'package:analysis_server/src/services/kythe/kythe_visitors.dart';
-import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/element/inheritance_manager2.dart';
import 'package:analyzer/src/generated/type_system.dart';
@@ -56,10 +56,9 @@
//
List<KytheGetKytheEntriesResult> allResults =
<KytheGetKytheEntriesResult>[];
- AnalysisResult result = await server.getAnalysisResult(file);
- CompilationUnit unit = result?.unit;
- TypeSystem typeSystem = result.libraryElement.context.typeSystem;
- if (unit != null && result.exists) {
+ ResolvedUnitResult result = await server.getResolvedUnit(file);
+ if (result?.state == ResultState.VALID) {
+ TypeSystem typeSystem = await result.libraryElement.session.typeSystem;
List<KytheEntry> entries = <KytheEntry>[];
// TODO(brianwilkerson) Figure out how to get the list of files.
List<String> files = <String>[];
diff --git a/pkg/analysis_server/lib/src/domains/analysis/navigation_dart.dart b/pkg/analysis_server/lib/src/domains/analysis/navigation_dart.dart
index 46a455e..74bbf87 100644
--- a/pkg/analysis_server/lib/src/domains/analysis/navigation_dart.dart
+++ b/pkg/analysis_server/lib/src/domains/analysis/navigation_dart.dart
@@ -8,17 +8,22 @@
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/utilities/navigation/navigation.dart';
-NavigationCollector computeDartNavigation(NavigationCollector collector,
- CompilationUnit unit, int offset, int length) {
+NavigationCollector computeDartNavigation(
+ ResourceProvider resourceProvider,
+ NavigationCollector collector,
+ CompilationUnit unit,
+ int offset,
+ int length) {
_DartNavigationCollector dartCollector =
new _DartNavigationCollector(collector);
_DartNavigationComputerVisitor visitor =
- new _DartNavigationComputerVisitor(dartCollector);
+ new _DartNavigationComputerVisitor(resourceProvider, dartCollector);
if (offset == null || length == null) {
unit.accept(visitor);
} else {
@@ -87,9 +92,10 @@
}
class _DartNavigationComputerVisitor extends RecursiveAstVisitor {
+ final ResourceProvider resourceProvider;
final _DartNavigationCollector computer;
- _DartNavigationComputerVisitor(this.computer);
+ _DartNavigationComputerVisitor(this.resourceProvider, this.computer);
@override
visitAnnotation(Annotation node) {
@@ -352,7 +358,7 @@
void _addUriDirectiveRegion(UriBasedDirective node, Element element) {
if (element != null) {
Source source = element.source;
- if (element.context.exists(source)) {
+ if (resourceProvider.getResource(source.fullName).exists) {
computer._addRegionForNode(node.uri, element);
}
}
diff --git a/pkg/analysis_server/lib/src/domains/execution/completion.dart b/pkg/analysis_server/lib/src/domains/execution/completion.dart
index c3a218e..a8a55f1 100644
--- a/pkg/analysis_server/lib/src/domains/execution/completion.dart
+++ b/pkg/analysis_server/lib/src/domains/execution/completion.dart
@@ -14,6 +14,7 @@
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:analyzer/dart/analysis/results.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
@@ -81,7 +82,7 @@
// Update the context file content to include the code being completed.
// Then resolve it, and restore the file to its initial state.
- AnalysisResult targetResult;
+ ResolvedUnitResult targetResult;
String contentFileOverlay = fileContentOverlay[contextFile];
try {
fileContentOverlay[contextFile] = targetCode;
diff --git a/pkg/analysis_server/lib/src/edit/edit_dartfix.dart b/pkg/analysis_server/lib/src/edit/edit_dartfix.dart
index 2dc141b..72b62a6 100644
--- a/pkg/analysis_server/lib/src/edit/edit_dartfix.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_dartfix.dart
@@ -2,7 +2,6 @@
// 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/plugin/edit/assist/assist_dart.dart';
import 'package:analysis_server/plugin/edit/fix/fix_core.dart';
import 'package:analysis_server/protocol/protocol.dart';
import 'package:analysis_server/protocol/protocol_generated.dart';
@@ -11,13 +10,15 @@
import 'package:analysis_server/src/edit/fix/prefer_mixin_fix.dart';
import 'package:analysis_server/src/services/correction/fix.dart';
import 'package:analysis_server/src/services/correction/fix_internal.dart';
-import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/error/listener.dart';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/dart/analysis/ast_provider_driver.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
+import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/lint/linter.dart';
import 'package:analyzer/src/lint/linter_visitor.dart';
@@ -124,32 +125,52 @@
}
continue;
}
- AnalysisResult result = await server.getAnalysisResult(res.path);
- CompilationUnit unit = result?.unit;
- if (unit != null) {
- if (!hasErrors) {
- for (AnalysisError error in result.errors) {
- if (!(await fixError(result, error))) {
- if (error.errorCode.type == ErrorType.SYNTACTIC_ERROR) {
- hasErrors = true;
+
+ const maxAttempts = 3;
+ int attempt = 0;
+ while (attempt < maxAttempts) {
+ ResolvedUnitResult result = await server.getResolvedUnit(res.path);
+
+ // TODO(danrubel): Investigate why InconsistentAnalysisException occurs
+ // and whether this is an appropriate way to handle the situation
+ ++attempt;
+ try {
+ CompilationUnit unit = result?.unit;
+ if (unit != null) {
+ if (!hasErrors) {
+ for (AnalysisError error in result.errors) {
+ if (!(await fixError(result, error))) {
+ if (error.errorCode.type == ErrorType.SYNTACTIC_ERROR) {
+ hasErrors = true;
+ }
+ }
}
}
+ Source source = result.unit.declaredElement.source;
+ for (Linter linter in linters) {
+ if (linter != null) {
+ linter.reporter.source = source;
+ }
+ }
+ var lintVisitors = lintVisitorsBySession[result.session] ??=
+ await _setupLintVisitors(result, linters);
+ if (lintVisitors.astVisitor != null) {
+ unit.accept(lintVisitors.astVisitor);
+ }
+ unit.accept(lintVisitors.linterVisitor);
+ for (LinterFix fix in fixes) {
+ await fix.applyLocalFixes(result);
+ }
}
- }
- Source source = result.sourceFactory.forUri2(result.uri);
- for (Linter linter in linters) {
- if (linter != null) {
- linter.reporter.source = source;
+ break;
+ } on InconsistentAnalysisException catch (_) {
+ if (attempt == maxAttempts) {
+ // TODO(danrubel): Consider improving the edit.dartfix protocol
+ // to gracefully report inconsistent results for a particular
+ // file rather than aborting the entire operation.
+ rethrow;
}
- }
- var lintVisitors = lintVisitorsBySession[result.session] ??=
- await _setupLintVisitors(result, linters);
- if (lintVisitors.astVisitor != null) {
- unit.accept(lintVisitors.astVisitor);
- }
- unit.accept(lintVisitors.linterVisitor);
- for (LinterFix fix in fixes) {
- await fix.applyLocalFixes(result);
+ // try again
}
}
}
@@ -177,7 +198,7 @@
.toResponse(request.id);
}
- Future<bool> fixError(AnalysisResult result, AnalysisError error) async {
+ Future<bool> fixError(ResolvedUnitResult result, AnalysisError error) async {
if (error.errorCode ==
StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR) {
// TODO(danrubel): Rather than comparing the error codes individually,
@@ -190,11 +211,7 @@
return false;
}
- final dartContext = new DartFixContextImpl(
- new FixContextImpl(
- server.resourceProvider, result.driver, error, result.errors),
- new AstProviderForDriver(result.driver),
- result.unit);
+ final dartContext = new DartFixContextImpl(result, error);
final processor = new FixProcessor(dartContext);
Fix fix = await processor.computeFix();
final location = locationFor(result, error.offset, error.length);
@@ -226,7 +243,7 @@
return false;
}
- Location locationFor(AnalysisResult result, int offset, int length) {
+ Location locationFor(ResolvedUnitResult result, int offset, int length) {
final locInfo = result.unit.lineInfo.getLocation(offset);
final location = new Location(
result.path, offset, length, locInfo.lineNumber, locInfo.columnNumber);
@@ -234,7 +251,7 @@
}
Future<_LintVisitors> _setupLintVisitors(
- AnalysisResult result, List<Linter> linters) async {
+ ResolvedUnitResult result, List<Linter> linters) async {
final visitors = <AstVisitor>[];
final registry = new NodeLintRegistry(false);
// TODO(paulberry): use an API that provides this information more readily
@@ -246,7 +263,7 @@
if (identical(cu, unitElement)) {
allUnits.add(currentUnit);
} else {
- var result = await session.getResolvedAst(cu.source.fullName);
+ var result = await session.getResolvedUnit(cu.source.fullName);
allUnits.add(LinterContextUnit(result.content, result.unit));
}
}
@@ -258,11 +275,8 @@
if (visitor != null) {
visitors.add(visitor);
}
- if (linter is NodeLintRuleWithContext) {
- (linter as NodeLintRuleWithContext)
- .registerNodeProcessors(registry, context);
- } else if (linter is NodeLintRule) {
- (linter as NodeLintRule).registerNodeProcessors(registry);
+ if (linter is NodeLintRule) {
+ (linter as NodeLintRule).registerNodeProcessors(registry, context);
}
}
}
@@ -276,29 +290,6 @@
}
}
-class EditDartFixAssistContext implements DartAssistContext {
- @override
- final AnalysisDriver analysisDriver;
-
- @override
- final int selectionLength;
-
- @override
- final int selectionOffset;
-
- @override
- final Source source;
-
- @override
- final CompilationUnit unit;
-
- EditDartFixAssistContext(
- EditDartFix dartFix, this.source, this.unit, AstNode node)
- : analysisDriver = dartFix.server.getAnalysisDriver(source.fullName),
- selectionOffset = node.offset,
- selectionLength = 0;
-}
-
abstract class LinterFix implements ErrorReporter {
final EditDartFix dartFix;
@@ -308,7 +299,7 @@
LinterFix(this.dartFix);
/// Apply fixes for the current compilation unit.
- Future<void> applyLocalFixes(AnalysisResult result);
+ Future<void> applyLocalFixes(ResolvedUnitResult result);
/// Apply any fixes remaining after analysis is complete.
Future<void> applyRemainingFixes();
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index f7a28e7..8f3a144 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -5,9 +5,7 @@
import 'dart:async';
import 'package:analysis_server/plugin/edit/assist/assist_core.dart';
-import 'package:analysis_server/plugin/edit/assist/assist_dart.dart';
import 'package:analysis_server/plugin/edit/fix/fix_core.dart';
-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';
@@ -19,22 +17,21 @@
import 'package:analysis_server/src/protocol_server.dart' hide Element;
import 'package:analysis_server/src/services/completion/postfix/postfix_completion.dart';
import 'package:analysis_server/src/services/completion/statement/statement_completion.dart';
+import 'package:analysis_server/src/services/correction/assist.dart';
import 'package:analysis_server/src/services/correction/assist_internal.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
import 'package:analysis_server/src/services/correction/fix_internal.dart';
import 'package:analysis_server/src/services/correction/organize_directives.dart';
import 'package:analysis_server/src/services/correction/sort_members.dart';
import 'package:analysis_server/src/services/correction/status.dart';
import 'package:analysis_server/src/services/refactoring/refactoring.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/standard_resolution_map.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/error/error.dart' as engine;
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/dart/analysis/ast_provider_driver.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
-import 'package:analyzer/src/dart/element/ast_provider.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart' as engine;
import 'package:analyzer/src/error/codes.dart' as engine;
import 'package:analyzer/src/generated/engine.dart' as engine;
@@ -175,7 +172,7 @@
Map<PluginInfo, Future<plugin.Response>> pluginFutures;
plugin.EditGetAssistsParams requestParams =
new plugin.EditGetAssistsParams(file, offset, length);
- AnalysisDriver driver = server.getAnalysisDriver(file);
+ var driver = server.getAnalysisDriver(file);
if (driver == null) {
pluginFutures = <PluginInfo, Future<plugin.Response>>{};
} else {
@@ -185,15 +182,11 @@
//
// Compute fixes associated with server-generated errors.
//
- AnalysisResult result = await server.getAnalysisResult(file);
+ ResolvedUnitResult result = await server.getResolvedUnit(file);
if (result != null) {
- CompilationUnit unit = result.unit;
- CompilationUnitElement compilationUnitElement =
- resolutionMap.elementDeclaredByCompilationUnit(unit);
- DartAssistContext dartAssistContext = new _DartAssistContextForValues(
- compilationUnitElement.source, offset, length, driver, unit);
+ var context = new DartAssistContextImpl(result, offset, length);
try {
- AssistProcessor processor = new AssistProcessor(dartAssistContext);
+ AssistProcessor processor = new AssistProcessor(context);
List<Assist> assists = await processor.compute();
assists.sort(Assist.SORT_BY_RELEVANCE);
for (Assist assist in assists) {
@@ -236,7 +229,7 @@
Map<PluginInfo, Future<plugin.Response>> pluginFutures;
plugin.EditGetFixesParams requestParams =
new plugin.EditGetFixesParams(file, offset);
- AnalysisDriver driver = server.getAnalysisDriver(file);
+ var driver = server.getAnalysisDriver(file);
if (driver == null) {
pluginFutures = <PluginInfo, Future<plugin.Response>>{};
} else {
@@ -249,7 +242,7 @@
List<AnalysisErrorFixes> errorFixesList = null;
while (errorFixesList == null) {
try {
- errorFixesList = await _computeServerErrorFixes(driver, file, offset);
+ errorFixesList = await _computeServerErrorFixes(file, offset);
} on InconsistentAnalysisException {
// Loop around to try again to compute the fixes.
}
@@ -281,26 +274,17 @@
var params = new EditGetPostfixCompletionParams.fromRequest(request);
SourceChange change;
- AnalysisResult result = await server.getAnalysisResult(params.file);
+ ResolvedUnitResult result = await server.getResolvedUnit(params.file);
if (result != null) {
- CompilationUnit unit = result.unit;
- CompilationUnitElement unitElement =
- resolutionMap.elementDeclaredByCompilationUnit(unit);
- if (unitElement.context != null) {
- PostfixCompletionContext context = new PostfixCompletionContext(
- params.file,
- result.lineInfo,
- params.offset,
- params.key,
- result.driver,
- unit,
- unitElement,
- result.errors);
- PostfixCompletionProcessor processor =
- new PostfixCompletionProcessor(context);
- PostfixCompletion completion = await processor.compute();
- change = completion?.change;
- }
+ PostfixCompletionContext context = new PostfixCompletionContext(
+ result,
+ params.offset,
+ params.key,
+ );
+ PostfixCompletionProcessor processor =
+ new PostfixCompletionProcessor(context);
+ PostfixCompletion completion = await processor.compute();
+ change = completion?.change;
}
if (change == null) {
change = new SourceChange("", edits: []);
@@ -317,24 +301,13 @@
var params = new EditGetStatementCompletionParams.fromRequest(request);
SourceChange change;
- AnalysisResult result = await server.getAnalysisResult(params.file);
+ ResolvedUnitResult result = await server.getResolvedUnit(params.file);
if (result != null) {
- CompilationUnit unit = result.unit;
- CompilationUnitElement unitElement =
- resolutionMap.elementDeclaredByCompilationUnit(unit);
- if (unitElement.context != null) {
- StatementCompletionContext context = new StatementCompletionContext(
- params.file,
- result.lineInfo,
- params.offset,
- unit,
- unitElement,
- result.errors);
- StatementCompletionProcessor processor =
- new StatementCompletionProcessor(context);
- StatementCompletion completion = await processor.compute();
- change = completion.change;
- }
+ var context = new StatementCompletionContext(result, params.offset);
+ StatementCompletionProcessor processor =
+ new StatementCompletionProcessor(context);
+ StatementCompletion completion = await processor.compute();
+ change = completion.change;
}
if (change == null) {
change = new SourceChange("", edits: []);
@@ -404,7 +377,7 @@
//
// Prepare the resolved unit.
//
- AnalysisResult result = await server.getAnalysisResult(params.file);
+ ResolvedUnitResult result = await server.getResolvedUnit(params.file);
if (result == null) {
server.sendResponse(new Response.importElementsInvalidFile(request));
}
@@ -413,7 +386,7 @@
if (libraryUnit != result.unit.declaredElement) {
// The file in the request is a part of a library. We need to pass the
// defining compilation unit to the computer, not the part.
- result = await server.getAnalysisResult(libraryUnit.source.fullName);
+ result = await server.getResolvedUnit(libraryUnit.source.fullName);
if (result == null) {
server.sendResponse(new Response.importElementsInvalidFile(request));
}
@@ -439,25 +412,15 @@
var params = new EditGetPostfixCompletionParams.fromRequest(request);
bool value = false;
- AnalysisResult result = await server.getAnalysisResult(params.file);
+ ResolvedUnitResult result = await server.getResolvedUnit(params.file);
if (result != null) {
- CompilationUnit unit = result.unit;
- CompilationUnitElement unitElement =
- resolutionMap.elementDeclaredByCompilationUnit(unit);
- if (unitElement.context != null) {
- PostfixCompletionContext context = new PostfixCompletionContext(
- params.file,
- result.lineInfo,
- params.offset,
- params.key,
- result.driver,
- unit,
- unitElement,
- result.errors);
- PostfixCompletionProcessor processor =
- new PostfixCompletionProcessor(context);
- value = await processor.isApplicable();
- }
+ var context = new PostfixCompletionContext(
+ result,
+ params.offset,
+ params.key,
+ );
+ var processor = new PostfixCompletionProcessor(context);
+ value = await processor.isApplicable();
}
Response response = new EditIsPostfixCompletionApplicableResult(value)
@@ -491,7 +454,7 @@
return;
}
// Prepare the file information.
- AnalysisResult result = await server.getAnalysisResult(file);
+ ResolvedUnitResult result = await server.getResolvedUnit(file);
if (result == null) {
server.sendResponse(new Response.fileNotAnalyzed(request, file));
return;
@@ -526,8 +489,8 @@
return;
}
// Prepare the file information.
- AnalysisDriver driver = server.getAnalysisDriver(file);
- ParseResult result = await driver?.parseFile(file);
+ var driver = server.getAnalysisDriver(file);
+ ParsedUnitResult result = await driver?.parseFile(file);
if (result == null) {
server.sendResponse(new Response.fileNotAnalyzed(request, file));
return;
@@ -555,29 +518,20 @@
* Compute and return the fixes associated with server-generated errors.
*/
Future<List<AnalysisErrorFixes>> _computeServerErrorFixes(
- AnalysisDriver driver, String file, int offset) async {
+ String file, int offset) async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
List<AnalysisErrorFixes> errorFixesList = <AnalysisErrorFixes>[];
- AnalysisResult result = await server.getAnalysisResult(file);
+ var result = await server.getResolvedUnit(file);
if (result != null) {
- CompilationUnit unit = result.unit;
LineInfo lineInfo = result.lineInfo;
int requestLine = lineInfo.getLocation(offset).lineNumber;
- List<engine.AnalysisError> errorsCopy = new List.from(result.errors);
for (engine.AnalysisError error in result.errors) {
int errorLine = lineInfo.getLocation(error.offset).lineNumber;
if (errorLine == requestLine) {
- AstProvider astProvider = new AstProviderForDriver(driver);
- DartFixContext context = new _DartFixContextImpl(
- server.resourceProvider,
- result.driver,
- astProvider,
- unit,
- error,
- errorsCopy);
+ var context = new DartFixContextImpl(result, error);
List<Fix> fixes =
- await new DefaultFixContributor().internalComputeFixes(context);
+ await new DartFixContributor().computeFixes(context);
if (fixes.isNotEmpty) {
fixes.sort(Fix.SORT_BY_RELEVANCE);
AnalysisError serverError =
@@ -611,22 +565,22 @@
List<RefactoringKind> kinds = <RefactoringKind>[];
// Check nodes.
{
- var analysisResult = await server.getAnalysisResult(file);
- if (analysisResult != null) {
+ var resolvedUnit = await server.getResolvedUnit(file);
+ if (resolvedUnit != null) {
// Try EXTRACT_LOCAL_VARIABLE.
- if (new ExtractLocalRefactoring(analysisResult, offset, length)
+ if (new ExtractLocalRefactoring(resolvedUnit, offset, length)
.isAvailable()) {
kinds.add(RefactoringKind.EXTRACT_LOCAL_VARIABLE);
}
// Try EXTRACT_METHOD.
- if (new ExtractMethodRefactoring(searchEngine,
- server.getAstProvider(file), analysisResult, offset, length)
+ if (new ExtractMethodRefactoring(
+ searchEngine, resolvedUnit, offset, length)
.isAvailable()) {
kinds.add(RefactoringKind.EXTRACT_METHOD);
}
// Try EXTRACT_WIDGETS.
if (new ExtractWidgetRefactoring(
- searchEngine, analysisResult, offset, length)
+ searchEngine, resolvedUnit, offset, length)
.isAvailable()) {
kinds.add(RefactoringKind.EXTRACT_WIDGET);
}
@@ -634,23 +588,28 @@
}
// check elements
{
- Element element = await server.getElementAtOffset(file, offset);
- if (element != null) {
- // try CONVERT_METHOD_TO_GETTER
- if (element is ExecutableElement) {
- Refactoring refactoring = new ConvertMethodToGetterRefactoring(
- searchEngine, server.getAstProvider(file), element);
- RefactoringStatus status = await refactoring.checkInitialConditions();
- if (!status.hasFatalError) {
- kinds.add(RefactoringKind.CONVERT_METHOD_TO_GETTER);
+ var resolvedUnit = await server.getResolvedUnit(file);
+ if (resolvedUnit != null) {
+ var node = new NodeLocator(offset).searchWithin(resolvedUnit.unit);
+ var element = server.getElementOfNode(node);
+ if (element != null) {
+ // try CONVERT_METHOD_TO_GETTER
+ if (element is ExecutableElement) {
+ Refactoring refactoring = new ConvertMethodToGetterRefactoring(
+ searchEngine, resolvedUnit.session, element);
+ RefactoringStatus status =
+ await refactoring.checkInitialConditions();
+ if (!status.hasFatalError) {
+ kinds.add(RefactoringKind.CONVERT_METHOD_TO_GETTER);
+ }
}
- }
- // try RENAME
- {
- RenameRefactoring renameRefactoring = new RenameRefactoring(
- refactoringWorkspace, server.getAstProvider(file), element);
- if (renameRefactoring != null) {
- kinds.add(RefactoringKind.RENAME);
+ // try RENAME
+ {
+ RenameRefactoring renameRefactoring = new RenameRefactoring(
+ refactoringWorkspace, resolvedUnit.session, element);
+ if (renameRefactoring != null) {
+ kinds.add(RefactoringKind.RENAME);
+ }
}
}
}
@@ -689,60 +648,6 @@
}
/**
- * Implementation of [DartAssistContext] that is based on the values passed
- * in the constructor, as opposite to be partially based on [AssistContext].
- */
-class _DartAssistContextForValues implements DartAssistContext {
- @override
- final Source source;
-
- @override
- final int selectionOffset;
-
- @override
- final int selectionLength;
-
- @override
- final AnalysisDriver analysisDriver;
-
- @override
- final CompilationUnit unit;
-
- _DartAssistContextForValues(this.source, this.selectionOffset,
- this.selectionLength, this.analysisDriver, this.unit);
-}
-
-/**
- * And implementation of [DartFixContext].
- */
-class _DartFixContextImpl implements DartFixContext {
- @override
- final ResourceProvider resourceProvider;
-
- @override
- final AnalysisDriver analysisDriver;
-
- @override
- final AstProvider astProvider;
-
- @override
- final CompilationUnit unit;
-
- @override
- final engine.AnalysisError error;
-
- @override
- final List<engine.AnalysisError> errors;
-
- _DartFixContextImpl(this.resourceProvider, this.analysisDriver,
- this.astProvider, this.unit, this.error, this.errors);
-
- @override
- GetTopLevelDeclarations get getTopLevelDeclarations =>
- analysisDriver.getTopLevelNameDeclarations;
-}
-
-/**
* An object managing a single [Refactoring] instance.
*
* The instance is identified by its kind, file, offset and length.
@@ -940,28 +845,35 @@
}
// create a new Refactoring instance
if (kind == RefactoringKind.CONVERT_GETTER_TO_METHOD) {
- Element element = await server.getElementAtOffset(file, offset);
- if (element != null) {
- if (element is ExecutableElement) {
- refactoring = new ConvertGetterToMethodRefactoring(
- searchEngine, server.getAstProvider(file), element);
+ var resolvedUnit = await server.getResolvedUnit(file);
+ if (resolvedUnit != null) {
+ var node = new NodeLocator(offset).searchWithin(resolvedUnit.unit);
+ var element = server.getElementOfNode(node);
+ if (element != null) {
+ if (element is ExecutableElement) {
+ refactoring = new ConvertGetterToMethodRefactoring(
+ searchEngine, resolvedUnit.session, element);
+ }
}
}
}
if (kind == RefactoringKind.CONVERT_METHOD_TO_GETTER) {
- Element element = await server.getElementAtOffset(file, offset);
- if (element != null) {
- if (element is ExecutableElement) {
- refactoring = new ConvertMethodToGetterRefactoring(
- searchEngine, server.getAstProvider(file), element);
+ var resolvedUnit = await server.getResolvedUnit(file);
+ if (resolvedUnit != null) {
+ var node = new NodeLocator(offset).searchWithin(resolvedUnit.unit);
+ var element = server.getElementOfNode(node);
+ if (element != null) {
+ if (element is ExecutableElement) {
+ refactoring = new ConvertMethodToGetterRefactoring(
+ searchEngine, resolvedUnit.session, element);
+ }
}
}
}
if (kind == RefactoringKind.EXTRACT_LOCAL_VARIABLE) {
- var analysisResult = await server.getAnalysisResult(file);
- if (analysisResult != null) {
- refactoring =
- new ExtractLocalRefactoring(analysisResult, offset, length);
+ var resolvedUnit = await server.getResolvedUnit(file);
+ if (resolvedUnit != null) {
+ refactoring = new ExtractLocalRefactoring(resolvedUnit, offset, length);
feedback = new ExtractLocalVariableFeedback(
<String>[], <int>[], <int>[],
coveringExpressionOffsets: <int>[],
@@ -969,34 +881,40 @@
}
}
if (kind == RefactoringKind.EXTRACT_METHOD) {
- var analysisResult = await server.getAnalysisResult(file);
- if (analysisResult != null) {
- refactoring = new ExtractMethodRefactoring(searchEngine,
- server.getAstProvider(file), analysisResult, offset, length);
+ var resolvedUnit = await server.getResolvedUnit(file);
+ if (resolvedUnit != null) {
+ refactoring = new ExtractMethodRefactoring(
+ searchEngine, resolvedUnit, offset, length);
feedback = new ExtractMethodFeedback(offset, length, '', <String>[],
false, <RefactoringMethodParameter>[], <int>[], <int>[]);
}
}
if (kind == RefactoringKind.EXTRACT_WIDGET) {
- var analysisResult = await server.getAnalysisResult(file);
- if (analysisResult != null) {
+ var resolvedUnit = await server.getResolvedUnit(file);
+ if (resolvedUnit != null) {
refactoring = new ExtractWidgetRefactoring(
- searchEngine, analysisResult, offset, length);
+ searchEngine, resolvedUnit, offset, length);
feedback = new ExtractWidgetFeedback();
}
}
if (kind == RefactoringKind.INLINE_LOCAL_VARIABLE) {
- var analysisResult = await server.getAnalysisResult(file);
- if (analysisResult != null) {
+ var resolvedUnit = await server.getResolvedUnit(file);
+ if (resolvedUnit != null) {
refactoring = new InlineLocalRefactoring(
- searchEngine, server.getAstProvider(file), analysisResult, offset);
+ searchEngine,
+ resolvedUnit,
+ offset,
+ );
}
}
if (kind == RefactoringKind.INLINE_METHOD) {
- var analysisResult = await server.getAnalysisResult(file);
- if (analysisResult != null) {
+ var resolvedUnit = await server.getResolvedUnit(file);
+ if (resolvedUnit != null) {
refactoring = new InlineMethodRefactoring(
- searchEngine, server.getAstProvider(file), analysisResult, offset);
+ searchEngine,
+ resolvedUnit,
+ offset,
+ );
}
}
if (kind == RefactoringKind.MOVE_FILE) {
@@ -1009,41 +927,44 @@
// server.resourceProvider, searchEngine, context, source, file);
}
if (kind == RefactoringKind.RENAME) {
- AstNode node = await server.getNodeAtOffset(file, offset);
- Element element = server.getElementOfNode(node);
- if (node != null && element != null) {
- int feedbackOffset = node.offset;
- int feedbackLength = node.length;
+ var resolvedUnit = await server.getResolvedUnit(file);
+ if (resolvedUnit != null) {
+ var node = new NodeLocator(offset).searchWithin(resolvedUnit.unit);
+ var element = server.getElementOfNode(node);
+ if (node != null && element != null) {
+ int feedbackOffset = node.offset;
+ int feedbackLength = node.length;
- if (element is FieldFormalParameterElement) {
- element = (element as FieldFormalParameterElement).field;
- }
-
- // Use the prefix offset/length when renaming an import directive.
- if (node is ImportDirective && element is ImportElement) {
- if (node.prefix != null) {
- feedbackOffset = node.prefix.offset;
- feedbackLength = node.prefix.length;
- } else {
- feedbackOffset = -1;
- feedbackLength = 0;
+ if (element is FieldFormalParameterElement) {
+ element = (element as FieldFormalParameterElement).field;
}
- }
- // Rename the class when on `new` in an instance creation.
- if (node is InstanceCreationExpression) {
- InstanceCreationExpression creation = node;
- var typeIdentifier = creation.constructorName.type.name;
- element = typeIdentifier.staticElement;
- feedbackOffset = typeIdentifier.offset;
- feedbackLength = typeIdentifier.length;
- }
+ // Use the prefix offset/length when renaming an import directive.
+ if (node is ImportDirective && element is ImportElement) {
+ if (node.prefix != null) {
+ feedbackOffset = node.prefix.offset;
+ feedbackLength = node.prefix.length;
+ } else {
+ feedbackOffset = -1;
+ feedbackLength = 0;
+ }
+ }
- // do create the refactoring
- refactoring = new RenameRefactoring(
- refactoringWorkspace, server.getAstProvider(file), element);
- feedback = new RenameFeedback(
- feedbackOffset, feedbackLength, 'kind', 'oldName');
+ // Rename the class when on `new` in an instance creation.
+ if (node is InstanceCreationExpression) {
+ InstanceCreationExpression creation = node;
+ var typeIdentifier = creation.constructorName.type.name;
+ element = typeIdentifier.staticElement;
+ feedbackOffset = typeIdentifier.offset;
+ feedbackLength = typeIdentifier.length;
+ }
+
+ // do create the refactoring
+ refactoring = new RenameRefactoring(
+ refactoringWorkspace, resolvedUnit.session, element);
+ feedback = new RenameFeedback(
+ feedbackOffset, feedbackLength, 'kind', 'oldName');
+ }
}
}
if (refactoring == null) {
diff --git a/pkg/analysis_server/lib/src/edit/fix/prefer_int_literals_fix.dart b/pkg/analysis_server/lib/src/edit/fix/prefer_int_literals_fix.dart
index 52dda1f..fa2ba99 100644
--- a/pkg/analysis_server/lib/src/edit/fix/prefer_int_literals_fix.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/prefer_int_literals_fix.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2018, 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.
@@ -6,9 +6,9 @@
import 'package:analysis_server/src/edit/edit_dartfix.dart';
import 'package:analysis_server/src/services/correction/assist.dart';
import 'package:analysis_server/src/services/correction/assist_internal.dart';
-import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/error/error.dart';
class PreferIntLiteralsFix extends LinterFix {
final literalsToConvert = <DoubleLiteral>[];
@@ -16,11 +16,12 @@
PreferIntLiteralsFix(EditDartFix dartFix) : super(dartFix);
@override
- Future<void> applyLocalFixes(AnalysisResult result) async {
+ Future<void> applyLocalFixes(ResolvedUnitResult result) async {
while (literalsToConvert.isNotEmpty) {
DoubleLiteral literal = literalsToConvert.removeLast();
AssistProcessor processor = new AssistProcessor(
- new EditDartFixAssistContext(dartFix, source, result.unit, literal));
+ new DartAssistContextImpl(result, literal.offset, 0),
+ );
List<Assist> assists =
await processor.computeAssist(DartAssistKind.CONVERT_TO_INT_LITERAL);
final location =
diff --git a/pkg/analysis_server/lib/src/edit/fix/prefer_mixin_fix.dart b/pkg/analysis_server/lib/src/edit/fix/prefer_mixin_fix.dart
index 52f924a..c929ff1 100644
--- a/pkg/analysis_server/lib/src/edit/fix/prefer_mixin_fix.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/prefer_mixin_fix.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2018, 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.
@@ -6,10 +6,10 @@
import 'package:analysis_server/src/edit/edit_dartfix.dart';
import 'package:analysis_server/src/services/correction/assist.dart';
import 'package:analysis_server/src/services/correction/assist_internal.dart';
-import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/error/error.dart';
class PreferMixinFix extends LinterFix {
final classesToConvert = new Set<Element>();
@@ -17,7 +17,7 @@
PreferMixinFix(EditDartFix dartFix) : super(dartFix);
@override
- Future<void> applyLocalFixes(AnalysisResult result) {
+ Future<void> applyLocalFixes(ResolvedUnitResult result) {
// All fixes applied in [applyRemainingFixes]
return null;
}
@@ -30,15 +30,15 @@
}
Future<void> convertClassToMixin(Element elem) async {
- AnalysisResult result =
- await dartFix.server.getAnalysisResult(elem.source?.fullName);
+ ResolvedUnitResult result =
+ await dartFix.server.getResolvedUnit(elem.source?.fullName);
for (CompilationUnitMember declaration in result.unit.declarations) {
if (declaration is ClassOrMixinDeclaration &&
declaration.name.name == elem.name) {
AssistProcessor processor = new AssistProcessor(
- new EditDartFixAssistContext(
- dartFix, elem.source, result.unit, declaration.name));
+ new DartAssistContextImpl(result, declaration.name.offset, 0),
+ );
List<Assist> assists = await processor
.computeAssist(DartAssistKind.CONVERT_CLASS_TO_MIXIN);
final location =
diff --git a/pkg/analysis_server/lib/src/flutter/flutter_correction.dart b/pkg/analysis_server/lib/src/flutter/flutter_correction.dart
index 459baf7..34e2864 100644
--- a/pkg/analysis_server/lib/src/flutter/flutter_correction.dart
+++ b/pkg/analysis_server/lib/src/flutter/flutter_correction.dart
@@ -5,46 +5,34 @@
import 'dart:async';
import 'package:analysis_server/src/services/correction/util.dart';
-import 'package:analyzer/dart/analysis/session.dart';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
-import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element;
import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
import 'package:meta/meta.dart';
class FlutterCorrections {
- final String file;
- final String fileContent;
-
+ final ResolvedUnitResult resolveResult;
final int selectionOffset;
final int selectionLength;
final int selectionEnd;
- final SourceRange selectionRange;
- final AnalysisSession session;
- final CompilationUnit unit;
+ final CorrectionUtils utils;
AstNode node;
- CorrectionUtils utils;
FlutterCorrections(
- {@required this.file,
- @required this.fileContent,
+ {@required this.resolveResult,
@required this.selectionOffset,
- @required this.selectionLength,
- @required this.session,
- @required this.unit})
- : assert(file != null),
- assert(fileContent != null),
+ @required this.selectionLength})
+ : assert(resolveResult != null),
assert(selectionOffset != null),
assert(selectionLength != null),
- assert(session != null),
- assert(unit != null),
selectionEnd = selectionOffset + selectionLength,
- selectionRange = new SourceRange(selectionOffset, selectionLength) {
- node = new NodeLocator(selectionOffset, selectionEnd).searchWithin(unit);
- utils = new CorrectionUtils(unit, buffer: fileContent);
+ utils = new CorrectionUtils(resolveResult) {
+ node = new NodeLocator(selectionOffset, selectionEnd)
+ .searchWithin(resolveResult.unit);
}
/**
@@ -59,8 +47,8 @@
if (node is ClassDeclaration) {
var className = node.name.name;
var location = utils.prepareNewConstructorLocation(node);
- var changeBuilder = new DartChangeBuilder(session);
- await changeBuilder.addFileEdit(file, (builder) {
+ var changeBuilder = new DartChangeBuilder(resolveResult.session);
+ await changeBuilder.addFileEdit(resolveResult.path, (builder) {
builder.addInsertion(location.offset, (builder) {
builder.write(location.prefix);
diff --git a/pkg/analysis_server/lib/src/flutter/flutter_domain.dart b/pkg/analysis_server/lib/src/flutter/flutter_domain.dart
index 45698c4..7bc3713 100644
--- a/pkg/analysis_server/lib/src/flutter/flutter_domain.dart
+++ b/pkg/analysis_server/lib/src/flutter/flutter_domain.dart
@@ -33,15 +33,13 @@
String file = params.file;
int offset = params.offset;
- ResolveResult result = await server.getAnalysisResult(file);
+ ResolvedUnitResult result = await server.getResolvedUnit(file);
if (result != null) {
var corrections = new FlutterCorrections(
- file: file,
- fileContent: result.content,
- selectionOffset: offset,
- selectionLength: 0,
- session: result.session,
- unit: result.unit);
+ resolveResult: result,
+ selectionOffset: offset,
+ selectionLength: 0,
+ );
SourceChange change = await corrections.addForDesignTimeConstructor();
if (change != null) {
server.sendResponse(
diff --git a/pkg/analysis_server/lib/src/flutter/flutter_notifications.dart b/pkg/analysis_server/lib/src/flutter/flutter_notifications.dart
index a468fd4..b387156 100644
--- a/pkg/analysis_server/lib/src/flutter/flutter_notifications.dart
+++ b/pkg/analysis_server/lib/src/flutter/flutter_notifications.dart
@@ -6,13 +6,19 @@
import 'package:analysis_server/src/flutter/flutter_outline_computer.dart';
import 'package:analysis_server/src/protocol_server.dart' as protocol;
import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source.dart';
-void sendFlutterNotificationOutline(AnalysisServer server, String file,
- String content, LineInfo lineInfo, CompilationUnit dartUnit) {
+void sendFlutterNotificationOutline(
+ AnalysisServer server,
+ String file,
+ String content,
+ LineInfo lineInfo,
+ CompilationUnit dartUnit,
+ TypeProvider typeProvider) {
_sendNotification(server, () {
- var computer =
- new FlutterOutlineComputer(file, content, lineInfo, dartUnit);
+ var computer = new FlutterOutlineComputer(
+ file, content, lineInfo, dartUnit, typeProvider);
protocol.FlutterOutline outline = computer.compute();
// send notification
var params = new protocol.FlutterOutlineParams(file, outline,
diff --git a/pkg/analysis_server/lib/src/flutter/flutter_outline_computer.dart b/pkg/analysis_server/lib/src/flutter/flutter_outline_computer.dart
index f1d5470..5d503b4 100644
--- a/pkg/analysis_server/lib/src/flutter/flutter_outline_computer.dart
+++ b/pkg/analysis_server/lib/src/flutter/flutter_outline_computer.dart
@@ -45,8 +45,8 @@
final List<protocol.SourceEdit> instrumentationEdits = [];
String instrumentedCode;
- FlutterOutlineComputer(this.file, this.content, this.lineInfo, this.unit)
- : typeProvider = unit.declaredElement.context.typeProvider;
+ FlutterOutlineComputer(
+ this.file, this.content, this.lineInfo, this.unit, this.typeProvider);
protocol.FlutterOutline compute() {
protocol.Outline dartOutline = new DartUnitOutlineComputer(
diff --git a/pkg/analysis_server/lib/src/lsp/channel/lsp_byte_stream_channel.dart b/pkg/analysis_server/lib/src/lsp/channel/lsp_byte_stream_channel.dart
new file mode 100644
index 0000000..7861d0d
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/channel/lsp_byte_stream_channel.dart
@@ -0,0 +1,140 @@
+// Copyright (c) 2018, 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 'dart:convert';
+import 'dart:io';
+
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/analysis_server.dart';
+import 'package:analysis_server/src/lsp/channel/lsp_channel.dart';
+import 'package:analysis_server/src/lsp/lsp_packet_transformer.dart';
+import 'package:analyzer/instrumentation/instrumentation.dart';
+
+/**
+ * Instances of the class [LspByteStreamServerChannel] implement an
+ * [LspServerCommunicationChannel] that uses a stream and a sink (typically,
+ * standard input and standard output) to communicate with clients.
+ */
+class LspByteStreamServerChannel implements LspServerCommunicationChannel {
+ final Stream _input;
+
+ final IOSink _output;
+
+ final InstrumentationService _instrumentationService;
+
+ /**
+ * Completer that will be signalled when the input stream is closed.
+ */
+ final Completer _closed = new Completer();
+
+ /**
+ * True if [close] has been called.
+ */
+ bool _closeRequested = false;
+
+ LspByteStreamServerChannel(
+ this._input, this._output, this._instrumentationService);
+
+ /**
+ * Future that will be completed when the input stream is closed.
+ */
+ Future get closed {
+ return _closed.future;
+ }
+
+ @override
+ void close() {
+ if (!_closeRequested) {
+ _closeRequested = true;
+ assert(!_closed.isCompleted);
+ _closed.complete();
+ }
+ }
+
+ @override
+ void listen(void onMessage(IncomingMessage message),
+ {Function onError, void onDone()}) {
+ _input.transform(new LspPacketTransformer()).listen(
+ (String data) => _readMessage(data, onMessage),
+ onError: onError,
+ onDone: () {
+ close();
+ onDone();
+ },
+ );
+ }
+
+ @override
+ void sendNotification(NotificationMessage notification) =>
+ _sendLsp(notification.toJson());
+
+ @override
+ void sendResponse(ResponseMessage response) => _sendLsp(response.toJson());
+
+ /**
+ * Read a request from the given [data] and use the given function to handle
+ * the message.
+ */
+ void _readMessage(String data, void onMessage(IncomingMessage request)) {
+ // Ignore any further requests after the communication channel is closed.
+ if (_closed.isCompleted) {
+ return;
+ }
+ ServerPerformanceStatistics.serverChannel.makeCurrentWhile(() {
+ _instrumentationService.logRequest(data);
+ final Map<String, Object> json = jsonDecode(data);
+ if (RequestMessage.canParse(json)) {
+ onMessage(RequestMessage.fromJson(json));
+ } else if (NotificationMessage.canParse(json)) {
+ onMessage(NotificationMessage.fromJson(json));
+ } else {
+ _sendParseError();
+ }
+ });
+ }
+
+ /// Sends a message prefixed with the required LSP headers.
+ void _sendLsp(Map<String, Object> json) {
+ // Don't send any further responses after the communication channel is
+ // closed.
+ if (_closeRequested) {
+ return;
+ }
+ ServerPerformanceStatistics.serverChannel.makeCurrentWhile(() {
+ final jsonEncodedBody = jsonEncode(json);
+ final utf8EncodedBody = utf8.encode(jsonEncodedBody);
+ final header = 'Content-Length: ${utf8EncodedBody.length}\r\n'
+ 'Content-Type: application/vscode-jsonrpc; charset=utf-8\r\n\r\n';
+ final asciiEncodedHeader = ascii.encode(header);
+
+ // Header is always ascii, body is always utf8!
+ _write(asciiEncodedHeader);
+ _write(utf8EncodedBody);
+
+ _instrumentationService.logResponse(jsonEncodedBody);
+ });
+ }
+
+ void _sendParseError() {
+ final error = new ResponseMessage(
+ null,
+ null,
+ new ResponseError(
+ ErrorCodes.ParseError, 'Unable to parse message', null),
+ jsonRpcVersion);
+ sendResponse(error);
+ }
+
+ /**
+ * Send [bytes] to [_output].
+ */
+ void _write(List<int> bytes) {
+ runZoned(
+ () => _output.add(bytes),
+ onError: (e) => close(),
+ );
+ }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/channel/lsp_channel.dart b/pkg/analysis_server/lib/src/lsp/channel/lsp_channel.dart
new file mode 100644
index 0000000..dd23b812
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/channel/lsp_channel.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2018, 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/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+
+/**
+ * The abstract class [LspServerCommunicationChannel] defines the behavior of
+ * objects that allow an [LspAnalysisServer] to receive [RequestMessage]s and
+ * [NotificationMessage]s and to return both [ResponseMessage]s and
+ * [NotificationMessage]s.
+ */
+abstract class LspServerCommunicationChannel {
+ /**
+ * Close the communication channel.
+ */
+ void close();
+
+ /**
+ * Listen to the channel for messages. If a message is received, invoke the
+ * [onMessage] function. If an error is encountered while trying to read from
+ * the socket, invoke the [onError] function. If the socket is closed by the
+ * client, invoke the [onDone] function.
+ * Only one listener is allowed per channel.
+ */
+ void listen(void onMessage(IncomingMessage message),
+ {Function onError, void onDone()});
+
+ /**
+ * Send the given [notification] to the client.
+ */
+ void sendNotification(NotificationMessage notification);
+
+ /**
+ * Send the given [response] to the client.
+ */
+ void sendResponse(ResponseMessage response);
+}
diff --git a/pkg/analysis_server/lib/src/lsp/dartdoc.dart b/pkg/analysis_server/lib/src/lsp/dartdoc.dart
new file mode 100644
index 0000000..dd2de9e
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/dartdoc.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2018, 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.
+
+final _dartdocCodeBlockSections = new RegExp(r'(```\w+) +\w+');
+final _dartdocDirectives =
+ new RegExp(r'(\n *{@.*?}$)|(^{@.*?}\n)', multiLine: true);
+
+String cleanDartdoc(String doc) {
+ if (doc == null) {
+ return null;
+ }
+ // Remove any dartdoc directives like {@template xxx}
+ doc = doc.replaceAll(_dartdocDirectives, '');
+
+ // Remove any code block section names like ```dart preamble that Flutter
+ // docs contain.
+ doc = doc.replaceAllMapped(
+ _dartdocCodeBlockSections,
+ (match) => match.group(1),
+ );
+
+ return doc;
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
new file mode 100644
index 0000000..6d7d0be
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
@@ -0,0 +1,100 @@
+// Copyright (c) 2018, 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 'dart:collection';
+
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/lsp/handlers/handlers.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+import 'package:analysis_server/src/lsp/mapping.dart';
+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:analyzer/dart/analysis/results.dart';
+
+// If the client does not provide capabilities.completion.completionItemKind.valueSet
+// then we must never send a kind that's not in this list.
+final defaultSupportedCompletionKinds = new HashSet<CompletionItemKind>.of([
+ CompletionItemKind.Text,
+ CompletionItemKind.Method,
+ CompletionItemKind.Function,
+ CompletionItemKind.Constructor,
+ CompletionItemKind.Field,
+ CompletionItemKind.Variable,
+ CompletionItemKind.Class,
+ CompletionItemKind.Interface,
+ CompletionItemKind.Module,
+ CompletionItemKind.Property,
+ CompletionItemKind.Unit,
+ CompletionItemKind.Value,
+ CompletionItemKind.Enum,
+ CompletionItemKind.Keyword,
+ CompletionItemKind.Snippet,
+ CompletionItemKind.Color,
+ CompletionItemKind.File,
+ CompletionItemKind.Reference,
+]);
+
+class CompletionHandler
+ extends MessageHandler<CompletionParams, List<CompletionItem>> {
+ CompletionHandler(LspAnalysisServer server) : super(server);
+ Method get handlesMessage => Method.textDocument_completion;
+
+ @override
+ CompletionParams convertParams(Map<String, dynamic> json) =>
+ CompletionParams.fromJson(json);
+
+ Future<ErrorOr<List<CompletionItem>>> handle(CompletionParams params) async {
+ final completionCapabilities =
+ server?.clientCapabilities?.textDocument?.completion;
+
+ final clientSupportedCompletionKinds =
+ completionCapabilities?.completionItemKind?.valueSet != null
+ ? new HashSet<CompletionItemKind>.of(
+ completionCapabilities.completionItemKind.valueSet)
+ : defaultSupportedCompletionKinds;
+
+ final pos = params.position;
+ final path = pathOf(params.textDocument);
+ final unit = await path.mapResult(requireUnit);
+ final offset = await unit.mapResult((unit) => toOffset(unit.lineInfo, pos));
+ return offset.mapResult((offset) => _getItems(
+ completionCapabilities,
+ clientSupportedCompletionKinds,
+ unit.result,
+ offset,
+ ));
+ }
+
+ Future<ErrorOr<List<CompletionItem>>> _getItems(
+ TextDocumentClientCapabilitiesCompletion completionCapabilities,
+ HashSet<CompletionItemKind> clientSupportedCompletionKinds,
+ ResolvedUnitResult unit,
+ int offset,
+ ) async {
+ final performance = new CompletionPerformance();
+ final completionRequest =
+ new CompletionRequestImpl(unit, offset, performance);
+
+ try {
+ CompletionContributor contributor = new DartCompletionManager();
+ final items = await contributor.computeSuggestions(completionRequest);
+ return success(items
+ .map((item) => toCompletionItem(
+ completionCapabilities,
+ clientSupportedCompletionKinds,
+ unit.lineInfo,
+ item,
+ completionRequest.replacementOffset,
+ completionRequest.replacementLength,
+ ))
+ .toList());
+ } on AbortCompletion {
+ return success([]);
+ }
+ }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart
new file mode 100644
index 0000000..f06f364
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2018, 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/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/domains/analysis/navigation_dart.dart';
+import 'package:analysis_server/src/lsp/handlers/handlers.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+import 'package:analysis_server/src/lsp/mapping.dart';
+import 'package:analysis_server/src/protocol_server.dart' show NavigationTarget;
+import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
+
+class DefinitionHandler
+ extends MessageHandler<TextDocumentPositionParams, List<Location>> {
+ DefinitionHandler(LspAnalysisServer server) : super(server);
+ Method get handlesMessage => Method.textDocument_definition;
+
+ @override
+ TextDocumentPositionParams convertParams(Map<String, dynamic> json) =>
+ TextDocumentPositionParams.fromJson(json);
+
+ Future<ErrorOr<List<Location>>> handle(
+ TextDocumentPositionParams params) async {
+ final pos = params.position;
+ final path = pathOf(params.textDocument);
+ final unit = await path.mapResult(requireUnit);
+ final offset = await unit.mapResult((unit) => toOffset(unit.lineInfo, pos));
+
+ return offset.mapResult((offset) {
+ NavigationCollectorImpl collector = new NavigationCollectorImpl();
+ computeDartNavigation(
+ server.resourceProvider, collector, unit.result.unit, offset, 0);
+
+ Location toLocation(NavigationTarget target) {
+ final targetFilePath = collector.files[target.fileIndex];
+ final lineInfo = server.getLineInfo(targetFilePath);
+ return navigationTargetToLocation(targetFilePath, target, lineInfo);
+ }
+
+ return success(convert(collector.targets, toLocation).toList());
+ });
+ }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_document_symbols.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_document_symbols.dart
new file mode 100644
index 0000000..f805495
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_document_symbols.dart
@@ -0,0 +1,157 @@
+// Copyright (c) 2018, 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 'dart:collection';
+
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/computer/computer_outline.dart';
+import 'package:analysis_server/src/lsp/handlers/handlers.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+import 'package:analysis_server/src/lsp/mapping.dart';
+import 'package:analysis_server/src/protocol_server.dart' show Outline;
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/source/line_info.dart';
+
+// If the client does not provide capabilities.documentSymbol.symbolKind.valueSet
+// then we must never send a kind that's not in this list.
+final defaultSupportedSymbolKinds = new HashSet<SymbolKind>.of([
+ SymbolKind.File,
+ SymbolKind.Module,
+ SymbolKind.Namespace,
+ SymbolKind.Package,
+ SymbolKind.Class,
+ SymbolKind.Method,
+ SymbolKind.Property,
+ SymbolKind.Field,
+ SymbolKind.Constructor,
+ SymbolKind.Enum,
+ SymbolKind.Interface,
+ SymbolKind.Function,
+ SymbolKind.Variable,
+ SymbolKind.Constant,
+ SymbolKind.Str,
+ SymbolKind.Number,
+ SymbolKind.Boolean,
+ SymbolKind.Array,
+]);
+
+class DocumentSymbolHandler extends MessageHandler<DocumentSymbolParams,
+ Either2<List<DocumentSymbol>, List<SymbolInformation>>> {
+ DocumentSymbolHandler(LspAnalysisServer server) : super(server);
+ Method get handlesMessage => Method.textDocument_documentSymbol;
+
+ @override
+ DocumentSymbolParams convertParams(Map<String, dynamic> json) =>
+ DocumentSymbolParams.fromJson(json);
+
+ Future<ErrorOr<Either2<List<DocumentSymbol>, List<SymbolInformation>>>>
+ handle(DocumentSymbolParams params) async {
+ final symbolCapabilities =
+ server?.clientCapabilities?.textDocument?.documentSymbol;
+
+ final clientSupportedSymbolKinds =
+ symbolCapabilities?.symbolKind?.valueSet != null
+ ? new HashSet<SymbolKind>.of(symbolCapabilities.symbolKind.valueSet)
+ : defaultSupportedSymbolKinds;
+
+ final clientSupportsDocumentSymbol =
+ symbolCapabilities?.hierarchicalDocumentSymbolSupport ?? false;
+
+ final path = pathOf(params.textDocument);
+ final unit = await path.mapResult(requireUnit);
+ return unit.mapResult((unit) => _getSymbols(clientSupportedSymbolKinds,
+ clientSupportsDocumentSymbol, path.result, unit));
+ }
+
+ DocumentSymbol _asDocumentSymbol(
+ HashSet<SymbolKind> clientSupportedSymbolKinds,
+ LineInfo lineInfo,
+ Outline outline,
+ ) {
+ return new DocumentSymbol(
+ outline.element.name,
+ outline.element.parameters,
+ elementKindToSymbolKind(clientSupportedSymbolKinds, outline.element.kind),
+ outline.element.isDeprecated,
+ toRange(lineInfo, outline.codeOffset, outline.codeLength),
+ toRange(lineInfo, outline.element.location.offset,
+ outline.element.location.length),
+ outline.children
+ ?.map((child) =>
+ _asDocumentSymbol(clientSupportedSymbolKinds, lineInfo, child))
+ ?.toList(),
+ );
+ }
+
+ SymbolInformation _asSymbolInformation(
+ String containerName,
+ HashSet<SymbolKind> clientSupportedSymbolKinds,
+ String documentUri,
+ LineInfo lineInfo,
+ Outline outline,
+ ) {
+ return new SymbolInformation(
+ outline.element.name,
+ elementKindToSymbolKind(clientSupportedSymbolKinds, outline.element.kind),
+ outline.element.isDeprecated,
+ new Location(
+ documentUri,
+ toRange(lineInfo, outline.element.location.offset,
+ outline.element.location.length),
+ ),
+ containerName,
+ );
+ }
+
+ ErrorOr<Either2<List<DocumentSymbol>, List<SymbolInformation>>> _getSymbols(
+ HashSet<SymbolKind> clientSupportedSymbolKinds,
+ bool clientSupportsDocumentSymbol,
+ String path,
+ ResolvedUnitResult unit,
+ ) {
+ final computer =
+ new DartUnitOutlineComputer(path, unit.lineInfo, unit.unit);
+ final outline = computer.compute();
+
+ if (clientSupportsDocumentSymbol) {
+ // Return a tree of DocumentSymbol only if the client shows explicit support
+ // for it.
+ return success(
+ Either2<List<DocumentSymbol>, List<SymbolInformation>>.t1(
+ outline?.children
+ ?.map((child) => _asDocumentSymbol(
+ clientSupportedSymbolKinds, unit.lineInfo, child))
+ ?.toList(),
+ ),
+ );
+ } else {
+ // Otherwise, we need to use the original flat SymbolInformation.
+ final allSymbols = <SymbolInformation>[];
+ final documentUri = new Uri.file(path).toString();
+
+ // Adds a symbol and it's children recursively, supplying the parent
+ // name as required by SymbolInformation.
+ addSymbol(Outline outline, {String parentName}) {
+ allSymbols.add(_asSymbolInformation(
+ parentName,
+ clientSupportedSymbolKinds,
+ documentUri,
+ unit.lineInfo,
+ outline,
+ ));
+ outline.children?.forEach(
+ (c) => addSymbol(c, parentName: outline.element.name),
+ );
+ }
+
+ outline?.children?.forEach(addSymbol);
+
+ return success(
+ Either2<List<DocumentSymbol>, List<SymbolInformation>>.t2(allSymbols),
+ );
+ }
+ }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_exit.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_exit.dart
new file mode 100644
index 0000000..f2b3579
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_exit.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2018, 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/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/lsp/handlers/handlers.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+
+class ExitMessageHandler extends MessageHandler<void, void> {
+ ExitMessageHandler(LspAnalysisServer server) : super(server);
+ Method get handlesMessage => Method.exit;
+
+ @override
+ void convertParams(Map<String, dynamic> json) => null;
+
+ @override
+ Future<ErrorOr<void>> handle(void _) async {
+ await server.shutdown();
+ return success();
+ }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_format_on_type.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_format_on_type.dart
new file mode 100644
index 0000000..f704f06
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_format_on_type.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2018, 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/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/lsp/handlers/handlers.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+import 'package:analysis_server/src/lsp/mapping.dart';
+import 'package:analysis_server/src/lsp/source_edits.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+
+class FormatOnTypeHandler
+ extends MessageHandler<DocumentOnTypeFormattingParams, List<TextEdit>> {
+ FormatOnTypeHandler(LspAnalysisServer server) : super(server);
+ Method get handlesMessage => Method.textDocument_onTypeFormatting;
+
+ @override
+ DocumentOnTypeFormattingParams convertParams(Map<String, dynamic> json) =>
+ DocumentOnTypeFormattingParams.fromJson(json);
+
+ ErrorOr<List<TextEdit>> formatFile(String path, ResolvedUnitResult unit) {
+ final unformattedSource = server.fileContentOverlay[path] ??
+ server.resourceProvider.getFile(path).readAsStringSync();
+
+ return success(generateEditsForFormatting(unformattedSource));
+ }
+
+ Future<ErrorOr<List<TextEdit>>> handle(
+ DocumentOnTypeFormattingParams params) async {
+ final path = pathOf(params.textDocument);
+ final unit = await path.mapResult(requireUnit);
+ return unit.mapResult((unit) => formatFile(path.result, unit));
+ }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_formatting.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_formatting.dart
new file mode 100644
index 0000000..a0078c0
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_formatting.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2018, 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/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/lsp/handlers/handlers.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+import 'package:analysis_server/src/lsp/mapping.dart';
+import 'package:analysis_server/src/lsp/source_edits.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+
+class FormattingHandler
+ extends MessageHandler<DocumentFormattingParams, List<TextEdit>> {
+ FormattingHandler(LspAnalysisServer server) : super(server);
+ Method get handlesMessage => Method.textDocument_formatting;
+
+ @override
+ DocumentFormattingParams convertParams(Map<String, dynamic> json) =>
+ DocumentFormattingParams.fromJson(json);
+
+ ErrorOr<List<TextEdit>> formatFile(String path, ResolvedUnitResult unit) {
+ final unformattedSource = server.fileContentOverlay[path] ??
+ server.resourceProvider.getFile(path).readAsStringSync();
+
+ return success(generateEditsForFormatting(unformattedSource));
+ }
+
+ Future<ErrorOr<List<TextEdit>>> handle(
+ DocumentFormattingParams params) async {
+ final path = pathOf(params.textDocument);
+ final unit = await path.mapResult(requireUnit);
+ return unit.mapResult((unit) => formatFile(path.result, unit));
+ }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_hover.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_hover.dart
new file mode 100644
index 0000000..682bbdb
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_hover.dart
@@ -0,0 +1,84 @@
+// Copyright (c) 2018, 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/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/protocol/protocol_generated.dart';
+import 'package:analysis_server/src/computer/computer_hover.dart';
+import 'package:analysis_server/src/lsp/dartdoc.dart';
+import 'package:analysis_server/src/lsp/handlers/handlers.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+import 'package:analysis_server/src/lsp/mapping.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/source/line_info.dart';
+
+class HoverHandler extends MessageHandler<TextDocumentPositionParams, Hover> {
+ HoverHandler(LspAnalysisServer server) : super(server);
+ Method get handlesMessage => Method.textDocument_hover;
+
+ @override
+ TextDocumentPositionParams convertParams(Map<String, dynamic> json) =>
+ TextDocumentPositionParams.fromJson(json);
+
+ Future<ErrorOr<Hover>> handle(TextDocumentPositionParams params) async {
+ final pos = params.position;
+ final path = pathOf(params.textDocument);
+ final unit = await path.mapResult(requireUnit);
+ final offset = await unit.mapResult((unit) => toOffset(unit.lineInfo, pos));
+ return offset.mapResult((offset) => _getHover(unit.result, offset));
+ }
+
+ Hover toHover(LineInfo lineInfo, HoverInformation hover) {
+ if (hover == null) {
+ return null;
+ }
+
+ // Import prefix tooltips are not useful currently.
+ // https://github.com/dart-lang/sdk/issues/32735
+ if (hover.elementKind == 'import prefix') {
+ return null;
+ }
+
+ final content = new StringBuffer();
+
+ // Description.
+ if (hover.elementDescription != null) {
+ content.writeln('```dart');
+ if (hover.isDeprecated) {
+ content.write('(deprecated) ');
+ }
+ content..writeln(hover.elementDescription)..writeln('```')..writeln();
+ }
+
+ // Source library.
+ if (hover.containingLibraryName != null &&
+ hover.containingLibraryName.isNotEmpty) {
+ content..writeln('*${hover.containingLibraryName}*')..writeln();
+ } else if (hover.containingLibraryPath != null) {
+ // TODO(dantup): Support displaying the package name (probably by adding
+ // containingPackageName to the main hover?) once the analyzer work to
+ // support this (inc Bazel/Gn) is done.
+ // content..writeln('*${hover.containingPackageName}*')..writeln();
+ }
+
+ // Doc comments.
+ if (hover.dartdoc != null) {
+ content.writeln(cleanDartdoc(hover.dartdoc));
+ }
+
+ final formats =
+ server?.clientCapabilities?.textDocument?.hover?.contentFormat;
+ return new Hover(
+ asStringOrMarkupContent(formats, content.toString().trimRight()),
+ toRange(lineInfo, hover.offset, hover.length),
+ );
+ }
+
+ ErrorOr<Hover> _getHover(ResolvedUnitResult unit, int offset) {
+ final hover = new DartUnitHoverComputer(unit.unit, offset).compute();
+ return success(toHover(unit.lineInfo, hover));
+ }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart
new file mode 100644
index 0000000..9c4a555
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart
@@ -0,0 +1,84 @@
+// Copyright (c) 2018, 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/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/lsp/handlers/handler_states.dart';
+import 'package:analysis_server/src/lsp/handlers/handlers.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+
+class InitializeMessageHandler
+ extends MessageHandler<InitializeParams, InitializeResult> {
+ InitializeMessageHandler(LspAnalysisServer server) : super(server);
+
+ Method get handlesMessage => Method.initialize;
+
+ @override
+ InitializeParams convertParams(Map<String, dynamic> json) =>
+ InitializeParams.fromJson(json);
+
+ ErrorOr<InitializeResult> handle(InitializeParams params) {
+ final openWorkspacePaths = <String>[];
+
+ if (params.workspaceFolders != null) {
+ params.workspaceFolders.forEach((wf) {
+ openWorkspacePaths.add(Uri.parse(wf.uri).toFilePath());
+ });
+ }
+ if (params.rootUri != null) {
+ openWorkspacePaths.add(Uri.parse(params.rootUri).toFilePath());
+ // ignore: deprecated_member_use
+ } else if (params.rootPath != null) {
+ openWorkspacePaths.add(params.rootUri);
+ }
+
+ server.setClientCapabilities(params.capabilities);
+ server.messageHandler =
+ new InitializingStateMessageHandler(server, openWorkspacePaths);
+
+ return success(new InitializeResult(new ServerCapabilities(
+ Either2<TextDocumentSyncOptions, num>.t1(new TextDocumentSyncOptions(
+ true,
+ TextDocumentSyncKind.Incremental,
+ false,
+ false,
+ null,
+ )),
+ true, // hoverProvider
+ new CompletionOptions(
+ false,
+ // Set the characters that will cause the editor to automatically
+ // trigger completion.
+ // TODO(dantup): This is quite eager and may need filtering in the
+ // completion handler.
+ // See https://github.com/Dart-Code/Dart-Code/blob/c616c93c87972713454eb0518f97c0278201a99a/src/providers/dart_completion_item_provider.ts#L36
+ r'''.: =(${'"/\'''.split(''),
+ ),
+ new SignatureHelpOptions(
+ // TODO(dantup): Signature help triggering is even more sensitive to
+ // bad chars, so we'll need to implement the logic described here:
+ // https://github.com/dart-lang/sdk/issues/34241
+ [],
+ ),
+ true, // definitionProvider
+ null,
+ null,
+ true, // referencesProvider
+ null,
+ true, // documentSymbolProvider
+ null,
+ null,
+ null,
+ true, // documentFormattingProvider
+ false, // documentRangeFormattingProvider
+ new DocumentOnTypeFormattingOptions('}', [';']),
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null)));
+ }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_initialized.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_initialized.dart
new file mode 100644
index 0000000..8201ae8
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_initialized.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2018, 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/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/lsp/handlers/handler_states.dart';
+import 'package:analysis_server/src/lsp/handlers/handlers.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+
+class IntializedMessageHandler extends MessageHandler<InitializedParams, void> {
+ final List<String> openWorkspacePaths;
+ IntializedMessageHandler(LspAnalysisServer server, this.openWorkspacePaths)
+ : super(server);
+ Method get handlesMessage => Method.initialized;
+
+ @override
+ InitializedParams convertParams(Map<String, dynamic> json) =>
+ InitializedParams.fromJson(json);
+
+ ErrorOr<void> handle(InitializedParams params) {
+ server.messageHandler = new InitializedStateMessageHandler(server);
+
+ server.setAnalysisRoots(openWorkspacePaths, [], {});
+
+ return success();
+ }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_references.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_references.dart
new file mode 100644
index 0000000..ec5dc37
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_references.dart
@@ -0,0 +1,84 @@
+// Copyright (c) 2018, 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/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/domains/analysis/navigation_dart.dart';
+import 'package:analysis_server/src/lsp/handlers/handlers.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+import 'package:analysis_server/src/lsp/mapping.dart';
+import 'package:analysis_server/src/protocol_server.dart' show SearchResult;
+import 'package:analysis_server/src/protocol_server.dart' show NavigationTarget;
+import 'package:analysis_server/src/search/element_references.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
+
+class ReferencesHandler
+ extends MessageHandler<ReferenceParams, List<Location>> {
+ ReferencesHandler(LspAnalysisServer server) : super(server);
+ Method get handlesMessage => Method.textDocument_references;
+
+ @override
+ ReferenceParams convertParams(Map<String, dynamic> json) =>
+ ReferenceParams.fromJson(json);
+
+ @override
+ Future<ErrorOr<List<Location>>> handle(ReferenceParams params) async {
+ final pos = params.position;
+ final path = pathOf(params.textDocument);
+ final unit = await path.mapResult(requireUnit);
+ final offset = await unit.mapResult((unit) => toOffset(unit.lineInfo, pos));
+ return offset.mapResult(
+ (offset) => _getRefererences(path.result, offset, params, unit.result));
+ }
+
+ List<Location> _getDeclarations(CompilationUnit unit, int offset) {
+ final collector = new NavigationCollectorImpl();
+ computeDartNavigation(server.resourceProvider, collector, unit, offset, 0);
+
+ return convert(collector.targets, (NavigationTarget target) {
+ final targetFilePath = collector.files[target.fileIndex];
+ final lineInfo = server.getLineInfo(targetFilePath);
+ return navigationTargetToLocation(targetFilePath, target, lineInfo);
+ }).toList();
+ }
+
+ Future<ErrorOr<List<Location>>> _getRefererences(String path, int offset,
+ ReferenceParams params, ResolvedUnitResult unit) async {
+ Element element = await server.getElementAtOffset(path, offset);
+ if (element is ImportElement) {
+ element = (element as ImportElement).prefix;
+ }
+ if (element is FieldFormalParameterElement) {
+ element = (element as FieldFormalParameterElement).field;
+ }
+ if (element is PropertyAccessorElement) {
+ element = (element as PropertyAccessorElement).variable;
+ }
+ if (element == null) {
+ return success();
+ }
+
+ final computer = new ElementReferencesComputer(server.searchEngine);
+ final results = await computer.compute(element, false);
+
+ Location toLocation(SearchResult result) {
+ final lineInfo = server.getLineInfo(result.location.file);
+ return searchResultToLocation(result, lineInfo);
+ }
+
+ final referenceResults = convert(results, toLocation).toList();
+
+ if (params.context?.includeDeclaration == true) {
+ // Also include the definition for the symbol at this location.
+ referenceResults.addAll(_getDeclarations(unit.unit, offset));
+ }
+
+ return success(referenceResults);
+ }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_reject.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_reject.dart
new file mode 100644
index 0000000..8cd06e5
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_reject.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2018, 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/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/lsp/handlers/handlers.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+
+/// A [MessageHandler] that rejects specific tpyes of messages with a given
+/// error code/message.
+class RejectMessageHandler extends MessageHandler<Object, void> {
+ final Method handlesMessage;
+ final ErrorCodes errorCode;
+ final String errorMessage;
+ RejectMessageHandler(LspAnalysisServer server, this.handlesMessage,
+ this.errorCode, this.errorMessage)
+ : super(server);
+
+ @override
+ void convertParams(Map<String, dynamic> json) => null;
+
+ @override
+ ErrorOr<void> handle(void _) {
+ return error(errorCode, errorMessage, null);
+ }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_shutdown.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_shutdown.dart
new file mode 100644
index 0000000..82e50f6
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_shutdown.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2018, 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/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/lsp/handlers/handlers.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+
+class ShutdownMessageHandler extends MessageHandler<void, void> {
+ ShutdownMessageHandler(LspAnalysisServer server) : super(server);
+ Method get handlesMessage => Method.shutdown;
+
+ @override
+ void convertParams(Map<String, dynamic> json) => null;
+
+ @override
+ ErrorOr<void> handle(void _) {
+ // We can clean up and shut down here, but we cannot terminate the server
+ // because that must be done after the exit notification.
+ return success();
+ }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_signature_help.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_signature_help.dart
new file mode 100644
index 0000000..c5e0caf
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_signature_help.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2018, 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/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/computer/computer_signature.dart';
+import 'package:analysis_server/src/lsp/handlers/handlers.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+import 'package:analysis_server/src/lsp/mapping.dart';
+
+class SignatureHelpHandler
+ extends MessageHandler<TextDocumentPositionParams, SignatureHelp> {
+ SignatureHelpHandler(LspAnalysisServer server) : super(server);
+ Method get handlesMessage => Method.textDocument_signatureHelp;
+
+ @override
+ TextDocumentPositionParams convertParams(Map<String, dynamic> json) =>
+ TextDocumentPositionParams.fromJson(json);
+
+ Future<ErrorOr<SignatureHelp>> handle(
+ TextDocumentPositionParams params) async {
+ final pos = params.position;
+ final path = pathOf(params.textDocument);
+ final unit = await path.mapResult(requireUnit);
+ final offset = await unit.mapResult((unit) => toOffset(unit.lineInfo, pos));
+
+ return offset.mapResult((offset) {
+ final computer = new DartUnitSignatureComputer(unit.result.unit, offset);
+ if (!computer.offsetIsValid) {
+ return success(); // No error, just no valid hover.
+ }
+ final signature = computer.compute();
+ if (signature == null) {
+ return success(); // No error, just no valid hover.
+ }
+ final formats = server?.clientCapabilities?.textDocument?.signatureHelp
+ ?.signatureInformation?.documentationFormat;
+ return success(toSignatureHelp(formats, signature));
+ });
+ }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart
new file mode 100644
index 0000000..af58e9c
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart
@@ -0,0 +1,82 @@
+// Copyright (c) 2018, 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/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/lsp/handlers/handler_completion.dart';
+import 'package:analysis_server/src/lsp/handlers/handler_definition.dart';
+import 'package:analysis_server/src/lsp/handlers/handler_document_symbols.dart';
+import 'package:analysis_server/src/lsp/handlers/handler_format_on_type.dart';
+import 'package:analysis_server/src/lsp/handlers/handler_formatting.dart';
+import 'package:analysis_server/src/lsp/handlers/handler_hover.dart';
+import 'package:analysis_server/src/lsp/handlers/handler_initialize.dart';
+import 'package:analysis_server/src/lsp/handlers/handler_initialized.dart';
+import 'package:analysis_server/src/lsp/handlers/handler_references.dart';
+import 'package:analysis_server/src/lsp/handlers/handler_signature_help.dart';
+import 'package:analysis_server/src/lsp/handlers/handler_text_document_changes.dart';
+import 'package:analysis_server/src/lsp/handlers/handlers.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+
+class InitializedStateMessageHandler extends ServerStateMessageHandler {
+ InitializedStateMessageHandler(LspAnalysisServer server) : super(server) {
+ reject(Method.initialize, ServerErrorCodes.ServerAlreadyInitialized,
+ 'Server already initialized');
+ reject(Method.initialized, ServerErrorCodes.ServerAlreadyInitialized,
+ 'Server already initialized');
+ registerHandler(new TextDocumentOpenHandler(server));
+ registerHandler(new TextDocumentChangeHandler(server));
+ registerHandler(new TextDocumentCloseHandler(server));
+ registerHandler(new HoverHandler(server));
+ registerHandler(new CompletionHandler(server));
+ registerHandler(new SignatureHelpHandler(server));
+ registerHandler(new DefinitionHandler(server));
+ registerHandler(new ReferencesHandler(server));
+ registerHandler(new FormattingHandler(server));
+ registerHandler(new FormatOnTypeHandler(server));
+ registerHandler(new DocumentSymbolHandler(server));
+ }
+}
+
+class InitializingStateMessageHandler extends ServerStateMessageHandler {
+ InitializingStateMessageHandler(
+ LspAnalysisServer server, List<String> openWorkspacePaths)
+ : super(server) {
+ reject(Method.initialize, ServerErrorCodes.ServerAlreadyInitialized,
+ 'Server already initialized');
+ registerHandler(new IntializedMessageHandler(server, openWorkspacePaths));
+ }
+
+ @override
+ ErrorOr<void> handleUnknownMessage(IncomingMessage message) {
+ // Silently drop non-requests.
+ if (message is! RequestMessage) {
+ return success();
+ }
+ return failure(
+ ErrorCodes.ServerNotInitialized,
+ 'Unable to handle ${message.method} before the server is initialized '
+ 'and the client has sent the initialized notification',
+ null);
+ }
+}
+
+class UninitializedStateMessageHandler extends ServerStateMessageHandler {
+ UninitializedStateMessageHandler(LspAnalysisServer server) : super(server) {
+ registerHandler(new InitializeMessageHandler(server));
+ }
+
+ @override
+ FutureOr<ErrorOr<Object>> handleUnknownMessage(IncomingMessage message) {
+ // Silently drop non-requests.
+ if (message is! RequestMessage) {
+ return success();
+ }
+ return failure(
+ ErrorCodes.ServerNotInitialized,
+ 'Unable to handle ${message.method} before client has sent initialize request',
+ null);
+ }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_text_document_changes.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_text_document_changes.dart
new file mode 100644
index 0000000..28ae74c
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_text_document_changes.dart
@@ -0,0 +1,91 @@
+// Copyright (c) 2018, 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/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/lsp/handlers/handlers.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+import 'package:analysis_server/src/lsp/mapping.dart';
+import 'package:analysis_server/src/lsp/source_edits.dart';
+
+class TextDocumentChangeHandler
+ extends MessageHandler<DidChangeTextDocumentParams, void> {
+ TextDocumentChangeHandler(LspAnalysisServer server) : super(server);
+ Method get handlesMessage => Method.textDocument_didChange;
+
+ @override
+ DidChangeTextDocumentParams convertParams(Map<String, dynamic> json) =>
+ DidChangeTextDocumentParams.fromJson(json);
+
+ ErrorOr<void> handle(DidChangeTextDocumentParams params) {
+ final path = pathOf(params.textDocument);
+ return path.mapResult((path) => _changeFile(path, params));
+ }
+
+ ErrorOr<void> _changeFile(String path, DidChangeTextDocumentParams params) {
+ final oldContents = server.fileContentOverlay[path];
+ // TODO(dantup): Should we be tracking the version?
+
+ // Visual Studio has been seen to skip didOpen notifications for files that
+ // were already open when the LSP server initialized, so handle this with
+ // a specific message to make it clear what's happened.
+ if (oldContents == null) {
+ return error(
+ ErrorCodes.InvalidParams,
+ 'Unable to edit document because the file was not previously opened: $path',
+ null,
+ );
+ }
+ final newContents = applyEdits(oldContents, params.contentChanges);
+ return newContents.mapResult((newcontents) {
+ server.updateOverlay(path, newContents.result);
+ return success();
+ });
+ }
+}
+
+class TextDocumentCloseHandler
+ extends MessageHandler<DidCloseTextDocumentParams, void> {
+ TextDocumentCloseHandler(LspAnalysisServer server) : super(server);
+ Method get handlesMessage => Method.textDocument_didClose;
+
+ @override
+ DidCloseTextDocumentParams convertParams(Map<String, dynamic> json) =>
+ DidCloseTextDocumentParams.fromJson(json);
+
+ ErrorOr<void> handle(DidCloseTextDocumentParams params) {
+ final path = pathOf(params.textDocument);
+ return path.mapResult((path) {
+ server.updateOverlay(path, null);
+ return success();
+ });
+ }
+}
+
+class TextDocumentOpenHandler
+ extends MessageHandler<DidOpenTextDocumentParams, void> {
+ TextDocumentOpenHandler(LspAnalysisServer server) : super(server);
+ Method get handlesMessage => Method.textDocument_didOpen;
+
+ @override
+ DidOpenTextDocumentParams convertParams(Map<String, dynamic> json) =>
+ DidOpenTextDocumentParams.fromJson(json);
+
+ ErrorOr<void> handle(DidOpenTextDocumentParams params) {
+ final doc = params.textDocument;
+ // TODO(dantup): This needs similar error handling to pathOf()
+ final path = Uri.parse(doc.uri).toFilePath();
+ // TODO(dantup): Keep track of versions, so that when we compute fixes etc.
+ // we can send them back versions so the client can drop them if the document
+ // has been modified.
+
+ server.updateOverlay(path, doc.text);
+
+ // If the file did not exist, and is "overlay only", it still should be
+ // analyzed. Add it to driver to which it should have been added.
+ server.contextManager.getDriverFor(path)?.addFile(path);
+
+ return success();
+ }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart b/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
new file mode 100644
index 0000000..d58569d
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
@@ -0,0 +1,118 @@
+// Copyright (c) 2018, 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/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/lsp/handlers/handler_exit.dart';
+import 'package:analysis_server/src/lsp/handlers/handler_reject.dart';
+import 'package:analysis_server/src/lsp/handlers/handler_shutdown.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+
+/// An object that can handle messages and produce responses for requests.
+///
+/// Clients may not extend, implement or mix-in this class.
+abstract class MessageHandler<P, R> {
+ LspAnalysisServer server;
+
+ MessageHandler(this.server);
+
+ /// The method that this handler can handle.
+ Method get handlesMessage;
+
+ /// Converts an iterable using the provided function and skipping over any
+ /// null values.
+ Iterable<T> convert<T, E>(Iterable<E> items, T Function(E) converter) {
+ return items.map(converter).where((item) => item != null);
+ }
+
+ P convertParams(Map<String, dynamic> json);
+
+ ErrorOr<R> error<R>(ErrorCodes code, String message, Object data) =>
+ new ErrorOr<R>.error(new ResponseError(code, message, data));
+
+ ErrorOr<R> failure<R>(ErrorOr<dynamic> error) =>
+ new ErrorOr<R>.error(error.error);
+
+ FutureOr<ErrorOr<R>> handle(P params);
+
+ /// Handle the given [message]. If the [message] is a [RequestMessage], then the
+ /// return value will be sent back in a [ResponseMessage].
+ /// [NotificationMessage]s are not expected to return results.
+ FutureOr<ErrorOr<R>> handleMessage(IncomingMessage message) {
+ final params = convertParams(message.params);
+ return handle(params);
+ }
+
+ Future<ErrorOr<ResolvedUnitResult>> requireUnit(String path) async {
+ final result = await server.getResolvedUnit(path);
+ if (result?.state != ResultState.VALID) {
+ return error(ServerErrorCodes.InvalidFilePath, 'Invalid file path', path);
+ }
+ return success(result);
+ }
+
+ ErrorOr<R> success<R>([R t]) => new ErrorOr<R>.success(t);
+}
+
+/// A message handler that handles all messages for a given server state.
+abstract class ServerStateMessageHandler {
+ final LspAnalysisServer server;
+ Map<Method, MessageHandler> _messageHandlers = {};
+
+ ServerStateMessageHandler(this.server) {
+ // All server states support shutdown and exit.
+ registerHandler(new ShutdownMessageHandler(server));
+ registerHandler(new ExitMessageHandler(server));
+ }
+
+ ErrorOr<Object> failure<Object>(
+ ErrorCodes code, String message, Object data) =>
+ new ErrorOr<Object>.error(new ResponseError(code, message, data));
+
+ /// Handle the given [message]. If the [message] is a [RequestMessage], then the
+ /// return value will be sent back in a [ResponseMessage].
+ /// [NotificationMessage]s are not expected to return results.
+ FutureOr<ErrorOr<Object>> handleMessage(IncomingMessage message) async {
+ final handler = _messageHandlers[message.method];
+ return handler != null
+ ? handler.handleMessage(message)
+ : handleUnknownMessage(message);
+ }
+
+ FutureOr<ErrorOr<Object>> handleUnknownMessage(IncomingMessage message) {
+ // TODO(dantup): How should we handle unknown notifications that do
+ // *not* start with $/?
+ // https://github.com/Microsoft/language-server-protocol/issues/608
+ if (!_isOptionalRequest(message)) {
+ return failure(
+ ErrorCodes.MethodNotFound, 'Unknown method ${message.method}', null);
+ }
+ return success();
+ }
+
+ registerHandler(MessageHandler handler) {
+ assert(
+ handler.handlesMessage != null,
+ 'Unable to register handler ${handler.runtimeType} because it does '
+ 'not declare which messages it can handle');
+
+ _messageHandlers[handler.handlesMessage] = handler;
+ }
+
+ reject(Method method, ErrorCodes code, String message) {
+ registerHandler(new RejectMessageHandler(server, method, code, message));
+ }
+
+ ErrorOr<Object> success<Object>([Object t]) => new ErrorOr<Object>.success(t);
+
+ bool _isOptionalRequest(IncomingMessage message) {
+ // Messages that start with $/ are optional and can be silently ignored
+ // if we don't know how to handle them.
+ final stringValue = message.method.toJson();
+ return stringValue is String && stringValue.startsWith(r'$/');
+ }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
new file mode 100644
index 0000000..3e1d0e7
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
@@ -0,0 +1,431 @@
+// Copyright (c) 2018, 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 'dart:io' as io;
+
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/protocol/protocol_generated.dart' as protocol;
+import 'package:analysis_server/src/analysis_server.dart';
+import 'package:analysis_server/src/analysis_server_abstract.dart';
+import 'package:analysis_server/src/context_manager.dart';
+import 'package:analysis_server/src/lsp/channel/lsp_channel.dart';
+import 'package:analysis_server/src/lsp/handlers/handler_states.dart';
+import 'package:analysis_server/src/lsp/handlers/handlers.dart';
+import 'package:analysis_server/src/lsp/mapping.dart';
+import 'package:analysis_server/src/plugin/notification_manager.dart';
+import 'package:analysis_server/src/protocol_server.dart' as protocol;
+import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analysis_server/src/services/search/search_engine_internal.dart';
+import 'package:analysis_server/src/utilities/null_string_sink.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/source/line_info.dart';
+import 'package:analyzer/src/context/builder.dart';
+import 'package:analyzer/src/context/context_root.dart';
+import 'package:analyzer/src/dart/analysis/byte_store.dart';
+import 'package:analyzer/src/dart/analysis/driver.dart' as nd;
+import 'package:analyzer/src/dart/analysis/file_state.dart' as nd;
+import 'package:analyzer/src/dart/analysis/performance_logger.dart';
+import 'package:analyzer/src/dart/analysis/status.dart' as nd;
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/plugin/resolver_provider.dart';
+import 'package:watcher/watcher.dart';
+
+/**
+ * Instances of the class [LspAnalysisServer] implement an LSP-based server that
+ * listens on a [CommunicationChannel] for LSP messages and processes them.
+ */
+class LspAnalysisServer extends AbstractAnalysisServer {
+ /// The capabilities of the LSP client. Will be null prior to initialization.
+ ClientCapabilities _clientCapabilities;
+
+ /**
+ * The options of this server instance.
+ */
+ AnalysisServerOptions options;
+
+ /**
+ * The channel from which messages are received and to which responses should
+ * be sent.
+ */
+ final LspServerCommunicationChannel channel;
+
+ /// The [SearchEngine] for this server, may be `null` if indexing is disabled.
+ SearchEngine searchEngine;
+
+ final NotificationManager notificationManager = new NullNotificationManager();
+
+ /**
+ * The object used to manage the SDK's known to this server.
+ */
+ final DartSdkManager sdkManager;
+
+ /**
+ * The instrumentation service that is to be used by this analysis server.
+ */
+ final InstrumentationService instrumentationService;
+
+ /**
+ * The content overlay for all analysis drivers.
+ */
+ final nd.FileContentOverlay fileContentOverlay = new nd.FileContentOverlay();
+
+ /**
+ * The default options used to create new analysis contexts. This object is
+ * also referenced by the ContextManager.
+ */
+ final AnalysisOptionsImpl defaultContextOptions = new AnalysisOptionsImpl();
+
+ /**
+ * The file resolver provider used to override the way file URI's are
+ * resolved in some contexts.
+ */
+ ResolverProvider fileResolverProvider;
+
+ /**
+ * The package resolver provider used to override the way package URI's are
+ * resolved in some contexts.
+ */
+ ResolverProvider packageResolverProvider;
+
+ PerformanceLog _analysisPerformanceLogger;
+
+ ByteStore byteStore;
+
+ nd.AnalysisDriverScheduler analysisDriverScheduler;
+
+ ServerStateMessageHandler messageHandler;
+
+ /**
+ * Initialize a newly created server to send and receive messages to the given
+ * [channel].
+ */
+ LspAnalysisServer(
+ this.channel,
+ ResourceProvider resourceProvider,
+ this.options,
+ this.sdkManager,
+ this.instrumentationService, {
+ ResolverProvider packageResolverProvider: null,
+ }) : super(resourceProvider) {
+ messageHandler = new UninitializedStateMessageHandler(this);
+ defaultContextOptions.generateImplicitErrors = false;
+ defaultContextOptions.useFastaParser = options.useFastaParser;
+
+ {
+ String name = options.newAnalysisDriverLog;
+ StringSink sink = new NullStringSink();
+ if (name != null) {
+ if (name == 'stdout') {
+ sink = io.stdout;
+ } else if (name.startsWith('file:')) {
+ String path = name.substring('file:'.length);
+ sink = new io.File(path).openWrite(mode: io.FileMode.append);
+ }
+ }
+ _analysisPerformanceLogger = new PerformanceLog(sink);
+ }
+ byteStore = createByteStore(resourceProvider);
+ analysisDriverScheduler =
+ new nd.AnalysisDriverScheduler(_analysisPerformanceLogger);
+ analysisDriverScheduler.start();
+
+ contextManager = new ContextManagerImpl(
+ resourceProvider,
+ fileContentOverlay,
+ sdkManager,
+ packageResolverProvider,
+ analyzedFilesGlobs,
+ instrumentationService,
+ defaultContextOptions);
+ final contextManagerCallbacks =
+ new LspServerContextManagerCallbacks(this, resourceProvider);
+ contextManager.callbacks = contextManagerCallbacks;
+ searchEngine = new SearchEngineImpl(driverMap.values);
+
+ channel.listen(handleMessage, onDone: done, onError: error);
+ }
+
+ /// The capabilities of the LSP client. Will be null prior to initialization.
+ ClientCapabilities get clientCapabilities => _clientCapabilities;
+
+ /**
+ * The socket from which messages are being read has been closed.
+ */
+ void done() {}
+
+ /**
+ * There was an error related to the socket from which messages are being
+ * read.
+ */
+ void error(error, stack) {
+ sendServerErrorNotification('Server error', error, stack);
+ }
+
+ /// Return the LineInfo for the file with the given [path]. The file is
+ /// analyzed in one of the analysis drivers to which the file was added,
+ /// otherwise in the first driver, otherwise `null` is returned.
+ LineInfo getLineInfo(String path) {
+ if (!AnalysisEngine.isDartFileName(path)) {
+ return null;
+ }
+
+ return getAnalysisDriver(path)?.getFileSync(path)?.lineInfo;
+ }
+
+ /**
+ * Handle a [message] that was read from the communication channel.
+ */
+ void handleMessage(IncomingMessage message) {
+ // TODO(dantup): Put in all the things this server is missing, like:
+ // _performance.logRequest(message);
+ runZoned(() {
+ ServerPerformanceStatistics.serverRequests.makeCurrentWhile(() async {
+ try {
+ final result = await messageHandler.handleMessage(message);
+ if (result.isError) {
+ sendErrorResponse(message, result.error);
+ } else if (message is RequestMessage) {
+ channel.sendResponse(new ResponseMessage(
+ message.id, result.result, null, jsonRpcVersion));
+ }
+ } catch (error, stackTrace) {
+ sendErrorResponse(
+ message,
+ new ResponseError(
+ ServerErrorCodes.UnhandledError,
+ 'An error occurred while handling ${message.method} message',
+ null));
+ logError(error.toString());
+ if (stackTrace != null) {
+ logError(stackTrace.toString());
+ }
+ }
+ });
+ }, onError: error);
+ }
+
+ void logError(String message) {
+ channel.sendNotification(new NotificationMessage(
+ Method.window_logMessage,
+ new LogMessageParams(MessageType.Error, message),
+ jsonRpcVersion,
+ ));
+ }
+
+ void sendErrorResponse(IncomingMessage message, ResponseError error) {
+ if (message is RequestMessage) {
+ channel.sendResponse(
+ new ResponseMessage(message.id, null, error, jsonRpcVersion));
+ // Since the LSP client might not show the failed requests to the user,
+ // also ensure the error is logged to the client.
+ logError(error.message);
+ } else {
+ // For notifications where we couldn't respond with an error, send it as
+ // show instead of log.
+ showError(error.message);
+ }
+ }
+
+ /**
+ * Send the given [notification] to the client.
+ */
+ void sendNotification(NotificationMessage notification) {
+ channel.sendNotification(notification);
+ }
+
+ /**
+ * Send the given [response] to the client.
+ */
+ void sendResponse(ResponseMessage response) {
+ channel.sendResponse(response);
+ }
+
+ void sendServerErrorNotification(String message, exception, stackTrace) {
+ final fullError = new StringBuffer();
+ fullError.writeln(message);
+ if (exception != null) {
+ fullError.writeln(exception.toString());
+ }
+ if (stackTrace != null) {
+ fullError.writeln(stackTrace.toString());
+ }
+ showError(message); // Show message to the user.
+ logError(fullError.toString()); // Log the full message.
+ }
+
+ void setAnalysisRoots(List<String> includedPaths, List<String> excludedPaths,
+ Map<String, String> packageRoots) {
+ contextManager.setRoots(includedPaths, excludedPaths, packageRoots);
+ }
+
+ void setClientCapabilities(ClientCapabilities capabilities) {
+ _clientCapabilities = capabilities;
+ }
+
+ /**
+ * Returns `true` if errors should be reported for [file] with the given
+ * absolute path.
+ */
+ bool shouldSendErrorsNotificationFor(String file) {
+ return contextManager.isInAnalysisRoot(file);
+ }
+
+ void showError(String message) {
+ channel.sendNotification(new NotificationMessage(
+ Method.window_showMessage,
+ new ShowMessageParams(MessageType.Error, message),
+ jsonRpcVersion,
+ ));
+ }
+
+ Future<void> shutdown() {
+ // Defer closing the channel so that the shutdown response can be sent and
+ // logged.
+ new Future(() {
+ channel.close();
+ });
+
+ return new Future.value();
+ }
+
+ void updateOverlay(String path, String contents) {
+ fileContentOverlay[path] = contents;
+ driverMap.values.forEach((driver) => driver.changeFile(path));
+ }
+}
+
+class LspServerContextManagerCallbacks extends ContextManagerCallbacks {
+ // TODO(dantup): Lots of copy/paste from the Analysis Server one here.
+
+ final LspAnalysisServer analysisServer;
+
+ /**
+ * The [ResourceProvider] by which paths are converted into [Resource]s.
+ */
+ final ResourceProvider resourceProvider;
+
+ LspServerContextManagerCallbacks(this.analysisServer, this.resourceProvider);
+
+ @override
+ NotificationManager get notificationManager =>
+ analysisServer.notificationManager;
+
+ @override
+ nd.AnalysisDriver addAnalysisDriver(
+ Folder folder, ContextRoot contextRoot, AnalysisOptions options) {
+ ContextBuilder builder = createContextBuilder(folder, options);
+ nd.AnalysisDriver analysisDriver = builder.buildDriver(contextRoot);
+ analysisDriver.results.listen((result) {
+ String path = result.path;
+ if (analysisServer.shouldSendErrorsNotificationFor(path)) {
+ final serverErrors = protocol.mapEngineErrors(
+ result.session.analysisContext.analysisOptions,
+ result.lineInfo,
+ result.errors,
+ toDiagnostic);
+
+ final params = new PublishDiagnosticsParams(
+ Uri.file(result.path).toString(), serverErrors);
+ // TODO(dantup): Move all these method names to constants.
+ final message = new NotificationMessage(
+ Method.textDocument_publishDiagnostics,
+ params,
+ jsonRpcVersion,
+ );
+ analysisServer.sendNotification(message);
+ }
+ });
+ analysisDriver.exceptions.listen((nd.ExceptionResult result) {
+ String message = 'Analysis failed: ${result.path}';
+ if (result.contextKey != null) {
+ message += ' context: ${result.contextKey}';
+ }
+ AnalysisEngine.instance.logger.logError(message, result.exception);
+ });
+ analysisServer.driverMap[folder] = analysisDriver;
+ return analysisDriver;
+ }
+
+ @override
+ void afterWatchEvent(WatchEvent event) {
+ // TODO: implement afterWatchEvent
+ }
+
+ @override
+ void applyChangesToContext(Folder contextFolder, ChangeSet changeSet) {
+ nd.AnalysisDriver analysisDriver = analysisServer.driverMap[contextFolder];
+ if (analysisDriver != null) {
+ changeSet.addedSources.forEach((source) {
+ analysisDriver.addFile(source.fullName);
+ });
+ changeSet.changedSources.forEach((source) {
+ analysisDriver.changeFile(source.fullName);
+ });
+ changeSet.removedSources.forEach((source) {
+ analysisDriver.removeFile(source.fullName);
+ });
+ }
+ }
+
+ @override
+ void applyFileRemoved(nd.AnalysisDriver driver, String file) {
+ driver.removeFile(file);
+ // sendAnalysisNotificationFlushResults(analysisServer, [file]);
+ }
+
+ @override
+ void broadcastWatchEvent(WatchEvent event) {
+ // TODO: implement broadcastWatchEvent
+ }
+
+ @override
+ ContextBuilder createContextBuilder(Folder folder, AnalysisOptions options) {
+ String defaultPackageFilePath = null;
+ String defaultPackagesDirectoryPath = null;
+ String path = (analysisServer.contextManager as ContextManagerImpl)
+ .normalizedPackageRoots[folder.path];
+ if (path != null) {
+ Resource resource = resourceProvider.getResource(path);
+ if (resource.exists) {
+ if (resource is File) {
+ defaultPackageFilePath = path;
+ } else {
+ defaultPackagesDirectoryPath = path;
+ }
+ }
+ }
+
+ ContextBuilderOptions builderOptions = new ContextBuilderOptions();
+ builderOptions.defaultOptions = options;
+ builderOptions.defaultPackageFilePath = defaultPackageFilePath;
+ builderOptions.defaultPackagesDirectoryPath = defaultPackagesDirectoryPath;
+ ContextBuilder builder = new ContextBuilder(
+ resourceProvider, analysisServer.sdkManager, null,
+ options: builderOptions);
+ builder.fileResolverProvider = analysisServer.fileResolverProvider;
+ builder.packageResolverProvider = analysisServer.packageResolverProvider;
+ builder.analysisDriverScheduler = analysisServer.analysisDriverScheduler;
+ builder.performanceLog = analysisServer._analysisPerformanceLogger;
+ builder.byteStore = analysisServer.byteStore;
+ builder.enableIndex = true;
+ builder.fileContentOverlay = analysisServer.fileContentOverlay;
+ return builder;
+ }
+
+ @override
+ void removeContext(Folder folder, List<String> flushedFiles) {
+ // sendAnalysisNotificationFlushResults(analysisServer, flushedFiles);
+ nd.AnalysisDriver driver = analysisServer.driverMap.remove(folder);
+ driver.dispose();
+ }
+}
+
+class NullNotificationManager implements NotificationManager {
+ @override
+ noSuchMethod(Invocation invocation) {}
+}
diff --git a/pkg/analysis_server/lib/src/lsp/lsp_packet_transformer.dart b/pkg/analysis_server/lib/src/lsp/lsp_packet_transformer.dart
new file mode 100644
index 0000000..c766875
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/lsp_packet_transformer.dart
@@ -0,0 +1,73 @@
+// Copyright (c) 2018, 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 'dart:convert';
+
+/// Transforms a stream of LSP data in the form:
+///
+/// Content-Length: xxx\r\n
+/// Content-Type: application/vscode-jsonrpc; charset=utf-8\r\n
+/// \r\n
+/// { JSON payload }
+///
+/// into just the JSON payload, decoded with the specified encoding. Line endings
+/// for headers must be \r\n on all platforms as defined in the LSP spec.
+class LspPacketTransformer extends StreamTransformerBase<List<int>, String> {
+ @override
+ Stream<String> bind(Stream<List<int>> stream) {
+ StreamSubscription<int> input;
+ StreamController<String> _output;
+ final buffer = <int>[];
+ bool isParsingHeaders = true;
+ int contentLength;
+ _output = StreamController<String>(
+ onListen: () {
+ input = stream.expand((b) => b).listen(
+ (codeUnit) {
+ buffer.add(codeUnit);
+ if (isParsingHeaders && _endsWithCrLfCrLf(buffer)) {
+ contentLength = _parseContentLength(buffer);
+ buffer.clear();
+ isParsingHeaders = false;
+ } else if (!isParsingHeaders && buffer.length >= contentLength) {
+ // LSP Spec: "It defaults to utf-8, which is the only encoding
+ // supported right now".
+ _output.add(utf8.decode(buffer));
+ buffer.clear();
+ isParsingHeaders = true;
+ }
+ },
+ onError: _output.addError,
+ onDone: _output.close,
+ );
+ },
+ onPause: () => input.pause(),
+ onResume: () => input.resume(),
+ onCancel: () => input.cancel(),
+ );
+ return _output.stream;
+ }
+
+ /// Whether [buffer] ends in '\r\n\r\n'.
+ static bool _endsWithCrLfCrLf(List<int> buffer) {
+ var l = buffer.length;
+ return l > 4 &&
+ buffer[l - 1] == 10 &&
+ buffer[l - 2] == 13 &&
+ buffer[l - 3] == 10 &&
+ buffer[l - 4] == 13;
+ }
+
+ /// Decodes [buffer] into a String and returns the 'Content-Length' header value.
+ static int _parseContentLength(List<int> buffer) {
+ // Headers are specified as always ASCII in LSP.
+ var asString = ascii.decode(buffer);
+ var headers = asString.split('\r\n');
+ var lengthHeader =
+ headers.firstWhere((h) => h.startsWith('Content-Length'));
+ var length = lengthHeader.split(':').last.trim();
+ return int.parse(length);
+ }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/lsp_socket_server.dart b/pkg/analysis_server/lib/src/lsp/lsp_socket_server.dart
new file mode 100644
index 0000000..1831321
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/lsp_socket_server.dart
@@ -0,0 +1,82 @@
+// Copyright (c) 2018, 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/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/analysis_server.dart';
+import 'package:analysis_server/src/lsp/channel/lsp_channel.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+import 'package:analysis_server/src/socket_server.dart';
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/src/generated/sdk.dart';
+
+/**
+ * Instances of the class [SocketServer] implement the common parts of
+ * http-based and stdio-based analysis servers. The primary responsibility of
+ * the SocketServer is to manage the lifetime of the AnalysisServer and to
+ * encode and decode the JSON messages exchanged with the client.
+ */
+class LspSocketServer {
+ final AnalysisServerOptions analysisServerOptions;
+ /**
+ * The analysis server that was created when a client established a
+ * connection, or `null` if no such connection has yet been established.
+ */
+ LspAnalysisServer analysisServer;
+
+ /**
+ * The function used to create a new SDK using the default SDK.
+ */
+ final DartSdkManager sdkManager;
+
+ final InstrumentationService instrumentationService;
+
+ LspSocketServer(
+ this.analysisServerOptions,
+ this.sdkManager,
+ this.instrumentationService,
+ );
+
+ /**
+ * Create an analysis server which will communicate with the client using the
+ * given serverChannel.
+ */
+ void createAnalysisServer(LspServerCommunicationChannel serverChannel) {
+ if (analysisServer != null) {
+ ResponseError error = new ResponseError<void>(
+ ServerErrorCodes.ServerAlreadyStarted,
+ 'Server already started',
+ null);
+ serverChannel.sendNotification(new NotificationMessage(
+ Method.window_showMessage,
+ new ShowMessageParams(MessageType.Error, error.message),
+ jsonRpcVersion,
+ ));
+ serverChannel.listen((IncomingMessage message) {
+ if (message is RequestMessage) {
+ serverChannel.sendResponse(
+ new ResponseMessage(message.id, null, error, jsonRpcVersion));
+ }
+ });
+ return;
+ }
+
+ PhysicalResourceProvider resourceProvider;
+ if (analysisServerOptions.fileReadMode == 'as-is') {
+ resourceProvider = new PhysicalResourceProvider(null,
+ stateLocation: analysisServerOptions.cacheFolder);
+ } else if (analysisServerOptions.fileReadMode == 'normalize-eol-always') {
+ resourceProvider = new PhysicalResourceProvider(
+ PhysicalResourceProvider.NORMALIZE_EOL_ALWAYS,
+ stateLocation: analysisServerOptions.cacheFolder);
+ } else {
+ throw new Exception(
+ 'File read mode was set to the unknown mode: $analysisServerOptions.fileReadMode');
+ }
+
+ analysisServer = new LspAnalysisServer(serverChannel, resourceProvider,
+ analysisServerOptions, sdkManager, instrumentationService);
+ }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/mapping.dart b/pkg/analysis_server/lib/src/lsp/mapping.dart
new file mode 100644
index 0000000..414ba60
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/mapping.dart
@@ -0,0 +1,499 @@
+import 'dart:collection';
+
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart' as lsp;
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart' as lsp;
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/lsp/dartdoc.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart' as lsp;
+import 'package:analysis_server/src/protocol_server.dart' as server
+ hide AnalysisError;
+import 'package:analyzer/dart/analysis/results.dart' as server;
+import 'package:analyzer/error/error.dart' as server;
+import 'package:analyzer/source/line_info.dart' as server;
+import 'package:analyzer/src/generated/source.dart' as server;
+
+const languageSourceName = 'dart';
+
+lsp.Either2<String, lsp.MarkupContent> asStringOrMarkupContent(
+ List<lsp.MarkupKind> preferredFormats, String content) {
+ if (content == null) {
+ return null;
+ }
+
+ return preferredFormats == null
+ ? new lsp.Either2<String, lsp.MarkupContent>.t1(content)
+ : new lsp.Either2<String, lsp.MarkupContent>.t2(
+ _asMarkup(preferredFormats, content));
+}
+
+lsp.CompletionItemKind elementKindToCompletionItemKind(
+ HashSet<lsp.CompletionItemKind> clientSupportedCompletionKinds,
+ server.ElementKind kind,
+) {
+ bool isSupported(lsp.CompletionItemKind kind) =>
+ clientSupportedCompletionKinds.contains(kind);
+
+ List<lsp.CompletionItemKind> getKindPreferences() {
+ switch (kind) {
+ case server.ElementKind.CLASS:
+ case server.ElementKind.CLASS_TYPE_ALIAS:
+ return const [lsp.CompletionItemKind.Class];
+ case server.ElementKind.COMPILATION_UNIT:
+ return const [lsp.CompletionItemKind.Module];
+ case server.ElementKind.CONSTRUCTOR:
+ case server.ElementKind.CONSTRUCTOR_INVOCATION:
+ return const [lsp.CompletionItemKind.Constructor];
+ case server.ElementKind.ENUM:
+ case server.ElementKind.ENUM_CONSTANT:
+ return const [lsp.CompletionItemKind.Enum];
+ case server.ElementKind.FIELD:
+ return const [lsp.CompletionItemKind.Field];
+ case server.ElementKind.FILE:
+ return const [lsp.CompletionItemKind.File];
+ case server.ElementKind.FUNCTION:
+ return const [lsp.CompletionItemKind.Function];
+ case server.ElementKind.FUNCTION_TYPE_ALIAS:
+ return const [lsp.CompletionItemKind.Class];
+ case server.ElementKind.GETTER:
+ return const [lsp.CompletionItemKind.Property];
+ case server.ElementKind.LABEL:
+ // There isn't really a good CompletionItemKind for labels so we'll
+ // just use the Text option.
+ return const [lsp.CompletionItemKind.Text];
+ case server.ElementKind.LIBRARY:
+ return const [lsp.CompletionItemKind.Module];
+ case server.ElementKind.LOCAL_VARIABLE:
+ return const [lsp.CompletionItemKind.Variable];
+ case server.ElementKind.METHOD:
+ return const [lsp.CompletionItemKind.Method];
+ case server.ElementKind.PARAMETER:
+ case server.ElementKind.PREFIX:
+ return const [lsp.CompletionItemKind.Variable];
+ case server.ElementKind.SETTER:
+ return const [lsp.CompletionItemKind.Property];
+ case server.ElementKind.TOP_LEVEL_VARIABLE:
+ return const [lsp.CompletionItemKind.Variable];
+ case server.ElementKind.TYPE_PARAMETER:
+ return const [
+ lsp.CompletionItemKind.TypeParameter,
+ lsp.CompletionItemKind.Variable,
+ ];
+ case server.ElementKind.UNIT_TEST_GROUP:
+ case server.ElementKind.UNIT_TEST_TEST:
+ return const [lsp.CompletionItemKind.Method];
+ default:
+ return null;
+ }
+ }
+
+ return getKindPreferences().firstWhere(isSupported, orElse: () => null);
+}
+
+lsp.SymbolKind elementKindToSymbolKind(
+ HashSet<lsp.SymbolKind> clientSupportedSymbolKinds,
+ server.ElementKind kind,
+) {
+ bool isSupported(lsp.SymbolKind kind) =>
+ clientSupportedSymbolKinds.contains(kind);
+
+ List<lsp.SymbolKind> getKindPreferences() {
+ switch (kind) {
+ case server.ElementKind.CLASS:
+ case server.ElementKind.CLASS_TYPE_ALIAS:
+ return const [lsp.SymbolKind.Class];
+ case server.ElementKind.COMPILATION_UNIT:
+ return const [lsp.SymbolKind.Module];
+ case server.ElementKind.CONSTRUCTOR:
+ case server.ElementKind.CONSTRUCTOR_INVOCATION:
+ return const [lsp.SymbolKind.Constructor];
+ case server.ElementKind.ENUM:
+ case server.ElementKind.ENUM_CONSTANT:
+ return const [lsp.SymbolKind.Enum];
+ case server.ElementKind.FIELD:
+ return const [lsp.SymbolKind.Field];
+ case server.ElementKind.FILE:
+ return const [lsp.SymbolKind.File];
+ case server.ElementKind.FUNCTION:
+ case server.ElementKind.FUNCTION_INVOCATION:
+ return const [lsp.SymbolKind.Function];
+ case server.ElementKind.FUNCTION_TYPE_ALIAS:
+ return const [lsp.SymbolKind.Class];
+ case server.ElementKind.GETTER:
+ return const [lsp.SymbolKind.Property];
+ case server.ElementKind.LABEL:
+ // There isn't really a good SymbolKind for labels so we'll
+ // just use the Null option.
+ return const [lsp.SymbolKind.Null];
+ case server.ElementKind.LIBRARY:
+ return const [lsp.SymbolKind.Namespace];
+ case server.ElementKind.LOCAL_VARIABLE:
+ return const [lsp.SymbolKind.Variable];
+ case server.ElementKind.METHOD:
+ return const [lsp.SymbolKind.Method];
+ case server.ElementKind.MIXIN:
+ return const [lsp.SymbolKind.Class];
+ case server.ElementKind.PARAMETER:
+ case server.ElementKind.PREFIX:
+ return const [lsp.SymbolKind.Variable];
+ case server.ElementKind.SETTER:
+ return const [lsp.SymbolKind.Property];
+ case server.ElementKind.TOP_LEVEL_VARIABLE:
+ return const [lsp.SymbolKind.Variable];
+ case server.ElementKind.TYPE_PARAMETER:
+ return const [
+ lsp.SymbolKind.TypeParameter,
+ lsp.SymbolKind.Variable,
+ ];
+ case server.ElementKind.UNIT_TEST_GROUP:
+ case server.ElementKind.UNIT_TEST_TEST:
+ return const [lsp.SymbolKind.Method];
+ default:
+ // TODO(dantup): Do we want an assert here to crash in test runs? It's
+ // valid to return null but we should aim to have everything above.
+ return null;
+ }
+ }
+
+ return getKindPreferences().firstWhere(isSupported, orElse: () => null);
+}
+
+String getCompletionDetail(
+ server.CompletionSuggestion suggestion,
+ lsp.CompletionItemKind completionKind,
+ bool clientSupportsDeprecated,
+) {
+ final hasElement = suggestion.element != null;
+ final hasParameters = hasElement &&
+ suggestion.element.parameters != null &&
+ suggestion.element.parameters.isNotEmpty;
+ final hasReturnType = hasElement &&
+ suggestion.element.returnType != null &&
+ suggestion.element.returnType.isNotEmpty;
+ final hasParameterType =
+ suggestion.parameterType != null && suggestion.parameterType.isNotEmpty;
+
+ final prefix = clientSupportsDeprecated || !suggestion.isDeprecated
+ ? ''
+ : '(Deprecated) ';
+
+ if (completionKind == lsp.CompletionItemKind.Property) {
+ // Setters appear as methods with one arg but they also cause getters to not
+ // appear in the completion list, so displaying them as setters is misleading.
+ // To avoid this, always show only the return type, whether it's a getter
+ // or a setter.
+ return prefix +
+ (suggestion.element.kind == server.ElementKind.GETTER
+ ? suggestion.element.returnType
+ // Don't assume setters always have parameters
+ // See https://github.com/dart-lang/sdk/issues/27747
+ : suggestion.element.parameters != null &&
+ suggestion.element.parameters.isNotEmpty
+ // Extract the type part from '(MyType value)`
+ ? suggestion.element.parameters.substring(
+ 1, suggestion.element.parameters.lastIndexOf(" "))
+ : '');
+ } else if (hasParameters && hasReturnType) {
+ return '$prefix${suggestion.element.parameters} → ${suggestion.element.returnType}';
+ } else if (hasReturnType) {
+ return '$prefix${suggestion.element.returnType}';
+ } else if (hasParameterType) {
+ return '$prefix${suggestion.parameterType}';
+ } else {
+ return prefix;
+ }
+}
+
+lsp.Location navigationTargetToLocation(String targetFilePath,
+ server.NavigationTarget target, server.LineInfo lineInfo) {
+ if (lineInfo == null) {
+ return null;
+ }
+
+ return new Location(
+ Uri.file(targetFilePath).toString(),
+ toRange(lineInfo, target.offset, target.length),
+ );
+}
+
+/// Returns the file system path for a TextDocumentIdentifier.
+ErrorOr<String> pathOf(lsp.TextDocumentIdentifier doc) {
+ final uri = Uri.tryParse(doc.uri);
+ final isValidFileUri = (uri?.isScheme('file') ?? false);
+ if (!isValidFileUri) {
+ return new ErrorOr<String>.error(new ResponseError(
+ lsp.ServerErrorCodes.InvalidFilePath,
+ 'URI was not a valid file:// URI',
+ doc.uri));
+ }
+ try {
+ return new ErrorOr<String>.success(uri.toFilePath());
+ } catch (e) {
+ // Even if tryParse() works and file == scheme, toFilePath() can throw on
+ // Windows if there are invalid characters.
+ return new ErrorOr<String>.error(new ResponseError(
+ lsp.ServerErrorCodes.InvalidFilePath,
+ 'File URI did not contain a valid file path',
+ doc.uri));
+ }
+}
+
+lsp.Location searchResultToLocation(
+ server.SearchResult result, server.LineInfo lineInfo) {
+ final location = result.location;
+
+ if (lineInfo == null) {
+ return null;
+ }
+
+ return new Location(
+ Uri.file(result.location.file).toString(),
+ toRange(lineInfo, location.offset, location.length),
+ );
+}
+
+lsp.CompletionItemKind suggestionKindToCompletionItemKind(
+ HashSet<lsp.CompletionItemKind> clientSupportedCompletionKinds,
+ server.CompletionSuggestionKind kind,
+ String label,
+) {
+ bool isSupported(lsp.CompletionItemKind kind) =>
+ clientSupportedCompletionKinds.contains(kind);
+
+ List<lsp.CompletionItemKind> getKindPreferences() {
+ switch (kind) {
+ case server.CompletionSuggestionKind.ARGUMENT_LIST:
+ return const [lsp.CompletionItemKind.Variable];
+ case server.CompletionSuggestionKind.IMPORT:
+ // For package/relative URIs, we can send File/Folder kinds for better icons.
+ if (!label.startsWith('dart:')) {
+ return label.endsWith('.dart')
+ ? const [
+ lsp.CompletionItemKind.File,
+ lsp.CompletionItemKind.Module,
+ ]
+ : const [
+ lsp.CompletionItemKind.Folder,
+ lsp.CompletionItemKind.Module,
+ ];
+ }
+ return const [lsp.CompletionItemKind.Module];
+ case server.CompletionSuggestionKind.IDENTIFIER:
+ return const [lsp.CompletionItemKind.Variable];
+ case server.CompletionSuggestionKind.INVOCATION:
+ return const [lsp.CompletionItemKind.Method];
+ case server.CompletionSuggestionKind.KEYWORD:
+ return const [lsp.CompletionItemKind.Keyword];
+ case server.CompletionSuggestionKind.NAMED_ARGUMENT:
+ return const [lsp.CompletionItemKind.Variable];
+ case server.CompletionSuggestionKind.OPTIONAL_ARGUMENT:
+ return const [lsp.CompletionItemKind.Variable];
+ case server.CompletionSuggestionKind.PARAMETER:
+ return const [lsp.CompletionItemKind.Value];
+ default:
+ return null;
+ }
+ }
+
+ return getKindPreferences().firstWhere(isSupported, orElse: () => null);
+}
+
+lsp.CompletionItem toCompletionItem(
+ lsp.TextDocumentClientCapabilitiesCompletion completionCapabilities,
+ HashSet<lsp.CompletionItemKind> supportedCompletionItemKinds,
+ server.LineInfo lineInfo,
+ server.CompletionSuggestion suggestion,
+ int replacementOffset,
+ int replacementLength,
+) {
+ final label = suggestion.displayText != null
+ ? suggestion.displayText
+ : suggestion.completion;
+
+ final useSnippets =
+ completionCapabilities?.completionItem?.snippetSupport == true;
+ final useDeprecated =
+ completionCapabilities?.completionItem?.deprecatedSupport == true;
+ final formats = completionCapabilities?.completionItem?.documentationFormat;
+
+ final completionKind = suggestion.element != null
+ ? elementKindToCompletionItemKind(
+ supportedCompletionItemKinds, suggestion.element.kind)
+ : suggestionKindToCompletionItemKind(
+ supportedCompletionItemKinds, suggestion.kind, label);
+
+ return new lsp.CompletionItem(
+ label,
+ completionKind,
+ getCompletionDetail(suggestion, completionKind, useDeprecated),
+ asStringOrMarkupContent(formats, cleanDartdoc(suggestion.docComplete)),
+ useDeprecated ? suggestion.isDeprecated : null,
+ false, // preselect
+ // Relevance is a number, highest being best. LSP does text sort so subtract
+ // from a large number so that a text sort will result in the correct order.
+ // 555 -> 999455
+ // 10 -> 999990
+ // 1 -> 999999
+ (1000000 - suggestion.relevance).toString(),
+ null, // filterText uses label if not set
+ null, // insertText is deprecated, but also uses label if not set
+ useSnippets ? lsp.InsertTextFormat.Snippet : lsp.InsertTextFormat.PlainText,
+ new lsp.TextEdit(
+ // TODO(dantup): If `clientSupportsSnippets == true` then we should map
+ // `selection` in to a snippet (see how Dart Code does this).
+ toRange(lineInfo, replacementOffset, replacementLength),
+ suggestion.completion,
+ ),
+ [], // additionalTextEdits, used for adding imports, etc.
+ [], // commitCharacters
+ null, // command
+ null, // data, useful for if using lazy resolve, this comes back to us
+ );
+}
+
+lsp.Diagnostic toDiagnostic(
+ server.LineInfo lineInfo, server.AnalysisError error,
+ [server.ErrorSeverity errorSeverity]) {
+ server.ErrorCode errorCode = error.errorCode;
+
+ // Default to the error's severity if none is specified.
+ errorSeverity ??= errorCode.errorSeverity;
+
+ return new lsp.Diagnostic(
+ toRange(lineInfo, error.offset, error.length),
+ toDiagnosticSeverity(errorSeverity),
+ errorCode.name.toLowerCase(),
+ languageSourceName,
+ error.message,
+ null,
+ );
+}
+
+lsp.DiagnosticSeverity toDiagnosticSeverity(server.ErrorSeverity severity) {
+ switch (severity) {
+ case server.ErrorSeverity.ERROR:
+ return lsp.DiagnosticSeverity.Error;
+ case server.ErrorSeverity.WARNING:
+ return lsp.DiagnosticSeverity.Warning;
+ case server.ErrorSeverity.INFO:
+ return lsp.DiagnosticSeverity.Information;
+ // Note: LSP also supports "Hint", but they won't render in things like the
+ // VS Code errors list as they're apparently intended to communicate
+ // non-visible diagnostics back (for example, if you wanted to grey out
+ // unreachable code without producing an item in the error list).
+ default:
+ throw 'Unknown AnalysisErrorSeverity: $severity';
+ }
+}
+
+ErrorOr<int> toOffset(server.LineInfo lineInfo, lsp.Position pos) {
+ if (pos.line > lineInfo.lineCount) {
+ return new ErrorOr<int>.error(new lsp.ResponseError(
+ lsp.ServerErrorCodes.InvalidFileLineCol,
+ 'Invalid line number',
+ pos.line));
+ }
+ // TODO(dantup): Is there any way to validate the character? We could ensure
+ // it's less than the offset of the next line, but that would only work for
+ // all lines except the last one.
+ return new ErrorOr<int>.success(
+ lineInfo.getOffsetOfLine(pos.line) + pos.character);
+}
+
+lsp.Position toPosition(server.CharacterLocation location) {
+ // LSP is zero-based, but analysis server is 1-based.
+ return new lsp.Position(location.lineNumber - 1, location.columnNumber - 1);
+}
+
+lsp.Range toRange(server.LineInfo lineInfo, int offset, int length) {
+ server.CharacterLocation start = lineInfo.getLocation(offset);
+ server.CharacterLocation end = lineInfo.getLocation(offset + length);
+
+ return new lsp.Range(
+ toPosition(start),
+ toPosition(end),
+ );
+}
+
+lsp.SignatureHelp toSignatureHelp(List<lsp.MarkupKind> preferredFormats,
+ server.AnalysisGetSignatureResult signature) {
+ // For now, we only support returning one (though we may wish to use named
+ // args. etc. to provide one for each possible "next" option when the cursor
+ // is at the end ready to provide another argument).
+
+ /// Gets the label for an individual parameter in the form
+ /// String s = 'foo'
+ String getParamLabel(server.ParameterInfo p) {
+ final def = p.defaultValue != null ? ' = ${p.defaultValue}' : '';
+ return '${p.type} ${p.name}$def';
+ }
+
+ /// Gets the full signature label in the form
+ /// foo(String s, int i, bool a = true)
+ String getSignatureLabel(server.AnalysisGetSignatureResult resp) {
+ final req = signature.parameters
+ .where((p) => p.kind == server.ParameterKind.REQUIRED)
+ .toList();
+ final opt = signature.parameters
+ .where((p) => p.kind == server.ParameterKind.OPTIONAL)
+ .toList();
+ final named = signature.parameters
+ .where((p) => p.kind == server.ParameterKind.NAMED)
+ .toList();
+ final params = [];
+ if (req.isNotEmpty) {
+ params.add(req.map(getParamLabel).join(", "));
+ }
+ if (opt.isNotEmpty) {
+ params.add("[" + opt.map(getParamLabel).join(", ") + "]");
+ }
+ if (named.isNotEmpty) {
+ params.add("{" + named.map(getParamLabel).join(", ") + "}");
+ }
+ return '${resp.name}(${params.join(", ")})';
+ }
+
+ lsp.ParameterInformation toParameterInfo(server.ParameterInfo param) {
+ return new lsp.ParameterInformation(getParamLabel(param), null);
+ }
+
+ final cleanDoc = cleanDartdoc(signature.dartdoc);
+
+ return new lsp.SignatureHelp(
+ [
+ new lsp.SignatureInformation(
+ getSignatureLabel(signature),
+ asStringOrMarkupContent(preferredFormats, cleanDoc),
+ signature.parameters.map(toParameterInfo).toList(),
+ ),
+ ],
+ 0, // activeSignature
+ null, // activeParameter
+ );
+}
+
+lsp.MarkupContent _asMarkup(
+ List<lsp.MarkupKind> preferredFormats, String content) {
+ // It's not valid to call this function with a null format, as null formats
+ // do not support MarkupContent. [asStringOrMarkupContent] is probably the
+ // better choice.
+ assert(preferredFormats != null);
+
+ if (content == null) {
+ return null;
+ }
+
+ if (preferredFormats.isEmpty) {
+ preferredFormats.add(lsp.MarkupKind.Markdown);
+ }
+
+ final supportsMarkdown = preferredFormats.contains(lsp.MarkupKind.Markdown);
+ final supportsPlain = preferredFormats.contains(lsp.MarkupKind.PlainText);
+ // Since our PlainText version is actually just Markdown, only advertise it
+ // as PlainText if the client explicitly supports PlainText and not Markdown.
+ final format = supportsPlain && !supportsMarkdown
+ ? lsp.MarkupKind.PlainText
+ : lsp.MarkupKind.Markdown;
+
+ return new lsp.MarkupContent(format, content);
+}
diff --git a/pkg/analysis_server/lib/src/lsp/source_edits.dart b/pkg/analysis_server/lib/src/lsp/source_edits.dart
new file mode 100644
index 0000000..200ac92
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/source_edits.dart
@@ -0,0 +1,61 @@
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/lsp/mapping.dart';
+import 'package:analyzer/source/line_info.dart';
+import 'package:dart_style/dart_style.dart';
+
+final DartFormatter formatter = new DartFormatter();
+
+ErrorOr<String> applyEdits(
+ String oldContent, List<TextDocumentContentChangeEvent> changes) {
+ String newContent = oldContent;
+ for (var change in changes) {
+ if (change.range == null && change.rangeLength == null) {
+ newContent = change.text;
+ } else {
+ final lines = LineInfo.fromContent(newContent);
+ final offsetStart = toOffset(lines, change.range.start);
+ final offsetEnd = toOffset(lines, change.range.end);
+ if (offsetStart.isError) {
+ return new ErrorOr<String>.error(offsetStart.error);
+ }
+ if (offsetEnd.isError) {
+ return new ErrorOr<String>.error(offsetEnd.error);
+ }
+ newContent = newContent.replaceRange(
+ offsetStart.result, offsetEnd.result, change.text);
+ }
+ }
+ return new ErrorOr<String>.success(newContent);
+}
+
+List<TextEdit> generateEditsForFormatting(String unformattedSource) {
+ final lineInfo = new LineInfo.fromContent(unformattedSource);
+ final code =
+ new SourceCode(unformattedSource, uri: null, isCompilationUnit: true);
+ SourceCode formattedResult;
+ try {
+ formattedResult = formatter.formatSource(code);
+ } on FormatterException {
+ // If the document fails to parse, just return no edits to avoid the the
+ // use seeing edits on every save with invalid code (if LSP gains the
+ // ability to pass a context to know if the format was manually invoked
+ // we may wish to change this to return an error for that case).
+ return null;
+ }
+ final formattedSource = formattedResult.text;
+
+ if (formattedSource == unformattedSource) {
+ return null;
+ }
+
+ // We don't currently support returning "minimal" edits, we just replace
+ // entire document.
+ final end = lineInfo.getLocation(unformattedSource.length);
+ return [
+ new TextEdit(
+ new Range(new Position(0, 0), toPosition(end)),
+ formattedSource,
+ )
+ ];
+}
diff --git a/pkg/analysis_server/lib/src/operation/operation_analysis.dart b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
index 32b9153..9943cbd 100644
--- a/pkg/analysis_server/lib/src/operation/operation_analysis.dart
+++ b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
@@ -27,7 +27,7 @@
return;
}
for (String file in files) {
- CompilationUnit unit = server.getCachedAnalysisResult(file)?.unit;
+ CompilationUnit unit = server.getCachedResolvedUnit(file)?.unit;
CompilationUnitElement unitElement = unit?.declaredElement;
if (unitElement != null) {
try {
diff --git a/pkg/analysis_server/lib/src/plugin/plugin_manager.dart b/pkg/analysis_server/lib/src/plugin/plugin_manager.dart
index 6f95fd4a..63be71f 100644
--- a/pkg/analysis_server/lib/src/plugin/plugin_manager.dart
+++ b/pkg/analysis_server/lib/src/plugin/plugin_manager.dart
@@ -12,11 +12,11 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/src/context/context_root.dart' as analyzer;
-import 'package:analyzer/src/generated/bazel.dart';
-import 'package:analyzer/src/generated/gn.dart';
import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/workspace.dart';
import 'package:analyzer/src/util/glob.dart';
+import 'package:analyzer/src/workspace/bazel.dart';
+import 'package:analyzer/src/workspace/gn.dart';
+import 'package:analyzer/src/workspace/workspace.dart';
import 'package:analyzer_plugin/channel/channel.dart';
import 'package:analyzer_plugin/protocol/protocol.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
diff --git a/pkg/analysis_server/lib/src/plugin/result_collector.dart b/pkg/analysis_server/lib/src/plugin/result_collector.dart
index c2e3274..04c3f09 100644
--- a/pkg/analysis_server/lib/src/plugin/result_collector.dart
+++ b/pkg/analysis_server/lib/src/plugin/result_collector.dart
@@ -30,7 +30,7 @@
* the plugin that provided the partial results. The value is the partial
* results contributed by the plugin for the file.
*/
- Map<String, Map<String, E>> resultMap = <String, Map<String, E>>{};
+ final Map<String, Map<String, E>> resultMap = <String, Map<String, E>>{};
/**
* Initialize a newly created result manager.
diff --git a/pkg/analysis_server/lib/src/protocol_server.dart b/pkg/analysis_server/lib/src/protocol_server.dart
index 9ff7232..fc2d22a 100644
--- a/pkg/analysis_server/lib/src/protocol_server.dart
+++ b/pkg/analysis_server/lib/src/protocol_server.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -35,7 +35,21 @@
engine.AnalysisOptions analysisOptions,
engine.LineInfo lineInfo,
List<engine.AnalysisError> errors) {
- List<AnalysisError> serverErrors = <AnalysisError>[];
+ return mapEngineErrors(
+ analysisOptions, lineInfo, errors, newAnalysisError_fromEngine);
+}
+
+/**
+ * Translates engine errors through the ErrorProcessor.
+ */
+List<T> mapEngineErrors<T>(
+ engine.AnalysisOptions analysisOptions,
+ engine.LineInfo lineInfo,
+ List<engine.AnalysisError> errors,
+ T Function(engine.LineInfo lineInfo, engine.AnalysisError error,
+ [engine.ErrorSeverity errorSeverity])
+ constructor) {
+ List<T> serverErrors = <T>[];
for (engine.AnalysisError error in errors) {
ErrorProcessor processor =
ErrorProcessor.getProcessor(analysisOptions, error);
@@ -44,11 +58,10 @@
// Errors with null severity are filtered out.
if (severity != null) {
// Specified severities override.
- serverErrors
- .add(newAnalysisError_fromEngine(lineInfo, error, severity));
+ serverErrors.add(constructor(lineInfo, error, severity));
}
} else {
- serverErrors.add(newAnalysisError_fromEngine(lineInfo, error));
+ serverErrors.add(constructor(lineInfo, error));
}
}
return serverErrors;
@@ -163,7 +176,7 @@
*/
Location newLocation_fromNode(engine.AstNode node) {
engine.CompilationUnit unit =
- node.getAncestor((node) => node is engine.CompilationUnit);
+ node.thisOrAncestorOfType<engine.CompilationUnit>();
engine.CompilationUnitElement unitElement = unit.declaredElement;
engine.SourceRange range = new engine.SourceRange(node.offset, node.length);
return _locationForArgs(unitElement, range);
diff --git a/pkg/analysis_server/lib/src/provisional/completion/completion_core.dart b/pkg/analysis_server/lib/src/provisional/completion/completion_core.dart
index f100d1e..2d6adce 100644
--- a/pkg/analysis_server/lib/src/provisional/completion/completion_core.dart
+++ b/pkg/analysis_server/lib/src/provisional/completion/completion_core.dart
@@ -4,8 +4,8 @@
import 'dart:async';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
@@ -53,7 +53,7 @@
* The analysis result for the file in which the completion is being
* requested.
*/
- AnalysisResult get result;
+ ResolvedUnitResult get result;
/**
* Return the source in which the completion is being requested.
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index de0500c..3f6e67d 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.dart
@@ -9,10 +9,13 @@
import 'package:analysis_server/protocol/protocol_constants.dart'
show PROTOCOL_VERSION;
import 'package:analysis_server/src/analysis_server.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+import 'package:analysis_server/src/lsp/lsp_socket_server.dart';
import 'package:analysis_server/src/server/detachable_filesystem_manager.dart';
import 'package:analysis_server/src/server/dev_server.dart';
import 'package:analysis_server/src/server/diagnostic_server.dart';
import 'package:analysis_server/src/server/http_server.dart';
+import 'package:analysis_server/src/server/lsp_stdio_server.dart';
import 'package:analysis_server/src/server/stdio_server.dart';
import 'package:analysis_server/src/services/completion/dart/uri_contributor.dart'
show UriContributor;
@@ -263,6 +266,11 @@
static const String USE_FASTA_PARSER = "use-fasta-parser";
/**
+ * The name of the flag to use the Language Server Protocol (LSP).
+ */
+ static const String USE_LSP = "lsp";
+
+ /**
* A directory to analyze in order to train an analysis server snapshot.
*/
static const String TRAIN_USING = "train-using";
@@ -303,20 +311,14 @@
*/
DetachableFileSystemManager detachableFileSystemManager;
- SocketServer socketServer;
-
HttpAnalysisServer httpServer;
Driver();
/**
* Use the given command-line [arguments] to start this server.
- *
- * At least temporarily returns AnalysisServer so that consumers of the
- * starter API can then use the server, this is done as a stopgap for the
- * angular plugin until the official plugin API is finished.
*/
- AnalysisServer start(List<String> arguments) {
+ void start(List<String> arguments) {
CommandLineParser parser = _createArgParser();
ArgResults results = parser.parse(arguments, <String, String>{});
@@ -330,6 +332,7 @@
analysisServerOptions.clientVersion = results[CLIENT_VERSION];
analysisServerOptions.cacheFolder = results[CACHE_FOLDER];
analysisServerOptions.useFastaParser = results[USE_FASTA_PARSER];
+ analysisServerOptions.useLanguageServerProtocol = results[USE_LSP];
analysisServerOptions.enableUXExperiment1 = results[UX_EXPERIMENT_1];
analysisServerOptions.enableUXExperiment2 = results[UX_EXPERIMENT_2];
@@ -372,6 +375,54 @@
return null;
}
+ final defaultSdkPath = _getSdkPath(results);
+ final dartSdkManager = new DartSdkManager(defaultSdkPath, true);
+
+ // TODO(brianwilkerson) It would be nice to avoid creating an SDK that
+ // cannot be re-used, but the SDK is needed to create a package map provider
+ // in the case where we need to run `pub` in order to get the package map.
+ DartSdk defaultSdk = _createDefaultSdk(defaultSdkPath, true);
+ //
+ // Initialize the instrumentation service.
+ //
+ String logFilePath = results[INSTRUMENTATION_LOG_FILE];
+ if (logFilePath != null) {
+ _rollLogFiles(logFilePath, 5);
+ FileInstrumentationServer fileBasedServer =
+ new FileInstrumentationServer(logFilePath);
+ instrumentationServer = instrumentationServer != null
+ ? new MulticastInstrumentationServer(
+ [instrumentationServer, fileBasedServer])
+ : fileBasedServer;
+ }
+ InstrumentationService instrumentationService =
+ new InstrumentationService(instrumentationServer);
+ instrumentationService.logVersion(
+ results[TRAIN_USING] != null
+ ? 'training-0'
+ : _readUuid(instrumentationService),
+ analysisServerOptions.clientId,
+ analysisServerOptions.clientVersion,
+ PROTOCOL_VERSION,
+ defaultSdk.sdkVersion);
+ AnalysisEngine.instance.instrumentationService = instrumentationService;
+
+ if (analysisServerOptions.useLanguageServerProtocol) {
+ startLspServer(results, analysisServerOptions, dartSdkManager,
+ instrumentationService);
+ } else {
+ startAnalysisServer(results, analysisServerOptions, parser,
+ dartSdkManager, instrumentationService, analytics);
+ }
+ }
+
+ void startAnalysisServer(
+ ArgResults results,
+ AnalysisServerOptions analysisServerOptions,
+ CommandLineParser parser,
+ DartSdkManager dartSdkManager,
+ InstrumentationService instrumentationService,
+ telemetry.Analytics analytics) {
String trainDirectory = results[TRAIN_USING];
if (trainDirectory != null) {
if (!FileSystemEntity.isDirectorySync(trainDirectory)) {
@@ -403,45 +454,6 @@
manager.processPlugins(AnalysisEngine.instance.requiredPlugins);
linter.registerLintRules();
- String defaultSdkPath;
- if (results[SDK_OPTION] != null) {
- defaultSdkPath = results[SDK_OPTION];
- } else {
- // No path to the SDK was provided.
- // Use FolderBasedDartSdk.defaultSdkDirectory, which will make a guess.
- defaultSdkPath = FolderBasedDartSdk.defaultSdkDirectory(
- PhysicalResourceProvider.INSTANCE)
- .path;
- }
- // TODO(brianwilkerson) It would be nice to avoid creating an SDK that
- // cannot be re-used, but the SDK is needed to create a package map provider
- // in the case where we need to run `pub` in order to get the package map.
- DartSdk defaultSdk = _createDefaultSdk(defaultSdkPath, true);
- //
- // Initialize the instrumentation service.
- //
- String logFilePath = results[INSTRUMENTATION_LOG_FILE];
- if (logFilePath != null) {
- _rollLogFiles(logFilePath, 5);
- FileInstrumentationServer fileBasedServer =
- new FileInstrumentationServer(logFilePath);
- instrumentationServer = instrumentationServer != null
- ? new MulticastInstrumentationServer(
- [instrumentationServer, fileBasedServer])
- : fileBasedServer;
- }
- InstrumentationService instrumentationService =
- new InstrumentationService(instrumentationServer);
- instrumentationService.logVersion(
- trainDirectory != null
- ? 'training-0'
- : _readUuid(instrumentationService),
- analysisServerOptions.clientId,
- analysisServerOptions.clientVersion,
- PROTOCOL_VERSION,
- defaultSdk.sdkVersion);
- AnalysisEngine.instance.instrumentationService = instrumentationService;
-
_DiagnosticServerImpl diagnosticServer = new _DiagnosticServerImpl();
// Ping analytics with our initial call.
@@ -450,9 +462,9 @@
//
// Create the sockets and start listening for requests.
//
- socketServer = new SocketServer(
+ final socketServer = new SocketServer(
analysisServerOptions,
- new DartSdkManager(defaultSdkPath, true),
+ dartSdkManager,
instrumentationService,
diagnosticServer,
fileResolverProvider,
@@ -502,7 +514,7 @@
exit(exitCode);
}();
} else {
- _captureExceptions(instrumentationService, () {
+ _captureExceptions(socketServer, instrumentationService, () {
StdioAnalysisServer stdioServer = new StdioAnalysisServer(socketServer);
stdioServer.serveStdio().then((_) async {
// TODO(brianwilkerson) Determine whether this await is necessary.
@@ -520,8 +532,28 @@
? null
: httpServer.recordPrint);
}
+ }
- return socketServer.analysisServer;
+ void startLspServer(
+ ArgResults args,
+ AnalysisServerOptions analysisServerOptions,
+ DartSdkManager dartSdkManager,
+ InstrumentationService instrumentationService,
+ ) {
+ final socketServer = new LspSocketServer(
+ analysisServerOptions,
+ dartSdkManager,
+ instrumentationService,
+ );
+
+ _captureLspExceptions(socketServer, instrumentationService, () {
+ LspStdioAnalysisServer stdioServer =
+ new LspStdioAnalysisServer(socketServer);
+ stdioServer.serveStdio().then((_) async {
+ socketServer.analysisServer.shutdown();
+ exit(0);
+ });
+ });
}
/**
@@ -530,13 +562,13 @@
* instrumentation [service]. If a [print] function is provided, then also
* capture any data printed by the callback and redirect it to the function.
*/
- dynamic _captureExceptions(InstrumentationService service, dynamic callback(),
+ dynamic _captureExceptions(SocketServer socketServer,
+ InstrumentationService service, dynamic callback(),
{void print(String line)}) {
void errorFunction(Zone self, ZoneDelegate parent, Zone zone,
dynamic exception, StackTrace stackTrace) {
service.logPriorityException(exception, stackTrace);
- AnalysisServer analysisServer = socketServer.analysisServer;
- analysisServer.sendServerErrorNotification(
+ socketServer.analysisServer.sendServerErrorNotification(
'Captured exception', exception, stackTrace);
throw exception;
}
@@ -554,6 +586,33 @@
}
/**
+ * Execute the given [callback] within a zone that will capture any unhandled
+ * exceptions and both report them to the client and send them to the given
+ * instrumentation [service]. If a [print] function is provided, then also
+ * capture any data printed by the callback and redirect it to the function.
+ */
+ dynamic _captureLspExceptions(
+ // TODO(dantup): This is a copy/paste of the above with some minor changes.
+ // We should either factor these out, or if we end up with an LspDriver, put
+ // this there.
+ LspSocketServer socketServer,
+ InstrumentationService service,
+ dynamic callback()) {
+ void errorFunction(Zone self, ZoneDelegate parent, Zone zone,
+ dynamic exception, StackTrace stackTrace) {
+ service.logPriorityException(exception, stackTrace);
+ LspAnalysisServer analysisServer = socketServer.analysisServer;
+ analysisServer.sendServerErrorNotification(
+ 'Captured exception', exception, stackTrace);
+ throw exception;
+ }
+
+ ZoneSpecification zoneSpecification =
+ new ZoneSpecification(handleUncaughtError: errorFunction);
+ return runZoned(callback, zoneSpecification: zoneSpecification);
+ }
+
+ /**
* Create and return the parser used to parse the command-line arguments.
*/
CommandLineParser _createArgParser() {
@@ -615,6 +674,8 @@
parser.addFlag(USE_FASTA_PARSER,
defaultsTo: true,
help: "Whether to enable parsing via the Fasta parser");
+ parser.addFlag(USE_LSP,
+ defaultsTo: false, help: "Whether to use the Language Server Protocol");
parser.addOption(TRAIN_USING,
help: "Pass in a directory to analyze for purposes of training an "
"analysis server snapshot.");
@@ -641,6 +702,18 @@
return sdk;
}
+ String _getSdkPath(ArgResults args) {
+ if (args[SDK_OPTION] != null) {
+ return args[SDK_OPTION];
+ } else {
+ // No path to the SDK was provided.
+ // Use FolderBasedDartSdk.defaultSdkDirectory, which will make a guess.
+ return FolderBasedDartSdk.defaultSdkDirectory(
+ PhysicalResourceProvider.INSTANCE,
+ ).path;
+ }
+ }
+
/**
* Print information about how to use the server.
*/
diff --git a/pkg/analysis_server/lib/src/server/lsp_stdio_server.dart b/pkg/analysis_server/lib/src/server/lsp_stdio_server.dart
new file mode 100644
index 0000000..016bd11
--- /dev/null
+++ b/pkg/analysis_server/lib/src/server/lsp_stdio_server.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2018, 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 'dart:io';
+
+import 'package:analysis_server/src/lsp/channel/lsp_byte_stream_channel.dart';
+import 'package:analysis_server/src/lsp/lsp_socket_server.dart';
+
+/**
+ * Instances of the class [StdioServer] implement a simple server operating
+ * over standard input and output. The primary responsibility of this server
+ * is to split incoming messages on newlines and pass them along to the
+ * analysis server.
+ */
+class LspStdioAnalysisServer {
+ /**
+ * An object that can handle either a WebSocket connection or a connection
+ * to the client over stdio.
+ */
+ LspSocketServer socketServer;
+
+ /**
+ * Initialize a newly created stdio server.
+ */
+ LspStdioAnalysisServer(this.socketServer);
+
+ /**
+ * Begin serving requests over stdio.
+ *
+ * Return a future that will be completed when stdin closes.
+ */
+ Future serveStdio() {
+ LspByteStreamServerChannel serverChannel = new LspByteStreamServerChannel(
+ stdin, stdout, socketServer.instrumentationService);
+ socketServer.createAnalysisServer(serverChannel);
+ return serverChannel.closed;
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/completion_core.dart b/pkg/analysis_server/lib/src/services/completion/completion_core.dart
index 1403f86..02e617b 100644
--- a/pkg/analysis_server/lib/src/services/completion/completion_core.dart
+++ b/pkg/analysis_server/lib/src/services/completion/completion_core.dart
@@ -4,8 +4,8 @@
import 'package:analysis_server/src/provisional/completion/completion_core.dart';
import 'package:analysis_server/src/services/completion/completion_performance.dart';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/generated/source.dart';
/**
@@ -13,7 +13,7 @@
*/
class CompletionRequestImpl implements CompletionRequest {
@override
- final AnalysisResult result;
+ final ResolvedUnitResult result;
@override
final int offset;
diff --git a/pkg/analysis_server/lib/src/services/completion/completion_performance.dart b/pkg/analysis_server/lib/src/services/completion/completion_performance.dart
index 24b952f..37ee54e 100644
--- a/pkg/analysis_server/lib/src/services/completion/completion_performance.dart
+++ b/pkg/analysis_server/lib/src/services/completion/completion_performance.dart
@@ -25,11 +25,6 @@
int get elapsedInMilliseconds =>
operations.length > 0 ? operations.last.elapsed.inMilliseconds : 0;
- int get firstNotificationInMilliseconds =>
- _firstNotification != null ? _firstNotification.inMilliseconds : 0;
-
- String get startTimeAndMs => '${start.millisecondsSinceEpoch} - $start';
-
String get suggestionCount {
if (notificationCount < 1) return '';
if (notificationCount == 1) return '$suggestionCountFirst';
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
index 18ba66b..fc4e494 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -27,7 +27,7 @@
}
// Build list of suggestions
- var directive = node.getAncestor((parent) => parent is NamespaceDirective);
+ var directive = node.thisOrAncestorOfType<NamespaceDirective>();
if (directive is NamespaceDirective) {
LibraryElement library = directive.uriElement;
if (library != null) {
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
index 306c6b3..fe34f79 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
@@ -29,11 +29,12 @@
import 'package:analysis_server/src/services/completion/dart/type_member_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/uri_contributor.dart';
import 'package:analysis_server/src/services/completion/dart/variable_name_contributor.dart';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
import 'package:analyzer/src/generated/engine.dart' hide AnalysisResult;
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/task/api/model.dart';
@@ -178,7 +179,7 @@
*/
class DartCompletionRequestImpl implements DartCompletionRequest {
@override
- final AnalysisResult result;
+ final ResolvedUnitResult result;
@override
final ResourceProvider resourceProvider;
@@ -249,7 +250,10 @@
String get sourceContents => result.content;
@override
- SourceFactory get sourceFactory => result.sourceFactory;
+ SourceFactory get sourceFactory {
+ DriverBasedAnalysisContext context = result.session.analysisContext;
+ return context.driver.sourceFactory;
+ }
/**
* Throw [AbortCompletion] if the completion request has been aborted.
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart
index 2a45ee0..64ed46a 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -28,7 +28,7 @@
// If this is a constructor declaration
// then compute fields already referenced
ConstructorDeclaration constructorDecl =
- node.getAncestor((p) => p is ConstructorDeclaration);
+ node.thisOrAncestorOfType<ConstructorDeclaration>();
if (constructorDecl == null) {
return const <CompletionSuggestion>[];
}
@@ -53,7 +53,7 @@
// Add suggestions for fields that are not already referenced
ClassDeclaration classDecl =
- constructorDecl.getAncestor((p) => p is ClassDeclaration);
+ constructorDecl.thisOrAncestorOfType<ClassDeclaration>();
List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
for (ClassMember member in classDecl.members) {
if (member is FieldDeclaration && !member.isStatic) {
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
index 1db3c05..64bac8e 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -329,7 +329,7 @@
@override
visitFormalParameterList(FormalParameterList node) {
AstNode constructorDeclaration =
- node.getAncestor((p) => p is ConstructorDeclaration);
+ node.thisOrAncestorOfType<ConstructorDeclaration>();
if (constructorDeclaration != null) {
_addSuggestions([Keyword.THIS]);
}
@@ -746,21 +746,21 @@
}
bool _inAsyncMethodOrFunction(AstNode node) {
- FunctionBody body = node.getAncestor((n) => n is FunctionBody);
+ FunctionBody body = node.thisOrAncestorOfType<FunctionBody>();
return body != null && body.isAsynchronous && body.star == null;
}
bool _inAsyncStarOrSyncStarMethodOrFunction(AstNode node) {
- FunctionBody body = node.getAncestor((n) => n is FunctionBody);
+ FunctionBody body = node.thisOrAncestorOfType<FunctionBody>();
return body != null && body.keyword != null && body.star != null;
}
bool _inCatchClause(Block node) =>
- node.getAncestor((p) => p is CatchClause) != null;
+ node.thisOrAncestorOfType<CatchClause>() != null;
bool _inClassMemberBody(AstNode node) {
while (true) {
- AstNode body = node.getAncestor((n) => n is FunctionBody);
+ AstNode body = node.thisOrAncestorOfType<FunctionBody>();
if (body == null) {
return false;
}
@@ -773,23 +773,24 @@
}
bool _inDoLoop(AstNode node) =>
- node.getAncestor((p) => p is DoStatement) != null;
+ node.thisOrAncestorOfType<DoStatement>() != null;
bool _inForLoop(AstNode node) =>
- node.getAncestor((p) => p is ForStatement || p is ForEachStatement) !=
+ node.thisOrAncestorMatching(
+ (p) => p is ForStatement || p is ForEachStatement) !=
null;
bool _inLoop(AstNode node) =>
_inDoLoop(node) || _inForLoop(node) || _inWhileLoop(node);
bool _inSwitch(AstNode node) =>
- node.getAncestor((p) => p is SwitchStatement) != null;
+ node.thisOrAncestorOfType<SwitchStatement>() != null;
bool _inWhileLoop(AstNode node) =>
- node.getAncestor((p) => p is WhileStatement) != null;
+ node.thisOrAncestorOfType<WhileStatement>() != null;
bool _isEntityAfterIfWithoutElse(AstNode node) {
- Block block = node?.getAncestor((n) => n is Block);
+ Block block = node?.thisOrAncestorOfType<Block>();
if (block == null) {
return false;
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart
index 4dead0e..d580fcd 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart
@@ -91,6 +91,11 @@
}
@override
+ void declaredGenericTypeAlias(GenericTypeAlias declaration) {
+ // ignored
+ }
+
+ @override
void declaredLabel(Label label, bool isCaseLabel) {
if (isCaseLabel ? includeCaseLabels : includeStatementLabels) {
CompletionSuggestion suggestion = _addSuggestion(label.label);
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart
index aeda775..4d8b351 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart
@@ -84,6 +84,9 @@
void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {}
@override
+ void declaredGenericTypeAlias(GenericTypeAlias declaration) {}
+
+ @override
void declaredLabel(Label label, bool isCaseLabel) {}
@override
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
index cee82af..66a5fc6 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
@@ -226,6 +226,20 @@
}
@override
+ void declaredGenericTypeAlias(GenericTypeAlias declaration) {
+ if (optype.includeTypeNameSuggestions) {
+ // TODO (danrubel) determine parameters and return type
+ _addLocalSuggestion_includeTypeNameSuggestions(
+ declaration.documentationComment,
+ declaration.name,
+ declaration.functionType.returnType,
+ protocol.ElementKind.FUNCTION_TYPE_ALIAS,
+ isAbstract: true,
+ isDeprecated: isDeprecated(declaration));
+ }
+ }
+
+ @override
void declaredLabel(Label label, bool isCaseLabel) {
// ignored
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
index 34d1ffb..8bee14b2 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
@@ -9,10 +9,10 @@
import 'package:analysis_server/src/protocol_server.dart' as protocol
hide CompletionSuggestion, CompletionSuggestionKind;
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/element/inheritance_manager2.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
@@ -34,13 +34,15 @@
return const <CompletionSuggestion>[];
}
ClassDeclaration classDecl =
- targetId.getAncestor((p) => p is ClassDeclaration);
+ targetId.thisOrAncestorOfType<ClassDeclaration>();
if (classDecl == null) {
return const <CompletionSuggestion>[];
}
+ // TODO(brianwilkerson) Consider making the type system visible from the
+ // request.result.
var inheritance = new InheritanceManager2(
- request.result.libraryElement.context.typeSystem);
+ await request.result.libraryElement.session.typeSystem);
// Generate a collection of inherited members
ClassElement classElem = classDecl.declaredElement;
@@ -68,14 +70,13 @@
* the template will replace [targetId].
*/
Future<DartChangeBuilder> _buildReplacementText(
- AnalysisResult result,
+ ResolvedUnitResult result,
SimpleIdentifier targetId,
FunctionType signature,
StringBuffer displayTextBuffer) async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
- DartChangeBuilder builder =
- new DartChangeBuilder(result.driver.currentSession);
+ DartChangeBuilder builder = new DartChangeBuilder(result.session);
await builder.addFileEdit(result.path, (DartFileEditBuilder builder) {
builder.addReplacement(range.node(targetId), (DartEditBuilder builder) {
ExecutableElement element = signature.element;
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
index ef91fd7..e1ba6f9 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
@@ -110,9 +110,9 @@
}
/**
- * Common mixin for sharing behavior
+ * Common mixin for sharing behavior.
*/
-abstract class ElementSuggestionBuilder {
+mixin ElementSuggestionBuilder {
/**
* A collection of completion suggestions.
*/
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
index d0b3d04..a4e03b3 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
@@ -83,7 +83,7 @@
// Determine the name of the containing method because
// the most likely completion is a super expression with same name
MethodDeclaration containingMethod =
- expression.getAncestor((p) => p is MethodDeclaration);
+ expression.thisOrAncestorOfType<MethodDeclaration>();
if (containingMethod != null) {
SimpleIdentifier id = containingMethod.name;
if (id != null) {
@@ -174,6 +174,17 @@
}
@override
+ void declaredGenericTypeAlias(GenericTypeAlias declaration) {
+ if (declaration.name.name == targetName) {
+ TypeAnnotation typeName = declaration.functionType.returnType;
+ if (typeName != null) {
+ typeFound = typeName.type;
+ }
+ finished();
+ }
+ }
+
+ @override
void declaredLabel(Label label, bool isCaseLabel) {
if (label.label.name == targetName) {
// no type
diff --git a/pkg/analysis_server/lib/src/services/completion/postfix/postfix_completion.dart b/pkg/analysis_server/lib/src/services/completion/postfix/postfix_completion.dart
index 1a690a8..1c15d65 100644
--- a/pkg/analysis_server/lib/src/services/completion/postfix/postfix_completion.dart
+++ b/pkg/analysis_server/lib/src/services/completion/postfix/postfix_completion.dart
@@ -6,12 +6,11 @@
import 'package:analysis_server/src/protocol_server.dart' hide Element;
import 'package:analysis_server/src/services/correction/util.dart';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/error/error.dart' as engine;
-import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/generated/java_core.dart';
import 'package:analyzer/src/generated/resolver.dart';
@@ -256,21 +255,11 @@
* The context for computing a postfix completion.
*/
class PostfixCompletionContext {
- final String file;
- final LineInfo lineInfo;
+ final ResolvedUnitResult resolveResult;
final int selectionOffset;
final String key;
- final AnalysisDriver driver;
- final CompilationUnit unit;
- final CompilationUnitElement unitElement;
- final List<engine.AnalysisError> errors;
- PostfixCompletionContext(this.file, this.lineInfo, this.selectionOffset,
- this.key, this.driver, this.unit, this.unitElement, this.errors) {
- if (unitElement.context == null) {
- throw new Error(); // not reached
- }
- }
+ PostfixCompletionContext(this.resolveResult, this.selectionOffset, this.key);
}
/**
@@ -309,40 +298,25 @@
AstNode node;
PostfixCompletion completion;
SourceChange change = new SourceChange('postfix-completion');
- final Map<String, LinkedEditGroup> linkedPositionGroups =
- <String, LinkedEditGroup>{};
+ final Map<String, LinkedEditGroup> linkedPositionGroups = {};
Position exitPosition = null;
- TypeProvider _typeProvider;
PostfixCompletionProcessor(this.completionContext)
- : utils = new CorrectionUtils(completionContext.unit);
-
- AnalysisDriver get driver => completionContext.driver;
+ : utils = new CorrectionUtils(completionContext.resolveResult);
String get eol => utils.endOfLine;
- String get file => completionContext.file;
+ String get file => completionContext.resolveResult.path;
String get key => completionContext.key;
- LineInfo get lineInfo => completionContext.lineInfo;
+ LineInfo get lineInfo => completionContext.resolveResult.lineInfo;
int get selectionOffset => completionContext.selectionOffset;
- /**
- * Return the analysis session to be used to create the change builder.
- */
- AnalysisSession get session => driver.currentSession;
+ AnalysisSession get session => completionContext.resolveResult.session;
- Source get source => completionContext.unitElement.source;
-
- TypeProvider get typeProvider {
- return _typeProvider ??= unitElement.context.typeProvider;
- }
-
- CompilationUnit get unit => completionContext.unit;
-
- CompilationUnitElement get unitElement => completionContext.unitElement;
+ TypeProvider get typeProvider => completionContext.resolveResult.typeProvider;
Future<PostfixCompletion> compute() async {
// TODO(brianwilkerson) Determine whether this await is necessary.
@@ -591,7 +565,8 @@
}
AstNode _selectedNode({int at: null}) =>
- new NodeLocator(at == null ? selectionOffset : at).searchWithin(unit);
+ new NodeLocator(at == null ? selectionOffset : at)
+ .searchWithin(completionContext.resolveResult.unit);
void _setCompletionFromBuilder(
DartChangeBuilder builder, PostfixCompletionKind kind,
diff --git a/pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart b/pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart
index 929f1fe..303ddd5 100644
--- a/pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart
+++ b/pkg/analysis_server/lib/src/services/completion/statement/statement_completion.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// 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.
@@ -8,6 +8,7 @@
import 'package:analysis_server/src/protocol_server.dart' hide Element;
import 'package:analysis_server/src/services/correction/source_buffer.dart';
import 'package:analysis_server/src/services/correction/util.dart';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
@@ -81,19 +82,10 @@
* The context for computing a statement completion.
*/
class StatementCompletionContext {
- final String file;
- final LineInfo lineInfo;
+ final ResolvedUnitResult resolveResult;
final int selectionOffset;
- final CompilationUnit unit;
- final CompilationUnitElement unitElement;
- final List<engine.AnalysisError> errors;
- StatementCompletionContext(this.file, this.lineInfo, this.selectionOffset,
- this.unit, this.unitElement, this.errors) {
- if (unitElement.context == null) {
- throw new Error(); // not reached; see getStatementCompletion()
- }
- }
+ StatementCompletionContext(this.resolveResult, this.selectionOffset);
}
/**
@@ -143,21 +135,22 @@
Position exitPosition = null;
StatementCompletionProcessor(this.statementContext)
- : utils = new CorrectionUtils(statementContext.unit);
+ : utils = new CorrectionUtils(statementContext.resolveResult);
String get eol => utils.endOfLine;
- String get file => statementContext.file;
+ String get file => statementContext.resolveResult.path;
- LineInfo get lineInfo => statementContext.lineInfo;
+ LineInfo get lineInfo => statementContext.resolveResult.lineInfo;
int get selectionOffset => statementContext.selectionOffset;
- Source get source => statementContext.unitElement.source;
+ Source get source => unitElement.source;
- CompilationUnit get unit => statementContext.unit;
+ CompilationUnit get unit => statementContext.resolveResult.unit;
- CompilationUnitElement get unitElement => statementContext.unitElement;
+ CompilationUnitElement get unitElement =>
+ statementContext.resolveResult.unit.declaredElement;
Future<StatementCompletion> compute() async {
// TODO(brianwilkerson) Determine whether this await is necessary.
@@ -166,8 +159,8 @@
if (node == null) {
return NO_COMPLETION;
}
- node = node
- .getAncestor((n) => n is Statement || _isNonStatementDeclaration(n));
+ node = node.thisOrAncestorMatching(
+ (n) => n is Statement || _isNonStatementDeclaration(n));
if (node == null) {
return _complete_simpleEnter() ? completion : NO_COMPLETION;
}
@@ -180,7 +173,7 @@
if (_isEmptyStatementOrEmptyBlock(node)) {
node = node.parent;
}
- for (engine.AnalysisError error in statementContext.errors) {
+ for (engine.AnalysisError error in statementContext.resolveResult.errors) {
if (error.offset >= node.offset && error.offset <= node.end) {
if (error.errorCode is! HintCode) {
errors.add(error);
@@ -282,7 +275,7 @@
return null;
}
AstNode expr = _selectedNode();
- return (expr.getAncestor((n) => n is StringInterpolation) == null)
+ return (expr.thisOrAncestorOfType<StringInterpolation>() == null)
? expr
: null;
}
@@ -319,7 +312,7 @@
expr = errorMatching(ParserErrorCode.EXPECTED_TOKEN, partialMatch: "']'") ??
errorMatching(ScannerErrorCode.EXPECTED_TOKEN, partialMatch: "']'");
if (expr != null) {
- expr = expr.getAncestor((n) => n is ListLiteral);
+ expr = expr.thisOrAncestorOfType<ListLiteral>();
if (expr != null) {
ListLiteral lit = expr;
if (lit.rightBracket.isSynthetic) {
@@ -861,13 +854,13 @@
if (parenError == null) {
return false;
}
- AstNode argList = _selectedNode(at: selectionOffset)
- .getAncestor((n) => n is ArgumentList);
+ AstNode argList =
+ _selectedNode(at: selectionOffset).thisOrAncestorOfType<ArgumentList>();
if (argList == null) {
argList = _selectedNode(at: parenError.offset)
- .getAncestor((n) => n is ArgumentList);
+ .thisOrAncestorOfType<ArgumentList>();
}
- if (argList?.getAncestor((n) => n == node) == null) {
+ if (argList?.thisOrAncestorMatching((n) => n == node) == null) {
return false;
}
int previousInsertions = _lengthOfInsertions();
@@ -1107,31 +1100,12 @@
orElse: () => null);
}
- LinkedEditGroup _getLinkedPosition(String groupId) {
- LinkedEditGroup group = linkedPositionGroups[groupId];
- if (group == null) {
- group = new LinkedEditGroup.empty();
- linkedPositionGroups[groupId] = group;
- }
- return group;
- }
-
void _insertBuilder(SourceBuilder builder, [int length = 0]) {
{
SourceRange range = new SourceRange(builder.offset, length);
String text = builder.toString();
_addReplaceEdit(range, text);
}
- // add linked positions
- builder.linkedPositionGroups.forEach((String id, LinkedEditGroup group) {
- LinkedEditGroup fixGroup = _getLinkedPosition(id);
- group.positions.forEach((Position position) {
- fixGroup.addPosition(position, group.length);
- });
- group.suggestions.forEach((LinkedEditSuggestion suggestion) {
- fixGroup.addSuggestion(suggestion);
- });
- });
// add exit position
{
int exitOffset = builder.exitOffset;
diff --git a/pkg/analysis_server/lib/src/services/correction/assist.dart b/pkg/analysis_server/lib/src/services/correction/assist.dart
index 772299c..0d09721 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist.dart
@@ -2,9 +2,28 @@
// 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/plugin/edit/assist/assist_dart.dart';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer_plugin/utilities/assist/assist.dart';
/**
+ * The implementation of [DartAssistContext].
+ */
+class DartAssistContextImpl implements DartAssistContext {
+ @override
+ final ResolvedUnitResult resolveResult;
+
+ @override
+ final int selectionOffset;
+
+ @override
+ final int selectionLength;
+
+ DartAssistContextImpl(
+ this.resolveResult, this.selectionOffset, this.selectionLength);
+}
+
+/**
* An enumeration of possible assist kinds.
*/
class DartAssistKind {
@@ -28,10 +47,10 @@
'dart.assist.convert.bodyToBlock', 30, "Convert to block body");
static const CONVERT_INTO_EXPRESSION_BODY = const AssistKind(
'dart.assist.convert.bodyToExpression', 30, "Convert to expression body");
- static const CONVERT_INTO_FOR_INDEX = const AssistKind(
- 'dart.assist.convert.forEachToForIndex', 30, "Convert to for-index loop");
static const CONVERT_INTO_FINAL_FIELD = const AssistKind(
'dart.assist.convert.getterToFinalField', 30, "Convert to final field");
+ static const CONVERT_INTO_FOR_INDEX = const AssistKind(
+ 'dart.assist.convert.forEachToForIndex', 30, "Convert to for-index loop");
static const CONVERT_INTO_GENERIC_FUNCTION_SYNTAX = const AssistKind(
'dart.assist.convert.toGenericFunctionSyntax',
30,
@@ -96,6 +115,8 @@
const AssistKind('dart.assist.flutter.wrap.padding', 30, "Add padding");
static const FLUTTER_WRAP_ROW =
const AssistKind('dart.assist.flutter.wrap.row', 30, "Wrap with Row");
+ static const FLUTTER_WRAP_STREAM_BUILDER = const AssistKind(
+ 'dart.assist.flutter.wrap.streamBuilder', 30, "Wrap with StreamBuilder");
static const IMPORT_ADD_SHOW = const AssistKind(
'dart.assist.addShowCombinator', 30, "Add explicit 'show' combinator");
static const INTRODUCE_LOCAL_CAST_TYPE = const AssistKind(
diff --git a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
index b9a6be5..b9616861 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -16,12 +16,10 @@
import 'package:analysis_server/src/utilities/flutter.dart' as flutter;
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/standard_resolution_map.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/session_helper.dart';
import 'package:analyzer/src/dart/ast/token.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
@@ -42,73 +40,36 @@
* The computer for Dart assists.
*/
class AssistProcessor {
- /**
- * The analysis driver being used to perform analysis.
- */
- AnalysisDriver driver;
+ final DartAssistContext context;
+ final int selectionOffset;
+ final int selectionLength;
+ final int selectionEnd;
- /**
- * The analysis session to be used to create the change builder.
- */
- AnalysisSession session;
-
- /**
- * The helper wrapper around the [session].
- */
- AnalysisSessionHelper sessionHelper;
-
- Source source;
- String file;
-
- CompilationUnit unit;
- CompilationUnitElement unitElement;
-
- LibraryElement unitLibraryElement;
-
- int selectionOffset;
- int selectionLength;
- int selectionEnd;
+ final AnalysisSession session;
+ final AnalysisSessionHelper sessionHelper;
+ final TypeProvider typeProvider;
+ final String file;
+ final CorrectionUtils utils;
final List<Assist> assists = <Assist>[];
- CorrectionUtils utils;
-
AstNode node;
- TypeProvider _typeProvider;
-
- AssistProcessor(DartAssistContext dartContext) {
- driver = dartContext.analysisDriver;
- session = driver.currentSession;
- sessionHelper = new AnalysisSessionHelper(session);
- // source
- source = dartContext.source;
- file = dartContext.source.fullName;
- // unit
- unit = dartContext.unit;
- unitElement = dartContext.unit.declaredElement;
- // library
- unitLibraryElement = resolutionMap
- .elementDeclaredByCompilationUnit(dartContext.unit)
- .library;
- // selection
- selectionOffset = dartContext.selectionOffset;
- selectionLength = dartContext.selectionLength;
- selectionEnd = selectionOffset + selectionLength;
- }
+ AssistProcessor(this.context)
+ : selectionOffset = context.selectionOffset,
+ selectionLength = context.selectionLength,
+ selectionEnd = context.selectionOffset + context.selectionLength,
+ session = context.resolveResult.session,
+ sessionHelper = AnalysisSessionHelper(context.resolveResult.session),
+ typeProvider = context.resolveResult.typeProvider,
+ file = context.resolveResult.path,
+ utils = new CorrectionUtils(context.resolveResult);
/**
* Returns the EOL to use for this [CompilationUnit].
*/
String get eol => utils.endOfLine;
- TypeProvider get typeProvider {
- if (_typeProvider == null) {
- _typeProvider = unitElement.context.typeProvider;
- }
- return _typeProvider;
- }
-
Future<List<Assist>> compute() async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
@@ -149,6 +110,7 @@
await _addProposal_flutterRemoveWidget_multipleChildren();
await _addProposal_flutterSwapWithChild();
await _addProposal_flutterSwapWithParent();
+ await _addProposal_flutterWrapStreamBuilder();
await _addProposal_flutterWrapWidget();
await _addProposal_flutterWrapWidgets();
await _addProposal_importAddShow();
@@ -188,28 +150,27 @@
// isn't just "return node.getAncestor((node) => node is FunctionBody);"
{
FunctionExpression function =
- node.getAncestor((node) => node is FunctionExpression);
+ node.thisOrAncestorOfType<FunctionExpression>();
if (function != null) {
return function.body;
}
}
{
FunctionDeclaration function =
- node.getAncestor((node) => node is FunctionDeclaration);
+ node.thisOrAncestorOfType<FunctionDeclaration>();
if (function != null) {
return function.functionExpression.body;
}
}
{
ConstructorDeclaration constructor =
- node.getAncestor((node) => node is ConstructorDeclaration);
+ node.thisOrAncestorOfType<ConstructorDeclaration>();
if (constructor != null) {
return constructor.body;
}
}
{
- MethodDeclaration method =
- node.getAncestor((node) => node is MethodDeclaration);
+ MethodDeclaration method = node.thisOrAncestorOfType<MethodDeclaration>();
if (method != null) {
return method.body;
}
@@ -233,9 +194,9 @@
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
DeclaredIdentifier declaredIdentifier =
- node.getAncestor((n) => n is DeclaredIdentifier);
+ node.thisOrAncestorOfType<DeclaredIdentifier>();
if (declaredIdentifier == null) {
- ForEachStatement forEach = node.getAncestor((n) => n is ForEachStatement);
+ ForEachStatement forEach = node.thisOrAncestorOfType<ForEachStatement>();
int offset = node.offset;
if (forEach != null &&
forEach.iterable != null &&
@@ -328,7 +289,7 @@
AstNode node = this.node;
// prepare VariableDeclarationList
VariableDeclarationList declarationList =
- node.getAncestor((node) => node is VariableDeclarationList);
+ node.thisOrAncestorOfType<VariableDeclarationList>();
if (declarationList == null) {
_coverageMarker();
return;
@@ -385,33 +346,6 @@
}
}
- Future<void> _addProposal_convertToIntLiteral() async {
- if (node is! DoubleLiteral) {
- _coverageMarker();
- return;
- }
- DoubleLiteral literal = node;
- int intValue;
- try {
- intValue = literal.value?.truncate();
- } catch (e) {
- // Double cannot be converted to int
- }
- if (intValue == null || intValue != literal.value) {
- _coverageMarker();
- return;
- }
-
- DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addReplacement(new SourceRange(literal.offset, literal.length),
- (DartEditBuilder builder) {
- builder.write('$intValue');
- });
- });
- _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_TO_INT_LITERAL);
- }
-
Future<void> _addProposal_assignToLocalVariable() async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
@@ -469,7 +403,7 @@
Future<void> _addProposal_convertClassToMixin() async {
ClassDeclaration classDeclaration =
- node.getAncestor((n) => n is ClassDeclaration);
+ node.thisOrAncestorOfType<ClassDeclaration>();
if (classDeclaration == null) {
return;
}
@@ -524,7 +458,7 @@
Future<void> _addProposal_convertDocumentationIntoBlock() async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
- Comment comment = node.getAncestor((n) => n is Comment);
+ Comment comment = node.thisOrAncestorOfType<Comment>();
if (comment == null || !comment.isDocumentation) {
return;
}
@@ -557,7 +491,7 @@
Future<void> _addProposal_convertDocumentationIntoLine() async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
- Comment comment = node.getAncestor((n) => n is Comment);
+ Comment comment = node.thisOrAncestorOfType<Comment>();
if (comment == null ||
!comment.isDocumentation ||
comment.tokens.length != 1) {
@@ -592,13 +526,17 @@
if (line.startsWith(prefix + ' */')) {
break;
}
- String expectedPrefix = prefix + ' * ';
+ String expectedPrefix = prefix + ' *';
if (!line.startsWith(expectedPrefix)) {
_coverageMarker();
return;
}
line = line.substring(expectedPrefix.length).trim();
- newLines.add('$linePrefix/// $line');
+ if (line.isEmpty) {
+ newLines.add('$linePrefix///');
+ } else {
+ newLines.add('$linePrefix/// $line');
+ }
linePrefix = eol + prefix;
}
}
@@ -740,13 +678,12 @@
Future<void> _addProposal_convertPartOfToUri() async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
- PartOfDirective directive =
- node.getAncestor((node) => node is PartOfDirective);
+ PartOfDirective directive = node.thisOrAncestorOfType<PartOfDirective>();
if (directive == null || directive.libraryName == null) {
return;
}
- String libraryPath = unitLibraryElement.source.fullName;
- String partPath = unit.declaredElement.source.fullName;
+ String libraryPath = context.resolveResult.libraryElement.source.fullName;
+ String partPath = context.resolveResult.path;
String relativePath = relative(libraryPath, from: dirname(partPath));
String uri = new Uri.file(relativePath).toString();
SourceRange replacementRange = range.node(directive.libraryName);
@@ -902,7 +839,7 @@
}
// prepare ConstructorDeclaration
ConstructorDeclaration constructor =
- node.getAncestor((node) => node is ConstructorDeclaration);
+ node.thisOrAncestorOfType<ConstructorDeclaration>();
if (constructor == null) {
return;
}
@@ -993,7 +930,7 @@
await null;
// find enclosing ForEachStatement
ForEachStatement forEachStatement =
- node.getAncestor((n) => n is ForEachStatement);
+ node.thisOrAncestorOfType<ForEachStatement>();
if (forEachStatement == null) {
_coverageMarker();
return;
@@ -1088,6 +1025,33 @@
}
}
+ Future<void> _addProposal_convertToIntLiteral() async {
+ if (node is! DoubleLiteral) {
+ _coverageMarker();
+ return;
+ }
+ DoubleLiteral literal = node;
+ int intValue;
+ try {
+ intValue = literal.value?.truncate();
+ } catch (e) {
+ // Double cannot be converted to int
+ }
+ if (intValue == null || intValue != literal.value) {
+ _coverageMarker();
+ return;
+ }
+
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
+ await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addReplacement(new SourceRange(literal.offset, literal.length),
+ (DartEditBuilder builder) {
+ builder.write('$intValue');
+ });
+ });
+ _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_TO_INT_LITERAL);
+ }
+
Future<void> _addProposal_convertToIsNot_onIs() async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
@@ -1310,7 +1274,7 @@
await null;
// find FieldDeclaration
FieldDeclaration fieldDeclaration =
- node.getAncestor((x) => x is FieldDeclaration);
+ node.thisOrAncestorOfType<FieldDeclaration>();
if (fieldDeclaration == null) {
_coverageMarker();
return;
@@ -1496,7 +1460,7 @@
Future<void> _addProposal_flutterConvertToStatefulWidget() async {
ClassDeclaration widgetClass =
- node.getAncestor((n) => n is ClassDeclaration);
+ node.thisOrAncestorOfType<ClassDeclaration>();
TypeName superclass = widgetClass?.extendsClause?.superclass;
if (widgetClass == null || superclass == null) {
_coverageMarker();
@@ -1906,6 +1870,61 @@
parent, child, DartAssistKind.FLUTTER_SWAP_WITH_PARENT);
}
+ Future<void> _addProposal_flutterWrapStreamBuilder() async {
+ Expression widgetExpr = flutter.identifyWidgetExpression(node);
+ if (widgetExpr == null) {
+ return;
+ }
+ if (flutter.isExactWidgetTypeStreamBuilder(widgetExpr.staticType)) {
+ return;
+ }
+ String widgetSrc = utils.getNodeText(widgetExpr);
+
+ var streamBuilderElement = await sessionHelper.getClass(
+ flutter.WIDGETS_LIBRARY_URI,
+ 'StreamBuilder',
+ );
+ if (streamBuilderElement == null) {
+ return;
+ }
+
+ var changeBuilder = new DartChangeBuilder(session);
+ await changeBuilder.addFileEdit(file, (builder) {
+ builder.addReplacement(range.node(widgetExpr), (builder) {
+ builder.writeType(streamBuilderElement.type);
+ builder.writeln('<Object>(');
+
+ String indentOld = utils.getLinePrefix(widgetExpr.offset);
+ String indentNew1 = indentOld + utils.getIndent(1);
+ String indentNew2 = indentOld + utils.getIndent(2);
+
+ builder.write(indentNew1);
+ builder.writeln('stream: null,');
+
+ builder.write(indentNew1);
+ builder.writeln('builder: (context, snapshot) {');
+
+ widgetSrc = widgetSrc.replaceAll(
+ new RegExp("^$indentOld", multiLine: true),
+ indentNew2,
+ );
+ builder.write(indentNew2);
+ builder.write('return $widgetSrc');
+ builder.writeln(';');
+
+ builder.write(indentNew1);
+ builder.writeln('}');
+
+ builder.write(indentOld);
+ builder.write(')');
+ });
+ });
+ _addAssistFromBuilder(
+ changeBuilder,
+ DartAssistKind.FLUTTER_WRAP_STREAM_BUILDER,
+ );
+ }
+
Future<void> _addProposal_flutterWrapWidget() async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
@@ -2006,7 +2025,7 @@
await null;
var selectionRange = new SourceRange(selectionOffset, selectionLength);
var analyzer = new SelectionAnalyzer(selectionRange);
- unit.accept(analyzer);
+ context.resolveResult.unit.accept(analyzer);
List<Expression> widgetExpressions = [];
if (analyzer.hasSelectedNodes) {
@@ -2095,7 +2114,7 @@
await null;
// prepare ImportDirective
ImportDirective importDirective =
- node.getAncestor((node) => node is ImportDirective);
+ node.thisOrAncestorOfType<ImportDirective>();
if (importDirective == null) {
_coverageMarker();
return;
@@ -2121,7 +2140,7 @@
referencedNames.add(element.displayName);
}
});
- unit.accept(visitor);
+ context.resolveResult.unit.accept(visitor);
// ignore if unused
if (referencedNames.isEmpty) {
_coverageMarker();
@@ -2157,7 +2176,7 @@
String prefix;
Block targetBlock;
{
- Statement statement = node.getAncestor((n) => n is Statement);
+ Statement statement = node.thisOrAncestorOfType<Statement>();
if (statement is IfStatement && statement.thenStatement is Block) {
targetBlock = statement.thenStatement;
} else if (statement is WhileStatement && statement.body is Block) {
@@ -2389,6 +2408,7 @@
return;
}
int declOffset = element.nameOffset;
+ var unit = context.resolveResult.unit;
AstNode declNode = new NodeLocator(declOffset).searchWithin(unit);
if (declNode != null &&
declNode.parent is VariableDeclaration &&
@@ -2446,7 +2466,7 @@
await null;
// prepare enclosing VariableDeclarationList
VariableDeclarationList declList =
- node.getAncestor((node) => node is VariableDeclarationList);
+ node.thisOrAncestorOfType<VariableDeclarationList>();
if (declList != null && declList.variables.length == 1) {
} else {
_coverageMarker();
@@ -2515,7 +2535,7 @@
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
VariableDeclarationList declarationList =
- node.getAncestor((n) => n is VariableDeclarationList);
+ node.thisOrAncestorOfType<VariableDeclarationList>();
if (declarationList == null) {
_coverageMarker();
return;
@@ -2611,7 +2631,7 @@
await null;
ConditionalExpression conditional = null;
// may be on Statement with Conditional
- Statement statement = node.getAncestor((node) => node is Statement);
+ Statement statement = node.thisOrAncestorOfType<Statement>();
if (statement == null) {
_coverageMarker();
return;
@@ -2801,7 +2821,7 @@
return;
}
// prepare "if"
- Statement statement = node.getAncestor((node) => node is Statement);
+ Statement statement = node.thisOrAncestorOfType<Statement>();
if (statement is! IfStatement) {
_coverageMarker();
return;
@@ -2878,7 +2898,7 @@
await null;
// prepare DartVariableStatement, should be part of Block
VariableDeclarationStatement statement =
- node.getAncestor((node) => node is VariableDeclarationStatement);
+ node.thisOrAncestorOfType<VariableDeclarationStatement>();
if (statement != null && statement.parent is Block) {
} else {
_coverageMarker();
@@ -2920,8 +2940,9 @@
List<Statement> selectedStatements;
{
StatementAnalyzer selectionAnalyzer = new StatementAnalyzer(
- unit, new SourceRange(selectionOffset, selectionLength));
- unit.accept(selectionAnalyzer);
+ context.resolveResult,
+ new SourceRange(selectionOffset, selectionLength));
+ selectionAnalyzer.analyze();
List<AstNode> selectedNodes = selectionAnalyzer.selectedNodes;
// convert nodes to statements
selectedStatements = [];
@@ -3149,7 +3170,7 @@
utils.targetClassElement = null;
if (target is AstNode) {
ClassDeclaration targetClassDeclaration =
- target.getAncestor((node) => node is ClassDeclaration);
+ target.thisOrAncestorOfType<ClassDeclaration>();
if (targetClassDeclaration != null) {
utils.targetClassElement = targetClassDeclaration.declaredElement;
}
@@ -3330,13 +3351,8 @@
}
bool _setupCompute() {
- try {
- utils = new CorrectionUtils(unit);
- } catch (e) {
- throw new CancelCorrectionException(exception: e);
- }
-
- node = new NodeLocator(selectionOffset, selectionEnd).searchWithin(unit);
+ var locator = new NodeLocator(selectionOffset, selectionEnd);
+ node = locator.searchWithin(context.resolveResult.unit);
return node != null;
}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index 21765cf..796ae49 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -2,11 +2,10 @@
// 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/plugin/edit/fix/fix_core.dart';
+import 'package:analysis_server/plugin/edit/fix/fix_dart.dart';
import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/error/error.dart';
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/parser.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
@@ -62,7 +61,6 @@
errorCode == HintCode.UNUSED_CATCH_CLAUSE ||
errorCode == HintCode.UNUSED_CATCH_STACK ||
errorCode == HintCode.UNUSED_IMPORT ||
- errorCode == HintCode.UNDEFINED_METHOD ||
errorCode == ParserErrorCode.EXPECTED_TOKEN ||
errorCode == ParserErrorCode.GETTER_WITH_PARAMETERS ||
errorCode == ParserErrorCode.VAR_AS_TYPE_NAME ||
@@ -86,6 +84,23 @@
errorCode.name == LintNames.unnecessary_this));
/**
+ * The implementation of [DartFixContext].
+ */
+class DartFixContextImpl implements DartFixContext {
+ @override
+ final ResolvedUnitResult resolveResult;
+
+ @override
+ final AnalysisError error;
+
+ DartFixContextImpl(this.resolveResult, this.error);
+
+ DartFixContextImpl.from(DartFixContext other)
+ : resolveResult = other.resolveResult,
+ error = other.error;
+}
+
+/**
* An enumeration of possible quick fix kinds.
*/
class DartFixKind {
@@ -96,20 +111,22 @@
appliedTogetherMessage: "Add all casts in file");
static const ADD_FIELD_FORMAL_PARAMETERS = const FixKind(
'ADD_FIELD_FORMAL_PARAMETERS', 70, "Add final field formal parameters");
+ static const ADD_MISSING_PARAMETER_NAMED = const FixKind(
+ 'ADD_MISSING_PARAMETER_NAMED', 70, "Add named parameter '{0}'");
static const ADD_MISSING_PARAMETER_POSITIONAL = const FixKind(
'ADD_MISSING_PARAMETER_POSITIONAL',
69,
"Add optional positional parameter");
- static const ADD_MISSING_PARAMETER_NAMED = const FixKind(
- 'ADD_MISSING_PARAMETER_NAMED', 70, "Add named parameter '{0}'");
static const ADD_MISSING_PARAMETER_REQUIRED = const FixKind(
'ADD_MISSING_PARAMETER_REQUIRED', 70, "Add required parameter");
static const ADD_MISSING_REQUIRED_ARGUMENT = const FixKind(
'ADD_MISSING_REQUIRED_ARGUMENT', 70, "Add required argument '{0}'");
static const ADD_NE_NULL = const FixKind('ADD_NE_NULL', 50, "Add != null",
appliedTogetherMessage: "Add != null everywhere in file");
- static const ADD_PACKAGE_DEPENDENCY = const FixKind(
- 'ADD_PACKAGE_DEPENDENCY', 50, "Add dependency on package '{0}'");
+ static const ADD_OVERRIDE =
+ const FixKind('ADD_OVERRIDE', 50, "Add '@override' annotation");
+ static const ADD_REQUIRED =
+ const FixKind('ADD_REQUIRED', 50, "Add '@required' annotation");
static const ADD_STATIC =
const FixKind('ADD_STATIC', 50, "Add 'static' modifier");
static const ADD_SUPER_CONSTRUCTOR_INVOCATION = const FixKind(
@@ -129,6 +146,8 @@
const FixKind('CONVERT_FLUTTER_CHILD', 50, "Convert to children:");
static const CONVERT_FLUTTER_CHILDREN =
const FixKind('CONVERT_FLUTTER_CHILDREN', 50, "Convert to child:");
+ static const CONVERT_TO_NAMED_ARGUMENTS = const FixKind(
+ 'CONVERT_TO_NAMED_ARGUMENTS', 50, "Convert to named arguments");
static const CREATE_CLASS =
const FixKind('CREATE_CLASS', 50, "Create class '{0}'");
static const CREATE_CONSTRUCTOR =
@@ -157,8 +176,10 @@
const FixKind('CREATE_MIXIN', 50, "Create mixin '{0}'");
static const CREATE_NO_SUCH_METHOD = const FixKind(
'CREATE_NO_SUCH_METHOD', 49, "Create 'noSuchMethod' method");
- static const CONVERT_TO_NAMED_ARGUMENTS = const FixKind(
- 'CONVERT_TO_NAMED_ARGUMENTS', 50, "Convert to named arguments");
+ static const EXTEND_CLASS_FOR_MIXIN =
+ const FixKind('EXTEND_CLASS_FOR_MIXIN', 50, "Extend the class '{0}'");
+ static const IMPORT_ASYNC =
+ const FixKind('IMPORT_ASYNC', 49, "Import 'dart:async'");
static const IMPORT_LIBRARY_PREFIX = const FixKind('IMPORT_LIBRARY_PREFIX',
49, "Use imported library '{0}' with prefix '{1}'");
static const IMPORT_LIBRARY_PROJECT1 =
@@ -173,28 +194,18 @@
const FixKind('IMPORT_LIBRARY_SHOW', 55, "Update library '{0}' import");
static const INSERT_SEMICOLON =
const FixKind('INSERT_SEMICOLON', 50, "Insert ';'");
- static const INVOKE_CONSTRUCTOR_USING_NEW = const FixKind(
- 'INVOKE_CONSTRUCTOR_USING_NEW', 50, "Invoke constructor using 'new'");
- static const LINT_ADD_OVERRIDE =
- const FixKind('LINT_ADD_OVERRIDE', 50, "Add '@override' annotation");
- static const LINT_ADD_REQUIRED =
- const FixKind('LINT_ADD_REQUIRED', 50, "Add '@required' annotation");
- static const LINT_REMOVE_INTERPOLATION_BRACES = const FixKind(
- 'LINT_REMOVE_INTERPOLATION_BRACES',
- 50,
- "Remove unnecessary interpolation braces");
static const MAKE_CLASS_ABSTRACT =
const FixKind('MAKE_CLASS_ABSTRACT', 50, "Make class '{0}' abstract");
+ static const MAKE_FIELD_NOT_FINAL =
+ const FixKind('MAKE_FIELD_NOT_FINAL', 50, "Make field '{0}' not final");
+ static const MAKE_FINAL = const FixKind('MAKE_FINAL', 50, "Make final");
static const MOVE_TYPE_ARGUMENTS_TO_CLASS = const FixKind(
'MOVE_TYPE_ARGUMENTS_TO_CLASS',
50,
"Move type arguments to after class name");
+ static const REMOVE_AWAIT = const FixKind('REMOVE_AWAIT', 50, "Remove await");
static const REMOVE_DEAD_CODE =
const FixKind('REMOVE_DEAD_CODE', 50, "Remove dead code");
- static const MAKE_FIELD_NOT_FINAL =
- const FixKind('MAKE_FIELD_NOT_FINAL', 50, "Make field '{0}' not final");
- static const MAKE_FINAL = const FixKind('MAKE_FINAL', 50, "Make final");
- static const REMOVE_AWAIT = const FixKind('REMOVE_AWAIT', 50, "Remove await");
static const REMOVE_EMPTY_CATCH =
const FixKind('REMOVE_EMPTY_CATCH', 50, "Remove empty catch clause");
static const REMOVE_EMPTY_CONSTRUCTOR_BODY = const FixKind(
@@ -205,6 +216,10 @@
const FixKind('REMOVE_EMPTY_STATEMENT', 50, "Remove empty statement");
static const REMOVE_INITIALIZER =
const FixKind('REMOVE_INITIALIZER', 50, "Remove initializer");
+ static const REMOVE_INTERPOLATION_BRACES = const FixKind(
+ 'REMOVE_INTERPOLATION_BRACES',
+ 50,
+ "Remove unnecessary interpolation braces");
static const REMOVE_METHOD_DECLARATION = const FixKind(
'REMOVE_METHOD_DECLARATION', 50, "Remove method declaration");
static const REMOVE_PARAMETERS_IN_GETTER_DECLARATION = const FixKind(
@@ -217,10 +232,10 @@
"Remove parentheses in getter invocation");
static const REMOVE_THIS_EXPRESSION =
const FixKind('REMOVE_THIS_EXPRESSION', 50, "Remove this expression");
+ static const REMOVE_TYPE_ANNOTATION =
+ const FixKind('REMOVE_TYPE_ANNOTATION', 50, "Remove type annotation");
static const REMOVE_TYPE_ARGUMENTS =
const FixKind('REMOVE_TYPE_ARGUMENTS', 49, "Remove type arguments");
- static const REMOVE_TYPE_NAME =
- const FixKind('REMOVE_TYPE_NAME', 50, "Remove type name");
static const REMOVE_UNNECESSARY_CAST = const FixKind(
'REMOVE_UNNECESSARY_CAST', 50, "Remove unnecessary cast",
appliedTogetherMessage: "Remove all unnecessary casts in file");
@@ -238,12 +253,12 @@
appliedTogetherMessage: "Replace all 'boolean' with 'bool' in file");
static const REPLACE_FINAL_WITH_CONST = const FixKind(
'REPLACE_FINAL_WITH_CONST', 50, "Replace 'final' with 'const'");
- static const REPLACE_VAR_WITH_DYNAMIC = const FixKind(
- 'REPLACE_VAR_WITH_DYNAMIC', 50, "Replace 'var' with 'dynamic'");
static const REPLACE_RETURN_TYPE_FUTURE = const FixKind(
'REPLACE_RETURN_TYPE_FUTURE',
50,
"Return 'Future' from 'async' function");
+ static const REPLACE_VAR_WITH_DYNAMIC = const FixKind(
+ 'REPLACE_VAR_WITH_DYNAMIC', 50, "Replace 'var' with 'dynamic'");
static const REPLACE_WITH_BRACKETS =
const FixKind('REPLACE_WITH_BRACKETS', 50, "Replace with { }");
static const REPLACE_WITH_CONDITIONAL_ASSIGNMENT = const FixKind(
@@ -258,6 +273,8 @@
"Replace the '.' with a '?.' in the invocation");
static const REPLACE_WITH_TEAR_OFF = const FixKind(
'REPLACE_WITH_TEAR_OFF', 50, "Replace function literal with tear-off");
+ static const UPDATE_SDK_CONSTRAINTS =
+ const FixKind('UPDATE_SDK_CONSTRAINTS', 50, "Update the SDK constraints");
static const USE_CONST = const FixKind('USE_CONST', 50, "Change to constant");
static const USE_EFFECTIVE_INTEGER_DIVISION = const FixKind(
'USE_EFFECTIVE_INTEGER_DIVISION',
@@ -274,29 +291,3 @@
appliedTogetherMessage:
"Use != null instead of 'is! Null' everywhere in file");
}
-
-/**
- * The implementation of [FixContext].
- */
-class FixContextImpl implements FixContext {
- @override
- final ResourceProvider resourceProvider;
-
- @override
- final AnalysisDriver analysisDriver;
-
- @override
- final AnalysisError error;
-
- @override
- final List<AnalysisError> errors;
-
- FixContextImpl(
- this.resourceProvider, this.analysisDriver, this.error, this.errors);
-
- FixContextImpl.from(FixContext other)
- : resourceProvider = other.resourceProvider,
- analysisDriver = other.analysisDriver,
- error = other.error,
- errors = other.errors;
-}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index db40113..ff63464 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -23,16 +23,12 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/error.dart';
-import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/context/context_root.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/session_helper.dart';
import 'package:analyzer/src/dart/analysis/top_level_declaration.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/ast/token.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
-import 'package:analyzer/src/dart/element/ast_provider.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/member.dart';
import 'package:analyzer/src/dart/element/type.dart';
@@ -44,6 +40,7 @@
import 'package:analyzer/src/generated/parser.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/hint/sdk_constraint_extractor.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart'
hide AnalysisError, Element, ElementKind;
import 'package:analyzer_plugin/src/utilities/string_utilities.dart';
@@ -58,30 +55,11 @@
typedef bool ElementPredicate(Element argument);
/**
- * The implementation of [DartFixContext].
- *
- * Clients may not extend, implement or mix-in this class.
+ * A fix contributor that provides the default set of fixes for Dart files.
*/
-class DartFixContextImpl extends FixContextImpl implements DartFixContext {
+class DartFixContributor implements FixContributor {
@override
- final AstProvider astProvider;
-
- @override
- final CompilationUnit unit;
-
- DartFixContextImpl(FixContext fixContext, this.astProvider, this.unit)
- : super.from(fixContext);
-
- GetTopLevelDeclarations get getTopLevelDeclarations =>
- analysisDriver.getTopLevelNameDeclarations;
-}
-
-/**
- * A [FixContributor] that provides the default set of fixes.
- */
-class DefaultFixContributor extends DartFixContributor {
- @override
- Future<List<Fix>> internalComputeFixes(DartFixContext context) async {
+ Future<List<Fix>> computeFixes(DartFixContext context) async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
try {
@@ -98,8 +76,8 @@
DartFixContext context, List<Fix> fixes) async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
- final AnalysisError analysisError = context.error;
- final List<AnalysisError> allAnalysisErrors = context.errors;
+ final analysisError = context.error;
+ final allAnalysisErrors = context.resolveResult.errors.toList();
// Validate inputs:
// - return if no fixes
@@ -123,14 +101,9 @@
// one.
// For each fix, put the fix into the HashMap.
for (int i = 0; i < allAnalysisErrors.length; i++) {
- final FixContext fixContextI = new FixContextImpl(
- context.resourceProvider,
- context.analysisDriver,
- allAnalysisErrors[i],
- allAnalysisErrors);
- final DartFixContextImpl dartFixContextI = new DartFixContextImpl(
- fixContextI, context.astProvider, context.unit);
- final FixProcessor processorI = new FixProcessor(dartFixContextI);
+ final FixContext fixContextI =
+ new DartFixContextImpl(context.resolveResult, allAnalysisErrors[i]);
+ final FixProcessor processorI = new FixProcessor(fixContextI);
final List<Fix> fixesListI = await processorI.compute();
for (Fix f in fixesListI) {
if (!map.containsKey(f.kind)) {
@@ -188,70 +161,40 @@
class FixProcessor {
static const int MAX_LEVENSHTEIN_DISTANCE = 3;
- ResourceProvider resourceProvider;
- AstProvider astProvider;
- GetTopLevelDeclarations getTopLevelDeclarations;
- CompilationUnit unit;
- AnalysisError error;
+ final DartFixContext context;
+ final ResourceProvider resourceProvider;
+ final AnalysisSession session;
+ final AnalysisSessionHelper sessionHelper;
+ final TypeProvider typeProvider;
+ final TypeSystem typeSystem;
- /**
- * The analysis driver being used to perform analysis.
- */
- AnalysisDriver driver;
+ final String file;
+ final LibraryElement unitLibraryElement;
+ final CompilationUnit unit;
+ final CorrectionUtils utils;
- /**
- * The analysis session to be used to create the change builder.
- */
- AnalysisSession session;
-
- /**
- * The helper wrapper around the [session].
- */
- AnalysisSessionHelper sessionHelper;
-
- String file;
- CompilationUnitElement unitElement;
- Source unitSource;
- LibraryElement unitLibraryElement;
- File unitLibraryFile;
- Folder unitLibraryFolder;
+ final AnalysisError error;
+ final int errorOffset;
+ final int errorLength;
final List<Fix> fixes = <Fix>[];
- CorrectionUtils utils;
- int errorOffset;
- int errorLength;
- int errorEnd;
- SourceRange errorRange;
AstNode node;
AstNode coveredNode;
- TypeProvider _typeProvider;
- TypeSystem _typeSystem;
-
- FixProcessor(DartFixContext dartContext) {
- resourceProvider = dartContext.resourceProvider;
- astProvider = dartContext.astProvider;
- getTopLevelDeclarations = dartContext.getTopLevelDeclarations;
-
- driver = dartContext.analysisDriver;
- session = driver.currentSession;
- sessionHelper = new AnalysisSessionHelper(session);
-
- // unit
- unit = dartContext.unit;
- unitElement = unit.declaredElement;
- unitSource = unitElement.source;
- // file
- file = unitSource.fullName;
- // library
- unitLibraryElement = unitElement.library;
- String unitLibraryPath = unitLibraryElement.source.fullName;
- unitLibraryFile = resourceProvider.getFile(unitLibraryPath);
- unitLibraryFolder = unitLibraryFile.parent;
- // error
- error = dartContext.error;
- }
+ FixProcessor(this.context)
+ : resourceProvider = context.resolveResult.session.resourceProvider,
+ session = context.resolveResult.session,
+ sessionHelper = AnalysisSessionHelper(context.resolveResult.session),
+ typeProvider = context.resolveResult.typeProvider,
+ typeSystem = StrongTypeSystemImpl(context.resolveResult.typeProvider),
+ file = context.resolveResult.path,
+ unitLibraryElement = context.resolveResult.libraryElement,
+ unit = context.resolveResult.unit,
+ utils = CorrectionUtils(context.resolveResult),
+ error = context.error,
+ errorOffset = context.error.offset,
+ errorLength = context.error.length;
DartType get coreTypeBool => _getCoreType('bool');
@@ -260,36 +203,13 @@
*/
String get eol => utils.endOfLine;
- TypeProvider get typeProvider {
- if (_typeProvider == null) {
- _typeProvider = unitElement.context.typeProvider;
- }
- return _typeProvider;
- }
-
- TypeSystem get typeSystem {
- if (_typeSystem == null) {
- _typeSystem = new StrongTypeSystemImpl(typeProvider);
- }
- return _typeSystem;
- }
-
Future<List<Fix>> compute() async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
- try {
- utils = new CorrectionUtils(unit);
- } catch (e) {
- throw new CancelCorrectionException(exception: e);
- }
- errorOffset = error.offset;
- errorLength = error.length;
- errorEnd = errorOffset + errorLength;
- errorRange = new SourceRange(errorOffset, errorLength);
node = new NodeLocator2(errorOffset).searchWithin(unit);
- coveredNode =
- new NodeLocator2(errorOffset, errorEnd - 1).searchWithin(unit);
+ coveredNode = new NodeLocator2(errorOffset, errorOffset + errorLength - 1)
+ .searchWithin(unit);
if (coveredNode == null) {
// TODO(brianwilkerson) Figure out why the coveredNode is sometimes null.
return fixes;
@@ -481,9 +401,6 @@
errorCode == StaticWarningCode.UNDEFINED_NAMED_PARAMETER) {
await _addFix_addMissingNamedArgument();
}
- if (errorCode == StaticTypeWarningCode.UNDEFINED_METHOD_WITH_CONSTRUCTOR) {
- await _addFix_undefinedMethodWithContructor();
- }
if (errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE) {
await _addFix_illegalAsyncReturnType();
}
@@ -526,8 +443,7 @@
await _addFix_importLibrary_withTopLevelVariable();
await _addFix_importLibrary_withType();
}
- if (errorCode == HintCode.UNDEFINED_METHOD ||
- errorCode == StaticTypeWarningCode.UNDEFINED_METHOD) {
+ if (errorCode == StaticTypeWarningCode.UNDEFINED_METHOD) {
await _addFix_createClass();
await _addFix_importLibrary_withFunction();
await _addFix_importLibrary_withType();
@@ -556,6 +472,14 @@
await _addFix_moveTypeArgumentsToClass();
await _addFix_removeTypeArguments();
}
+ if (errorCode ==
+ CompileTimeErrorCode.MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE) {
+ await _addFix_extendClassForMixin();
+ }
+ if (errorCode == HintCode.SDK_VERSION_ASYNC_EXPORTED_FROM_CORE) {
+ await _addFix_importAsync();
+ await _addFix_updateSdkConstraints();
+ }
// lints
if (errorCode is LintCode) {
String name = errorCode.name;
@@ -642,7 +566,7 @@
Future<void> _addFix_addAsync() async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
- FunctionBody body = node.getAncestor((n) => n is FunctionBody);
+ FunctionBody body = node.thisOrAncestorOfType<FunctionBody>();
if (body != null && body.keyword == null) {
TypeProvider typeProvider = this.typeProvider;
DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
@@ -777,7 +701,7 @@
AstNode argumentList = namedExpression.parent;
// Prepare the invoked element.
- var context = new _ExecutableParameters(astProvider, argumentList.parent);
+ var context = new _ExecutableParameters(sessionHelper, argumentList.parent);
if (context == null) {
return;
}
@@ -829,7 +753,7 @@
List<Expression> arguments = argumentList.arguments;
// Prepare the invoked element.
- var context = new _ExecutableParameters(astProvider, node.parent);
+ var context = new _ExecutableParameters(sessionHelper, node.parent);
if (context == null) {
return;
}
@@ -902,7 +826,7 @@
argumentList = invocation.argumentList;
} else {
creation =
- invocation.getAncestor((p) => p is InstanceCreationExpression);
+ invocation.thisOrAncestorOfType<InstanceCreationExpression>();
if (creation != null) {
targetElement = creation.staticElement;
argumentList = creation.argumentList;
@@ -960,7 +884,7 @@
Future<void> _addFix_addOverrideAnnotation() async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
- ClassMember member = node.getAncestor((n) => n is ClassMember);
+ ClassMember member = node.thisOrAncestorOfType<ClassMember>();
if (member == null) {
return;
}
@@ -981,7 +905,7 @@
range.startLength(token, 0), '@override$eol$indent');
});
changeBuilder.setSelection(exitPosition);
- _addFixFromBuilder(changeBuilder, DartFixKind.LINT_ADD_OVERRIDE);
+ _addFixFromBuilder(changeBuilder, DartFixKind.ADD_OVERRIDE);
}
Future<void> _addFix_addRequiredAnnotation() async {
@@ -991,14 +915,14 @@
await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
builder.addSimpleInsertion(node.parent.offset, '@required ');
});
- _addFixFromBuilder(changeBuilder, DartFixKind.LINT_ADD_REQUIRED);
+ _addFixFromBuilder(changeBuilder, DartFixKind.ADD_REQUIRED);
}
Future<void> _addFix_addStatic() async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
FieldDeclaration declaration =
- node.getAncestor((n) => n is FieldDeclaration);
+ node.thisOrAncestorOfType<FieldDeclaration>();
DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
builder.addSimpleInsertion(declaration.offset, 'static ');
@@ -1265,9 +1189,10 @@
int offset = -1;
String filePath;
if (prefixElement == null) {
- targetUnit = unitElement;
- CompilationUnitMember enclosingMember = node.getAncestor((node) =>
- node is CompilationUnitMember && node.parent is CompilationUnit);
+ targetUnit = unit.declaredElement;
+ CompilationUnitMember enclosingMember = node.thisOrAncestorMatching(
+ (node) =>
+ node is CompilationUnitMember && node.parent is CompilationUnit);
if (enclosingMember == null) {
return;
}
@@ -1324,7 +1249,7 @@
}
ClassDeclaration classDeclaration =
- node.getAncestor((node) => node is ClassDeclaration);
+ node.thisOrAncestorOfType<ClassDeclaration>();
if (classDeclaration == null) {
return;
}
@@ -1418,12 +1343,12 @@
}
ClassElement targetElement = constructorElement.enclosingElement;
// prepare location for a new constructor
- AstNode targetTypeNode = getParsedClassElementNode(targetElement);
- if (targetTypeNode is! ClassDeclaration) {
+ var targetNode = await _getClassDeclaration(targetElement);
+ if (targetNode == null) {
return;
}
ClassMemberLocation targetLocation =
- utils.prepareNewConstructorLocation(targetTypeNode);
+ utils.prepareNewConstructorLocation(targetNode);
Source targetSource = targetElement.source;
String targetFile = targetSource.fullName;
DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
@@ -1474,12 +1399,12 @@
}
// prepare location for a new constructor
ClassElement targetElement = targetType.element as ClassElement;
- AstNode targetTypeNode = getParsedClassElementNode(targetElement);
- if (targetTypeNode is! ClassDeclaration) {
+ var targetNode = await _getClassDeclaration(targetElement);
+ if (targetNode == null) {
return;
}
ClassMemberLocation targetLocation =
- utils.prepareNewConstructorLocation(targetTypeNode);
+ utils.prepareNewConstructorLocation(targetNode);
String targetFile = targetElement.source.fullName;
DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
@@ -1574,7 +1499,7 @@
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
ClassDeclaration targetClassNode =
- node.getAncestor((parent) => parent is ClassDeclaration);
+ node.thisOrAncestorOfType<ClassDeclaration>();
ClassElement targetClassElement = targetClassNode.declaredElement;
InterfaceType superType = targetClassElement.supertype;
String targetClassName = targetClassElement.name;
@@ -1689,14 +1614,16 @@
}
utils.targetClassElement = targetClassElement;
// prepare target ClassDeclaration
- AstNode targetTypeNode = getParsedClassElementNode(targetClassElement);
- if (targetTypeNode is! ClassDeclaration) {
+ var targetDeclarationResult =
+ await sessionHelper.getElementDeclaration(targetClassElement);
+ if (targetDeclarationResult.node is! ClassOrMixinDeclaration) {
return;
}
- ClassDeclaration targetClassNode = targetTypeNode;
+ ClassOrMixinDeclaration targetNode = targetDeclarationResult.node;
// prepare location
ClassMemberLocation targetLocation =
- _getUtilsFor(targetClassNode).prepareNewFieldLocation(targetClassNode);
+ CorrectionUtils(targetDeclarationResult.resolvedUnit)
+ .prepareNewFieldLocation(targetNode);
// build field source
Source targetSource = targetClassElement.source;
String targetFile = targetSource.fullName;
@@ -1724,12 +1651,12 @@
// Ensure that we are in an initializing formal parameter.
//
FieldFormalParameter parameter =
- node.getAncestor((node) => node is FieldFormalParameter);
+ node.thisOrAncestorOfType<FieldFormalParameter>();
if (parameter == null) {
return;
}
ClassDeclaration targetClassNode =
- parameter.getAncestor((node) => node is ClassDeclaration);
+ parameter.thisOrAncestorOfType<ClassDeclaration>();
if (targetClassNode == null) {
return;
}
@@ -1772,8 +1699,8 @@
return;
}
} else {
- ClassDeclaration enclosingClass =
- node.getAncestor((node) => node is ClassDeclaration);
+ ClassOrMixinDeclaration enclosingClass =
+ node.thisOrAncestorOfType<ClassOrMixinDeclaration>();
targetElement = enclosingClass?.declaredElement;
argument = nameNode;
}
@@ -1851,15 +1778,17 @@
return;
}
utils.targetClassElement = targetClassElement;
- // prepare target ClassDeclaration
- AstNode targetTypeNode = getParsedClassElementNode(targetClassElement);
- if (targetTypeNode is! ClassDeclaration) {
+ // prepare target ClassOrMixinDeclaration
+ var targetDeclarationResult =
+ await sessionHelper.getElementDeclaration(targetClassElement);
+ if (targetDeclarationResult.node is! ClassOrMixinDeclaration) {
return;
}
- ClassDeclaration targetClassNode = targetTypeNode;
+ ClassOrMixinDeclaration targetNode = targetDeclarationResult.node;
// prepare location
ClassMemberLocation targetLocation =
- _getUtilsFor(targetClassNode).prepareNewGetterLocation(targetClassNode);
+ CorrectionUtils(targetDeclarationResult.resolvedUnit)
+ .prepareNewGetterLocation(targetNode);
// build method source
Source targetSource = targetClassElement.source;
String targetFile = targetSource.fullName;
@@ -1891,18 +1820,15 @@
if (source != null) {
String file = source.fullName;
if (isAbsolute(file) && AnalysisEngine.isDartFileName(file)) {
- String libName = _computeLibraryName(file);
- try {
- DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
- await changeBuilder.addFileEdit(source.fullName,
- (DartFileEditBuilder builder) {
- builder.addSimpleInsertion(0, 'library $libName;$eol$eol');
- });
- _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_FILE,
- args: [source.shortName]);
- } on AnalysisException {
- // Ignore the exception and just don't create a fix.
- }
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
+ await changeBuilder.addFileEdit(source.fullName, (builder) {
+ builder.addSimpleInsertion(0, '// TODO Implement this library.');
+ });
+ _addFixFromBuilder(
+ changeBuilder,
+ DartFixKind.CREATE_FILE,
+ args: [source.shortName],
+ );
}
}
}
@@ -1932,7 +1858,7 @@
}
}
// prepare target Statement
- Statement target = node.getAncestor((x) => x is Statement);
+ Statement target = node.thisOrAncestorOfType<Statement>();
if (target == null) {
return;
}
@@ -2083,9 +2009,10 @@
int offset = -1;
String filePath;
if (prefixElement == null) {
- targetUnit = unitElement;
- CompilationUnitMember enclosingMember = node.getAncestor((node) =>
- node is CompilationUnitMember && node.parent is CompilationUnit);
+ targetUnit = unit.declaredElement;
+ CompilationUnitMember enclosingMember = node.thisOrAncestorMatching(
+ (node) =>
+ node is CompilationUnitMember && node.parent is CompilationUnit);
if (enclosingMember == null) {
return;
}
@@ -2179,11 +2106,30 @@
}
}
+ Future<void> _addFix_extendClassForMixin() async {
+ ClassDeclaration declaration =
+ node.thisOrAncestorOfType<ClassDeclaration>();
+ if (declaration != null && declaration.extendsClause == null) {
+ String message = error.message;
+ int startIndex = message.indexOf("'", message.indexOf("'") + 1) + 1;
+ int endIndex = message.indexOf("'", startIndex);
+ String typeName = message.substring(startIndex, endIndex);
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
+ await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addSimpleInsertion(
+ declaration.typeParameters?.end ?? declaration.name.end,
+ ' extends $typeName');
+ });
+ _addFixFromBuilder(changeBuilder, DartFixKind.EXTEND_CLASS_FOR_MIXIN,
+ args: [typeName]);
+ }
+ }
+
Future<void> _addFix_illegalAsyncReturnType() async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
// prepare the existing type
- TypeAnnotation typeName = node.getAncestor((n) => n is TypeAnnotation);
+ TypeAnnotation typeName = node.thisOrAncestorOfType<TypeAnnotation>();
TypeProvider typeProvider = this.typeProvider;
DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
@@ -2192,6 +2138,11 @@
_addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_RETURN_TYPE_FUTURE);
}
+ Future<void> _addFix_importAsync() async {
+ await _addFix_importLibrary(
+ DartFixKind.IMPORT_ASYNC, Uri.parse('dart:async'));
+ }
+
Future<void> _addFix_importLibrary(FixKind kind, Uri library) async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
@@ -2260,7 +2211,8 @@
String newShowCode = 'show ${showNames.join(', ')}';
int offset = showCombinator.offset;
int length = showCombinator.end - offset;
- String libraryFile = unitLibraryElement.source.fullName;
+ String libraryFile =
+ context.resolveResult.libraryElement.source.fullName;
DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
await changeBuilder.addFileEdit(libraryFile,
(DartFileEditBuilder builder) {
@@ -2273,8 +2225,7 @@
}
// Find new top-level declarations.
{
- List<TopLevelDeclarationInSource> declarations =
- await getTopLevelDeclarations(name);
+ var declarations = await session.getTopLevelDeclarations(name);
for (TopLevelDeclarationInSource declaration in declarations) {
// Check the kind.
if (declaration.declaration.kind != kind2) {
@@ -2431,7 +2382,7 @@
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
ClassDeclaration enclosingClass =
- node.getAncestor((node) => node is ClassDeclaration);
+ node.thisOrAncestorOfType<ClassDeclaration>();
if (enclosingClass == null) {
return;
}
@@ -2457,9 +2408,9 @@
!getter.variable.isSynthetic &&
getter.variable.setter == null &&
getter.enclosingElement is ClassElement) {
- AstNode name =
- await astProvider.getParsedNameForElement(getter.variable);
- AstNode variable = name?.parent;
+ var declarationResult =
+ await sessionHelper.getElementDeclaration(getter.variable);
+ AstNode variable = declarationResult.node;
if (variable is VariableDeclaration &&
variable.parent is VariableDeclarationList &&
variable.parent.parent is FieldDeclaration) {
@@ -2580,6 +2531,7 @@
} else if (coveringNode is Block) {
Block block = coveringNode;
List<Statement> statementsToRemove = <Statement>[];
+ var errorRange = SourceRange(errorOffset, errorLength);
for (Statement statement in block.statements) {
if (range.node(statement).intersects(errorRange)) {
statementsToRemove.add(statement);
@@ -2667,7 +2619,7 @@
await null;
// Retrieve the linted node.
VariableDeclaration ancestor =
- node.getAncestor((a) => a is VariableDeclaration);
+ node.thisOrAncestorOfType<VariableDeclaration>();
if (ancestor == null) {
return;
}
@@ -2692,7 +2644,7 @@
builder.addDeletion(range.token(right));
});
_addFixFromBuilder(
- changeBuilder, DartFixKind.LINT_REMOVE_INTERPOLATION_BRACES);
+ changeBuilder, DartFixKind.REMOVE_INTERPOLATION_BRACES);
} else {}
}
}
@@ -2701,7 +2653,7 @@
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
MethodDeclaration declaration =
- node.getAncestor((node) => node is MethodDeclaration);
+ node.thisOrAncestorOfType<MethodDeclaration>();
if (declaration != null) {
DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
@@ -2759,7 +2711,7 @@
await null;
final thisExpression = node is ThisExpression
? node
- : node.getAncestor((node) => node is ThisExpression);
+ : node.thisOrAncestorOfType<ThisExpression>();
final parent = thisExpression?.parent;
if (parent is PropertyAccess) {
DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
@@ -2779,14 +2731,13 @@
Future<void> _addFix_removeTypeAnnotation() async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
- final TypeAnnotation type =
- node.getAncestor((node) => node is TypeAnnotation);
+ final TypeAnnotation type = node.thisOrAncestorOfType<TypeAnnotation>();
if (type != null) {
DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
builder.addDeletion(range.startStart(type, type.endToken.next));
});
- _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_TYPE_NAME);
+ _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_TYPE_ANNOTATION);
}
}
@@ -2861,7 +2812,7 @@
await null;
// prepare ImportDirective
ImportDirective importDirective =
- node.getAncestor((node) => node is ImportDirective);
+ node.thisOrAncestorOfType<ImportDirective>();
if (importDirective == null) {
return;
}
@@ -2892,11 +2843,11 @@
List<SimpleIdentifier> references;
Element element = identifier.staticElement;
if (element is LocalVariableElement) {
- AstNode root = node.getAncestor((node) => node is Block);
+ AstNode root = node.thisOrAncestorOfType<Block>();
references = findLocalElementReferences(root, element);
} else if (element is ParameterElement) {
if (!element.isNamed) {
- AstNode root = node.getAncestor((node) =>
+ AstNode root = node.thisOrAncestorMatching((node) =>
node.parent is ClassOrMixinDeclaration ||
node.parent is CompilationUnit);
references = findLocalElementReferences(root, element);
@@ -2943,9 +2894,8 @@
Future<void> _addFix_replaceWithConditionalAssignment() async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
- IfStatement ifStatement = node is IfStatement
- ? node
- : node.getAncestor((node) => node is IfStatement);
+ IfStatement ifStatement =
+ node is IfStatement ? node : node.thisOrAncestorOfType<IfStatement>();
if (ifStatement == null) {
return;
}
@@ -3000,7 +2950,7 @@
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
final FunctionTypedFormalParameter functionTyped =
- node.getAncestor((node) => node is FunctionTypedFormalParameter);
+ node.thisOrAncestorOfType<FunctionTypedFormalParameter>();
if (functionTyped != null) {
DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
@@ -3017,7 +2967,7 @@
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
final InstanceCreationExpression instanceCreation =
- node.getAncestor((node) => node is InstanceCreationExpression);
+ node.thisOrAncestorOfType<InstanceCreationExpression>();
final InterfaceType type = instanceCreation.staticType;
final generics = instanceCreation.constructorName.type.typeArguments;
DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
@@ -3041,7 +2991,7 @@
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
FunctionExpression ancestor =
- node.getAncestor((a) => a is FunctionExpression);
+ node.thisOrAncestorOfType<FunctionExpression>();
if (ancestor == null) {
return;
}
@@ -3168,8 +3118,7 @@
new _ClosestElementFinder(name, predicate, MAX_LEVENSHTEIN_DISTANCE);
// unqualified invocation
if (target == null) {
- ClassDeclaration clazz =
- node.getAncestor((node) => node is ClassDeclaration);
+ ClassDeclaration clazz = node.thisOrAncestorOfType<ClassDeclaration>();
if (clazz != null) {
ClassElement classElement = clazz.declaredElement;
_updateFinderWithClassMembers(finder, classElement);
@@ -3213,7 +3162,7 @@
int insertOffset;
String sourcePrefix;
AstNode enclosingMember =
- node.getAncestor((node) => node is CompilationUnitMember);
+ node.thisOrAncestorOfType<CompilationUnitMember>();
insertOffset = enclosingMember.end;
sourcePrefix = '$eol$eol';
utils.targetClassElement = null;
@@ -3301,12 +3250,12 @@
Element targetElement;
bool staticModifier = false;
- ClassDeclaration targetClassNode;
+ ClassOrMixinDeclaration targetClassNode;
Expression target = invocation.realTarget;
+ CorrectionUtils utils = this.utils;
if (target == null) {
- targetElement = unitElement;
- ClassMember enclosingMember =
- node.getAncestor((node) => node is ClassMember);
+ targetElement = unit.declaredElement;
+ ClassMember enclosingMember = node.thisOrAncestorOfType<ClassMember>();
if (enclosingMember == null) {
// If the undefined identifier isn't inside a class member, then it
// doesn't make sense to create a method.
@@ -3327,11 +3276,10 @@
}
targetElement = targetClassElement;
// prepare target ClassDeclaration
- AstNode targetTypeNode = getParsedClassElementNode(targetClassElement);
- if (targetTypeNode is! ClassDeclaration) {
+ targetClassNode = await _getClassDeclaration(targetClassElement);
+ if (targetClassNode == null) {
return;
}
- targetClassNode = targetTypeNode;
// maybe static
if (target is Identifier) {
staticModifier =
@@ -3339,10 +3287,9 @@
ElementKind.CLASS;
}
// use different utils
- CompilationUnitElement targetUnitElement =
- getCompilationUnitElement(targetClassElement);
- CompilationUnit targetUnit = getParsedUnit(targetUnitElement);
- utils = new CorrectionUtils(targetUnit);
+ var targetPath = targetClassElement.source.fullName;
+ var targetResolveResult = await session.getResolvedUnit(targetPath);
+ utils = CorrectionUtils(targetResolveResult);
}
ClassMemberLocation targetLocation =
utils.prepareNewMethodLocation(targetClassNode);
@@ -3392,22 +3339,6 @@
}
}
- Future<void> _addFix_undefinedMethodWithContructor() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
- if (node is SimpleIdentifier && node.parent is MethodInvocation) {
- DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
- await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
- builder.addSimpleInsertion(node.parent.offset, 'new ');
- });
- _addFixFromBuilder(
- changeBuilder, DartFixKind.INVOKE_CONSTRUCTOR_USING_NEW);
- // TODO(brianwilkerson) Figure out whether the constructor is a `const`
- // constructor and all of the parameters are constant expressions, and
- // suggest inserting 'const ' if so.
- }
- }
-
/**
* Here we handle cases when a constructors does not initialize all of the
* final fields.
@@ -3474,6 +3405,53 @@
_addFixFromBuilder(changeBuilder, DartFixKind.ADD_FIELD_FORMAL_PARAMETERS);
}
+ Future<void> _addFix_updateSdkConstraints() async {
+ Context context = resourceProvider.pathContext;
+ File pubspecFile = null;
+ Folder folder = resourceProvider.getFolder(context.dirname(file));
+ while (folder != null) {
+ pubspecFile = folder.getChildAssumingFile('pubspec.yaml');
+ if (pubspecFile.exists) {
+ break;
+ }
+ pubspecFile = null;
+ folder = folder.parent;
+ }
+ if (pubspecFile == null) {
+ return;
+ }
+ SdkConstraintExtractor extractor = new SdkConstraintExtractor(pubspecFile);
+ String text = extractor.constraintText();
+ int offset = extractor.constraintOffset();
+ int length = text.length;
+ if (text == null || offset < 0) {
+ return;
+ }
+ String newText;
+ int spaceOffset = text.indexOf(' ');
+ if (spaceOffset >= 0) {
+ length = spaceOffset;
+ }
+ if (text == 'any') {
+ newText = '^2.1.0';
+ } else if (text.startsWith('^')) {
+ newText = '^2.1.0';
+ } else if (text.startsWith('>=')) {
+ newText = '>=2.1.0';
+ } else if (text.startsWith('>')) {
+ newText = '>=2.1.0';
+ }
+ if (newText == null) {
+ return;
+ }
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
+ await changeBuilder.addFileEdit(pubspecFile.path,
+ (DartFileEditBuilder builder) {
+ builder.addSimpleReplacement(new SourceRange(offset, length), newText);
+ });
+ _addFixFromBuilder(changeBuilder, DartFixKind.UPDATE_SDK_CONSTRAINTS);
+ }
+
Future<void> _addFix_useEffectiveIntegerDivision() async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
@@ -3564,7 +3542,7 @@
Future<DartChangeBuilder> _addProposal_createFunction(
FunctionType functionType,
String name,
- Source targetSource,
+ String targetFile,
int insertOffset,
bool isStatic,
String prefix,
@@ -3574,7 +3552,6 @@
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
// build method source
- String targetFile = targetSource.fullName;
DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
await changeBuilder.addFileEdit(targetFile, (DartFileEditBuilder builder) {
builder.addInsertion(insertOffset, (DartEditBuilder builder) {
@@ -3622,7 +3599,7 @@
builder.write(' {$eol$prefix}');
builder.write(sourceSuffix);
});
- if (targetSource == unitSource) {
+ if (targetFile == file) {
builder.addLinkedPosition(range.node(node), 'NAME');
}
});
@@ -3647,13 +3624,13 @@
DartChangeBuilder changeBuilder = await _addProposal_createFunction(
functionType,
name,
- unitSource,
+ file,
insertOffset,
false,
prefix,
sourcePrefix,
sourceSuffix,
- unitElement);
+ unit.declaredElement);
_addFixFromBuilder(changeBuilder, DartFixKind.CREATE_FUNCTION,
args: [name]);
}
@@ -3670,13 +3647,15 @@
// prepare environment
Source targetSource = targetClassElement.source;
// prepare insert offset
- ClassDeclaration targetClassNode =
- getParsedClassElementNode(targetClassElement);
- int insertOffset = targetClassNode.end - 1;
+ var targetNode = await _getClassDeclaration(targetClassElement);
+ if (targetNode == null) {
+ return;
+ }
+ int insertOffset = targetNode.end - 1;
// prepare prefix
String prefix = ' ';
String sourcePrefix;
- if (targetClassNode.members.isEmpty) {
+ if (targetNode.members.isEmpty) {
sourcePrefix = '';
} else {
sourcePrefix = eol;
@@ -3685,7 +3664,7 @@
DartChangeBuilder changeBuilder = await _addProposal_createFunction(
functionType,
name,
- targetSource,
+ targetSource.fullName,
insertOffset,
_inStaticContext(),
prefix,
@@ -3696,48 +3675,15 @@
}
/**
- * Computes the name of the library at the given [path].
- * See https://www.dartlang.org/articles/style-guide/#names for conventions.
+ * Returns the [ClassOrMixinDeclaration] for the given [element].
*/
- String _computeLibraryName(String path) {
- Context pathContext = resourceProvider.pathContext;
- String packageFolder = _computePackageFolder(path);
- if (packageFolder == null) {
- return pathContext.basenameWithoutExtension(path);
+ Future<ClassOrMixinDeclaration> _getClassDeclaration(
+ ClassElement element) async {
+ var result = await sessionHelper.getElementDeclaration(element);
+ if (result.node is ClassOrMixinDeclaration) {
+ return result.node;
}
- String packageName = pathContext.basename(packageFolder);
- String relPath = pathContext.relative(path, from: packageFolder);
- List<String> relPathParts = pathContext.split(relPath);
- if (relPathParts.isNotEmpty) {
- if (relPathParts[0].toLowerCase() == 'lib') {
- relPathParts.removeAt(0);
- }
- if (relPathParts.isNotEmpty) {
- String nameWithoutExt = pathContext.withoutExtension(relPathParts.last);
- relPathParts[relPathParts.length - 1] = nameWithoutExt;
- }
- }
- return packageName + '.' + relPathParts.join('.');
- }
-
- /**
- * Returns the path of the folder which contains the given [path].
- */
- String _computePackageFolder(String path) {
- Context pathContext = resourceProvider.pathContext;
- String pubspecFolder = dirname(path);
- while (true) {
- if (resourceProvider
- .getResource(pathContext.join(pubspecFolder, 'pubspec.yaml'))
- .exists) {
- return pubspecFolder;
- }
- String pubspecFolderNew = pathContext.dirname(pubspecFolder);
- if (pubspecFolderNew == pubspecFolder) {
- return null;
- }
- pubspecFolder = pubspecFolderNew;
- }
+ return null;
}
/**
@@ -3774,26 +3720,6 @@
}
/**
- * Return the correction utilities that should be used when creating an edit
- * in the compilation unit containing the given [node].
- */
- CorrectionUtils _getUtilsFor(AstNode node) {
- CompilationUnit targetUnit =
- node.getAncestor((node) => node is CompilationUnit);
- CompilationUnitElement targetUnitElement = targetUnit?.declaredElement;
- CorrectionUtils realUtils = utils;
- if (targetUnitElement != utils.unit.declaredElement) {
- realUtils = new CorrectionUtils(targetUnit);
- ClassDeclaration targetClass =
- node.getAncestor((node) => node is ClassDeclaration);
- if (targetClass != null) {
- realUtils.targetClassElement = targetClass.declaredElement;
- }
- }
- return realUtils;
- }
-
- /**
* Returns an expected [DartType] of [expression], may be `null` if cannot be
* inferred.
*/
@@ -3924,17 +3850,15 @@
*/
bool _inStaticContext() {
// constructor initializer cannot reference "this"
- if (node.getAncestor((node) => node is ConstructorInitializer) != null) {
+ if (node.thisOrAncestorOfType<ConstructorInitializer>() != null) {
return true;
}
// field initializer cannot reference "this"
- if (node.getAncestor((node) => node is FieldDeclaration) != null) {
+ if (node.thisOrAncestorOfType<FieldDeclaration>() != null) {
return true;
}
// static method
- MethodDeclaration method = node.getAncestor((node) {
- return node is MethodDeclaration;
- });
+ MethodDeclaration method = node.thisOrAncestorOfType<MethodDeclaration>();
return method != null && method.isStatic;
}
@@ -3999,24 +3923,24 @@
}
/**
- * Return `true` if the [source] can be imported into [unitLibraryFile].
+ * Return `true` if the [source] can be imported into current library.
*/
bool _isSourceVisibleToLibrary(Source source) {
String path = source.fullName;
- ContextRoot contextRoot = driver.contextRoot;
+ var contextRoot = context.resolveResult.session.analysisContext.contextRoot;
if (contextRoot == null) {
return true;
}
// We don't want to use private libraries of other packages.
if (source.uri.isScheme('package') && _isLibSrcPath(path)) {
- return resourceProvider.pathContext.isWithin(contextRoot.root, path);
+ return contextRoot.root.contains(path);
}
// We cannot use relative URIs to reference files outside of our package.
if (source.uri.isScheme('file')) {
- return resourceProvider.pathContext.isWithin(contextRoot.root, path);
+ return contextRoot.root.contains(path);
}
return true;
@@ -4181,14 +4105,15 @@
* [ExecutableElement], its parameters, and operations on them.
*/
class _ExecutableParameters {
- final AstProvider astProvider;
+ final AnalysisSessionHelper sessionHelper;
final ExecutableElement executable;
final List<ParameterElement> required = [];
final List<ParameterElement> optionalPositional = [];
final List<ParameterElement> named = [];
- factory _ExecutableParameters(AstProvider astProvider, AstNode invocation) {
+ factory _ExecutableParameters(
+ AnalysisSessionHelper sessionHelper, AstNode invocation) {
Element element;
if (invocation is InstanceCreationExpression) {
element = invocation.staticElement;
@@ -4196,14 +4121,14 @@
if (invocation is MethodInvocation) {
element = invocation.methodName.staticElement;
}
- if (element is ExecutableElement) {
- return new _ExecutableParameters._(astProvider, element);
+ if (element is ExecutableElement && !element.isSynthetic) {
+ return new _ExecutableParameters._(sessionHelper, element);
} else {
return null;
}
}
- _ExecutableParameters._(this.astProvider, this.executable) {
+ _ExecutableParameters._(this.sessionHelper, this.executable) {
for (var parameter in executable.parameters) {
if (parameter.isNotOptional) {
required.add(parameter);
@@ -4222,10 +4147,8 @@
* be found.
*/
Future<FormalParameterList> getParameterList() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
- var name = await astProvider.getParsedNameForElement(executable);
- AstNode targetDeclaration = name?.parent;
+ var result = await sessionHelper.getElementDeclaration(executable);
+ var targetDeclaration = result.node;
if (targetDeclaration is ConstructorDeclaration) {
return targetDeclaration.parameters;
} else if (targetDeclaration is FunctionDeclaration) {
@@ -4242,10 +4165,9 @@
* or `null` is cannot be found.
*/
Future<FormalParameter> getParameterNode(ParameterElement element) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
- var name = await astProvider.getParsedNameForElement(element);
- for (AstNode node = name; node != null; node = node.parent) {
+ var result = await sessionHelper.getElementDeclaration(element);
+ var declaration = result.node;
+ for (AstNode node = declaration; node != null; node = node.parent) {
if (node is FormalParameter && node.parent is FormalParameterList) {
return node;
}
diff --git a/pkg/analysis_server/lib/src/services/correction/name_suggestion.dart b/pkg/analysis_server/lib/src/services/correction/name_suggestion.dart
index 46fa120..e8da43f 100644
--- a/pkg/analysis_server/lib/src/services/correction/name_suggestion.dart
+++ b/pkg/analysis_server/lib/src/services/correction/name_suggestion.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -8,7 +8,7 @@
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer_plugin/src/utilities/string_utilities.dart';
-List<String> _KNOWN_METHOD_NAME_PREFIXES = ['get', 'is', 'to'];
+final List<String> _KNOWN_METHOD_NAME_PREFIXES = ['get', 'is', 'to'];
/**
* Returns all variants of names by removing leading words one by one.
@@ -37,7 +37,7 @@
if (isMethod) {
// If we're in a build() method, use 'build' as the name prefix.
MethodDeclaration method =
- assignedExpression.getAncestor((n) => n is MethodDeclaration);
+ assignedExpression.thisOrAncestorOfType<MethodDeclaration>();
if (method != null) {
String enclosingName = method.name?.name;
if (enclosingName != null && enclosingName.startsWith('build')) {
diff --git a/pkg/analysis_server/lib/src/services/correction/namespace.dart b/pkg/analysis_server/lib/src/services/correction/namespace.dart
index 1419922..a3bdd84 100644
--- a/pkg/analysis_server/lib/src/services/correction/namespace.dart
+++ b/pkg/analysis_server/lib/src/services/correction/namespace.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -18,15 +18,6 @@
}
/**
- * Returns the namespace of the given [ExportElement].
- */
-Map<String, Element> getExportNamespaceForDirective(ExportElement exp) {
- Namespace namespace =
- new NamespaceBuilder().createExportNamespaceForDirective(exp);
- return namespace.definedNames;
-}
-
-/**
* Returns the export namespace of the given [LibraryElement].
*/
Map<String, Element> getExportNamespaceForLibrary(LibraryElement library) {
@@ -45,8 +36,7 @@
if (parent is ImportDirective) {
return parent.element;
}
- ImportElementInfo info = internal_getImportElementInfo(prefixNode);
- return info?.element;
+ return internal_getImportElementInfo(prefixNode);
}
/**
@@ -130,15 +120,13 @@
}
/**
- * Returns the [ImportElementInfo] with the [ImportElement] that is referenced
- * by [prefixNode] with a [PrefixElement], maybe `null`.
+ * Returns the [ImportElement] that is referenced by [prefixNode] with a
+ * [PrefixElement], maybe `null`.
*/
-ImportElementInfo internal_getImportElementInfo(SimpleIdentifier prefixNode) {
- ImportElementInfo info = new ImportElementInfo();
+ImportElement internal_getImportElementInfo(SimpleIdentifier prefixNode) {
// prepare environment
AstNode parent = prefixNode.parent;
- CompilationUnit unit =
- prefixNode.getAncestor((node) => node is CompilationUnit);
+ CompilationUnit unit = prefixNode.thisOrAncestorOfType<CompilationUnit>();
LibraryElement libraryElement =
resolutionMap.elementDeclaredByCompilationUnit(unit).library;
// prepare used element
@@ -147,14 +135,12 @@
PrefixedIdentifier prefixed = parent;
if (prefixed.prefix == prefixNode) {
usedElement = prefixed.staticElement;
- info.periodEnd = prefixed.period.end;
}
}
if (parent is MethodInvocation) {
MethodInvocation invocation = parent;
if (invocation.target == prefixNode) {
usedElement = invocation.methodName.staticElement;
- info.periodEnd = invocation.operator.end;
}
}
// we need used Element
@@ -164,12 +150,8 @@
// find ImportElement
String prefix = prefixNode.name;
Map<ImportElement, Set<Element>> importElementsMap = {};
- info.element = internal_getImportElement(
+ return internal_getImportElement(
libraryElement, prefix, usedElement, importElementsMap);
- if (info.element == null) {
- return null;
- }
- return info;
}
/**
@@ -178,5 +160,4 @@
*/
class ImportElementInfo {
ImportElement element;
- int periodEnd;
}
diff --git a/pkg/analysis_server/lib/src/services/correction/selection_analyzer.dart b/pkg/analysis_server/lib/src/services/correction/selection_analyzer.dart
index 9b026bd..3b9b505 100644
--- a/pkg/analysis_server/lib/src/services/correction/selection_analyzer.dart
+++ b/pkg/analysis_server/lib/src/services/correction/selection_analyzer.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -10,7 +10,7 @@
/**
* A visitor for visiting [AstNode]s covered by a selection [SourceRange].
*/
-class SelectionAnalyzer extends GeneralizingAstVisitor<Object> {
+class SelectionAnalyzer extends GeneralizingAstVisitor<void> {
final SourceRange selection;
AstNode _coveringNode;
@@ -57,19 +57,6 @@
}
/**
- * Returns the [SourceRange] which covers selected [AstNode]s, may be `null`
- * if there are no [AstNode]s under the selection.
- */
- SourceRange get selectedNodeRange {
- if (_selectedNodes == null || _selectedNodes.isEmpty) {
- return null;
- }
- AstNode firstNode = _selectedNodes[0];
- AstNode lastNode = _selectedNodes[_selectedNodes.length - 1];
- return range.startEnd(firstNode, lastNode);
- }
-
- /**
* Return the [AstNode]s fully covered by the selection [SourceRange].
*/
List<AstNode> get selectedNodes {
@@ -114,7 +101,7 @@
}
@override
- Object visitNode(AstNode node) {
+ void visitNode(AstNode node) {
SourceRange nodeRange = range.node(node);
if (selection.covers(nodeRange)) {
if (isFirstNode) {
@@ -122,21 +109,20 @@
} else {
handleNextSelectedNode(node);
}
- return null;
+ return;
} else if (selection.coveredBy(nodeRange)) {
_coveringNode = node;
node.visitChildren(this);
- return null;
+ return;
} else if (selection.startsIn(nodeRange)) {
handleSelectionStartsIn(node);
node.visitChildren(this);
- return null;
+ return;
} else if (selection.endsIn(nodeRange)) {
handleSelectionEndsIn(node);
node.visitChildren(this);
- return null;
+ return;
}
// no intersection
- return null;
}
}
diff --git a/pkg/analysis_server/lib/src/services/correction/sort_members.dart b/pkg/analysis_server/lib/src/services/correction/sort_members.dart
index 1bd8aef8..04baf5f 100644
--- a/pkg/analysis_server/lib/src/services/correction/sort_members.dart
+++ b/pkg/analysis_server/lib/src/services/correction/sort_members.dart
@@ -20,6 +20,8 @@
new _PriorityItem(false, _MemberKind.UNIT_ACCESSOR, true),
new _PriorityItem(false, _MemberKind.UNIT_FUNCTION, false),
new _PriorityItem(false, _MemberKind.UNIT_FUNCTION, true),
+ new _PriorityItem(false, _MemberKind.UNIT_GENERIC_TYPE_ALIAS, false),
+ new _PriorityItem(false, _MemberKind.UNIT_GENERIC_TYPE_ALIAS, true),
new _PriorityItem(false, _MemberKind.UNIT_FUNCTION_TYPE, false),
new _PriorityItem(false, _MemberKind.UNIT_FUNCTION_TYPE, true),
new _PriorityItem(false, _MemberKind.UNIT_CLASS, false),
@@ -83,21 +85,20 @@
}
/**
- * Sorts all members of all [ClassDeclaration]s.
+ * Sorts all members of all [ClassOrMixinDeclaration]s.
*/
void _sortClassesMembers() {
for (CompilationUnitMember unitMember in unit.declarations) {
- if (unitMember is ClassDeclaration) {
- ClassDeclaration classDeclaration = unitMember;
- _sortClassMembers(classDeclaration);
+ if (unitMember is ClassOrMixinDeclaration) {
+ _sortClassMembers(unitMember);
}
}
}
/**
- * Sorts all members of the given [ClassDeclaration].
+ * Sorts all members of the given [classDeclaration].
*/
- void _sortClassMembers(ClassDeclaration classDeclaration) {
+ void _sortClassMembers(ClassOrMixinDeclaration classDeclaration) {
List<_MemberInfo> members = <_MemberInfo>[];
for (ClassMember member in classDeclaration.members) {
_MemberKind kind = null;
@@ -272,7 +273,7 @@
for (CompilationUnitMember member in unit.declarations) {
_MemberKind kind = null;
String name = null;
- if (member is ClassDeclaration) {
+ if (member is ClassOrMixinDeclaration) {
kind = _MemberKind.UNIT_CLASS;
name = member.name.name;
}
@@ -305,6 +306,10 @@
kind = _MemberKind.UNIT_FUNCTION_TYPE;
name = member.name.name;
}
+ if (member is GenericTypeAlias) {
+ kind = _MemberKind.UNIT_GENERIC_TYPE_ALIAS;
+ name = member.name.name;
+ }
if (member is TopLevelVariableDeclaration) {
TopLevelVariableDeclaration variableDeclaration = member;
List<VariableDeclaration> variables =
@@ -458,14 +463,16 @@
static const UNIT_FUNCTION_MAIN = const _MemberKind('UNIT_FUNCTION_MAIN', 0);
static const UNIT_ACCESSOR = const _MemberKind('UNIT_ACCESSOR', 1);
static const UNIT_FUNCTION = const _MemberKind('UNIT_FUNCTION', 2);
- static const UNIT_FUNCTION_TYPE = const _MemberKind('UNIT_FUNCTION_TYPE', 3);
- static const UNIT_CLASS = const _MemberKind('UNIT_CLASS', 4);
- static const UNIT_VARIABLE_CONST = const _MemberKind('UNIT_VARIABLE', 5);
- static const UNIT_VARIABLE = const _MemberKind('UNIT_VARIABLE', 6);
- static const CLASS_ACCESSOR = const _MemberKind('CLASS_ACCESSOR', 7);
- static const CLASS_CONSTRUCTOR = const _MemberKind('CLASS_CONSTRUCTOR', 8);
- static const CLASS_FIELD = const _MemberKind('CLASS_FIELD', 9);
- static const CLASS_METHOD = const _MemberKind('CLASS_METHOD', 10);
+ static const UNIT_GENERIC_TYPE_ALIAS =
+ const _MemberKind('UNIT_GENERIC_TYPE_ALIAS', 3);
+ static const UNIT_FUNCTION_TYPE = const _MemberKind('UNIT_FUNCTION_TYPE', 4);
+ static const UNIT_CLASS = const _MemberKind('UNIT_CLASS', 5);
+ static const UNIT_VARIABLE_CONST = const _MemberKind('UNIT_VARIABLE', 6);
+ static const UNIT_VARIABLE = const _MemberKind('UNIT_VARIABLE', 7);
+ static const CLASS_ACCESSOR = const _MemberKind('CLASS_ACCESSOR', 8);
+ static const CLASS_CONSTRUCTOR = const _MemberKind('CLASS_CONSTRUCTOR', 9);
+ static const CLASS_FIELD = const _MemberKind('CLASS_FIELD', 10);
+ static const CLASS_METHOD = const _MemberKind('CLASS_METHOD', 11);
final String name;
final int ordinal;
diff --git a/pkg/analysis_server/lib/src/services/correction/source_buffer.dart b/pkg/analysis_server/lib/src/services/correction/source_buffer.dart
index 24d6848..a414cd5 100644
--- a/pkg/analysis_server/lib/src/services/correction/source_buffer.dart
+++ b/pkg/analysis_server/lib/src/services/correction/source_buffer.dart
@@ -2,9 +2,6 @@
// 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:analyzer/src/generated/source.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
-
/**
* Helper for building Dart source with linked positions.
*/
@@ -13,18 +10,10 @@
final int offset;
final StringBuffer _buffer = new StringBuffer();
- final Map<String, LinkedEditGroup> linkedPositionGroups =
- <String, LinkedEditGroup>{};
- LinkedEditGroup _currentLinkedPositionGroup;
- int _currentPositionStart;
int _exitOffset;
SourceBuilder(this.file, this.offset);
- SourceBuilder.buffer()
- : file = null,
- offset = 0;
-
/**
* Returns the exit offset, maybe `null` if not set.
*/
@@ -37,15 +26,6 @@
int get length => _buffer.length;
- void addSuggestion(LinkedEditSuggestionKind kind, String value) {
- var suggestion = new LinkedEditSuggestion(value, kind);
- _currentLinkedPositionGroup.addSuggestion(suggestion);
- }
-
- void addSuggestions(LinkedEditSuggestionKind kind, List<String> values) {
- values.forEach((value) => addSuggestion(kind, value));
- }
-
/**
* Appends [s] to the buffer.
*/
@@ -55,45 +35,12 @@
}
/**
- * Ends position started using [startPosition].
- */
- void endPosition() {
- assert(_currentLinkedPositionGroup != null);
- _addPosition();
- _currentLinkedPositionGroup = null;
- }
-
- /**
* Marks the current offset as an "exit" one.
*/
void setExitOffset() {
_exitOffset = _buffer.length;
}
- /**
- * Marks start of a new linked position for the group with the given ID.
- */
- void startPosition(String id) {
- assert(_currentLinkedPositionGroup == null);
- _currentLinkedPositionGroup = linkedPositionGroups[id];
- if (_currentLinkedPositionGroup == null) {
- _currentLinkedPositionGroup = new LinkedEditGroup.empty();
- linkedPositionGroups[id] = _currentLinkedPositionGroup;
- }
- _currentPositionStart = _buffer.length;
- }
-
@override
String toString() => _buffer.toString();
-
- /**
- * Adds position location [SourceRange] using current fields.
- */
- void _addPosition() {
- int start = offset + _currentPositionStart;
- int end = offset + _buffer.length;
- int length = end - start;
- Position position = new Position(file, start);
- _currentLinkedPositionGroup.addPosition(position, length);
- }
}
diff --git a/pkg/analysis_server/lib/src/services/correction/statement_analyzer.dart b/pkg/analysis_server/lib/src/services/correction/statement_analyzer.dart
index 3a5b1af..db39ca8 100644
--- a/pkg/analysis_server/lib/src/services/correction/statement_analyzer.dart
+++ b/pkg/analysis_server/lib/src/services/correction/statement_analyzer.dart
@@ -6,9 +6,9 @@
import 'package:analysis_server/src/services/correction/selection_analyzer.dart';
import 'package:analysis_server/src/services/correction/status.dart';
import 'package:analysis_server/src/services/correction/util.dart';
+import 'package:analyzer/dart/analysis/results.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/src/dart/scanner/reader.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart';
import 'package:analyzer/src/generated/source.dart';
@@ -37,11 +37,12 @@
* Analyzer to check if a selection covers a valid set of statements of AST.
*/
class StatementAnalyzer extends SelectionAnalyzer {
- final CompilationUnit unit;
+ final ResolvedUnitResult resolveResult;
final RefactoringStatus _status = new RefactoringStatus();
- StatementAnalyzer(this.unit, SourceRange selection) : super(selection);
+ StatementAnalyzer(this.resolveResult, SourceRange selection)
+ : super(selection);
/**
* Returns the [RefactoringStatus] result of selection checking.
@@ -49,6 +50,13 @@
RefactoringStatus get status => _status;
/**
+ * Analyze the selection, compute [status] and nodes.
+ */
+ void analyze() {
+ resolveResult.unit.accept(this);
+ }
+
+ /**
* Records fatal error with given message and [Location].
*/
void invalidSelection(String message, [Location context]) {
@@ -68,7 +76,7 @@
{
int selectionStart = selection.offset;
int selectionEnd = selection.end;
- List<SourceRange> commentRanges = getCommentRanges(unit);
+ List<SourceRange> commentRanges = getCommentRanges(resolveResult.unit);
for (SourceRange commentRange in commentRanges) {
if (commentRange.contains(selectionStart)) {
invalidSelection("Selection begins inside a comment.");
@@ -204,8 +212,7 @@
* Returns `true` if there are [Token]s in the given [SourceRange].
*/
bool _hasTokens(SourceRange range) {
- CompilationUnitElement unitElement = unit.declaredElement;
- String fullText = unitElement.context.getContents(unitElement.source).data;
+ String fullText = resolveResult.content;
String rangeText = fullText.substring(range.offset, range.end);
return _getTokens(rangeText).isNotEmpty;
}
diff --git a/pkg/analysis_server/lib/src/services/correction/strings.dart b/pkg/analysis_server/lib/src/services/correction/strings.dart
index 33a4c6a..125fc14 100644
--- a/pkg/analysis_server/lib/src/services/correction/strings.dart
+++ b/pkg/analysis_server/lib/src/services/correction/strings.dart
@@ -12,11 +12,6 @@
const int CHAR_DOLLAR = 0x24;
/**
- * "."
- */
-const int CHAR_DOT = 0x2E;
-
-/**
* "_"
*/
const int CHAR_UNDERSCORE = 0x5F;
@@ -98,39 +93,6 @@
}
/**
- * Returns the number of characters common to the end of [a] and the start
- * of [b].
- */
-int findCommonOverlap(String a, String b) {
- int a_length = a.length;
- int b_length = b.length;
- // all empty
- if (a_length == 0 || b_length == 0) {
- return 0;
- }
- // truncate
- if (a_length > b_length) {
- a = a.substring(a_length - b_length);
- } else if (a_length < b_length) {
- b = b.substring(0, a_length);
- }
- int text_length = min(a_length, b_length);
- // the worst case
- if (a == b) {
- return text_length;
- }
- // increase common length one by one
- int length = 0;
- while (length < text_length) {
- if (a.codeUnitAt(text_length - 1 - length) != b.codeUnitAt(length)) {
- break;
- }
- length++;
- }
- return length;
-}
-
-/**
* Return the number of characters common to the start of [a] and [b].
*/
int findCommonPrefix(String a, String b) {
@@ -193,13 +155,6 @@
return isSpace(c) || isEOL(c);
}
-String remove(String str, String remove) {
- if (isEmpty(str) || isEmpty(remove)) {
- return str;
- }
- return str.replaceAll(remove, '');
-}
-
String removeEnd(String str, String remove) {
if (isEmpty(str) || isEmpty(remove)) {
return str;
@@ -233,24 +188,6 @@
}
/**
- * Gets the substring after the last occurrence of a separator.
- * The separator is not returned.
- */
-String substringAfterLast(String str, String separator) {
- if (isEmpty(str)) {
- return str;
- }
- if (isEmpty(separator)) {
- return '';
- }
- int pos = str.lastIndexOf(separator);
- if (pos == -1) {
- return str;
- }
- return str.substring(pos + separator.length);
-}
-
-/**
* Information about a single replacement that should be made to convert the
* "old" string to the "new" one.
*/
diff --git a/pkg/analysis_server/lib/src/services/correction/util.dart b/pkg/analysis_server/lib/src/services/correction/util.dart
index f517e04..9ea11e0 100644
--- a/pkg/analysis_server/lib/src/services/correction/util.dart
+++ b/pkg/analysis_server/lib/src/services/correction/util.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -7,6 +7,8 @@
import 'package:analysis_server/src/protocol_server.dart'
show doSourceChange_addElementEdit;
import 'package:analysis_server/src/services/correction/strings.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
@@ -15,7 +17,6 @@
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/dart/scanner/reader.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart';
-import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart'
show SourceChange, SourceEdit;
@@ -27,16 +28,11 @@
* Adds edits to the given [change] that ensure that all the [libraries] are
* imported into the given [targetLibrary].
*/
-void addLibraryImports(pathos.Context pathContext, SourceChange change,
- LibraryElement targetLibrary, Set<Source> libraries) {
- CorrectionUtils libUtils;
- try {
- CompilationUnitElement unitElement = targetLibrary.definingCompilationUnit;
- CompilationUnit unitAst = getParsedUnit(unitElement);
- libUtils = new CorrectionUtils(unitAst);
- } catch (e) {
- throw new CancelCorrectionException(exception: e);
- }
+Future<void> addLibraryImports(AnalysisSession session, SourceChange change,
+ LibraryElement targetLibrary, Set<Source> libraries) async {
+ var libraryPath = targetLibrary.source.fullName;
+ var resolveResult = await session.getResolvedUnit(libraryPath);
+ var libUtils = new CorrectionUtils(resolveResult);
String eol = libUtils.endOfLine;
// Prepare information about existing imports.
LibraryDirective libraryDirective;
@@ -46,14 +42,14 @@
libraryDirective = directive;
} else if (directive is ImportDirective) {
importDirectives.add(new _ImportDirectiveInfo(
- directive.uriContent, directive.offset, directive.end));
+ directive.uri.stringValue, directive.offset, directive.end));
}
}
// Prepare all URIs to import.
List<String> uriList = libraries
- .map((library) =>
- getLibrarySourceUri(pathContext, targetLibrary, library.uri))
+ .map((library) => getLibrarySourceUri(
+ session.resourceProvider.pathContext, targetLibrary, library.uri))
.toList();
uriList.sort((a, b) => a.compareTo(b));
@@ -235,12 +231,12 @@
}
/**
- * If the given [AstNode] is in a [ClassDeclaration], returns the
+ * If the given [AstNode] is in a [ClassOrMixinDeclaration], returns the
* [ClassElement]. Otherwise returns `null`.
*/
ClassElement getEnclosingClassElement(AstNode node) {
- ClassDeclaration enclosingClassNode =
- node.getAncestor((node) => node is ClassDeclaration);
+ ClassOrMixinDeclaration enclosingClassNode =
+ node.thisOrAncestorOfType<ClassOrMixinDeclaration>();
if (enclosingClassNode != null) {
return enclosingClassNode.declaredElement;
}
@@ -470,40 +466,6 @@
}
/**
- * Returns a parsed [AstNode] for the given [classElement].
- *
- * The resulting AST structure may or may not be resolved.
- */
-AstNode getParsedClassElementNode(ClassElement classElement) {
- CompilationUnitElement unitElement = getCompilationUnitElement(classElement);
- CompilationUnit unit = getParsedUnit(unitElement);
- int offset = classElement.nameOffset;
- AstNode classNameNode = new NodeLocator(offset).searchWithin(unit);
- if (classElement.isEnum) {
- return classNameNode.getAncestor((node) => node is EnumDeclaration);
- } else {
- return classNameNode.getAncestor(
- (node) => node is ClassDeclaration || node is ClassTypeAlias);
- }
-}
-
-/**
- * Returns a parsed [CompilationUnit] for the given [unitElement].
- *
- * The resulting AST structure may or may not be resolved.
- * If it is not resolved, then at least the given [unitElement] will be set.
- */
-CompilationUnit getParsedUnit(CompilationUnitElement unitElement) {
- AnalysisContext context = unitElement.context;
- Source source = unitElement.source;
- CompilationUnit unit = context.parseCompilationUnit(source);
- if (unit.declaredElement == null) {
- unit.element = unitElement;
- }
- return unit;
-}
-
-/**
* If given [node] is name of qualified property extraction, returns target from
* which this property is extracted, otherwise `null`.
*/
@@ -641,6 +603,8 @@
class CorrectionUtils {
final CompilationUnit unit;
+ final LibraryElement _library;
+ final String _buffer;
/**
* The [ClassElement] the generated code is inserted to, so we can decide if
@@ -650,19 +614,12 @@
ExecutableElement targetExecutableElement;
- LibraryElement _library;
- String _buffer;
String _endOfLine;
- CorrectionUtils(this.unit, {String buffer}) {
- CompilationUnitElement unitElement = unit.declaredElement;
- AnalysisContext context = unitElement.context;
- if (context == null) {
- throw new CancelCorrectionException();
- }
- this._library = unitElement.library;
- this._buffer = buffer ?? context.getContents(unitElement.source).data;
- }
+ CorrectionUtils(ResolvedUnitResult result)
+ : unit = result.unit,
+ _library = result.libraryElement,
+ _buffer = result.content;
/**
* Returns the EOL to use for this [CompilationUnit].
@@ -690,7 +647,7 @@
Set<String> findPossibleLocalVariableConflicts(int offset) {
Set<String> conflicts = new Set<String>();
AstNode enclosingNode = findNode(offset);
- Block enclosingBlock = enclosingNode.getAncestor((node) => node is Block);
+ Block enclosingBlock = enclosingNode.thisOrAncestorOfType<Block>();
if (enclosingBlock != null) {
_CollectReferencedUnprefixedNames visitor =
new _CollectReferencedUnprefixedNames();
@@ -1091,7 +1048,7 @@
* Return `true` if the given [classDeclaration] has open '{' and close '}'
* at the same line, e.g. `class X {}`.
*/
- bool isClassWithEmptyBody(ClassDeclaration classDeclaration) {
+ bool isClassWithEmptyBody(ClassOrMixinDeclaration classDeclaration) {
return getLineThis(classDeclaration.leftBracket.offset) ==
getLineThis(classDeclaration.rightBracket.offset);
}
@@ -1110,7 +1067,7 @@
}
ClassMemberLocation prepareNewClassMemberLocation(
- ClassDeclaration classDeclaration,
+ ClassOrMixinDeclaration classDeclaration,
bool shouldSkip(ClassMember existingMember)) {
String indent = getIndent(1);
// Find the last target member.
@@ -1145,13 +1102,13 @@
}
ClassMemberLocation prepareNewFieldLocation(
- ClassDeclaration classDeclaration) {
+ ClassOrMixinDeclaration classDeclaration) {
return prepareNewClassMemberLocation(
classDeclaration, (member) => member is FieldDeclaration);
}
ClassMemberLocation prepareNewGetterLocation(
- ClassDeclaration classDeclaration) {
+ ClassOrMixinDeclaration classDeclaration) {
return prepareNewClassMemberLocation(
classDeclaration,
(member) =>
@@ -1161,7 +1118,7 @@
}
ClassMemberLocation prepareNewMethodLocation(
- ClassDeclaration classDeclaration) {
+ ClassOrMixinDeclaration classDeclaration) {
return prepareNewClassMemberLocation(
classDeclaration,
(member) =>
diff --git a/pkg/analysis_server/lib/src/services/kythe/kythe_visitors.dart b/pkg/analysis_server/lib/src/services/kythe/kythe_visitors.dart
index 23c804b..24d7722 100644
--- a/pkg/analysis_server/lib/src/services/kythe/kythe_visitors.dart
+++ b/pkg/analysis_server/lib/src/services/kythe/kythe_visitors.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// 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.
@@ -14,8 +14,8 @@
import 'package:analyzer/dart/element/visitor.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/element/inheritance_manager2.dart';
-import 'package:analyzer/src/generated/bazel.dart';
-import 'package:analyzer/src/generated/gn.dart';
+import 'package:analyzer/src/workspace/bazel.dart';
+import 'package:analyzer/src/workspace/gn.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart'
show KytheEntry, KytheVName;
@@ -803,7 +803,7 @@
// Most simple identifiers are "ref" edges. In cases some cases, there may
// be other ref/* edges.
- if (node.getAncestor((node) => node is CommentReference) != null) {
+ if (node.thisOrAncestorOfType<CommentReference>() != null) {
// The identifier is in a comment, add just the "ref" edge.
_handleRefEdge(
node.staticElement,
@@ -1106,7 +1106,7 @@
/// This class is meant to be a mixin to concrete visitor methods to walk the
/// [Element] or [AstNode]s produced by the Dart Analyzer to output Kythe
/// [KytheEntry] protos.
-abstract class OutputUtils {
+mixin OutputUtils {
/// A set of [String]s which have already had a name [KytheVName] created.
final Set<String> nameNodes = new Set<String>();
diff --git a/pkg/analysis_server/lib/src/services/refactoring/convert_getter_to_method.dart b/pkg/analysis_server/lib/src/services/refactoring/convert_getter_to_method.dart
index 61dd338..94010f7 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/convert_getter_to_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/convert_getter_to_method.dart
@@ -10,10 +10,11 @@
import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart';
import 'package:analysis_server/src/services/search/hierarchy.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/analysis/session.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/src/dart/element/ast_provider.dart';
+import 'package:analyzer/src/dart/analysis/session_helper.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/utilities/range_factory.dart';
@@ -23,13 +24,13 @@
class ConvertGetterToMethodRefactoringImpl extends RefactoringImpl
implements ConvertGetterToMethodRefactoring {
final SearchEngine searchEngine;
- final AstProvider astProvider;
+ final AnalysisSession session;
final PropertyAccessorElement element;
SourceChange change;
ConvertGetterToMethodRefactoringImpl(
- this.searchEngine, this.astProvider, this.element);
+ this.searchEngine, this.session, this.element);
@override
String get refactoringName => 'Convert Getter To Method';
@@ -92,8 +93,9 @@
// prepare "get" keyword
Token getKeyword = null;
{
- AstNode name = await astProvider.getParsedNameForElement(element);
- AstNode declaration = name?.parent;
+ var sessionHelper = AnalysisSessionHelper(session);
+ var result = await sessionHelper.getElementDeclaration(element);
+ var declaration = result.node;
if (declaration is MethodDeclaration) {
getKeyword = declaration.propertyKeyword;
} else if (declaration is FunctionDeclaration) {
diff --git a/pkg/analysis_server/lib/src/services/refactoring/convert_method_to_getter.dart b/pkg/analysis_server/lib/src/services/refactoring/convert_method_to_getter.dart
index 4f38b26..e7bc247 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/convert_method_to_getter.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/convert_method_to_getter.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -12,8 +12,8 @@
import 'package:analysis_server/src/services/search/search_engine.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/analysis/session_helper.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
-import 'package:analyzer/src/dart/element/ast_provider.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/utilities/range_factory.dart';
@@ -23,13 +23,13 @@
class ConvertMethodToGetterRefactoringImpl extends RefactoringImpl
implements ConvertMethodToGetterRefactoring {
final SearchEngine searchEngine;
- final AstProvider astProvider;
+ final AnalysisSessionHelper sessionHelper;
final ExecutableElement element;
SourceChange change;
- ConvertMethodToGetterRefactoringImpl(
- this.searchEngine, this.astProvider, this.element);
+ ConvertMethodToGetterRefactoringImpl(this.searchEngine, this.element)
+ : sessionHelper = AnalysisSessionHelper(element.session);
@override
String get refactoringName => 'Convert Method To Getter';
@@ -100,8 +100,8 @@
// prepare parameters
FormalParameterList parameters;
{
- AstNode name = await astProvider.getParsedNameForElement(element);
- AstNode declaration = name?.parent;
+ var result = await sessionHelper.getElementDeclaration(element);
+ var declaration = result.node;
if (declaration is MethodDeclaration) {
parameters = declaration.parameters;
} else if (declaration is FunctionDeclaration) {
@@ -133,11 +133,11 @@
// prepare invocation
MethodInvocation invocation;
{
- CompilationUnit refUnit =
- await astProvider.getParsedUnitForElement(refElement);
- AstNode refNode =
- new NodeLocator(refRange.offset).searchWithin(refUnit);
- invocation = refNode.getAncestor((node) => node is MethodInvocation);
+ var resolvedUnit =
+ await sessionHelper.getResolvedUnitByElement(refElement);
+ var refUnit = resolvedUnit.unit;
+ var refNode = new NodeLocator(refRange.offset).searchWithin(refUnit);
+ invocation = refNode.thisOrAncestorOfType<MethodInvocation>();
}
// we need invocation
if (invocation != null) {
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
index cf9cd10..d8e0c05 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -31,7 +31,7 @@
*/
class ExtractLocalRefactoringImpl extends RefactoringImpl
implements ExtractLocalRefactoring {
- final ResolveResult resolveResult;
+ final ResolvedUnitResult resolveResult;
final int selectionOffset;
final int selectionLength;
SourceRange selectionRange;
@@ -56,7 +56,7 @@
ExtractLocalRefactoringImpl(
this.resolveResult, this.selectionOffset, this.selectionLength) {
selectionRange = new SourceRange(selectionOffset, selectionLength);
- utils = new CorrectionUtils(unit, buffer: resolveResult.content);
+ utils = new CorrectionUtils(resolveResult);
}
String get file => resolveResult.path;
@@ -319,7 +319,7 @@
// into this block. If it has an expression body, we can convert it into
// the block body first.
if (coveringNode == null ||
- coveringNode.getAncestor((node) => node is FunctionBody) == null) {
+ coveringNode.thisOrAncestorOfType<FunctionBody>() == null) {
return new RefactoringStatus.fatal(
'An expression inside a function must be selected '
'to activate this refactoring.');
@@ -414,7 +414,7 @@
return expressionBody;
}
// single Statement
- AstNode target = commonParent.getAncestor((node) => node is Statement);
+ AstNode target = commonParent.thisOrAncestorOfType<Statement>();
while (target.parent is! Block) {
target = target.parent;
}
@@ -601,7 +601,7 @@
}
}
-class _OccurrencesVisitor extends GeneralizingAstVisitor<Object> {
+class _OccurrencesVisitor extends GeneralizingAstVisitor<void> {
final ExtractLocalRefactoringImpl ref;
final List<SourceRange> occurrences;
final String selectionSource;
@@ -609,24 +609,24 @@
_OccurrencesVisitor(this.ref, this.occurrences, this.selectionSource);
@override
- Object visitBinaryExpression(BinaryExpression node) {
+ void visitBinaryExpression(BinaryExpression node) {
if (!_hasStatements(node)) {
_tryToFindOccurrenceFragments(node);
- return null;
+ return;
}
- return super.visitBinaryExpression(node);
+ super.visitBinaryExpression(node);
}
@override
- Object visitExpression(Expression node) {
+ void visitExpression(Expression node) {
if (ref._isExtractable(range.node(node))) {
_tryToFindOccurrence(node);
}
- return super.visitExpression(node);
+ super.visitExpression(node);
}
@override
- Object visitStringLiteral(StringLiteral node) {
+ void visitStringLiteral(StringLiteral node) {
if (ref.stringLiteralPart != null) {
int length = ref.stringLiteralPart.length;
String value = ref.utils.getNodeText(node);
@@ -641,9 +641,9 @@
SourceRange range = new SourceRange(start, length);
occurrences.add(range);
}
- return null;
+ return;
}
- return visitExpression(node);
+ visitExpression(node);
}
void _addOccurrence(SourceRange range) {
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
index 6969c41..bce5382 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -23,8 +23,8 @@
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/analysis/session_helper.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
-import 'package:analyzer/src/dart/element/ast_provider.dart';
import 'package:analyzer/src/generated/java_core.dart';
import 'package:analyzer/src/generated/resolver.dart' show ExitDetector;
import 'package:analyzer/src/generated/resolver.dart';
@@ -74,8 +74,7 @@
'execution flows exit. Semantics may not be preserved.';
final SearchEngine searchEngine;
- final AstProvider astProvider;
- final ResolveResult resolveResult;
+ final ResolvedUnitResult resolveResult;
final int selectionOffset;
final int selectionLength;
SourceRange selectionRange;
@@ -119,11 +118,10 @@
List<_Occurrence> _occurrences = [];
bool _staticContext = false;
- ExtractMethodRefactoringImpl(this.searchEngine, this.astProvider,
- this.resolveResult, this.selectionOffset, this.selectionLength) {
+ ExtractMethodRefactoringImpl(this.searchEngine, this.resolveResult,
+ this.selectionOffset, this.selectionLength) {
selectionRange = new SourceRange(selectionOffset, selectionLength);
- utils =
- new CorrectionUtils(resolveResult.unit, buffer: resolveResult.content);
+ utils = new CorrectionUtils(resolveResult);
}
@override
@@ -138,8 +136,7 @@
String get refactoringName {
AstNode node =
new NodeLocator(selectionOffset).searchWithin(resolveResult.unit);
- if (node != null &&
- node.getAncestor((node) => node is ClassDeclaration) != null) {
+ if (node != null && node.thisOrAncestorOfType<ClassDeclaration>() != null) {
return 'Extract Method';
}
return 'Extract Function';
@@ -394,8 +391,8 @@
}
}
// done
- addLibraryImports(resolveResult.session.resourceProvider.pathContext,
- change, resolveResult.libraryElement, librariesToImport);
+ await addLibraryImports(resolveResult.session, change,
+ resolveResult.libraryElement, librariesToImport);
return change;
}
@@ -454,8 +451,8 @@
// method of class
if (parent is ClassDeclaration) {
ClassElement classElement = parent.declaredElement;
- return validateCreateMethod(
- searchEngine, astProvider, classElement, name);
+ return validateCreateMethod(searchEngine,
+ AnalysisSessionHelper(resolveResult.session), classElement, name);
}
// OK
return new Future<RefactoringStatus>.value(result);
@@ -477,23 +474,20 @@
}
}
- _ExtractMethodAnalyzer selectionAnalyzer =
- new _ExtractMethodAnalyzer(resolveResult.unit, selectionRange);
- resolveResult.unit.accept(selectionAnalyzer);
+ var analyzer = new _ExtractMethodAnalyzer(resolveResult, selectionRange);
+ analyzer.analyze();
// May be a fatal error.
{
- if (selectionAnalyzer.status.hasFatalError) {
- return selectionAnalyzer.status;
+ if (analyzer.status.hasFatalError) {
+ return analyzer.status;
}
}
- List<AstNode> selectedNodes = selectionAnalyzer.selectedNodes;
+ List<AstNode> selectedNodes = analyzer.selectedNodes;
// If no selected nodes, extract the smallest covering expression.
if (selectedNodes.isEmpty) {
- for (var node = selectionAnalyzer.coveringNode;
- node != null;
- node = node.parent) {
+ for (var node = analyzer.coveringNode; node != null; node = node.parent) {
if (node is Statement) {
break;
}
@@ -586,7 +580,7 @@
// Check for the parameter list of a FunctionExpression.
{
FunctionExpression function =
- node?.getAncestor((n) => n is FunctionExpression);
+ node?.thisOrAncestorOfType<FunctionExpression>();
if (function != null &&
function.parameters != null &&
range.node(function.parameters).contains(offset)) {
@@ -655,7 +649,7 @@
// change indentation
if (_selectionFunctionExpression != null) {
AstNode baseNode =
- _selectionFunctionExpression.getAncestor((node) => node is Statement);
+ _selectionFunctionExpression.thisOrAncestorOfType<Statement>();
if (baseNode != null) {
String baseIndent = utils.getNodePrefix(baseNode);
String targetIndent = utils.getNodePrefix(_parentMember);
@@ -826,9 +820,8 @@
* Checks if it is OK to extract the node with the given [SourceRange].
*/
bool _isExtractable(SourceRange range) {
- _ExtractMethodAnalyzer analyzer =
- new _ExtractMethodAnalyzer(resolveResult.unit, range);
- utils.unit.accept(analyzer);
+ var analyzer = new _ExtractMethodAnalyzer(resolveResult, range);
+ analyzer.analyze();
return analyzer.status.isOK;
}
@@ -929,8 +922,9 @@
* [SelectionAnalyzer] for [ExtractMethodRefactoringImpl].
*/
class _ExtractMethodAnalyzer extends StatementAnalyzer {
- _ExtractMethodAnalyzer(CompilationUnit unit, SourceRange selection)
- : super(unit, selection);
+ _ExtractMethodAnalyzer(
+ ResolvedUnitResult resolveResult, SourceRange selection)
+ : super(resolveResult, selection);
@override
void handleNextSelectedNode(AstNode node) {
@@ -1120,7 +1114,7 @@
}
}
-class _InitializeOccurrencesVisitor extends GeneralizingAstVisitor<Object> {
+class _InitializeOccurrencesVisitor extends GeneralizingAstVisitor<void> {
final ExtractMethodRefactoringImpl ref;
final _SourcePattern selectionPattern;
final Map<String, String> patternToSelectionName;
@@ -1131,50 +1125,50 @@
this.ref, this.selectionPattern, this.patternToSelectionName);
@override
- Object visitBlock(Block node) {
+ void visitBlock(Block node) {
if (ref._selectionStatements != null) {
_visitStatements(node.statements);
}
- return super.visitBlock(node);
+ super.visitBlock(node);
}
@override
- Object visitConstructorInitializer(ConstructorInitializer node) {
+ void visitConstructorInitializer(ConstructorInitializer node) {
forceStatic = true;
try {
- return super.visitConstructorInitializer(node);
+ super.visitConstructorInitializer(node);
} finally {
forceStatic = false;
}
}
@override
- Object visitExpression(Expression node) {
+ void visitExpression(Expression node) {
if (ref._selectionFunctionExpression != null ||
ref._selectionExpression != null &&
node.runtimeType == ref._selectionExpression.runtimeType) {
SourceRange nodeRange = range.node(node);
_tryToFindOccurrence(nodeRange);
}
- return super.visitExpression(node);
+ super.visitExpression(node);
}
@override
- Object visitMethodDeclaration(MethodDeclaration node) {
+ void visitMethodDeclaration(MethodDeclaration node) {
forceStatic = node.isStatic;
try {
- return super.visitMethodDeclaration(node);
+ super.visitMethodDeclaration(node);
} finally {
forceStatic = false;
}
}
@override
- Object visitSwitchMember(SwitchMember node) {
+ void visitSwitchMember(SwitchMember node) {
if (ref._selectionStatements != null) {
_visitStatements(node.statements);
}
- return super.visitSwitchMember(node);
+ super.visitSwitchMember(node);
}
/**
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart
index 8218754..b182f37 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2018, 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.
@@ -13,12 +13,13 @@
import 'package:analysis_server/src/services/search/element_visitors.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
import 'package:analysis_server/src/utilities/flutter.dart';
-import 'package:analyzer/analyzer.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/analysis/session_helper.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/generated/java_core.dart';
import 'package:analyzer/src/generated/source.dart' show SourceRange;
import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
@@ -28,7 +29,7 @@
class ExtractWidgetRefactoringImpl extends RefactoringImpl
implements ExtractWidgetRefactoring {
final SearchEngine searchEngine;
- final ResolveResult resolveResult;
+ final ResolvedUnitResult resolveResult;
final AnalysisSessionHelper sessionHelper;
final int offset;
final int length;
@@ -73,8 +74,7 @@
ExtractWidgetRefactoringImpl(
this.searchEngine, this.resolveResult, this.offset, this.length)
: sessionHelper = new AnalysisSessionHelper(resolveResult.session) {
- utils =
- new CorrectionUtils(resolveResult.unit, buffer: resolveResult.content);
+ utils = new CorrectionUtils(resolveResult);
}
@override
@@ -103,7 +103,7 @@
}
AstNode astNode = _expression ?? _method ?? _statements.first;
- _enclosingUnitMember = astNode.getAncestor((n) {
+ _enclosingUnitMember = astNode.thisOrAncestorMatching((n) {
return n is CompilationUnitMember && n.parent is CompilationUnit;
});
@@ -178,7 +178,7 @@
}
// Find the enclosing class.
- _enclosingClassNode = node?.getAncestor((n) => n is ClassDeclaration);
+ _enclosingClassNode = node?.thisOrAncestorOfType<ClassDeclaration>();
_enclosingClassElement = _enclosingClassNode?.declaredElement;
// new MyWidget(...)
diff --git a/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart b/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart
index eafbcaf..00b8883 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -14,8 +14,8 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/analysis/session_helper.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
-import 'package:analyzer/src/dart/element/ast_provider.dart';
import 'package:analyzer/src/generated/java_core.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/utilities/range_factory.dart';
@@ -26,8 +26,7 @@
class InlineLocalRefactoringImpl extends RefactoringImpl
implements InlineLocalRefactoring {
final SearchEngine searchEngine;
- final AstProvider astProvider;
- final ResolveResult resolveResult;
+ final ResolvedUnitResult resolveResult;
final int offset;
CorrectionUtils utils;
@@ -36,9 +35,8 @@
List<SearchMatch> _references;
InlineLocalRefactoringImpl(
- this.searchEngine, this.astProvider, this.resolveResult, this.offset) {
- utils =
- new CorrectionUtils(resolveResult.unit, buffer: resolveResult.content);
+ this.searchEngine, this.resolveResult, this.offset) {
+ utils = new CorrectionUtils(resolveResult);
}
@override
@@ -79,8 +77,10 @@
Element element = offsetNode.staticElement;
if (element is LocalVariableElement) {
_variableElement = element;
- AstNode name = await astProvider.getResolvedNameForElement(element);
- _variableNode = name.parent as VariableDeclaration;
+ var declarationResult =
+ await AnalysisSessionHelper(resolveResult.session)
+ .getElementDeclaration(element);
+ _variableNode = declarationResult.node;
}
}
}
@@ -121,8 +121,8 @@
SourceChange change = new SourceChange(refactoringName);
// remove declaration
{
- Statement declarationStatement = _variableNode
- .getAncestor((node) => node is VariableDeclarationStatement);
+ Statement declarationStatement =
+ _variableNode.thisOrAncestorOfType<VariableDeclarationStatement>();
SourceRange range = utils.getLinesRangeStatements([declarationStatement]);
doSourceChange_addElementEdit(change, resolveResult.unit.declaredElement,
newSourceEdit_range(range, ''));
diff --git a/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart b/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
index 05e5c1b..4d7b4e2 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -16,8 +16,8 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/analysis/session_helper.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
-import 'package:analyzer/src/dart/element/ast_provider.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/utilities/range_factory.dart';
@@ -26,7 +26,7 @@
*/
SourceRange _getLocalsConflictingRange(AstNode node) {
// maybe Block
- Block block = node.getAncestor((node) => node is Block);
+ Block block = node.thisOrAncestorOfType<Block>();
if (block != null) {
return range.startEnd(node, block);
}
@@ -188,10 +188,9 @@
class InlineMethodRefactoringImpl extends RefactoringImpl
implements InlineMethodRefactoring {
final SearchEngine searchEngine;
- final AstProvider astProvider;
- final ResolveResult resolveResult;
+ final ResolvedUnitResult resolveResult;
final int offset;
- ResolvedUnitCache _unitCache;
+ final AnalysisSessionHelper sessionHelper;
CorrectionUtils utils;
SourceChange change;
@@ -200,7 +199,6 @@
bool inlineAll = true;
ExecutableElement _methodElement;
- bool _isAccessor;
CompilationUnit _methodUnit;
CorrectionUtils _methodUtils;
AstNode _methodNode;
@@ -210,13 +208,12 @@
_SourcePart _methodExpressionPart;
_SourcePart _methodStatementsPart;
final List<_ReferenceProcessor> _referenceProcessors = [];
- final Set<FunctionBody> _alreadyMadeAsync = new Set<FunctionBody>();
+ final Set<Element> _alreadyMadeAsync = new Set<Element>();
InlineMethodRefactoringImpl(
- this.searchEngine, this.astProvider, this.resolveResult, this.offset) {
- _unitCache = new ResolvedUnitCache(astProvider, resolveResult.unit);
- utils =
- new CorrectionUtils(resolveResult.unit, buffer: resolveResult.content);
+ this.searchEngine, this.resolveResult, this.offset)
+ : sessionHelper = AnalysisSessionHelper(resolveResult.session) {
+ utils = new CorrectionUtils(resolveResult);
}
@override
@@ -311,24 +308,6 @@
return new Future.value(change);
}
- Future<FunctionDeclaration> _computeFunctionDeclaration() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
- CompilationUnit unit = await _unitCache.getUnit(_methodElement);
- return new NodeLocator(_methodElement.nameOffset)
- .searchWithin(unit)
- .getAncestor((n) => n is FunctionDeclaration) as FunctionDeclaration;
- }
-
- Future<MethodDeclaration> _computeMethodDeclaration() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
- CompilationUnit unit = await _unitCache.getUnit(_methodElement);
- return new NodeLocator(_methodElement.nameOffset)
- .searchWithin(unit)
- .getAncestor((n) => n is MethodDeclaration) as MethodDeclaration;
- }
-
_SourcePart _createSourcePart(SourceRange range) {
String source = _methodUtils.getRangeText(range);
String prefix = getLinePrefix(source);
@@ -368,38 +347,30 @@
return fatalStatus;
}
_methodElement = element as ExecutableElement;
- _isAccessor = element is PropertyAccessorElement;
- _methodUnit = await _unitCache.getUnit(element);
- _methodUtils = new CorrectionUtils(_methodUnit);
- // class member
- bool isClassMember = element.enclosingElement is ClassElement;
- if (element is MethodElement || _isAccessor && isClassMember) {
- MethodDeclaration methodDeclaration = await _computeMethodDeclaration();
- _methodNode = methodDeclaration;
- _methodParameters = methodDeclaration.parameters;
- _methodBody = methodDeclaration.body;
- // prepare mode
- isDeclaration = node == methodDeclaration.name;
- deleteSource = isDeclaration;
- inlineAll = deleteSource;
- return new RefactoringStatus();
+
+ var declaration = await sessionHelper.getElementDeclaration(_methodElement);
+ var methodNode = declaration.node;
+ _methodNode = methodNode;
+
+ var resolvedUnit = declaration.resolvedUnit;
+ _methodUnit = resolvedUnit.unit;
+ _methodUtils = new CorrectionUtils(resolvedUnit);
+
+ if (methodNode is MethodDeclaration) {
+ _methodParameters = methodNode.parameters;
+ _methodBody = methodNode.body;
+ } else if (methodNode is FunctionDeclaration) {
+ _methodParameters = methodNode.functionExpression.parameters;
+ _methodBody = methodNode.functionExpression.body;
+ } else {
+ return fatalStatus;
}
- // unit member
- bool isUnitMember = element.enclosingElement is CompilationUnitElement;
- if (element is FunctionElement || _isAccessor && isUnitMember) {
- FunctionDeclaration functionDeclaration =
- await _computeFunctionDeclaration();
- _methodNode = functionDeclaration;
- _methodParameters = functionDeclaration.functionExpression.parameters;
- _methodBody = functionDeclaration.functionExpression.body;
- // prepare mode
- isDeclaration = node == functionDeclaration.name;
- deleteSource = isDeclaration;
- inlineAll = deleteSource;
- return new RefactoringStatus();
- }
- // OK
- return fatalStatus;
+
+ isDeclaration = resolveResult.uri == element.source.uri &&
+ node.offset == element.nameOffset;
+ deleteSource = isDeclaration;
+ inlineAll = deleteSource;
+ return new RefactoringStatus();
}
/**
@@ -467,12 +438,14 @@
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
refElement = reference.element;
+
// prepare CorrectionUtils
- CompilationUnit refUnit = await ref._unitCache.getUnit(refElement);
- _refUtils = new CorrectionUtils(refUnit);
+ var result = await ref.sessionHelper.getResolvedUnitByElement(refElement);
+ _refUtils = new CorrectionUtils(result);
+
// prepare node and environment
_node = _refUtils.findNode(reference.sourceRange.offset);
- Statement refStatement = _node.getAncestor((node) => node is Statement);
+ Statement refStatement = _node.thisOrAncestorOfType<Statement>();
if (refStatement != null) {
_refLineRange = _refUtils.getLinesRangeStatements([refStatement]);
_refPrefix = _refUtils.getNodePrefix(refStatement);
@@ -591,7 +564,7 @@
// If the element being inlined is async, ensure that the function
// body that encloses the method is also async.
if (ref._methodElement.isAsynchronous) {
- FunctionBody body = _node.getAncestor((n) => n is FunctionBody);
+ FunctionBody body = _node.thisOrAncestorOfType<FunctionBody>();
if (body != null) {
if (body.isSynchronous) {
if (body.isGenerator) {
@@ -608,7 +581,7 @@
return;
}
}
- if (ref._alreadyMadeAsync.add(body)) {
+ if (ref._alreadyMadeAsync.add(refElement)) {
SourceRange bodyStart = range.startLength(body, 0);
_addRefEdit(newSourceEdit_range(bodyStart, 'async '));
}
@@ -650,7 +623,7 @@
List<Expression> arguments = [];
if (_node.inSetterContext()) {
AssignmentExpression assignment =
- _node.getAncestor((node) => node is AssignmentExpression);
+ _node.thisOrAncestorOfType<AssignmentExpression>();
arguments.add(assignment.rightHandSide);
}
// inline body
diff --git a/pkg/analysis_server/lib/src/services/refactoring/move_file.dart b/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
index d2e3c69..a068451 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
@@ -32,6 +32,8 @@
String oldFile;
String newFile;
+ final packagePrefixedStringPattern = new RegExp(r'''^r?['"]+package:''');
+
MoveFileRefactoringImpl(ResourceProvider resourceProvider, this.workspace,
this.source, this.oldFile)
: resourceProvider = resourceProvider,
@@ -90,7 +92,8 @@
});
} else {
// Otherwise, we need to update any relative part-of references.
- Iterable<PartOfDirective> partOfs = element.unit.directives
+ final result = await driver.currentSession.getResolvedUnit(oldFile);
+ Iterable<PartOfDirective> partOfs = result.unit.directives
.whereType<PartOfDirective>()
.where((po) => po.uri != null && _isRelativeUri(po.uri.stringValue));
@@ -139,7 +142,12 @@
return _getRelativeUri(newFile, refDir);
}
- final packagePrefixedStringPattern = new RegExp(r'''^r?['"]+package:''');
+ String _getRelativeUri(String path, String from) {
+ String uri = pathContext.relative(path, from: from);
+ List<String> parts = pathContext.split(uri);
+ return pathos.posix.joinAll(parts);
+ }
+
bool _isPackageReference(SourceReference reference) {
final Source source = reference.element.source;
final String quotedImportUri = source.contents.data.substring(
@@ -148,12 +156,6 @@
return packagePrefixedStringPattern.hasMatch(quotedImportUri);
}
- String _getRelativeUri(String path, String from) {
- String uri = pathContext.relative(path, from: from);
- List<String> parts = pathContext.split(uri);
- return pathos.posix.joinAll(parts);
- }
-
/**
* Checks if the given [path] represents a relative URI.
*
diff --git a/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart b/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
index 50e2344..223d699 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
@@ -22,11 +22,11 @@
import 'package:analysis_server/src/services/refactoring/rename_unit_member.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
-import 'package:analyzer/src/dart/element/ast_provider.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart'
show RefactoringMethodParameter, SourceChange;
@@ -40,9 +40,9 @@
* [element] and all the corresponding hierarchy elements.
*/
factory ConvertGetterToMethodRefactoring(SearchEngine searchEngine,
- AstProvider astProvider, PropertyAccessorElement element) {
+ AnalysisSession session, PropertyAccessorElement element) {
return new ConvertGetterToMethodRefactoringImpl(
- searchEngine, astProvider, element);
+ searchEngine, session, element);
}
}
@@ -55,9 +55,8 @@
* [element] and all the corresponding hierarchy elements.
*/
factory ConvertMethodToGetterRefactoring(SearchEngine searchEngine,
- AstProvider astProvider, ExecutableElement element) {
- return new ConvertMethodToGetterRefactoringImpl(
- searchEngine, astProvider, element);
+ AnalysisSession session, ExecutableElement element) {
+ return new ConvertMethodToGetterRefactoringImpl(searchEngine, element);
}
}
@@ -68,7 +67,7 @@
/**
* Returns a new [ExtractLocalRefactoring] instance.
*/
- factory ExtractLocalRefactoring(ResolveResult resolveResult,
+ factory ExtractLocalRefactoring(ResolvedUnitResult resolveResult,
int selectionOffset, int selectionLength) = ExtractLocalRefactoringImpl;
/**
@@ -144,12 +143,11 @@
*/
factory ExtractMethodRefactoring(
SearchEngine searchEngine,
- AstProvider astProvider,
- ResolveResult resolveResult,
+ ResolvedUnitResult resolveResult,
int selectionOffset,
int selectionLength) {
- return new ExtractMethodRefactoringImpl(searchEngine, astProvider,
- resolveResult, selectionOffset, selectionLength);
+ return new ExtractMethodRefactoringImpl(
+ searchEngine, resolveResult, selectionOffset, selectionLength);
}
/**
@@ -243,7 +241,7 @@
* Returns a new [ExtractWidgetRefactoring] instance.
*/
factory ExtractWidgetRefactoring(SearchEngine searchEngine,
- ResolveResult resolveResult, int offset, int length) {
+ ResolvedUnitResult resolveResult, int offset, int length) {
return new ExtractWidgetRefactoringImpl(
searchEngine, resolveResult, offset, length);
}
@@ -278,10 +276,9 @@
/**
* Returns a new [InlineLocalRefactoring] instance.
*/
- factory InlineLocalRefactoring(SearchEngine searchEngine,
- AstProvider astProvider, ResolveResult resolveResult, int offset) {
- return new InlineLocalRefactoringImpl(
- searchEngine, astProvider, resolveResult, offset);
+ factory InlineLocalRefactoring(
+ SearchEngine searchEngine, ResolvedUnitResult resolveResult, int offset) {
+ return new InlineLocalRefactoringImpl(searchEngine, resolveResult, offset);
}
/**
@@ -302,10 +299,9 @@
/**
* Returns a new [InlineMethodRefactoring] instance.
*/
- factory InlineMethodRefactoring(SearchEngine searchEngine,
- AstProvider astProvider, ResolveResult resolveResult, int offset) {
- return new InlineMethodRefactoringImpl(
- searchEngine, astProvider, resolveResult, offset);
+ factory InlineMethodRefactoring(
+ SearchEngine searchEngine, ResolvedUnitResult resolveResult, int offset) {
+ return new InlineMethodRefactoringImpl(searchEngine, resolveResult, offset);
}
/**
@@ -413,6 +409,13 @@
RefactoringWorkspace(this.drivers, this.searchEngine);
/**
+ * Whether the [element] is defined in a file that is in a context root.
+ */
+ bool containsElement(Element element) {
+ return containsFile(element.source.fullName);
+ }
+
+ /**
* Whether the file with the given [path] is in a context root.
*/
bool containsFile(String path) {
@@ -441,7 +444,7 @@
* type.
*/
factory RenameRefactoring(RefactoringWorkspace workspace,
- AstProvider astProvider, Element element) {
+ AnalysisSession session, Element element) {
if (element == null) {
return null;
}
@@ -452,11 +455,10 @@
return new RenameUnitMemberRefactoringImpl(workspace, element);
}
if (element is ConstructorElement) {
- return new RenameConstructorRefactoringImpl(
- workspace, astProvider, element);
+ return new RenameConstructorRefactoringImpl(workspace, session, element);
}
if (element is ImportElement) {
- return new RenameImportRefactoringImpl(workspace, astProvider, element);
+ return new RenameImportRefactoringImpl(workspace, session, element);
}
if (element is LabelElement) {
return new RenameLabelRefactoringImpl(workspace, element);
@@ -465,11 +467,10 @@
return new RenameLibraryRefactoringImpl(workspace, element);
}
if (element is LocalElement) {
- return new RenameLocalRefactoringImpl(workspace, astProvider, element);
+ return new RenameLocalRefactoringImpl(workspace, element);
}
if (element.enclosingElement is ClassElement) {
- return new RenameClassMemberRefactoringImpl(
- workspace, astProvider, element);
+ return new RenameClassMemberRefactoringImpl(workspace, session, element);
}
return null;
}
@@ -501,38 +502,3 @@
*/
RefactoringStatus checkNewName();
}
-
-/**
- * Cache for accessing resolved [CompilationUnit]s by [Element]s.
- *
- * Must by short-lived.
- *
- * TODO(scheglov) consider moving to request-bound object.
- */
-class ResolvedUnitCache {
- final AstProvider _astProvider;
- final Map<CompilationUnitElement, CompilationUnit> _map = {};
-
- ResolvedUnitCache(this._astProvider, [CompilationUnit unit]) {
- if (unit != null) {
- _map[unit.declaredElement] = unit;
- }
- }
-
- Future<CompilationUnit> getUnit(Element element) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
- CompilationUnitElement unitElement = getUnitElement(element);
- CompilationUnit unit = _map[unitElement];
- if (unit == null) {
- unit = await _astProvider.getResolvedUnitForElement(element);
- _map[unitElement] = unit;
- }
- return unit;
- }
-
- CompilationUnitElement getUnitElement(Element element) {
- return element.getAncestor((e) => e is CompilationUnitElement)
- as CompilationUnitElement;
- }
-}
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename.dart b/pkg/analysis_server/lib/src/services/refactoring/rename.dart
index d7f193c..b7663c0 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename.dart
@@ -18,17 +18,17 @@
* Helper for renaming one or more [Element]s.
*/
class RenameProcessor {
- final SearchEngine searchEngine;
+ final RefactoringWorkspace workspace;
final SourceChange change;
final String newName;
- RenameProcessor(this.searchEngine, this.change, this.newName);
+ RenameProcessor(this.workspace, this.change, this.newName);
/**
* Add the edit that updates the [element] declaration.
*/
void addDeclarationEdit(Element element) {
- if (element != null) {
+ if (element != null && workspace.containsElement(element)) {
SourceEdit edit =
newSourceEdit_range(range.elementName(element), newName);
doSourceChange_addElementEdit(change, element, edit);
@@ -41,6 +41,9 @@
void addReferenceEdits(List<SearchMatch> matches) {
List<SourceReference> references = getSourceReferences(matches);
for (SourceReference reference in references) {
+ if (!workspace.containsElement(reference.element)) {
+ continue;
+ }
reference.addEdit(change, newName);
}
}
@@ -50,7 +53,9 @@
*/
Future<void> renameElement(Element element) {
addDeclarationEdit(element);
- return searchEngine.searchReferences(element).then(addReferenceEdits);
+ return workspace.searchEngine
+ .searchReferences(element)
+ .then(addReferenceEdits);
}
}
@@ -86,7 +91,7 @@
getElementQualifiedName(element));
result.addFatalError(message);
}
- if (!workspace.containsFile(element.source.fullName)) {
+ if (!workspace.containsElement(element)) {
String message = format(
"The {0} '{1}' is defined outside of the project, so cannot be renamed.",
getElementKindName(element),
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
index d085e78..df98b9e 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
@@ -14,10 +14,11 @@
import 'package:analysis_server/src/services/refactoring/rename.dart';
import 'package:analysis_server/src/services/search/hierarchy.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/dart/element/ast_provider.dart';
+import 'package:analyzer/src/dart/analysis/session_helper.dart';
import 'package:analyzer/src/generated/java_core.dart';
import 'package:analyzer/src/generated/source.dart';
@@ -25,10 +26,13 @@
* Checks if creating a method with the given [name] in [classElement] will
* cause any conflicts.
*/
-Future<RefactoringStatus> validateCreateMethod(SearchEngine searchEngine,
- AstProvider astProvider, ClassElement classElement, String name) {
+Future<RefactoringStatus> validateCreateMethod(
+ SearchEngine searchEngine,
+ AnalysisSessionHelper sessionHelper,
+ ClassElement classElement,
+ String name) {
return new _ClassMemberValidator.forCreate(
- searchEngine, astProvider, classElement, name)
+ searchEngine, sessionHelper, classElement, name)
.validate();
}
@@ -36,13 +40,14 @@
* A [Refactoring] for renaming class member [Element]s.
*/
class RenameClassMemberRefactoringImpl extends RenameRefactoringImpl {
- final AstProvider astProvider;
+ final AnalysisSessionHelper sessionHelper;
_ClassMemberValidator _validator;
RenameClassMemberRefactoringImpl(
- RefactoringWorkspace workspace, this.astProvider, Element element)
- : super(workspace, element);
+ RefactoringWorkspace workspace, AnalysisSession session, Element element)
+ : sessionHelper = AnalysisSessionHelper(session),
+ super(workspace, element);
@override
String get refactoringName {
@@ -58,7 +63,7 @@
@override
Future<RefactoringStatus> checkFinalConditions() {
_validator = new _ClassMemberValidator.forRename(
- searchEngine, astProvider, element, newName);
+ searchEngine, sessionHelper, element, newName);
return _validator.validate();
}
@@ -87,7 +92,7 @@
@override
Future<void> fillChange() async {
- var processor = new RenameProcessor(searchEngine, change, newName);
+ var processor = new RenameProcessor(workspace, change, newName);
// update declarations
for (Element renameElement in _validator.elements) {
if (renameElement.isSynthetic && renameElement is FieldElement) {
@@ -105,7 +110,7 @@
List<SourceReference> nameRefs = getSourceReferences(nameMatches);
for (SourceReference reference in nameRefs) {
// ignore references from SDK and pub cache
- if (!workspace.containsFile(reference.element.source.fullName)) {
+ if (!workspace.containsElement(reference.element)) {
continue;
}
// check the element being renamed is accessible
@@ -132,7 +137,7 @@
*/
class _ClassMemberValidator {
final SearchEngine searchEngine;
- final ResolvedUnitCache unitCache;
+ final AnalysisSessionHelper sessionHelper;
final LibraryElement library;
final Element element;
final ClassElement elementClass;
@@ -145,17 +150,15 @@
List<SearchMatch> references = <SearchMatch>[];
_ClassMemberValidator.forCreate(
- this.searchEngine, AstProvider astProvider, this.elementClass, this.name)
- : unitCache = new ResolvedUnitCache(astProvider),
- isRename = false,
+ this.searchEngine, this.sessionHelper, this.elementClass, this.name)
+ : isRename = false,
library = null,
element = null,
elementKind = ElementKind.METHOD;
_ClassMemberValidator.forRename(
- this.searchEngine, AstProvider astProvider, Element element, this.name)
- : unitCache = new ResolvedUnitCache(astProvider),
- isRename = true,
+ this.searchEngine, this.sessionHelper, Element element, this.name)
+ : isRename = true,
library = element.library,
element = element,
elementClass = element.enclosingElement,
@@ -260,12 +263,13 @@
Future<List<LocalElement>> getLocalElements(Element element) async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
- var unitElement = unitCache.getUnitElement(element);
+
+ var resolvedUnit = await sessionHelper.getResolvedUnitByElement(element);
+ var unitElement = resolvedUnit.unit.declaredElement;
var localElements = localElementMap[unitElement];
if (localElements == null) {
- var unit = await unitCache.getUnit(unitElement);
var collector = new _LocalElementsCollector(name);
- unit.accept(collector);
+ resolvedUnit.unit.accept(collector);
localElements = collector.elements;
localElementMap[unitElement] = localElements;
}
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart
index 755ebff..6baadf4 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart
@@ -14,9 +14,10 @@
import 'package:analysis_server/src/services/search/hierarchy.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
import 'package:analysis_server/src/services/search/search_engine_internal.dart';
+import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/dart/element/ast_provider.dart';
+import 'package:analyzer/src/dart/analysis/session_helper.dart';
import 'package:analyzer/src/generated/java_core.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/utilities/range_factory.dart';
@@ -25,10 +26,10 @@
* A [Refactoring] for renaming [ConstructorElement]s.
*/
class RenameConstructorRefactoringImpl extends RenameRefactoringImpl {
- final AstProvider astProvider;
+ final AnalysisSession session;
- RenameConstructorRefactoringImpl(RefactoringWorkspace workspace,
- this.astProvider, ConstructorElement element)
+ RenameConstructorRefactoringImpl(
+ RefactoringWorkspace workspace, this.session, ConstructorElement element)
: super(workspace, element);
@override
@@ -117,11 +118,12 @@
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
ClassElement classElement = element.enclosingElement;
- AstNode name = await astProvider.getResolvedNameForElement(classElement);
- ClassDeclaration classNode = name.parent as ClassDeclaration;
- CorrectionUtils utils = new CorrectionUtils(classNode.parent);
- ClassMemberLocation location =
- utils.prepareNewConstructorLocation(classNode);
+
+ var result = await AnalysisSessionHelper(session)
+ .getElementDeclaration(classElement);
+ ClassDeclaration classNode = result.node;
+ var utils = new CorrectionUtils(result.resolvedUnit);
+ var location = utils.prepareNewConstructorLocation(classNode);
doSourceChange_addElementEdit(
change,
classElement,
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_import.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_import.dart
index 53e382b..2bc3c99 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_import.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_import.dart
@@ -11,12 +11,10 @@
import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart';
import 'package:analysis_server/src/services/refactoring/rename.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
-import 'package:analyzer/src/dart/element/ast_provider.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/utilities/range_factory.dart';
@@ -24,10 +22,10 @@
* A [Refactoring] for renaming [ImportElement]s.
*/
class RenameImportRefactoringImpl extends RenameRefactoringImpl {
- final AstProvider astProvider;
+ final AnalysisSession session;
RenameImportRefactoringImpl(
- RefactoringWorkspace workspace, this.astProvider, ImportElement element)
+ RefactoringWorkspace workspace, this.session, ImportElement element)
: super(workspace, element);
@override
@@ -60,14 +58,14 @@
PrefixElement prefix = element.prefix;
SourceEdit edit = null;
if (newName.isEmpty) {
- ImportDirective node = await _findNode();
+ ImportDirective node = _findNode();
int uriEnd = node.uri.end;
int prefixEnd = element.prefixOffset + prefix.nameLength;
edit = newSourceEdit_range(
range.startOffsetEndOffset(uriEnd, prefixEnd), "");
} else {
if (prefix == null) {
- ImportDirective node = await _findNode();
+ ImportDirective node = _findNode();
int uriEnd = node.uri.end;
edit =
newSourceEdit_range(new SourceRange(uriEnd, 0), " as $newName");
@@ -89,7 +87,7 @@
reference.addEdit(change, '');
} else {
SimpleIdentifier interpolationIdentifier =
- await _getInterpolationIdentifier(reference);
+ _getInterpolationIdentifier(reference);
if (interpolationIdentifier != null) {
doSourceChange_addElementEdit(
change,
@@ -108,11 +106,10 @@
/**
* Return the [ImportDirective] node that corresponds to the [element].
*/
- Future<ImportDirective> _findNode() async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
+ ImportDirective _findNode() {
LibraryElement library = element.library;
- CompilationUnit unit = await astProvider.getParsedUnitForElement(library);
+ String path = library.source.fullName;
+ CompilationUnit unit = session.getParsedUnit(path).unit;
int index = library.imports.indexOf(element);
return unit.directives.where((d) => d is ImportDirective).toList()[index];
}
@@ -122,14 +119,9 @@
* an [InterpolationExpression] without surrounding curly brackets, return it.
* Otherwise return `null`.
*/
- Future<SimpleIdentifier> _getInterpolationIdentifier(
- SourceReference reference) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
+ SimpleIdentifier _getInterpolationIdentifier(SourceReference reference) {
Source source = reference.element.source;
- AnalysisSession currentSession = astProvider.driver.currentSession;
- ParseResult result = await currentSession.getParsedAst(source.fullName);
- CompilationUnit unit = result.unit;
+ CompilationUnit unit = session.getParsedUnit(source.fullName).unit;
NodeLocator nodeLocator = new NodeLocator(reference.range.offset);
AstNode node = nodeLocator.searchWithin(unit);
if (node is SimpleIdentifier) {
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_label.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_label.dart
index 643be1f..012f500 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_label.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_label.dart
@@ -39,7 +39,7 @@
@override
Future<void> fillChange() {
- var processor = new RenameProcessor(searchEngine, change, newName);
+ var processor = new RenameProcessor(workspace, change, newName);
return processor.renameElement(element);
}
}
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_library.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_library.dart
index e270f82..8ad6912 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_library.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_library.dart
@@ -41,7 +41,7 @@
@override
Future<void> fillChange() async {
- var processor = new RenameProcessor(searchEngine, change, newName);
+ var processor = new RenameProcessor(workspace, change, newName);
await processor.renameElement(element);
}
}
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart
index 369b832..7fac53a 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -15,21 +15,20 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/dart/element/ast_provider.dart';
+import 'package:analyzer/src/dart/analysis/session_helper.dart';
import 'package:analyzer/src/generated/source.dart';
/**
* A [Refactoring] for renaming [LocalElement]s.
*/
class RenameLocalRefactoringImpl extends RenameRefactoringImpl {
- final AstProvider astProvider;
- final ResolvedUnitCache unitCache;
+ final AnalysisSessionHelper sessionHelper;
List<LocalElement> elements = [];
RenameLocalRefactoringImpl(
- RefactoringWorkspace workspace, this.astProvider, LocalElement element)
- : unitCache = new ResolvedUnitCache(astProvider),
+ RefactoringWorkspace workspace, LocalElement element)
+ : sessionHelper = AnalysisSessionHelper(element.session),
super(workspace, element);
@override
@@ -53,10 +52,9 @@
RefactoringStatus result = new RefactoringStatus();
await _prepareElements();
for (LocalElement element in elements) {
- CompilationUnit unit = await unitCache.getUnit(element);
- if (unit != null) {
- unit.accept(new _ConflictValidatorVisitor(result, newName, element));
- }
+ var resolvedUnit = await sessionHelper.getResolvedUnitByElement(element);
+ var unit = resolvedUnit.unit;
+ unit.accept(new _ConflictValidatorVisitor(result, newName, element));
}
return result;
}
@@ -76,7 +74,7 @@
@override
Future<void> fillChange() async {
- var processor = new RenameProcessor(searchEngine, change, newName);
+ var processor = new RenameProcessor(workspace, change, newName);
for (Element element in elements) {
processor.addDeclarationEdit(element);
var references = await searchEngine.searchReferences(element);
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_unit_member.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_unit_member.dart
index 88cac3a..5d20312 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_unit_member.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_unit_member.dart
@@ -127,7 +127,7 @@
}
// Rename each element and references to it.
- var processor = new RenameProcessor(searchEngine, change, newName);
+ var processor = new RenameProcessor(workspace, change, newName);
for (var element in elements) {
await processor.renameElement(element);
}
@@ -136,7 +136,7 @@
if (_flutterWidgetState != null) {
_updateFlutterWidgetStateName();
await new RenameProcessor(
- searchEngine,
+ workspace,
change,
_flutterWidgetStateNewName,
).renameElement(_flutterWidgetState);
diff --git a/pkg/analysis_server/lib/src/services/search/search_engine.dart b/pkg/analysis_server/lib/src/services/search/search_engine.dart
index df6e31c..74445c4 100644
--- a/pkg/analysis_server/lib/src/services/search/search_engine.dart
+++ b/pkg/analysis_server/lib/src/services/search/search_engine.dart
@@ -140,7 +140,7 @@
MatchKind get kind;
/**
- * Return the [LibraryElement] for the [libraryUri] in the [context].
+ * Return the [LibraryElement] for the [file].
*/
LibraryElement get libraryElement;
diff --git a/pkg/analysis_server/lib/src/status/diagnostics.dart b/pkg/analysis_server/lib/src/status/diagnostics.dart
index dc21222..a8b5a1a 100644
--- a/pkg/analysis_server/lib/src/status/diagnostics.dart
+++ b/pkg/analysis_server/lib/src/status/diagnostics.dart
@@ -12,7 +12,6 @@
import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/domain_completion.dart';
-import 'package:analysis_server/src/domain_diagnostic.dart';
import 'package:analysis_server/src/plugin/plugin_manager.dart';
import 'package:analysis_server/src/server/http_server.dart';
import 'package:analysis_server/src/services/completion/completion_performance.dart';
@@ -21,6 +20,7 @@
import 'package:analysis_server/src/status/element_writer.dart';
import 'package:analysis_server/src/status/pages.dart';
import 'package:analysis_server/src/utilities/profiling.dart';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/src/context/context_root.dart';
@@ -187,7 +187,7 @@
raw: true);
return;
}
- AnalysisResult result = await driver.getResult(path);
+ ResolvedUnitResult result = await driver.getResult(path);
if (result == null) {
p(
'An AST could not be produced for the file '
@@ -387,7 +387,6 @@
b.write(writeOption('Strong mode', options.strongMode));
b.write(writeOption('Implicit dynamic', options.implicitDynamic));
b.write(writeOption('Implicit casts', options.implicitCasts));
- b.write(writeOption('Declaration casts', options.declarationCasts));
b.write(
writeOption('Analyze function bodies', options.analyzeFunctionBodies));
@@ -400,6 +399,8 @@
b.write(writeOption('Preserve comments', options.preserveComments));
b.write(writeOption('Strong mode hints', options.strongModeHints));
+ b.write(writeOption('Enabled experiments', options.enabledExperiments));
+
return b.toString();
}
@@ -714,7 +715,7 @@
SocketServer socketServer;
/// The last few lines printed.
- List<String> lastPrintedLines = <String>[];
+ final List<String> lastPrintedLines;
DiagnosticsSite(this.socketServer, this.lastPrintedLines)
: super('Analysis Server') {
@@ -783,7 +784,7 @@
raw: true);
return;
}
- AnalysisResult result = await driver.getResult(path);
+ ResolvedUnitResult result = await driver.getResult(path);
if (result == null) {
p(
'An element model could not be produced for the file '
@@ -956,11 +957,6 @@
: super(site, 'memory', 'Memory and CPU Usage',
description: 'Memory and CPU usage for the analysis server.');
- DiagnosticDomainHandler get diagnosticDomain {
- return server.handlers
- .firstWhere((handler) => handler is DiagnosticDomainHandler);
- }
-
@override
Future generateContent(Map<String, String> params) async {
// TODO(brianwilkerson) Determine whether this await is necessary.
@@ -1246,7 +1242,7 @@
final WebSocket socket;
int _id = 0;
- Map<String, Completer<Map>> _completers = {};
+ final Map<String, Completer<Map>> _completers = {};
ServiceProtocol._(this.socket) {
socket.listen(_handleMessage);
diff --git a/pkg/analysis_server/lib/src/status/pages.dart b/pkg/analysis_server/lib/src/status/pages.dart
index b270a3c..41b9b80 100644
--- a/pkg/analysis_server/lib/src/status/pages.dart
+++ b/pkg/analysis_server/lib/src/status/pages.dart
@@ -136,7 +136,7 @@
/// Contains a collection of Pages.
abstract class Site {
final String title;
- List<Page> pages = [];
+ final List<Page> pages = [];
Site(this.title);
diff --git a/pkg/analysis_server/lib/src/status/tree_writer.dart b/pkg/analysis_server/lib/src/status/tree_writer.dart
index 9feb8af..62b07f1 100644
--- a/pkg/analysis_server/lib/src/status/tree_writer.dart
+++ b/pkg/analysis_server/lib/src/status/tree_writer.dart
@@ -13,7 +13,7 @@
* Utility methods that can be mixed in to classes that produce an HTML
* representation of a tree structure.
*/
-abstract class TreeWriter {
+mixin TreeWriter {
/**
* The buffer on which the HTML is to be written.
*/
diff --git a/pkg/analysis_server/lib/src/utilities/flutter.dart b/pkg/analysis_server/lib/src/utilities/flutter.dart
index f116530..6e754c3 100644
--- a/pkg/analysis_server/lib/src/utilities/flutter.dart
+++ b/pkg/analysis_server/lib/src/utilities/flutter.dart
@@ -19,6 +19,8 @@
const _STATE_NAME = "State";
const _STATEFUL_WIDGET_NAME = "StatefulWidget";
const _STATELESS_WIDGET_NAME = "StatelessWidget";
+const _STREAM_BUILDER_NAME = "StreamBuilder";
+const _STREAM_BUILDER_URI = "package:flutter/src/widgets/async.dart";
const _WIDGET_NAME = "Widget";
const _WIDGET_URI = "package:flutter/src/widgets/framework.dart";
final _frameworkUri = Uri.parse('package:flutter/src/widgets/framework.dart');
@@ -307,6 +309,14 @@
}
/**
+ * Return `true` if the given [type] is the Flutter class `StreamBuilder`.
+ */
+bool isExactWidgetTypeStreamBuilder(DartType type) {
+ return type is InterfaceType &&
+ _isExactWidget(type.element, _STREAM_BUILDER_NAME, _STREAM_BUILDER_URI);
+}
+
+/**
* Return `true` if the given [type] is the Flutter class `Widget`, or its
* subtype.
*/
diff --git a/pkg/analysis_server/lib/src/utilities/profiling.dart b/pkg/analysis_server/lib/src/utilities/profiling.dart
index 7e2e49b..9dbd260 100644
--- a/pkg/analysis_server/lib/src/utilities/profiling.dart
+++ b/pkg/analysis_server/lib/src/utilities/profiling.dart
@@ -12,8 +12,6 @@
Future<UsageInfo> getProcessUsage(int processId);
- UsageInfo getProcessUsageSync(int processId);
-
/// Return a [ProcessProfiler] instance suitable for the current host
/// platform. This can return `null` if we're not able to gather memory and
/// cpu information for the current platform.
@@ -65,17 +63,6 @@
}
}
- UsageInfo getProcessUsageSync(int processId) {
- try {
- // Execution time is typically 2-4ms.
- ProcessResult result =
- Process.runSync('ps', ['-o', '%cpu=,rss=', processId.toString()]);
- return result.exitCode == 0 ? _parse(result.stdout) : null;
- } catch (e) {
- return null;
- }
- }
-
UsageInfo _parse(String psResults) {
try {
// " 0.0 378940"
diff --git a/pkg/analysis_server/lib/starter.dart b/pkg/analysis_server/lib/starter.dart
index aa4a30e..949e761 100644
--- a/pkg/analysis_server/lib/starter.dart
+++ b/pkg/analysis_server/lib/starter.dart
@@ -2,7 +2,6 @@
// 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/src/analysis_server.dart';
import 'package:analysis_server/src/server/detachable_filesystem_manager.dart';
import 'package:analysis_server/src/server/driver.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
@@ -47,10 +46,6 @@
/**
* Use the given command-line [arguments] to start this server.
- *
- * At least temporarily returns AnalysisServer so that consumers of the
- * starter API can then use the server, this is done as a stopgap for the
- * angular plugin until the official plugin API is finished.
*/
- AnalysisServer start(List<String> arguments);
+ void start(List<String> arguments);
}
diff --git a/pkg/analysis_server/test/abstract_context.dart b/pkg/analysis_server/test/abstract_context.dart
index ecbbbb32..6f4f753 100644
--- a/pkg/analysis_server/test/abstract_context.dart
+++ b/pkg/analysis_server/test/abstract_context.dart
@@ -1,29 +1,23 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
+import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/visitor.dart';
-import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/context/context_root.dart';
+import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
-import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/engine.dart' as engine;
-import 'package:analyzer/src/generated/parser.dart' as analyzer;
-import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/source/package_map_resolver.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
-import 'package:analyzer/src/dart/analysis/byte_store.dart';
-import 'package:analyzer/src/dart/analysis/performance_logger.dart';
-import 'mock_sdk.dart';
import 'src/utilities/flutter_util.dart';
/**
@@ -48,25 +42,25 @@
*/
typedef void _ElementVisitorFunction(Element element);
-class AbstractContextTest extends Object with ResourceProviderMixin {
- DartSdk sdk;
- Map<String, List<Folder>> packageMap;
- UriResolver resourceResolver;
-
- StringBuffer _logBuffer = new StringBuffer();
+class AbstractContextTest with ResourceProviderMixin {
FileContentOverlay fileContentOverlay = new FileContentOverlay();
AnalysisDriver _driver;
AnalysisDriver get driver => _driver;
+ AnalysisSession get session => driver.currentSession;
+
+ /// The file system specific `/home/test/pubspec.yaml` path.
+ String get testPubspecPath => convertPath('/home/test/pubspec.yaml');
+
void addFlutterPackage() {
- addMetaPackageSource();
+ addMetaPackage();
Folder libFolder = configureFlutterPackage(resourceProvider);
- packageMap['flutter'] = [libFolder];
- configureDriver();
+ _addTestPackageDependency('flutter', libFolder.parent.path);
}
- Source addMetaPackageSource() => addPackageSource('meta', 'meta.dart', r'''
+ void addMetaPackage() {
+ addPackageFile('meta', 'meta.dart', r'''
library meta;
const _IsTest isTest = const _IsTest();
@@ -88,13 +82,15 @@
const _IsTestGroup();
}
''');
+ }
- Source addPackageSource(String packageName, String filePath, String content) {
- packageMap[packageName] = [newFolder('/pubcache/$packageName/lib')];
- File file =
- newFile('/pubcache/$packageName/lib/$filePath', content: content);
- configureDriver();
- return file.createSource();
+ /// Add a new file with the given [pathInLib] to the package with the
+ /// given [packageName]. Then ensure that the test package depends on the
+ /// [packageName].
+ File addPackageFile(String packageName, String pathInLib, String content) {
+ var packagePath = '/.pub-cache/$packageName';
+ _addTestPackageDependency(packageName, packagePath);
+ return newFile('$packagePath/lib/$pathInLib', content: content);
}
Source addSource(String path, String content, [Uri uri]) {
@@ -106,52 +102,22 @@
return source;
}
- /**
- * Re-configure the driver. This is necessary, for example, after defining a
- * new package that test code will reference.
- */
- void configureDriver() {
- driver.configure();
- }
-
- void configurePreviewDart2() {
- driver.configure(
- analysisOptions: new AnalysisOptionsImpl.from(driver.analysisOptions)
- ..previewDart2 = true);
- }
-
- void processRequiredPlugins() {
- AnalysisEngine.instance.processRequiredPlugins();
- }
-
Future<CompilationUnit> resolveLibraryUnit(Source source) async {
- return (await driver.getResult(source.fullName))?.unit;
+ var resolveResult = await session.getResolvedUnit(source.fullName);
+ return resolveResult.unit;
}
void setUp() {
- processRequiredPlugins();
setupResourceProvider();
- sdk = new MockSdk(resourceProvider: resourceProvider);
- resourceResolver = new ResourceUriResolver(resourceProvider);
- packageMap = new Map<String, List<Folder>>();
- PackageMapUriResolver packageResolver =
- new PackageMapUriResolver(resourceProvider, packageMap);
- SourceFactory sourceFactory = new SourceFactory(
- [new DartUriResolver(sdk), packageResolver, resourceResolver]);
- PerformanceLog log = new PerformanceLog(_logBuffer);
- AnalysisDriverScheduler scheduler = new AnalysisDriverScheduler(log);
- _driver = new AnalysisDriver(
- scheduler,
- log,
- resourceProvider,
- new MemoryByteStore(),
- fileContentOverlay,
- new ContextRoot(resourceProvider.convertPath('/project'), [],
- pathContext: resourceProvider.pathContext),
- sourceFactory,
- new AnalysisOptionsImpl()..useFastaParser = analyzer.Parser.useFasta);
- scheduler.start();
- AnalysisEngine.instance.logger = PrintLogger.instance;
+
+ new MockSdk(resourceProvider: resourceProvider);
+
+ newFolder('/home/test');
+ newFile('/home/test/.packages', content: r'''
+test:file:///home/test/lib
+''');
+
+ _createDriver();
}
void setupResourceProvider() {}
@@ -160,28 +126,42 @@
AnalysisEngine.instance.clearCaches();
AnalysisEngine.instance.logger = null;
}
-}
-/**
- * Instances of the class [PrintLogger] print all of the errors.
- */
-class PrintLogger implements Logger {
- static final Logger instance = new PrintLogger();
-
- @override
- void logError(String message, [CaughtException exception]) {
- print(message);
- if (exception != null) {
- print(exception);
- }
+ /// Update `/home/test/pubspec.yaml` and create the driver.
+ void updateTestPubspecFile(String content) {
+ newFile(testPubspecPath, content: content);
+ _createDriver();
}
- @override
- void logInformation(String message, [CaughtException exception]) {
- print(message);
- if (exception != null) {
- print(exception);
+ void _addTestPackageDependency(String name, String rootPath) {
+ var packagesFile = getFile('/home/test/.packages');
+ var packagesContent = packagesFile.readAsStringSync();
+
+ // Ignore if there is already the same package dependency.
+ if (packagesContent.contains('$name:file://')) {
+ return;
}
+
+ packagesContent += '$name:${toUri('$rootPath/lib')}\n';
+
+ packagesFile.writeAsStringSync(packagesContent);
+
+ _createDriver();
+ }
+
+ void _createDriver() {
+ var collection = AnalysisContextCollectionImpl(
+ includedPaths: [convertPath('/home')],
+ enableIndex: true,
+ fileContentOverlay: fileContentOverlay,
+ resourceProvider: resourceProvider,
+ sdkPath: convertPath('/sdk'),
+ );
+
+ var testPath = convertPath('/home/test');
+ DriverBasedAnalysisContext context = collection.contextFor(testPath);
+
+ _driver = context.driver;
}
}
diff --git a/pkg/analysis_server/test/abstract_single_unit.dart b/pkg/analysis_server/test/abstract_single_unit.dart
index 78e2280..b0901725 100644
--- a/pkg/analysis_server/test/abstract_single_unit.dart
+++ b/pkg/analysis_server/test/abstract_single_unit.dart
@@ -1,14 +1,14 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/error/error.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/dart/error/hint_codes.dart';
import 'package:analyzer/src/generated/java_engine.dart';
@@ -23,7 +23,7 @@
String testCode;
String testFile;
Source testSource;
- AnalysisResult testAnalysisResult;
+ ResolvedUnitResult testAnalysisResult;
CompilationUnit testUnit;
CompilationUnitElement testUnitElement;
LibraryElement testLibraryElement;
@@ -64,7 +64,7 @@
AstNode findNodeAtOffset(int offset, [Predicate<AstNode> predicate]) {
AstNode result = new NodeLocator(offset).searchWithin(testUnit);
if (result != null && predicate != null) {
- result = result.getAncestor(predicate);
+ result = result.thisOrAncestorMatching(predicate);
}
return result;
}
@@ -112,7 +112,7 @@
Future<void> resolveTestUnit(String code) async {
addTestSource(code);
- testAnalysisResult = await driver.getResult(convertPath(testFile));
+ testAnalysisResult = await session.getResolvedUnit(testFile);
testUnit = testAnalysisResult.unit;
if (verifyNoTestUnitErrors) {
expect(testAnalysisResult.errors.where((AnalysisError error) {
@@ -132,7 +132,7 @@
@override
void setUp() {
super.setUp();
- testFile = resourceProvider.convertPath('/project/test.dart');
+ testFile = convertPath('/home/test/lib/test.dart');
}
}
diff --git a/pkg/analysis_server/test/analysis/get_errors_test.dart b/pkg/analysis_server/test/analysis/get_errors_test.dart
index 8649fcc..cb0baa7 100644
--- a/pkg/analysis_server/test/analysis/get_errors_test.dart
+++ b/pkg/analysis_server/test/analysis/get_errors_test.dart
@@ -67,13 +67,6 @@
}
@failingTest
- test_fileDoesNotExist() {
- // Broken under the new driver.
- String file = convertPath('$projectPath/doesNotExist.dart');
- return _checkInvalid(file);
- }
-
- @failingTest
test_fileWithoutContext() {
// Broken under the new driver.
String file = convertPath('/outside.dart');
@@ -112,25 +105,6 @@
expect(errors, isEmpty);
}
- @failingTest
- test_removeContextAfterRequest() async {
- // Broken under the new driver.
- addTestFile('''
-main() {
- print(42)
-}
-''');
- // handle the request synchronously
- Request request = _createGetErrorsRequest(testFile);
- server.handleRequest(request);
- // remove context, causes sending an "invalid file" error
- deleteFolder(projectPath);
- // wait for an error response
- Response response = await serverChannel.waitForResponse(request);
- expect(response.error, isNotNull);
- expect(response.error.code, RequestErrorCode.GET_ERRORS_INVALID_FILE);
- }
-
Future _checkInvalid(String file) async {
Request request = _createGetErrorsRequest(file);
Response response = await serverChannel.sendRequest(request);
diff --git a/pkg/analysis_server/test/analysis/get_navigation_test.dart b/pkg/analysis_server/test/analysis/get_navigation_test.dart
index 20f6b0f..d620a0d 100644
--- a/pkg/analysis_server/test/analysis/get_navigation_test.dart
+++ b/pkg/analysis_server/test/analysis/get_navigation_test.dart
@@ -75,7 +75,7 @@
}
test_fileOutsideOfRoot() async {
- testFile = resourceProvider.convertPath('/outside.dart');
+ testFile = convertPath('/outside.dart');
addTestFile('''
main() {
var test = 0;
diff --git a/pkg/analysis_server/test/analysis/get_signature_test.dart b/pkg/analysis_server/test/analysis/get_signature_test.dart
index fdf651e..10567ce 100644
--- a/pkg/analysis_server/test/analysis/get_signature_test.dart
+++ b/pkg/analysis_server/test/analysis/get_signature_test.dart
@@ -116,6 +116,21 @@
equals(new ParameterInfo(ParameterKind.NAMED, "length", "int")));
}
+ test_does_not_walk_up_over_closure() async {
+ addTestFile('''
+one(String name, int length) {}
+main() {
+ one("Danny", () {
+ /*^*/
+ });
+}
+''');
+ var result = await prepareRawSignature('/*^*/');
+ expect(result.error, isNotNull);
+ expect(result.error.code,
+ equals(RequestErrorCode.GET_SIGNATURE_UNKNOWN_FUNCTION));
+ }
+
test_error_file_invalid_path() async {
var result = await prepareRawSignatureAt(0, file: ':\\/?*');
expect(result.error, isNotNull);
@@ -125,10 +140,10 @@
test_error_file_not_analyzed() async {
var result = await prepareRawSignatureAt(0,
- file: resourceProvider.convertPath('/not/in/project.dart'));
+ file: convertPath('/not/in/project.dart'));
expect(result.error, isNotNull);
- expect(result.error.code,
- equals(RequestErrorCode.GET_SIGNATURE_UNKNOWN_FUNCTION));
+ expect(
+ result.error.code, equals(RequestErrorCode.GET_SIGNATURE_INVALID_FILE));
}
test_error_function_unknown() async {
@@ -438,19 +453,4 @@
expect(result.parameters[1],
equals(new ParameterInfo(ParameterKind.NAMED, "length", "int")));
}
-
- test_does_not_walk_up_over_closure() async {
- addTestFile('''
-one(String name, int length) {}
-main() {
- one("Danny", () {
- /*^*/
- });
-}
-''');
- var result = await prepareRawSignature('/*^*/');
- expect(result.error, isNotNull);
- expect(result.error.code,
- equals(RequestErrorCode.GET_SIGNATURE_UNKNOWN_FUNCTION));
- }
}
diff --git a/pkg/analysis_server/test/analysis_abstract.dart b/pkg/analysis_server/test/analysis_abstract.dart
index 3610b68..8415bc9 100644
--- a/pkg/analysis_server/test/analysis_abstract.dart
+++ b/pkg/analysis_server/test/analysis_abstract.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -18,6 +18,7 @@
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
@@ -26,7 +27,6 @@
import 'package:test/test.dart';
import 'package:watcher/watcher.dart';
-import 'mock_sdk.dart';
import 'mocks.dart';
int findIdentifierLength(String search) {
@@ -47,7 +47,7 @@
/**
* An abstract base for all 'analysis' domain tests.
*/
-class AbstractAnalysisTest extends Object with ResourceProviderMixin {
+class AbstractAnalysisTest with ResourceProviderMixin {
bool generateSummaryFiles = false;
MockServerChannel serverChannel;
TestPluginManager pluginManager;
@@ -120,7 +120,7 @@
serverChannel,
resourceProvider,
options,
- new DartSdkManager(resourceProvider.convertPath('/'), true),
+ new DartSdkManager(resourceProvider.convertPath('/sdk'), true),
InstrumentationService.NULL_SERVICE);
}
@@ -194,9 +194,9 @@
void setUp() {
serverChannel = new MockServerChannel();
- projectPath = resourceProvider.convertPath('/project');
- testFolder = resourceProvider.convertPath('/project/bin');
- testFile = resourceProvider.convertPath('/project/bin/test.dart');
+ projectPath = convertPath('/project');
+ testFolder = convertPath('/project/bin');
+ testFile = convertPath('/project/bin/test.dart');
pluginManager = new TestPluginManager();
server = createAnalysisServer();
server.pluginManager = pluginManager;
diff --git a/pkg/analysis_server/test/analysis_server_test.dart b/pkg/analysis_server/test/analysis_server_test.dart
index 789f634..8a9ea74 100644
--- a/pkg/analysis_server/test/analysis_server_test.dart
+++ b/pkg/analysis_server/test/analysis_server_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -11,15 +11,13 @@
import 'package:analysis_server/src/domain_server.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
-import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
-import 'package:plugin/manager.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'mock_sdk.dart';
import 'mocks.dart';
main() {
@@ -29,7 +27,7 @@
}
@reflectiveTest
-class AnalysisServerTest extends Object with ResourceProviderMixin {
+class AnalysisServerTest with ResourceProviderMixin {
MockServerChannel channel;
AnalysisServer server;
@@ -82,13 +80,7 @@
}
}
- void processRequiredPlugins() {
- ExtensionManager manager = new ExtensionManager();
- manager.processPlugins(AnalysisEngine.instance.requiredPlugins);
- }
-
void setUp() {
- processRequiredPlugins();
channel = new MockServerChannel();
// Create an SDK in the mock file system.
new MockSdk(resourceProvider: resourceProvider);
@@ -96,7 +88,7 @@
channel,
resourceProvider,
new AnalysisServerOptions(),
- new DartSdkManager(convertPath('/'), false),
+ new DartSdkManager(convertPath('/sdk'), false),
InstrumentationService.NULL_SERVICE);
}
@@ -114,8 +106,7 @@
var pkgFolder = convertPath('/pkg');
newFolder(pkgFolder);
newFolder(join(pkgFolder, 'lib'));
- newFile(join(pkgFolder, 'lib', 'test.dart'),
- content: 'class C {}');
+ newFile(join(pkgFolder, 'lib', 'test.dart'), content: 'class C {}');
server.setAnalysisRoots('0', [pkgFolder], [], {});
// Pump the event queue to make sure the server has finished any
// analysis.
diff --git a/pkg/analysis_server/test/completion_test.dart b/pkg/analysis_server/test/completion_test.dart
index 5bed630..50b8449 100644
--- a/pkg/analysis_server/test/completion_test.dart
+++ b/pkg/analysis_server/test/completion_test.dart
@@ -1709,8 +1709,7 @@
buildTests(
'testLibrary002',
'''t2() {var q=[0],z=q.!1length;q.!2clear();}''',
- <String>["1+length", "1+isEmpty", "2+clear"],
- failingTests: '1');
+ <String>["1+length", "1+isEmpty", "2+clear"]);
// TODO Include corelib analysis
buildTests('testLibrary003', '''class X{var q; f() {q.!1a!2}}''',
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index e04d0de..0bfbe6b 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -24,6 +24,7 @@
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/services/lint.dart';
import 'package:analyzer/src/summary/summary_file_builder.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer/src/util/glob.dart';
import 'package:linter/src/rules.dart';
@@ -34,7 +35,6 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:watcher/watcher.dart';
-import 'mock_sdk.dart';
import 'src/plugin/plugin_manager_test.dart';
main() {
@@ -500,7 +500,7 @@
var testLibUri = resourceProvider.pathContext.toUri(testLib);
resourceProvider.newFile(packagespecPath, 'unittest:$testLibUri');
String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
- File mainFile = newFile('$libPath/main.dart', content: '');
+ File mainFile = newFile('$libPath/main.dart');
Source source = mainFile.createSource();
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
@@ -586,8 +586,8 @@
// create files
newFile('$subProjectA/pubspec.yaml', content: 'pubspec');
newFile('$subProjectB/pubspec.yaml', content: 'pubspec');
- newFile('$subProjectA/.packages', content: '');
- newFile('$subProjectB/.packages', content: '');
+ newFile('$subProjectA/.packages');
+ newFile('$subProjectB/.packages');
newFile(rootFile, content: 'library root;');
newFile(subProjectA_file, content: 'library a;');
@@ -1641,7 +1641,7 @@
}
}
-abstract class ContextManagerTest extends Object with ResourceProviderMixin {
+abstract class ContextManagerTest with ResourceProviderMixin {
/**
* The name of the 'bin' directory.
*/
@@ -1741,7 +1741,7 @@
resourceProvider.newFolder(projPath);
// Create an SDK in the mock file system.
new MockSdk(generateSummaryFiles: true, resourceProvider: resourceProvider);
- DartSdkManager sdkManager = new DartSdkManager(convertPath('/'), true);
+ DartSdkManager sdkManager = new DartSdkManager(convertPath('/sdk'), true);
manager = new ContextManagerImpl(
resourceProvider,
new FileContentOverlay(),
@@ -2167,7 +2167,7 @@
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
await pumpEventQueue();
- AnalysisResult result = await callbacks.currentDriver.getResult(file.path);
+ var result = await callbacks.currentDriver.getResult(file.path);
// Not strong mode - both in the context and the SDK context.
// AnalysisContext sdkContext = sourceFactory.dartSdk.context;
@@ -2569,7 +2569,7 @@
ContextBuilderOptions builderOptions = new ContextBuilderOptions();
builderOptions.defaultOptions = options;
ContextBuilder builder = new ContextBuilder(
- resourceProvider, sdkManager, new ContentCache(),
+ resourceProvider, sdkManager, null,
options: builderOptions);
return builder;
}
diff --git a/pkg/analysis_server/test/domain_analysis_test.dart b/pkg/analysis_server/test/domain_analysis_test.dart
index 6bb6343..e50b52f 100644
--- a/pkg/analysis_server/test/domain_analysis_test.dart
+++ b/pkg/analysis_server/test/domain_analysis_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -10,17 +10,15 @@
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/domain_analysis.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
-import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
-import 'package:plugin/manager.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'analysis_abstract.dart';
-import 'mock_sdk.dart';
import 'mocks.dart';
main() {
@@ -64,8 +62,8 @@
expect(response, isResponseSuccess('0'));
// verify that unit is resolved eventually
await server.onAnalysisComplete;
- var unit = await serverRef.getResolvedCompilationUnit(file);
- expect(unit, isNotNull);
+ var resolvedUnit = await serverRef.getResolvedUnit(file);
+ expect(resolvedUnit, isNotNull);
}
test_setAnalysisRoots_included_nonexistentFolder() async {
@@ -78,8 +76,8 @@
// Non-existence of /project_a should not prevent files in /project_b
// from being analyzed.
await server.onAnalysisComplete;
- var unit = await serverRef.getResolvedCompilationUnit(fileB);
- expect(unit, isNotNull);
+ var resolvedUnit = await serverRef.getResolvedUnit(fileB);
+ expect(resolvedUnit, isNotNull);
}
test_setAnalysisRoots_included_notAbsolute() async {
@@ -338,7 +336,7 @@
/**
* A helper to test 'analysis.*' requests.
*/
-class AnalysisTestHelper extends Object with ResourceProviderMixin {
+class AnalysisTestHelper with ResourceProviderMixin {
MockServerChannel serverChannel;
AnalysisServer server;
AnalysisDomainHandler handler;
@@ -356,7 +354,6 @@
AnalysisTestHelper() {
projectPath = convertPath('/project');
testFile = convertPath('/project/bin/test.dart');
- processRequiredPlugins();
serverChannel = new MockServerChannel();
// Create an SDK in the mock file system.
new MockSdk(resourceProvider: resourceProvider);
@@ -364,7 +361,7 @@
serverChannel,
resourceProvider,
new AnalysisServerOptions(),
- new DartSdkManager(convertPath('/'), false),
+ new DartSdkManager(convertPath('/sdk'), false),
InstrumentationService.NULL_SERVICE);
handler = new AnalysisDomainHandler(server);
// listen for notifications
@@ -518,11 +515,6 @@
expect(response, isResponseSuccess('0'));
}
- void processRequiredPlugins() {
- ExtensionManager manager = new ExtensionManager();
- manager.processPlugins(AnalysisEngine.instance.requiredPlugins);
- }
-
/**
* Send an `updateContent` request for [testFile].
*/
@@ -661,7 +653,7 @@
}
test_afterAnalysis_sdkFile() async {
- String file = convertPath('/lib/core/core.dart');
+ String file = convertPath('/sdk/lib/core/core.dart');
addTestFile('// no matter');
createProject();
// wait for analysis, no results initially
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index 0566e1f..b3c7c46 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -238,7 +238,7 @@
//
// We no longer support the analysis of non-dart files.
//
- testFile = resourceProvider.convertPath('/project/web/test.html');
+ testFile = convertPath('/project/web/test.html');
addTestFile('''
<html>^</html>
''');
diff --git a/pkg/analysis_server/test/domain_server_test.dart b/pkg/analysis_server/test/domain_server_test.dart
index f7f1fda..1d8389f 100644
--- a/pkg/analysis_server/test/domain_server_test.dart
+++ b/pkg/analysis_server/test/domain_server_test.dart
@@ -67,14 +67,9 @@
});
test('shutdown', () async {
- expect(server.running, isTrue);
- // send request
var request = new ServerShutdownParams().toRequest('0');
var response = await serverChannel.sendRequest(request);
expect(response, isResponseSuccess('0'));
-
- // server is down
- expect(server.running, isFalse);
});
});
}
diff --git a/pkg/analysis_server/test/edit/fixes_test.dart b/pkg/analysis_server/test/edit/fixes_test.dart
index 4d07618..c9c5eaa 100644
--- a/pkg/analysis_server/test/edit/fixes_test.dart
+++ b/pkg/analysis_server/test/edit/fixes_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -35,11 +35,12 @@
createProject();
addTestFile('''
main() {
- Future<String> x = null;
+ Completer<String> x = null;
}
''');
await waitForTasksFinished();
- List<AnalysisErrorFixes> errorFixes = await _getFixesAt('Future<String>');
+ List<AnalysisErrorFixes> errorFixes =
+ await _getFixesAt('Completer<String>');
expect(errorFixes, hasLength(1));
AnalysisError error = errorFixes[0].error;
expect(error.severity, AnalysisErrorSeverity.WARNING);
@@ -130,7 +131,7 @@
handler: analysisHandler);
// Configure the test file.
- testFile = resourceProvider.convertPath('/aaa/main.dart');
+ testFile = convertPath('/aaa/main.dart');
testCode = 'main() { new Foo(); }';
_addOverlay(testFile, testCode);
diff --git a/pkg/analysis_server/test/integration/analysis/get_errors_nonStandard_sdk_test.dart b/pkg/analysis_server/test/integration/analysis/get_errors_nonStandard_sdk_test.dart
index be6e77a..4b102a6 100644
--- a/pkg/analysis_server/test/integration/analysis/get_errors_nonStandard_sdk_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/get_errors_nonStandard_sdk_test.dart
@@ -5,13 +5,11 @@
import 'dart:async';
import 'dart:io';
-import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:path/path.dart' as path;
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../mock_sdk.dart';
import '../support/integration_tests.dart';
main() {
@@ -28,42 +26,56 @@
class AnalysisDomainGetErrorsTest
extends AbstractAnalysisServerIntegrationTest {
String createNonStandardSdk() {
- MockSdkLibrary fakeLibrary =
- new MockSdkLibrary('dart:fake', '/lib/fake/fake.dart', '');
- String sdkPath = path.join(sourceDirectory.path, 'sdk');
- StringBuffer librariesContent = new StringBuffer();
- librariesContent.writeln(
- 'final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {');
- MockSdk.LIBRARIES.toList()
- ..add(fakeLibrary)
- ..forEach((SdkLibrary library) {
- List<String> components = path.posix.split(library.path);
- components[0] = sdkPath;
- String libraryPath = path.joinAll(components);
- new Directory(path.dirname(libraryPath)).createSync(recursive: true);
- new File(libraryPath)
- .writeAsStringSync((library as MockSdkLibrary).content);
+ var sdkPath = path.join(sourceDirectory.path, 'sdk');
- String relativePath = path.joinAll(components.sublist(2));
- librariesContent.write('"');
- librariesContent
- .write(library.shortName.substring(5)); // Remove the 'dart:' prefix
- librariesContent.write('": const LibraryInfo("');
- librariesContent.write(relativePath);
- librariesContent.writeln('"),');
- });
- librariesContent.writeln('};');
+ new Directory(path.join(sdkPath, 'lib', 'core'))
+ .createSync(recursive: true);
+ new Directory(path.join(sdkPath, 'lib', 'async'))
+ .createSync(recursive: true);
+ new Directory(path.join(sdkPath, 'lib', 'fake'))
+ .createSync(recursive: true);
- String librariesPath = path.joinAll([
+ new File(path.join(sdkPath, 'lib', 'core', 'core.dart'))
+ .writeAsStringSync(r'''
+library dart.core;
+import 'dart:async';
+class bool {}
+class double {}
+class int {}
+class num {}
+class Object {}
+class Map<K, V> {}
+class Null {}
+class String {}
+class Type {}
+''');
+
+ new File(path.join(sdkPath, 'lib', 'async', 'async.dart'))
+ .writeAsStringSync(r'''
+library dart.async;
+class Future<T> {}
+''');
+
+ new File(path.join(sdkPath, 'lib', 'fake', 'fake.dart'))
+ .writeAsStringSync(r'''
+class Fake {}
+''');
+
+ var libsDir = path.join(
sdkPath,
'lib',
'_internal',
'sdk_library_metadata',
'lib',
- 'libraries.dart'
- ]);
- new Directory(path.dirname(librariesPath)).createSync(recursive: true);
- new File(librariesPath).writeAsStringSync(librariesContent.toString());
+ );
+ new Directory(libsDir).createSync(recursive: true);
+ new File(path.join(libsDir, 'libraries.dart')).writeAsStringSync(r'''
+final LIBRARIES = const <String, LibraryInfo> {
+ "core": const LibraryInfo("core/core.dart"),
+ "async": const LibraryInfo("async/async.dart"),
+ "fake": const LibraryInfo("fake/fake.dart"),
+};
+''');
return sdkPath;
}
diff --git a/pkg/analysis_server/test/integration/analysis/hint_sdk_version_async_exported_from_core_test.dart b/pkg/analysis_server/test/integration/analysis/hint_sdk_version_async_exported_from_core_test.dart
new file mode 100644
index 0000000..6703374
--- /dev/null
+++ b/pkg/analysis_server/test/integration/analysis/hint_sdk_version_async_exported_from_core_test.dart
@@ -0,0 +1,65 @@
+// Copyright (c) 2018, 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:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../support/integration_tests.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(SdkVersionAsyncExportedFromCoreIntegrationTest);
+ });
+}
+
+@reflectiveTest
+class SdkVersionAsyncExportedFromCoreIntegrationTest
+ extends AbstractAnalysisServerIntegrationTest {
+ test_update_pubspec() async {
+ var pubspecPath = sourcePath('pubspec.yaml');
+ writeFile(pubspecPath, r'''
+name: test
+environment:
+ sdk: ^2.0.0
+''');
+
+ var testPath = sourcePath('lib/test.dart');
+ writeFile(testPath, '''
+Future<int> zero() async => 0;
+''');
+ standardAnalysisSetup();
+
+ // There is a hint with this SDK version constraint.
+ await analysisFinished;
+ expect(currentAnalysisErrors[testPath], hasLength(1));
+
+ // 2.0.0 -> 2.1.0
+ {
+ writeFile(pubspecPath, r'''
+name: test
+environment:
+ sdk: ^2.1.0
+''');
+
+ // The pubspec.yaml file change has been noticed and processed.
+ // No more hints.
+ await analysisFinished;
+ expect(currentAnalysisErrors[testPath], isEmpty);
+ }
+
+ // 2.1.0 -> 2.0.0
+ {
+ writeFile(pubspecPath, r'''
+name: test
+environment:
+ sdk: ^2.0.0
+''');
+
+ // The pubspec.yaml file change has been noticed and processed.
+ // There is a hint again.
+ await analysisFinished;
+ expect(currentAnalysisErrors[testPath], hasLength(1));
+ }
+ }
+}
diff --git a/pkg/analysis_server/test/integration/analysis/test_all.dart b/pkg/analysis_server/test/integration/analysis/test_all.dart
index 99021da..d85814a 100644
--- a/pkg/analysis_server/test/integration/analysis/test_all.dart
+++ b/pkg/analysis_server/test/integration/analysis/test_all.dart
@@ -15,6 +15,8 @@
import 'get_reachable_sources_test.dart' as get_reachable_sources_test;
import 'highlights2_test.dart' as highlights2_test;
import 'highlights_test.dart' as highlights_test;
+import 'hint_sdk_version_async_exported_from_core_test.dart'
+ as hint_sdk_version_async_exported_from_core_test;
import 'lint_test.dart' as lint_test;
import 'navigation_test.dart' as navigation_test;
import 'occurrences_test.dart' as occurrences_test;
@@ -47,6 +49,7 @@
get_reachable_sources_test.main();
highlights2_test.main();
highlights_test.main();
+ hint_sdk_version_async_exported_from_core_test.main();
lint_test.main();
navigation_test.main();
occurrences_test.main();
diff --git a/pkg/analysis_server/test/lsp/completion_test.dart b/pkg/analysis_server/test/lsp/completion_test.dart
new file mode 100644
index 0000000..aa7002c
--- /dev/null
+++ b/pkg/analysis_server/test/lsp/completion_test.dart
@@ -0,0 +1,276 @@
+// Copyright (c) 2018, 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/lsp_protocol/protocol_generated.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'server_abstract.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(CompletionTest);
+ });
+}
+
+@reflectiveTest
+class CompletionTest extends AbstractLspAnalysisServerTest {
+ test_completionKinds_default() async {
+ newFile(join(projectFolderPath, 'file.dart'));
+ newFolder(join(projectFolderPath, 'folder'));
+
+ final content = "import '^';";
+
+ await initialize();
+ await openFile(mainFileUri, withoutMarkers(content));
+ final res = await getCompletion(mainFileUri, positionFromMarker(content));
+
+ final file = res.singleWhere((c) => c.label == 'file.dart');
+ final folder = res.singleWhere((c) => c.label == 'folder/');
+ final builtin = res.singleWhere((c) => c.label == 'dart:core');
+ // Default capabilities include File + Module but not Folder.
+ expect(file.kind, equals(CompletionItemKind.File));
+ // We fall back to Module if Folder isn't supported.
+ expect(folder.kind, equals(CompletionItemKind.Module));
+ expect(builtin.kind, equals(CompletionItemKind.Module));
+ }
+
+ test_completionKinds_imports() async {
+ final content = "import '^';";
+
+ // Tell the server we support some specific CompletionItemKinds.
+ await initialize(textDocumentCapabilities: {
+ 'completion': {
+ 'completionItemKind': {
+ 'valueSet': [
+ CompletionItemKind.File.toJson(),
+ CompletionItemKind.Folder.toJson(),
+ CompletionItemKind.Module.toJson(),
+ ],
+ }
+ },
+ });
+ await openFile(mainFileUri, withoutMarkers(content));
+ final res = await getCompletion(mainFileUri, positionFromMarker(content));
+
+ final file = res.singleWhere((c) => c.label == 'file.dart');
+ final folder = res.singleWhere((c) => c.label == 'folder/');
+ final builtin = res.singleWhere((c) => c.label == 'dart:core');
+ expect(file.kind, equals(CompletionItemKind.File));
+ expect(folder.kind, equals(CompletionItemKind.Folder));
+ expect(builtin.kind, equals(CompletionItemKind.Module));
+ }
+
+ test_completionKinds_supportedSubset() async {
+ final content = '''
+ class MyClass {
+ String abcdefghij;
+ }
+
+ main() {
+ MyClass a;
+ a.abc^
+ }
+ ''';
+
+ // Tell the server we only support the Field CompletionItemKind.
+ await initialize(textDocumentCapabilities: {
+ 'completion': {
+ 'completionItemKind': {
+ 'valueSet': [
+ CompletionItemKind.Field.toJson(),
+ ],
+ }
+ },
+ });
+ await openFile(mainFileUri, withoutMarkers(content));
+ final res = await getCompletion(mainFileUri, positionFromMarker(content));
+ final kinds = res.map((item) => item.kind).toList();
+
+ // Ensure we only get nulls or Fields (the sample code contains Classes).
+ expect(
+ kinds,
+ everyElement(anyOf(isNull, equals(CompletionItemKind.Field))),
+ );
+ }
+
+ test_gettersAndSetters() async {
+ final content = '''
+ class MyClass {
+ String get justGetter => '';
+ String set justSetter(String value) {}
+ String get getterAndSetter => '';
+ String set getterAndSetter(String value) {}
+ }
+
+ main() {
+ MyClass a;
+ a.^
+ }
+ ''';
+
+ await initialize();
+ await openFile(mainFileUri, withoutMarkers(content));
+ final res = await getCompletion(mainFileUri, positionFromMarker(content));
+ final getter = res.singleWhere((c) => c.label == 'justGetter');
+ final setter = res.singleWhere((c) => c.label == 'justSetter');
+ final both = res.singleWhere((c) => c.label == 'getterAndSetter');
+ expect(getter.detail, equals('String'));
+ expect(setter.detail, equals('String'));
+ expect(both.detail, equals('String'));
+ [getter, setter, both].forEach((item) {
+ expect(item.kind, equals(CompletionItemKind.Property));
+ });
+ }
+
+ test_insideString() async {
+ final content = '''
+ var a = "This is ^a test"
+ ''';
+
+ await initialize();
+ await openFile(mainFileUri, withoutMarkers(content));
+ final res = await getCompletion(mainFileUri, positionFromMarker(content));
+ expect(res, isEmpty);
+ }
+
+ test_isDeprecated_notSupported() async {
+ final content = '''
+ class MyClass {
+ @deprecated
+ String abcdefghij;
+ }
+
+ main() {
+ MyClass a;
+ a.abc^
+ }
+ ''';
+
+ await initialize();
+ await openFile(mainFileUri, withoutMarkers(content));
+ final res = await getCompletion(mainFileUri, positionFromMarker(content));
+ final item = res.singleWhere((c) => c.label == 'abcdefghij');
+ expect(item.deprecated, isNull);
+ // If the does not say it supports the deprecated flag, we should show
+ // '(deprecated)' in the details.
+ expect(item.detail.toLowerCase(), contains('deprecated'));
+ }
+
+ test_isDeprecated_supported() async {
+ final content = '''
+ class MyClass {
+ @deprecated
+ String abcdefghij;
+ }
+
+ main() {
+ MyClass a;
+ a.abc^
+ }
+ ''';
+
+ await initialize(textDocumentCapabilities: {
+ 'completion': {
+ 'completionItem': {
+ 'deprecatedSupport': true,
+ }
+ },
+ });
+ await openFile(mainFileUri, withoutMarkers(content));
+ final res = await getCompletion(mainFileUri, positionFromMarker(content));
+ final item = res.singleWhere((c) => c.label == 'abcdefghij');
+ expect(item.deprecated, isTrue);
+ // If the client says it supports the deprecated flag, we should not show
+ // deprecated in the details.
+ expect(item.detail, isNot(contains('deprecated')));
+ }
+
+ test_plainText_simple() async {
+ final content = '''
+ class MyClass {
+ String abcdefghij;
+ }
+
+ main() {
+ MyClass a;
+ a.abc^
+ }
+ ''';
+
+ await initialize();
+ await openFile(mainFileUri, withoutMarkers(content));
+ final res = await getCompletion(mainFileUri, positionFromMarker(content));
+ expect(res.any((c) => c.label == 'abcdefghij'), isTrue);
+ final item = res.singleWhere((c) => c.label == 'abcdefghij');
+ expect(item.insertTextFormat, equals(InsertTextFormat.PlainText));
+ // ignore: deprecated_member_use
+ expect(item.insertText, anyOf(equals('abcdefghij'), isNull));
+ final updated = applyEdits(withoutMarkers(content), [item.textEdit]);
+ expect(updated, contains('a.abcdefghij'));
+ }
+
+ test_snippet_simple() async {
+ final content = '''
+ class MyClass {
+ String abcdefghij;
+ }
+
+ main() {
+ MyClass a;
+ a.abc^
+ }
+ ''';
+
+ await initialize(textDocumentCapabilities: {
+ 'completion': {
+ 'completionItem': {
+ 'snippetSupport': true,
+ }
+ }
+ });
+ await openFile(mainFileUri, withoutMarkers(content));
+ final res = await getCompletion(mainFileUri, positionFromMarker(content));
+ expect(res.any((c) => c.label == 'abcdefghij'), isTrue);
+ final item = res.singleWhere((c) => c.label == 'abcdefghij');
+ // ignore: deprecated_member_use
+ expect(item.insertText, anyOf(equals('abcdefghij'), isNull));
+ expect(item.insertTextFormat, equals(InsertTextFormat.Snippet));
+ final updated = applyEdits(withoutMarkers(content), [item.textEdit]);
+ expect(updated, contains('a.abcdefghij'));
+ expect(item.kind, equals(CompletionItemKind.Field));
+ }
+
+ @failingTest
+ test_snippet_withSelection() async {
+ // TODO(dantup): Implement snippet functionality + test.
+ // Like above, but one that actually has a selectionOffset and results in
+ // a snippet with tabstop.
+ fail('NYI');
+ }
+
+ test_unopenFile() async {
+ final content = '''
+ class MyClass {
+ String abcdefghij;
+ }
+
+ main() {
+ MyClass a;
+ a.abc^
+ }
+ ''';
+
+ newFile(mainFilePath, content: withoutMarkers(content));
+ await initialize();
+ final res = await getCompletion(mainFileUri, positionFromMarker(content));
+ expect(res.any((c) => c.label == 'abcdefghij'), isTrue);
+ final item = res.singleWhere((c) => c.label == 'abcdefghij');
+ expect(item.insertTextFormat, equals(InsertTextFormat.PlainText));
+ // ignore: deprecated_member_use
+ expect(item.insertText, anyOf(equals('abcdefghij'), isNull));
+ final updated = applyEdits(withoutMarkers(content), [item.textEdit]);
+ expect(updated, contains('a.abcdefghij'));
+ }
+}
diff --git a/pkg/analysis_server/test/lsp/definition_test.dart b/pkg/analysis_server/test/lsp/definition_test.dart
new file mode 100644
index 0000000..4e99a7f
--- /dev/null
+++ b/pkg/analysis_server/test/lsp/definition_test.dart
@@ -0,0 +1,89 @@
+// Copyright (c) 2018, 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/lsp_protocol/protocol_generated.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'server_abstract.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(DefinitionTest);
+ });
+}
+
+@reflectiveTest
+class DefinitionTest extends AbstractLspAnalysisServerTest {
+ test_acrossFiles() async {
+ final mainContents = '''
+ import 'referenced.dart';
+
+ main() {
+ fo^o();
+ }
+ ''';
+
+ final referencedContents = '''
+ /// Ensure the function is on a line that
+ /// does not exist in the mainContents file
+ /// to ensure we're translating offsets to line/col
+ /// using the correct file's LineInfo
+ /// ...
+ /// ...
+ /// ...
+ /// ...
+ /// ...
+ [[foo]]() {}
+ ''';
+
+ final referencedFileUri =
+ Uri.file(join(projectFolderPath, 'lib', 'referenced.dart'));
+
+ await initialize();
+ await openFile(mainFileUri, withoutMarkers(mainContents));
+ await openFile(referencedFileUri, withoutMarkers(referencedContents));
+ final res =
+ await getDefinition(mainFileUri, positionFromMarker(mainContents));
+
+ expect(res, hasLength(1));
+ Location loc = res.single;
+ expect(loc.range, equals(rangeFromMarkers(referencedContents)));
+ expect(loc.uri, equals(referencedFileUri.toString()));
+ }
+
+ test_singleFile() async {
+ final contents = '''
+ [[foo]]() {
+ fo^o();
+ }
+ ''';
+
+ await initialize();
+ await openFile(mainFileUri, withoutMarkers(contents));
+ final res = await getDefinition(mainFileUri, positionFromMarker(contents));
+
+ expect(res, hasLength(1));
+ Location loc = res.single;
+ expect(loc.range, equals(rangeFromMarkers(contents)));
+ expect(loc.uri, equals(mainFileUri.toString()));
+ }
+
+ test_unopenFile() async {
+ final contents = '''
+ [[foo]]() {
+ fo^o();
+ }
+ ''';
+
+ newFile(mainFilePath, content: withoutMarkers(contents));
+ await initialize();
+ final res = await getDefinition(mainFileUri, positionFromMarker(contents));
+
+ expect(res, hasLength(1));
+ Location loc = res.single;
+ expect(loc.range, equals(rangeFromMarkers(contents)));
+ expect(loc.uri, equals(mainFileUri.toString()));
+ }
+}
diff --git a/pkg/analysis_server/test/lsp/diagnostic_test.dart b/pkg/analysis_server/test/lsp/diagnostic_test.dart
new file mode 100644
index 0000000..430b8a1
--- /dev/null
+++ b/pkg/analysis_server/test/lsp/diagnostic_test.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2018, 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:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'server_abstract.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(DiagnosticTest);
+ });
+}
+
+@reflectiveTest
+class DiagnosticTest extends AbstractLspAnalysisServerTest {
+ test_afterDocumentEdits() async {
+ const initialContents = 'int a = 1;';
+ newFile(mainFilePath, content: initialContents);
+
+ await initialize();
+ final initialDiagnostics = await waitForDiagnostics(mainFileUri);
+ expect(initialDiagnostics, hasLength(0));
+
+ await openFile(mainFileUri, initialContents);
+ await replaceFile(mainFileUri, 'String a = 1;');
+ final updatedDiagnostics = await waitForDiagnostics(mainFileUri);
+ expect(updatedDiagnostics, hasLength(1));
+ }
+
+ test_initialAnalysis() async {
+ newFile(mainFilePath, content: 'String a = 1;');
+
+ await initialize();
+ final diagnostics = await waitForDiagnostics(mainFileUri);
+ expect(diagnostics, hasLength(1));
+ final diagnostic = diagnostics.first;
+ expect(diagnostic.code, equals('invalid_assignment'));
+ expect(diagnostic.range.start.line, equals(0));
+ expect(diagnostic.range.start.character, equals(11));
+ expect(diagnostic.range.end.line, equals(0));
+ expect(diagnostic.range.end.character, equals(12));
+ }
+}
diff --git a/pkg/analysis_server/test/lsp/document_symbols_test.dart b/pkg/analysis_server/test/lsp/document_symbols_test.dart
new file mode 100644
index 0000000..752a160
--- /dev/null
+++ b/pkg/analysis_server/test/lsp/document_symbols_test.dart
@@ -0,0 +1,109 @@
+// Copyright (c) 2018, 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/lsp_protocol/protocol_generated.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'server_abstract.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(DocumentSymbolsTest);
+ });
+}
+
+@reflectiveTest
+class DocumentSymbolsTest extends AbstractLspAnalysisServerTest {
+ test_hierarchical() async {
+ const content = '''
+ String topLevel = '';
+ class MyClass {
+ int myField;
+ MyClass(this.myField);
+ myMethod() {}
+ }
+ ''';
+ newFile(mainFilePath, content: content);
+ await initialize(textDocumentCapabilities: {
+ 'documentSymbol': {
+ 'hierarchicalDocumentSymbolSupport': true,
+ },
+ });
+
+ final result = await getDocumentSymbols(mainFileUri.toString());
+ final symbols = result.map(
+ (docsymbols) => docsymbols,
+ (symbolInfos) => throw 'Expected DocumentSymbols, got SymbolInformations',
+ );
+
+ expect(symbols, hasLength(2));
+
+ final topLevel = symbols[0];
+ expect(topLevel.name, equals('topLevel'));
+ expect(topLevel.kind, equals(SymbolKind.Variable));
+
+ final myClass = symbols[1];
+ expect(myClass.name, equals('MyClass'));
+ expect(myClass.kind, equals(SymbolKind.Class));
+ expect(myClass.children, hasLength(3));
+
+ final field = myClass.children[0];
+ expect(field.name, equals('myField'));
+ expect(field.kind, equals(SymbolKind.Field));
+
+ final constructor = myClass.children[1];
+ expect(constructor.name, equals('MyClass'));
+ expect(constructor.kind, equals(SymbolKind.Constructor));
+
+ final method = myClass.children[2];
+ expect(method.name, equals('myMethod'));
+ expect(method.kind, equals(SymbolKind.Method));
+ }
+
+ test_flat() async {
+ const content = '''
+ String topLevel = '';
+ class MyClass {
+ int myField;
+ MyClass(this.myField);
+ myMethod() {}
+ }
+ ''';
+ newFile(mainFilePath, content: content);
+ await initialize();
+
+ final result = await getDocumentSymbols(mainFileUri.toString());
+ final symbols = result.map(
+ (docsymbols) => throw 'Expected SymbolInformations, got DocumentSymbols',
+ (symbolInfos) => symbolInfos,
+ );
+ expect(symbols, hasLength(5));
+
+ final topLevel = symbols[0];
+ expect(topLevel.name, equals('topLevel'));
+ expect(topLevel.kind, equals(SymbolKind.Variable));
+ expect(topLevel.containerName, isNull);
+
+ final myClass = symbols[1];
+ expect(myClass.name, equals('MyClass'));
+ expect(myClass.kind, equals(SymbolKind.Class));
+ expect(myClass.containerName, isNull);
+
+ final field = symbols[2];
+ expect(field.name, equals('myField'));
+ expect(field.kind, equals(SymbolKind.Field));
+ expect(field.containerName, equals(myClass.name));
+
+ final constructor = symbols[3];
+ expect(constructor.name, equals('MyClass'));
+ expect(constructor.kind, equals(SymbolKind.Constructor));
+ expect(constructor.containerName, equals(myClass.name));
+
+ final method = symbols[4];
+ expect(method.name, equals('myMethod'));
+ expect(method.kind, equals(SymbolKind.Method));
+ expect(method.containerName, equals(myClass.name));
+ }
+}
diff --git a/pkg/analysis_server/test/lsp/file_modification_test.dart b/pkg/analysis_server/test/lsp/file_modification_test.dart
new file mode 100644
index 0000000..a7ec93c
--- /dev/null
+++ b/pkg/analysis_server/test/lsp/file_modification_test.dart
@@ -0,0 +1,110 @@
+// Copyright (c) 2018, 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/lsp_protocol/protocol_generated.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'server_abstract.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(FileModificationTest);
+ });
+}
+
+@reflectiveTest
+class FileModificationTest extends AbstractLspAnalysisServerTest {
+ test_change_badPosition() async {
+ final contents = '';
+ await initialize();
+ await openFile(mainFileUri, contents);
+
+ // Since this is a notification and not a request, the server cannot
+ // respond with an error, but instead sends a ShowMessage notification
+ // to alert the user to something failing.
+ final error = await expectErrorNotification<ShowMessageParams>(() async {
+ await changeFile(mainFileUri, [
+ new TextDocumentContentChangeEvent(
+ new Range(new Position(999, 999), new Position(999, 999)),
+ null,
+ ' ',
+ )
+ ]);
+ });
+
+ expect(error.message, contains('Invalid line'));
+ }
+
+ test_change_fullContents() async {
+ final initialContent = 'int a = 1;';
+ final updatedContent = 'int a = 2;';
+
+ await initialize();
+ await openFile(mainFileUri, initialContent);
+ await replaceFile(mainFileUri, updatedContent);
+ expect(server.fileContentOverlay[mainFilePath], equals(updatedContent));
+ }
+
+ test_change_incremental() async {
+ final initialContent = '0123456789\n0123456789';
+ final expectedUpdatedContent = '0123456789\n01234 89';
+
+ await initialize();
+ await openFile(mainFileUri, initialContent);
+ await changeFile(mainFileUri, [
+ // Replace line1:5-1:8 with spaces.
+ new TextDocumentContentChangeEvent(
+ new Range(new Position(1, 5), new Position(1, 8)),
+ null,
+ ' ',
+ )
+ ]);
+ expect(server.fileContentOverlay[mainFilePath],
+ equals(expectedUpdatedContent));
+ }
+
+ test_change_unopenedFile() async {
+ // It's not valid for a client to send a request to modify a file that it
+ // has not opened, but Visual Studio has done it in the past so we should
+ // ensure it generates an obvious error that the user can understand.
+ final simpleEdit = new TextDocumentContentChangeEvent(
+ new Range(new Position(1, 1), new Position(1, 1)),
+ null,
+ 'test',
+ );
+ await initialize();
+ final notificationParams = await expectErrorNotification<ShowMessageParams>(
+ () => changeFile(mainFileUri, [simpleEdit]),
+ );
+ expect(notificationParams, isNotNull);
+ expect(
+ notificationParams.message,
+ allOf(
+ contains('because the file was not previously opened'),
+ contains(mainFilePath),
+ ),
+ );
+ }
+
+ test_close() async {
+ final initialContent = 'int a = 1;';
+ final updatedContent = 'int a = 2;';
+
+ await initialize();
+ await openFile(mainFileUri, initialContent);
+ await replaceFile(mainFileUri, updatedContent);
+ await closeFile(mainFileUri);
+ expect(server.fileContentOverlay[mainFilePath], isNull);
+ }
+
+ test_open() async {
+ const testContent = 'CONTENT';
+
+ await initialize();
+ expect(server.fileContentOverlay[mainFilePath], isNull);
+ await openFile(mainFileUri, testContent);
+ expect(server.fileContentOverlay[mainFilePath], equals(testContent));
+ }
+}
diff --git a/pkg/analysis_server/test/lsp/format_test.dart b/pkg/analysis_server/test/lsp/format_test.dart
new file mode 100644
index 0000000..4b58805
--- /dev/null
+++ b/pkg/analysis_server/test/lsp/format_test.dart
@@ -0,0 +1,136 @@
+// Copyright (c) 2018, 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/lsp_protocol/protocol_special.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../tool/lsp_spec/matchers.dart';
+import 'server_abstract.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(FormatTest);
+ });
+}
+
+@reflectiveTest
+class FormatTest extends AbstractLspAnalysisServerTest {
+ test_alreadyFormatted() async {
+ const contents = '''main() {
+ print('test');
+}
+''';
+ await initialize();
+ await openFile(mainFileUri, contents);
+
+ final formatEdits = await formatDocument(mainFileUri.toString());
+ expect(formatEdits, isNull);
+ }
+
+ test_formatOnType_simple() async {
+ const contents = '''
+ main ()
+ {
+
+ print('test');
+ ^}
+ ''';
+ final expected = '''main() {
+ print('test');
+}
+''';
+ await initialize();
+ await openFile(mainFileUri, withoutMarkers(contents));
+
+ final formatEdits = await formatOnType(
+ mainFileUri.toString(), positionFromMarker(contents), '}');
+ expect(formatEdits, isNotNull);
+ final formattedContents = applyEdits(contents, formatEdits);
+ expect(formattedContents, equals(expected));
+ }
+
+ test_invalidSyntax() async {
+ const contents = '''main(((( {
+ print('test');
+}
+''';
+ await initialize();
+ await openFile(mainFileUri, contents);
+
+ final formatEdits = await formatDocument(mainFileUri.toString());
+ expect(formatEdits, isNull);
+ }
+
+ test_path_doesNotExist() async {
+ await initialize();
+
+ await expectLater(
+ formatDocument(
+ new Uri.file(join(projectFolderPath, 'missing.dart')).toString()),
+ throwsA(isResponseError(ServerErrorCodes.InvalidFilePath)),
+ );
+ }
+
+ test_path_invalidFormat() async {
+ await initialize();
+
+ await expectLater(
+ // Add some invalid path characters to the end of a valid file:// URI.
+ formatDocument(mainFileUri.toString() + '***'),
+ throwsA(isResponseError(ServerErrorCodes.InvalidFilePath)),
+ );
+ }
+
+ test_path_notFileScheme() async {
+ await initialize();
+
+ await expectLater(
+ formatDocument('a:/a.a'),
+ throwsA(isResponseError(ServerErrorCodes.InvalidFilePath)),
+ );
+ }
+
+ test_simple() async {
+ const contents = '''
+ main ()
+ {
+
+ print('test');
+ }
+ ''';
+ final expected = '''main() {
+ print('test');
+}
+''';
+ await initialize();
+ await openFile(mainFileUri, contents);
+
+ final formatEdits = await formatDocument(mainFileUri.toString());
+ expect(formatEdits, isNotNull);
+ final formattedContents = applyEdits(contents, formatEdits);
+ expect(formattedContents, equals(expected));
+ }
+
+ test_unopenFile() async {
+ const contents = '''
+ main ()
+ {
+
+ print('test');
+ }
+ ''';
+ final expected = '''main() {
+ print('test');
+}
+''';
+ newFile(mainFilePath, content: contents);
+ await initialize();
+
+ final formatEdits = await formatDocument(mainFileUri.toString());
+ expect(formatEdits, isNotNull);
+ final formattedContents = applyEdits(contents, formatEdits);
+ expect(formattedContents, equals(expected));
+ }
+}
diff --git a/pkg/analysis_server/test/lsp/hover_test.dart b/pkg/analysis_server/test/lsp/hover_test.dart
new file mode 100644
index 0000000..1905922
--- /dev/null
+++ b/pkg/analysis_server/test/lsp/hover_test.dart
@@ -0,0 +1,219 @@
+// Copyright (c) 2018, 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/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../tool/lsp_spec/matchers.dart';
+import 'server_abstract.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(HoverTest);
+ });
+}
+
+@reflectiveTest
+class HoverTest extends AbstractLspAnalysisServerTest {
+ Future<void> initializeSupportingMarkupContent([
+ List<MarkupKind> formats = const [MarkupKind.Markdown],
+ ]) async {
+ await initialize(textDocumentCapabilities: {
+ 'hover': {'contentFormat': formats.map((f) => f.toJson())}
+ });
+ }
+
+ test_hover_bad_position() async {
+ await initialize();
+ await openFile(mainFileUri, '');
+ await expectLater(
+ () => getHover(mainFileUri, new Position(999, 999)),
+ throwsA(isResponseError(ServerErrorCodes.InvalidFileLineCol)),
+ );
+ }
+
+ test_markdown_isFormattedForDisplay() async {
+ final content = '''
+ /// This is a string.
+ ///
+ /// {@template foo}
+ /// With some [refs] and some
+ /// [links](https://www.dartlang.org/)
+ /// {@endTemplate foo}
+ ///
+ /// ```dart sample
+ /// print();
+ /// ```
+ String [[a^bc]];
+ ''';
+
+ final expectedHoverContent = '''
+```dart
+String abc
+```
+
+This is a string.
+
+With some [refs] and some
+[links](https://www.dartlang.org/)
+
+```dart
+print();
+```
+ '''
+ .trim();
+
+ await initializeSupportingMarkupContent([MarkupKind.Markdown]);
+ await openFile(mainFileUri, withoutMarkers(content));
+ final hover = await getHover(mainFileUri, positionFromMarker(content));
+ expect(hover, isNotNull);
+ expect(hover.range, equals(rangeFromMarkers(content)));
+ expect(hover.contents, isNotNull);
+ final markup = _getMarkupContents(hover);
+ expect(markup.kind, equals(MarkupKind.Markdown));
+ expect(markup.value, equals(expectedHoverContent));
+ }
+
+ test_markdown_simple() async {
+ final content = '''
+ /// This is a string.
+ String [[a^bc]];
+ ''';
+
+ await initializeSupportingMarkupContent();
+ await openFile(mainFileUri, withoutMarkers(content));
+ final hover = await getHover(mainFileUri, positionFromMarker(content));
+ expect(hover, isNotNull);
+ expect(hover.range, equals(rangeFromMarkers(content)));
+ expect(hover.contents, isNotNull);
+ final markup = _getMarkupContents(hover);
+ expect(markup.kind, equals(MarkupKind.Markdown));
+ expect(markup.value, contains('This is a string.'));
+ }
+
+ test_noElement() async {
+ final content = '''
+ String abc;
+
+ ^
+
+ int a;
+ ''';
+
+ await initializeSupportingMarkupContent();
+ await openFile(mainFileUri, withoutMarkers(content));
+ var hover = await getHover(mainFileUri, positionFromMarker(content));
+ expect(hover, isNull);
+ }
+
+ test_plainText_simple() async {
+ final content = '''
+ /// This is a string.
+ String [[a^bc]];
+ ''';
+
+ await initializeSupportingMarkupContent([MarkupKind.PlainText]);
+ await openFile(mainFileUri, withoutMarkers(content));
+ final hover = await getHover(mainFileUri, positionFromMarker(content));
+ expect(hover, isNotNull);
+ expect(hover.range, equals(rangeFromMarkers(content)));
+ expect(hover.contents, isNotNull);
+ // Ensure we got PlainText back as the type, even though we're sending the
+ // same markdown content.
+ final markup = _getMarkupContents(hover);
+ expect(markup.kind, equals(MarkupKind.PlainText));
+ expect(markup.value, contains('This is a string.'));
+ }
+
+ test_string_noDocComment() async {
+ final content = '''
+ String [[a^bc]];
+ ''';
+
+ final expectedHoverContent = '''
+```dart
+String abc
+```
+ '''
+ .trim();
+
+ await initialize();
+ await openFile(mainFileUri, withoutMarkers(content));
+ final hover = await getHover(mainFileUri, positionFromMarker(content));
+ expect(hover, isNotNull);
+ expect(hover.range, equals(rangeFromMarkers(content)));
+ expect(hover.contents, isNotNull);
+ expect(_getStringContents(hover), equals(expectedHoverContent));
+ }
+
+ test_string_reflectsLatestEdits() async {
+ final original = '''
+ /// Original string.
+ String [[a^bc]];
+ ''';
+ final updated = '''
+ /// Updated string.
+ String [[a^bc]];
+ ''';
+
+ await initialize();
+ await openFile(mainFileUri, withoutMarkers(original));
+ var hover = await getHover(mainFileUri, positionFromMarker(original));
+ var contents = _getStringContents(hover);
+ expect(contents, contains('Original'));
+
+ await replaceFile(mainFileUri, withoutMarkers(updated));
+ hover = await getHover(mainFileUri, positionFromMarker(updated));
+ contents = _getStringContents(hover);
+ expect(contents, contains('Updated'));
+ }
+
+ test_string_simple() async {
+ final content = '''
+ /// This is a string.
+ String [[a^bc]];
+ ''';
+
+ await initialize();
+ await openFile(mainFileUri, withoutMarkers(content));
+ final hover = await getHover(mainFileUri, positionFromMarker(content));
+ expect(hover, isNotNull);
+ expect(hover.range, equals(rangeFromMarkers(content)));
+ expect(hover.contents, isNotNull);
+ final contents = _getStringContents(hover);
+ expect(contents, contains('This is a string.'));
+ }
+
+ test_unopenFile() async {
+ final content = '''
+ /// This is a string.
+ String [[a^bc]];
+ ''';
+
+ newFile(mainFilePath, content: withoutMarkers(content));
+ await initialize();
+ final hover = await getHover(mainFileUri, positionFromMarker(content));
+ expect(hover, isNotNull);
+ expect(hover.range, equals(rangeFromMarkers(content)));
+ expect(hover.contents, isNotNull);
+ final markup = _getStringContents(hover);
+ expect(markup, contains('This is a string.'));
+ }
+
+ MarkupContent _getMarkupContents(Hover hover) {
+ return hover.contents.map(
+ (t1) => throw 'Hover contents were String, not MarkupContent',
+ (t2) => t2,
+ );
+ }
+
+ String _getStringContents(Hover hover) {
+ return hover.contents.map(
+ (t1) => t1,
+ (t2) => throw 'Hover contents were MarkupContent, not String',
+ );
+ }
+}
diff --git a/pkg/analysis_server/test/lsp/initialization_test.dart b/pkg/analysis_server/test/lsp/initialization_test.dart
new file mode 100644
index 0000000..ed25a40
--- /dev/null
+++ b/pkg/analysis_server/test/lsp/initialization_test.dart
@@ -0,0 +1,81 @@
+// Copyright (c) 2018, 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/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'server_abstract.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(InitializationTest);
+ });
+}
+
+@reflectiveTest
+class InitializationTest extends AbstractLspAnalysisServerTest {
+ test_initialize() async {
+ final response = await initialize();
+ expect(response, isNotNull);
+ expect(response.error, isNull);
+ expect(response.result, isNotNull);
+ expect(response.result, TypeMatcher<InitializeResult>());
+ InitializeResult result = response.result;
+ expect(result.capabilities, isNotNull);
+ // Check some basic capabilities that are unlikely to change.
+ expect(result.capabilities.textDocumentSync, isNotNull);
+ result.capabilities.textDocumentSync.map(
+ (options) {
+ // We'll always request open/closed notifications and incremental updates.
+ expect(options.openClose, isTrue);
+ expect(options.change, equals(TextDocumentSyncKind.Incremental));
+ },
+ (_) =>
+ throw 'Expected textDocumentSync capabilities to be a $TextDocumentSyncOptions',
+ );
+ }
+
+ test_initialize_onlyAllowedOnce() async {
+ await initialize();
+ final response = await initialize();
+ expect(response, isNotNull);
+ expect(response.result, isNull);
+ expect(response.error, isNotNull);
+ expect(
+ response.error.code, equals(ServerErrorCodes.ServerAlreadyInitialized));
+ }
+
+ test_uninitialized_dropsNotifications() async {
+ final notification =
+ makeNotification(new Method.fromJson('randomNotification'), null);
+ final nextNotification = channel.errorNotificationsFromServer.first;
+ channel.sendNotificationToServer(notification);
+
+ // Wait up to 1sec to ensure no error/log notifications were sent back.
+ var didTimeout = false;
+ final notificationFromServer = await nextNotification.timeout(
+ const Duration(seconds: 1),
+ onTimeout: () {
+ didTimeout = true;
+ },
+ );
+
+ expect(notificationFromServer, isNull);
+ expect(didTimeout, isTrue);
+ }
+
+ test_uninitialized_rejectsRequests() async {
+ final request = makeRequest(new Method.fromJson('randomRequest'), null);
+ final logParams = await expectErrorNotification<LogMessageParams>(() async {
+ final response = await channel.sendRequestToServer(request);
+ expect(response.id, equals(request.id));
+ expect(response.result, isNull);
+ expect(response.error, isNotNull);
+ expect(response.error.code, ErrorCodes.ServerNotInitialized);
+ });
+ expect(logParams.type, equals(MessageType.Error));
+ }
+}
diff --git a/pkg/analysis_server/test/lsp/references_test.dart b/pkg/analysis_server/test/lsp/references_test.dart
new file mode 100644
index 0000000..bd36c11
--- /dev/null
+++ b/pkg/analysis_server/test/lsp/references_test.dart
@@ -0,0 +1,141 @@
+// Copyright (c) 2018, 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/lsp_protocol/protocol_generated.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'server_abstract.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ReferencesTest);
+ });
+}
+
+@reflectiveTest
+class ReferencesTest extends AbstractLspAnalysisServerTest {
+ test_acrossFiles_includeDeclaration() async {
+ final mainContents = '''
+ import 'referenced.dart';
+
+ main() {
+ [[foo]]();
+ }
+ ''';
+
+ final referencedContents = '''
+ /// Ensure the function is on a line that
+ /// does not exist in the mainContents file
+ /// to ensure we're translating offsets to line/col
+ /// using the correct file's LineInfo
+ /// ...
+ /// ...
+ /// ...
+ /// ...
+ /// ...
+ [[^foo]]() {}
+ ''';
+
+ final referencedFileUri =
+ Uri.file(join(projectFolderPath, 'lib', 'referenced.dart'));
+
+ await initialize();
+ await openFile(mainFileUri, withoutMarkers(mainContents));
+ await openFile(referencedFileUri, withoutMarkers(referencedContents));
+ final res = await getReferences(
+ referencedFileUri,
+ positionFromMarker(referencedContents),
+ includeDeclarations: true,
+ );
+
+ // Ensure both the reference and the declaration are included.
+ expect(res, hasLength(2));
+ expect(
+ res,
+ contains(new Location(
+ mainFileUri.toString(), rangeFromMarkers(mainContents))));
+ expect(
+ res,
+ contains(new Location(referencedFileUri.toString(),
+ rangeFromMarkers(referencedContents))));
+ }
+
+ test_acrossFiles_withoutDeclaration() async {
+ final mainContents = '''
+ import 'referenced.dart';
+
+ main() {
+ [[foo]]();
+ }
+ ''';
+
+ final referencedContents = '''
+ /// Ensure the function is on a line that
+ /// does not exist in the mainContents file
+ /// to ensure we're translating offsets to line/col
+ /// using the correct file's LineInfo
+ /// ...
+ /// ...
+ /// ...
+ /// ...
+ /// ...
+ ^foo() {}
+ ''';
+
+ final referencedFileUri =
+ Uri.file(join(projectFolderPath, 'lib', 'referenced.dart'));
+
+ await initialize();
+ await openFile(mainFileUri, withoutMarkers(mainContents));
+ await openFile(referencedFileUri, withoutMarkers(referencedContents));
+ final res = await getReferences(
+ referencedFileUri, positionFromMarker(referencedContents));
+
+ expect(res, hasLength(1));
+ Location loc = res.single;
+ expect(loc.range, equals(rangeFromMarkers(mainContents)));
+ expect(loc.uri, equals(mainFileUri.toString()));
+ }
+
+ test_singleFile_withoutDeclaration() async {
+ final contents = '''
+ f^oo() {
+ [[foo]]();
+ }
+ ''';
+
+ await initialize();
+ await openFile(mainFileUri, withoutMarkers(contents));
+ final res = await getReferences(mainFileUri, positionFromMarker(contents));
+
+ expect(res, hasLength(1));
+ expect(
+ res,
+ contains(
+ new Location(mainFileUri.toString(), rangeFromMarkers(contents)),
+ ),
+ );
+ }
+
+ test_unopenFile() async {
+ final contents = '''
+ f^oo() {
+ [[foo]]();
+ }
+ ''';
+
+ newFile(mainFilePath, content: withoutMarkers(contents));
+ await initialize();
+ final res = await getReferences(mainFileUri, positionFromMarker(contents));
+
+ expect(res, hasLength(1));
+ expect(
+ res,
+ contains(
+ new Location(mainFileUri.toString(), rangeFromMarkers(contents)),
+ ),
+ );
+ }
+}
diff --git a/pkg/analysis_server/test/lsp/server_abstract.dart b/pkg/analysis_server/test/lsp/server_abstract.dart
new file mode 100644
index 0000000..368b330
--- /dev/null
+++ b/pkg/analysis_server/test/lsp/server_abstract.dart
@@ -0,0 +1,377 @@
+// Copyright (c) 2018, 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/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/analysis_server.dart';
+import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
+import 'package:analysis_server/src/lsp/mapping.dart';
+import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/source/line_info.dart';
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:test/test.dart';
+
+import '../mocks.dart';
+
+const dartLanguageId = 'dart';
+
+/// Useful for debugging locally, setting this to true will cause all JSON
+/// communication to be printed to stdout.
+const debugPrintCommunication = false;
+
+abstract class AbstractLspAnalysisServerTest with ResourceProviderMixin {
+ static const positionMarker = '^';
+ static const rangeMarkerStart = '[[';
+ static const rangeMarkerEnd = ']]';
+ static const allMarkers = [positionMarker, rangeMarkerStart, rangeMarkerEnd];
+ static final allMarkersPattern =
+ new RegExp(allMarkers.map(RegExp.escape).join('|'));
+ MockLspServerChannel channel;
+ LspAnalysisServer server;
+
+ int _id = 0;
+ String projectFolderPath, mainFilePath;
+ Uri mainFileUri;
+
+ final emptyTextDocumentClientCapabilities =
+ new TextDocumentClientCapabilities(
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null,
+ null);
+
+ String applyEdits(String oldContent, List<TextEdit> changes) {
+ String newContent = oldContent;
+ // Complex text manipulations are described with an array of TextEdit's,
+ // representing a single change to the document.
+ //
+ // All text edits ranges refer to positions in the original document. Text
+ // edits ranges must never overlap, that means no part of the original
+ // document must be manipulated by more than one edit. However, it is possible
+ // that multiple edits have the same start position: multiple inserts, or any
+ // number of inserts followed by a single remove or replace edit. If multiple
+ // inserts have the same position, the order in the array defines the order in
+ // which the inserted strings appear in the resulting text.
+ if (changes.length > 1) {
+ // TODO(dantup): Implement multi-edit edits.
+ throw 'Test helper applyEdits does not support applying multiple edits';
+ } else if (changes.length == 1) {
+ final change = changes.single;
+ final startPos = change.range.start;
+ final endPos = change.range.end;
+ final lineInfo = LineInfo.fromContent(newContent);
+ final start =
+ lineInfo.getOffsetOfLine(startPos.line) + startPos.character;
+ final end = lineInfo.getOffsetOfLine(endPos.line) + endPos.character;
+ newContent = newContent.replaceRange(start, end, change.newText);
+ }
+
+ return newContent;
+ }
+
+ Future changeFile(
+ Uri uri, List<TextDocumentContentChangeEvent> changes) async {
+ var notification = makeNotification(
+ Method.textDocument_didChange,
+ new DidChangeTextDocumentParams(
+ new VersionedTextDocumentIdentifier(1, uri.toString()), changes),
+ );
+ channel.sendNotificationToServer(notification);
+ await pumpEventQueue();
+ }
+
+ Future closeFile(Uri uri) async {
+ var notification = makeNotification(
+ Method.textDocument_didClose,
+ new DidCloseTextDocumentParams(
+ new TextDocumentIdentifier(uri.toString())),
+ );
+ channel.sendNotificationToServer(notification);
+ await pumpEventQueue();
+ }
+
+ Future<T> expectErrorNotification<T>(
+ FutureOr<void> f(), {
+ Duration timeout = const Duration(seconds: 5),
+ }) async {
+ final firstError = channel.errorNotificationsFromServer.first;
+ await f();
+
+ final notificationFromServer = await firstError.timeout(timeout);
+
+ expect(notificationFromServer, isNotNull);
+ return notificationFromServer.params as T;
+ }
+
+ /// Sends a request to the server and unwraps the result. Throws if the
+ /// response was not successful or returned an error.
+ Future<T> expectSuccessfulResponseTo<T>(RequestMessage request) async {
+ final resp = await channel.sendRequestToServer(request);
+ if (resp.error != null) {
+ throw resp.error;
+ } else {
+ return resp.result as T;
+ }
+ }
+
+ Future<List<TextEdit>> formatDocument(String fileUri) async {
+ final request = makeRequest(
+ Method.textDocument_formatting,
+ new DocumentFormattingParams(
+ new TextDocumentIdentifier(fileUri),
+ new FormattingOptions(2, true), // These currently don't do anything
+ ),
+ );
+ return expectSuccessfulResponseTo(request);
+ }
+
+ Future<List<TextEdit>> formatOnType(
+ String fileUri, Position pos, String character) async {
+ final request = makeRequest(
+ Method.textDocument_onTypeFormatting,
+ new DocumentOnTypeFormattingParams(
+ new TextDocumentIdentifier(fileUri),
+ pos,
+ character,
+ new FormattingOptions(2, true), // These currently don't do anything
+ ),
+ );
+ return expectSuccessfulResponseTo(request);
+ }
+
+ Future<List<CompletionItem>> getCompletion(Uri uri, Position pos,
+ {CompletionContext context}) async {
+ final request = makeRequest(
+ Method.textDocument_completion,
+ new CompletionParams(
+ context,
+ new TextDocumentIdentifier(uri.toString()),
+ pos,
+ ),
+ );
+ return expectSuccessfulResponseTo<List<CompletionItem>>(request);
+ }
+
+ Future<List<Location>> getDefinition(Uri uri, Position pos) async {
+ final request = makeRequest(
+ Method.textDocument_definition,
+ new TextDocumentPositionParams(
+ new TextDocumentIdentifier(uri.toString()),
+ pos,
+ ),
+ );
+ return expectSuccessfulResponseTo<List<Location>>(request);
+ }
+
+ Future<Either2<List<DocumentSymbol>, List<SymbolInformation>>>
+ getDocumentSymbols(String fileUri) async {
+ final request = makeRequest(
+ Method.textDocument_documentSymbol,
+ new DocumentSymbolParams(
+ new TextDocumentIdentifier(fileUri),
+ ),
+ );
+ return expectSuccessfulResponseTo(request);
+ }
+
+ Future<Hover> getHover(Uri uri, Position pos) async {
+ final request = makeRequest(
+ Method.textDocument_hover,
+ new TextDocumentPositionParams(
+ new TextDocumentIdentifier(uri.toString()), pos),
+ );
+ return expectSuccessfulResponseTo<Hover>(request);
+ }
+
+ Future<List<Location>> getReferences(
+ Uri uri,
+ Position pos, {
+ includeDeclarations = false,
+ }) async {
+ final request = makeRequest(
+ Method.textDocument_references,
+ new ReferenceParams(
+ new ReferenceContext(includeDeclarations),
+ new TextDocumentIdentifier(uri.toString()),
+ pos,
+ ),
+ );
+ return expectSuccessfulResponseTo<List<Location>>(request);
+ }
+
+ Future<SignatureHelp> getSignatureHelp(Uri uri, Position pos) async {
+ final request = makeRequest(
+ Method.textDocument_signatureHelp,
+ new TextDocumentPositionParams(
+ new TextDocumentIdentifier(uri.toString()),
+ pos,
+ ),
+ );
+ return expectSuccessfulResponseTo<SignatureHelp>(request);
+ }
+
+ /// A helper that initializes the server with common values, since the server
+ /// will reject any other requests until it is initialized.
+ /// Capabilities are overridden by providing JSON to avoid having to construct
+ /// full objects just to change one value (the types are immutable) so must
+ /// match the spec exactly and are not verified.
+ Future<ResponseMessage> initialize({
+ String rootPath,
+ Map<String, dynamic> textDocumentCapabilities,
+ }) async {
+ final rootUri = Uri.file(rootPath ?? projectFolderPath).toString();
+ final newTextDocumentCapabilities =
+ overrideTextDocumentCapabilities(textDocumentCapabilities);
+ final request = makeRequest(
+ Method.initialize,
+ new InitializeParams(
+ null,
+ null,
+ rootUri,
+ null,
+ new ClientCapabilities(null, newTextDocumentCapabilities, null),
+ null,
+ null));
+ final response = await channel.sendRequestToServer(request);
+ expect(response.id, equals(request.id));
+
+ if (response.error == null) {
+ final notification = makeNotification(Method.initialized, null);
+ channel.sendNotificationToServer(notification);
+ }
+
+ return response;
+ }
+
+ NotificationMessage makeNotification(Method method, ToJsonable params) {
+ return new NotificationMessage(method, params, jsonRpcVersion);
+ }
+
+ RequestMessage makeRequest(Method method, ToJsonable params) {
+ final id = Either2<num, String>.t1(_id++);
+ return new RequestMessage(id, method, params, jsonRpcVersion);
+ }
+
+ Future openFile(Uri uri, String content) async {
+ var notification = makeNotification(
+ Method.textDocument_didOpen,
+ new DidOpenTextDocumentParams(
+ new TextDocumentItem(uri.toString(), dartLanguageId, 1, content)),
+ );
+ channel.sendNotificationToServer(notification);
+ await pumpEventQueue();
+ }
+
+ TextDocumentClientCapabilities overrideTextDocumentCapabilities(
+ Map<String, dynamic> textDocumentCapabilities) {
+ final json = emptyTextDocumentClientCapabilities.toJson();
+ if (textDocumentCapabilities != null) {
+ textDocumentCapabilities.keys.forEach((key) {
+ json[key] = textDocumentCapabilities[key];
+ });
+ }
+ final newTextDocumentCapabilities =
+ TextDocumentClientCapabilities.fromJson(json);
+ return newTextDocumentCapabilities;
+ }
+
+ Position positionFromMarker(String contents) =>
+ positionFromOffset(contents.indexOf('^'), contents);
+
+ Position positionFromOffset(int offset, String contents) {
+ final lineInfo = LineInfo.fromContent(contents);
+ return toPosition(lineInfo.getLocation(offset));
+ }
+
+ /// Returns the range surrounded by `[[markers]]` in the provided string,
+ /// excluding the markers themselves (as well as position markers `^` from
+ /// the offsets).
+ Range rangeFromMarkers(String contents) {
+ contents = contents.replaceAll(positionMarker, '');
+ final start = contents.indexOf(rangeMarkerStart);
+ if (start == -1) {
+ throw 'Contents did not contain $rangeMarkerStart';
+ }
+ final end = contents.indexOf(rangeMarkerEnd);
+ if (end == -1) {
+ throw 'Contents did not contain $rangeMarkerEnd';
+ }
+ return new Range(
+ positionFromOffset(start, contents),
+ positionFromOffset(end - rangeMarkerStart.length, contents),
+ );
+ }
+
+ Future replaceFile(Uri uri, String content) async {
+ await changeFile(
+ uri,
+ [new TextDocumentContentChangeEvent(null, null, content)],
+ );
+ }
+
+ void setUp() {
+ channel = new MockLspServerChannel(debugPrintCommunication);
+ // Create an SDK in the mock file system.
+ new MockSdk(resourceProvider: resourceProvider);
+ server = new LspAnalysisServer(
+ channel,
+ resourceProvider,
+ new AnalysisServerOptions(),
+ new DartSdkManager(convertPath('/sdk'), false),
+ InstrumentationService.NULL_SERVICE);
+
+ projectFolderPath = convertPath('/project');
+ newFolder(projectFolderPath);
+ newFolder(join(projectFolderPath, 'lib'));
+ // Create a folder and file to aid testing that includes imports/completion.
+ newFolder(join(projectFolderPath, 'lib', 'folder'));
+ newFile(join(projectFolderPath, 'lib', 'file.dart'));
+ mainFilePath = join(projectFolderPath, 'lib', 'main.dart');
+ mainFileUri = Uri.file(mainFilePath);
+ }
+
+ Future tearDown() async {
+ channel.close();
+ await server.shutdown();
+ }
+
+ Future<List<Diagnostic>> waitForDiagnostics(Uri uri) async {
+ PublishDiagnosticsParams diagnosticParams;
+ await channel.serverToClient.firstWhere((message) {
+ if (message is NotificationMessage &&
+ message.method == Method.textDocument_publishDiagnostics) {
+ diagnosticParams = message.params;
+
+ return diagnosticParams.uri == uri.toString();
+ }
+ return false;
+ });
+ return diagnosticParams.diagnostics;
+ }
+
+ /// Removes markers like `[[` and `]]` and `^` that are used for marking
+ /// positions/ranges in strings to avoid hard-coding positions in tests.
+ String withoutMarkers(String contents) =>
+ contents.replaceAll(allMarkersPattern, '');
+}
diff --git a/pkg/analysis_server/test/lsp/server_test.dart b/pkg/analysis_server/test/lsp/server_test.dart
new file mode 100644
index 0000000..9054552
--- /dev/null
+++ b/pkg/analysis_server/test/lsp/server_test.dart
@@ -0,0 +1,73 @@
+// Copyright (c) 2018, 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/lsp_protocol/protocol_generated.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'server_abstract.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ServerTest);
+ });
+}
+
+@reflectiveTest
+class ServerTest extends AbstractLspAnalysisServerTest {
+ test_shutdown_initialized() async {
+ await initialize();
+ final request = makeRequest(Method.shutdown, null);
+ final response = await channel.sendRequestToServer(request);
+ expect(response.id, equals(request.id));
+ expect(response.error, isNull);
+ expect(response.result, isNull);
+ }
+
+ test_shutdown_uninitialized() async {
+ final request = makeRequest(Method.shutdown, null);
+ final response = await channel.sendRequestToServer(request);
+ expect(response.id, equals(request.id));
+ expect(response.error, isNull);
+ expect(response.result, isNull);
+ }
+
+ test_unknownNotifications_silentlyDropped() async {
+ await initialize();
+ final notification =
+ makeNotification(new Method.fromJson(r'$/randomNotification'), null);
+ final firstError = channel.errorNotificationsFromServer.first;
+ channel.sendNotificationToServer(notification);
+
+ // Wait up to 1sec to ensure no error/log notifications were sent back.
+ var didTimeout = false;
+ final notificationFromServer = await firstError.timeout(
+ const Duration(seconds: 1),
+ onTimeout: () {
+ didTimeout = true;
+ },
+ );
+
+ expect(notificationFromServer, isNull);
+ expect(didTimeout, isTrue);
+ }
+
+ test_unknownRequest_rejected() async {
+ await initialize();
+ final request = makeRequest(new Method.fromJson('randomRequest'), null);
+ final response = await channel.sendRequestToServer(request);
+ expect(response.id, equals(request.id));
+ expect(response.error, isNotNull);
+ expect(response.error.code, equals(ErrorCodes.MethodNotFound));
+ expect(response.result, isNull);
+ }
+
+ @failingTest
+ test_unknownRequest_silentlyDropped /*??*/ () async {
+ // TODO(dantup): Fix this test up when we know how we're supposed to handle
+ // unknown $/ requests.
+ // https://github.com/Microsoft/language-server-protocol/issues/607
+ fail('TODO(dantup)');
+ }
+}
diff --git a/pkg/analysis_server/test/lsp/signature_help_test.dart b/pkg/analysis_server/test/lsp/signature_help_test.dart
new file mode 100644
index 0000000..b72233d
--- /dev/null
+++ b/pkg/analysis_server/test/lsp/signature_help_test.dart
@@ -0,0 +1,304 @@
+// Copyright (c) 2018, 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/lsp_protocol/protocol_generated.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'server_abstract.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(SignatureHelpTest);
+ });
+}
+
+@reflectiveTest
+class SignatureHelpTest extends AbstractLspAnalysisServerTest {
+ Future<void> initializeSupportingMarkupContent([
+ List<MarkupKind> formats = const [MarkupKind.Markdown],
+ ]) async {
+ await initialize(textDocumentCapabilities: {
+ 'signatureHelp': {
+ 'signatureInformation': {
+ 'documentationFormat': formats.map((f) => f.toJson())
+ }
+ }
+ });
+ }
+
+ test_formats_markdown() async {
+ final content = '''
+ /// Does foo.
+ foo(String s, int i) {
+ foo(^);
+ }
+ ''';
+ final expectedLabel = 'foo(String s, int i)';
+ final expectedDoc = 'Does foo.';
+
+ await initializeSupportingMarkupContent([MarkupKind.Markdown]);
+ await openFile(mainFileUri, withoutMarkers(content));
+ await testSignature(
+ content,
+ expectedLabel,
+ expectedDoc,
+ [
+ new ParameterInformation('String s', null),
+ new ParameterInformation('int i', null),
+ ],
+ expectedFormat: MarkupKind.Markdown,
+ );
+ }
+
+ test_formats_notSupported() async {
+ final content = '''
+ /// Does foo.
+ foo(String s, int i) {
+ foo(^);
+ }
+ ''';
+ final expectedLabel = 'foo(String s, int i)';
+ final expectedDoc = 'Does foo.';
+
+ await initialize();
+ await openFile(mainFileUri, withoutMarkers(content));
+ await testSignature(
+ content,
+ expectedLabel,
+ expectedDoc,
+ [
+ new ParameterInformation('String s', null),
+ new ParameterInformation('int i', null),
+ ],
+ expectedFormat: null,
+ );
+ }
+
+ test_formats_plainTextOnly() async {
+ final content = '''
+ /// Does foo.
+ foo(String s, int i) {
+ foo(^);
+ }
+ ''';
+ final expectedLabel = 'foo(String s, int i)';
+ final expectedDoc = 'Does foo.';
+
+ await initializeSupportingMarkupContent([MarkupKind.PlainText]);
+ await openFile(mainFileUri, withoutMarkers(content));
+ await testSignature(
+ content,
+ expectedLabel,
+ expectedDoc,
+ [
+ new ParameterInformation('String s', null),
+ new ParameterInformation('int i', null),
+ ],
+ expectedFormat: MarkupKind.PlainText,
+ );
+ }
+
+ test_formats_plainTextPreferred() async {
+ final content = '''
+ /// Does foo.
+ foo(String s, int i) {
+ foo(^);
+ }
+ ''';
+ final expectedLabel = 'foo(String s, int i)';
+ final expectedDoc = 'Does foo.';
+
+ // We say we prefer PlainText as a client, but since we only really
+ // support Markdown and the client supports it, we expect the server
+ // to provide Markdown.
+ await initializeSupportingMarkupContent(
+ [MarkupKind.PlainText, MarkupKind.Markdown]);
+ await openFile(mainFileUri, withoutMarkers(content));
+ await testSignature(
+ content,
+ expectedLabel,
+ expectedDoc,
+ [
+ new ParameterInformation('String s', null),
+ new ParameterInformation('int i', null),
+ ],
+ expectedFormat: MarkupKind.Markdown,
+ );
+ }
+
+ test_params_multipleNamed() async {
+ final content = '''
+ /// Does foo.
+ foo(String s, {bool b = true, bool a}) {
+ foo(^);
+ }
+ ''';
+
+ final expectedLabel = 'foo(String s, {bool b = true, bool a})';
+ final expectedDoc = 'Does foo.';
+
+ await initializeSupportingMarkupContent();
+ await openFile(mainFileUri, withoutMarkers(content));
+ await testSignature(
+ content,
+ expectedLabel,
+ expectedDoc,
+ [
+ new ParameterInformation('String s', null),
+ new ParameterInformation('bool b = true', null),
+ new ParameterInformation('bool a', null),
+ ],
+ );
+ }
+
+ test_params_multipleOptional() async {
+ final content = '''
+ /// Does foo.
+ foo(String s, [bool b = true, bool a]) {
+ foo(^);
+ }
+ ''';
+
+ final expectedLabel = 'foo(String s, [bool b = true, bool a])';
+ final expectedDoc = 'Does foo.';
+
+ await initializeSupportingMarkupContent();
+ await openFile(mainFileUri, withoutMarkers(content));
+ await testSignature(
+ content,
+ expectedLabel,
+ expectedDoc,
+ [
+ new ParameterInformation('String s', null),
+ new ParameterInformation('bool b = true', null),
+ new ParameterInformation('bool a', null),
+ ],
+ );
+ }
+
+ test_params_named() async {
+ final content = '''
+ /// Does foo.
+ foo(String s, {bool b = true}) {
+ foo(^);
+ }
+ ''';
+
+ final expectedLabel = 'foo(String s, {bool b = true})';
+ final expectedDoc = 'Does foo.';
+
+ await initializeSupportingMarkupContent();
+ await openFile(mainFileUri, withoutMarkers(content));
+ await testSignature(
+ content,
+ expectedLabel,
+ expectedDoc,
+ [
+ new ParameterInformation('String s', null),
+ new ParameterInformation('bool b = true', null),
+ ],
+ );
+ }
+
+ test_params_optional() async {
+ final content = '''
+ /// Does foo.
+ foo(String s, [bool b = true]) {
+ foo(^);
+ }
+ ''';
+
+ final expectedLabel = 'foo(String s, [bool b = true])';
+ final expectedDoc = 'Does foo.';
+
+ await initializeSupportingMarkupContent();
+ await openFile(mainFileUri, withoutMarkers(content));
+ await testSignature(
+ content,
+ expectedLabel,
+ expectedDoc,
+ [
+ new ParameterInformation('String s', null),
+ new ParameterInformation('bool b = true', null),
+ ],
+ );
+ }
+
+ test_simple() async {
+ final content = '''
+ /// Does foo.
+ foo(String s, int i) {
+ foo(^);
+ }
+ ''';
+ final expectedLabel = 'foo(String s, int i)';
+ final expectedDoc = 'Does foo.';
+
+ await initializeSupportingMarkupContent();
+ await openFile(mainFileUri, withoutMarkers(content));
+ await testSignature(
+ content,
+ expectedLabel,
+ expectedDoc,
+ [
+ new ParameterInformation('String s', null),
+ new ParameterInformation('int i', null),
+ ],
+ );
+ }
+
+ test_unopenFile() async {
+ final content = '''
+ /// Does foo.
+ foo(String s, int i) {
+ foo(^);
+ }
+ ''';
+ final expectedLabel = 'foo(String s, int i)';
+ final expectedDoc = 'Does foo.';
+
+ newFile(mainFilePath, content: withoutMarkers(content));
+ await initializeSupportingMarkupContent();
+ await testSignature(
+ content,
+ expectedLabel,
+ expectedDoc,
+ [
+ new ParameterInformation('String s', null),
+ new ParameterInformation('int i', null),
+ ],
+ );
+ }
+
+ Future<void> testSignature(
+ String fileContent,
+ String expectedLabel,
+ String expectedDoc,
+ List<ParameterInformation> expectedParams, {
+ MarkupKind expectedFormat = MarkupKind.Markdown,
+ }) async {
+ final res =
+ await getSignatureHelp(mainFileUri, positionFromMarker(fileContent));
+
+ expect(res.activeParameter, isNull);
+ expect(res.activeSignature, equals(0));
+ expect(res.signatures, hasLength(1));
+ final sig = res.signatures.first;
+ expect(sig.label, equals(expectedLabel));
+ expect(sig.parameters, equals(expectedParams));
+
+ // Test the format matches the tests expectation.
+ // For clients that don't support MarkupContent it'll be a plain string,
+ // but otherwise it'll be a MarkupContent of type PlainText or Markdown.
+ final doc = sig.documentation;
+ if (expectedFormat == null) {
+ // Plain string.
+ expect(doc.valueEquals(expectedDoc), isTrue);
+ } else {
+ final expected = new MarkupContent(expectedFormat, expectedDoc);
+ expect(doc.valueEquals(expected), isTrue);
+ }
+ }
+}
diff --git a/pkg/analysis_server/test/lsp/test_all.dart b/pkg/analysis_server/test/lsp/test_all.dart
new file mode 100644
index 0000000..c889439
--- /dev/null
+++ b/pkg/analysis_server/test/lsp/test_all.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2018, 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:test_reflective_loader/test_reflective_loader.dart';
+
+import 'completion_test.dart' as completion_test;
+import 'definition_test.dart' as definition_test;
+import 'diagnostic_test.dart' as diagnostic_test;
+import 'document_symbols_test.dart' as document_symbols_test;
+import 'file_modification_test.dart' as file_modification_test;
+import 'format_test.dart' as format_test;
+import 'hover_test.dart' as hover_test;
+import 'initialization_test.dart' as initialization_test;
+import 'references_test.dart' as references_test;
+import 'server_test.dart' as server_test;
+import 'signature_help_test.dart' as signature_help_test;
+
+main() {
+ defineReflectiveSuite(() {
+ completion_test.main();
+ definition_test.main();
+ diagnostic_test.main();
+ document_symbols_test.main();
+ file_modification_test.main();
+ format_test.main();
+ hover_test.main();
+ initialization_test.main();
+ references_test.main();
+ server_test.main();
+ signature_help_test.main();
+ }, name: 'lsp');
+}
diff --git a/pkg/analysis_server/test/mock_sdk.dart b/pkg/analysis_server/test/mock_sdk.dart
deleted file mode 100644
index 07f8f15..0000000
--- a/pkg/analysis_server/test/mock_sdk.dart
+++ /dev/null
@@ -1,452 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/file_system/file_system.dart' as resource;
-import 'package:analyzer/file_system/memory_file_system.dart' as resource;
-import 'package:analyzer/src/context/context.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/summary/idl.dart' show PackageBundle;
-import 'package:analyzer/src/summary/summary_file_builder.dart';
-
-class MockSdk implements DartSdk {
- static const MockSdkLibrary LIB_CORE =
- const MockSdkLibrary('dart:core', '/lib/core/core.dart', '''
-library dart.core;
-
-import 'dart:async';
-import 'dart:_internal';
-
-class Object {
- const Object();
- bool operator ==(other) => identical(this, other);
- String toString() => 'a string';
- int get hashCode => 0;
- Type get runtimeType => null;
- dynamic noSuchMethod(Invocation invocation) => null;
-}
-
-class Function {}
-class StackTrace {}
-class Symbol {}
-class Type {}
-
-abstract class Comparable<T> {
- int compareTo(T other);
-}
-
-abstract class String implements Comparable<String> {
- external factory String.fromCharCodes(Iterable<int> charCodes,
- [int start = 0, int end]);
- bool get isEmpty => false;
- bool get isNotEmpty => false;
- int get length => 0;
- String toUpperCase();
- List<int> get codeUnits;
-}
-
-class bool extends Object {}
-
-abstract class num implements Comparable<num> {
- bool operator <(num other);
- bool operator <=(num other);
- bool operator >(num other);
- bool operator >=(num other);
- num operator +(num other);
- num operator -(num other);
- num operator *(num other);
- num operator /(num other);
- int operator ^(int other);
- int operator &(int other);
- int operator |(int other);
- int operator <<(int other);
- int operator >>(int other);
- int operator ~/(num other);
- num operator %(num other);
- int operator ~();
- int toInt();
- double toDouble();
- num abs();
- int round();
-}
-
-abstract class int extends num {
- bool get isEven => false;
- int operator -();
- external static int parse(String source,
- { int radix,
- int onError(String source) });
-}
-
-abstract class double extends num {
- static const double NAN = 0.0 / 0.0;
- static const double INFINITY = 1.0 / 0.0;
- static const double NEGATIVE_INFINITY = -INFINITY;
- static const double MIN_POSITIVE = 5e-324;
- static const double MAX_FINITE = 1.7976931348623157e+308;
-
- double remainder(num other);
- double operator +(num other);
- double operator -(num other);
- double operator *(num other);
- double operator %(num other);
- double operator /(num other);
- int operator ~/(num other);
- double operator -();
- double abs();
- double get sign;
- int round();
- int floor();
- int ceil();
- int truncate();
- double roundToDouble();
- double floorToDouble();
- double ceilToDouble();
- double truncateToDouble();
- external static double parse(String source,
- [double onError(String source)]);
-}
-
-class DateTime extends Object {}
-class Null extends Object {}
-
-class Deprecated extends Object {
- final String expires;
- const Deprecated(this.expires);
-}
-const Object deprecated = const Deprecated("next release");
-
-class Exception {
- factory Exception([var message]);
-}
-
-class Iterator<E> {
- bool moveNext();
- E get current;
-}
-
-abstract class Iterable<E> {
- Iterator<E> get iterator;
- bool get isEmpty;
- void forEach(void f(E element));
- Iterable<T> map<T>(T f(E e)) => null;
- T fold<T>(T initialValue, T combine(T previousValue, E element));
- List<E> toList({bool growable: true});
-}
-
-class List<E> implements Iterable<E> {
- List();
- void add(E value) {}
- void addAll(Iterable<E> iterable) {}
- List<R> cast<R>();
- E operator [](int index) => null;
- void operator []=(int index, E value) {}
- Iterator<E> get iterator => null;
- void clear() {}
- Iterable<E> where(bool test(E element)) {}
-
- bool get isEmpty => false;
- E get first => null;
- E get last => null;
-}
-
-abstract class Map<K, V> extends Object {
- Iterable<K> get keys;
- int get length;
- Iterable<V> get values;
- V operator [](K key) => null;
- void operator []=(K key, V value) {}
- Map<RK, RV> cast<RK, RV>();
- bool containsKey(Object key);
-}
-
-external bool identical(Object a, Object b);
-
-void print(Object object) {}
-
-class Set<E> implements Iterable<E> {
- Set<R> cast<R>();
-}
-
-class Uri {
- static List<int> parseIPv6Address(String host, [int start = 0, int end]) {
- int parseHex(int start, int end) {
- return 0;
- }
- return null;
- }
-}
-
-class _Override { const _Override(); }
-const Object override = const _Override();
-''');
- static const MockSdkLibrary LIB_ASYNC =
- const MockSdkLibrary('dart:async', '/lib/async/async.dart', '''
-library dart.async;
-
-import 'dart:math';
-
-class Future<T> {
- factory Future(computation()) => null;
- factory Future.delayed(Duration duration, [T computation()]) => null;
- factory Future.value([value]) => null;
- static Future wait(List<Future> futures) => null;
-}
-
-class FutureOr<T> {}
-
-class Stream<T> {}
-abstract class StreamTransformer<S, T> {}
-''');
-
- static const MockSdkLibrary LIB_COLLECTION = const MockSdkLibrary(
- 'dart:collection', '/lib/collection/collection.dart', '''
-library dart.collection;
-
-abstract class HashMap<K, V> implements Map<K, V> {}
-abstract class LinkedHashMap<K, V> implements Map<K, V> {}
-''');
-
- static const MockSdkLibrary LIB_CONVERT =
- const MockSdkLibrary('dart:convert', '/lib/convert/convert.dart', '''
-library dart.convert;
-
-import 'dart:async';
-
-abstract class Converter<S, T> implements StreamTransformer {}
-class JsonDecoder extends Converter<String, Object> {}
-''');
-
- static const MockSdkLibrary LIB_MATH =
- const MockSdkLibrary('dart:math', '/lib/math/math.dart', '''
-library dart.math;
-const double E = 2.718281828459045;
-const double PI = 3.1415926535897932;
-const double LN10 = 2.302585092994046;
-T min<T extends num>(T a, T b) => null;
-T max<T extends num>(T a, T b) => null;
-external double cos(num radians);
-external num pow(num x, num exponent);
-external double sin(num radians);
-external double sqrt(num x);
-class Random {
- bool nextBool() => true;
- double nextDouble() => 2.0;
- int nextInt() => 1;
-}
-''');
-
- static const MockSdkLibrary LIB_HTML = const MockSdkLibrary(
- 'dart:html', '/lib/html/dartium/html_dartium.dart', '''
-library dart.html;
-class HtmlElement {}
-''');
-
- static const MockSdkLibrary LIB_INTERNAL =
- const MockSdkLibrary('dart:_internal', '/lib/internal/internal.dart', '''
-library dart._internal;
-external void printToConsole(String line);
-''');
-
- static const List<SdkLibrary> LIBRARIES = const [
- LIB_CORE,
- LIB_ASYNC,
- LIB_COLLECTION,
- LIB_CONVERT,
- LIB_MATH,
- LIB_HTML,
- LIB_INTERNAL,
- ];
-
- static const String librariesContent = r'''
-const Map<String, LibraryInfo> libraries = const {
- "async": const LibraryInfo("async/async.dart"),
- "collection": const LibraryInfo("collection/collection.dart"),
- "convert": const LibraryInfo("convert/convert.dart"),
- "core": const LibraryInfo("core/core.dart"),
- "html": const LibraryInfo("html/dartium/html_dartium.dart"),
- "math": const LibraryInfo("math/math.dart"),
- "_internal": const LibraryInfo("internal/internal.dart"),
-};
-''';
-
- final resource.MemoryResourceProvider provider;
-
- /**
- * The [AnalysisContext] which is used for all of the sources.
- */
- InternalAnalysisContext _analysisContext;
-
- /**
- * The cached linked bundle of the SDK.
- */
- PackageBundle _bundle;
-
- MockSdk(
- {bool generateSummaryFiles: false,
- resource.ResourceProvider resourceProvider})
- : provider = resourceProvider ?? new resource.MemoryResourceProvider() {
- LIBRARIES.forEach((SdkLibrary library) {
- provider.newFile(provider.convertPath(library.path),
- (library as MockSdkLibrary).content);
- });
- provider.newFile(
- provider.convertPath(
- '/lib/_internal/sdk_library_metadata/lib/libraries.dart'),
- librariesContent);
- if (generateSummaryFiles) {
- List<int> bytes = _computeLinkedBundleBytes();
- provider.newFileWithBytes(
- provider.convertPath('/lib/_internal/strong.sum'), bytes);
- }
- }
-
- @override
- AnalysisContext get context {
- if (_analysisContext == null) {
- _analysisContext = new SdkAnalysisContext(null);
- SourceFactory factory = new SourceFactory([new DartUriResolver(this)]);
- _analysisContext.sourceFactory = factory;
- }
- return _analysisContext;
- }
-
- @override
- List<SdkLibrary> get sdkLibraries => LIBRARIES;
-
- @override
- String get sdkVersion => throw unimplemented;
-
- UnimplementedError get unimplemented => new UnimplementedError();
-
- @override
- List<String> get uris {
- List<String> uris = <String>[];
- for (SdkLibrary library in LIBRARIES) {
- uris.add(library.shortName);
- }
- return uris;
- }
-
- @override
- Source fromFileUri(Uri uri) {
- String filePath = provider.pathContext.fromUri(uri);
- for (SdkLibrary library in sdkLibraries) {
- String libraryPath = provider.convertPath(library.path);
- if (filePath == libraryPath) {
- try {
- resource.File file = provider.getResource(filePath);
- Uri dartUri = Uri.parse(library.shortName);
- return file.createSource(dartUri);
- } catch (exception) {
- return null;
- }
- }
- String libraryRootPath = provider.pathContext.dirname(libraryPath) +
- provider.pathContext.separator;
- if (filePath.startsWith(libraryRootPath)) {
- String pathInLibrary = filePath.substring(libraryRootPath.length);
- String uriStr = '${library.shortName}/$pathInLibrary';
- try {
- resource.File file = provider.getResource(filePath);
- Uri dartUri = Uri.parse(uriStr);
- return file.createSource(dartUri);
- } catch (exception) {
- return null;
- }
- }
- }
- return null;
- }
-
- @override
- PackageBundle getLinkedBundle() {
- if (_bundle == null) {
- resource.File summaryFile =
- provider.getFile(provider.convertPath('/lib/_internal/strong.sum'));
- List<int> bytes;
- if (summaryFile.exists) {
- bytes = summaryFile.readAsBytesSync();
- } else {
- bytes = _computeLinkedBundleBytes();
- }
- _bundle = new PackageBundle.fromBuffer(bytes);
- }
- return _bundle;
- }
-
- @override
- SdkLibrary getSdkLibrary(String dartUri) {
- // getSdkLibrary() is only used to determine whether a library is internal
- // to the SDK. The mock SDK doesn't have any internals, so it's safe to
- // return null.
- return null;
- }
-
- @override
- Source mapDartUri(String dartUri) {
- const Map<String, String> uriToPath = const {
- "dart:core": "/lib/core/core.dart",
- "dart:html": "/lib/html/dartium/html_dartium.dart",
- "dart:async": "/lib/async/async.dart",
- "dart:collection": "/lib/collection/collection.dart",
- "dart:convert": "/lib/convert/convert.dart",
- "dart:math": "/lib/math/math.dart",
- "dart:_internal": "/lib/internal/internal.dart",
- };
-
- String path = uriToPath[dartUri];
- if (path != null) {
- resource.File file = provider.getResource(provider.convertPath(path));
- Uri uri = new Uri(scheme: 'dart', path: dartUri.substring(5));
- return file.createSource(uri);
- }
-
- // If we reach here then we tried to use a dartUri that's not in the
- // table above.
- return null;
- }
-
- /**
- * Compute the bytes of the linked bundle associated with this SDK.
- */
- List<int> _computeLinkedBundleBytes() {
- List<Source> librarySources = sdkLibraries
- .map((SdkLibrary library) => mapDartUri(library.shortName))
- .toList();
- return new SummaryBuilder(librarySources, context).build();
- }
-}
-
-class MockSdkLibrary implements SdkLibrary {
- final String shortName;
- final String path;
- final String content;
-
- const MockSdkLibrary(this.shortName, this.path, this.content);
-
- @override
- String get category => throw unimplemented;
-
- @override
- bool get isDart2JsLibrary => throw unimplemented;
-
- @override
- bool get isDocumented => throw unimplemented;
-
- @override
- bool get isImplementation => false;
-
- @override
- bool get isInternal => shortName.startsWith('dart:_');
-
- @override
- bool get isShared => throw unimplemented;
-
- @override
- bool get isVmLibrary => throw unimplemented;
-
- UnimplementedError get unimplemented => new UnimplementedError();
-}
diff --git a/pkg/analysis_server/test/mocks.dart b/pkg/analysis_server/test/mocks.dart
index 6c4b927..23f74f9 100644
--- a/pkg/analysis_server/test/mocks.dart
+++ b/pkg/analysis_server/test/mocks.dart
@@ -3,12 +3,17 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
+import 'dart:convert';
import 'dart:io';
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart' as lsp;
+import 'package:analysis_server/lsp_protocol/protocol_generated.dart';
+import 'package:analysis_server/lsp_protocol/protocol_special.dart' as lsp;
import 'package:analysis_server/protocol/protocol.dart';
import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/channel/channel.dart';
+import 'package:analysis_server/src/lsp/channel/lsp_channel.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/timestamped_data.dart';
import 'package:test/test.dart';
@@ -43,6 +48,140 @@
Matcher isResponseSuccess(String id) => new _IsResponseSuccess(id);
/**
+ * A mock [LspServerCommunicationChannel] for testing [LspAnalysisServer].
+ */
+class MockLspServerChannel implements LspServerCommunicationChannel {
+ // TODO(dantup): Support server-to-client requests. We'll probably need to
+ // change IncomingMessage to just Message for both directions?
+ final StreamController<lsp.IncomingMessage> _clientToServer =
+ new StreamController<lsp.IncomingMessage>.broadcast();
+ final StreamController<lsp.Message> _serverToClient =
+ new StreamController<lsp.Message>.broadcast();
+
+ bool _closed = false;
+
+ String name;
+
+ MockLspServerChannel(bool _printMessages) {
+ if (_printMessages) {
+ _serverToClient.stream
+ .listen((message) => print('<== ' + jsonEncode(message)));
+ _clientToServer.stream
+ .listen((message) => print('==> ' + jsonEncode(message)));
+ }
+ }
+
+ Stream<lsp.Message> get serverToClient => _serverToClient.stream;
+
+ @override
+ void close() {
+ _closed = true;
+ }
+
+ /**
+ * A stream of [NotificationMessage]s from the server that may be errors.
+ */
+ Stream<lsp.NotificationMessage> get errorNotificationsFromServer {
+ return notificationsFromServer.where(_isErrorNotification);
+ }
+
+ @override
+ void listen(void Function(lsp.IncomingMessage message) onMessage,
+ {Function onError, void Function() onDone}) {
+ _clientToServer.stream.listen(onMessage, onError: onError, onDone: onDone);
+ }
+
+ /**
+ * A stream of [NotificationMessage]s from the server.
+ */
+ Stream<lsp.NotificationMessage> get notificationsFromServer {
+ return _serverToClient.stream
+ .where((m) => m is lsp.NotificationMessage)
+ .cast<lsp.NotificationMessage>();
+ }
+
+ @override
+ void sendNotification(lsp.NotificationMessage notification) {
+ // Don't deliver notifications after the connection is closed.
+ if (_closed) {
+ return;
+ }
+ _serverToClient.add(notification);
+ }
+
+ void sendNotificationToServer(lsp.NotificationMessage notification) {
+ // Don't deliver notifications after the connection is closed.
+ if (_closed) {
+ return;
+ }
+ notification = _convertJson(notification, lsp.NotificationMessage.fromJson);
+ _clientToServer.add(notification);
+ }
+
+ /**
+ * Send the given [request] to the server and return a future that will
+ * complete when a response associated with the [request] has been received.
+ * The value of the future will be the received response.
+ */
+ Future<lsp.ResponseMessage> sendRequestToServer(lsp.RequestMessage request) {
+ // No further requests should be sent after the connection is closed.
+ if (_closed) {
+ throw new Exception('sendLspRequest after connection closed');
+ }
+ request = _convertJson(request, lsp.RequestMessage.fromJson);
+ // Wrap send request in future to simulate WebSocket.
+ new Future(() => _clientToServer.add(request));
+ return waitForResponse(request);
+ }
+
+ @override
+ void sendResponse(lsp.ResponseMessage response) {
+ // Don't deliver responses after the connection is closed.
+ if (_closed) {
+ return;
+ }
+ // Wrap send response in future to simulate WebSocket.
+ new Future(() => _serverToClient.add(response));
+ }
+
+ /**
+ * Return a future that will complete when a response associated with the
+ * given [request] has been received. The value of the future will be the
+ * received response. The returned future will throw an exception if a server
+ * error is reported before the response has been received.
+ *
+ * Unlike [sendLspRequest], this method assumes that the [request] has already
+ * been sent to the server.
+ */
+ Future<lsp.ResponseMessage> waitForResponse(
+ lsp.RequestMessage request) async {
+ // TODO(dantup): Make this throw if an error notifications comes in (as
+ // described above).
+ final response = await _serverToClient.stream.firstWhere((response) =>
+ response is lsp.ResponseMessage && response.id == request.id);
+ return response;
+ }
+
+ /// Round trips the object to JSON and back to ensure it behaves the same as
+ /// when running over the real STDIO server. Without this, the object passed
+ /// to the handlers will have concrete types as constructed in tests rather
+ /// than the maps as they would be (the server expects to do the conversion).
+ T _convertJson<T>(
+ lsp.ToJsonable message, T Function(Map<String, dynamic>) constructor) {
+ return constructor(jsonDecode(jsonEncode(message.toJson())));
+ }
+
+ /// Checks whether a notification is likely an error from the server (for
+ /// example a window/showMessage). This is useful for tests that want to
+ /// ensure no errors come from the server in response to notifications (which
+ /// don't have their own responses).
+ bool _isErrorNotification(lsp.NotificationMessage notification) {
+ return notification.method == Method.window_logMessage ||
+ notification.method == Method.window_showMessage;
+ }
+}
+
+/**
* A mock [ServerCommunicationChannel] for testing [AnalysisServer].
*/
class MockServerChannel implements ServerCommunicationChannel {
@@ -55,6 +194,7 @@
List<Response> responsesReceived = [];
List<Notification> notificationsReceived = [];
+
bool _closed = false;
String name;
diff --git a/pkg/analysis_server/test/plugin/protocol_dart_test.dart b/pkg/analysis_server/test/plugin/protocol_dart_test.dart
index 67f5ca5..ed8e850 100644
--- a/pkg/analysis_server/test/plugin/protocol_dart_test.dart
+++ b/pkg/analysis_server/test/plugin/protocol_dart_test.dart
@@ -39,6 +39,8 @@
convertElementKind(engine.ElementKind.FUNCTION), ElementKind.FUNCTION);
expect(convertElementKind(engine.ElementKind.FUNCTION_TYPE_ALIAS),
ElementKind.FUNCTION_TYPE_ALIAS);
+ expect(convertElementKind(engine.ElementKind.GENERIC_FUNCTION_TYPE),
+ ElementKind.FUNCTION_TYPE_ALIAS);
expect(convertElementKind(engine.ElementKind.GETTER), ElementKind.GETTER);
expect(convertElementKind(engine.ElementKind.LABEL), ElementKind.LABEL);
expect(convertElementKind(engine.ElementKind.LIBRARY), ElementKind.LIBRARY);
@@ -169,7 +171,7 @@
}
test_fromElement_CONSTRUCTOR_required_parameters_1() async {
- addMetaPackageSource();
+ addMetaPackage();
engine.Source source = addSource('/test.dart', '''
import 'package:meta/meta.dart';
class A {
@@ -186,7 +188,7 @@
/// Verify parameter re-ordering for required params
test_fromElement_CONSTRUCTOR_required_parameters_2() async {
- addMetaPackageSource();
+ addMetaPackage();
engine.Source source = addSource('/test.dart', '''
import 'package:meta/meta.dart';
class A {
@@ -204,7 +206,7 @@
/// Verify parameter re-ordering for required params
test_fromElement_CONSTRUCTOR_required_parameters_3() async {
- addMetaPackageSource();
+ addMetaPackage();
engine.Source source = addSource('/test.dart', '''
import 'package:meta/meta.dart';
class A {
@@ -408,6 +410,30 @@
expect(element.flags, 0);
}
+ test_fromElement_FUNCTION_TYPE_ALIAS_genericTypeAlias() async {
+ engine.Source source = addSource('/test.dart', '''
+typedef F<T> = int Function(String x);
+''');
+ engine.CompilationUnit unit = await resolveLibraryUnit(source);
+ engine.GenericTypeAliasElement engineElement = findElementInUnit(unit, 'F');
+ // create notification Element
+ Element element = convertElement(engineElement);
+ expect(element.kind, ElementKind.FUNCTION_TYPE_ALIAS);
+ expect(element.name, 'F');
+ expect(element.typeParameters, '<T>');
+ {
+ Location location = element.location;
+ expect(location.file, convertPath('/test.dart'));
+ expect(location.offset, 8);
+ expect(location.length, 'F'.length);
+ expect(location.startLine, 1);
+ expect(location.startColumn, 9);
+ }
+ expect(element.parameters, '(String x)');
+ expect(element.returnType, 'int');
+ expect(element.flags, 0);
+ }
+
test_fromElement_GETTER() async {
engine.Source source = addSource('/test.dart', '''
class A {
diff --git a/pkg/analysis_server/test/protocol_server_test.dart b/pkg/analysis_server/test/protocol_server_test.dart
index 7ac554b..9d2e9ca 100644
--- a/pkg/analysis_server/test/protocol_server_test.dart
+++ b/pkg/analysis_server/test/protocol_server_test.dart
@@ -128,7 +128,7 @@
engine.ElementKind.DYNAMIC: ElementKind.UNKNOWN,
engine.ElementKind.ERROR: ElementKind.UNKNOWN,
engine.ElementKind.EXPORT: ElementKind.UNKNOWN,
- engine.ElementKind.GENERIC_FUNCTION_TYPE: ElementKind.UNKNOWN,
+ engine.ElementKind.GENERIC_FUNCTION_TYPE: ElementKind.FUNCTION_TYPE_ALIAS,
engine.ElementKind.IMPORT: ElementKind.UNKNOWN,
engine.ElementKind.NAME: ElementKind.UNKNOWN,
engine.ElementKind.UNIVERSE: ElementKind.UNKNOWN
diff --git a/pkg/analysis_server/test/search/element_references_test.dart b/pkg/analysis_server/test/search/element_references_test.dart
index fb3aa88..6473f65 100644
--- a/pkg/analysis_server/test/search/element_references_test.dart
+++ b/pkg/analysis_server/test/search/element_references_test.dart
@@ -693,6 +693,18 @@
assertHasResult(SearchResultKind.REFERENCE, 'F f');
}
+ Future<void> test_typeReference_genericTypeAlias_function() async {
+ addTestFile('''
+typedef F = Function();
+main(F f) {
+}
+''');
+ await findElementReferences('F =', false);
+ expect(searchElement.kind, ElementKind.FUNCTION_TYPE_ALIAS);
+ expect(results, hasLength(1));
+ assertHasResult(SearchResultKind.REFERENCE, 'F f');
+ }
+
Future<void> test_typeReference_typeVariable() async {
addTestFile('''
class A<T> {
diff --git a/pkg/analysis_server/test/search/top_level_declarations_test.dart b/pkg/analysis_server/test/search/top_level_declarations_test.dart
index 5e46628..7e1fd99 100644
--- a/pkg/analysis_server/test/search/top_level_declarations_test.dart
+++ b/pkg/analysis_server/test/search/top_level_declarations_test.dart
@@ -67,16 +67,18 @@
class A {} // A
class B = Object with A;
typedef C();
-D() {}
-var E = null;
+typedef D();
+E() {}
+var F = null;
class ABC {}
''');
- await findTopLevelDeclarations('^[A-E]\$');
+ await findTopLevelDeclarations('^[A-F]\$');
assertHasDeclaration(ElementKind.CLASS, 'A');
assertHasDeclaration(ElementKind.CLASS, 'B');
assertHasDeclaration(ElementKind.FUNCTION_TYPE_ALIAS, 'C');
- assertHasDeclaration(ElementKind.FUNCTION, 'D');
- assertHasDeclaration(ElementKind.TOP_LEVEL_VARIABLE, 'E');
+ assertHasDeclaration(ElementKind.FUNCTION_TYPE_ALIAS, 'D');
+ assertHasDeclaration(ElementKind.FUNCTION, 'E');
+ assertHasDeclaration(ElementKind.TOP_LEVEL_VARIABLE, 'F');
assertNoDeclaration(ElementKind.CLASS, 'ABC');
}
}
diff --git a/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
index a75c2e4..d6c7124 100644
--- a/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
@@ -896,7 +896,7 @@
}
test_ArgumentList_local_constructor_required_param_0() async {
- addMetaPackageSource();
+ addMetaPackage();
addTestSource('''
import 'package:meta/meta.dart';
class A { A({int one, @required String two: 'defaultValue'}) { } }
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
index fc67b56..acd42b0 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
@@ -9,7 +9,6 @@
import 'package:analysis_server/src/services/completion/completion_performance.dart';
import 'package:analysis_server/src/services/completion/dart/completion_manager.dart'
show DartCompletionRequestImpl;
-import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/generated/parser.dart' as analyzer;
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:test/test.dart';
@@ -460,19 +459,10 @@
return cs;
}
- /**
- * Return a [Future] that completes with the containing library information
- * after it is accessible via [context.getLibrariesContaining].
- */
- Future<void> computeLibrariesContaining([int times = 200]) {
- return driver.getResult(testFile).then((result) => null);
- }
-
Future computeSuggestions({int times = 200}) async {
- AnalysisResult analysisResult =
- await driver.getResult(convertPath(testFile));
+ var resolveResult = await session.getResolvedUnit(testFile);
CompletionRequestImpl baseRequest = new CompletionRequestImpl(
- analysisResult, completionOffset, new CompletionPerformance());
+ resolveResult, completionOffset, new CompletionPerformance());
// Build the request
var request = await DartCompletionRequestImpl.from(baseRequest);
@@ -553,7 +543,7 @@
@override
void setUp() {
super.setUp();
- testFile = resourceProvider.convertPath('/completionTest.dart');
+ testFile = convertPath('/completionTest.dart');
contributor = createContributor();
}
}
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart b/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart
index 263f905..83ad6a8 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart
@@ -47,7 +47,7 @@
// Build the request
CompletionRequestImpl baseRequest = new CompletionRequestImpl(
- await driver.getResult(testFile),
+ await session.getResolvedUnit(testFile),
completionOffset,
new CompletionPerformance());
Completer<DartCompletionRequest> requestCompleter =
diff --git a/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
index 26100ebf..d36e5af 100644
--- a/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
@@ -1,12 +1,10 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/src/protocol_server.dart';
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/imported_reference_contributor.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/source.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -30,7 +28,7 @@
/// Sanity check. Permutations tested in local_ref_contributor.
test_ArgDefaults_function_with_required_named() async {
- addMetaPackageSource();
+ addMetaPackage();
resolveSource('/testB.dart', '''
lib B;
@@ -504,7 +502,7 @@
await computeSuggestions();
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
- assertSuggestFunction('y', 'dynamic');
+ assertSuggestFunction('y', 'Future<dynamic>');
assertNotSuggested('A');
assertSuggestClass('Object');
}
@@ -1201,19 +1199,16 @@
}
test_Block_unimported() async {
- addPackageSource('myBar', 'bar.dart', 'class Foo2 { Foo2() { } }');
- addSource(
- '/proj/testAB.dart', 'import "package:myBar/bar.dart"; class Foo { }');
- testFile = '/proj/completionTest.dart';
- addTestSource('class C {foo(){F^}}');
+ addPackageFile('aaa', 'a.dart', 'class A {}');
+ addTestSource('main() { ^ }');
await computeSuggestions();
- expect(replacementOffset, completionOffset - 1);
- expect(replacementLength, 1);
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+
// Not imported, so not suggested
- assertNotSuggested('Foo');
- assertNotSuggested('Foo2');
- assertNotSuggested('Future');
+ assertNotSuggested('A');
+ assertNotSuggested('Completer');
}
test_CascadeExpression_selector1() async {
@@ -2367,6 +2362,36 @@
assertSuggestClass('Object');
}
+ test_functionTypeAlias_genericTypeAlias() async {
+ addSource('/a.dart', r'''
+typedef F = void Function();
+''');
+ addTestSource(r'''
+import 'a.dart';
+
+main() {
+ ^
+}
+''');
+ await computeSuggestions();
+ assertSuggestFunctionTypeAlias('F', 'void');
+ }
+
+ test_functionTypeAlias_old() async {
+ addSource('/a.dart', r'''
+typedef void F();
+''');
+ addTestSource(r'''
+import 'a.dart';
+
+main() {
+ ^
+}
+''');
+ await computeSuggestions();
+ assertSuggestFunctionTypeAlias('F', 'void');
+ }
+
test_IfStatement() async {
// SimpleIdentifier IfStatement
addTestSource('''
@@ -2433,7 +2458,6 @@
}
test_implicitCreation() async {
- configurePreviewDart2();
addSource('/a.dart', '''
class A {
A.a1();
@@ -2609,7 +2633,6 @@
}
test_InstanceCreationExpression_filter() async {
- configurePreviewDart2();
addSource('/a.dart', '''
class A {}
class B extends A {}
@@ -2637,7 +2660,12 @@
assertSuggestConstructor('D', elemOffset: -1);
}
+ @failingTest
test_InstanceCreationExpression_imported() async {
+ // This is failing because the constructor for Future is added twice. I
+ // suspect that we're adding it from both dart:core and dart:async and are
+ // not noticing that it's the same element.
+
// SimpleIdentifier TypeName ConstructorName InstanceCreationExpression
addSource('/testA.dart', '''
int T1;
@@ -2676,15 +2704,15 @@
test_InstanceCreationExpression_unimported() async {
// SimpleIdentifier TypeName ConstructorName InstanceCreationExpression
- addSource('/testAB.dart', 'class Foo { }');
- addTestSource('class C {foo(){new F^}}');
+ addSource('/testAB.dart', 'class Clip { }');
+ addTestSource('class A {foo(){new C^}}');
await computeSuggestions();
expect(replacementOffset, completionOffset - 1);
expect(replacementLength, 1);
// Not imported, so not suggested
- assertNotSuggested('Future');
- assertNotSuggested('Foo');
+ assertNotSuggested('Completer');
+ assertNotSuggested('Clip');
}
test_internal_sdk_libs() async {
@@ -3252,9 +3280,7 @@
assertNotSuggested('_g');
assertSuggestClass('bool');
if (suggestConstructorsWithoutNew) {
- // TODO(brianwilkerson) Should not suggest constructors for classes that
- // cannot be instantiated.
- assertSuggestConstructor('bool');
+ assertSuggestConstructor('List');
}
}
@@ -3464,48 +3490,6 @@
assertNotSuggested('m');
}
- /**
- * Ensure that completions in one context don't appear in another
- */
- test_multiple_contexts() async {
- // Create a 2nd context with source
- var context2 = AnalysisEngine.instance.createAnalysisContext();
- context2.sourceFactory =
- new SourceFactory([new DartUriResolver(sdk), resourceResolver]);
- String content2 = 'class ClassFromAnotherContext { }';
- Source source2 =
- newFile('/context2/foo.dart', content: content2).createSource();
- ChangeSet changeSet = new ChangeSet();
- changeSet.addedSource(source2);
- context2.applyChanges(changeSet);
- context2.setContents(source2, content2);
-
- // Resolve the source in the 2nd context and update the index
- var result = context2.performAnalysisTask();
- while (result.hasMoreWork) {
- result = context2.performAnalysisTask();
- }
-
- // Check that source in 2nd context does not appear in completion in 1st
- addSource('/context1/libA.dart', '''
- library libA;
- class ClassInLocalContext {int x;}''');
- testFile = '/context1/completionTest.dart';
- addTestSource('''
- import "${convertAbsolutePathToUri("/context1/libA.dart")}";
- import "${convertAbsolutePathToUri("/foo.dart")}";
- main() {C^}
- ''');
-
- await computeSuggestions();
- assertSuggestClass('ClassInLocalContext');
- if (suggestConstructorsWithoutNew) {
- assertSuggestConstructor('ClassInLocalContext');
- }
- // Assert contributor does not include results from 2nd context.
- assertNotSuggested('ClassFromAnotherContext');
- }
-
test_new_instance() async {
addTestSource('import "dart:math"; class A {x() {new Random().^}}');
@@ -3588,7 +3572,6 @@
class B { factory B.bar(int x) => null; }
main() {new ^}''');
- await computeLibrariesContaining();
await computeSuggestions();
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
@@ -3624,7 +3607,6 @@
main() {new ^}
var m;''');
- await computeLibrariesContaining();
await computeSuggestions();
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
diff --git a/pkg/analysis_server/test/services/completion/dart/inherited_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/inherited_reference_contributor_test.dart
index d4689fe..d0b31fc 100644
--- a/pkg/analysis_server/test/services/completion/dart/inherited_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/inherited_reference_contributor_test.dart
@@ -1,6 +1,7 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+
import 'dart:async';
import 'package:analysis_server/src/protocol_server.dart';
@@ -29,7 +30,7 @@
/// Sanity check. Permutations tested in local_ref_contributor.
test_ArgDefaults_inherited_method_with_required_named() async {
- addMetaPackageSource();
+ addMetaPackage();
resolveSource('/testB.dart', '''
import 'package:meta/meta.dart';
@@ -72,7 +73,7 @@
assertNotSuggested('B');
assertNotSuggested('A');
assertNotSuggested('Object');
- assertSuggestMethod('y', 'A', 'dynamic');
+ assertSuggestMethod('y', 'A', 'Future<dynamic>');
}
test_Block_inherited_imported() async {
diff --git a/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart
index 0bf6a76..2627c39 100644
--- a/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart
@@ -94,7 +94,6 @@
part "${convertAbsolutePathToUri(testFile)}";''');
addTestSource('part of testA; foo() {bar.^}');
// Assume that libraries containing has been computed for part files
- await computeLibrariesContaining();
await computeSuggestions();
assertSuggestClass('Future');
assertSuggestFunction('loadLibrary', 'Future<dynamic>');
@@ -195,7 +194,6 @@
part of testA;
main() {b.^}''');
// Assume that libraries containing has been computed for part files
- await computeLibrariesContaining();
await computeSuggestions();
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
diff --git a/pkg/analysis_server/test/services/completion/dart/library_prefix_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/library_prefix_contributor_test.dart
index 052103e..2d2cbac 100644
--- a/pkg/analysis_server/test/services/completion/dart/library_prefix_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/library_prefix_contributor_test.dart
@@ -304,7 +304,6 @@
addTestSource('''
part of testB;
main() {new ^ String x = "hello";}''');
- await computeLibrariesContaining();
await computeSuggestions();
assertSuggestLibraryPrefixes(['math', 't']);
}
diff --git a/pkg/analysis_server/test/services/completion/dart/local_constructor_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_constructor_contributor_test.dart
index d361dc9..7a841e7 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_constructor_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_constructor_contributor_test.dart
@@ -57,7 +57,7 @@
/// Sanity check. Permutations tested in local_ref_contributor.
test_ArgDefaults_cons_with_required_named() async {
- addMetaPackageSource();
+ addMetaPackage();
addTestSource('''
import 'package:meta/meta.dart';
@@ -1142,18 +1142,15 @@
}
test_Block_unimported() async {
- addPackageSource('myBar', 'bar.dart', 'class Foo2 { Foo2() { } }');
- addSource(
- '/proj/testAB.dart', 'import "package:myBar/bar.dart"; class Foo { }');
- testFile = '/proj/completionTest.dart';
- addTestSource('class C {foo(){F^}}');
- await computeSuggestions();
+ addPackageFile('aaa', 'a.dart', 'class A {}');
+ addTestSource('main() { ^ }');
- expect(replacementOffset, completionOffset - 1);
- expect(replacementLength, 1);
- assertNotSuggested('Foo');
- // TODO(danrubel) implement
- assertNotSuggested('Foo2');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+
+ // Not imported, so not suggested
+ assertNotSuggested('A');
assertNotSuggested('Future');
}
@@ -3290,7 +3287,6 @@
part of libA;
class B { factory B.bar(int x) => null; }
main() {new ^}''');
- await computeLibrariesContaining();
await computeSuggestions();
expect(replacementOffset, completionOffset);
diff --git a/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart
index 07d9364..dbe61ec 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart
@@ -39,7 +39,6 @@
part of libA;
class B { factory B.bar(int x) => null; }
main() {new ^}''');
- await computeLibrariesContaining();
await computeSuggestions();
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
@@ -74,7 +73,6 @@
class A { A({String boo: 'hoo'}) { } }
main() {new ^}
var m;''');
- await computeLibrariesContaining();
await computeSuggestions();
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
@@ -114,7 +112,6 @@
a = new ^
}
var m;''');
- await computeLibrariesContaining();
await computeSuggestions();
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
@@ -165,7 +162,6 @@
A a = new ^
}
var m;''');
- await computeLibrariesContaining();
await computeSuggestions();
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
@@ -214,7 +210,6 @@
part of libA;
class B { factory B.bar(int x) => null; }
main() {^}''');
- await computeLibrariesContaining();
await computeSuggestions();
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
@@ -261,7 +256,6 @@
class A { A({String boo: 'hoo'}) { } }
main() {^}
var m;''');
- await computeLibrariesContaining();
await computeSuggestions();
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
diff --git a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
index e96883c..2f3bad3 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -87,7 +87,7 @@
}
test_ArgDefaults_function_with_optional_positional() async {
- addMetaPackageSource();
+ addMetaPackage();
addTestSource('''
import 'package:meta/meta.dart';
@@ -102,7 +102,7 @@
}
test_ArgDefaults_function_with_required_named() async {
- addMetaPackageSource();
+ addMetaPackage();
addTestSource('''
import 'package:meta/meta.dart';
@@ -117,7 +117,7 @@
}
test_ArgDefaults_method_with_required_named() async {
- addMetaPackageSource();
+ addMetaPackage();
addTestSource('''
import 'package:meta/meta.dart';
@@ -783,7 +783,7 @@
await computeSuggestions();
expect(replacementOffset, completionOffset);
expect(replacementLength, 0);
- assertSuggestMethod('y', 'A', 'Future',
+ assertSuggestMethod('y', 'A', 'Future<dynamic>',
relevance: DART_RELEVANCE_LOCAL_METHOD);
assertSuggestClass('A');
assertNotSuggested('Object');
@@ -1415,18 +1415,15 @@
}
test_Block_unimported() async {
- addPackageSource('myBar', 'bar.dart', 'class Foo2 { Foo2() { } }');
- addSource(
- '/proj/testAB.dart', 'import "package:myBar/bar.dart"; class Foo { }');
- testFile = '/proj/completionTest.dart';
- addTestSource('class C {foo(){F^}}');
- await computeSuggestions();
+ addPackageFile('aaa', 'a.dart', 'class A {}');
+ addTestSource('main() { ^ }');
- expect(replacementOffset, completionOffset - 1);
- expect(replacementLength, 1);
- assertNotSuggested('Foo');
- // TODO(danrubel) implement
- assertNotSuggested('Foo2');
+ await computeSuggestions();
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+
+ // Not imported, so not suggested
+ assertNotSuggested('A');
assertNotSuggested('Future');
}
@@ -1912,6 +1909,40 @@
assertSuggestParameter('y', 'int');
}
+ test_ConstructorFieldInitializer_name() async {
+ addTestSource('''
+class A {
+ final int foo;
+ A() : ^
+}
+''');
+ await computeSuggestions();
+
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestField('foo', 'int', relevance: DART_RELEVANCE_LOCAL_FIELD);
+ }
+
+ test_ConstructorFieldInitializer_value() async {
+ addTestSource('''
+var foo = 0;
+
+class A {
+ final int bar;
+ A() : bar = ^
+}
+''');
+ await computeSuggestions();
+
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+ assertSuggestTopLevelVar(
+ 'foo',
+ 'int',
+ relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE,
+ );
+ }
+
test_ConstructorName_importedClass() async {
// SimpleIdentifier PrefixedIdentifier TypeName ConstructorName
// InstanceCreationExpression
@@ -2747,6 +2778,28 @@
assertNotSuggested('Object');
}
+ test_functionTypeAlias_genericTypeAlias() async {
+ addTestSource(r'''
+typedef F = void Function();
+main() {
+ ^
+}
+''');
+ await computeSuggestions();
+ assertSuggestFunctionTypeAlias('F', 'void');
+ }
+
+ test_functionTypeAlias_old() async {
+ addTestSource(r'''
+typedef void F();
+main() {
+ ^
+}
+''');
+ await computeSuggestions();
+ assertSuggestFunctionTypeAlias('F', 'void');
+ }
+
test_IfStatement() async {
// SimpleIdentifier IfStatement
addTestSource('''
@@ -3820,7 +3873,6 @@
class A { A({String boo: 'hoo'}) { } }
main() {new ^}
var m;''');
- await computeLibrariesContaining();
await computeSuggestions();
expect(replacementOffset, completionOffset);
diff --git a/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart
index 8d5a329..cd1ffcc 100644
--- a/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart
@@ -116,7 +116,6 @@
}
''');
// assume information for context.getLibrariesContaining has been cached
- await computeLibrariesContaining();
await computeSuggestions();
_assertOverride('''
@override
diff --git a/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart
index 2987710..1907389 100644
--- a/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart
@@ -98,7 +98,6 @@
}
test_implicitCreation() async {
- configurePreviewDart2();
addSource('/a.dart', '''
class A {
A.foo();
@@ -257,7 +256,7 @@
import "dart:async" as async;
void main() {async.Future.^.w()}''');
await computeSuggestions();
- assertSuggestMethod('wait', 'Future', 'Future<dynamic>');
+ assertSuggestMethod('wait', 'Future', 'Future<List<T>>');
}
test_PrefixedIdentifier_class_const() async {
diff --git a/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart
index a39270d..d36ca4d 100644
--- a/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart
@@ -81,7 +81,7 @@
}
test_ArgDefaults_method_with_optional_positional() async {
- addMetaPackageSource();
+ addMetaPackage();
addTestSource('''
import 'package:meta/meta.dart';
@@ -96,7 +96,7 @@
}
test_ArgDefaults_method_with_required_named() async {
- addMetaPackageSource();
+ addMetaPackage();
addTestSource('''
import 'package:meta/meta.dart';
@@ -1085,17 +1085,15 @@
}
test_Block_unimported() async {
- addPackageSource('myBar', 'bar.dart', 'class Foo2 { Foo2() { } }');
- addSource(
- '/proj/testAB.dart', 'import "package:myBar/bar.dart"; class Foo { }');
- testFile = resourceProvider.convertPath('/proj/completionTest.dart');
- addTestSource('class C {foo(){F^}}');
+ addPackageFile('aaa', 'a.dart', 'class A {}');
+ addTestSource('main() { ^ }');
+
await computeSuggestions();
- expect(replacementOffset, completionOffset - 1);
- expect(replacementLength, 1);
- assertNotSuggested('Foo');
- // TODO(danrubel) implement
- assertNotSuggested('Foo2');
+ expect(replacementOffset, completionOffset);
+ expect(replacementLength, 0);
+
+ // Not imported, so not suggested
+ assertNotSuggested('A');
assertNotSuggested('Future');
}
diff --git a/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart
index 7d66b12..c283cde 100644
--- a/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart
@@ -67,9 +67,9 @@
}
test_export_package2() async {
- addPackageSource('foo', 'foo.dart', 'library foo;');
- addPackageSource('foo', 'baz/too.dart', 'library too;');
- addPackageSource('bar', 'bar.dart', 'library bar;');
+ addPackageFile('foo', 'foo.dart', 'library foo;');
+ addPackageFile('foo', 'baz/too.dart', 'library too;');
+ addPackageFile('bar', 'bar.dart', 'library bar;');
addTestSource('export "package:foo/baz/^" import');
await computeSuggestions();
assertSuggest('package:foo/baz/too.dart',
@@ -79,9 +79,9 @@
test_export_package2_off() async {
try {
UriContributor.suggestFilePaths = false;
- addPackageSource('foo', 'foo.dart', 'library foo;');
- addPackageSource('foo', 'baz/too.dart', 'library too;');
- addPackageSource('bar', 'bar.dart', 'library bar;');
+ addPackageFile('foo', 'foo.dart', 'library foo;');
+ addPackageFile('foo', 'baz/too.dart', 'library too;');
+ addPackageFile('bar', 'bar.dart', 'library bar;');
addTestSource('export "package:foo/baz/^" import');
await computeSuggestions();
assertNotSuggested('package:foo/baz/too.dart');
@@ -144,7 +144,7 @@
}
test_import_file() async {
- testFile = '/proj/completion.dart';
+ testFile = convertPath('/proj/completion.dart');
addSource('/proj/other.dart', 'library other;');
addSource('/proj/foo/bar.dart', 'library bar;');
addSource('/blat.dart', 'library blat;');
@@ -161,7 +161,7 @@
}
test_import_file2() async {
- testFile = '/proj/completion.dart';
+ testFile = convertPath('/proj/completion.dart');
addSource('/proj/other.dart', 'library other;');
addSource('/proj/foo/bar.dart', 'library bar;');
addSource('/blat.dart', 'library blat;');
@@ -180,7 +180,7 @@
test_import_file2_off() async {
try {
UriContributor.suggestFilePaths = false;
- testFile = '/proj/completion.dart';
+ testFile = convertPath('/proj/completion.dart');
addSource('/proj/other.dart', 'library other;');
addSource('/proj/foo/bar.dart', 'library bar;');
addSource('/blat.dart', 'library blat;');
@@ -200,7 +200,7 @@
}
test_import_file_child() async {
- testFile = '/proj/completion.dart';
+ testFile = convertPath('/proj/completion.dart');
addSource('/proj/other.dart', 'library other;');
addSource('/proj/foo/bar.dart', 'library bar;');
addSource('/blat.dart', 'library blat;');
@@ -217,7 +217,7 @@
}
test_import_file_outside_lib() async {
- testFile = '/proj/lib/completion.dart';
+ testFile = convertPath('/proj/lib/completion.dart');
addSource('/proj/lib/other.dart', 'library other;');
addSource('/proj/lib/foo/bar.dart', 'library bar;');
addSource('/proj/blat.dart', 'library blat;');
@@ -237,7 +237,7 @@
}
test_import_file_parent() async {
- testFile = '/proj/completion.dart';
+ testFile = convertPath('/proj/completion.dart');
addSource('/proj/other.dart', 'library other;');
addSource('/proj/foo/bar.dart', 'library bar;');
addSource('/blat.dart', 'library blat;');
@@ -256,7 +256,7 @@
}
test_import_file_parent2() async {
- testFile = '/proj/completion.dart';
+ testFile = convertPath('/proj/completion.dart');
addSource('/proj/other.dart', 'library other;');
addSource('/proj/foo/bar.dart', 'library bar;');
addSource('/blat.dart', 'library blat;');
@@ -273,7 +273,7 @@
}
test_import_no_dot_folders() async {
- testFile = '/proj/completion.dart';
+ testFile = convertPath('/proj/completion.dart');
addSource('/proj/other.dart', 'library other;');
newFolder('/proj/.fooFolder');
addTestSource('import "package:^";');
@@ -282,7 +282,7 @@
}
test_import_only_dart_files() async {
- testFile = '/proj/completion.dart';
+ testFile = convertPath('/proj/completion.dart');
addSource('/proj/other.dart', 'library other;');
newFile('/proj/analysis_options.yaml', content: '# analysis options');
addTestSource('import "package:^";');
@@ -291,9 +291,9 @@
}
test_import_package() async {
- addPackageSource('foo', 'foo.dart', 'library foo;');
- addPackageSource('foo', 'baz/too.dart', 'library too;');
- addPackageSource('bar', 'bar.dart', 'library bar;');
+ addPackageFile('foo', 'foo.dart', 'library foo;');
+ addPackageFile('foo', 'baz/too.dart', 'library too;');
+ addPackageFile('bar', 'bar.dart', 'library bar;');
addTestSource('import "p^" import');
await computeSuggestions();
expect(replacementOffset, completionOffset - 1);
@@ -310,9 +310,9 @@
}
test_import_package2() async {
- addPackageSource('foo', 'foo.dart', 'library foo;');
- addPackageSource('foo', 'baz/too.dart', 'library too;');
- addPackageSource('bar', 'bar.dart', 'library bar;');
+ addPackageFile('foo', 'foo.dart', 'library foo;');
+ addPackageFile('foo', 'baz/too.dart', 'library too;');
+ addPackageFile('bar', 'bar.dart', 'library bar;');
addTestSource('import "package:foo/baz/^" import');
await computeSuggestions();
assertSuggest('package:foo/baz/too.dart',
@@ -322,9 +322,9 @@
test_import_package2_off() async {
try {
UriContributor.suggestFilePaths = false;
- addPackageSource('foo', 'foo.dart', 'library foo;');
- addPackageSource('foo', 'baz/too.dart', 'library too;');
- addPackageSource('bar', 'bar.dart', 'library bar;');
+ addPackageFile('foo', 'foo.dart', 'library foo;');
+ addPackageFile('foo', 'baz/too.dart', 'library too;');
+ addPackageFile('bar', 'bar.dart', 'library bar;');
addTestSource('import "package:foo/baz/^" import');
await computeSuggestions();
assertNotSuggested('package:foo/baz/too.dart');
@@ -334,9 +334,9 @@
}
test_import_package2_raw() async {
- addPackageSource('foo', 'foo.dart', 'library foo;');
- addPackageSource('foo', 'baz/too.dart', 'library too;');
- addPackageSource('bar', 'bar.dart', 'library bar;');
+ addPackageFile('foo', 'foo.dart', 'library foo;');
+ addPackageFile('foo', 'baz/too.dart', 'library too;');
+ addPackageFile('bar', 'bar.dart', 'library bar;');
addTestSource('import r"package:foo/baz/^" import');
await computeSuggestions();
assertSuggest('package:foo/baz/too.dart',
@@ -344,9 +344,9 @@
}
test_import_package2_with_trailing() async {
- addPackageSource('foo', 'foo.dart', 'library foo;');
- addPackageSource('foo', 'baz/too.dart', 'library too;');
- addPackageSource('bar', 'bar.dart', 'library bar;');
+ addPackageFile('foo', 'foo.dart', 'library foo;');
+ addPackageFile('foo', 'baz/too.dart', 'library too;');
+ addPackageFile('bar', 'bar.dart', 'library bar;');
addTestSource('import "package:foo/baz/^.dart" import');
await computeSuggestions();
assertSuggest('package:foo/baz/too.dart',
@@ -356,8 +356,8 @@
}
test_import_package_missing_lib() async {
- var pkgSrc = addPackageSource('bar', 'bar.dart', 'library bar;');
- deleteFolder(dirname(pkgSrc.fullName));
+ var pkgFile = addPackageFile('bar', 'bar.dart', 'library bar;');
+ deleteFolder(pkgFile.parent.path);
addTestSource('import "p^" class');
await computeSuggestions();
expect(replacementOffset, completionOffset - 1);
@@ -368,9 +368,9 @@
}
test_import_package_raw() async {
- addPackageSource('foo', 'foo.dart', 'library foo;');
- addPackageSource('foo', 'baz/too.dart', 'library too;');
- addPackageSource('bar', 'bar.dart', 'library bar;');
+ addPackageFile('foo', 'foo.dart', 'library foo;');
+ addPackageFile('foo', 'baz/too.dart', 'library too;');
+ addPackageFile('bar', 'bar.dart', 'library bar;');
addTestSource('import r"p^" import');
await computeSuggestions();
expect(replacementOffset, completionOffset - 1);
@@ -460,7 +460,7 @@
}
test_part_file() async {
- testFile = '/proj/completion.dart';
+ testFile = convertPath('/proj/completion.dart');
addSource('/proj/other.dart', 'library other;');
addSource('/proj/foo/bar.dart', 'library bar;');
addSource('/blat.dart', 'library blat;');
@@ -477,7 +477,7 @@
}
test_part_file2() async {
- testFile = '/proj/completion.dart';
+ testFile = convertPath('/proj/completion.dart');
addSource('/proj/other.dart', 'library other;');
addSource('/proj/foo/bar.dart', 'library bar;');
addSource('/blat.dart', 'library blat;');
@@ -494,7 +494,7 @@
}
test_part_file_child() async {
- testFile = '/proj/completion.dart';
+ testFile = convertPath('/proj/completion.dart');
addSource('/proj/other.dart', 'library other;');
addSource('/proj/foo/bar.dart', 'library bar;');
addSource('/blat.dart', 'library blat;');
@@ -511,7 +511,7 @@
}
test_part_file_parent() async {
- testFile = '/proj/completion.dart';
+ testFile = convertPath('/proj/completion.dart');
addSource('/proj/other.dart', 'library other;');
addSource('/proj/foo/bar.dart', 'library bar;');
addSource('/blat.dart', 'library blat;');
@@ -541,7 +541,7 @@
}
test_import_file() async {
- testFile = '\\proj\\completion.dart';
+ testFile = convertPath('\\proj\\completion.dart');
addSource('\\proj\\other.dart', 'library other;');
addSource('\\proj\\foo\\bar.dart', 'library bar;');
addSource('\\blat.dart', 'library blat;');
@@ -558,7 +558,7 @@
}
test_import_file2() async {
- testFile = '\\proj\\completion.dart';
+ testFile = convertPath('\\proj\\completion.dart');
addSource('\\proj\\other.dart', 'library other;');
addSource('\\proj\\foo\\bar.dart', 'library bar;');
addSource('\\blat.dart', 'library blat;');
@@ -575,7 +575,7 @@
}
test_import_file_child() async {
- testFile = '\\proj\\completion.dart';
+ testFile = convertPath('\\proj\\completion.dart');
addSource('\\proj\\other.dart', 'library other;');
addSource('\\proj\\foo\\bar.dart', 'library bar;');
addSource('\\blat.dart', 'library blat;');
@@ -592,7 +592,7 @@
}
test_import_file_parent() async {
- testFile = '\\proj\\completion.dart';
+ testFile = convertPath('\\proj\\completion.dart');
addSource('\\proj\\other.dart', 'library other;');
addSource('\\proj\\foo\\bar.dart', 'library bar;');
addSource('\\blat.dart', 'library blat;');
@@ -609,7 +609,7 @@
}
test_import_file_parent2() async {
- testFile = '\\proj\\completion.dart';
+ testFile = convertPath('\\proj\\completion.dart');
addSource('\\proj\\other.dart', 'library other;');
addSource('\\proj\\foo\\bar.dart', 'library bar;');
addSource('\\blat.dart', 'library blat;');
@@ -626,7 +626,7 @@
}
test_part_file() async {
- testFile = '\\proj\\completion.dart';
+ testFile = convertPath('\\proj\\completion.dart');
addSource('\\proj\\other.dart', 'library other;');
addSource('\\proj\\foo\\bar.dart', 'library bar;');
addSource('\\blat.dart', 'library blat;');
@@ -643,7 +643,7 @@
}
test_part_file2() async {
- testFile = '\\proj\\completion.dart';
+ testFile = convertPath('\\proj\\completion.dart');
addSource('\\proj\\other.dart', 'library other;');
addSource('\\proj\\foo\\bar.dart', 'library bar;');
addSource('\\blat.dart', 'library blat;');
@@ -660,7 +660,7 @@
}
test_part_file_child() async {
- testFile = '\\proj\\completion.dart';
+ testFile = convertPath('\\proj\\completion.dart');
addSource('\\proj\\other.dart', 'library other;');
addSource('\\proj\\foo\\bar.dart', 'library bar;');
addSource('\\blat.dart', 'library blat;');
@@ -677,7 +677,7 @@
}
test_part_file_parent() async {
- testFile = '\\proj\\completion.dart';
+ testFile = convertPath('\\proj\\completion.dart');
addSource('\\proj\\other.dart', 'library other;');
addSource('\\proj\\foo\\bar.dart', 'library bar;');
addSource('\\blat.dart', 'library blat;');
diff --git a/pkg/analysis_server/test/services/completion/postfix/postfix_completion_test.dart b/pkg/analysis_server/test/services/completion/postfix/postfix_completion_test.dart
index e72c2e8..1fa242e 100644
--- a/pkg/analysis_server/test/services/completion/postfix/postfix_completion_test.dart
+++ b/pkg/analysis_server/test/services/completion/postfix/postfix_completion_test.dart
@@ -79,15 +79,7 @@
verifyNoTestUnitErrors = false;
await resolveTestUnit(code);
- PostfixCompletionContext context = new PostfixCompletionContext(
- testFile,
- testAnalysisResult.lineInfo,
- offset,
- key,
- testAnalysisResult.driver,
- testUnit,
- testUnitElement,
- testAnalysisResult.errors);
+ var context = new PostfixCompletionContext(testAnalysisResult, offset, key);
processor = new PostfixCompletionProcessor(context);
}
}
diff --git a/pkg/analysis_server/test/services/completion/statement/statement_completion_test.dart b/pkg/analysis_server/test/services/completion/statement/statement_completion_test.dart
index 9ef3195..3fb9792 100644
--- a/pkg/analysis_server/test/services/completion/statement/statement_completion_test.dart
+++ b/pkg/analysis_server/test/services/completion/statement/statement_completion_test.dart
@@ -4,7 +4,7 @@
import 'package:analysis_server/src/protocol_server.dart';
import 'package:analysis_server/src/services/completion/statement/statement_completion.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -63,14 +63,8 @@
_computeCompletion(int offset) async {
driver.changeFile(testFile);
- AnalysisResult result = await driver.getResult(testFile);
- StatementCompletionContext context = new StatementCompletionContext(
- testFile,
- result.lineInfo,
- offset,
- testUnit,
- testUnitElement,
- result.errors);
+ ResolvedUnitResult result = await session.getResolvedUnit(testFile);
+ var context = new StatementCompletionContext(result, offset);
StatementCompletionProcessor processor =
new StatementCompletionProcessor(context);
StatementCompletion completion = await processor.compute();
diff --git a/pkg/analysis_server/test/services/correction/assist_test.dart b/pkg/analysis_server/test/services/correction/assist_test.dart
deleted file mode 100644
index b9e542f..0000000
--- a/pkg/analysis_server/test/services/correction/assist_test.dart
+++ /dev/null
@@ -1,6875 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:analysis_server/plugin/edit/assist/assist_core.dart';
-import 'package:analysis_server/plugin/edit/assist/assist_dart.dart';
-import 'package:analysis_server/src/services/correction/assist.dart';
-import 'package:analysis_server/src/services/correction/assist_internal.dart';
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/standard_resolution_map.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
-import 'package:analyzer_plugin/utilities/assist/assist.dart';
-import 'package:plugin/manager.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../../abstract_single_unit.dart';
-
-main() {
- defineReflectiveSuite(() {
- defineReflectiveTests(AssistProcessorTest);
- });
-}
-
-@reflectiveTest
-class AssistProcessorTest extends AbstractSingleUnitTest {
- int offset;
- int length;
-
- Assist assist;
- SourceChange change;
- String resultCode;
- LinkedEditGroup linkedPositionGroup;
-
- bool get omitNew => true;
-
- /**
- * Asserts that there is an [Assist] of the given [kind] at [offset] which
- * produces the [expected] code when applied to [testCode].
- */
- assertHasAssist(AssistKind kind, String expected) async {
- assist = await _assertHasAssist(kind);
- change = assist.change;
- expect(change.id, kind.id);
- // apply to "file"
- List<SourceFileEdit> fileEdits = change.edits;
- expect(fileEdits, hasLength(1));
- resultCode = SourceEdit.applySequence(testCode, change.edits[0].edits);
- // verify
- expect(resultCode, expected);
- }
-
- /**
- * Calls [assertHasAssist] at the offset of [offsetSearch] in [testCode].
- */
- assertHasAssistAt(
- String offsetSearch, AssistKind kind, String expected) async {
- offset = findOffset(offsetSearch);
- await assertHasAssist(kind, expected);
- }
-
- /**
- * Asserts that there is no [Assist] of the given [kind] at [offset].
- */
- assertNoAssist(AssistKind kind) async {
- List<Assist> assists = await _computeAssists();
- for (Assist assist in assists) {
- if (assist.kind == kind) {
- fail('Unexpected assist $kind in\n${assists.join('\n')}');
- }
- }
- }
-
- /**
- * Calls [assertNoAssist] at the offset of [offsetSearch] in [testCode].
- */
- assertNoAssistAt(String offsetSearch, AssistKind kind) async {
- offset = findOffset(offsetSearch);
- await assertNoAssist(kind);
- }
-
- List<LinkedEditSuggestion> expectedSuggestions(
- LinkedEditSuggestionKind kind, List<String> values) {
- return values.map((value) {
- return new LinkedEditSuggestion(value, kind);
- }).toList();
- }
-
- void processRequiredPlugins() {
- ExtensionManager manager = new ExtensionManager();
- manager.processPlugins(AnalysisEngine.instance.requiredPlugins);
- }
-
- void setUp() {
- super.setUp();
- offset = 0;
- length = 0;
- }
-
- test_addTypeAnnotation_BAD_privateType_closureParameter() async {
- addSource('/project/my_lib.dart', '''
-library my_lib;
-class A {}
-class _B extends A {}
-foo(f(_B p)) {}
-''');
- await resolveTestUnit('''
-import 'my_lib.dart';
-main() {
- foo((test) {});
-}
- ''');
- await assertNoAssistAt('test)', DartAssistKind.ADD_TYPE_ANNOTATION);
- }
-
- test_addTypeAnnotation_BAD_privateType_declaredIdentifier() async {
- addSource('/project/my_lib.dart', '''
-library my_lib;
-class A {}
-class _B extends A {}
-List<_B> getValues() => [];
-''');
- await resolveTestUnit('''
-import 'my_lib.dart';
-class A<T> {
- main() {
- for (var item in getValues()) {
- }
- }
-}
-''');
- await assertNoAssistAt('var item', DartAssistKind.ADD_TYPE_ANNOTATION);
- }
-
- test_addTypeAnnotation_BAD_privateType_list() async {
- // This is now failing because we're suggesting "List" rather than nothing.
- // Is it really better to produce nothing?
- addSource('/project/my_lib.dart', '''
-library my_lib;
-class A {}
-class _B extends A {}
-List<_B> getValues() => [];
-''');
- await resolveTestUnit('''
-import 'my_lib.dart';
-main() {
- var v = getValues();
-}
-''');
- await assertHasAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION, '''
-import 'my_lib.dart';
-main() {
- List v = getValues();
-}
-''');
- }
-
- test_addTypeAnnotation_BAD_privateType_variable() async {
- addSource('/project/my_lib.dart', '''
-library my_lib;
-class A {}
-class _B extends A {}
-_B getValue() => new _B();
-''');
- await resolveTestUnit('''
-import 'my_lib.dart';
-main() {
- var v = getValue();
-}
-''');
- await assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION);
- }
-
- test_addTypeAnnotation_classField_OK_final() async {
- await resolveTestUnit('''
-class A {
- final f = 0;
-}
-''');
- await assertHasAssistAt('final ', DartAssistKind.ADD_TYPE_ANNOTATION, '''
-class A {
- final int f = 0;
-}
-''');
- }
-
- test_addTypeAnnotation_classField_OK_int() async {
- await resolveTestUnit('''
-class A {
- var f = 0;
-}
-''');
- await await assertHasAssistAt(
- 'var ', DartAssistKind.ADD_TYPE_ANNOTATION, '''
-class A {
- int f = 0;
-}
-''');
- }
-
- test_addTypeAnnotation_declaredIdentifier_BAD_hasTypeAnnotation() async {
- await resolveTestUnit('''
-main(List<String> items) {
- for (String item in items) {
- }
-}
-''');
- await assertNoAssistAt('item in', DartAssistKind.ADD_TYPE_ANNOTATION);
- }
-
- test_addTypeAnnotation_declaredIdentifier_BAD_inForEachBody() async {
- await resolveTestUnit('''
-main(List<String> items) {
- for (var item in items) {
- 42;
- }
-}
-''');
- await assertNoAssistAt('42;', DartAssistKind.ADD_TYPE_ANNOTATION);
- }
-
- test_addTypeAnnotation_declaredIdentifier_BAD_unknownType() async {
- verifyNoTestUnitErrors = false;
- await resolveTestUnit('''
-main() {
- for (var item in unknownList) {
- }
-}
-''');
- await assertNoAssistAt('item in', DartAssistKind.ADD_TYPE_ANNOTATION);
- }
-
- test_addTypeAnnotation_declaredIdentifier_generic_OK() async {
- await resolveTestUnit('''
-class A<T> {
- main(List<List<T>> items) {
- for (var item in items) {
- }
- }
-}
-''');
- await assertHasAssistAt('item in', DartAssistKind.ADD_TYPE_ANNOTATION, '''
-class A<T> {
- main(List<List<T>> items) {
- for (List<T> item in items) {
- }
- }
-}
-''');
- }
-
- test_addTypeAnnotation_declaredIdentifier_OK() async {
- await resolveTestUnit('''
-main(List<String> items) {
- for (var item in items) {
- }
-}
-''');
- // on identifier
- await assertHasAssistAt('item in', DartAssistKind.ADD_TYPE_ANNOTATION, '''
-main(List<String> items) {
- for (String item in items) {
- }
-}
-''');
- // on "for"
- await assertHasAssistAt('for (', DartAssistKind.ADD_TYPE_ANNOTATION, '''
-main(List<String> items) {
- for (String item in items) {
- }
-}
-''');
- }
-
- test_addTypeAnnotation_declaredIdentifier_OK_addImport_dartUri() async {
- addSource('/project/my_lib.dart', r'''
-import 'dart:async';
-List<Future<int>> getFutures() => null;
-''');
- await resolveTestUnit('''
-import 'my_lib.dart';
-main() {
- for (var future in getFutures()) {
- }
-}
-''');
- await assertHasAssistAt('future in', DartAssistKind.ADD_TYPE_ANNOTATION, '''
-import 'dart:async';
-
-import 'my_lib.dart';
-main() {
- for (Future<int> future in getFutures()) {
- }
-}
-''');
- }
-
- test_addTypeAnnotation_declaredIdentifier_OK_final() async {
- await resolveTestUnit('''
-main(List<String> items) {
- for (final item in items) {
- }
-}
-''');
- await assertHasAssistAt('item in', DartAssistKind.ADD_TYPE_ANNOTATION, '''
-main(List<String> items) {
- for (final String item in items) {
- }
-}
-''');
- }
-
- test_addTypeAnnotation_local_BAD_bottom() async {
- await resolveTestUnit('''
-main() {
- var v = throw 42;
-}
-''');
- await assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION);
- }
-
- test_addTypeAnnotation_local_BAD_hasTypeAnnotation() async {
- await resolveTestUnit('''
-main() {
- int v = 42;
-}
-''');
- await assertNoAssistAt(' = 42', DartAssistKind.ADD_TYPE_ANNOTATION);
- }
-
- test_addTypeAnnotation_local_BAD_multiple() async {
- await resolveTestUnit('''
-main() {
- var a = 1, b = '';
-}
-''');
- await assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION);
- }
-
- test_addTypeAnnotation_local_BAD_noValue() async {
- verifyNoTestUnitErrors = false;
- await resolveTestUnit('''
-main() {
- var v;
-}
-''');
- await assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION);
- }
-
- test_addTypeAnnotation_local_BAD_null() async {
- await resolveTestUnit('''
-main() {
- var v = null;
-}
-''');
- await assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION);
- }
-
- test_addTypeAnnotation_local_BAD_onInitializer() async {
- await resolveTestUnit('''
-main() {
- var abc = 0;
-}
-''');
- await assertNoAssistAt('0;', DartAssistKind.ADD_TYPE_ANNOTATION);
- }
-
- test_addTypeAnnotation_local_BAD_unknown() async {
- verifyNoTestUnitErrors = false;
- await resolveTestUnit('''
-main() {
- var v = unknownVar;
-}
-''');
- await assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION);
- }
-
- test_addTypeAnnotation_local_generic_OK_literal() async {
- await resolveTestUnit('''
-class A {
- main(List<int> items) {
- var v = items;
- }
-}
-''');
- await assertHasAssistAt('v =', DartAssistKind.ADD_TYPE_ANNOTATION, '''
-class A {
- main(List<int> items) {
- List<int> v = items;
- }
-}
-''');
- }
-
- test_addTypeAnnotation_local_generic_OK_local() async {
- await resolveTestUnit('''
-class A<T> {
- main(List<T> items) {
- var v = items;
- }
-}
-''');
- await assertHasAssistAt('v =', DartAssistKind.ADD_TYPE_ANNOTATION, '''
-class A<T> {
- main(List<T> items) {
- List<T> v = items;
- }
-}
-''');
- }
-
- test_addTypeAnnotation_local_OK_addImport_dartUri() async {
- addSource('/project/my_lib.dart', r'''
-import 'dart:async';
-Future<int> getFutureInt() => null;
-''');
- await resolveTestUnit('''
-import 'my_lib.dart';
-main() {
- var v = getFutureInt();
-}
-''');
- await assertHasAssistAt('v =', DartAssistKind.ADD_TYPE_ANNOTATION, '''
-import 'dart:async';
-
-import 'my_lib.dart';
-main() {
- Future<int> v = getFutureInt();
-}
-''');
- }
-
- test_addTypeAnnotation_local_OK_addImport_notLibraryUnit() async {
- // prepare library
- addSource('/project/my_lib.dart', r'''
-import 'dart:async';
-Future<int> getFutureInt() => null;
-''');
- // prepare code
- String appCode = r'''
-library my_app;
-import 'my_lib.dart';
-part 'test.dart';
-''';
- testCode = r'''
-part of my_app;
-main() {
- var v = getFutureInt();
-}
-''';
- // add sources
- addSource('/project/app.dart', appCode);
- testSource = addSource('/project/test.dart', testCode);
- // resolve
- await resolveTestUnit(testCode);
- // prepare the assist
- offset = findOffset('v = ');
- assist = await _assertHasAssist(DartAssistKind.ADD_TYPE_ANNOTATION);
- change = assist.change;
- // verify
- {
- var testFileEdit = change.getFileEdit(convertPath('/project/app.dart'));
- var resultCode = SourceEdit.applySequence(appCode, testFileEdit.edits);
- expect(resultCode, '''
-library my_app;
-import 'dart:async';
-
-import 'my_lib.dart';
-part 'test.dart';
-''');
- }
- {
- var testFileEdit = change.getFileEdit(convertPath('/project/test.dart'));
- var resultCode = SourceEdit.applySequence(testCode, testFileEdit.edits);
- expect(resultCode, '''
-part of my_app;
-main() {
- Future<int> v = getFutureInt();
-}
-''');
- }
- }
-
- test_addTypeAnnotation_local_OK_addImport_relUri() async {
- addSource('/project/aa/bbb/lib_a.dart', r'''
-class MyClass {}
-''');
- addSource('/project/ccc/lib_b.dart', r'''
-import '../aa/bbb/lib_a.dart';
-MyClass newMyClass() => null;
-''');
- await resolveTestUnit('''
-import 'ccc/lib_b.dart';
-main() {
- var v = newMyClass();
-}
-''');
- await assertHasAssistAt('v =', DartAssistKind.ADD_TYPE_ANNOTATION, '''
-import 'aa/bbb/lib_a.dart';
-import 'ccc/lib_b.dart';
-main() {
- MyClass v = newMyClass();
-}
-''');
- }
-
- test_addTypeAnnotation_local_OK_Function() async {
- await resolveTestUnit('''
-main() {
- var v = () => 1;
-}
-''');
- await assertHasAssistAt('v =', DartAssistKind.ADD_TYPE_ANNOTATION, '''
-main() {
- int Function() v = () => 1;
-}
-''');
- }
-
- test_addTypeAnnotation_local_OK_int() async {
- await resolveTestUnit('''
-main() {
- var v = 0;
-}
-''');
- await assertHasAssistAt('v =', DartAssistKind.ADD_TYPE_ANNOTATION, '''
-main() {
- int v = 0;
-}
-''');
- }
-
- test_addTypeAnnotation_local_OK_List() async {
- await resolveTestUnit('''
-main() {
- var v = <String>[];
-}
-''');
- await assertHasAssistAt('v =', DartAssistKind.ADD_TYPE_ANNOTATION, '''
-main() {
- List<String> v = <String>[];
-}
-''');
- }
-
- test_addTypeAnnotation_local_OK_localType() async {
- await resolveTestUnit('''
-class C {}
-C f() => null;
-main() {
- var x = f();
-}
-''');
- await assertHasAssistAt('x =', DartAssistKind.ADD_TYPE_ANNOTATION, '''
-class C {}
-C f() => null;
-main() {
- C x = f();
-}
-''');
- }
-
- test_addTypeAnnotation_local_OK_onName() async {
- await resolveTestUnit('''
-main() {
- var abc = 0;
-}
-''');
- await assertHasAssistAt('bc', DartAssistKind.ADD_TYPE_ANNOTATION, '''
-main() {
- int abc = 0;
-}
-''');
- }
-
- test_addTypeAnnotation_local_OK_onVar() async {
- await resolveTestUnit('''
-main() {
- var v = 0;
-}
-''');
- await assertHasAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION, '''
-main() {
- int v = 0;
-}
-''');
- }
-
- test_addTypeAnnotation_OK_privateType_sameLibrary() async {
- await resolveTestUnit('''
-class _A {}
-_A getValue() => new _A();
-main() {
- var v = getValue();
-}
-''');
- await assertHasAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION, '''
-class _A {}
-_A getValue() => new _A();
-main() {
- _A v = getValue();
-}
-''');
- }
-
- test_addTypeAnnotation_parameter_BAD_hasExplicitType() async {
- await resolveTestUnit('''
-foo(f(int p)) {}
-main() {
- foo((num test) {});
-}
-''');
- await assertNoAssistAt('test', DartAssistKind.ADD_TYPE_ANNOTATION);
- }
-
- test_addTypeAnnotation_parameter_BAD_noPropagatedType() async {
- await resolveTestUnit('''
-foo(f(p)) {}
-main() {
- foo((test) {});
-}
-''');
- await assertNoAssistAt('test', DartAssistKind.ADD_TYPE_ANNOTATION);
- }
-
- test_addTypeAnnotation_parameter_OK() async {
- await resolveTestUnit('''
-foo(f(int p)) {}
-main() {
- foo((test) {});
-}
-''');
- await assertHasAssistAt('test', DartAssistKind.ADD_TYPE_ANNOTATION, '''
-foo(f(int p)) {}
-main() {
- foo((int test) {});
-}
-''');
- }
-
- test_addTypeAnnotation_topLevelField_BAD_multiple() async {
- await resolveTestUnit('''
-var A = 1, V = '';
-''');
- await assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION);
- }
-
- test_addTypeAnnotation_topLevelField_BAD_noValue() async {
- await resolveTestUnit('''
-var V;
-''');
- await assertNoAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION);
- }
-
- test_addTypeAnnotation_topLevelField_OK_int() async {
- await resolveTestUnit('''
-var V = 0;
-''');
- await assertHasAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION, '''
-int V = 0;
-''');
- }
-
- test_assignToLocalVariable() async {
- await resolveTestUnit('''
-main() {
- List<int> bytes;
- readBytes();
-}
-List<int> readBytes() => <int>[];
-''');
- await assertHasAssistAt(
- 'readBytes();', DartAssistKind.ASSIGN_TO_LOCAL_VARIABLE, '''
-main() {
- List<int> bytes;
- var readBytes = readBytes();
-}
-List<int> readBytes() => <int>[];
-''');
- _assertLinkedGroup(
- change.linkedEditGroups[0],
- ['readBytes = '],
- expectedSuggestions(LinkedEditSuggestionKind.VARIABLE,
- ['list', 'bytes2', 'readBytes']));
- }
-
- test_assignToLocalVariable_alreadyAssignment() async {
- await resolveTestUnit('''
-main() {
- var vvv;
- vvv = 42;
-}
-''');
- await assertNoAssistAt('vvv =', DartAssistKind.ASSIGN_TO_LOCAL_VARIABLE);
- }
-
- test_assignToLocalVariable_inClosure() async {
- await resolveTestUnit(r'''
-main() {
- print(() {
- 12345;
- });
-}
-''');
- await assertHasAssistAt('345', DartAssistKind.ASSIGN_TO_LOCAL_VARIABLE, '''
-main() {
- print(() {
- var i = 12345;
- });
-}
-''');
- }
-
- test_assignToLocalVariable_invocationArgument() async {
- await resolveTestUnit(r'''
-main() {
- f(12345);
-}
-void f(p) {}
-''');
- await assertNoAssistAt('345', DartAssistKind.ASSIGN_TO_LOCAL_VARIABLE);
- }
-
- test_assignToLocalVariable_throw() async {
- await resolveTestUnit('''
-main() {
- throw 42;
-}
-''');
- await assertNoAssistAt('throw ', DartAssistKind.ASSIGN_TO_LOCAL_VARIABLE);
- }
-
- test_assignToLocalVariable_void() async {
- await resolveTestUnit('''
-main() {
- f();
-}
-void f() {}
-''');
- await assertNoAssistAt('f();', DartAssistKind.ASSIGN_TO_LOCAL_VARIABLE);
- }
-
- test_convertClassToMixin_abstract() async {
- await resolveTestUnit('''
-abstract class A {}
-''');
- await assertHasAssistAt('A', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
-mixin A {}
-''');
- }
-
- test_convertClassToMixin_extends_noSuper() async {
- await resolveTestUnit('''
-class A {}
-class B extends A {}
-''');
- await assertHasAssistAt('B', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
-class A {}
-mixin B implements A {}
-''');
- }
-
- test_convertClassToMixin_extends_super() async {
- await resolveTestUnit('''
-class A {
- a() {}
-}
-class B extends A {
- b() {
- super.a();
- }
-}
-''');
- await assertHasAssistAt('B', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
-class A {
- a() {}
-}
-mixin B on A {
- b() {
- super.a();
- }
-}
-''');
- }
-
- test_convertClassToMixin_extends_superSuper() async {
- await resolveTestUnit('''
-class A {
- a() {}
-}
-class B extends A {}
-class C extends B {
- c() {
- super.a();
- }
-}
-''');
- await assertHasAssistAt('C', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
-class A {
- a() {}
-}
-class B extends A {}
-mixin C on B {
- c() {
- super.a();
- }
-}
-''');
- }
-
- test_convertClassToMixin_extendsImplements_noSuper() async {
- await resolveTestUnit('''
-class A {}
-class B {}
-class C extends A implements B {}
-''');
- await assertHasAssistAt('C', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
-class A {}
-class B {}
-mixin C implements A, B {}
-''');
- }
-
- test_convertClassToMixin_extendsImplements_super_extends() async {
- await resolveTestUnit('''
-class A {
- a() {}
-}
-class B {}
-class C extends A implements B {
- c() {
- super.a();
- }
-}
-''');
- await assertHasAssistAt('C', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
-class A {
- a() {}
-}
-class B {}
-mixin C on A implements B {
- c() {
- super.a();
- }
-}
-''');
- }
-
- test_convertClassToMixin_extendsWith_noSuper() async {
- await resolveTestUnit('''
-class A {}
-class B {}
-class C extends A with B {}
-''');
- await assertHasAssistAt('C', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
-class A {}
-class B {}
-mixin C implements A, B {}
-''');
- }
-
- test_convertClassToMixin_extendsWith_super_both() async {
- await resolveTestUnit('''
-class A {
- a() {}
-}
-class B {
- b() {}
-}
-class C extends A with B {
- c() {
- super.a();
- super.b();
- }
-}
-''');
- await assertHasAssistAt('C', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
-class A {
- a() {}
-}
-class B {
- b() {}
-}
-mixin C on A, B {
- c() {
- super.a();
- super.b();
- }
-}
-''');
- }
-
- test_convertClassToMixin_extendsWith_super_extends() async {
- await resolveTestUnit('''
-class A {
- a() {}
-}
-class B {
- b() {}
-}
-class C extends A with B {
- c() {
- super.a();
- }
-}
-''');
- await assertHasAssistAt('C', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
-class A {
- a() {}
-}
-class B {
- b() {}
-}
-mixin C on A implements B {
- c() {
- super.a();
- }
-}
-''');
- }
-
- test_convertClassToMixin_extendsWith_super_with() async {
- await resolveTestUnit('''
-class A {
- a() {}
-}
-class B {
- b() {}
-}
-class C extends A with B {
- c() {
- super.b();
- }
-}
-''');
- await assertHasAssistAt('C', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
-class A {
- a() {}
-}
-class B {
- b() {}
-}
-mixin C on B implements A {
- c() {
- super.b();
- }
-}
-''');
- }
-
- test_convertClassToMixin_extendsWithImplements_noSuper() async {
- await resolveTestUnit('''
-class A {}
-class B {}
-class C {}
-class D extends A with B implements C {}
-''');
- await assertHasAssistAt('D', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
-class A {}
-class B {}
-class C {}
-mixin D implements A, B, C {}
-''');
- }
-
- test_convertClassToMixin_extendsWithImplements_super_both() async {
- await resolveTestUnit('''
-class A {
- a() {}
-}
-class B {
- b() {}
-}
-class C {}
-class D extends A with B implements C {
- d() {
- super.a();
- super.b();
- }
-}
-''');
- await assertHasAssistAt('D', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
-class A {
- a() {}
-}
-class B {
- b() {}
-}
-class C {}
-mixin D on A, B implements C {
- d() {
- super.a();
- super.b();
- }
-}
-''');
- }
-
- test_convertClassToMixin_extendsWithImplements_super_extends() async {
- await resolveTestUnit('''
-class A {
- a() {}
-}
-class B {
- b() {}
-}
-class C {}
-class D extends A with B implements C {
- d() {
- super.a();
- }
-}
-''');
- await assertHasAssistAt('D', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
-class A {
- a() {}
-}
-class B {
- b() {}
-}
-class C {}
-mixin D on A implements B, C {
- d() {
- super.a();
- }
-}
-''');
- }
-
- test_convertClassToMixin_extendsWithImplements_super_with() async {
- await resolveTestUnit('''
-class A {
- a() {}
-}
-class B {
- b() {}
-}
-class C {}
-class D extends A with B implements C {
- d() {
- super.b();
- }
-}
-''');
- await assertHasAssistAt('D', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
-class A {
- a() {}
-}
-class B {
- b() {}
-}
-class C {}
-mixin D on B implements A, C {
- d() {
- super.b();
- }
-}
-''');
- }
-
- test_convertClassToMixin_implements() async {
- await resolveTestUnit('''
-class A {}
-class B implements A {}
-''');
- await assertHasAssistAt('B', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
-class A {}
-mixin B implements A {}
-''');
- }
-
- test_convertClassToMixin_noClauses_invalidSelection() async {
- await resolveTestUnit('''
-class A {}
-''');
- await assertNoAssistAt(
- '{}',
- DartAssistKind.CONVERT_CLASS_TO_MIXIN,
- );
- }
-
- test_convertClassToMixin_noClauses_selectKeyword() async {
- await resolveTestUnit('''
-class A {}
-''');
- await assertHasAssistAt('class', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
-mixin A {}
-''');
- }
-
- test_convertClassToMixin_noClauses_selectName() async {
- await resolveTestUnit('''
-class A {}
-''');
- await assertHasAssistAt('A', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
-mixin A {}
-''');
- }
-
- test_convertClassToMixin_with_noSuper() async {
- await resolveTestUnit('''
-class A {}
-class B with A {}
-''');
- await assertHasAssistAt('B', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
-class A {}
-mixin B implements A {}
-''');
- }
-
- test_convertClassToMixin_with_super() async {
- await resolveTestUnit('''
-class A {
- a() {}
-}
-class B with A {
- b() {
- super.a();
- }
-}
-''');
- await assertHasAssistAt('B', DartAssistKind.CONVERT_CLASS_TO_MIXIN, '''
-class A {
- a() {}
-}
-mixin B on A {
- b() {
- super.a();
- }
-}
-''');
- }
-
- test_convertDocumentationIntoBlock_BAD_alreadyBlock() async {
- await resolveTestUnit('''
-/**
- * AAAAAAA
- */
-class A {}
-''');
- await assertNoAssistAt(
- 'AAA', DartAssistKind.CONVERT_DOCUMENTATION_INTO_BLOCK);
- }
-
- test_convertDocumentationIntoBlock_BAD_notDocumentation() async {
- await resolveTestUnit('''
-// AAAA
-class A {}
-''');
- await assertNoAssistAt(
- 'AAA', DartAssistKind.CONVERT_DOCUMENTATION_INTO_BLOCK);
- }
-
- test_convertDocumentationIntoBlock_OK_noSpaceBeforeText() async {
- await resolveTestUnit('''
-class A {
- /// AAAAA
- ///BBBBB
- ///
- /// CCCCC
- mmm() {}
-}
-''');
- await assertHasAssistAt(
- 'AAAAA', DartAssistKind.CONVERT_DOCUMENTATION_INTO_BLOCK, '''
-class A {
- /**
- * AAAAA
- *BBBBB
- *
- * CCCCC
- */
- mmm() {}
-}
-''');
- }
-
- test_convertDocumentationIntoBlock_OK_onReference() async {
- await resolveTestUnit('''
-/// AAAAAAA [int] AAAAAAA
-class A {}
-''');
- await assertHasAssistAt(
- 'nt]', DartAssistKind.CONVERT_DOCUMENTATION_INTO_BLOCK, '''
-/**
- * AAAAAAA [int] AAAAAAA
- */
-class A {}
-''');
- }
-
- test_convertDocumentationIntoBlock_OK_onText() async {
- await resolveTestUnit('''
-class A {
- /// AAAAAAA [int] AAAAAAA
- /// BBBBBBBB BBBB BBBB
- /// CCC [A] CCCCCCCCCCC
- mmm() {}
-}
-''');
- await assertHasAssistAt(
- 'AAA [', DartAssistKind.CONVERT_DOCUMENTATION_INTO_BLOCK, '''
-class A {
- /**
- * AAAAAAA [int] AAAAAAA
- * BBBBBBBB BBBB BBBB
- * CCC [A] CCCCCCCCCCC
- */
- mmm() {}
-}
-''');
- }
-
- test_convertDocumentationIntoLine_BAD_alreadyLine() async {
- await resolveTestUnit('''
-/// AAAAAAA
-class A {}
-''');
- await assertNoAssistAt(
- 'AAA', DartAssistKind.CONVERT_DOCUMENTATION_INTO_LINE);
- }
-
- test_convertDocumentationIntoLine_BAD_notDocumentation() async {
- await resolveTestUnit('''
-/* AAAA */
-class A {}
-''');
- await assertNoAssistAt(
- 'AAA', DartAssistKind.CONVERT_DOCUMENTATION_INTO_LINE);
- }
-
- test_convertDocumentationIntoLine_OK_onReference() async {
- await resolveTestUnit('''
-/**
- * AAAAAAA [int] AAAAAAA
- */
-class A {}
-''');
- await assertHasAssistAt(
- 'nt]', DartAssistKind.CONVERT_DOCUMENTATION_INTO_LINE, '''
-/// AAAAAAA [int] AAAAAAA
-class A {}
-''');
- }
-
- test_convertDocumentationIntoLine_OK_onText() async {
- await resolveTestUnit('''
-class A {
- /**
- * AAAAAAA [int] AAAAAAA
- * BBBBBBBB BBBB BBBB
- * CCC [A] CCCCCCCCCCC
- */
- mmm() {}
-}
-''');
- await assertHasAssistAt(
- 'AAA [', DartAssistKind.CONVERT_DOCUMENTATION_INTO_LINE, '''
-class A {
- /// AAAAAAA [int] AAAAAAA
- /// BBBBBBBB BBBB BBBB
- /// CCC [A] CCCCCCCCCCC
- mmm() {}
-}
-''');
- }
-
- test_convertDocumentationIntoLine_OK_onText_hasFirstLine() async {
- await resolveTestUnit('''
-class A {
- /** AAAAAAA [int] AAAAAAA
- * BBBBBBBB BBBB BBBB
- * CCC [A] CCCCCCCCCCC
- */
- mmm() {}
-}
-''');
- await assertHasAssistAt(
- 'AAA [', DartAssistKind.CONVERT_DOCUMENTATION_INTO_LINE, '''
-class A {
- /// AAAAAAA [int] AAAAAAA
- /// BBBBBBBB BBBB BBBB
- /// CCC [A] CCCCCCCCCCC
- mmm() {}
-}
-''');
- }
-
- test_convertPartOfToUri_file_nonSibling() async {
- addSource('/pkg/lib/foo.dart', '''
-library foo;
-part 'src/bar.dart';
-''');
- testFile = resourceProvider.convertPath('/pkg/lib/src/bar.dart');
- await resolveTestUnit('''
-part of foo;
-''');
- await assertHasAssistAt('foo', DartAssistKind.CONVERT_PART_OF_TO_URI, '''
-part of '../foo.dart';
-''');
- }
-
- test_convertPartOfToUri_file_sibling() async {
- addSource('/pkg/foo.dart', '''
-library foo;
-part 'bar.dart';
-''');
- testFile = resourceProvider.convertPath('/pkg/bar.dart');
- await resolveTestUnit('''
-part of foo;
-''');
- await assertHasAssistAt('foo', DartAssistKind.CONVERT_PART_OF_TO_URI, '''
-part of 'foo.dart';
-''');
- }
-
- test_convertToAsyncBody_BAD_async() async {
- await resolveTestUnit('''
-import 'dart:async';
-Future<String> f() async => '';
-''');
- await assertNoAssistAt('=>', DartAssistKind.CONVERT_INTO_ASYNC_BODY);
- }
-
- test_convertToAsyncBody_BAD_asyncStar() async {
- await resolveTestUnit('''
-import 'dart:async';
-Stream<String> f() async* {}
-''');
- await assertNoAssistAt('{}', DartAssistKind.CONVERT_INTO_ASYNC_BODY);
- }
-
- test_convertToAsyncBody_BAD_constructor() async {
- await resolveTestUnit('''
-class C {
- C() {}
-}
-''');
- await assertNoAssistAt('{}', DartAssistKind.CONVERT_INTO_ASYNC_BODY);
- }
-
- test_convertToAsyncBody_BAD_inBody_block() async {
- await resolveTestUnit('''
-class C {
- void foo() {
- print(42);
- }
-}
-''');
- await assertNoAssistAt('print', DartAssistKind.CONVERT_INTO_ASYNC_BODY);
- }
-
- test_convertToAsyncBody_BAD_inBody_expression() async {
- await resolveTestUnit('''
-class C {
- void foo() => print(42);
-}
-''');
- await assertNoAssistAt('print', DartAssistKind.CONVERT_INTO_ASYNC_BODY);
- }
-
- test_convertToAsyncBody_BAD_syncStar() async {
- await resolveTestUnit('''
-Iterable<String> f() sync* {}
-''');
- await assertNoAssistAt('{}', DartAssistKind.CONVERT_INTO_ASYNC_BODY);
- }
-
- test_convertToAsyncBody_OK_closure() async {
- await resolveTestUnit('''
-main() {
- f(() => 123);
-}
-f(g) {}
-''');
- await assertHasAssistAt('=>', DartAssistKind.CONVERT_INTO_ASYNC_BODY, '''
-main() {
- f(() async => 123);
-}
-f(g) {}
-''');
- }
-
- test_convertToAsyncBody_OK_function() async {
- // TODO(brianwilkerson) Remove the "class C {}" when the bug in the builder
- // is fixed that causes the import to be incorrectly inserted when the first
- // character in the file is also being modified.
- await resolveTestUnit('''
-class C {}
-String f() => '';
-''');
- await assertHasAssistAt('=>', DartAssistKind.CONVERT_INTO_ASYNC_BODY, '''
-import 'dart:async';
-
-class C {}
-Future<String> f() async => '';
-''');
- }
-
- test_convertToAsyncBody_OK_getter_expression_noSpace() async {
- await resolveTestUnit('''
-class C {
- int get g=>0;
-}
-''');
- await assertHasAssistAt('get g', DartAssistKind.CONVERT_INTO_ASYNC_BODY, '''
-import 'dart:async';
-
-class C {
- Future<int> get g async =>0;
-}
-''');
- }
-
- test_convertToAsyncBody_OK_method() async {
- await resolveTestUnit('''
-class C {
- int m() { return 0; }
-}
-''');
- await assertHasAssistAt(
- '{ return', DartAssistKind.CONVERT_INTO_ASYNC_BODY, '''
-import 'dart:async';
-
-class C {
- Future<int> m() async { return 0; }
-}
-''');
- }
-
- test_convertToAsyncBody_OK_method_abstract() async {
- await resolveTestUnit('''
-abstract class C {
- int m();
-}
-''');
- await assertHasAssistAt('m()', DartAssistKind.CONVERT_INTO_ASYNC_BODY, '''
-import 'dart:async';
-
-abstract class C {
- Future<int> m();
-}
-''');
- }
-
- test_convertToAsyncBody_OK_method_noReturnType() async {
- await resolveTestUnit('''
-class C {
- m() { return 0; }
-}
-''');
- await assertHasAssistAt(
- '{ return', DartAssistKind.CONVERT_INTO_ASYNC_BODY, '''
-class C {
- m() async { return 0; }
-}
-''');
- }
-
- test_convertToBlockBody_BAD_inExpression() async {
- await resolveTestUnit('''
-main() => 123;
-''');
- await assertNoAssistAt('123;', DartAssistKind.CONVERT_INTO_BLOCK_BODY);
- }
-
- test_convertToBlockBody_BAD_noEnclosingFunction() async {
- await resolveTestUnit('''
-var v = 123;
-''');
- await assertNoAssistAt('v =', DartAssistKind.CONVERT_INTO_BLOCK_BODY);
- }
-
- test_convertToBlockBody_BAD_notExpressionBlock() async {
- await resolveTestUnit('''
-fff() {
- return 123;
-}
-''');
- await assertNoAssistAt('fff() {', DartAssistKind.CONVERT_INTO_BLOCK_BODY);
- }
-
- test_convertToBlockBody_OK_async() async {
- await resolveTestUnit('''
-class A {
- mmm() async => 123;
-}
-''');
- await assertHasAssistAt('mmm()', DartAssistKind.CONVERT_INTO_BLOCK_BODY, '''
-class A {
- mmm() async {
- return 123;
- }
-}
-''');
- }
-
- test_convertToBlockBody_OK_closure() async {
- await resolveTestUnit('''
-setup(x) {}
-main() {
- setup(() => 42);
-}
-''');
- await assertHasAssistAt(
- '() => 42', DartAssistKind.CONVERT_INTO_BLOCK_BODY, '''
-setup(x) {}
-main() {
- setup(() {
- return 42;
- });
-}
-''');
- {
- Position exitPos = change.selection;
- expect(exitPos, isNotNull);
- expect(exitPos.file, testFile);
- expect(exitPos.offset - 3, resultCode.indexOf('42;'));
- }
- }
-
- test_convertToBlockBody_OK_closure_voidExpression() async {
- await resolveTestUnit('''
-setup(x) {}
-main() {
- setup(() => print('done'));
-}
-''');
- await assertHasAssistAt(
- '() => print', DartAssistKind.CONVERT_INTO_BLOCK_BODY, '''
-setup(x) {}
-main() {
- setup(() {
- print('done');
- });
-}
-''');
- {
- Position exitPos = change.selection;
- expect(exitPos, isNotNull);
- expect(exitPos.file, testFile);
- expect(exitPos.offset - 3, resultCode.indexOf("');"));
- }
- }
-
- test_convertToBlockBody_OK_constructor() async {
- await resolveTestUnit('''
-class A {
- factory A() => null;
-}
-''');
- await assertHasAssistAt('A()', DartAssistKind.CONVERT_INTO_BLOCK_BODY, '''
-class A {
- factory A() {
- return null;
- }
-}
-''');
- }
-
- test_convertToBlockBody_OK_method() async {
- await resolveTestUnit('''
-class A {
- mmm() => 123;
-}
-''');
- await assertHasAssistAt('mmm()', DartAssistKind.CONVERT_INTO_BLOCK_BODY, '''
-class A {
- mmm() {
- return 123;
- }
-}
-''');
- }
-
- test_convertToBlockBody_OK_onArrow() async {
- await resolveTestUnit('''
-fff() => 123;
-''');
- await assertHasAssistAt('=>', DartAssistKind.CONVERT_INTO_BLOCK_BODY, '''
-fff() {
- return 123;
-}
-''');
- }
-
- test_convertToBlockBody_OK_onName() async {
- await resolveTestUnit('''
-fff() => 123;
-''');
- await assertHasAssistAt('fff()', DartAssistKind.CONVERT_INTO_BLOCK_BODY, '''
-fff() {
- return 123;
-}
-''');
- }
-
- test_convertToBlockBody_OK_throw() async {
- await resolveTestUnit('''
-class A {
- mmm() => throw 'error';
-}
-''');
- await assertHasAssistAt('mmm()', DartAssistKind.CONVERT_INTO_BLOCK_BODY, '''
-class A {
- mmm() {
- throw 'error';
- }
-}
-''');
- }
-
- test_convertToDoubleQuotedString_BAD_one_embeddedTarget() async {
- await resolveTestUnit('''
-main() {
- print('a"b"c');
-}
-''');
- await assertNoAssistAt(
- "'a", DartAssistKind.CONVERT_TO_DOUBLE_QUOTED_STRING);
- }
-
- test_convertToDoubleQuotedString_BAD_one_enclosingTarget() async {
- await resolveTestUnit('''
-main() {
- print("abc");
-}
-''');
- await assertNoAssistAt(
- '"ab', DartAssistKind.CONVERT_TO_DOUBLE_QUOTED_STRING);
- }
-
- test_convertToDoubleQuotedString_BAD_three_embeddedTarget() async {
- await resolveTestUnit("""
-main() {
- print('''a""\"c''');
-}
-""");
- await assertNoAssistAt(
- "'a", DartAssistKind.CONVERT_TO_DOUBLE_QUOTED_STRING);
- }
-
- test_convertToDoubleQuotedString_BAD_three_enclosingTarget() async {
- await resolveTestUnit('''
-main() {
- print("""abc""");
-}
-''');
- await assertNoAssistAt(
- '"ab', DartAssistKind.CONVERT_TO_DOUBLE_QUOTED_STRING);
- }
-
- test_convertToDoubleQuotedString_OK_one_interpolation() async {
- await resolveTestUnit(r'''
-main() {
- var b = 'b';
- var c = 'c';
- print('a $b-${c} d');
-}
-''');
- await assertHasAssistAt(
- r"'a $b", DartAssistKind.CONVERT_TO_DOUBLE_QUOTED_STRING, r'''
-main() {
- var b = 'b';
- var c = 'c';
- print("a $b-${c} d");
-}
-''');
- }
-
- test_convertToDoubleQuotedString_OK_one_raw() async {
- await resolveTestUnit('''
-main() {
- print(r'abc');
-}
-''');
- await assertHasAssistAt(
- "'ab", DartAssistKind.CONVERT_TO_DOUBLE_QUOTED_STRING, '''
-main() {
- print(r"abc");
-}
-''');
- }
-
- test_convertToDoubleQuotedString_OK_one_simple() async {
- await resolveTestUnit('''
-main() {
- print('abc');
-}
-''');
- await assertHasAssistAt(
- "'ab", DartAssistKind.CONVERT_TO_DOUBLE_QUOTED_STRING, '''
-main() {
- print("abc");
-}
-''');
- }
-
- test_convertToDoubleQuotedString_OK_three_interpolation() async {
- await resolveTestUnit(r"""
-main() {
- var b = 'b';
- var c = 'c';
- print('''a $b-${c} d''');
-}
-""");
- await assertHasAssistAt(
- r"'a $b", DartAssistKind.CONVERT_TO_DOUBLE_QUOTED_STRING, r'''
-main() {
- var b = 'b';
- var c = 'c';
- print("""a $b-${c} d""");
-}
-''');
- }
-
- test_convertToDoubleQuotedString_OK_three_raw() async {
- await resolveTestUnit("""
-main() {
- print(r'''abc''');
-}
-""");
- await assertHasAssistAt(
- "'ab", DartAssistKind.CONVERT_TO_DOUBLE_QUOTED_STRING, '''
-main() {
- print(r"""abc""");
-}
-''');
- }
-
- test_convertToDoubleQuotedString_OK_three_simple() async {
- await resolveTestUnit("""
-main() {
- print('''abc''');
-}
-""");
- await assertHasAssistAt(
- "'ab", DartAssistKind.CONVERT_TO_DOUBLE_QUOTED_STRING, '''
-main() {
- print("""abc""");
-}
-''');
- }
-
- test_convertToExpressionBody_BAD_already() async {
- await resolveTestUnit('''
-fff() => 42;
-''');
- await assertNoAssistAt(
- 'fff()', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY);
- }
-
- test_convertToExpressionBody_BAD_inExpression() async {
- await resolveTestUnit('''
-main() {
- return 42;
-}
-''');
- await assertNoAssistAt('42;', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY);
- }
-
- test_convertToExpressionBody_BAD_moreThanOneStatement() async {
- await resolveTestUnit('''
-fff() {
- var v = 42;
- return v;
-}
-''');
- await assertNoAssistAt(
- 'fff()', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY);
- }
-
- test_convertToExpressionBody_BAD_noEnclosingFunction() async {
- await resolveTestUnit('''
-var V = 42;
-''');
- await assertNoAssistAt('V = ', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY);
- }
-
- test_convertToExpressionBody_BAD_noReturn() async {
- await resolveTestUnit('''
-fff() {
- var v = 42;
-}
-''');
- await assertNoAssistAt(
- 'fff()', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY);
- }
-
- test_convertToExpressionBody_BAD_noReturnValue() async {
- await resolveTestUnit('''
-fff() {
- return;
-}
-''');
- await assertNoAssistAt(
- 'fff()', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY);
- }
-
- test_convertToExpressionBody_OK_async() async {
- await resolveTestUnit('''
-class A {
- mmm() async {
- return 42;
- }
-}
-''');
- await assertHasAssistAt(
- 'mmm', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY, '''
-class A {
- mmm() async => 42;
-}
-''');
- }
-
- test_convertToExpressionBody_OK_closure() async {
- await resolveTestUnit('''
-setup(x) {}
-main() {
- setup(() {
- return 42;
- });
-}
-''');
- await assertHasAssistAt(
- 'return', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY, '''
-setup(x) {}
-main() {
- setup(() => 42);
-}
-''');
- }
-
- test_convertToExpressionBody_OK_closure_voidExpression() async {
- await resolveTestUnit('''
-setup(x) {}
-main() {
- setup((_) {
- print('test');
- });
-}
-''');
- await assertHasAssistAt(
- '(_) {', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY, '''
-setup(x) {}
-main() {
- setup((_) => print('test'));
-}
-''');
- }
-
- test_convertToExpressionBody_OK_constructor() async {
- await resolveTestUnit('''
-class A {
- factory A() {
- return null;
- }
-}
-''');
- await assertHasAssistAt(
- 'A()', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY, '''
-class A {
- factory A() => null;
-}
-''');
- }
-
- test_convertToExpressionBody_OK_function_onBlock() async {
- await resolveTestUnit('''
-fff() {
- return 42;
-}
-''');
- await assertHasAssistAt(
- '{', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY, '''
-fff() => 42;
-''');
- }
-
- test_convertToExpressionBody_OK_function_onName() async {
- await resolveTestUnit('''
-fff() {
- return 42;
-}
-''');
- await assertHasAssistAt(
- 'ff()', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY, '''
-fff() => 42;
-''');
- }
-
- test_convertToExpressionBody_OK_method_onBlock() async {
- await resolveTestUnit('''
-class A {
- m() { // marker
- return 42;
- }
-}
-''');
- await assertHasAssistAt(
- '{ // marker', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY, '''
-class A {
- m() => 42;
-}
-''');
- }
-
- test_convertToExpressionBody_OK_topFunction_onReturnStatement() async {
- await resolveTestUnit('''
-fff() {
- return 42;
-}
-''');
- await assertHasAssistAt(
- 'return', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY, '''
-fff() => 42;
-''');
- }
-
- test_convertToFieldParameter_BAD_additionalUse() async {
- await resolveTestUnit('''
-class A {
- int aaa2;
- int bbb2;
- A(int aaa) : aaa2 = aaa, bbb2 = aaa;
-}
-''');
- await assertNoAssistAt('aaa)', DartAssistKind.CONVERT_TO_FIELD_PARAMETER);
- }
-
- test_convertToFieldParameter_BAD_notPureAssignment() async {
- await resolveTestUnit('''
-class A {
- int aaa2;
- A(int aaa) : aaa2 = aaa * 2;
-}
-''');
- await assertNoAssistAt('aaa)', DartAssistKind.CONVERT_TO_FIELD_PARAMETER);
- }
-
- test_convertToFieldParameter_OK_firstInitializer() async {
- await resolveTestUnit('''
-class A {
- int aaa2;
- int bbb2;
- A(int aaa, int bbb) : aaa2 = aaa, bbb2 = bbb;
-}
-''');
- await assertHasAssistAt(
- 'aaa, ', DartAssistKind.CONVERT_TO_FIELD_PARAMETER, '''
-class A {
- int aaa2;
- int bbb2;
- A(this.aaa2, int bbb) : bbb2 = bbb;
-}
-''');
- }
-
- test_convertToFieldParameter_OK_onParameterName_inInitializer() async {
- await resolveTestUnit('''
-class A {
- int test2;
- A(int test) : test2 = test {
- }
-}
-''');
- await assertHasAssistAt(
- 'test {', DartAssistKind.CONVERT_TO_FIELD_PARAMETER, '''
-class A {
- int test2;
- A(this.test2) {
- }
-}
-''');
- }
-
- test_convertToFieldParameter_OK_onParameterName_inParameters() async {
- await resolveTestUnit('''
-class A {
- int test;
- A(int test) : test = test {
- }
-}
-''');
- await assertHasAssistAt(
- 'test)', DartAssistKind.CONVERT_TO_FIELD_PARAMETER, '''
-class A {
- int test;
- A(this.test) {
- }
-}
-''');
- }
-
- test_convertToFieldParameter_OK_secondInitializer() async {
- await resolveTestUnit('''
-class A {
- int aaa2;
- int bbb2;
- A(int aaa, int bbb) : aaa2 = aaa, bbb2 = bbb;
-}
-''');
- await assertHasAssistAt(
- 'bbb)', DartAssistKind.CONVERT_TO_FIELD_PARAMETER, '''
-class A {
- int aaa2;
- int bbb2;
- A(int aaa, this.bbb2) : aaa2 = aaa;
-}
-''');
- }
-
- test_convertToFinalField_BAD_hasSetter_inThisClass() async {
- await resolveTestUnit('''
-class A {
- int get foo => null;
- void set foo(_) {}
-}
-''');
- await assertNoAssistAt('get foo', DartAssistKind.CONVERT_INTO_FINAL_FIELD);
- }
-
- test_convertToFinalField_BAD_notExpressionBody() async {
- await resolveTestUnit('''
-class A {
- int get foo {
- int v = 1 + 2;
- return v + 3;
- }
-}
-''');
- await assertNoAssistAt('get foo', DartAssistKind.CONVERT_INTO_FINAL_FIELD);
- }
-
- test_convertToFinalField_BAD_notGetter() async {
- await resolveTestUnit('''
-class A {
- int foo() => 42;
-}
-''');
- await assertNoAssistAt('foo', DartAssistKind.CONVERT_INTO_FINAL_FIELD);
- }
-
- test_convertToFinalField_OK_blockBody_onlyReturnStatement() async {
- await resolveTestUnit('''
-class A {
- int get foo {
- return 1 + 2;
- }
-}
-''');
- await assertHasAssistAt(
- 'get foo', DartAssistKind.CONVERT_INTO_FINAL_FIELD, '''
-class A {
- final int foo = 1 + 2;
-}
-''');
- }
-
- test_convertToFinalField_OK_hasOverride() async {
- await resolveTestUnit('''
-const myAnnotation = const Object();
-class A {
- @myAnnotation
- int get foo => 42;
-}
-''');
- await assertHasAssistAt(
- 'get foo', DartAssistKind.CONVERT_INTO_FINAL_FIELD, '''
-const myAnnotation = const Object();
-class A {
- @myAnnotation
- final int foo = 42;
-}
-''');
- }
-
- test_convertToFinalField_OK_hasSetter_inSuper() async {
- await resolveTestUnit('''
-class A {
- void set foo(_) {}
-}
-class B extends A {
- int get foo => null;
-}
-''');
- await assertHasAssistAt(
- 'get foo', DartAssistKind.CONVERT_INTO_FINAL_FIELD, '''
-class A {
- void set foo(_) {}
-}
-class B extends A {
- final int foo;
-}
-''');
- }
-
- test_convertToFinalField_OK_noReturnType() async {
- await resolveTestUnit('''
-class A {
- get foo => 42;
-}
-''');
- await assertHasAssistAt(
- 'get foo', DartAssistKind.CONVERT_INTO_FINAL_FIELD, '''
-class A {
- final foo = 42;
-}
-''');
- }
-
- test_convertToFinalField_OK_noReturnType_static() async {
- await resolveTestUnit('''
-class A {
- static get foo => 42;
-}
-''');
- await assertHasAssistAt(
- 'get foo', DartAssistKind.CONVERT_INTO_FINAL_FIELD, '''
-class A {
- static final foo = 42;
-}
-''');
- }
-
- test_convertToFinalField_OK_notNull() async {
- await resolveTestUnit('''
-class A {
- int get foo => 1 + 2;
-}
-''');
- await assertHasAssistAt(
- 'get foo', DartAssistKind.CONVERT_INTO_FINAL_FIELD, '''
-class A {
- final int foo = 1 + 2;
-}
-''');
- }
-
- test_convertToFinalField_OK_null() async {
- await resolveTestUnit('''
-class A {
- int get foo => null;
-}
-''');
- await assertHasAssistAt(
- 'get foo', DartAssistKind.CONVERT_INTO_FINAL_FIELD, '''
-class A {
- final int foo;
-}
-''');
- }
-
- test_convertToFinalField_OK_onName() async {
- await resolveTestUnit('''
-class A {
- int get foo => 42;
-}
-''');
- await assertHasAssistAt('foo', DartAssistKind.CONVERT_INTO_FINAL_FIELD, '''
-class A {
- final int foo = 42;
-}
-''');
- }
-
- test_convertToFinalField_OK_onReturnType_parameterized() async {
- await resolveTestUnit('''
-class A {
- List<int> get foo => null;
-}
-''');
- await assertHasAssistAt(
- 'nt> get', DartAssistKind.CONVERT_INTO_FINAL_FIELD, '''
-class A {
- final List<int> foo;
-}
-''');
- }
-
- test_convertToFinalField_OK_onReturnType_simple() async {
- await resolveTestUnit('''
-class A {
- int get foo => 42;
-}
-''');
- await assertHasAssistAt(
- 'int get', DartAssistKind.CONVERT_INTO_FINAL_FIELD, '''
-class A {
- final int foo = 42;
-}
-''');
- }
-
- test_convertToForIndex_BAD_bodyNotBlock() async {
- await resolveTestUnit('''
-main(List<String> items) {
- for (String item in items) print(item);
-}
-''');
- await assertNoAssistAt(
- 'for (String', DartAssistKind.CONVERT_INTO_FOR_INDEX);
- }
-
- test_convertToForIndex_BAD_doesNotDeclareVariable() async {
- await resolveTestUnit('''
-main(List<String> items) {
- String item;
- for (item in items) {
- print(item);
- }
-}
-''');
- await assertNoAssistAt('for (item', DartAssistKind.CONVERT_INTO_FOR_INDEX);
- }
-
- test_convertToForIndex_BAD_iterableIsNotVariable() async {
- await resolveTestUnit('''
-main() {
- for (String item in ['a', 'b', 'c']) {
- print(item);
- }
-}
-''');
- await assertNoAssistAt(
- 'for (String', DartAssistKind.CONVERT_INTO_FOR_INDEX);
- }
-
- test_convertToForIndex_BAD_iterableNotList() async {
- await resolveTestUnit('''
-main(Iterable<String> items) {
- for (String item in items) {
- print(item);
- }
-}
-''');
- await assertNoAssistAt(
- 'for (String', DartAssistKind.CONVERT_INTO_FOR_INDEX);
- }
-
- test_convertToForIndex_BAD_usesIJK() async {
- await resolveTestUnit('''
-main(List<String> items) {
- for (String item in items) {
- print(item);
- int i, j, k;
- }
-}
-''');
- await assertNoAssistAt(
- 'for (String', DartAssistKind.CONVERT_INTO_FOR_INDEX);
- }
-
- test_convertToForIndex_OK_onDeclaredIdentifier_name() async {
- await resolveTestUnit('''
-main(List<String> items) {
- for (String item in items) {
- print(item);
- }
-}
-''');
- await assertHasAssistAt(
- 'item in', DartAssistKind.CONVERT_INTO_FOR_INDEX, '''
-main(List<String> items) {
- for (int i = 0; i < items.length; i++) {
- String item = items[i];
- print(item);
- }
-}
-''');
- }
-
- test_convertToForIndex_OK_onDeclaredIdentifier_type() async {
- await resolveTestUnit('''
-main(List<String> items) {
- for (String item in items) {
- print(item);
- }
-}
-''');
- await assertHasAssistAt(
- 'tring item', DartAssistKind.CONVERT_INTO_FOR_INDEX, '''
-main(List<String> items) {
- for (int i = 0; i < items.length; i++) {
- String item = items[i];
- print(item);
- }
-}
-''');
- }
-
- test_convertToForIndex_OK_onFor() async {
- await resolveTestUnit('''
-main(List<String> items) {
- for (String item in items) {
- print(item);
- }
-}
-''');
- await assertHasAssistAt(
- 'for (String', DartAssistKind.CONVERT_INTO_FOR_INDEX, '''
-main(List<String> items) {
- for (int i = 0; i < items.length; i++) {
- String item = items[i];
- print(item);
- }
-}
-''');
- }
-
- test_convertToForIndex_OK_usesI() async {
- await resolveTestUnit('''
-main(List<String> items) {
- for (String item in items) {
- int i = 0;
- }
-}
-''');
- await assertHasAssistAt(
- 'for (String', DartAssistKind.CONVERT_INTO_FOR_INDEX, '''
-main(List<String> items) {
- for (int j = 0; j < items.length; j++) {
- String item = items[j];
- int i = 0;
- }
-}
-''');
- }
-
- test_convertToForIndex_OK_usesIJ() async {
- await resolveTestUnit('''
-main(List<String> items) {
- for (String item in items) {
- print(item);
- int i = 0, j = 1;
- }
-}
-''');
- await assertHasAssistAt(
- 'for (String', DartAssistKind.CONVERT_INTO_FOR_INDEX, '''
-main(List<String> items) {
- for (int k = 0; k < items.length; k++) {
- String item = items[k];
- print(item);
- int i = 0, j = 1;
- }
-}
-''');
- }
-
- test_convertToFunctionSyntax_BAD_functionTypeAlias_insideParameterList() async {
- await resolveTestUnit('''
-typedef String F(int x, int y);
-''');
- await assertNoAssistAt(
- 'x,', DartAssistKind.CONVERT_INTO_GENERIC_FUNCTION_SYNTAX);
- }
-
- test_convertToFunctionSyntax_BAD_functionTypeAlias_noParameterTypes() async {
- await resolveTestUnit('''
-typedef String F(x);
-''');
- await assertNoAssistAt(
- 'def', DartAssistKind.CONVERT_INTO_GENERIC_FUNCTION_SYNTAX);
- }
-
- test_convertToFunctionSyntax_BAD_functionTypedParameter_insideParameterList() async {
- await resolveTestUnit('''
-g(String f(int x, int y)) {}
-''');
- await assertNoAssistAt(
- 'x,', DartAssistKind.CONVERT_INTO_GENERIC_FUNCTION_SYNTAX);
- }
-
- test_convertToFunctionSyntax_BAD_functionTypedParameter_noParameterTypes() async {
- await resolveTestUnit('''
-g(String f(x)) {}
-''');
- await assertNoAssistAt(
- 'f(', DartAssistKind.CONVERT_INTO_GENERIC_FUNCTION_SYNTAX);
- }
-
- test_convertToFunctionSyntax_OK_functionTypeAlias_noReturnType_noTypeParameters() async {
- await resolveTestUnit('''
-typedef String F(int x);
-''');
- await assertHasAssistAt(
- 'def', DartAssistKind.CONVERT_INTO_GENERIC_FUNCTION_SYNTAX, '''
-typedef F = String Function(int x);
-''');
- }
-
- test_convertToFunctionSyntax_OK_functionTypeAlias_noReturnType_typeParameters() async {
- await resolveTestUnit('''
-typedef F<P, R>(P x);
-''');
- await assertHasAssistAt(
- 'def', DartAssistKind.CONVERT_INTO_GENERIC_FUNCTION_SYNTAX, '''
-typedef F<P, R> = Function(P x);
-''');
- }
-
- test_convertToFunctionSyntax_OK_functionTypeAlias_returnType_noTypeParameters() async {
- await resolveTestUnit('''
-typedef String F(int x);
-''');
- await assertHasAssistAt(
- 'def', DartAssistKind.CONVERT_INTO_GENERIC_FUNCTION_SYNTAX, '''
-typedef F = String Function(int x);
-''');
- }
-
- test_convertToFunctionSyntax_OK_functionTypeAlias_returnType_typeParameters() async {
- await resolveTestUnit('''
-typedef R F<P, R>(P x);
-''');
- await assertHasAssistAt(
- 'def', DartAssistKind.CONVERT_INTO_GENERIC_FUNCTION_SYNTAX, '''
-typedef F<P, R> = R Function(P x);
-''');
- }
-
- test_convertToFunctionSyntax_OK_functionTypedParameter_noReturnType_noTypeParameters() async {
- await resolveTestUnit('''
-g(f(int x)) {}
-''');
- await assertHasAssistAt(
- 'f(', DartAssistKind.CONVERT_INTO_GENERIC_FUNCTION_SYNTAX, '''
-g(Function(int x) f) {}
-''');
- }
-
- test_convertToFunctionSyntax_OK_functionTypedParameter_returnType() async {
- await resolveTestUnit('''
-g(String f(int x)) {}
-''');
- await assertHasAssistAt(
- 'f(', DartAssistKind.CONVERT_INTO_GENERIC_FUNCTION_SYNTAX, '''
-g(String Function(int x) f) {}
-''');
- }
-
- test_convertToGetter_BAD_noInitializer() async {
- verifyNoTestUnitErrors = false;
- await resolveTestUnit('''
-class A {
- final int foo;
-}
-''');
- await assertNoAssistAt('foo', DartAssistKind.CONVERT_INTO_GETTER);
- }
-
- test_convertToGetter_BAD_notFinal() async {
- await resolveTestUnit('''
-class A {
- int foo = 1;
-}
-''');
- await assertNoAssistAt('foo', DartAssistKind.CONVERT_INTO_GETTER);
- }
-
- test_convertToGetter_BAD_notSingleField() async {
- await resolveTestUnit('''
-class A {
- final int foo = 1, bar = 2;
-}
-''');
- await assertNoAssistAt('foo', DartAssistKind.CONVERT_INTO_GETTER);
- }
-
- test_convertToGetter_OK() async {
- await resolveTestUnit('''
-const myAnnotation = const Object();
-class A {
- @myAnnotation
- final int foo = 1 + 2;
-}
-''');
- await assertHasAssistAt('foo =', DartAssistKind.CONVERT_INTO_GETTER, '''
-const myAnnotation = const Object();
-class A {
- @myAnnotation
- int get foo => 1 + 2;
-}
-''');
- }
-
- test_convertToGetter_OK_noType() async {
- await resolveTestUnit('''
-class A {
- final foo = 42;
-}
-''');
- await assertHasAssistAt('foo =', DartAssistKind.CONVERT_INTO_GETTER, '''
-class A {
- get foo => 42;
-}
-''');
- }
-
- test_convertToIntLiteral() async {
- await resolveTestUnit('''
-const double myDouble = 42.0;
-''');
- await assertHasAssistAt('42.0', DartAssistKind.CONVERT_TO_INT_LITERAL, '''
-const double myDouble = 42;
-''');
- }
-
- test_convertToIntLiteral_e() async {
- await resolveTestUnit('''
-const double myDouble = 4.2e1;
-''');
- await assertHasAssistAt('4.2e1', DartAssistKind.CONVERT_TO_INT_LITERAL, '''
-const double myDouble = 42;
-''');
- }
-
- test_convertToIntLiteral_eBig() async {
- await resolveTestUnit('''
-const double myDouble = 4.2e99999;
-''');
- await assertNoAssistAt('4.2e99999', DartAssistKind.CONVERT_TO_INT_LITERAL);
- }
-
- test_convertToIntLiteral_notDouble() async {
- await resolveTestUnit('''
-const double myDouble = 42;
-''');
- await assertNoAssistAt('42', DartAssistKind.CONVERT_TO_INT_LITERAL);
- }
-
- test_convertToIsNot_BAD_is_alreadyIsNot() async {
- await resolveTestUnit('''
-main(p) {
- p is! String;
-}
-''');
- await assertNoAssistAt('is!', DartAssistKind.CONVERT_INTO_IS_NOT);
- }
-
- test_convertToIsNot_BAD_is_noEnclosingParenthesis() async {
- await resolveTestUnit('''
-main(p) {
- p is String;
-}
-''');
- await assertNoAssistAt('is String', DartAssistKind.CONVERT_INTO_IS_NOT);
- }
-
- test_convertToIsNot_BAD_is_noPrefix() async {
- await resolveTestUnit('''
-main(p) {
- (p is String);
-}
-''');
- await assertNoAssistAt('is String', DartAssistKind.CONVERT_INTO_IS_NOT);
- }
-
- test_convertToIsNot_BAD_is_notIsExpression() async {
- await resolveTestUnit('''
-main(p) {
- 123 + 456;
-}
-''');
- await assertNoAssistAt('123 +', DartAssistKind.CONVERT_INTO_IS_NOT);
- }
-
- test_convertToIsNot_BAD_is_notTheNotOperator() async {
- verifyNoTestUnitErrors = false;
- await resolveTestUnit('''
-main(p) {
- ++(p is String);
-}
-''');
- await assertNoAssistAt('is String', DartAssistKind.CONVERT_INTO_IS_NOT);
- }
-
- test_convertToIsNot_BAD_not_alreadyIsNot() async {
- await resolveTestUnit('''
-main(p) {
- !(p is! String);
-}
-''');
- await assertNoAssistAt('!(p', DartAssistKind.CONVERT_INTO_IS_NOT);
- }
-
- test_convertToIsNot_BAD_not_noEnclosingParenthesis() async {
- await resolveTestUnit('''
-main(p) {
- !p;
-}
-''');
- await assertNoAssistAt('!p', DartAssistKind.CONVERT_INTO_IS_NOT);
- }
-
- test_convertToIsNot_BAD_not_notIsExpression() async {
- await resolveTestUnit('''
-main(p) {
- !(p == null);
-}
-''');
- await assertNoAssistAt('!(p', DartAssistKind.CONVERT_INTO_IS_NOT);
- }
-
- test_convertToIsNot_BAD_not_notTheNotOperator() async {
- verifyNoTestUnitErrors = false;
- await resolveTestUnit('''
-main(p) {
- ++(p is String);
-}
-''');
- await assertNoAssistAt('++(', DartAssistKind.CONVERT_INTO_IS_NOT);
- }
-
- test_convertToIsNot_OK_childOfIs_left() async {
- await resolveTestUnit('''
-main(p) {
- !(p is String);
-}
-''');
- await assertHasAssistAt('p is', DartAssistKind.CONVERT_INTO_IS_NOT, '''
-main(p) {
- p is! String;
-}
-''');
- }
-
- test_convertToIsNot_OK_childOfIs_right() async {
- await resolveTestUnit('''
-main(p) {
- !(p is String);
-}
-''');
- await assertHasAssistAt('String)', DartAssistKind.CONVERT_INTO_IS_NOT, '''
-main(p) {
- p is! String;
-}
-''');
- }
-
- test_convertToIsNot_OK_is() async {
- await resolveTestUnit('''
-main(p) {
- !(p is String);
-}
-''');
- await assertHasAssistAt('is String', DartAssistKind.CONVERT_INTO_IS_NOT, '''
-main(p) {
- p is! String;
-}
-''');
- }
-
- test_convertToIsNot_OK_is_higherPrecedencePrefix() async {
- await resolveTestUnit('''
-main(p) {
- !!(p is String);
-}
-''');
- await assertHasAssistAt('is String', DartAssistKind.CONVERT_INTO_IS_NOT, '''
-main(p) {
- !(p is! String);
-}
-''');
- }
-
- test_convertToIsNot_OK_is_not_higherPrecedencePrefix() async {
- await resolveTestUnit('''
-main(p) {
- !!(p is String);
-}
-''');
- await assertHasAssistAt('!(p', DartAssistKind.CONVERT_INTO_IS_NOT, '''
-main(p) {
- !(p is! String);
-}
-''');
- }
-
- test_convertToIsNot_OK_not() async {
- await resolveTestUnit('''
-main(p) {
- !(p is String);
-}
-''');
- await assertHasAssistAt('!(p', DartAssistKind.CONVERT_INTO_IS_NOT, '''
-main(p) {
- p is! String;
-}
-''');
- }
-
- test_convertToIsNot_OK_parentheses() async {
- await resolveTestUnit('''
-main(p) {
- !(p is String);
-}
-''');
- await assertHasAssistAt('(p is', DartAssistKind.CONVERT_INTO_IS_NOT, '''
-main(p) {
- p is! String;
-}
-''');
- }
-
- test_convertToIsNotEmpty_BAD_noBang() async {
- verifyNoTestUnitErrors = false;
- await resolveTestUnit('''
-main(String str) {
- ~str.isEmpty;
-}
-''');
- await assertNoAssistAt(
- 'isEmpty;', DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY);
- }
-
- test_convertToIsNotEmpty_BAD_noIsNotEmpty() async {
- await resolveTestUnit('''
-class A {
- bool get isEmpty => false;
-}
-main(A a) {
- !a.isEmpty;
-}
-''');
- await assertNoAssistAt(
- 'isEmpty;', DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY);
- }
-
- test_convertToIsNotEmpty_BAD_notInPrefixExpression() async {
- await resolveTestUnit('''
-main(String str) {
- str.isEmpty;
-}
-''');
- await assertNoAssistAt(
- 'isEmpty;', DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY);
- }
-
- test_convertToIsNotEmpty_BAD_notIsEmpty() async {
- await resolveTestUnit('''
-main(int p) {
- !p.isEven;
-}
-''');
- await assertNoAssistAt('isEven;', DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY);
- }
-
- test_convertToIsNotEmpty_OK_on_isEmpty() async {
- await resolveTestUnit('''
-main(String str) {
- !str.isEmpty;
-}
-''');
- await assertHasAssistAt(
- 'isEmpty', DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY, '''
-main(String str) {
- str.isNotEmpty;
-}
-''');
- }
-
- test_convertToIsNotEmpty_OK_on_str() async {
- await resolveTestUnit('''
-main(String str) {
- !str.isEmpty;
-}
-''');
- await assertHasAssistAt(
- 'str.', DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY, '''
-main(String str) {
- str.isNotEmpty;
-}
-''');
- }
-
- test_convertToIsNotEmpty_OK_propertyAccess() async {
- await resolveTestUnit('''
-main(String str) {
- !'text'.isEmpty;
-}
-''');
- await assertHasAssistAt(
- 'isEmpty', DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY, '''
-main(String str) {
- 'text'.isNotEmpty;
-}
-''');
- }
-
- test_convertToNormalParameter_OK_dynamic() async {
- await resolveTestUnit('''
-class A {
- var test;
- A(this.test) {
- }
-}
-''');
- await assertHasAssistAt(
- 'test)', DartAssistKind.CONVERT_TO_NORMAL_PARAMETER, '''
-class A {
- var test;
- A(test) : test = test {
- }
-}
-''');
- }
-
- test_convertToNormalParameter_OK_firstInitializer() async {
- await resolveTestUnit('''
-class A {
- int test;
- A(this.test) {
- }
-}
-''');
- await assertHasAssistAt(
- 'test)', DartAssistKind.CONVERT_TO_NORMAL_PARAMETER, '''
-class A {
- int test;
- A(int test) : test = test {
- }
-}
-''');
- }
-
- test_convertToNormalParameter_OK_secondInitializer() async {
- await resolveTestUnit('''
-class A {
- double aaa;
- int bbb;
- A(this.bbb) : aaa = 1.0;
-}
-''');
- await assertHasAssistAt(
- 'bbb)', DartAssistKind.CONVERT_TO_NORMAL_PARAMETER, '''
-class A {
- double aaa;
- int bbb;
- A(int bbb) : aaa = 1.0, bbb = bbb;
-}
-''');
- }
-
- test_convertToSingleQuotedString_BAD_one_embeddedTarget() async {
- await resolveTestUnit('''
-main() {
- print("a'b'c");
-}
-''');
- await assertNoAssistAt(
- '"a', DartAssistKind.CONVERT_TO_SINGLE_QUOTED_STRING);
- }
-
- test_convertToSingleQuotedString_BAD_one_enclosingTarget() async {
- await resolveTestUnit('''
-main() {
- print('abc');
-}
-''');
- await assertNoAssistAt(
- "'ab", DartAssistKind.CONVERT_TO_SINGLE_QUOTED_STRING);
- }
-
- test_convertToSingleQuotedString_BAD_three_embeddedTarget() async {
- await resolveTestUnit('''
-main() {
- print("""a''\'bc""");
-}
-''');
- await assertNoAssistAt(
- '"a', DartAssistKind.CONVERT_TO_SINGLE_QUOTED_STRING);
- }
-
- test_convertToSingleQuotedString_BAD_three_enclosingTarget() async {
- await resolveTestUnit("""
-main() {
- print('''abc''');
-}
-""");
- await assertNoAssistAt(
- "'ab", DartAssistKind.CONVERT_TO_SINGLE_QUOTED_STRING);
- }
-
- test_convertToSingleQuotedString_OK_one_interpolation() async {
- await resolveTestUnit(r'''
-main() {
- var b = 'b';
- var c = 'c';
- print("a $b-${c} d");
-}
-''');
- await assertHasAssistAt(
- r'"a $b', DartAssistKind.CONVERT_TO_SINGLE_QUOTED_STRING, r'''
-main() {
- var b = 'b';
- var c = 'c';
- print('a $b-${c} d');
-}
-''');
- }
-
- test_convertToSingleQuotedString_OK_one_raw() async {
- await resolveTestUnit('''
-main() {
- print(r"abc");
-}
-''');
- await assertHasAssistAt(
- '"ab', DartAssistKind.CONVERT_TO_SINGLE_QUOTED_STRING, '''
-main() {
- print(r'abc');
-}
-''');
- }
-
- test_convertToSingleQuotedString_OK_one_simple() async {
- await resolveTestUnit('''
-main() {
- print("abc");
-}
-''');
- await assertHasAssistAt(
- '"ab', DartAssistKind.CONVERT_TO_SINGLE_QUOTED_STRING, '''
-main() {
- print('abc');
-}
-''');
- }
-
- test_convertToSingleQuotedString_OK_three_interpolation() async {
- await resolveTestUnit(r'''
-main() {
- var b = 'b';
- var c = 'c';
- print("""a $b-${c} d""");
-}
-''');
- await assertHasAssistAt(
- r'"a $b', DartAssistKind.CONVERT_TO_SINGLE_QUOTED_STRING, r"""
-main() {
- var b = 'b';
- var c = 'c';
- print('''a $b-${c} d''');
-}
-""");
- }
-
- test_convertToSingleQuotedString_OK_three_raw() async {
- await resolveTestUnit('''
-main() {
- print(r"""abc""");
-}
-''');
- await assertHasAssistAt(
- '"ab', DartAssistKind.CONVERT_TO_SINGLE_QUOTED_STRING, """
-main() {
- print(r'''abc''');
-}
-""");
- }
-
- test_convertToSingleQuotedString_OK_three_simple() async {
- await resolveTestUnit('''
-main() {
- print("""abc""");
-}
-''');
- await assertHasAssistAt(
- '"ab', DartAssistKind.CONVERT_TO_SINGLE_QUOTED_STRING, """
-main() {
- print('''abc''');
-}
-""");
- }
-
- test_encapsulateField_BAD_alreadyPrivate() async {
- await resolveTestUnit('''
-class A {
- int _test = 42;
-}
-main(A a) {
- print(a._test);
-}
-''');
- await assertNoAssistAt('_test =', DartAssistKind.ENCAPSULATE_FIELD);
- }
-
- test_encapsulateField_BAD_final() async {
- await resolveTestUnit('''
-class A {
- final int test = 42;
-}
-''');
- await assertNoAssistAt('test =', DartAssistKind.ENCAPSULATE_FIELD);
- }
-
- test_encapsulateField_BAD_multipleFields() async {
- await resolveTestUnit('''
-class A {
- int aaa, bbb, ccc;
-}
-main(A a) {
- print(a.bbb);
-}
-''');
- await assertNoAssistAt('bbb, ', DartAssistKind.ENCAPSULATE_FIELD);
- }
-
- test_encapsulateField_BAD_notOnName() async {
- await resolveTestUnit('''
-class A {
- int test = 1 + 2 + 3;
-}
-''');
- await assertNoAssistAt('+ 2', DartAssistKind.ENCAPSULATE_FIELD);
- }
-
- test_encapsulateField_BAD_parseError() async {
- verifyNoTestUnitErrors = false;
- await resolveTestUnit('''
-class A {
- int; // marker
-}
-main(A a) {
- print(a.test);
-}
-''');
- await assertNoAssistAt('; // marker', DartAssistKind.ENCAPSULATE_FIELD);
- }
-
- test_encapsulateField_BAD_static() async {
- await resolveTestUnit('''
-class A {
- static int test = 42;
-}
-''');
- await assertNoAssistAt('test =', DartAssistKind.ENCAPSULATE_FIELD);
- }
-
- test_encapsulateField_OK_documentation() async {
- await resolveTestUnit('''
-class A {
- /// AAA
- /// BBB
- int test;
-}
-''');
- await assertHasAssistAt('test;', DartAssistKind.ENCAPSULATE_FIELD, '''
-class A {
- /// AAA
- /// BBB
- int _test;
-
- /// AAA
- /// BBB
- int get test => _test;
-
- /// AAA
- /// BBB
- set test(int test) {
- _test = test;
- }
-}
-''');
- }
-
- test_encapsulateField_OK_hasType() async {
- await resolveTestUnit('''
-class A {
- int test = 42;
- A(this.test);
-}
-main(A a) {
- print(a.test);
-}
-''');
- await assertHasAssistAt('test = 42', DartAssistKind.ENCAPSULATE_FIELD, '''
-class A {
- int _test = 42;
-
- int get test => _test;
-
- set test(int test) {
- _test = test;
- }
- A(this._test);
-}
-main(A a) {
- print(a.test);
-}
-''');
- }
-
- test_encapsulateField_OK_noType() async {
- await resolveTestUnit('''
-class A {
- var test = 42;
-}
-main(A a) {
- print(a.test);
-}
-''');
- await assertHasAssistAt('test = 42', DartAssistKind.ENCAPSULATE_FIELD, '''
-class A {
- var _test = 42;
-
- get test => _test;
-
- set test(test) {
- _test = test;
- }
-}
-main(A a) {
- print(a.test);
-}
-''');
- }
-
- test_exchangeBinaryExpressionArguments_BAD_extraLength() async {
- await resolveTestUnit('''
-main() {
- 111 + 222;
-}
-''');
- length = 3;
- await assertNoAssistAt('+ 222', DartAssistKind.EXCHANGE_OPERANDS);
- }
-
- test_exchangeBinaryExpressionArguments_BAD_onOperand() async {
- await resolveTestUnit('''
-main() {
- 111 + 222;
-}
-''');
- length = 3;
- await assertNoAssistAt('11 +', DartAssistKind.EXCHANGE_OPERANDS);
- }
-
- test_exchangeBinaryExpressionArguments_BAD_selectionWithBinary() async {
- await resolveTestUnit('''
-main() {
- 1 + 2 + 3;
-}
-''');
- length = '1 + 2 + 3'.length;
- await assertNoAssistAt('1 + 2 + 3', DartAssistKind.EXCHANGE_OPERANDS);
- }
-
- test_exchangeBinaryExpressionArguments_OK_compare() async {
- const initialOperators = const ['<', '<=', '>', '>='];
- const resultOperators = const ['>', '>=', '<', '<='];
- for (int i = 0; i <= 0; i++) {
- String initialOperator = initialOperators[i];
- String resultOperator = resultOperators[i];
- await resolveTestUnit('''
-bool main(int a, int b) {
- return a $initialOperator b;
-}
-''');
- await assertHasAssistAt(
- initialOperator, DartAssistKind.EXCHANGE_OPERANDS, '''
-bool main(int a, int b) {
- return b $resultOperator a;
-}
-''');
- }
- }
-
- test_exchangeBinaryExpressionArguments_OK_extended_mixOperator_1() async {
- await resolveTestUnit('''
-main() {
- 1 * 2 * 3 + 4;
-}
-''');
- await assertHasAssistAt('* 2', DartAssistKind.EXCHANGE_OPERANDS, '''
-main() {
- 2 * 3 * 1 + 4;
-}
-''');
- }
-
- test_exchangeBinaryExpressionArguments_OK_extended_mixOperator_2() async {
- await resolveTestUnit('''
-main() {
- 1 + 2 - 3 + 4;
-}
-''');
- await assertHasAssistAt('+ 2', DartAssistKind.EXCHANGE_OPERANDS, '''
-main() {
- 2 + 1 - 3 + 4;
-}
-''');
- }
-
- test_exchangeBinaryExpressionArguments_OK_extended_sameOperator_afterFirst() async {
- await resolveTestUnit('''
-main() {
- 1 + 2 + 3;
-}
-''');
- await assertHasAssistAt('+ 2', DartAssistKind.EXCHANGE_OPERANDS, '''
-main() {
- 2 + 3 + 1;
-}
-''');
- }
-
- test_exchangeBinaryExpressionArguments_OK_extended_sameOperator_afterSecond() async {
- await resolveTestUnit('''
-main() {
- 1 + 2 + 3;
-}
-''');
- await assertHasAssistAt('+ 3', DartAssistKind.EXCHANGE_OPERANDS, '''
-main() {
- 3 + 1 + 2;
-}
-''');
- }
-
- test_exchangeBinaryExpressionArguments_OK_simple_afterOperator() async {
- await resolveTestUnit('''
-main() {
- 1 + 2;
-}
-''');
- await assertHasAssistAt(' 2', DartAssistKind.EXCHANGE_OPERANDS, '''
-main() {
- 2 + 1;
-}
-''');
- }
-
- test_exchangeBinaryExpressionArguments_OK_simple_beforeOperator() async {
- await resolveTestUnit('''
-main() {
- 1 + 2;
-}
-''');
- await assertHasAssistAt('+ 2', DartAssistKind.EXCHANGE_OPERANDS, '''
-main() {
- 2 + 1;
-}
-''');
- }
-
- test_exchangeBinaryExpressionArguments_OK_simple_fullSelection() async {
- await resolveTestUnit('''
-main() {
- 1 + 2;
-}
-''');
- length = '1 + 2'.length;
- await assertHasAssistAt('1 + 2', DartAssistKind.EXCHANGE_OPERANDS, '''
-main() {
- 2 + 1;
-}
-''');
- }
-
- test_exchangeBinaryExpressionArguments_OK_simple_withLength() async {
- await resolveTestUnit('''
-main() {
- 1 + 2;
-}
-''');
- length = 2;
- await assertHasAssistAt('+ 2', DartAssistKind.EXCHANGE_OPERANDS, '''
-main() {
- 2 + 1;
-}
-''');
- }
-
- test_flutterConvertToChildren_BAD_childUnresolved() async {
- addFlutterPackage();
- verifyNoTestUnitErrors = false;
- await resolveTestUnit('''
-import 'package:flutter/material.dart';
-build() {
- return new Row(
- /*caret*/child: new Container()
- );
-}
-''');
- _setCaretLocation();
- await assertNoAssist(DartAssistKind.FLUTTER_CONVERT_TO_CHILDREN);
- }
-
- test_flutterConvertToChildren_BAD_notOnChild() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/material.dart';
-build() {
- return new Scaffold(
- body: /*caret*/new Center(
- child: new Container(),
- ),
- );
-}
-''');
- _setCaretLocation();
- await assertNoAssist(DartAssistKind.FLUTTER_CONVERT_TO_CHILDREN);
- }
-
- test_flutterConvertToChildren_OK_multiLine() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/material.dart';
-build() {
- return new Scaffold(
-// start
- body: new Center(
- /*caret*/child: new Container(
- width: 200.0,
- height: 300.0,
- ),
- key: null,
- ),
-// end
- );
-}
-''');
- _setCaretLocation();
- await assertHasAssist(DartAssistKind.FLUTTER_CONVERT_TO_CHILDREN, '''
-import 'package:flutter/material.dart';
-build() {
- return new Scaffold(
-// start
- body: new Center(
- /*caret*/children: <Widget>[
- new Container(
- width: 200.0,
- height: 300.0,
- ),
- ],
- key: null,
- ),
-// end
- );
-}
-''');
- }
-
- test_flutterConvertToChildren_OK_newlineChild() async {
- // This case could occur with deeply nested constructors, common in Flutter.
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/material.dart';
-build() {
- return new Scaffold(
-// start
- body: new Center(
- /*caret*/child:
- new Container(
- width: 200.0,
- height: 300.0,
- ),
- key: null,
- ),
-// end
- );
-}
-''');
- _setCaretLocation();
- await assertHasAssist(DartAssistKind.FLUTTER_CONVERT_TO_CHILDREN, '''
-import 'package:flutter/material.dart';
-build() {
- return new Scaffold(
-// start
- body: new Center(
- /*caret*/children: <Widget>[
- new Container(
- width: 200.0,
- height: 300.0,
- ),
- ],
- key: null,
- ),
-// end
- );
-}
-''');
- }
-
- test_flutterConvertToChildren_OK_singleLine() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/material.dart';
-build() {
- return new Scaffold(
-// start
- body: new Center(
- /*caret*/child: new GestureDetector(),
- key: null,
- ),
-// end
- );
-}
-''');
- _setCaretLocation();
- await assertHasAssist(DartAssistKind.FLUTTER_CONVERT_TO_CHILDREN, '''
-import 'package:flutter/material.dart';
-build() {
- return new Scaffold(
-// start
- body: new Center(
- /*caret*/children: <Widget>[new GestureDetector()],
- key: null,
- ),
-// end
- );
-}
-''');
- }
-
- test_flutterConvertToStatefulWidget_BAD_notClass() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/material.dart';
-/*caret*/main() {}
-''');
- _setCaretLocation();
- assertNoAssist(DartAssistKind.FLUTTER_CONVERT_TO_STATEFUL_WIDGET);
- }
-
- test_flutterConvertToStatefulWidget_BAD_notStatelessWidget() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/material.dart';
-class /*caret*/MyWidget extends Text {
- MyWidget() : super('');
-}
-''');
- _setCaretLocation();
- assertNoAssist(DartAssistKind.FLUTTER_CONVERT_TO_STATEFUL_WIDGET);
- }
-
- test_flutterConvertToStatefulWidget_BAD_notWidget() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/material.dart';
-class /*caret*/MyWidget {}
-''');
- _setCaretLocation();
- assertNoAssist(DartAssistKind.FLUTTER_CONVERT_TO_STATEFUL_WIDGET);
- }
-
- test_flutterConvertToStatefulWidget_OK() async {
- addFlutterPackage();
- await resolveTestUnit(r'''
-import 'package:flutter/material.dart';
-
-class /*caret*/MyWidget extends StatelessWidget {
- final String aaa;
- final String bbb;
-
- const MyWidget(this.aaa, this.bbb);
-
- @override
- Widget build(BuildContext context) {
- return new Row(
- children: [
- new Text(aaa),
- new Text(bbb),
- new Text('$aaa'),
- new Text('${bbb}'),
- ],
- );
- }
-}
-''');
- _setCaretLocation();
- await assertHasAssist(
- DartAssistKind.FLUTTER_CONVERT_TO_STATEFUL_WIDGET, r'''
-import 'package:flutter/material.dart';
-
-class /*caret*/MyWidget extends StatefulWidget {
- final String aaa;
- final String bbb;
-
- const MyWidget(this.aaa, this.bbb);
-
- @override
- MyWidgetState createState() {
- return new MyWidgetState();
- }
-}
-
-class MyWidgetState extends State<MyWidget> {
- @override
- Widget build(BuildContext context) {
- return new Row(
- children: [
- new Text(widget.aaa),
- new Text(widget.bbb),
- new Text('${widget.aaa}'),
- new Text('${widget.bbb}'),
- ],
- );
- }
-}
-''');
- }
-
- test_flutterConvertToStatefulWidget_OK_empty() async {
- addFlutterPackage();
- await resolveTestUnit(r'''
-import 'package:flutter/material.dart';
-
-class /*caret*/MyWidget extends StatelessWidget {
- @override
- Widget build(BuildContext context) {
- return new Container();
- }
-}
-''');
- _setCaretLocation();
- await assertHasAssist(
- DartAssistKind.FLUTTER_CONVERT_TO_STATEFUL_WIDGET, r'''
-import 'package:flutter/material.dart';
-
-class /*caret*/MyWidget extends StatefulWidget {
- @override
- MyWidgetState createState() {
- return new MyWidgetState();
- }
-}
-
-class MyWidgetState extends State<MyWidget> {
- @override
- Widget build(BuildContext context) {
- return new Container();
- }
-}
-''');
- }
-
- test_flutterConvertToStatefulWidget_OK_fields() async {
- addFlutterPackage();
- await resolveTestUnit(r'''
-import 'package:flutter/material.dart';
-
-class /*caret*/MyWidget extends StatelessWidget {
- static String staticField1;
- final String instanceField1;
- final String instanceField2;
- String instanceField3;
- static String staticField2;
- String instanceField4;
- String instanceField5;
- static String staticField3;
-
- MyWidget(this.instanceField1) : instanceField2 = '' {
- instanceField3 = '';
- }
-
- @override
- Widget build(BuildContext context) {
- instanceField4 = instanceField1;
- return new Row(
- children: [
- new Text(instanceField1),
- new Text(instanceField2),
- new Text(instanceField3),
- new Text(instanceField4),
- new Text(instanceField5),
- new Text(staticField1),
- new Text(staticField2),
- new Text(staticField3),
- ],
- );
- }
-}
-''');
- _setCaretLocation();
- await assertHasAssist(
- DartAssistKind.FLUTTER_CONVERT_TO_STATEFUL_WIDGET, r'''
-import 'package:flutter/material.dart';
-
-class /*caret*/MyWidget extends StatefulWidget {
- static String staticField1;
- final String instanceField1;
- final String instanceField2;
- String instanceField3;
- static String staticField2;
- static String staticField3;
-
- MyWidget(this.instanceField1) : instanceField2 = '' {
- instanceField3 = '';
- }
-
- @override
- MyWidgetState createState() {
- return new MyWidgetState();
- }
-}
-
-class MyWidgetState extends State<MyWidget> {
- String instanceField4;
-
- String instanceField5;
-
- @override
- Widget build(BuildContext context) {
- instanceField4 = widget.instanceField1;
- return new Row(
- children: [
- new Text(widget.instanceField1),
- new Text(widget.instanceField2),
- new Text(widget.instanceField3),
- new Text(instanceField4),
- new Text(instanceField5),
- new Text(MyWidget.staticField1),
- new Text(MyWidget.staticField2),
- new Text(MyWidget.staticField3),
- ],
- );
- }
-}
-''');
- }
-
- test_flutterConvertToStatefulWidget_OK_getters() async {
- addFlutterPackage();
- await resolveTestUnit(r'''
-import 'package:flutter/material.dart';
-
-class /*caret*/MyWidget extends StatelessWidget {
- @override
- Widget build(BuildContext context) {
- return new Row(
- children: [
- new Text(staticGetter1),
- new Text(staticGetter2),
- new Text(instanceGetter1),
- new Text(instanceGetter2),
- ],
- );
- }
-
- static String get staticGetter1 => '';
-
- String get instanceGetter1 => '';
-
- static String get staticGetter2 => '';
-
- String get instanceGetter2 => '';
-}
-''');
- _setCaretLocation();
- await assertHasAssist(
- DartAssistKind.FLUTTER_CONVERT_TO_STATEFUL_WIDGET, r'''
-import 'package:flutter/material.dart';
-
-class /*caret*/MyWidget extends StatefulWidget {
- @override
- MyWidgetState createState() {
- return new MyWidgetState();
- }
-
- static String get staticGetter1 => '';
-
- static String get staticGetter2 => '';
-}
-
-class MyWidgetState extends State<MyWidget> {
- @override
- Widget build(BuildContext context) {
- return new Row(
- children: [
- new Text(MyWidget.staticGetter1),
- new Text(MyWidget.staticGetter2),
- new Text(instanceGetter1),
- new Text(instanceGetter2),
- ],
- );
- }
-
- String get instanceGetter1 => '';
-
- String get instanceGetter2 => '';
-}
-''');
- }
-
- test_flutterConvertToStatefulWidget_OK_methods() async {
- addFlutterPackage();
- await resolveTestUnit(r'''
-import 'package:flutter/material.dart';
-
-class /*caret*/MyWidget extends StatelessWidget {
- static String staticField;
- final String instanceField1;
- String instanceField2;
-
- MyWidget(this.instanceField1);
-
- @override
- Widget build(BuildContext context) {
- return new Row(
- children: [
- new Text(instanceField1),
- new Text(instanceField2),
- new Text(staticField),
- ],
- );
- }
-
- void instanceMethod1() {
- instanceMethod1();
- instanceMethod2();
- staticMethod1();
- }
-
- static void staticMethod1() {
- print('static 1');
- }
-
- void instanceMethod2() {
- print('instance 2');
- }
-
- static void staticMethod2() {
- print('static 2');
- }
-}
-''');
- _setCaretLocation();
- await assertHasAssist(
- DartAssistKind.FLUTTER_CONVERT_TO_STATEFUL_WIDGET, r'''
-import 'package:flutter/material.dart';
-
-class /*caret*/MyWidget extends StatefulWidget {
- static String staticField;
- final String instanceField1;
-
- MyWidget(this.instanceField1);
-
- @override
- MyWidgetState createState() {
- return new MyWidgetState();
- }
-
- static void staticMethod1() {
- print('static 1');
- }
-
- static void staticMethod2() {
- print('static 2');
- }
-}
-
-class MyWidgetState extends State<MyWidget> {
- String instanceField2;
-
- @override
- Widget build(BuildContext context) {
- return new Row(
- children: [
- new Text(widget.instanceField1),
- new Text(instanceField2),
- new Text(MyWidget.staticField),
- ],
- );
- }
-
- void instanceMethod1() {
- instanceMethod1();
- instanceMethod2();
- MyWidget.staticMethod1();
- }
-
- void instanceMethod2() {
- print('instance 2');
- }
-}
-''');
- }
-
- test_flutterConvertToStatefulWidget_OK_tail() async {
- addFlutterPackage();
- await resolveTestUnit(r'''
-import 'package:flutter/material.dart';
-
-class /*caret*/MyWidget extends StatelessWidget {
- @override
- Widget build(BuildContext context) {
- return new Container();
- }
-}
-''');
- _setCaretLocation();
- await assertHasAssist(
- DartAssistKind.FLUTTER_CONVERT_TO_STATEFUL_WIDGET, r'''
-import 'package:flutter/material.dart';
-
-class /*caret*/MyWidget extends StatefulWidget {
- @override
- MyWidgetState createState() {
- return new MyWidgetState();
- }
-}
-
-class MyWidgetState extends State<MyWidget> {
- @override
- Widget build(BuildContext context) {
- return new Container();
- }
-}
-''');
- }
-
- test_flutterMoveWidgetDown_BAD_last() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/material.dart';
-main() {
- new Column(
- children: <Widget>[
- new Text('aaa'),
- new Text('bbb'),
- /*caret*/new Text('ccc'),
- ],
- );
-}
-''');
- _setCaretLocation();
- await assertNoAssist(DartAssistKind.FLUTTER_MOVE_DOWN);
- }
-
- test_flutterMoveWidgetDown_BAD_notInList() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/material.dart';
-main() {
- new Center(
- child: /*caret*/new Text('aaa'),
- );
-}
-''');
- _setCaretLocation();
- await assertNoAssist(DartAssistKind.FLUTTER_MOVE_DOWN);
- }
-
- test_flutterMoveWidgetDown_OK() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/material.dart';
-main() {
- new Column(
- children: <Widget>[
- new Text('aaa'),
- /*caret*/new Text('bbbbbb'),
- new Text('ccccccccc'),
- ],
- );
-}
-''');
- _setCaretLocation();
- await assertHasAssist(DartAssistKind.FLUTTER_MOVE_DOWN, '''
-import 'package:flutter/material.dart';
-main() {
- new Column(
- children: <Widget>[
- new Text('aaa'),
- /*caret*/new Text('ccccccccc'),
- new Text('bbbbbb'),
- ],
- );
-}
-''');
- _assertExitPosition(before: "new Text('bbbbbb')");
- }
-
- test_flutterMoveWidgetUp_BAD_first() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/material.dart';
-main() {
- new Column(
- children: <Widget>[
- /*caret*/new Text('aaa'),
- new Text('bbb'),
- new Text('ccc'),
- ],
- );
-}
-''');
- _setCaretLocation();
- await assertNoAssist(DartAssistKind.FLUTTER_MOVE_UP);
- }
-
- test_flutterMoveWidgetUp_BAD_notInList() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/material.dart';
-main() {
- new Center(
- child: /*caret*/new Text('aaa'),
- );
-}
-''');
- _setCaretLocation();
- await assertNoAssist(DartAssistKind.FLUTTER_MOVE_UP);
- }
-
- test_flutterMoveWidgetUp_OK() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/material.dart';
-main() {
- new Column(
- children: <Widget>[
- new Text('aaa'),
- /*caret*/new Text('bbbbbb'),
- new Text('ccccccccc'),
- ],
- );
-}
-''');
- _setCaretLocation();
- await assertHasAssist(DartAssistKind.FLUTTER_MOVE_UP, '''
-import 'package:flutter/material.dart';
-main() {
- new Column(
- children: <Widget>[
- new Text('bbbbbb'),
- /*caret*/new Text('aaa'),
- new Text('ccccccccc'),
- ],
- );
-}
-''');
- _assertExitPosition(before: "new Text('bbbbbb')");
- }
-
- test_flutterRemoveWidget_BAD_childrenMultipleIntoChild() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/material.dart';
-main() {
- new Center(
- child: new /*caret*/Row(
- children: [
- new Text('aaa'),
- new Text('bbb'),
- ],
- ),
- );
-}
-''');
- _setCaretLocation();
- await assertNoAssist(DartAssistKind.FLUTTER_REMOVE_WIDGET);
- }
-
- test_flutterRemoveWidget_OK_childIntoChild_multiLine() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/material.dart';
-main() {
- new Column(
- children: <Widget>[
- new Center(
- child: new /*caret*/Padding(
- padding: const EdgeInsets.all(8.0),
- child: new Center(
- heightFactor: 0.5,
- child: new Text('foo'),
- ),
- ),
- ),
- ],
- );
-}
-''');
- _setCaretLocation();
- await assertHasAssist(DartAssistKind.FLUTTER_REMOVE_WIDGET, '''
-import 'package:flutter/material.dart';
-main() {
- new Column(
- children: <Widget>[
- new Center(
- child: new Center(
- heightFactor: 0.5,
- child: new Text('foo'),
- ),
- ),
- ],
- );
-}
-''');
- }
-
- test_flutterRemoveWidget_OK_childIntoChild_singleLine() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/material.dart';
-main() {
- new Padding(
- padding: const EdgeInsets.all(8.0),
- child: new /*caret*/Center(
- heightFactor: 0.5,
- child: new Text('foo'),
- ),
- );
-}
-''');
- _setCaretLocation();
- await assertHasAssist(DartAssistKind.FLUTTER_REMOVE_WIDGET, '''
-import 'package:flutter/material.dart';
-main() {
- new Padding(
- padding: const EdgeInsets.all(8.0),
- child: new Text('foo'),
- );
-}
-''');
- }
-
- test_flutterRemoveWidget_OK_childIntoChildren() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/material.dart';
-main() {
- new Column(
- children: <Widget>[
- new Text('foo'),
- new /*caret*/Center(
- heightFactor: 0.5,
- child: new Padding(
- padding: const EdgeInsets.all(8.0),
- child: new Text('bar'),
- ),
- ),
- new Text('baz'),
- ],
- );
-}
-''');
- _setCaretLocation();
- await assertHasAssist(DartAssistKind.FLUTTER_REMOVE_WIDGET, '''
-import 'package:flutter/material.dart';
-main() {
- new Column(
- children: <Widget>[
- new Text('foo'),
- new Padding(
- padding: const EdgeInsets.all(8.0),
- child: new Text('bar'),
- ),
- new Text('baz'),
- ],
- );
-}
-''');
- }
-
- test_flutterRemoveWidget_OK_childrenOneIntoChild() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/material.dart';
-main() {
- new Center(
- child: /*caret*/new Column(
- children: [
- new Text('foo'),
- ],
- ),
- );
-}
-''');
- _setCaretLocation();
- await assertHasAssist(DartAssistKind.FLUTTER_REMOVE_WIDGET, '''
-import 'package:flutter/material.dart';
-main() {
- new Center(
- child: /*caret*/new Text('foo'),
- );
-}
-''');
- }
-
- test_flutterRemoveWidget_OK_childrenOneIntoReturn() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/material.dart';
-main() {
- return /*caret*/new Column(
- children: [
- new Text('foo'),
- ],
- );
-}
-''');
- _setCaretLocation();
- await assertHasAssist(DartAssistKind.FLUTTER_REMOVE_WIDGET, '''
-import 'package:flutter/material.dart';
-main() {
- return /*caret*/new Text('foo');
-}
-''');
- }
-
- test_flutterRemoveWidget_OK_intoChildren() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/material.dart';
-main() {
- new Column(
- children: <Widget>[
- new Text('aaa'),
- new /*caret*/Column(
- children: [
- new Row(
- children: [
- new Text('bbb'),
- new Text('ccc'),
- ],
- ),
- new Row(
- children: [
- new Text('ddd'),
- new Text('eee'),
- ],
- ),
- ],
- ),
- new Text('fff'),
- ],
- );
-}
-''');
- _setCaretLocation();
- await assertHasAssist(DartAssistKind.FLUTTER_REMOVE_WIDGET, '''
-import 'package:flutter/material.dart';
-main() {
- new Column(
- children: <Widget>[
- new Text('aaa'),
- new Row(
- children: [
- new Text('bbb'),
- new Text('ccc'),
- ],
- ),
- new Row(
- children: [
- new Text('ddd'),
- new Text('eee'),
- ],
- ),
- new Text('fff'),
- ],
- );
-}
-''');
- }
-
- test_flutterSwapWithChild_OK() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/material.dart';
-build() {
- return new Scaffold(
-// start
- body: new /*caret*/GestureDetector(
- onTap: () => startResize(),
- child: new Center(
- child: new Container(
- width: 200.0,
- height: 300.0,
- ),
- key: null,
- ),
- ),
-// end
- );
-}
-startResize() {}
-''');
- _setCaretLocation();
- await assertHasAssist(DartAssistKind.FLUTTER_SWAP_WITH_CHILD, '''
-import 'package:flutter/material.dart';
-build() {
- return new Scaffold(
-// start
- body: new Center(
- key: null,
- child: new /*caret*/GestureDetector(
- onTap: () => startResize(),
- child: new Container(
- width: 200.0,
- height: 300.0,
- ),
- ),
- ),
-// end
- );
-}
-startResize() {}
-''');
- }
-
- test_flutterSwapWithChild_OK_notFormatted() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/material.dart';
-
-class Foo extends StatefulWidget {
- @override
- _State createState() => new _State();
-}
-
-class _State extends State<Foo> {
- @override
- Widget build(BuildContext context) {
- return new /*caret*/Expanded(
- flex: 2,
- child: new GestureDetector(
- child: new Text(
- 'foo',
- ), onTap: () {
- print(42);
- },
- ),
- );
- }
-}''');
- _setCaretLocation();
- await assertHasAssist(DartAssistKind.FLUTTER_SWAP_WITH_CHILD, '''
-import 'package:flutter/material.dart';
-
-class Foo extends StatefulWidget {
- @override
- _State createState() => new _State();
-}
-
-class _State extends State<Foo> {
- @override
- Widget build(BuildContext context) {
- return new GestureDetector(
- onTap: () {
- print(42);
- },
- child: new /*caret*/Expanded(
- flex: 2,
- child: new Text(
- 'foo',
- ),
- ),
- );
- }
-}''');
- }
-
- test_flutterSwapWithParent_OK() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/material.dart';
-build() {
- return new Scaffold(
-// start
- body: new Center(
- child: new /*caret*/GestureDetector(
- onTap: () => startResize(),
- child: new Container(
- width: 200.0,
- height: 300.0,
- ),
- ),
- key: null,
- ),
-// end
- );
-}
-startResize() {}
-''');
- _setCaretLocation();
- await assertHasAssist(DartAssistKind.FLUTTER_SWAP_WITH_PARENT, '''
-import 'package:flutter/material.dart';
-build() {
- return new Scaffold(
-// start
- body: new /*caret*/GestureDetector(
- onTap: () => startResize(),
- child: new Center(
- key: null,
- child: new Container(
- width: 200.0,
- height: 300.0,
- ),
- ),
- ),
-// end
- );
-}
-startResize() {}
-''');
- }
-
- test_flutterSwapWithParent_OK_notFormatted() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/material.dart';
-
-class Foo extends StatefulWidget {
- @override
- _State createState() => new _State();
-}
-
-class _State extends State<Foo> {
- @override
- Widget build(BuildContext context) {
- return new GestureDetector(
- child: new /*caret*/Expanded(
- child: new Text(
- 'foo',
- ),
- flex: 2,
- ), onTap: () {
- print(42);
- },
- );
- }
-}''');
- _setCaretLocation();
- await assertHasAssist(DartAssistKind.FLUTTER_SWAP_WITH_PARENT, '''
-import 'package:flutter/material.dart';
-
-class Foo extends StatefulWidget {
- @override
- _State createState() => new _State();
-}
-
-class _State extends State<Foo> {
- @override
- Widget build(BuildContext context) {
- return new /*caret*/Expanded(
- flex: 2,
- child: new GestureDetector(
- onTap: () {
- print(42);
- },
- child: new Text(
- 'foo',
- ),
- ),
- );
- }
-}''');
- }
-
- test_flutterSwapWithParent_OK_outerIsInChildren() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/material.dart';
-main() {
- new Column(
- children: [
- new Column(
- children: [
- new Padding(
- padding: new EdgeInsets.all(16.0),
- child: new /*caret*/Center(
- child: new Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: <Widget>[],
- ),
- ),
- ),
- ],
- ),
- ],
- );
-}
-''');
- _setCaretLocation();
- await assertHasAssist(DartAssistKind.FLUTTER_SWAP_WITH_PARENT, '''
-import 'package:flutter/material.dart';
-main() {
- new Column(
- children: [
- new Column(
- children: [
- new /*caret*/Center(
- child: new Padding(
- padding: new EdgeInsets.all(16.0),
- child: new Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: <Widget>[],
- ),
- ),
- ),
- ],
- ),
- ],
- );
-}
-''');
- }
-
- test_flutterWrapCenter_BAD_onCenter() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-class FakeFlutter {
- main() {
- return /*caret*/new Center();
- }
-}
-''');
- _setCaretLocation();
- await assertNoAssist(DartAssistKind.FLUTTER_WRAP_CENTER);
- }
-
- test_flutterWrapCenter_OK() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-class FakeFlutter {
- main() {
- return /*caret*/new Container();
- }
-}
-''');
- _setCaretLocation();
- if (omitNew) {
- await assertHasAssist(DartAssistKind.FLUTTER_WRAP_CENTER, '''
-import 'package:flutter/widgets.dart';
-class FakeFlutter {
- main() {
- return /*caret*/Center(child: new Container());
- }
-}
-''');
- } else {
- await assertHasAssist(DartAssistKind.FLUTTER_WRAP_CENTER, '''
-import 'package:flutter/widgets.dart';
-class FakeFlutter {
- main() {
- return /*caret*/new Center(child: new Container());
- }
-}
-''');
- }
- }
-
- test_flutterWrapCenter_OK_implicitNew() async {
- configurePreviewDart2();
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-class FakeFlutter {
- main() {
- return /*caret*/Container();
- }
-}
-''');
- _setCaretLocation();
- await assertHasAssist(DartAssistKind.FLUTTER_WRAP_CENTER, '''
-import 'package:flutter/widgets.dart';
-class FakeFlutter {
- main() {
- return /*caret*/Center(child: Container());
- }
-}
-''');
- }
-
- test_flutterWrapCenter_OK_namedConstructor() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-
-class MyWidget extends StatelessWidget {
- MyWidget.named();
-
- Widget build(BuildContext context) => null;
-}
-
-main() {
- return MyWidget./*caret*/named();
-}
-''');
- _setCaretLocation();
- if (omitNew) {
- await assertHasAssist(DartAssistKind.FLUTTER_WRAP_CENTER, '''
-import 'package:flutter/widgets.dart';
-
-class MyWidget extends StatelessWidget {
- MyWidget.named();
-
- Widget build(BuildContext context) => null;
-}
-
-main() {
- return Center(child: MyWidget./*caret*/named());
-}
-''');
- } else {
- await assertHasAssist(DartAssistKind.FLUTTER_WRAP_CENTER, '''
-import 'package:flutter/widgets.dart';
-
-class MyWidget extends StatelessWidget {
- MyWidget.named();
-
- Widget build(BuildContext context) => null;
-}
-
-main() {
- return new Center(child: MyWidget./*caret*/named());
-}
-''');
- }
- }
-
- test_flutterWrapColumn_OK_coveredByWidget() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-
-class FakeFlutter {
- main() {
- return new Container(
- child: new /*caret*/Text('aaa'),
- );
- }
-}
-''');
- _setCaretLocation();
- if (omitNew) {
- await assertHasAssist(DartAssistKind.FLUTTER_WRAP_COLUMN, '''
-import 'package:flutter/widgets.dart';
-
-class FakeFlutter {
- main() {
- return new Container(
- child: Column(
- children: <Widget>[
- new /*caret*/Text('aaa'),
- ],
- ),
- );
- }
-}
-''');
- } else {
- await assertHasAssist(DartAssistKind.FLUTTER_WRAP_COLUMN, '''
-import 'package:flutter/widgets.dart';
-
-class FakeFlutter {
- main() {
- return new Container(
- child: new Column(
- children: <Widget>[
- new /*caret*/Text('aaa'),
- ],
- ),
- );
- }
-}
-''');
- }
- }
-
- test_flutterWrapColumn_OK_coversWidgets() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-
-class FakeFlutter {
- main() {
- return new Row(children: [
- new Text('aaa'),
-// start
- new Text('bbb'),
- new Text('ccc'),
-// end
- new Text('ddd'),
- ]);
- }
-}
-''');
- _setStartEndSelection();
- if (omitNew) {
- await assertHasAssist(DartAssistKind.FLUTTER_WRAP_COLUMN, '''
-import 'package:flutter/widgets.dart';
-
-class FakeFlutter {
- main() {
- return new Row(children: [
- new Text('aaa'),
-// start
- Column(
- children: <Widget>[
- new Text('bbb'),
- new Text('ccc'),
- ],
- ),
-// end
- new Text('ddd'),
- ]);
- }
-}
-''');
- } else {
- await assertHasAssist(DartAssistKind.FLUTTER_WRAP_COLUMN, '''
-import 'package:flutter/widgets.dart';
-
-class FakeFlutter {
- main() {
- return new Row(children: [
- new Text('aaa'),
-// start
- new Column(
- children: <Widget>[
- new Text('bbb'),
- new Text('ccc'),
- ],
- ),
-// end
- new Text('ddd'),
- ]);
- }
-}
-''');
- }
- }
-
- test_flutterWrapColumn_OK_implicitNew() async {
- configurePreviewDart2();
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-
-main() {
- return Container(
- child: /*caret*/Text('aaa'),
- );
-}
-''');
- _setCaretLocation();
- await assertHasAssist(DartAssistKind.FLUTTER_WRAP_COLUMN, '''
-import 'package:flutter/widgets.dart';
-
-main() {
- return Container(
- child: /*caret*/Column(
- children: <Widget>[
- Text('aaa'),
- ],
- ),
- );
-}
-''');
- }
-
- test_flutterWrapContainer_BAD_onContainer() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-main() {
- return /*caret*/new Container();
-}
-''');
- _setCaretLocation();
- await assertNoAssist(DartAssistKind.FLUTTER_WRAP_CONTAINER);
- }
-
- test_flutterWrapContainer_OK() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-main() {
- /*caret*/new Text('a');
-}
-''');
- _setCaretLocation();
- if (omitNew) {
- await assertHasAssist(DartAssistKind.FLUTTER_WRAP_CONTAINER, '''
-import 'package:flutter/widgets.dart';
-main() {
- /*caret*/Container(child: new Text('a'));
-}
-''');
- } else {
- await assertHasAssist(DartAssistKind.FLUTTER_WRAP_CONTAINER, '''
-import 'package:flutter/widgets.dart';
-main() {
- /*caret*/new Center(child: new Text('a'));
-}
-''');
- }
- }
-
- test_flutterWrapPadding_BAD_onPadding() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-class FakeFlutter {
- main() {
- return /*caret*/new Padding();
- }
-}
-''');
- _setCaretLocation();
- await assertNoAssist(DartAssistKind.FLUTTER_WRAP_PADDING);
- }
-
- test_flutterWrapPadding_OK() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-class FakeFlutter {
- main() {
- return /*caret*/new Container();
- }
-}
-''');
- _setCaretLocation();
- if (omitNew) {
- await assertHasAssist(DartAssistKind.FLUTTER_WRAP_PADDING, '''
-import 'package:flutter/widgets.dart';
-class FakeFlutter {
- main() {
- return /*caret*/Padding(
- padding: const EdgeInsets.all(8.0),
- child: new Container(),
- );
- }
-}
-''');
- } else {
- await assertHasAssist(DartAssistKind.FLUTTER_WRAP_PADDING, '''
-import 'package:flutter/widgets.dart';
-class FakeFlutter {
- main() {
- return /*caret*/new Padding(
- padding: const EdgeInsets.all(8.0),
- child: new Container(),
- );
- }
-}
-''');
- }
- }
-
- test_flutterWrapRow_OK() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-
-class FakeFlutter {
- main() {
- return new Column(children: [
- new Text('aaa'),
-// start
- new Text('bbb'),
- new Text('ccc'),
-// end
- new Text('ddd'),
- ]);
- }
-}
-''');
- _setStartEndSelection();
- if (omitNew) {
- await assertHasAssist(DartAssistKind.FLUTTER_WRAP_ROW, '''
-import 'package:flutter/widgets.dart';
-
-class FakeFlutter {
- main() {
- return new Column(children: [
- new Text('aaa'),
-// start
- Row(
- children: <Widget>[
- new Text('bbb'),
- new Text('ccc'),
- ],
- ),
-// end
- new Text('ddd'),
- ]);
- }
-}
-''');
- } else {
- await assertHasAssist(DartAssistKind.FLUTTER_WRAP_ROW, '''
-import 'package:flutter/widgets.dart';
-
-class FakeFlutter {
- main() {
- return new Column(children: [
- new Text('aaa'),
-// start
- new Row(
- children: <Widget>[
- new Text('bbb'),
- new Text('ccc'),
- ],
- ),
-// end
- new Text('ddd'),
- ]);
- }
-}
-''');
- }
- }
-
- test_flutterWrapWidget_BAD_minimal() async {
- addFlutterPackage();
- await resolveTestUnit('''
-/*caret*/x(){}
-''');
- _setCaretLocation();
- await assertNoAssist(DartAssistKind.FLUTTER_WRAP_GENERIC);
- }
-
- test_flutterWrapWidget_BAD_multiLine() async {
- verifyNoTestUnitErrors = false;
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-build() {
- return new Container(
- child: new Row(
- children: [/*caret*/
-// start
- new Transform(),
- new Object(),
- new AspectRatio(),
-// end
- ],
- ),
- );
-}
-''');
- _setCaretLocation();
- await assertNoAssist(DartAssistKind.FLUTTER_WRAP_GENERIC);
- }
-
- test_flutterWrapWidget_BAD_singleLine() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-class FakeFlutter {
- main() {
- var obj;
-// start
- return new Row(children: [/*caret*/ new Container()]);
-// end
- }
-}
-''');
- _setCaretLocation();
- await assertNoAssist(DartAssistKind.FLUTTER_WRAP_GENERIC);
- }
-
- test_flutterWrapWidget_OK_multiLine() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-build() {
- return new Container(
- child: new Row(
-// start
- children: [/*caret*/
- new Text('111'),
- new Text('222'),
- new Container(),
- ],
-// end
- ),
- );
-}
-''');
- _setCaretLocation();
- await assertHasAssist(DartAssistKind.FLUTTER_WRAP_GENERIC, '''
-import 'package:flutter/widgets.dart';
-build() {
- return new Container(
- child: new Row(
-// start
- children: [
- new widget(
- children: [/*caret*/
- new Text('111'),
- new Text('222'),
- new Container(),
- ],
- ),
- ],
-// end
- ),
- );
-}
-''');
- }
-
- test_flutterWrapWidget_OK_multiLines() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-class FakeFlutter {
- main() {
- return new Container(
-// start
- child: new /*caret*/DefaultTextStyle(
- child: new Row(
- children: <Widget>[
- new Container(
- ),
- ],
- ),
- ),
-// end
- );
- }
-}
-''');
- _setCaretLocation();
- if (omitNew) {
- await assertHasAssist(DartAssistKind.FLUTTER_WRAP_GENERIC, '''
-import 'package:flutter/widgets.dart';
-class FakeFlutter {
- main() {
- return new Container(
-// start
- child: widget(
- child: new /*caret*/DefaultTextStyle(
- child: new Row(
- children: <Widget>[
- new Container(
- ),
- ],
- ),
- ),
- ),
-// end
- );
- }
-}
-''');
- } else {
- await assertHasAssist(DartAssistKind.FLUTTER_WRAP_GENERIC, '''
-import 'package:flutter/widgets.dart';
-class FakeFlutter {
- main() {
- return new Container(
-// start
- child: new widget(
- child: new /*caret*/DefaultTextStyle(
- child: new Row(
- children: <Widget>[
- new Container(
- ),
- ],
- ),
- ),
- ),
-// end
- );
- }
-}
-''');
- }
- }
-
- test_flutterWrapWidget_OK_multiLines_eol2() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-class FakeFlutter {\r
- main() {\r
- return new Container(\r
-// start\r
- child: new /*caret*/DefaultTextStyle(\r
- child: new Row(\r
- children: <Widget>[\r
- new Container(\r
- ),\r
- ],\r
- ),\r
- ),\r
-// end\r
- );\r
- }\r
-}\r
-''');
- _setCaretLocation();
- if (omitNew) {
- await assertHasAssist(DartAssistKind.FLUTTER_WRAP_GENERIC, '''
-import 'package:flutter/widgets.dart';
-class FakeFlutter {\r
- main() {\r
- return new Container(\r
-// start\r
- child: widget(\r
- child: new /*caret*/DefaultTextStyle(\r
- child: new Row(\r
- children: <Widget>[\r
- new Container(\r
- ),\r
- ],\r
- ),\r
- ),\r
- ),\r
-// end\r
- );\r
- }\r
-}\r
-''');
- } else {
- await assertHasAssist(DartAssistKind.FLUTTER_WRAP_GENERIC, '''
-import 'package:flutter/widgets.dart';
-class FakeFlutter {\r
- main() {\r
- return new Container(\r
-// start\r
- child: new widget(\r
- child: new /*caret*/DefaultTextStyle(\r
- child: new Row(\r
- children: <Widget>[\r
- new Container(\r
- ),\r
- ],\r
- ),\r
- ),\r
- ),\r
-// end\r
- );\r
- }\r
-}\r
-''');
- }
- }
-
- test_flutterWrapWidget_OK_prefixedIdentifier_identifier() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-
-abstract class Foo extends Widget {
- Widget bar;
-}
-
-main(Foo foo) {
- return foo./*caret*/bar;
-}
-''');
- _setCaretLocation();
- await assertHasAssist(DartAssistKind.FLUTTER_WRAP_GENERIC, '''
-import 'package:flutter/widgets.dart';
-
-abstract class Foo extends Widget {
- Widget bar;
-}
-
-main(Foo foo) {
- return widget(child: foo./*caret*/bar);
-}
-''');
- }
-
- test_flutterWrapWidget_OK_prefixedIdentifier_prefix() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-
-abstract class Foo extends Widget {
- Widget bar;
-}
-
-main(Foo foo) {
- return /*caret*/foo.bar;
-}
-''');
- _setCaretLocation();
- await assertHasAssist(DartAssistKind.FLUTTER_WRAP_GENERIC, '''
-import 'package:flutter/widgets.dart';
-
-abstract class Foo extends Widget {
- Widget bar;
-}
-
-main(Foo foo) {
- return /*caret*/widget(child: foo.bar);
-}
-''');
- }
-
- test_flutterWrapWidget_OK_singleLine1() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-class FakeFlutter {
- main() {
-// start
- return /*caret*/new Container();
-// end
- }
-}
-''');
- _setCaretLocation();
- if (omitNew) {
- await assertHasAssist(DartAssistKind.FLUTTER_WRAP_GENERIC, '''
-import 'package:flutter/widgets.dart';
-class FakeFlutter {
- main() {
-// start
- return /*caret*/widget(child: new Container());
-// end
- }
-}
-''');
- } else {
- await assertHasAssist(DartAssistKind.FLUTTER_WRAP_GENERIC, '''
-import 'package:flutter/widgets.dart';
-class FakeFlutter {
- main() {
-// start
- return /*caret*/new widget(child: new Container());
-// end
- }
-}
-''');
- }
- }
-
- test_flutterWrapWidget_OK_singleLine2() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-class FakeFlutter {
- main() {
- return new ClipRect./*caret*/rect();
- }
-}
-''');
- _setCaretLocation();
- if (omitNew) {
- await assertHasAssist(DartAssistKind.FLUTTER_WRAP_GENERIC, '''
-import 'package:flutter/widgets.dart';
-class FakeFlutter {
- main() {
- return widget(child: new ClipRect./*caret*/rect());
- }
-}
-''');
- } else {
- await assertHasAssist(DartAssistKind.FLUTTER_WRAP_GENERIC, '''
-import 'package:flutter/widgets.dart';
-class FakeFlutter {
- main() {
- return new widget(child: new ClipRect./*caret*/rect());
- }
-}
-''');
- }
- }
-
- test_flutterWrapWidget_OK_variable() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-class FakeFlutter {
- main() {
- var container = new Container();
- return /*caret*/container;
- }
-}
-''');
- _setCaretLocation();
- if (omitNew) {
- await assertHasAssist(DartAssistKind.FLUTTER_WRAP_GENERIC, '''
-import 'package:flutter/widgets.dart';
-class FakeFlutter {
- main() {
- var container = new Container();
- return /*caret*/widget(child: container);
- }
-}
-''');
- } else {
- await assertHasAssist(DartAssistKind.FLUTTER_WRAP_GENERIC, '''
-import 'package:flutter/widgets.dart';
-class FakeFlutter {
- main() {
- var container = new Container();
- return /*caret*/new widget(child: container);
- }
-}
-''');
- }
- }
-
- test_importAddShow_BAD_hasShow() async {
- await resolveTestUnit('''
-import 'dart:math' show PI;
-main() {
- PI;
-}
-''');
- await assertNoAssistAt('import ', DartAssistKind.IMPORT_ADD_SHOW);
- }
-
- test_importAddShow_BAD_unresolvedUri() async {
- verifyNoTestUnitErrors = false;
- await resolveTestUnit('''
-import '/no/such/lib.dart';
-''');
- await assertNoAssistAt('import ', DartAssistKind.IMPORT_ADD_SHOW);
- }
-
- test_importAddShow_BAD_unused() async {
- await resolveTestUnit('''
-import 'dart:math';
-''');
- await assertNoAssistAt('import ', DartAssistKind.IMPORT_ADD_SHOW);
- }
-
- test_importAddShow_OK_hasUnresolvedIdentifier() async {
- await resolveTestUnit('''
-import 'dart:math';
-main(x) {
- PI;
- return x.foo();
-}
-''');
- await assertHasAssistAt('import ', DartAssistKind.IMPORT_ADD_SHOW, '''
-import 'dart:math' show PI;
-main(x) {
- PI;
- return x.foo();
-}
-''');
- }
-
- test_importAddShow_OK_onDirective() async {
- await resolveTestUnit('''
-import 'dart:math';
-main() {
- PI;
- E;
- max(1, 2);
-}
-''');
- await assertHasAssistAt('import ', DartAssistKind.IMPORT_ADD_SHOW, '''
-import 'dart:math' show E, PI, max;
-main() {
- PI;
- E;
- max(1, 2);
-}
-''');
- }
-
- test_importAddShow_OK_onUri() async {
- await resolveTestUnit('''
-import 'dart:math';
-main() {
- PI;
- E;
- max(1, 2);
-}
-''');
- await assertHasAssistAt('art:math', DartAssistKind.IMPORT_ADD_SHOW, '''
-import 'dart:math' show E, PI, max;
-main() {
- PI;
- E;
- max(1, 2);
-}
-''');
- }
-
- test_introduceLocalTestedType_BAD_notBlock() async {
- await resolveTestUnit('''
-main(p) {
- if (p is String)
- print('not a block');
-}
-''');
- await assertNoAssistAt('if (p', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE);
- }
-
- test_introduceLocalTestedType_BAD_notIsExpression() async {
- await resolveTestUnit('''
-main(p) {
- if (p == null) {
- }
-}
-''');
- await assertNoAssistAt('if (p', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE);
- }
-
- test_introduceLocalTestedType_BAD_notStatement() async {
- await resolveTestUnit('''
-class C {
- bool b;
- C(v) : b = v is int;
-}''');
- await assertNoAssistAt('is int', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE);
- }
-
- test_introduceLocalTestedType_OK_if_is() async {
- await resolveTestUnit('''
-class MyTypeName {}
-main(p) {
- if (p is MyTypeName) {
- }
- p = null;
-}
-''');
- String expected = '''
-class MyTypeName {}
-main(p) {
- if (p is MyTypeName) {
- MyTypeName myTypeName = p;
- }
- p = null;
-}
-''';
- await assertHasAssistAt(
- 'is MyType', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE, expected);
- _assertLinkedGroup(
- change.linkedEditGroups[0],
- ['myTypeName = '],
- expectedSuggestions(LinkedEditSuggestionKind.VARIABLE,
- ['myTypeName', 'typeName', 'name']));
- // another good location
- await assertHasAssistAt(
- 'if (p', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE, expected);
- }
-
- test_introduceLocalTestedType_OK_if_isNot() async {
- await resolveTestUnit('''
-class MyTypeName {}
-main(p) {
- if (p is! MyTypeName) {
- return;
- }
-}
-''');
- String expected = '''
-class MyTypeName {}
-main(p) {
- if (p is! MyTypeName) {
- return;
- }
- MyTypeName myTypeName = p;
-}
-''';
- await assertHasAssistAt(
- 'is! MyType', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE, expected);
- _assertLinkedGroup(
- change.linkedEditGroups[0],
- ['myTypeName = '],
- expectedSuggestions(LinkedEditSuggestionKind.VARIABLE,
- ['myTypeName', 'typeName', 'name']));
- // another good location
- await assertHasAssistAt(
- 'if (p', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE, expected);
- }
-
- test_introduceLocalTestedType_OK_while() async {
- await resolveTestUnit('''
-main(p) {
- while (p is String) {
- }
- p = null;
-}
-''');
- String expected = '''
-main(p) {
- while (p is String) {
- String s = p;
- }
- p = null;
-}
-''';
- await assertHasAssistAt(
- 'is String', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE, expected);
- await assertHasAssistAt(
- 'while (p', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE, expected);
- }
-
- test_invalidSelection() async {
- await resolveTestUnit('');
- offset = -1;
- length = 0;
- List<Assist> assists = await _computeAssists();
- expect(assists, isEmpty);
- }
-
- test_invertIfStatement_blocks() async {
- await resolveTestUnit('''
-main() {
- if (true) {
- 0;
- } else {
- 1;
- }
-}
-''');
- await assertHasAssistAt('if (', DartAssistKind.INVERT_IF_STATEMENT, '''
-main() {
- if (false) {
- 1;
- } else {
- 0;
- }
-}
-''');
- }
-
- test_invertIfStatement_statements() async {
- await resolveTestUnit('''
-main() {
- if (true)
- 0;
- else
- 1;
-}
-''');
- await assertHasAssistAt('if (', DartAssistKind.INVERT_IF_STATEMENT, '''
-main() {
- if (false)
- 1;
- else
- 0;
-}
-''');
- }
-
- test_joinIfStatementInner_BAD_innerNotIf() async {
- await resolveTestUnit('''
-main() {
- if (1 == 1) {
- print(0);
- }
-}
-''');
- await assertNoAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER);
- }
-
- test_joinIfStatementInner_BAD_innerWithElse() async {
- await resolveTestUnit('''
-main() {
- if (1 == 1) {
- if (2 == 2) {
- print(0);
- } else {
- print(1);
- }
- }
-}
-''');
- await assertNoAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER);
- }
-
- test_joinIfStatementInner_BAD_statementAfterInner() async {
- await resolveTestUnit('''
-main() {
- if (1 == 1) {
- if (2 == 2) {
- print(2);
- }
- print(1);
- }
-}
-''');
- await assertNoAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER);
- }
-
- test_joinIfStatementInner_BAD_statementBeforeInner() async {
- await resolveTestUnit('''
-main() {
- if (1 == 1) {
- print(1);
- if (2 == 2) {
- print(2);
- }
- }
-}
-''');
- await assertNoAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER);
- }
-
- test_joinIfStatementInner_BAD_targetNotIf() async {
- await resolveTestUnit('''
-main() {
- print(0);
-}
-''');
- await assertNoAssistAt('print', DartAssistKind.JOIN_IF_WITH_INNER);
- }
-
- test_joinIfStatementInner_BAD_targetWithElse() async {
- await resolveTestUnit('''
-main() {
- if (1 == 1) {
- if (2 == 2) {
- print(0);
- }
- } else {
- print(1);
- }
-}
-''');
- await assertNoAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER);
- }
-
- test_joinIfStatementInner_OK_conditionAndOr() async {
- await resolveTestUnit('''
-main() {
- if (1 == 1) {
- if (2 == 2 || 3 == 3) {
- print(0);
- }
- }
-}
-''');
- await assertHasAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER, '''
-main() {
- if (1 == 1 && (2 == 2 || 3 == 3)) {
- print(0);
- }
-}
-''');
- }
-
- test_joinIfStatementInner_OK_conditionInvocation() async {
- await resolveTestUnit('''
-main() {
- if (isCheck()) {
- if (2 == 2) {
- print(0);
- }
- }
-}
-bool isCheck() => false;
-''');
- await assertHasAssistAt(
- 'if (isCheck', DartAssistKind.JOIN_IF_WITH_INNER, '''
-main() {
- if (isCheck() && 2 == 2) {
- print(0);
- }
-}
-bool isCheck() => false;
-''');
- }
-
- test_joinIfStatementInner_OK_conditionOrAnd() async {
- await resolveTestUnit('''
-main() {
- if (1 == 1 || 2 == 2) {
- if (3 == 3) {
- print(0);
- }
- }
-}
-''');
- await assertHasAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER, '''
-main() {
- if ((1 == 1 || 2 == 2) && 3 == 3) {
- print(0);
- }
-}
-''');
- }
-
- test_joinIfStatementInner_OK_onCondition() async {
- await resolveTestUnit('''
-main() {
- if (1 == 1) {
- if (2 == 2) {
- print(0);
- }
- }
-}
-''');
- await assertHasAssistAt('1 ==', DartAssistKind.JOIN_IF_WITH_INNER, '''
-main() {
- if (1 == 1 && 2 == 2) {
- print(0);
- }
-}
-''');
- }
-
- test_joinIfStatementInner_OK_simpleConditions_block_block() async {
- await resolveTestUnit('''
-main() {
- if (1 == 1) {
- if (2 == 2) {
- print(0);
- }
- }
-}
-''');
- await assertHasAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER, '''
-main() {
- if (1 == 1 && 2 == 2) {
- print(0);
- }
-}
-''');
- }
-
- test_joinIfStatementInner_OK_simpleConditions_block_single() async {
- await resolveTestUnit('''
-main() {
- if (1 == 1) {
- if (2 == 2)
- print(0);
- }
-}
-''');
- await assertHasAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER, '''
-main() {
- if (1 == 1 && 2 == 2) {
- print(0);
- }
-}
-''');
- }
-
- test_joinIfStatementInner_OK_simpleConditions_single_blockMulti() async {
- await resolveTestUnit('''
-main() {
- if (1 == 1) {
- if (2 == 2) {
- print(1);
- print(2);
- print(3);
- }
- }
-}
-''');
- await assertHasAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER, '''
-main() {
- if (1 == 1 && 2 == 2) {
- print(1);
- print(2);
- print(3);
- }
-}
-''');
- }
-
- test_joinIfStatementInner_OK_simpleConditions_single_blockOne() async {
- await resolveTestUnit('''
-main() {
- if (1 == 1)
- if (2 == 2) {
- print(0);
- }
-}
-''');
- await assertHasAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER, '''
-main() {
- if (1 == 1 && 2 == 2) {
- print(0);
- }
-}
-''');
- }
-
- test_joinIfStatementOuter_BAD_outerNotIf() async {
- await resolveTestUnit('''
-main() {
- if (1 == 1) {
- print(0);
- }
-}
-''');
- await assertNoAssistAt('if (1 == 1', DartAssistKind.JOIN_IF_WITH_OUTER);
- }
-
- test_joinIfStatementOuter_BAD_outerWithElse() async {
- await resolveTestUnit('''
-main() {
- if (1 == 1) {
- if (2 == 2) {
- print(0);
- }
- } else {
- print(1);
- }
-}
-''');
- await assertNoAssistAt('if (2 == 2', DartAssistKind.JOIN_IF_WITH_OUTER);
- }
-
- test_joinIfStatementOuter_BAD_statementAfterInner() async {
- await resolveTestUnit('''
-main() {
- if (1 == 1) {
- if (2 == 2) {
- print(2);
- }
- print(1);
- }
-}
-''');
- await assertNoAssistAt('if (2 == 2', DartAssistKind.JOIN_IF_WITH_OUTER);
- }
-
- test_joinIfStatementOuter_BAD_statementBeforeInner() async {
- await resolveTestUnit('''
-main() {
- if (1 == 1) {
- print(1);
- if (2 == 2) {
- print(2);
- }
- }
-}
-''');
- await assertNoAssistAt('if (2 == 2', DartAssistKind.JOIN_IF_WITH_OUTER);
- }
-
- test_joinIfStatementOuter_BAD_targetNotIf() async {
- await resolveTestUnit('''
-main() {
- print(0);
-}
-''');
- await assertNoAssistAt('print', DartAssistKind.JOIN_IF_WITH_OUTER);
- }
-
- test_joinIfStatementOuter_BAD_targetWithElse() async {
- await resolveTestUnit('''
-main() {
- if (1 == 1) {
- if (2 == 2) {
- print(0);
- } else {
- print(1);
- }
- }
-}
-''');
- await assertNoAssistAt('if (2 == 2', DartAssistKind.JOIN_IF_WITH_OUTER);
- }
-
- test_joinIfStatementOuter_OK_conditionAndOr() async {
- await resolveTestUnit('''
-main() {
- if (1 == 1) {
- if (2 == 2 || 3 == 3) {
- print(0);
- }
- }
-}
-''');
- await assertHasAssistAt('if (2 ==', DartAssistKind.JOIN_IF_WITH_OUTER, '''
-main() {
- if (1 == 1 && (2 == 2 || 3 == 3)) {
- print(0);
- }
-}
-''');
- }
-
- test_joinIfStatementOuter_OK_conditionInvocation() async {
- await resolveTestUnit('''
-main() {
- if (1 == 1) {
- if (isCheck()) {
- print(0);
- }
- }
-}
-bool isCheck() => false;
-''');
- await assertHasAssistAt(
- 'if (isCheck', DartAssistKind.JOIN_IF_WITH_OUTER, '''
-main() {
- if (1 == 1 && isCheck()) {
- print(0);
- }
-}
-bool isCheck() => false;
-''');
- }
-
- test_joinIfStatementOuter_OK_conditionOrAnd() async {
- await resolveTestUnit('''
-main() {
- if (1 == 1 || 2 == 2) {
- if (3 == 3) {
- print(0);
- }
- }
-}
-''');
- await assertHasAssistAt('if (3 == 3', DartAssistKind.JOIN_IF_WITH_OUTER, '''
-main() {
- if ((1 == 1 || 2 == 2) && 3 == 3) {
- print(0);
- }
-}
-''');
- }
-
- test_joinIfStatementOuter_OK_onCondition() async {
- await resolveTestUnit('''
-main() {
- if (1 == 1) {
- if (2 == 2) {
- print(0);
- }
- }
-}
-''');
- await assertHasAssistAt('if (2 == 2', DartAssistKind.JOIN_IF_WITH_OUTER, '''
-main() {
- if (1 == 1 && 2 == 2) {
- print(0);
- }
-}
-''');
- }
-
- test_joinIfStatementOuter_OK_simpleConditions_block_block() async {
- await resolveTestUnit('''
-main() {
- if (1 == 1) {
- if (2 == 2) {
- print(0);
- }
- }
-}
-''');
- await assertHasAssistAt('if (2 == 2', DartAssistKind.JOIN_IF_WITH_OUTER, '''
-main() {
- if (1 == 1 && 2 == 2) {
- print(0);
- }
-}
-''');
- }
-
- test_joinIfStatementOuter_OK_simpleConditions_block_single() async {
- await resolveTestUnit('''
-main() {
- if (1 == 1) {
- if (2 == 2)
- print(0);
- }
-}
-''');
- await assertHasAssistAt('if (2 == 2', DartAssistKind.JOIN_IF_WITH_OUTER, '''
-main() {
- if (1 == 1 && 2 == 2) {
- print(0);
- }
-}
-''');
- }
-
- test_joinIfStatementOuter_OK_simpleConditions_single_blockMulti() async {
- await resolveTestUnit('''
-main() {
- if (1 == 1) {
- if (2 == 2) {
- print(1);
- print(2);
- print(3);
- }
- }
-}
-''');
- await assertHasAssistAt('if (2 == 2', DartAssistKind.JOIN_IF_WITH_OUTER, '''
-main() {
- if (1 == 1 && 2 == 2) {
- print(1);
- print(2);
- print(3);
- }
-}
-''');
- }
-
- test_joinIfStatementOuter_OK_simpleConditions_single_blockOne() async {
- await resolveTestUnit('''
-main() {
- if (1 == 1)
- if (2 == 2) {
- print(0);
- }
-}
-''');
- await assertHasAssistAt('if (2 == 2', DartAssistKind.JOIN_IF_WITH_OUTER, '''
-main() {
- if (1 == 1 && 2 == 2) {
- print(0);
- }
-}
-''');
- }
-
- test_joinVariableDeclaration_onAssignment_BAD_hasInitializer() async {
- await resolveTestUnit('''
-main() {
- var v = 1;
- v = 2;
-}
-''');
- await assertNoAssistAt('v = 2', DartAssistKind.JOIN_VARIABLE_DECLARATION);
- }
-
- test_joinVariableDeclaration_onAssignment_BAD_notAdjacent() async {
- await resolveTestUnit('''
-main() {
- var v;
- var bar;
- v = 1;
-}
-''');
- await assertNoAssistAt('v = 1', DartAssistKind.JOIN_VARIABLE_DECLARATION);
- }
-
- test_joinVariableDeclaration_onAssignment_BAD_notAssignment() async {
- await resolveTestUnit('''
-main() {
- var v;
- v += 1;
-}
-''');
- await assertNoAssistAt('v += 1', DartAssistKind.JOIN_VARIABLE_DECLARATION);
- }
-
- test_joinVariableDeclaration_onAssignment_BAD_notDeclaration() async {
- await resolveTestUnit('''
-main(var v) {
- v = 1;
-}
-''');
- await assertNoAssistAt('v = 1', DartAssistKind.JOIN_VARIABLE_DECLARATION);
- }
-
- test_joinVariableDeclaration_onAssignment_BAD_notLeftArgument() async {
- await resolveTestUnit('''
-main() {
- var v;
- 1 + v; // marker
-}
-''');
- await assertNoAssistAt(
- 'v; // marker', DartAssistKind.JOIN_VARIABLE_DECLARATION);
- }
-
- test_joinVariableDeclaration_onAssignment_BAD_notOneVariable() async {
- await resolveTestUnit('''
-main() {
- var v, v2;
- v = 1;
-}
-''');
- await assertNoAssistAt('v = 1', DartAssistKind.JOIN_VARIABLE_DECLARATION);
- }
-
- test_joinVariableDeclaration_onAssignment_BAD_notResolved() async {
- verifyNoTestUnitErrors = false;
- await resolveTestUnit('''
-main() {
- var v;
- x = 1;
-}
-''');
- await assertNoAssistAt('x = 1', DartAssistKind.JOIN_VARIABLE_DECLARATION);
- }
-
- test_joinVariableDeclaration_onAssignment_BAD_notSameBlock() async {
- await resolveTestUnit('''
-main() {
- var v;
- {
- v = 1;
- }
-}
-''');
- await assertNoAssistAt('v = 1', DartAssistKind.JOIN_VARIABLE_DECLARATION);
- }
-
- test_joinVariableDeclaration_onAssignment_OK() async {
- await resolveTestUnit('''
-main() {
- var v;
- v = 1;
-}
-''');
- await assertHasAssistAt('v =', DartAssistKind.JOIN_VARIABLE_DECLARATION, '''
-main() {
- var v = 1;
-}
-''');
- }
-
- test_joinVariableDeclaration_onDeclaration_BAD_hasInitializer() async {
- await resolveTestUnit('''
-main() {
- var v = 1;
- v = 2;
-}
-''');
- await assertNoAssistAt('v = 1', DartAssistKind.JOIN_VARIABLE_DECLARATION);
- }
-
- test_joinVariableDeclaration_onDeclaration_BAD_lastStatement() async {
- await resolveTestUnit('''
-main() {
- if (true)
- var v;
-}
-''');
- await assertNoAssistAt('v;', DartAssistKind.JOIN_VARIABLE_DECLARATION);
- }
-
- test_joinVariableDeclaration_onDeclaration_BAD_nextNotAssignmentExpression() async {
- await resolveTestUnit('''
-main() {
- var v;
- 42;
-}
-''');
- await assertNoAssistAt('v;', DartAssistKind.JOIN_VARIABLE_DECLARATION);
- }
-
- test_joinVariableDeclaration_onDeclaration_BAD_nextNotExpressionStatement() async {
- await resolveTestUnit('''
-main() {
- var v;
- if (true) return;
-}
-''');
- await assertNoAssistAt('v;', DartAssistKind.JOIN_VARIABLE_DECLARATION);
- }
-
- test_joinVariableDeclaration_onDeclaration_BAD_nextNotPureAssignment() async {
- await resolveTestUnit('''
-main() {
- var v;
- v += 1;
-}
-''');
- await assertNoAssistAt('v;', DartAssistKind.JOIN_VARIABLE_DECLARATION);
- }
-
- test_joinVariableDeclaration_onDeclaration_BAD_notOneVariable() async {
- await resolveTestUnit('''
-main() {
- var v, v2;
- v = 1;
-}
-''');
- await assertNoAssistAt('v, ', DartAssistKind.JOIN_VARIABLE_DECLARATION);
- }
-
- test_joinVariableDeclaration_onDeclaration_OK_onName() async {
- await resolveTestUnit('''
-main() {
- var v;
- v = 1;
-}
-''');
- await assertHasAssistAt('v;', DartAssistKind.JOIN_VARIABLE_DECLARATION, '''
-main() {
- var v = 1;
-}
-''');
- }
-
- test_joinVariableDeclaration_onDeclaration_OK_onType() async {
- await resolveTestUnit('''
-main() {
- int v;
- v = 1;
-}
-''');
- await assertHasAssistAt(
- 'int v', DartAssistKind.JOIN_VARIABLE_DECLARATION, '''
-main() {
- int v = 1;
-}
-''');
- }
-
- test_joinVariableDeclaration_onDeclaration_OK_onVar() async {
- await resolveTestUnit('''
-main() {
- var v;
- v = 1;
-}
-''');
- await assertHasAssistAt(
- 'var v', DartAssistKind.JOIN_VARIABLE_DECLARATION, '''
-main() {
- var v = 1;
-}
-''');
- }
-
- test_removeTypeAnnotation_classField_OK() async {
- await resolveTestUnit('''
-class A {
- int v = 1;
-}
-''');
- await assertHasAssistAt('v = ', DartAssistKind.REMOVE_TYPE_ANNOTATION, '''
-class A {
- var v = 1;
-}
-''');
- }
-
- test_removeTypeAnnotation_classField_OK_final() async {
- await resolveTestUnit('''
-class A {
- final int v = 1;
-}
-''');
- await assertHasAssistAt('v = ', DartAssistKind.REMOVE_TYPE_ANNOTATION, '''
-class A {
- final v = 1;
-}
-''');
- }
-
- test_removeTypeAnnotation_field_BAD_noInitializer() async {
- await resolveTestUnit('''
-class A {
- int v;
-}
-''');
- await assertNoAssistAt('v;', DartAssistKind.REMOVE_TYPE_ANNOTATION);
- }
-
- test_removeTypeAnnotation_localVariable_BAD_noInitializer() async {
- await resolveTestUnit('''
-main() {
- int v;
-}
-''');
- await assertNoAssistAt('v;', DartAssistKind.REMOVE_TYPE_ANNOTATION);
- }
-
- test_removeTypeAnnotation_localVariable_BAD_onInitializer() async {
- await resolveTestUnit('''
-main() {
- final int v = 1;
-}
-''');
- await assertNoAssistAt('1;', DartAssistKind.REMOVE_TYPE_ANNOTATION);
- }
-
- test_removeTypeAnnotation_localVariable_OK() async {
- await resolveTestUnit('''
-main() {
- int a = 1, b = 2;
-}
-''');
- await assertHasAssistAt('int ', DartAssistKind.REMOVE_TYPE_ANNOTATION, '''
-main() {
- var a = 1, b = 2;
-}
-''');
- }
-
- test_removeTypeAnnotation_localVariable_OK_const() async {
- await resolveTestUnit('''
-main() {
- const int v = 1;
-}
-''');
- await assertHasAssistAt('int ', DartAssistKind.REMOVE_TYPE_ANNOTATION, '''
-main() {
- const v = 1;
-}
-''');
- }
-
- test_removeTypeAnnotation_localVariable_OK_final() async {
- await resolveTestUnit('''
-main() {
- final int v = 1;
-}
-''');
- await assertHasAssistAt('int ', DartAssistKind.REMOVE_TYPE_ANNOTATION, '''
-main() {
- final v = 1;
-}
-''');
- }
-
- test_removeTypeAnnotation_topLevelVariable_BAD_noInitializer() async {
- verifyNoTestUnitErrors = false;
- await resolveTestUnit('''
-int v;
-''');
- await assertNoAssistAt('v;', DartAssistKind.REMOVE_TYPE_ANNOTATION);
- }
-
- test_removeTypeAnnotation_topLevelVariable_BAD_syntheticName() async {
- verifyNoTestUnitErrors = false;
- await resolveTestUnit('''
-MyType
-''');
- await assertNoAssistAt('MyType', DartAssistKind.REMOVE_TYPE_ANNOTATION);
- }
-
- test_removeTypeAnnotation_topLevelVariable_OK() async {
- await resolveTestUnit('''
-int V = 1;
-''');
- await assertHasAssistAt('int ', DartAssistKind.REMOVE_TYPE_ANNOTATION, '''
-var V = 1;
-''');
- }
-
- test_removeTypeAnnotation_topLevelVariable_OK_final() async {
- await resolveTestUnit('''
-final int V = 1;
-''');
- await assertHasAssistAt('int ', DartAssistKind.REMOVE_TYPE_ANNOTATION, '''
-final V = 1;
-''');
- }
-
- test_replaceConditionalWithIfElse_BAD_noEnclosingStatement() async {
- await resolveTestUnit('''
-var v = true ? 111 : 222;
-''');
- await assertNoAssistAt(
- '? 111', DartAssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE);
- }
-
- test_replaceConditionalWithIfElse_BAD_notConditional() async {
- await resolveTestUnit('''
-main() {
- var v = 42;
-}
-''');
- await assertNoAssistAt(
- 'v = 42', DartAssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE);
- }
-
- test_replaceConditionalWithIfElse_OK_assignment() async {
- await resolveTestUnit('''
-main() {
- var v;
- v = true ? 111 : 222;
-}
-''');
- // on conditional
- await assertHasAssistAt(
- '11 :', DartAssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE, '''
-main() {
- var v;
- if (true) {
- v = 111;
- } else {
- v = 222;
- }
-}
-''');
- // on variable
- await assertHasAssistAt(
- 'v =', DartAssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE, '''
-main() {
- var v;
- if (true) {
- v = 111;
- } else {
- v = 222;
- }
-}
-''');
- }
-
- test_replaceConditionalWithIfElse_OK_return() async {
- await resolveTestUnit('''
-main() {
- return true ? 111 : 222;
-}
-''');
- await assertHasAssistAt(
- 'return ', DartAssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE, '''
-main() {
- if (true) {
- return 111;
- } else {
- return 222;
- }
-}
-''');
- }
-
- test_replaceConditionalWithIfElse_OK_variableDeclaration() async {
- await resolveTestUnit('''
-main() {
- int a = 1, vvv = true ? 111 : 222, b = 2;
-}
-''');
- await assertHasAssistAt(
- '11 :', DartAssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE, '''
-main() {
- int a = 1, vvv, b = 2;
- if (true) {
- vvv = 111;
- } else {
- vvv = 222;
- }
-}
-''');
- }
-
- test_replaceIfElseWithConditional_BAD_expressionVsReturn() async {
- await resolveTestUnit('''
-main() {
- if (true) {
- print(42);
- } else {
- return;
- }
-}
-''');
- await assertNoAssistAt(
- 'else', DartAssistKind.REPLACE_IF_ELSE_WITH_CONDITIONAL);
- }
-
- test_replaceIfElseWithConditional_BAD_notIfStatement() async {
- await resolveTestUnit('''
-main() {
- print(0);
-}
-''');
- await assertNoAssistAt(
- 'print', DartAssistKind.REPLACE_IF_ELSE_WITH_CONDITIONAL);
- }
-
- test_replaceIfElseWithConditional_BAD_notSingleStatement() async {
- await resolveTestUnit('''
-main() {
- int vvv;
- if (true) {
- print(0);
- vvv = 111;
- } else {
- print(0);
- vvv = 222;
- }
-}
-''');
- await assertNoAssistAt(
- 'if (true)', DartAssistKind.REPLACE_IF_ELSE_WITH_CONDITIONAL);
- }
-
- test_replaceIfElseWithConditional_OK_assignment() async {
- await resolveTestUnit('''
-main() {
- int vvv;
- if (true) {
- vvv = 111;
- } else {
- vvv = 222;
- }
-}
-''');
- await assertHasAssistAt(
- 'if (true)', DartAssistKind.REPLACE_IF_ELSE_WITH_CONDITIONAL, '''
-main() {
- int vvv;
- vvv = true ? 111 : 222;
-}
-''');
- }
-
- test_replaceIfElseWithConditional_OK_return() async {
- await resolveTestUnit('''
-main() {
- if (true) {
- return 111;
- } else {
- return 222;
- }
-}
-''');
- await assertHasAssistAt(
- 'if (true)', DartAssistKind.REPLACE_IF_ELSE_WITH_CONDITIONAL, '''
-main() {
- return true ? 111 : 222;
-}
-''');
- }
-
- test_splitAndCondition_BAD_hasElse() async {
- await resolveTestUnit('''
-main() {
- if (1 == 1 && 2 == 2) {
- print(1);
- } else {
- print(2);
- }
-}
-''');
- await assertNoAssistAt('&& 2', DartAssistKind.SPLIT_AND_CONDITION);
- }
-
- test_splitAndCondition_BAD_notAnd() async {
- await resolveTestUnit('''
-main() {
- if (1 == 1 || 2 == 2) {
- print(0);
- }
-}
-''');
- await assertNoAssistAt('|| 2', DartAssistKind.SPLIT_AND_CONDITION);
- }
-
- test_splitAndCondition_BAD_notPartOfIf() async {
- await resolveTestUnit('''
-main() {
- print(1 == 1 && 2 == 2);
-}
-''');
- await assertNoAssistAt('&& 2', DartAssistKind.SPLIT_AND_CONDITION);
- }
-
- test_splitAndCondition_BAD_notTopLevelAnd() async {
- await resolveTestUnit('''
-main() {
- if (true || (1 == 1 && 2 == 2)) {
- print(0);
- }
- if (true && (3 == 3 && 4 == 4)) {
- print(0);
- }
-}
-''');
- await assertNoAssistAt('&& 2', DartAssistKind.SPLIT_AND_CONDITION);
- await assertNoAssistAt('&& 4', DartAssistKind.SPLIT_AND_CONDITION);
- }
-
- test_splitAndCondition_OK_innerAndExpression() async {
- await resolveTestUnit('''
-main() {
- if (1 == 1 && 2 == 2 && 3 == 3) {
- print(0);
- }
-}
-''');
- await assertHasAssistAt('&& 2 == 2', DartAssistKind.SPLIT_AND_CONDITION, '''
-main() {
- if (1 == 1) {
- if (2 == 2 && 3 == 3) {
- print(0);
- }
- }
-}
-''');
- }
-
- test_splitAndCondition_OK_thenBlock() async {
- await resolveTestUnit('''
-main() {
- if (true && false) {
- print(0);
- if (3 == 3) {
- print(1);
- }
- }
-}
-''');
- await assertHasAssistAt('&& false', DartAssistKind.SPLIT_AND_CONDITION, '''
-main() {
- if (true) {
- if (false) {
- print(0);
- if (3 == 3) {
- print(1);
- }
- }
- }
-}
-''');
- }
-
- test_splitAndCondition_OK_thenStatement() async {
- await resolveTestUnit('''
-main() {
- if (true && false)
- print(0);
-}
-''');
- await assertHasAssistAt('&& false', DartAssistKind.SPLIT_AND_CONDITION, '''
-main() {
- if (true)
- if (false)
- print(0);
-}
-''');
- }
-
- test_splitAndCondition_wrong() async {
- await resolveTestUnit('''
-main() {
- if (1 == 1 && 2 == 2) {
- print(0);
- }
- print(3 == 3 && 4 == 4);
-}
-''');
- // not binary expression
- await assertNoAssistAt('main() {', DartAssistKind.SPLIT_AND_CONDITION);
- // selection is not empty and includes more than just operator
- {
- length = 5;
- await assertNoAssistAt('&& 2 == 2', DartAssistKind.SPLIT_AND_CONDITION);
- }
- }
-
- test_splitVariableDeclaration_BAD_notOneVariable() async {
- await resolveTestUnit('''
-main() {
- var v = 1, v2;
-}
-''');
- await assertNoAssistAt('v = 1', DartAssistKind.SPLIT_VARIABLE_DECLARATION);
- }
-
- test_splitVariableDeclaration_OK_onName() async {
- await resolveTestUnit('''
-main() {
- var v = 1;
-}
-''');
- await assertHasAssistAt(
- 'v =', DartAssistKind.SPLIT_VARIABLE_DECLARATION, '''
-main() {
- var v;
- v = 1;
-}
-''');
- }
-
- test_splitVariableDeclaration_OK_onType() async {
- await resolveTestUnit('''
-main() {
- int v = 1;
-}
-''');
- await assertHasAssistAt(
- 'int ', DartAssistKind.SPLIT_VARIABLE_DECLARATION, '''
-main() {
- int v;
- v = 1;
-}
-''');
- }
-
- test_splitVariableDeclaration_OK_onVar() async {
- await resolveTestUnit('''
-main() {
- var v = 1;
-}
-''');
- await assertHasAssistAt(
- 'var ', DartAssistKind.SPLIT_VARIABLE_DECLARATION, '''
-main() {
- var v;
- v = 1;
-}
-''');
- }
-
- test_surroundWith_block() async {
- await resolveTestUnit('''
-main() {
-// start
- print(0);
- print(1);
-// end
-}
-''');
- _setStartEndSelection();
- await assertHasAssist(DartAssistKind.SURROUND_WITH_BLOCK, '''
-main() {
-// start
- {
- print(0);
- print(1);
- }
-// end
-}
-''');
- }
-
- test_surroundWith_doWhile() async {
- await resolveTestUnit('''
-main() {
-// start
- print(0);
- print(1);
-// end
-}
-''');
- _setStartEndSelection();
- await assertHasAssist(DartAssistKind.SURROUND_WITH_DO_WHILE, '''
-main() {
-// start
- do {
- print(0);
- print(1);
- } while (condition);
-// end
-}
-''');
- _assertLinkedGroup(change.linkedEditGroups[0], ['condition);']);
- _assertExitPosition(after: 'condition);');
- }
-
- test_surroundWith_for() async {
- await resolveTestUnit('''
-main() {
-// start
- print(0);
- print(1);
-// end
-}
-''');
- _setStartEndSelection();
- await assertHasAssist(DartAssistKind.SURROUND_WITH_FOR, '''
-main() {
-// start
- for (var v = init; condition; increment) {
- print(0);
- print(1);
- }
-// end
-}
-''');
- _assertLinkedGroup(change.linkedEditGroups[0], ['v =']);
- _assertLinkedGroup(change.linkedEditGroups[1], ['init;']);
- _assertLinkedGroup(change.linkedEditGroups[2], ['condition;']);
- _assertLinkedGroup(change.linkedEditGroups[3], ['increment']);
- _assertExitPosition(after: ' }');
- }
-
- test_surroundWith_forIn() async {
- await resolveTestUnit('''
-main() {
-// start
- print(0);
- print(1);
-// end
-}
-''');
- _setStartEndSelection();
- await assertHasAssist(DartAssistKind.SURROUND_WITH_FOR_IN, '''
-main() {
-// start
- for (var item in iterable) {
- print(0);
- print(1);
- }
-// end
-}
-''');
- _assertLinkedGroup(change.linkedEditGroups[0], ['item']);
- _assertLinkedGroup(change.linkedEditGroups[1], ['iterable']);
- _assertExitPosition(after: ' }');
- }
-
- test_surroundWith_if() async {
- await resolveTestUnit('''
-main() {
-// start
- print(0);
- print(1);
-// end
-}
-''');
- _setStartEndSelection();
- await assertHasAssist(DartAssistKind.SURROUND_WITH_IF, '''
-main() {
-// start
- if (condition) {
- print(0);
- print(1);
- }
-// end
-}
-''');
- _assertLinkedGroup(change.linkedEditGroups[0], ['condition']);
- _assertExitPosition(after: ' }');
- }
-
- test_surroundWith_tryCatch() async {
- await resolveTestUnit('''
-main() {
-// start
- print(0);
- print(1);
-// end
-}
-''');
- _setStartEndSelection();
- await assertHasAssist(DartAssistKind.SURROUND_WITH_TRY_CATCH, '''
-main() {
-// start
- try {
- print(0);
- print(1);
- } on Exception catch (e) {
- // TODO
- }
-// end
-}
-''');
- _assertLinkedGroup(change.linkedEditGroups[0], ['Exception']);
- _assertLinkedGroup(change.linkedEditGroups[1], ['e) {']);
- _assertLinkedGroup(change.linkedEditGroups[2], ['// TODO']);
- _assertExitPosition(after: '// TODO');
- }
-
- test_surroundWith_tryFinally() async {
- await resolveTestUnit('''
-main() {
-// start
- print(0);
- print(1);
-// end
-}
-''');
- _setStartEndSelection();
- await assertHasAssist(DartAssistKind.SURROUND_WITH_TRY_FINALLY, '''
-main() {
-// start
- try {
- print(0);
- print(1);
- } finally {
- // TODO
- }
-// end
-}
-''');
- _assertLinkedGroup(change.linkedEditGroups[0], ['// TODO']);
- _assertExitPosition(after: '// TODO');
- }
-
- test_surroundWith_while() async {
- await resolveTestUnit('''
-main() {
-// start
- print(0);
- print(1);
-// end
-}
-''');
- _setStartEndSelection();
- await assertHasAssist(DartAssistKind.SURROUND_WITH_WHILE, '''
-main() {
-// start
- while (condition) {
- print(0);
- print(1);
- }
-// end
-}
-''');
- _assertLinkedGroup(change.linkedEditGroups[0], ['condition']);
- _assertExitPosition(after: ' }');
- }
-
- void _assertExitPosition({String before, String after}) {
- Position exitPosition = change.selection;
- expect(exitPosition, isNotNull);
- expect(exitPosition.file, testFile);
- if (before != null) {
- expect(exitPosition.offset, resultCode.indexOf(before));
- } else if (after != null) {
- expect(exitPosition.offset, resultCode.indexOf(after) + after.length);
- } else {
- fail("One of 'before' or 'after' expected.");
- }
- }
-
- /**
- * Computes assists and verifies that there is an assist of the given kind.
- */
- Future<Assist> _assertHasAssist(AssistKind kind) async {
- List<Assist> assists = await _computeAssists();
- for (Assist assist in assists) {
- if (assist.kind == kind) {
- return assist;
- }
- }
- fail('Expected to find assist $kind in\n${assists.join('\n')}');
- }
-
- void _assertLinkedGroup(LinkedEditGroup group, List<String> expectedStrings,
- [List<LinkedEditSuggestion> expectedSuggestions]) {
- List<Position> expectedPositions = _findResultPositions(expectedStrings);
- expect(group.positions, unorderedEquals(expectedPositions));
- if (expectedSuggestions != null) {
- expect(group.suggestions, unorderedEquals(expectedSuggestions));
- }
- }
-
- Future<List<Assist>> _computeAssists() async {
- CompilationUnitElement testUnitElement =
- resolutionMap.elementDeclaredByCompilationUnit(testUnit);
- DartAssistContext assistContext;
- assistContext = new _DartAssistContextForValues(
- testUnitElement.source, offset, length, driver, testUnit);
- AssistProcessor processor = new AssistProcessor(assistContext);
- return await processor.compute();
- }
-
- List<Position> _findResultPositions(List<String> searchStrings) {
- List<Position> positions = <Position>[];
- for (String search in searchStrings) {
- int offset = resultCode.indexOf(search);
- positions.add(new Position(testFile, offset));
- }
- return positions;
- }
-
- void _setCaretLocation() {
- offset = findOffset('/*caret*/') + '/*caret*/'.length;
- length = 0;
- }
-
- void _setStartEndSelection() {
- offset = findOffset('// start\n') + '// start\n'.length;
- length = findOffset('// end') - offset;
- }
-}
-
-class _DartAssistContextForValues implements DartAssistContext {
- @override
- final Source source;
-
- @override
- final int selectionOffset;
-
- @override
- final int selectionLength;
-
- @override
- final AnalysisDriver analysisDriver;
-
- @override
- final CompilationUnit unit;
-
- _DartAssistContextForValues(this.source, this.selectionOffset,
- this.selectionLength, this.analysisDriver, this.unit);
-}
diff --git a/pkg/analysis_server/test/services/correction/fix_test.dart b/pkg/analysis_server/test/services/correction/fix_test.dart
deleted file mode 100644
index db6d6b7..0000000
--- a/pkg/analysis_server/test/services/correction/fix_test.dart
+++ /dev/null
@@ -1,8840 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-
-import 'package:analysis_server/plugin/edit/fix/fix_core.dart';
-import 'package:analysis_server/plugin/edit/fix/fix_dart.dart';
-import 'package:analysis_server/src/services/correction/fix.dart';
-import 'package:analysis_server/src/services/correction/fix_internal.dart';
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/standard_resolution_map.dart';
-import 'package:analyzer/error/error.dart';
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/dart/analysis/ast_provider_driver.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
-import 'package:analyzer/src/dart/element/ast_provider.dart';
-import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/parser.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/source/package_map_resolver.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart'
- hide AnalysisError;
-import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../../abstract_single_unit.dart';
-
-main() {
- defineReflectiveSuite(() {
- defineReflectiveTests(FixProcessorTest);
- defineReflectiveTests(LintFixTest);
- });
-}
-
-typedef bool AnalysisErrorFilter(AnalysisError error);
-
-/**
- * Base class for fix processor tests.
- */
-class BaseFixProcessorTest extends AbstractSingleUnitTest {
- AnalysisErrorFilter errorFilter = (AnalysisError error) {
- return error.errorCode != HintCode.UNUSED_CATCH_CLAUSE &&
- error.errorCode != HintCode.UNUSED_CATCH_STACK &&
- error.errorCode != HintCode.UNUSED_ELEMENT &&
- error.errorCode != HintCode.UNUSED_FIELD &&
- error.errorCode != HintCode.UNUSED_LOCAL_VARIABLE;
- };
-
- String myPkgLibPath = '/packages/my_pkg/lib';
-
- String flutterPkgLibPath = '/packages/flutter/lib';
-
- Fix fix;
-
- SourceChange change;
- String resultCode;
-
- assert_undefinedFunction_create_returnType_bool(String lineWithTest) async {
- await resolveTestUnit('''
-main() {
- bool b = true;
- $lineWithTest
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FUNCTION, '''
-main() {
- bool b = true;
- $lineWithTest
-}
-
-bool test() {
-}
-''');
- }
-
- assertHasFix(FixKind kind, String expected, {String target}) async {
- AnalysisError error = await _findErrorToFix();
- fix = await _assertHasFix(kind, error);
- change = fix.change;
-
- // apply to "file"
- List<SourceFileEdit> fileEdits = change.edits;
- expect(fileEdits, hasLength(1));
-
- String fileContent = testCode;
- if (target != null) {
- expect(fileEdits.first.file, convertPath(target));
- fileContent = getFile(target).readAsStringSync();
- }
-
- resultCode = SourceEdit.applySequence(fileContent, change.edits[0].edits);
- // verify
- expect(resultCode, expected);
- }
-
- assertHasFixAllFix(ErrorCode errorCode, FixKind kind, String expected,
- {String target}) async {
- AnalysisError error = await _findErrorToFixOfType(errorCode);
- fix = await _assertHasFix(kind, error, hasFixAllFix: true);
- change = fix.change;
-
- // apply to "file"
- List<SourceFileEdit> fileEdits = change.edits;
- expect(fileEdits, hasLength(1));
-
- String fileContent = testCode;
- if (target != null) {
- expect(fileEdits.first.file, convertPath(target));
- fileContent = getFile(target).readAsStringSync();
- }
-
- resultCode = SourceEdit.applySequence(fileContent, change.edits[0].edits);
- // verify
- expect(resultCode, expected);
- }
-
- assertNoFix(FixKind kind) async {
- AnalysisError error = await _findErrorToFix();
- await _assertNoFix(kind, error);
- }
-
- List<LinkedEditSuggestion> expectedSuggestions(
- LinkedEditSuggestionKind kind, List<String> values) {
- return values.map((value) {
- return new LinkedEditSuggestion(value, kind);
- }).toList();
- }
-
- void setUp() {
- super.setUp();
- verifyNoTestUnitErrors = false;
- }
-
- /**
- * Computes fixes and verifies that there is a fix of the given kind.
- */
- Future<Fix> _assertHasFix(FixKind kind, AnalysisError error,
- {bool hasFixAllFix: false}) async {
- if (hasFixAllFix && !kind.canBeAppliedTogether()) {
- fail('Expected to find and return fix-all FixKind for $kind, '
- 'but kind.canBeAppliedTogether is ${kind.canBeAppliedTogether}');
- }
-
- // Compute the fixes for this AnalysisError
- final List<Fix> fixes = await _computeFixes(error);
-
- // If hasFixAllFix is false, assert that none of the fixes are a fix-all fix
- if (!hasFixAllFix) {
- for (Fix fix in fixes) {
- if (fix.isFixAllFix()) {
- fail('The boolean hasFixAllFix is false, but such a fix was found '
- 'in the computed set of fixes: $fixes, error: $error.');
- }
- }
- }
- // If hasFixAllFix is true, assert that there exists such a fix in the list
- else {
- bool foundFixAllFix = false;
- for (Fix fix in fixes) {
- if (fix.isFixAllFix()) {
- foundFixAllFix = true;
- break;
- }
- }
- if (!foundFixAllFix) {
- fail('The boolean hasFixAllFix is true, but no fix-all fix was found '
- 'in the computed set of fixes: $fixes, error: $error.');
- }
- }
-
- Fix foundFix = null;
- if (!hasFixAllFix) {
- foundFix = fixes.firstWhere(
- (fix) => fix.kind == kind && !fix.isFixAllFix(),
- orElse: () => null,
- );
- } else {
- foundFix = fixes.lastWhere(
- (fix) => fix.kind == kind && fix.isFixAllFix(),
- orElse: () => null,
- );
- }
- if (foundFix == null) {
- fail('Expected to find fix $kind in\n${fixes.join('\n')}, hasFixAllFix = '
- '$hasFixAllFix');
- }
- return foundFix;
- }
-
- void _assertLinkedGroup(LinkedEditGroup group, List<String> expectedStrings,
- [List<LinkedEditSuggestion> expectedSuggestions]) {
- List<Position> expectedPositions = _findResultPositions(expectedStrings);
- expect(group.positions, unorderedEquals(expectedPositions));
- if (expectedSuggestions != null) {
- expect(group.suggestions, unorderedEquals(expectedSuggestions));
- }
- }
-
- Future _assertNoFix(FixKind kind, AnalysisError error) async {
- List<Fix> fixes = await _computeFixes(error);
- for (Fix fix in fixes) {
- if (fix.kind == kind) {
- fail('Unexpected fix $kind in\n${fixes.join('\n')}');
- }
- }
- }
-
- Future<List<AnalysisError>> _computeErrors() async {
- return (await driver.getResult(convertPath(testFile))).errors;
- }
-
- /**
- * Computes fixes for the given [error] in [testUnit].
- */
- Future<List<Fix>> _computeFixes(AnalysisError error) async {
- DartFixContext fixContext = new _DartFixContextImpl(
- resourceProvider,
- driver,
- new AstProviderForDriver(driver),
- testUnit,
- error,
- await _computeErrors());
- return await new DefaultFixContributor().internalComputeFixes(fixContext);
- }
-
- /**
- * Configures the [SourceFactory] to have the `my_pkg` package in
- * `/packages/my_pkg/lib` folder.
- */
- void _configureMyPkg(Map<String, String> pathToCode) {
- pathToCode.forEach((path, code) {
- newFile('$myPkgLibPath/$path', content: code);
- });
- // configure SourceFactory
- Folder myPkgFolder = getFolder(myPkgLibPath);
- UriResolver pkgResolver = new PackageMapUriResolver(resourceProvider, {
- 'my_pkg': [myPkgFolder]
- });
- SourceFactory sourceFactory = new SourceFactory(
- [new DartUriResolver(sdk), pkgResolver, resourceResolver]);
- driver.configure(sourceFactory: sourceFactory);
- // force 'my_pkg' resolution
- addSource(
- '/tmp/other.dart',
- pathToCode.keys
- .map((path) => "import 'package:my_pkg/$path';")
- .join('\n'));
- }
-
- Future<AnalysisError> _findErrorToFix() async {
- List<AnalysisError> errors = await _computeErrors();
- List<AnalysisError> filteredErrors = errors;
- if (errorFilter != null) {
- filteredErrors = filteredErrors.where(errorFilter).toList();
- }
- if (filteredErrors.length != 1) {
- StringBuffer buffer = new StringBuffer();
- buffer.writeln('Expected one error, found:');
- for (AnalysisError error in errors) {
- buffer.writeln(' $error [${error.errorCode}]');
- }
- fail(buffer.toString());
- }
- return filteredErrors[0];
- }
-
- Future<AnalysisError> _findErrorToFixOfType(ErrorCode errorCode) async {
- List<AnalysisError> errors = await _computeErrors();
- if (errorFilter != null) {
- errors = errors.where(errorFilter).toList();
- }
- return errors.firstWhere((error) => errorCode == error.errorCode);
- }
-
- List<Position> _findResultPositions(List<String> searchStrings) {
- List<Position> positions = <Position>[];
- for (String search in searchStrings) {
- int offset = resultCode.indexOf(search);
- positions.add(new Position(testFile, offset));
- }
- return positions;
- }
-}
-
-@reflectiveTest
-class FixProcessorTest extends BaseFixProcessorTest {
- test_addAsync_asyncFor() async {
- await resolveTestUnit('''
-import 'dart:async';
-void main(Stream<String> names) {
- await for (String name in names) {
- print(name);
- }
-}
-''');
- await assertHasFix(DartFixKind.ADD_ASYNC, '''
-import 'dart:async';
-Future main(Stream<String> names) async {
- await for (String name in names) {
- print(name);
- }
-}
-''');
- }
-
- test_addAsync_BAD_nullFunctionBody() async {
- await resolveTestUnit('''
-var F = await;
-''');
- await assertNoFix(DartFixKind.ADD_ASYNC);
- }
-
- test_addAsync_blockFunctionBody() async {
- errorFilter = (AnalysisError error) {
- return error.errorCode ==
- CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE;
- };
- await resolveTestUnit('''
-foo() {}
-main() {
- await foo();
-}
-''');
- await assertHasFix(DartFixKind.ADD_ASYNC, '''
-foo() {}
-main() async {
- await foo();
-}
-''');
- }
-
- test_addAsync_blockFunctionBody_getter() async {
- errorFilter = (AnalysisError error) {
- return error.errorCode ==
- CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE;
- };
- await resolveTestUnit('''
-int get foo => null;
-int f() {
- await foo;
- return 1;
-}
-''');
- await assertHasFix(DartFixKind.ADD_ASYNC, '''
-import \'dart:async\';
-
-int get foo => null;
-Future<int> f() async {
- await foo;
- return 1;
-}
-''');
- }
-
- test_addAsync_closure() async {
- errorFilter = (AnalysisError error) {
- return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT;
- };
- await resolveTestUnit('''
-import 'dart:async';
-
-void takeFutureCallback(Future callback()) {}
-
-void doStuff() => takeFutureCallback(() => await 1);
-''');
- await assertHasFix(DartFixKind.ADD_ASYNC, '''
-import 'dart:async';
-
-void takeFutureCallback(Future callback()) {}
-
-void doStuff() => takeFutureCallback(() async => await 1);
-''');
- }
-
- test_addAsync_expressionFunctionBody() async {
- errorFilter = (AnalysisError error) {
- return error.errorCode == ParserErrorCode.UNEXPECTED_TOKEN;
- };
- await resolveTestUnit('''
-foo() {}
-main() => await foo();
-''');
- await assertHasFix(DartFixKind.ADD_ASYNC, '''
-foo() {}
-main() async => await foo();
-''');
- }
-
- test_addAsync_returnFuture() async {
- errorFilter = (AnalysisError error) {
- return error.errorCode ==
- CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE;
- };
- await resolveTestUnit('''
-foo() {}
-int main() {
- await foo();
- return 42;
-}
-''');
- await assertHasFix(DartFixKind.ADD_ASYNC, '''
-import 'dart:async';
-
-foo() {}
-Future<int> main() async {
- await foo();
- return 42;
-}
-''');
- }
-
- test_addAsync_returnFuture_alreadyFuture() async {
- errorFilter = (AnalysisError error) {
- return error.errorCode ==
- CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE;
- };
- await resolveTestUnit('''
-import 'dart:async';
-foo() {}
-Future<int> main() {
- await foo();
- return 42;
-}
-''');
- await assertHasFix(DartFixKind.ADD_ASYNC, '''
-import 'dart:async';
-foo() {}
-Future<int> main() async {
- await foo();
- return 42;
-}
-''');
- }
-
- test_addAsync_returnFuture_dynamic() async {
- errorFilter = (AnalysisError error) {
- return error.errorCode ==
- CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE;
- };
- await resolveTestUnit('''
-foo() {}
-dynamic main() {
- await foo();
- return 42;
-}
-''');
- await assertHasFix(DartFixKind.ADD_ASYNC, '''
-foo() {}
-dynamic main() async {
- await foo();
- return 42;
-}
-''');
- }
-
- test_addAsync_returnFuture_noType() async {
- errorFilter = (AnalysisError error) {
- return error.errorCode ==
- CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE;
- };
- await resolveTestUnit('''
-foo() {}
-main() {
- await foo();
- return 42;
-}
-''');
- await assertHasFix(DartFixKind.ADD_ASYNC, '''
-foo() {}
-main() async {
- await foo();
- return 42;
-}
-''');
- }
-
- test_addExplicitCast_assignment_general() async {
- await resolveTestUnit('''
-f(A a) {
- B b;
- b = a;
-}
-class A {}
-class B {}
-''');
- await assertHasFix(DartFixKind.ADD_EXPLICIT_CAST, '''
-f(A a) {
- B b;
- b = a as B;
-}
-class A {}
-class B {}
-''');
- }
-
- test_addExplicitCast_assignment_general_all() async {
- await resolveTestUnit('''
-f(A a) {
- B b, b2;
- b = a;
- b2 = a;
-}
-class A {}
-class B {}
-''');
- await assertHasFixAllFix(StaticTypeWarningCode.INVALID_ASSIGNMENT,
- DartFixKind.ADD_EXPLICIT_CAST, '''
-f(A a) {
- B b, b2;
- b = a as B;
- b2 = a as B;
-}
-class A {}
-class B {}
-''');
- }
-
- test_addExplicitCast_assignment_list() async {
- await resolveTestUnit('''
-f(List<A> a) {
- List<B> b;
- b = a.where((e) => e is B).toList();
-}
-class A {}
-class B {}
-''');
- await assertHasFix(DartFixKind.ADD_EXPLICIT_CAST, '''
-f(List<A> a) {
- List<B> b;
- b = a.where((e) => e is B).cast<B>().toList();
-}
-class A {}
-class B {}
-''');
- }
-
- test_addExplicitCast_assignment_list_all() async {
- await resolveTestUnit('''
-f(List<A> a) {
- List<B> b, b2;
- b = a.where((e) => e is B).toList();
- b2 = a.where((e) => e is B).toList();
-}
-class A {}
-class B {}
-''');
- await assertHasFixAllFix(StaticTypeWarningCode.INVALID_ASSIGNMENT,
- DartFixKind.ADD_EXPLICIT_CAST, '''
-f(List<A> a) {
- List<B> b, b2;
- b = a.where((e) => e is B).cast<B>().toList();
- b2 = a.where((e) => e is B).cast<B>().toList();
-}
-class A {}
-class B {}
-''');
- }
-
- test_addExplicitCast_assignment_map() async {
- await resolveTestUnit('''
-f(Map<A, B> a) {
- Map<B, A> b;
- b = a;
-}
-class A {}
-class B {}
-''');
- await assertHasFix(DartFixKind.ADD_EXPLICIT_CAST, '''
-f(Map<A, B> a) {
- Map<B, A> b;
- b = a.cast<B, A>();
-}
-class A {}
-class B {}
-''');
- }
-
- test_addExplicitCast_assignment_map_all() async {
- await resolveTestUnit('''
-f(Map<A, B> a) {
- Map<B, A> b, b2;
- b = a;
- b2 = a;
-}
-class A {}
-class B {}
-''');
- await assertHasFixAllFix(StaticTypeWarningCode.INVALID_ASSIGNMENT,
- DartFixKind.ADD_EXPLICIT_CAST, '''
-f(Map<A, B> a) {
- Map<B, A> b, b2;
- b = a.cast<B, A>();
- b2 = a.cast<B, A>();
-}
-class A {}
-class B {}
-''');
- }
-
- test_addExplicitCast_assignment_needsParens() async {
- await resolveTestUnit('''
-f(A a) {
- B b;
- b = a..m();
-}
-class A {
- int m() => 0;
-}
-class B {}
-''');
- await assertHasFix(DartFixKind.ADD_EXPLICIT_CAST, '''
-f(A a) {
- B b;
- b = (a..m()) as B;
-}
-class A {
- int m() => 0;
-}
-class B {}
-''');
- }
-
- test_addExplicitCast_assignment_needsParens_all() async {
- await resolveTestUnit('''
-f(A a) {
- B b, b2;
- b = a..m();
- b2 = a..m();
-}
-class A {
- int m() => 0;
-}
-class B {}
-''');
- await assertHasFixAllFix(StaticTypeWarningCode.INVALID_ASSIGNMENT,
- DartFixKind.ADD_EXPLICIT_CAST, '''
-f(A a) {
- B b, b2;
- b = (a..m()) as B;
- b2 = (a..m()) as B;
-}
-class A {
- int m() => 0;
-}
-class B {}
-''');
- }
-
- test_addExplicitCast_assignment_set() async {
- await resolveTestUnit('''
-f(Set<A> a) {
- Set<B> b;
- b = a;
-}
-class A {}
-class B {}
-''');
- await assertHasFix(DartFixKind.ADD_EXPLICIT_CAST, '''
-f(Set<A> a) {
- Set<B> b;
- b = a.cast<B>();
-}
-class A {}
-class B {}
-''');
- }
-
- test_addExplicitCast_assignment_set_all() async {
- await resolveTestUnit('''
-f(Set<A> a) {
- Set<B> b, b2;
- b = a;
- b2 = a;
-}
-class A {}
-class B {}
-''');
- await assertHasFixAllFix(StaticTypeWarningCode.INVALID_ASSIGNMENT,
- DartFixKind.ADD_EXPLICIT_CAST, '''
-f(Set<A> a) {
- Set<B> b, b2;
- b = a.cast<B>();
- b2 = a.cast<B>();
-}
-class A {}
-class B {}
-''');
- }
-
- test_addExplicitCast_BAD_as() async {
- await resolveTestUnit('''
-f(A a) {
- C c = a as B;
-}
-class A {}
-class B {}
-class C {}
-''');
- await assertNoFix(DartFixKind.ADD_EXPLICIT_CAST);
- }
-
- test_addExplicitCast_BAD_cast() async {
- await resolveTestUnit('''
-f(List<A> a) {
- List<B> b = a.cast<A>();
-}
-class A {}
-class B {}
-''');
- await assertNoFix(DartFixKind.ADD_EXPLICIT_CAST);
- }
-
- test_addExplicitCast_declaration_general() async {
- await resolveTestUnit('''
-f(A a) {
- B b = a;
-}
-class A {}
-class B {}
-''');
- await assertHasFix(DartFixKind.ADD_EXPLICIT_CAST, '''
-f(A a) {
- B b = a as B;
-}
-class A {}
-class B {}
-''');
- }
-
- test_addExplicitCast_declaration_general_all() async {
- await resolveTestUnit('''
-f(A a) {
- B b = a;
- B b2 = a;
-}
-class A {}
-class B {}
-''');
- await assertHasFixAllFix(StaticTypeWarningCode.INVALID_ASSIGNMENT,
- DartFixKind.ADD_EXPLICIT_CAST, '''
-f(A a) {
- B b = a as B;
- B b2 = a as B;
-}
-class A {}
-class B {}
-''');
- }
-
- test_addExplicitCast_declaration_list() async {
- await resolveTestUnit('''
-f(List<A> a) {
- List<B> b = a.where((e) => e is B).toList();
-}
-class A {}
-class B {}
-''');
- await assertHasFix(DartFixKind.ADD_EXPLICIT_CAST, '''
-f(List<A> a) {
- List<B> b = a.where((e) => e is B).cast<B>().toList();
-}
-class A {}
-class B {}
-''');
- }
-
- test_addExplicitCast_declaration_list_all() async {
- await resolveTestUnit('''
-f(List<A> a) {
- List<B> b = a.where((e) => e is B).toList();
- List<B> b2 = a.where((e) => e is B).toList();
-}
-class A {}
-class B {}
-''');
- await assertHasFixAllFix(StaticTypeWarningCode.INVALID_ASSIGNMENT,
- DartFixKind.ADD_EXPLICIT_CAST, '''
-f(List<A> a) {
- List<B> b = a.where((e) => e is B).cast<B>().toList();
- List<B> b2 = a.where((e) => e is B).cast<B>().toList();
-}
-class A {}
-class B {}
-''');
- }
-
- test_addExplicitCast_declaration_map() async {
- await resolveTestUnit('''
-f(Map<A, B> a) {
- Map<B, A> b = a;
-}
-class A {}
-class B {}
-''');
- await assertHasFix(DartFixKind.ADD_EXPLICIT_CAST, '''
-f(Map<A, B> a) {
- Map<B, A> b = a.cast<B, A>();
-}
-class A {}
-class B {}
-''');
- }
-
- test_addExplicitCast_declaration_map_all() async {
- await resolveTestUnit('''
-f(Map<A, B> a) {
- Map<B, A> b = a;
- Map<B, A> b2 = a;
-}
-class A {}
-class B {}
-''');
- await assertHasFixAllFix(StaticTypeWarningCode.INVALID_ASSIGNMENT,
- DartFixKind.ADD_EXPLICIT_CAST, '''
-f(Map<A, B> a) {
- Map<B, A> b = a.cast<B, A>();
- Map<B, A> b2 = a.cast<B, A>();
-}
-class A {}
-class B {}
-''');
- }
-
- test_addExplicitCast_declaration_needsParens() async {
- await resolveTestUnit('''
-f(A a) {
- B b = a..m();
-}
-class A {
- int m() => 0;
-}
-class B {}
-''');
- await assertHasFix(DartFixKind.ADD_EXPLICIT_CAST, '''
-f(A a) {
- B b = (a..m()) as B;
-}
-class A {
- int m() => 0;
-}
-class B {}
-''');
- }
-
- test_addExplicitCast_declaration_needsParens_all() async {
- await resolveTestUnit('''
-f(A a) {
- B b = a..m();
- B b2 = a..m();
-}
-class A {
- int m() => 0;
-}
-class B {}
-''');
- await assertHasFixAllFix(StaticTypeWarningCode.INVALID_ASSIGNMENT,
- DartFixKind.ADD_EXPLICIT_CAST, '''
-f(A a) {
- B b = (a..m()) as B;
- B b2 = (a..m()) as B;
-}
-class A {
- int m() => 0;
-}
-class B {}
-''');
- }
-
- test_addExplicitCast_declaration_set() async {
- await resolveTestUnit('''
-f(Set<A> a) {
- Set<B> b = a;
-}
-class A {}
-class B {}
-''');
- await assertHasFix(DartFixKind.ADD_EXPLICIT_CAST, '''
-f(Set<A> a) {
- Set<B> b = a.cast<B>();
-}
-class A {}
-class B {}
-''');
- }
-
- test_addExplicitCast_declaration_set_all() async {
- await resolveTestUnit('''
-f(Set<A> a) {
- Set<B> b = a;
- Set<B> b2 = a;
-}
-class A {}
-class B {}
-''');
- await assertHasFixAllFix(StaticTypeWarningCode.INVALID_ASSIGNMENT,
- DartFixKind.ADD_EXPLICIT_CAST, '''
-f(Set<A> a) {
- Set<B> b = a.cast<B>();
- Set<B> b2 = a.cast<B>();
-}
-class A {}
-class B {}
-''');
- }
-
- test_addFieldFormalParameters_flutter() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-
-class MyWidget extends StatelessWidget {
- final int a;
- final int b;
- final int c;
-
- MyWidget({Key key, this.a}) : super(key: key);
-}
-''');
- await assertHasFix(DartFixKind.ADD_FIELD_FORMAL_PARAMETERS, '''
-import 'package:flutter/widgets.dart';
-
-class MyWidget extends StatelessWidget {
- final int a;
- final int b;
- final int c;
-
- MyWidget({Key key, this.a, this.b, this.c}) : super(key: key);
-}
-''');
- }
-
- test_addFieldFormalParameters_hasRequiredParameter() async {
- await resolveTestUnit('''
-class Test {
- final int a;
- final int b;
- final int c;
- Test(this.a);
-}
-''');
- await assertHasFix(DartFixKind.ADD_FIELD_FORMAL_PARAMETERS, '''
-class Test {
- final int a;
- final int b;
- final int c;
- Test(this.a, this.b, this.c);
-}
-''');
- }
-
- test_addFieldFormalParameters_noParameters() async {
- await resolveTestUnit('''
-class Test {
- final int a;
- final int b;
- final int c;
- Test();
-}
-''');
- await assertHasFix(DartFixKind.ADD_FIELD_FORMAL_PARAMETERS, '''
-class Test {
- final int a;
- final int b;
- final int c;
- Test(this.a, this.b, this.c);
-}
-''');
- }
-
- test_addFieldFormalParameters_noRequiredParameter() async {
- await resolveTestUnit('''
-class Test {
- final int a;
- final int b;
- final int c;
- Test([this.c]);
-}
-''');
- await assertHasFix(DartFixKind.ADD_FIELD_FORMAL_PARAMETERS, '''
-class Test {
- final int a;
- final int b;
- final int c;
- Test(this.a, this.b, [this.c]);
-}
-''');
- }
-
- test_addFieldFormalParameters_notAllFinal() async {
- await resolveTestUnit('''
-class Test {
- final int a;
- int b;
- final int c;
- Test();
-}
-''');
- await assertHasFix(DartFixKind.ADD_FIELD_FORMAL_PARAMETERS, '''
-class Test {
- final int a;
- int b;
- final int c;
- Test(this.a, this.c);
-}
-''');
- }
-
- test_addMissingParameter_constructor_named_required_hasOne() async {
- await resolveTestUnit('''
-class A {
- A.named(int a) {}
-}
-main() {
- new A.named(1, 2.0);
-}
-''');
- await assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_REQUIRED, '''
-class A {
- A.named(int a, double d) {}
-}
-main() {
- new A.named(1, 2.0);
-}
-''');
- }
-
- test_addMissingParameter_constructor_unnamed_required_hasOne() async {
- await resolveTestUnit('''
-class A {
- A(int a) {}
-}
-main() {
- new A(1, 2.0);
-}
-''');
- await assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_REQUIRED, '''
-class A {
- A(int a, double d) {}
-}
-main() {
- new A(1, 2.0);
-}
-''');
- }
-
- test_addMissingParameter_function_positional_hasNamed() async {
- await resolveTestUnit('''
-test({int a}) {}
-main() {
- test(1);
-}
-''');
- await assertNoFix(DartFixKind.ADD_MISSING_PARAMETER_POSITIONAL);
- }
-
- test_addMissingParameter_function_positional_hasZero() async {
- await resolveTestUnit('''
-test() {}
-main() {
- test(1);
-}
-''');
- await assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_POSITIONAL, '''
-test([int i]) {}
-main() {
- test(1);
-}
-''');
- }
-
- test_addMissingParameter_function_required_hasNamed() async {
- await resolveTestUnit('''
-test({int a}) {}
-main() {
- test(1);
-}
-''');
- await assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_REQUIRED, '''
-test(int i, {int a}) {}
-main() {
- test(1);
-}
-''');
- }
-
- test_addMissingParameter_function_required_hasOne() async {
- await resolveTestUnit('''
-test(int a) {}
-main() {
- test(1, 2.0);
-}
-''');
- await assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_REQUIRED, '''
-test(int a, double d) {}
-main() {
- test(1, 2.0);
-}
-''');
- }
-
- test_addMissingParameter_function_required_hasZero() async {
- await resolveTestUnit('''
-test() {}
-main() {
- test(1);
-}
-''');
- await assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_REQUIRED, '''
-test(int i) {}
-main() {
- test(1);
-}
-''');
- }
-
- test_addMissingParameter_method_positional_hasOne() async {
- await resolveTestUnit('''
-class A {
- test(int a) {}
- main() {
- test(1, 2.0);
- }
-}
-''');
- await assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_POSITIONAL, '''
-class A {
- test(int a, [double d]) {}
- main() {
- test(1, 2.0);
- }
-}
-''');
- }
-
- test_addMissingParameter_method_required_hasOne() async {
- await resolveTestUnit('''
-class A {
- test(int a) {}
- main() {
- test(1, 2.0);
- }
-}
-''');
- await assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_REQUIRED, '''
-class A {
- test(int a, double d) {}
- main() {
- test(1, 2.0);
- }
-}
-''');
- }
-
- test_addMissingParameter_method_required_hasZero() async {
- await resolveTestUnit('''
-class A {
- test() {}
- main() {
- test(1);
- }
-}
-''');
- await assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_REQUIRED, '''
-class A {
- test(int i) {}
- main() {
- test(1);
- }
-}
-''');
- }
-
- test_addMissingParameterNamed_constructor_hasNamed() async {
- await resolveTestUnit('''
-class A {
- A(int a, {int b}) {}
-}
-
-main() {
- new A(1, b: 2, named: 3.0);
-}
-''');
- await assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_NAMED, '''
-class A {
- A(int a, {int b, double named}) {}
-}
-
-main() {
- new A(1, b: 2, named: 3.0);
-}
-''');
- }
-
- test_addMissingParameterNamed_constructor_hasRequired() async {
- await resolveTestUnit('''
-class A {
- A(int a) {}
-}
-
-main() {
- new A(1, named: 2.0);
-}
-''');
- await assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_NAMED, '''
-class A {
- A(int a, {double named}) {}
-}
-
-main() {
- new A(1, named: 2.0);
-}
-''');
- }
-
- test_addMissingParameterNamed_constructor_noParameters() async {
- await resolveTestUnit('''
-class A {
- A() {}
-}
-
-main() {
- new A(named: 42);
-}
-''');
- await assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_NAMED, '''
-class A {
- A({int named}) {}
-}
-
-main() {
- new A(named: 42);
-}
-''');
- }
-
- test_addMissingParameterNamed_constructor_noParameters_named() async {
- await resolveTestUnit('''
-class A {
- A.aaa() {}
-}
-
-main() {
- new A.aaa(named: 42);
-}
-''');
- await assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_NAMED, '''
-class A {
- A.aaa({int named}) {}
-}
-
-main() {
- new A.aaa(named: 42);
-}
-''');
- }
-
- test_addMissingParameterNamed_function_hasNamed() async {
- await resolveTestUnit('''
-test(int a, {int b: 0}) {}
-
-main() {
- test(1, b: 2, named: 3.0);
-}
-''');
- await assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_NAMED, '''
-test(int a, {int b: 0, double named}) {}
-
-main() {
- test(1, b: 2, named: 3.0);
-}
-''');
- }
-
- test_addMissingParameterNamed_function_hasRequired() async {
- await resolveTestUnit('''
-test(int a) {}
-
-main() {
- test(1, named: 2.0);
-}
-''');
- await assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_NAMED, '''
-test(int a, {double named}) {}
-
-main() {
- test(1, named: 2.0);
-}
-''');
- }
-
- test_addMissingParameterNamed_function_noParameters() async {
- await resolveTestUnit('''
-test() {}
-
-main() {
- test(named: 42);
-}
-''');
- await assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_NAMED, '''
-test({int named}) {}
-
-main() {
- test(named: 42);
-}
-''');
- }
-
- test_addMissingParameterNamed_method_hasNamed() async {
- await resolveTestUnit('''
-class A {
- test(int a, {int b: 0}) {}
-
- main() {
- test(1, b: 2, named: 3.0);
- }
-}
-''');
- await assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_NAMED, '''
-class A {
- test(int a, {int b: 0, double named}) {}
-
- main() {
- test(1, b: 2, named: 3.0);
- }
-}
-''');
- }
-
- test_addMissingParameterNamed_method_hasOptionalPositional() async {
- await resolveTestUnit('''
-class A {
- test(int a, [int b]) {}
-
- main() {
- test(1, 2, named: 3.0);
- }
-}
-''');
- await assertNoFix(DartFixKind.ADD_MISSING_PARAMETER_NAMED);
- }
-
- test_addMissingParameterNamed_method_hasRequired() async {
- await resolveTestUnit('''
-class A {
- test(int a) {}
-
- main() {
- test(1, named: 2.0);
- }
-}
-''');
- await assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_NAMED, '''
-class A {
- test(int a, {double named}) {}
-
- main() {
- test(1, named: 2.0);
- }
-}
-''');
- }
-
- test_addMissingParameterNamed_method_noParameters() async {
- await resolveTestUnit('''
-class A {
- test() {}
-
- main() {
- test(named: 42);
- }
-}
-''');
- await assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_NAMED, '''
-class A {
- test({int named}) {}
-
- main() {
- test(named: 42);
- }
-}
-''');
- }
-
- test_addMissingRequiredArg_cons_flutter_children() async {
- addFlutterPackage();
- _addMetaPackageSource();
-
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-import 'package:meta/meta.dart';
-
-class MyWidget extends Widget {
- MyWidget({@required List<Widget> children});
-}
-
-build() {
- return new MyWidget();
-}
-''');
-
- await assertHasFix(DartFixKind.ADD_MISSING_REQUIRED_ARGUMENT, '''
-import 'package:flutter/widgets.dart';
-import 'package:meta/meta.dart';
-
-class MyWidget extends Widget {
- MyWidget({@required List<Widget> children});
-}
-
-build() {
- return new MyWidget(children: <Widget>[],);
-}
-''');
- }
-
- test_addMissingRequiredArg_cons_flutter_hasTrailingComma() async {
- addFlutterPackage();
- _addMetaPackageSource();
-
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-import 'package:meta/meta.dart';
-
-class MyWidget extends Widget {
- MyWidget({@required int a, @required int b});
-}
-
-build() {
- return new MyWidget(a: 1,);
-}
-''');
-
- await assertHasFix(DartFixKind.ADD_MISSING_REQUIRED_ARGUMENT, '''
-import 'package:flutter/widgets.dart';
-import 'package:meta/meta.dart';
-
-class MyWidget extends Widget {
- MyWidget({@required int a, @required int b});
-}
-
-build() {
- return new MyWidget(a: 1, b: null,);
-}
-''');
- }
-
- test_addMissingRequiredArg_cons_single() async {
- _addMetaPackageSource();
- addSource('/project/libA.dart', r'''
-library libA;
-import 'package:meta/meta.dart';
-
-class A {
- A({@required int a}) {}
-}
-''');
-
- await resolveTestUnit('''
-import 'libA.dart';
-
-main() {
- A a = new A();
-}
-''');
- await assertHasFix(DartFixKind.ADD_MISSING_REQUIRED_ARGUMENT, '''
-import 'libA.dart';
-
-main() {
- A a = new A(a: null);
-}
-''');
- }
-
- test_addMissingRequiredArg_cons_single_closure() async {
- _addMetaPackageSource();
-
- addSource('/project/libA.dart', r'''
-library libA;
-import 'package:meta/meta.dart';
-
-typedef void VoidCallback();
-
-class A {
- A({@required VoidCallback onPressed}) {}
-}
-''');
-
- await resolveTestUnit('''
-import 'libA.dart';
-
-main() {
- A a = new A();
-}
-''');
- await assertHasFix(DartFixKind.ADD_MISSING_REQUIRED_ARGUMENT, '''
-import 'libA.dart';
-
-main() {
- A a = new A(onPressed: () {});
-}
-''');
- }
-
- test_addMissingRequiredArg_cons_single_closure_2() async {
- _addMetaPackageSource();
-
- addSource('/project/libA.dart', r'''
-library libA;
-import 'package:meta/meta.dart';
-
-typedef void Callback(e);
-
-class A {
- A({@required Callback callback}) {}
-}
-''');
-
- await resolveTestUnit('''
-import 'libA.dart';
-
-main() {
- A a = new A();
-}
-''');
- await assertHasFix(DartFixKind.ADD_MISSING_REQUIRED_ARGUMENT, '''
-import 'libA.dart';
-
-main() {
- A a = new A(callback: (e) {});
-}
-''');
- }
-
- test_addMissingRequiredArg_cons_single_closure_3() async {
- _addMetaPackageSource();
-
- addSource('/project/libA.dart', r'''
-library libA;
-import 'package:meta/meta.dart';
-
-typedef void Callback(a,b,c);
-
-class A {
- A({@required Callback callback}) {}
-}
-''');
-
- await resolveTestUnit('''
-import 'libA.dart';
-
-main() {
- A a = new A();
-}
-''');
- await assertHasFix(DartFixKind.ADD_MISSING_REQUIRED_ARGUMENT, '''
-import 'libA.dart';
-
-main() {
- A a = new A(callback: (a, b, c) {});
-}
-''');
- }
-
- test_addMissingRequiredArg_cons_single_closure_4() async {
- _addMetaPackageSource();
-
- addSource('/project/libA.dart', r'''
-library libA;
-import 'package:meta/meta.dart';
-
-typedef int Callback(int a, String b,c);
-
-class A {
- A({@required Callback callback}) {}
-}
-''');
-
- await resolveTestUnit('''
-import 'libA.dart';
-
-main() {
- A a = new A();
-}
-''');
- await assertHasFix(DartFixKind.ADD_MISSING_REQUIRED_ARGUMENT, '''
-import 'libA.dart';
-
-main() {
- A a = new A(callback: (int a, String b, c) {});
-}
-''');
- }
-
- test_addMissingRequiredArg_cons_single_list() async {
- _addMetaPackageSource();
-
- addSource('/project/libA.dart', r'''
-library libA;
-import 'package:meta/meta.dart';
-
-class A {
- A({@required List<String> names}) {}
-}
-''');
-
- await resolveTestUnit('''
-import 'libA.dart';
-
-main() {
- A a = new A();
-}
-''');
- await assertHasFix(DartFixKind.ADD_MISSING_REQUIRED_ARGUMENT, '''
-import 'libA.dart';
-
-main() {
- A a = new A(names: <String>[]);
-}
-''');
- }
-
- test_addMissingRequiredArg_multiple() async {
- _addMetaPackageSource();
-
- await resolveTestUnit('''
-import 'package:meta/meta.dart';
-
-test({@required int a, @required int bcd}) {}
-main() {
- test(a: 3);
-}
-''');
- await assertHasFix(DartFixKind.ADD_MISSING_REQUIRED_ARGUMENT, '''
-import 'package:meta/meta.dart';
-
-test({@required int a, @required int bcd}) {}
-main() {
- test(a: 3, bcd: null);
-}
-''');
- }
-
- test_addMissingRequiredArg_multiple_2() async {
- _addMetaPackageSource();
-
- await resolveTestUnit('''
-import 'package:meta/meta.dart';
-
-test({@required int a, @required int bcd}) {}
-main() {
- test();
-}
-''');
-
- // For now we expect one error per missing arg (dartbug.com/28830).
- List<AnalysisError> errors = await _computeErrors();
- expect(errors, hasLength(2));
-
- List<AnalysisError> filteredErrors = errors
- .where((e) => e.message == "The parameter 'a' is required.")
- .toList();
- expect(filteredErrors, hasLength(1));
-
- List<Fix> fixes = await _computeFixes(filteredErrors.first);
-
- List<Fix> filteredFixes = fixes
- .where((fix) => fix.change.message == "Add required argument 'a'")
- .toList();
- expect(filteredFixes, hasLength(1));
- change = filteredFixes.first.change;
- resultCode = SourceEdit.applySequence(testCode, change.edits[0].edits);
- // verify
- expect(resultCode, '''
-import 'package:meta/meta.dart';
-
-test({@required int a, @required int bcd}) {}
-main() {
- test(a: null);
-}
-''');
- }
-
- test_addMissingRequiredArg_single() async {
- _addMetaPackageSource();
-
- await resolveTestUnit('''
-import 'package:meta/meta.dart';
-
-test({@required int abc}) {}
-main() {
- test();
-}
-''');
- await assertHasFix(DartFixKind.ADD_MISSING_REQUIRED_ARGUMENT, '''
-import 'package:meta/meta.dart';
-
-test({@required int abc}) {}
-main() {
- test(abc: null);
-}
-''');
- }
-
- test_addMissingRequiredArg_single_normal() async {
- _addMetaPackageSource();
-
- await resolveTestUnit('''
-import 'package:meta/meta.dart';
-
-test(String x, {@required int abc}) {}
-main() {
- test("foo");
-}
-''');
- await assertHasFix(DartFixKind.ADD_MISSING_REQUIRED_ARGUMENT, '''
-import 'package:meta/meta.dart';
-
-test(String x, {@required int abc}) {}
-main() {
- test("foo", abc: null);
-}
-''');
- }
-
- test_addMissingRequiredArg_single_with_details() async {
- _addMetaPackageSource();
-
- await resolveTestUnit('''
-import 'package:meta/meta.dart';
-
-test({@Required("Really who doesn't need an abc?") int abc}) {}
-main() {
- test();
-}
-''');
- await assertHasFix(DartFixKind.ADD_MISSING_REQUIRED_ARGUMENT, '''
-import 'package:meta/meta.dart';
-
-test({@Required("Really who doesn't need an abc?") int abc}) {}
-main() {
- test(abc: null);
-}
-''');
- }
-
- test_addStatic_multipleFields() async {
- await resolveTestUnit('''
-class C {
- const int x = 0, y = 0;
-}
-''');
- await assertHasFix(DartFixKind.ADD_STATIC, '''
-class C {
- static const int x = 0, y = 0;
-}
-''');
- }
-
- test_addStatic_oneField() async {
- await resolveTestUnit('''
-class C {
- const int x = 0;
-}
-''');
- await assertHasFix(DartFixKind.ADD_STATIC, '''
-class C {
- static const int x = 0;
-}
-''');
- }
-
- test_boolean() async {
- await resolveTestUnit('''
-main() {
- boolean v;
-}
-''');
- await assertHasFix(DartFixKind.REPLACE_BOOLEAN_WITH_BOOL, '''
-main() {
- bool v;
-}
-''');
- }
-
- test_boolean_all() async {
- await resolveTestUnit('''
-main() {
- boolean v;
- boolean w;
-}
-''');
- await assertHasFixAllFix(StaticWarningCode.UNDEFINED_CLASS_BOOLEAN,
- DartFixKind.REPLACE_BOOLEAN_WITH_BOOL, '''
-main() {
- bool v;
- bool w;
-}
-''');
- }
-
- test_canBeNullAfterNullAware_chain() async {
- await resolveTestUnit('''
-main(x) {
- x?.a.b.c;
-}
-''');
- await assertHasFix(DartFixKind.REPLACE_WITH_NULL_AWARE, '''
-main(x) {
- x?.a?.b?.c;
-}
-''');
- }
-
- test_canBeNullAfterNullAware_methodInvocation() async {
- await resolveTestUnit('''
-main(x) {
- x?.a.b();
-}
-''');
- await assertHasFix(DartFixKind.REPLACE_WITH_NULL_AWARE, '''
-main(x) {
- x?.a?.b();
-}
-''');
- }
-
- test_canBeNullAfterNullAware_propertyAccess() async {
- await resolveTestUnit('''
-main(x) {
- x?.a().b;
-}
-''');
- await assertHasFix(DartFixKind.REPLACE_WITH_NULL_AWARE, '''
-main(x) {
- x?.a()?.b;
-}
-''');
- }
-
- test_changeToStaticAccess_method() async {
- await resolveTestUnit('''
-class A {
- static foo() {}
-}
-main(A a) {
- a.foo();
-}
-''');
- await assertHasFix(DartFixKind.CHANGE_TO_STATIC_ACCESS, '''
-class A {
- static foo() {}
-}
-main(A a) {
- A.foo();
-}
-''');
- }
-
- test_changeToStaticAccess_method_importType() async {
- addSource('/project/libA.dart', r'''
-library libA;
-class A {
- static foo() {}
-}
-''');
- addSource('/project/libB.dart', r'''
-library libB;
-import 'libA.dart';
-class B extends A {}
-''');
- await resolveTestUnit('''
-import 'libB.dart';
-main(B b) {
- b.foo();
-}
-''');
- await assertHasFix(DartFixKind.CHANGE_TO_STATIC_ACCESS, '''
-import 'libA.dart';
-import 'libB.dart';
-main(B b) {
- A.foo();
-}
-''');
- }
-
- test_changeToStaticAccess_method_prefixLibrary() async {
- await resolveTestUnit('''
-import 'dart:async' as pref;
-main(pref.Future f) {
- f.wait([]);
-}
-''');
- await assertHasFix(DartFixKind.CHANGE_TO_STATIC_ACCESS, '''
-import 'dart:async' as pref;
-main(pref.Future f) {
- pref.Future.wait([]);
-}
-''');
- }
-
- test_changeToStaticAccess_property() async {
- await resolveTestUnit('''
-class A {
- static get foo => 42;
-}
-main(A a) {
- a.foo;
-}
-''');
- await assertHasFix(DartFixKind.CHANGE_TO_STATIC_ACCESS, '''
-class A {
- static get foo => 42;
-}
-main(A a) {
- A.foo;
-}
-''');
- }
-
- test_changeToStaticAccess_property_importType() async {
- addSource('/project/libA.dart', r'''
-library libA;
-class A {
- static get foo => null;
-}
-''');
- addSource('/project/libB.dart', r'''
-library libB;
-import 'libA.dart';
-class B extends A {}
-''');
- await resolveTestUnit('''
-import 'libB.dart';
-main(B b) {
- b.foo;
-}
-''');
- await assertHasFix(DartFixKind.CHANGE_TO_STATIC_ACCESS, '''
-import 'libA.dart';
-import 'libB.dart';
-main(B b) {
- A.foo;
-}
-''');
- }
-
- test_changeTypeAnnotation_BAD_multipleVariables() async {
- await resolveTestUnit('''
-main() {
- String a, b = 42;
-}
-''');
- await assertNoFix(DartFixKind.CHANGE_TYPE_ANNOTATION);
- }
-
- test_changeTypeAnnotation_BAD_notVariableDeclaration() async {
- await resolveTestUnit('''
-main() {
- String v;
- v = 42;
-}
-''');
- await assertNoFix(DartFixKind.CHANGE_TYPE_ANNOTATION);
- }
-
- test_changeTypeAnnotation_OK_generic() async {
- await resolveTestUnit('''
-main() {
- String v = <int>[];
-}
-''');
- await assertHasFix(DartFixKind.CHANGE_TYPE_ANNOTATION, '''
-main() {
- List<int> v = <int>[];
-}
-''');
- }
-
- test_changeTypeAnnotation_OK_simple() async {
- await resolveTestUnit('''
-main() {
- String v = 'abc'.length;
-}
-''');
- await assertHasFix(DartFixKind.CHANGE_TYPE_ANNOTATION, '''
-main() {
- int v = 'abc'.length;
-}
-''');
- }
-
- test_convertToNamedArguments_BAD_ambiguous() async {
- await resolveTestUnit('''
-class A {
- A({int a, int b});
-}
-
-main() {
- new A(1, 2);
-}
-''');
- await assertNoFix(DartFixKind.CONVERT_TO_NAMED_ARGUMENTS);
- }
-
- test_convertToNamedArguments_BAD_noCompatibleParameter() async {
- await resolveTestUnit('''
-class A {
- A({String a});
-}
-
-main() {
- new A(1);
-}
-''');
- await assertNoFix(DartFixKind.CONVERT_TO_NAMED_ARGUMENTS);
- }
-
- test_convertToNamedArguments_OK_instanceCreation() async {
- await resolveTestUnit('''
-class A {
- A({int a, double b});
-}
-
-main() {
- new A(1.2, 3);
-}
-''');
- await assertHasFix(DartFixKind.CONVERT_TO_NAMED_ARGUMENTS, '''
-class A {
- A({int a, double b});
-}
-
-main() {
- new A(b: 1.2, a: 3);
-}
-''');
- }
-
- test_convertToNamedArguments_OK_instanceCreation_hasPositional() async {
- await resolveTestUnit('''
-class A {
- A(int a, {int b});
-}
-
-main() {
- new A(1, 2);
-}
-''');
- await assertHasFix(DartFixKind.CONVERT_TO_NAMED_ARGUMENTS, '''
-class A {
- A(int a, {int b});
-}
-
-main() {
- new A(1, b: 2);
-}
-''');
- }
-
- test_convertToNamedArguments_OK_methodInvocation() async {
- await resolveTestUnit('''
-class C {
- void foo({int a}) {}
-}
-
-main(C c) {
- c.foo(1);
-}
-''');
- await assertHasFix(DartFixKind.CONVERT_TO_NAMED_ARGUMENTS, '''
-class C {
- void foo({int a}) {}
-}
-
-main(C c) {
- c.foo(a: 1);
-}
-''');
- }
-
- test_createClass() async {
- await resolveTestUnit('''
-main() {
- Test v = null;
-}
-''');
- await assertHasFix(DartFixKind.CREATE_CLASS, '''
-main() {
- Test v = null;
-}
-
-class Test {
-}
-''');
- _assertLinkedGroup(change.linkedEditGroups[0], ['Test v =', 'Test {']);
- }
-
- test_createClass_BAD_hasUnresolvedPrefix() async {
- await resolveTestUnit('''
-main() {
- prefix.Test v = null;
-}
-''');
- await assertNoFix(DartFixKind.CREATE_CLASS);
- }
-
- test_createClass_inLibraryOfPrefix() async {
- String libCode = r'''
-library my.lib;
-
-class A {}
-''';
- addSource('/project/lib.dart', libCode);
- await resolveTestUnit('''
-import 'lib.dart' as lib;
-
-main() {
- lib.A a = null;
- lib.Test t = null;
-}
-''');
- AnalysisError error = await _findErrorToFix();
- fix = await _assertHasFix(DartFixKind.CREATE_CLASS, error);
- change = fix.change;
- // apply to "lib.dart"
- List<SourceFileEdit> fileEdits = change.edits;
- expect(fileEdits, hasLength(1));
- SourceFileEdit fileEdit = change.edits[0];
- expect(fileEdit.file, convertPath('/project/lib.dart'));
- expect(SourceEdit.applySequence(libCode, fileEdit.edits), r'''
-library my.lib;
-
-class A {}
-
-class Test {
-}
-''');
- expect(change.linkedEditGroups, hasLength(1));
- }
-
- test_createClass_innerLocalFunction() async {
- await resolveTestUnit('''
-f() {
- g() {
- Test v = null;
- }
-}
-''');
- await assertHasFix(DartFixKind.CREATE_CLASS, '''
-f() {
- g() {
- Test v = null;
- }
-}
-
-class Test {
-}
-''');
- _assertLinkedGroup(change.linkedEditGroups[0], ['Test v =', 'Test {']);
- }
-
- test_createClass_instanceCreation_withoutNew_fromFunction() async {
- await resolveTestUnit('''
-main() {
- Test ();
-}
-''');
- await assertHasFix(DartFixKind.CREATE_CLASS, '''
-main() {
- Test ();
-}
-
-class Test {
-}
-''');
- _assertLinkedGroup(change.linkedEditGroups[0], ['Test ()', 'Test {']);
- }
-
- test_createClass_instanceCreation_withoutNew_fromMethod() async {
- await resolveTestUnit('''
-class A {
- main() {
- Test ();
- }
-}
-''');
- await assertHasFix(DartFixKind.CREATE_CLASS, '''
-class A {
- main() {
- Test ();
- }
-}
-
-class Test {
-}
-''');
- _assertLinkedGroup(change.linkedEditGroups[0], ['Test ()', 'Test {']);
- }
-
- test_createClass_itemOfList() async {
- await resolveTestUnit('''
-main() {
- var a = [Test];
-}
-''');
- await assertHasFix(DartFixKind.CREATE_CLASS, '''
-main() {
- var a = [Test];
-}
-
-class Test {
-}
-''');
- _assertLinkedGroup(change.linkedEditGroups[0], ['Test];', 'Test {']);
- }
-
- test_createClass_itemOfList_inAnnotation() async {
- errorFilter = (AnalysisError error) {
- return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER;
- };
- await resolveTestUnit('''
-class MyAnnotation {
- const MyAnnotation(a, b);
-}
-@MyAnnotation(int, const [Test])
-main() {}
-''');
- await assertHasFix(DartFixKind.CREATE_CLASS, '''
-class MyAnnotation {
- const MyAnnotation(a, b);
-}
-@MyAnnotation(int, const [Test])
-main() {}
-
-class Test {
-}
-''');
- _assertLinkedGroup(change.linkedEditGroups[0], ['Test])', 'Test {']);
- }
-
- test_createConstructor_forFinalFields() async {
- errorFilter = (AnalysisError error) {
- return error.message.contains("'a'");
- };
- await resolveTestUnit('''
-class Test {
- final int a;
- final int b = 2;
- final int c;
-}
-''');
- await assertHasFix(DartFixKind.CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS, '''
-class Test {
- final int a;
- final int b = 2;
- final int c;
-
- Test(this.a, this.c);
-}
-''');
- }
-
- test_createConstructor_forFinalFields_flutter() async {
- addFlutterPackage();
- errorFilter = (AnalysisError error) {
- return error.message.contains("'a'");
- };
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-
-class MyWidget extends StatelessWidget {
- final int a;
- final int b = 2;
- final int c;
-}
-''');
- await assertHasFix(DartFixKind.CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS, '''
-import 'package:flutter/widgets.dart';
-
-class MyWidget extends StatelessWidget {
- final int a;
- final int b = 2;
- final int c;
-
- const MyWidget({Key key, this.a, this.c}) : super(key: key);
-}
-''');
- }
-
- test_createConstructor_forFinalFields_flutter_childLast() async {
- addFlutterPackage();
- errorFilter = (AnalysisError error) {
- return error.message.contains("'a'");
- };
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-
-class MyWidget extends StatelessWidget {
- final int a;
- final Widget child;
- final int b;
-}
-''');
- await assertHasFix(DartFixKind.CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS, '''
-import 'package:flutter/widgets.dart';
-
-class MyWidget extends StatelessWidget {
- final int a;
- final Widget child;
- final int b;
-
- const MyWidget({Key key, this.a, this.b, this.child}) : super(key: key);
-}
-''');
- }
-
- test_createConstructor_forFinalFields_flutter_childrenLast() async {
- addFlutterPackage();
- errorFilter = (AnalysisError error) {
- return error.message.contains("'a'");
- };
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-
-class MyWidget extends StatelessWidget {
- final int a;
- final List<Widget> children;
- final int b;
-}
-''');
- await assertHasFix(DartFixKind.CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS, '''
-import 'package:flutter/widgets.dart';
-
-class MyWidget extends StatelessWidget {
- final int a;
- final List<Widget> children;
- final int b;
-
- const MyWidget({Key key, this.a, this.b, this.children}) : super(key: key);
-}
-''');
- }
-
- test_createConstructor_insteadOfSyntheticDefault() async {
- await resolveTestUnit('''
-class A {
- int field;
-
- method() {}
-}
-main() {
- new A(1, 2.0);
-}
-''');
- await assertHasFix(DartFixKind.CREATE_CONSTRUCTOR, '''
-class A {
- int field;
-
- A(int i, double d);
-
- method() {}
-}
-main() {
- new A(1, 2.0);
-}
-''');
- }
-
- test_createConstructor_named() async {
- await resolveTestUnit('''
-class A {
- method() {}
-}
-main() {
- new A.named(1, 2.0);
-}
-''');
- await assertHasFix(DartFixKind.CREATE_CONSTRUCTOR, '''
-class A {
- A.named(int i, double d);
-
- method() {}
-}
-main() {
- new A.named(1, 2.0);
-}
-''');
- _assertLinkedGroup(change.linkedEditGroups[0], ['named(int ', 'named(1']);
- }
-
- test_createConstructor_named_emptyClassBody() async {
- await resolveTestUnit('''
-class A {}
-main() {
- new A.named(1);
-}
-''');
- await assertHasFix(DartFixKind.CREATE_CONSTRUCTOR, '''
-class A {
- A.named(int i);
-}
-main() {
- new A.named(1);
-}
-''');
- _assertLinkedGroup(change.linkedEditGroups[0], ['named(int ', 'named(1']);
- }
-
- test_createConstructorForFinalFields_inTopLevelMethod() async {
- await resolveTestUnit('''
-main() {
- final int v;
-}
-''');
- await assertNoFix(DartFixKind.CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS);
- }
-
- test_createConstructorForFinalFields_topLevelField() async {
- await resolveTestUnit('''
-final int v;
-''');
- await assertNoFix(DartFixKind.CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS);
- }
-
- test_createConstructorSuperExplicit() async {
- await resolveTestUnit('''
-class A {
- A(bool p1, int p2, double p3, String p4, {p5});
-}
-class B extends A {
- B() {}
-}
-''');
- await assertHasFix(DartFixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION, '''
-class A {
- A(bool p1, int p2, double p3, String p4, {p5});
-}
-class B extends A {
- B() : super(false, 0, 0.0, '') {}
-}
-''');
- }
-
- test_createConstructorSuperExplicit_hasInitializers() async {
- await resolveTestUnit('''
-class A {
- A(int p);
-}
-class B extends A {
- int field;
- B() : field = 42 {}
-}
-''');
- await assertHasFix(DartFixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION, '''
-class A {
- A(int p);
-}
-class B extends A {
- int field;
- B() : field = 42, super(0) {}
-}
-''');
- }
-
- test_createConstructorSuperExplicit_named() async {
- await resolveTestUnit('''
-class A {
- A.named(int p);
-}
-class B extends A {
- B() {}
-}
-''');
- await assertHasFix(DartFixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION, '''
-class A {
- A.named(int p);
-}
-class B extends A {
- B() : super.named(0) {}
-}
-''');
- }
-
- test_createConstructorSuperExplicit_named_private() async {
- await resolveTestUnit('''
-class A {
- A._named(int p);
-}
-class B extends A {
- B() {}
-}
-''');
- await assertNoFix(DartFixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION);
- }
-
- test_createConstructorSuperExplicit_typeArgument() async {
- await resolveTestUnit('''
-class A<T> {
- A(T p);
-}
-class B extends A<int> {
- B();
-}
-''');
- await assertHasFix(DartFixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION, '''
-class A<T> {
- A(T p);
-}
-class B extends A<int> {
- B() : super(0);
-}
-''');
- }
-
- test_createConstructorSuperImplicit() async {
- await resolveTestUnit('''
-class A {
- A(p1, int p2, List<String> p3, [int p4]);
-}
-class B extends A {
- int existingField;
-
- void existingMethod() {}
-}
-''');
- await assertHasFix(DartFixKind.CREATE_CONSTRUCTOR_SUPER, '''
-class A {
- A(p1, int p2, List<String> p3, [int p4]);
-}
-class B extends A {
- int existingField;
-
- B(p1, int p2, List<String> p3) : super(p1, p2, p3);
-
- void existingMethod() {}
-}
-''');
- }
-
- test_createConstructorSuperImplicit_fieldInitializer() async {
- await resolveTestUnit('''
-class A {
- int _field;
- A(this._field);
-}
-class B extends A {
- int existingField;
-
- void existingMethod() {}
-}
-''');
- await assertHasFix(DartFixKind.CREATE_CONSTRUCTOR_SUPER, '''
-class A {
- int _field;
- A(this._field);
-}
-class B extends A {
- int existingField;
-
- B(int field) : super(field);
-
- void existingMethod() {}
-}
-''');
- }
-
- test_createConstructorSuperImplicit_importType() async {
- addSource('/project/libA.dart', r'''
-library libA;
-class A {}
-''');
- addSource('/project/libB.dart', r'''
-library libB;
-import 'libA.dart';
-class B {
- B(A a);
-}
-''');
- await resolveTestUnit('''
-import 'libB.dart';
-class C extends B {
-}
-''');
- await assertHasFix(DartFixKind.CREATE_CONSTRUCTOR_SUPER, '''
-import 'libA.dart';
-import 'libB.dart';
-class C extends B {
- C(A a) : super(a);
-}
-''');
- }
-
- test_createConstructorSuperImplicit_named() async {
- await resolveTestUnit('''
-class A {
- A.named(p1, int p2);
-}
-class B extends A {
- int existingField;
-
- void existingMethod() {}
-}
-''');
- await assertHasFix(DartFixKind.CREATE_CONSTRUCTOR_SUPER, '''
-class A {
- A.named(p1, int p2);
-}
-class B extends A {
- int existingField;
-
- B.named(p1, int p2) : super.named(p1, p2);
-
- void existingMethod() {}
-}
-''');
- }
-
- test_createConstructorSuperImplicit_private() async {
- await resolveTestUnit('''
-class A {
- A._named(p);
-}
-class B extends A {
-}
-''');
- await assertNoFix(DartFixKind.CREATE_CONSTRUCTOR_SUPER);
- }
-
- test_createConstructorSuperImplicit_typeArgument() async {
- await resolveTestUnit('''
-class C<T> {
- final T x;
- C(this.x);
-}
-class D extends C<int> {
-}''');
- await assertHasFix(DartFixKind.CREATE_CONSTRUCTOR_SUPER, '''
-class C<T> {
- final T x;
- C(this.x);
-}
-class D extends C<int> {
- D(int x) : super(x);
-}''');
- }
-
- test_createField_BAD_inEnum() async {
- await resolveTestUnit('''
-enum MyEnum {
- AAA, BBB
-}
-main() {
- MyEnum.foo;
-}
-''');
- await assertNoFix(DartFixKind.CREATE_FIELD);
- }
-
- test_createField_BAD_inSDK() async {
- await resolveTestUnit('''
-main(List p) {
- p.foo = 1;
-}
-''');
- await assertNoFix(DartFixKind.CREATE_FIELD);
- }
-
- test_createField_getter_multiLevel() async {
- await resolveTestUnit('''
-class A {
-}
-class B {
- A a;
-}
-class C {
- B b;
-}
-main(C c) {
- int v = c.b.a.test;
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FIELD, '''
-class A {
- int test;
-}
-class B {
- A a;
-}
-class C {
- B b;
-}
-main(C c) {
- int v = c.b.a.test;
-}
-''');
- }
-
- test_createField_getter_qualified_instance() async {
- await resolveTestUnit('''
-class A {
-}
-main(A a) {
- int v = a.test;
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FIELD, '''
-class A {
- int test;
-}
-main(A a) {
- int v = a.test;
-}
-''');
- }
-
- test_createField_getter_qualified_instance_differentLibrary() async {
- addSource('/project/other.dart', '''
-/**
- * A comment to push the offset of the braces for the following class
- * declaration past the end of the content of the test file. Used to catch an
- * index out of bounds exception that occurs when using the test source instead
- * of the target source to compute the location at which to insert the field.
- */
-class A {
-}
-''');
- await resolveTestUnit('''
-import 'other.dart';
-main(A a) {
- int v = a.test;
-}
-''');
- await assertHasFix(
- DartFixKind.CREATE_FIELD,
- '''
-/**
- * A comment to push the offset of the braces for the following class
- * declaration past the end of the content of the test file. Used to catch an
- * index out of bounds exception that occurs when using the test source instead
- * of the target source to compute the location at which to insert the field.
- */
-class A {
- int test;
-}
-''',
- target: '/project/other.dart');
- }
-
- test_createField_getter_qualified_instance_dynamicType() async {
- await resolveTestUnit('''
-class A {
- B b;
- void f(Object p) {
- p == b.test;
- }
-}
-class B {
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FIELD, '''
-class A {
- B b;
- void f(Object p) {
- p == b.test;
- }
-}
-class B {
- var test;
-}
-''');
- }
-
- test_createField_getter_qualified_propagatedType() async {
- await resolveTestUnit('''
-class A {
- A get self => this;
-}
-main() {
- var a = new A();
- int v = a.self.test;
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FIELD, '''
-class A {
- int test;
-
- A get self => this;
-}
-main() {
- var a = new A();
- int v = a.self.test;
-}
-''');
- }
-
- test_createField_getter_unqualified_instance_asInvocationArgument() async {
- await resolveTestUnit('''
-class A {
- main() {
- f(test);
- }
-}
-f(String s) {}
-''');
- await assertHasFix(DartFixKind.CREATE_FIELD, '''
-class A {
- String test;
-
- main() {
- f(test);
- }
-}
-f(String s) {}
-''');
- }
-
- test_createField_getter_unqualified_instance_assignmentRhs() async {
- await resolveTestUnit('''
-class A {
- main() {
- int v = test;
- }
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FIELD, '''
-class A {
- int test;
-
- main() {
- int v = test;
- }
-}
-''');
- }
-
- test_createField_getter_unqualified_instance_asStatement() async {
- await resolveTestUnit('''
-class A {
- main() {
- test;
- }
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FIELD, '''
-class A {
- var test;
-
- main() {
- test;
- }
-}
-''');
- }
-
- test_createField_hint() async {
- await resolveTestUnit('''
-class A {
-}
-main(A a) {
- var x = a;
- int v = x.test;
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FIELD, '''
-class A {
- int test;
-}
-main(A a) {
- var x = a;
- int v = x.test;
-}
-''');
- }
-
- test_createField_hint_setter() async {
- await resolveTestUnit('''
-class A {
-}
-main(A a) {
- var x = a;
- x.test = 0;
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FIELD, '''
-class A {
- int test;
-}
-main(A a) {
- var x = a;
- x.test = 0;
-}
-''');
- }
-
- test_createField_importType() async {
- addSource('/project/libA.dart', r'''
-library libA;
-class A {}
-''');
- addSource('/project/libB.dart', r'''
-library libB;
-import 'libA.dart';
-A getA() => null;
-''');
- await resolveTestUnit('''
-import 'libB.dart';
-class C {
-}
-main(C c) {
- c.test = getA();
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FIELD, '''
-import 'libA.dart';
-import 'libB.dart';
-class C {
- A test;
-}
-main(C c) {
- c.test = getA();
-}
-''');
- }
-
- test_createField_invalidInitializer_withoutType() async {
- await resolveTestUnit('''
-class C {
- C(this.text);
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FIELD, '''
-class C {
- var text;
-
- C(this.text);
-}
-''');
- }
-
- test_createField_invalidInitializer_withType() async {
- await resolveTestUnit('''
-class C {
- C(String this.text);
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FIELD, '''
-class C {
- String text;
-
- C(String this.text);
-}
-''');
- }
-
- test_createField_setter_generic_BAD() async {
- await resolveTestUnit('''
-class A {
-}
-class B<T> {
- List<T> items;
- main(A a) {
- a.test = items;
- }
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FIELD, '''
-class A {
- List test;
-}
-class B<T> {
- List<T> items;
- main(A a) {
- a.test = items;
- }
-}
-''');
- }
-
- test_createField_setter_generic_OK_local() async {
- await resolveTestUnit('''
-class A<T> {
- List<T> items;
-
- main(A a) {
- test = items;
- }
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FIELD, '''
-class A<T> {
- List<T> items;
-
- List<T> test;
-
- main(A a) {
- test = items;
- }
-}
-''');
- }
-
- test_createField_setter_qualified_instance_hasField() async {
- await resolveTestUnit('''
-class A {
- int aaa;
- int zzz;
-
- existingMethod() {}
-}
-main(A a) {
- a.test = 5;
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FIELD, '''
-class A {
- int aaa;
- int zzz;
-
- int test;
-
- existingMethod() {}
-}
-main(A a) {
- a.test = 5;
-}
-''');
- }
-
- test_createField_setter_qualified_instance_hasMethod() async {
- await resolveTestUnit('''
-class A {
- existingMethod() {}
-}
-main(A a) {
- a.test = 5;
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FIELD, '''
-class A {
- int test;
-
- existingMethod() {}
-}
-main(A a) {
- a.test = 5;
-}
-''');
- }
-
- test_createField_setter_qualified_static() async {
- await resolveTestUnit('''
-class A {
-}
-main() {
- A.test = 5;
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FIELD, '''
-class A {
- static int test;
-}
-main() {
- A.test = 5;
-}
-''');
- }
-
- test_createField_setter_unqualified_instance() async {
- await resolveTestUnit('''
-class A {
- main() {
- test = 5;
- }
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FIELD, '''
-class A {
- int test;
-
- main() {
- test = 5;
- }
-}
-''');
- }
-
- test_createField_setter_unqualified_static() async {
- await resolveTestUnit('''
-class A {
- static main() {
- test = 5;
- }
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FIELD, '''
-class A {
- static int test;
-
- static main() {
- test = 5;
- }
-}
-''');
- }
-
- test_createFile_forImport() async {
- testFile = '/my/project/bin/test.dart';
- await resolveTestUnit('''
-import 'my_file.dart';
-''');
- AnalysisError error = await _findErrorToFix();
- fix = await _assertHasFix(DartFixKind.CREATE_FILE, error);
- change = fix.change;
- // validate change
- List<SourceFileEdit> fileEdits = change.edits;
- expect(fileEdits, hasLength(1));
- SourceFileEdit fileEdit = change.edits[0];
- expect(fileEdit.file, convertPath('/my/project/bin/my_file.dart'));
- expect(fileEdit.fileStamp, -1);
- expect(fileEdit.edits, hasLength(1));
- expect(fileEdit.edits[0].replacement, contains('library my_file;'));
- }
-
- test_createFile_forImport_BAD_inPackage_lib_justLib() async {
- newFile('/projects/my_package/pubspec.yaml', content: 'name: my_package');
- testFile = '/projects/my_package/test.dart';
- await resolveTestUnit('''
-import 'lib';
-''');
- await assertNoFix(DartFixKind.CREATE_FILE);
- }
-
- test_createFile_forImport_BAD_notDart() async {
- testFile = '/my/project/bin/test.dart';
- await resolveTestUnit('''
-import 'my_file.txt';
-''');
- await assertNoFix(DartFixKind.CREATE_FILE);
- }
-
- test_createFile_forImport_inPackage_lib() async {
- newFile('/projects/my_package/pubspec.yaml', content: 'name: my_package');
- testFile = '/projects/my_package/lib/test.dart';
- newFolder('/projects/my_package/lib');
- await resolveTestUnit('''
-import 'a/bb/c_cc/my_lib.dart';
-''');
- AnalysisError error = await _findErrorToFix();
- fix = await _assertHasFix(DartFixKind.CREATE_FILE, error);
- change = fix.change;
- // validate change
- List<SourceFileEdit> fileEdits = change.edits;
- expect(fileEdits, hasLength(1));
- SourceFileEdit fileEdit = change.edits[0];
- expect(fileEdit.file,
- convertPath('/projects/my_package/lib/a/bb/c_cc/my_lib.dart'));
- expect(fileEdit.fileStamp, -1);
- expect(fileEdit.edits, hasLength(1));
- expect(fileEdit.edits[0].replacement,
- contains('library my_package.a.bb.c_cc.my_lib;'));
- }
-
- test_createFile_forImport_inPackage_test() async {
- newFile('/projects/my_package/pubspec.yaml', content: 'name: my_package');
- testFile = '/projects/my_package/test/misc/test_all.dart';
- await resolveTestUnit('''
-import 'a/bb/my_lib.dart';
-''');
- AnalysisError error = await _findErrorToFix();
- fix = await _assertHasFix(DartFixKind.CREATE_FILE, error);
- change = fix.change;
- // validate change
- List<SourceFileEdit> fileEdits = change.edits;
- expect(fileEdits, hasLength(1));
- SourceFileEdit fileEdit = change.edits[0];
- expect(fileEdit.file,
- convertPath('/projects/my_package/test/misc/a/bb/my_lib.dart'));
- expect(fileEdit.fileStamp, -1);
- expect(fileEdit.edits, hasLength(1));
- expect(fileEdit.edits[0].replacement,
- contains('library my_package.test.misc.a.bb.my_lib;'));
- }
-
- test_createFile_forPart() async {
- testFile = convertPath('/my/project/bin/test.dart');
- await resolveTestUnit('''
-library my.lib;
-part 'my_part.dart';
-''');
- AnalysisError error = await _findErrorToFix();
- fix = await _assertHasFix(DartFixKind.CREATE_FILE, error);
- change = fix.change;
- // validate change
- List<SourceFileEdit> fileEdits = change.edits;
- expect(fileEdits, hasLength(1));
- SourceFileEdit fileEdit = change.edits[0];
- expect(fileEdit.file, convertPath('/my/project/bin/my_part.dart'));
- expect(fileEdit.fileStamp, -1);
- expect(fileEdit.edits, hasLength(1));
- expect(fileEdit.edits[0].replacement, contains('part of my.lib;'));
- }
-
- test_createFile_forPart_inPackageLib() async {
- newFile('/my/pubspec.yaml', content: r'''
-name: my_test
-''');
- testFile = '/my/lib/test.dart';
- addTestSource('''
-library my.lib;
-part 'my_part.dart';
-''', Uri.parse('package:my/test.dart'));
- // configure SourceFactory
- UriResolver pkgResolver = new PackageMapUriResolver(resourceProvider, {
- 'my': <Folder>[getFolder('/my/lib')],
- });
- SourceFactory sourceFactory = new SourceFactory(
- [new DartUriResolver(sdk), pkgResolver, resourceResolver]);
- driver.configure(sourceFactory: sourceFactory);
- testUnit = (await driver.getResult(convertPath(testFile))).unit;
- // prepare fix
- AnalysisError error = await _findErrorToFix();
- fix = await _assertHasFix(DartFixKind.CREATE_FILE, error);
- change = fix.change;
- // validate change
- List<SourceFileEdit> fileEdits = change.edits;
- expect(fileEdits, hasLength(1));
- SourceFileEdit fileEdit = change.edits[0];
- expect(fileEdit.file, convertPath('/my/lib/my_part.dart'));
- expect(fileEdit.fileStamp, -1);
- expect(fileEdit.edits, hasLength(1));
- expect(fileEdit.edits[0].replacement, contains('part of my.lib;'));
- }
-
- test_createGetter_BAD_inSDK() async {
- await resolveTestUnit('''
-main(List p) {
- int v = p.foo;
-}
-''');
- await assertNoFix(DartFixKind.CREATE_GETTER);
- }
-
- test_createGetter_hint_getter() async {
- await resolveTestUnit('''
-class A {
-}
-main(A a) {
- var x = a;
- int v = x.test;
-}
-''');
- await assertHasFix(DartFixKind.CREATE_GETTER, '''
-class A {
- int get test => null;
-}
-main(A a) {
- var x = a;
- int v = x.test;
-}
-''');
- }
-
- test_createGetter_location_afterLastGetter() async {
- await resolveTestUnit('''
-class A {
- int existingField;
-
- int get existingGetter => null;
-
- existingMethod() {}
-}
-main(A a) {
- int v = a.test;
-}
-''');
- await assertHasFix(DartFixKind.CREATE_GETTER, '''
-class A {
- int existingField;
-
- int get existingGetter => null;
-
- int get test => null;
-
- existingMethod() {}
-}
-main(A a) {
- int v = a.test;
-}
-''');
- }
-
- test_createGetter_multiLevel() async {
- await resolveTestUnit('''
-class A {
-}
-class B {
- A a;
-}
-class C {
- B b;
-}
-main(C c) {
- int v = c.b.a.test;
-}
-''');
- await assertHasFix(DartFixKind.CREATE_GETTER, '''
-class A {
- int get test => null;
-}
-class B {
- A a;
-}
-class C {
- B b;
-}
-main(C c) {
- int v = c.b.a.test;
-}
-''');
- }
-
- test_createGetter_qualified_instance() async {
- await resolveTestUnit('''
-class A {
-}
-main(A a) {
- int v = a.test;
-}
-''');
- await assertHasFix(DartFixKind.CREATE_GETTER, '''
-class A {
- int get test => null;
-}
-main(A a) {
- int v = a.test;
-}
-''');
- }
-
- test_createGetter_qualified_instance_differentLibrary() async {
- addSource('/project/other.dart', '''
-/**
- * A comment to push the offset of the braces for the following class
- * declaration past the end of the content of the test file. Used to catch an
- * index out of bounds exception that occurs when using the test source instead
- * of the target source to compute the location at which to insert the field.
- */
-class A {
-}
-''');
- await resolveTestUnit('''
-import 'other.dart';
-main(A a) {
- int v = a.test;
-}
-''');
- await assertHasFix(
- DartFixKind.CREATE_GETTER,
- '''
-/**
- * A comment to push the offset of the braces for the following class
- * declaration past the end of the content of the test file. Used to catch an
- * index out of bounds exception that occurs when using the test source instead
- * of the target source to compute the location at which to insert the field.
- */
-class A {
- int get test => null;
-}
-''',
- target: '/project/other.dart');
- }
-
- test_createGetter_qualified_instance_dynamicType() async {
- await resolveTestUnit('''
-class A {
- B b;
- void f(Object p) {
- p == b.test;
- }
-}
-class B {
-}
-''');
- await assertHasFix(DartFixKind.CREATE_GETTER, '''
-class A {
- B b;
- void f(Object p) {
- p == b.test;
- }
-}
-class B {
- get test => null;
-}
-''');
- }
-
- test_createGetter_qualified_propagatedType() async {
- await resolveTestUnit('''
-class A {
- A get self => this;
-}
-main() {
- var a = new A();
- int v = a.self.test;
-}
-''');
- await assertHasFix(DartFixKind.CREATE_GETTER, '''
-class A {
- A get self => this;
-
- int get test => null;
-}
-main() {
- var a = new A();
- int v = a.self.test;
-}
-''');
- }
-
- test_createGetter_setterContext() async {
- await resolveTestUnit('''
-class A {
-}
-main(A a) {
- a.test = 42;
-}
-''');
- await assertNoFix(DartFixKind.CREATE_GETTER);
- }
-
- test_createGetter_unqualified_instance_asInvocationArgument() async {
- await resolveTestUnit('''
-class A {
- main() {
- f(test);
- }
-}
-f(String s) {}
-''');
- await assertHasFix(DartFixKind.CREATE_GETTER, '''
-class A {
- String get test => null;
-
- main() {
- f(test);
- }
-}
-f(String s) {}
-''');
- }
-
- test_createGetter_unqualified_instance_assignmentLhs() async {
- await resolveTestUnit('''
-class A {
- main() {
- test = 42;
- }
-}
-''');
- await assertNoFix(DartFixKind.CREATE_GETTER);
- }
-
- test_createGetter_unqualified_instance_assignmentRhs() async {
- await resolveTestUnit('''
-class A {
- main() {
- int v = test;
- }
-}
-''');
- await assertHasFix(DartFixKind.CREATE_GETTER, '''
-class A {
- int get test => null;
-
- main() {
- int v = test;
- }
-}
-''');
- }
-
- test_createGetter_unqualified_instance_asStatement() async {
- await resolveTestUnit('''
-class A {
- main() {
- test;
- }
-}
-''');
- await assertHasFix(DartFixKind.CREATE_GETTER, '''
-class A {
- get test => null;
-
- main() {
- test;
- }
-}
-''');
- }
-
- test_createLocalVariable_functionType_named() async {
- await resolveTestUnit('''
-typedef MY_FUNCTION(int p);
-foo(MY_FUNCTION f) {}
-main() {
- foo(bar);
-}
-''');
- await assertHasFix(DartFixKind.CREATE_LOCAL_VARIABLE, '''
-typedef MY_FUNCTION(int p);
-foo(MY_FUNCTION f) {}
-main() {
- MY_FUNCTION bar;
- foo(bar);
-}
-''');
- }
-
- test_createLocalVariable_functionType_named_generic() async {
- await resolveTestUnit('''
-typedef MY_FUNCTION<T>(T p);
-foo(MY_FUNCTION<int> f) {}
-main() {
- foo(bar);
-}
-''');
- await assertHasFix(DartFixKind.CREATE_LOCAL_VARIABLE, '''
-typedef MY_FUNCTION<T>(T p);
-foo(MY_FUNCTION<int> f) {}
-main() {
- MY_FUNCTION<int> bar;
- foo(bar);
-}
-''');
- }
-
- test_createLocalVariable_functionType_synthetic() async {
- await resolveTestUnit('''
-foo(f(int p)) {}
-main() {
- foo(bar);
-}
-''');
- await assertHasFix(DartFixKind.CREATE_LOCAL_VARIABLE, '''
-foo(f(int p)) {}
-main() {
- Function(int p) bar;
- foo(bar);
-}
-''');
- }
-
- test_createLocalVariable_read_typeAssignment() async {
- await resolveTestUnit('''
-main() {
- int a = test;
-}
-''');
- await assertHasFix(DartFixKind.CREATE_LOCAL_VARIABLE, '''
-main() {
- int test;
- int a = test;
-}
-''');
- }
-
- test_createLocalVariable_read_typeCondition() async {
- await resolveTestUnit('''
-main() {
- if (!test) {
- print(42);
- }
-}
-''');
- await assertHasFix(DartFixKind.CREATE_LOCAL_VARIABLE, '''
-main() {
- bool test;
- if (!test) {
- print(42);
- }
-}
-''');
- }
-
- test_createLocalVariable_read_typeInvocationArgument() async {
- await resolveTestUnit('''
-main() {
- f(test);
-}
-f(String p) {}
-''');
- await assertHasFix(DartFixKind.CREATE_LOCAL_VARIABLE, '''
-main() {
- String test;
- f(test);
-}
-f(String p) {}
-''');
- _assertLinkedGroup(change.linkedEditGroups[0], ['String test;']);
- _assertLinkedGroup(change.linkedEditGroups[1], ['test;', 'test);']);
- }
-
- test_createLocalVariable_read_typeInvocationTarget() async {
- await resolveTestUnit('''
-main() {
- test.add('hello');
-}
-''');
- await assertHasFix(DartFixKind.CREATE_LOCAL_VARIABLE, '''
-main() {
- var test;
- test.add('hello');
-}
-''');
- _assertLinkedGroup(change.linkedEditGroups[0], ['test;', 'test.add(']);
- }
-
- test_createLocalVariable_withImport() async {
- addPackageSource('pkg', 'a/a.dart', '''
-class A {}
-''');
- addPackageSource('pkg', 'b/b.dart', '''
-class B {}
-''');
- addPackageSource('pkg', 'c/c.dart', '''
-import 'package:pkg/a/a.dart';
-import 'package:pkg/b/b.dart';
-
-class C {
- C(A a, B b);
-}
-''');
-
- await resolveTestUnit('''
-import 'package:pkg/a/a.dart';
-import 'package:pkg/c/c.dart';
-
-main() {
- A a;
- new C(a, b);
-}
-''');
- await assertHasFix(DartFixKind.CREATE_LOCAL_VARIABLE, '''
-import 'package:pkg/a/a.dart';
-import 'package:pkg/b/b.dart';
-import 'package:pkg/c/c.dart';
-
-main() {
- A a;
- B b;
- new C(a, b);
-}
-''');
-
- List<LinkedEditGroup> groups = change.linkedEditGroups;
- expect(groups, hasLength(2));
- LinkedEditGroup typeGroup = groups[0];
- List<Position> typePositions = typeGroup.positions;
- expect(typePositions, hasLength(1));
- expect(typePositions[0].offset, 112);
- LinkedEditGroup nameGroup = groups[1];
- List<Position> groupPositions = nameGroup.positions;
- expect(groupPositions, hasLength(2));
- expect(groupPositions[0].offset, 114);
- expect(groupPositions[1].offset, 128);
- }
-
- test_createLocalVariable_write_assignment() async {
- await resolveTestUnit('''
-main() {
- test = 42;
-}
-''');
- await assertHasFix(DartFixKind.CREATE_LOCAL_VARIABLE, '''
-main() {
- var test = 42;
-}
-''');
- }
-
- test_createLocalVariable_write_assignment_compound() async {
- await resolveTestUnit('''
-main() {
- test += 42;
-}
-''');
- await assertHasFix(DartFixKind.CREATE_LOCAL_VARIABLE, '''
-main() {
- int test;
- test += 42;
-}
-''');
- }
-
- test_createMissingOverrides_field_untyped() async {
- await resolveTestUnit('''
-class A {
- var f;
-}
-
-class B implements A {
-}
-''');
- await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, '''
-class A {
- var f;
-}
-
-class B implements A {
- @override
- var f;
-}
-''');
- }
-
- test_createMissingOverrides_functionTypeAlias() async {
- await resolveTestUnit('''
-typedef int Binary(int left, int right);
-
-abstract class Emulator {
- void performBinary(Binary binary);
-}
-
-class MyEmulator extends Emulator {
-}
-''');
- await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, '''
-typedef int Binary(int left, int right);
-
-abstract class Emulator {
- void performBinary(Binary binary);
-}
-
-class MyEmulator extends Emulator {
- @override
- void performBinary(Binary binary) {
- // TODO: implement performBinary
- }
-}
-''');
- }
-
- test_createMissingOverrides_functionTypedParameter() async {
- await resolveTestUnit('''
-abstract class A {
- void forEach(int f(double p1, String p2));
-}
-
-class B extends A {
-}
-''');
- await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, '''
-abstract class A {
- void forEach(int f(double p1, String p2));
-}
-
-class B extends A {
- @override
- void forEach(int Function(double p1, String p2) f) {
- // TODO: implement forEach
- }
-}
-''');
- }
-
- test_createMissingOverrides_generics_typeArguments() async {
- await resolveTestUnit('''
-class Iterator<T> {
-}
-
-abstract class IterableMixin<T> {
- Iterator<T> get iterator;
-}
-
-class Test extends IterableMixin<int> {
-}
-''');
- await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, '''
-class Iterator<T> {
-}
-
-abstract class IterableMixin<T> {
- Iterator<T> get iterator;
-}
-
-class Test extends IterableMixin<int> {
- @override
- // TODO: implement iterator
- Iterator<int> get iterator => null;
-}
-''');
- }
-
- test_createMissingOverrides_generics_typeParameters() async {
- await resolveTestUnit('''
-abstract class ItemProvider<T> {
- List<T> getItems();
-}
-
-class Test<V> extends ItemProvider<V> {
-}
-''');
- await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, '''
-abstract class ItemProvider<T> {
- List<T> getItems();
-}
-
-class Test<V> extends ItemProvider<V> {
- @override
- List<V> getItems() {
- // TODO: implement getItems
- return null;
- }
-}
-''');
- }
-
- test_createMissingOverrides_getter() async {
- await resolveTestUnit('''
-abstract class A {
- get g1;
- int get g2;
-}
-
-class B extends A {
-}
-''');
- await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, '''
-abstract class A {
- get g1;
- int get g2;
-}
-
-class B extends A {
- @override
- // TODO: implement g1
- get g1 => null;
-
- @override
- // TODO: implement g2
- int get g2 => null;
-}
-''');
- }
-
- test_createMissingOverrides_importPrefix() async {
- await resolveTestUnit('''
-import 'dart:async' as aaa;
-abstract class A {
- Map<aaa.Future, List<aaa.Future>> g(aaa.Future p);
-}
-
-class B extends A {
-}
-''');
- await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, '''
-import 'dart:async' as aaa;
-abstract class A {
- Map<aaa.Future, List<aaa.Future>> g(aaa.Future p);
-}
-
-class B extends A {
- @override
- Map<aaa.Future, List<aaa.Future>> g(aaa.Future p) {
- // TODO: implement g
- return null;
- }
-}
-''');
- }
-
- test_createMissingOverrides_mergeToField_getterSetter() async {
- await resolveTestUnit('''
-class A {
- int ma;
- void mb() {}
- double mc;
-}
-
-class B implements A {
-}
-''');
- await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, '''
-class A {
- int ma;
- void mb() {}
- double mc;
-}
-
-class B implements A {
- @override
- int ma;
-
- @override
- double mc;
-
- @override
- void mb() {
- // TODO: implement mb
- }
-}
-''');
- }
-
- test_createMissingOverrides_method() async {
- await resolveTestUnit('''
-abstract class A {
- void m1();
- int m2();
- String m3(int p1, double p2, Map<int, List<String>> p3);
- String m4(p1, p2);
- String m5(p1, [int p2 = 2, int p3, p4 = 4]);
- String m6(p1, {int p2 = 2, int p3, p4: 4});
-}
-
-class B extends A {
-}
-''');
- String expectedCode = '''
-abstract class A {
- void m1();
- int m2();
- String m3(int p1, double p2, Map<int, List<String>> p3);
- String m4(p1, p2);
- String m5(p1, [int p2 = 2, int p3, p4 = 4]);
- String m6(p1, {int p2 = 2, int p3, p4: 4});
-}
-
-class B extends A {
- @override
- void m1() {
- // TODO: implement m1
- }
-
- @override
- int m2() {
- // TODO: implement m2
- return null;
- }
-
- @override
- String m3(int p1, double p2, Map<int, List<String>> p3) {
- // TODO: implement m3
- return null;
- }
-
- @override
- String m4(p1, p2) {
- // TODO: implement m4
- return null;
- }
-
- @override
- String m5(p1, [int p2 = 2, int p3, p4 = 4]) {
- // TODO: implement m5
- return null;
- }
-
- @override
- String m6(p1, {int p2 = 2, int p3, p4 = 4}) {
- // TODO: implement m6
- return null;
- }
-}
-''';
- await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, expectedCode);
- // end position should be on "m1", not on "m2", "m3", etc
- {
- Position endPosition = change.selection;
- expect(endPosition, isNotNull);
- expect(endPosition.file, testFile);
- int endOffset = endPosition.offset;
- String endString = expectedCode.substring(endOffset, endOffset + 25);
- expect(endString, contains('m1'));
- expect(endString, isNot(contains('m2')));
- expect(endString, isNot(contains('m3')));
- expect(endString, isNot(contains('m4')));
- expect(endString, isNot(contains('m5')));
- expect(endString, isNot(contains('m6')));
- }
- }
-
- test_createMissingOverrides_method_emptyClassBody() async {
- await resolveTestUnit('''
-abstract class A {
- void foo();
-}
-
-class B extends A {}
-''');
- await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, '''
-abstract class A {
- void foo();
-}
-
-class B extends A {
- @override
- void foo() {
- // TODO: implement foo
- }
-}
-''');
- }
-
- test_createMissingOverrides_method_generic() async {
- await resolveTestUnit('''
-class C<T> {}
-class V<E> {}
-
-abstract class A {
- E1 foo<E1, E2 extends C<int>>(V<E2> v);
-}
-
-class B implements A {
-}
-''');
- await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, '''
-class C<T> {}
-class V<E> {}
-
-abstract class A {
- E1 foo<E1, E2 extends C<int>>(V<E2> v);
-}
-
-class B implements A {
- @override
- E1 foo<E1, E2 extends C<int>>(V<E2> v) {
- // TODO: implement foo
- return null;
- }
-}
-''');
- }
-
- test_createMissingOverrides_method_genericClass2() async {
- await resolveTestUnit('''
-class A<R> {
- R foo(int a) => null;
-}
-
-class B<R> extends A<R> {
- R bar(double b) => null;
-}
-
-class X implements B<bool> {
-}
-''');
- await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, '''
-class A<R> {
- R foo(int a) => null;
-}
-
-class B<R> extends A<R> {
- R bar(double b) => null;
-}
-
-class X implements B<bool> {
- @override
- bool bar(double b) {
- // TODO: implement bar
- return null;
- }
-
- @override
- bool foo(int a) {
- // TODO: implement foo
- return null;
- }
-}
-''');
- }
-
- test_createMissingOverrides_method_generic_withBounds() async {
- // https://github.com/dart-lang/sdk/issues/31199
- await resolveTestUnit('''
-abstract class A<K, V> {
- List<T> foo<T extends V>(K key);
-}
-
-class B<K, V> implements A<K, V> {
-}
-''');
- await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, '''
-abstract class A<K, V> {
- List<T> foo<T extends V>(K key);
-}
-
-class B<K, V> implements A<K, V> {
- @override
- List<T> foo<T extends V>(K key) {
- // TODO: implement foo
- return null;
- }
-}
-''');
- }
-
- test_createMissingOverrides_method_notEmptyClassBody() async {
- await resolveTestUnit('''
-abstract class A {
- void foo();
-}
-
-class B extends A {
- void bar() {}
-}
-''');
- await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, '''
-abstract class A {
- void foo();
-}
-
-class B extends A {
- void bar() {}
-
- @override
- void foo() {
- // TODO: implement foo
- }
-}
-''');
- }
-
- test_createMissingOverrides_operator() async {
- await resolveTestUnit('''
-abstract class A {
- int operator [](int index);
- void operator []=(int index, String value);
-}
-
-class B extends A {
-}
-''');
- await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, '''
-abstract class A {
- int operator [](int index);
- void operator []=(int index, String value);
-}
-
-class B extends A {
- @override
- int operator [](int index) {
- // TODO: implement []
- return null;
- }
-
- @override
- void operator []=(int index, String value) {
- // TODO: implement []=
- }
-}
-''');
- }
-
- test_createMissingOverrides_setter() async {
- await resolveTestUnit('''
-abstract class A {
- set s1(x);
- set s2(int x);
- void set s3(String x);
-}
-
-class B extends A {
-}
-''');
- await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, '''
-abstract class A {
- set s1(x);
- set s2(int x);
- void set s3(String x);
-}
-
-class B extends A {
- @override
- void set s1(x) {
- // TODO: implement s1
- }
-
- @override
- void set s2(int x) {
- // TODO: implement s2
- }
-
- @override
- void set s3(String x) {
- // TODO: implement s3
- }
-}
-''');
- }
-
- test_createMixin() async {
- await resolveTestUnit('''
-main() {
- Test v = null;
-}
-''');
- await assertHasFix(DartFixKind.CREATE_MIXIN, '''
-main() {
- Test v = null;
-}
-
-mixin Test {
-}
-''');
- _assertLinkedGroup(change.linkedEditGroups[0], ['Test v =', 'Test {']);
- }
-
- test_createMixin_BAD_hasUnresolvedPrefix() async {
- await resolveTestUnit('''
-main() {
- prefix.Test v = null;
-}
-''');
- await assertNoFix(DartFixKind.CREATE_MIXIN);
- }
-
- test_createMixin_BAD_instanceCreation_withNew() async {
- await resolveTestUnit('''
-main() {
- new Test();
-}
-''');
- await assertNoFix(DartFixKind.CREATE_MIXIN);
- }
-
- test_createMixin_BAD_instanceCreation_withoutNew() async {
- await resolveTestUnit('''
-main() {
- Test();
-}
-''');
- await assertNoFix(DartFixKind.CREATE_MIXIN);
- }
-
- test_createMixin_inLibraryOfPrefix() async {
- String libCode = r'''
-library my.lib;
-
-class A {}
-''';
- addSource('/project/lib.dart', libCode);
- await resolveTestUnit('''
-import 'lib.dart' as lib;
-
-main() {
- lib.A a = null;
- lib.Test t = null;
-}
-''');
- AnalysisError error = await _findErrorToFix();
- fix = await _assertHasFix(DartFixKind.CREATE_MIXIN, error);
- change = fix.change;
- // apply to "lib.dart"
- List<SourceFileEdit> fileEdits = change.edits;
- expect(fileEdits, hasLength(1));
- SourceFileEdit fileEdit = change.edits[0];
- expect(fileEdit.file, convertPath('/project/lib.dart'));
- expect(SourceEdit.applySequence(libCode, fileEdit.edits), r'''
-library my.lib;
-
-class A {}
-
-mixin Test {
-}
-''');
- expect(change.linkedEditGroups, hasLength(1));
- }
-
- test_createMixin_innerLocalFunction() async {
- await resolveTestUnit('''
-f() {
- g() {
- Test v = null;
- }
-}
-''');
- await assertHasFix(DartFixKind.CREATE_MIXIN, '''
-f() {
- g() {
- Test v = null;
- }
-}
-
-mixin Test {
-}
-''');
- _assertLinkedGroup(change.linkedEditGroups[0], ['Test v =', 'Test {']);
- }
-
- test_createMixin_itemOfList() async {
- await resolveTestUnit('''
-main() {
- var a = [Test];
-}
-''');
- await assertHasFix(DartFixKind.CREATE_MIXIN, '''
-main() {
- var a = [Test];
-}
-
-mixin Test {
-}
-''');
- _assertLinkedGroup(change.linkedEditGroups[0], ['Test];', 'Test {']);
- }
-
- test_createMixin_itemOfList_inAnnotation() async {
- errorFilter = (AnalysisError error) {
- return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER;
- };
- await resolveTestUnit('''
-class MyAnnotation {
- const MyAnnotation(a, b);
-}
-@MyAnnotation(int, const [Test])
-main() {}
-''');
- await assertHasFix(DartFixKind.CREATE_MIXIN, '''
-class MyAnnotation {
- const MyAnnotation(a, b);
-}
-@MyAnnotation(int, const [Test])
-main() {}
-
-mixin Test {
-}
-''');
- _assertLinkedGroup(change.linkedEditGroups[0], ['Test])', 'Test {']);
- }
-
- test_createNoSuchMethod_BAD_classTypeAlias() async {
- await resolveTestUnit('''
-abstract class A {
- m();
-}
-
-class B = Object with A;
-''');
- await assertNoFix(
- DartFixKind.CREATE_NO_SUCH_METHOD,
- );
- }
-
- test_createNoSuchMethod_OK() async {
- await resolveTestUnit('''
-abstract class A {
- m1();
- int m2();
-}
-
-class B extends A {
- existing() {}
-}
-''');
- await assertHasFix(DartFixKind.CREATE_NO_SUCH_METHOD, '''
-abstract class A {
- m1();
- int m2();
-}
-
-class B extends A {
- existing() {}
-
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
-''');
- }
-
- test_creationFunction_forFunctionType_cascadeSecond() async {
- await resolveTestUnit('''
-class A {
- B ma() => null;
-}
-class B {
- useFunction(int g(double a, String b)) {}
-}
-
-main() {
- A a = new A();
- a..ma().useFunction(test);
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FUNCTION, '''
-class A {
- B ma() => null;
-}
-class B {
- useFunction(int g(double a, String b)) {}
-}
-
-main() {
- A a = new A();
- a..ma().useFunction(test);
-}
-
-int test(double a, String b) {
-}
-''');
- }
-
- test_creationFunction_forFunctionType_coreFunction() async {
- await resolveTestUnit('''
-main() {
- useFunction(g: test);
-}
-useFunction({Function g}) {}
-''');
- await assertHasFix(DartFixKind.CREATE_FUNCTION, '''
-main() {
- useFunction(g: test);
-}
-useFunction({Function g}) {}
-
-test() {
-}
-''');
- }
-
- test_creationFunction_forFunctionType_dynamicArgument() async {
- await resolveTestUnit('''
-main() {
- useFunction(test);
-}
-useFunction(int g(a, b)) {}
-''');
- await assertHasFix(DartFixKind.CREATE_FUNCTION, '''
-main() {
- useFunction(test);
-}
-useFunction(int g(a, b)) {}
-
-int test(a, b) {
-}
-''');
- }
-
- test_creationFunction_forFunctionType_function() async {
- await resolveTestUnit('''
-main() {
- useFunction(test);
-}
-useFunction(int g(double a, String b)) {}
-''');
- await assertHasFix(DartFixKind.CREATE_FUNCTION, '''
-main() {
- useFunction(test);
-}
-useFunction(int g(double a, String b)) {}
-
-int test(double a, String b) {
-}
-''');
- }
-
- test_creationFunction_forFunctionType_function_namedArgument() async {
- await resolveTestUnit('''
-main() {
- useFunction(g: test);
-}
-useFunction({int g(double a, String b)}) {}
-''');
- await assertHasFix(DartFixKind.CREATE_FUNCTION, '''
-main() {
- useFunction(g: test);
-}
-useFunction({int g(double a, String b)}) {}
-
-int test(double a, String b) {
-}
-''');
- }
-
- test_creationFunction_forFunctionType_importType() async {
- addSource('/project/libA.dart', r'''
-library libA;
-class A {}
-''');
- addSource('/project/libB.dart', r'''
-library libB;
-import 'libA.dart';
-useFunction(int g(A a)) {}
-''');
- await resolveTestUnit('''
-import 'libB.dart';
-main() {
- useFunction(test);
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FUNCTION, '''
-import 'libA.dart';
-import 'libB.dart';
-main() {
- useFunction(test);
-}
-
-int test(A a) {
-}
-''');
- }
-
- test_creationFunction_forFunctionType_method_enclosingClass_static() async {
- await resolveTestUnit('''
-class A {
- static foo() {
- useFunction(test);
- }
-}
-useFunction(int g(double a, String b)) {}
-''');
- await assertHasFix(DartFixKind.CREATE_METHOD, '''
-class A {
- static foo() {
- useFunction(test);
- }
-
- static int test(double a, String b) {
- }
-}
-useFunction(int g(double a, String b)) {}
-''');
- }
-
- test_creationFunction_forFunctionType_method_enclosingClass_static2() async {
- await resolveTestUnit('''
-class A {
- var f;
- A() : f = useFunction(test);
-}
-useFunction(int g(double a, String b)) {}
-''');
- await assertHasFix(DartFixKind.CREATE_METHOD, '''
-class A {
- var f;
- A() : f = useFunction(test);
-
- static int test(double a, String b) {
- }
-}
-useFunction(int g(double a, String b)) {}
-''');
- }
-
- test_creationFunction_forFunctionType_method_targetClass() async {
- await resolveTestUnit('''
-main(A a) {
- useFunction(a.test);
-}
-class A {
-}
-useFunction(int g(double a, String b)) {}
-''');
- await assertHasFix(DartFixKind.CREATE_METHOD, '''
-main(A a) {
- useFunction(a.test);
-}
-class A {
- int test(double a, String b) {
- }
-}
-useFunction(int g(double a, String b)) {}
-''');
- }
-
- test_creationFunction_forFunctionType_method_targetClass_hasOtherMember() async {
- await resolveTestUnit('''
-main(A a) {
- useFunction(a.test);
-}
-class A {
- m() {}
-}
-useFunction(int g(double a, String b)) {}
-''');
- await assertHasFix(DartFixKind.CREATE_METHOD, '''
-main(A a) {
- useFunction(a.test);
-}
-class A {
- m() {}
-
- int test(double a, String b) {
- }
-}
-useFunction(int g(double a, String b)) {}
-''');
- }
-
- test_creationFunction_forFunctionType_notFunctionType() async {
- await resolveTestUnit('''
-main(A a) {
- useFunction(a.test);
-}
-typedef A();
-useFunction(g) {}
-''');
- await assertNoFix(DartFixKind.CREATE_METHOD);
- await assertNoFix(DartFixKind.CREATE_FUNCTION);
- }
-
- test_creationFunction_forFunctionType_unknownTarget() async {
- await resolveTestUnit('''
-main(A a) {
- useFunction(a.test);
-}
-class A {
-}
-useFunction(g) {}
-''');
- await assertNoFix(DartFixKind.CREATE_METHOD);
- }
-
- test_expectedToken_semicolon() async {
- await resolveTestUnit('''
-main() {
- print(0)
-}
-''');
- await assertHasFix(DartFixKind.INSERT_SEMICOLON, '''
-main() {
- print(0);
-}
-''');
- }
-
- test_illegalAsyncReturnType_adjacentNodes() async {
- errorFilter = (AnalysisError error) {
- return error.errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE;
- };
- await resolveTestUnit('''
-import 'dart:async';
-var v;int main() async => 0;
-''');
- await assertHasFix(DartFixKind.REPLACE_RETURN_TYPE_FUTURE, '''
-import 'dart:async';
-var v;Future<int> main() async => 0;
-''');
- }
-
- test_illegalAsyncReturnType_asyncLibrary_import() async {
- errorFilter = (AnalysisError error) {
- return error.errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE;
- };
- await resolveTestUnit('''
-library main;
-int main() async {
-}
-''');
- await assertHasFix(DartFixKind.REPLACE_RETURN_TYPE_FUTURE, '''
-library main;
-
-import 'dart:async';
-
-Future<int> main() async {
-}
-''');
- }
-
- test_illegalAsyncReturnType_asyncLibrary_usePrefix() async {
- errorFilter = (AnalysisError error) {
- return error.errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE;
- };
- await resolveTestUnit('''
-import 'dart:async' as al;
-int main() async {
-}
-''');
- await assertHasFix(DartFixKind.REPLACE_RETURN_TYPE_FUTURE, '''
-import 'dart:async' as al;
-al.Future<int> main() async {
-}
-''');
- }
-
- test_illegalAsyncReturnType_complexTypeName() async {
- errorFilter = (AnalysisError error) {
- return error.errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE;
- };
- await resolveTestUnit('''
-import 'dart:async';
-List<int> main() async {
-}
-''');
- await assertHasFix(DartFixKind.REPLACE_RETURN_TYPE_FUTURE, '''
-import 'dart:async';
-Future<List<int>> main() async {
-}
-''');
- }
-
- test_importLibraryPackage_preferDirectOverExport() async {
- _configureMyPkg({'b.dart': 'class Test {}', 'a.dart': "export 'b.dart';"});
- await resolveTestUnit('''
-main() {
- Test test = null;
-}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT1, '''
-import 'package:my_pkg/b.dart';
-
-main() {
- Test test = null;
-}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT2, '''
-import 'package:my_pkg/a.dart';
-
-main() {
- Test test = null;
-}
-''');
- }
-
- test_importLibraryPackage_preferDirectOverExport_src() async {
- myPkgLibPath = '/my/src/packages/my_pkg/lib';
- _configureMyPkg({'b.dart': 'class Test {}', 'a.dart': "export 'b.dart';"});
- await resolveTestUnit('''
-main() {
- Test test = null;
-}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT1, '''
-import 'package:my_pkg/b.dart';
-
-main() {
- Test test = null;
-}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT2, '''
-import 'package:my_pkg/a.dart';
-
-main() {
- Test test = null;
-}
-''');
- }
-
- test_importLibraryProject_BAD_inLibSrc_differentContextRoot() async {
- addPackageSource('bbb', 'b1.dart', r'''
-import 'src/b2.dart';
-''');
- addPackageSource('bbb', 'src/b2.dart', 'class Test {}');
- await resolveTestUnit('''
-import 'package:bbb/b1.dart';
-main() {
- Test t;
-}
-''');
- errorFilter = (AnalysisError error) {
- return error.errorCode == StaticWarningCode.UNDEFINED_CLASS;
- };
- await assertNoFix(DartFixKind.IMPORT_LIBRARY_PROJECT3);
- }
-
- test_importLibraryProject_BAD_notInLib_BUILD() async {
- testFile = '/project/lib/test.dart';
- addSource('/other/test/lib.dart', 'class Test {}');
- await resolveTestUnit('''
-main() {
- Test t;
-}
-''');
- await assertNoFix(DartFixKind.IMPORT_LIBRARY_PROJECT1);
- }
-
- test_importLibraryProject_BAD_notInLib_pubspec() async {
- testFile = '/project/lib/test.dart';
- addSource('/other/test/lib.dart', 'class Test {}');
- await resolveTestUnit('''
-main() {
- Test t;
-}
-''');
- await assertNoFix(DartFixKind.IMPORT_LIBRARY_PROJECT1);
- }
-
- test_importLibraryProject_OK_inLibSrc_thisContextRoot() async {
- testFile = '/project/lib/test.dart';
- packageMap['project'] = [newFolder('/project/lib')];
- addSource('/project/lib/src/lib.dart', 'class Test {}');
- configureDriver();
- await resolveTestUnit('''
-main() {
- Test t;
-}
-''');
- errorFilter = (AnalysisError error) {
- return error.errorCode == StaticWarningCode.UNDEFINED_CLASS;
- };
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT3, '''
-import 'package:project/src/lib.dart';
-
-main() {
- Test t;
-}
-''');
- }
-
- test_importLibraryProject_withClass_annotation() async {
- testFile = '/project/lib/test.dart';
- addSource('/project/lib/lib.dart', '''
-library lib;
-class Test {
- const Test(int p);
-}
-''');
- await resolveTestUnit('''
-@Test(0)
-main() {
-}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT1, '''
-import 'lib.dart';
-
-@Test(0)
-main() {
-}
-''');
- }
-
- test_importLibraryProject_withClass_hasOtherLibraryWithPrefix() async {
- testFile = '/project/bin/test.dart';
- addSource('/project/bin/a.dart', '''
-library a;
-class One {}
-''');
- addSource('/project/bin/b.dart', '''
-library b;
-class One {}
-class Two {}
-''');
- await resolveTestUnit('''
-import 'b.dart' show Two;
-main () {
- new Two();
- new One();
-}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT1, '''
-import 'a.dart';
-import 'b.dart' show Two;
-main () {
- new Two();
- new One();
-}
-''');
- }
-
- test_importLibraryProject_withClass_inParentFolder() async {
- testFile = '/project/bin/test.dart';
- addSource('/project/lib.dart', '''
-library lib;
-class Test {}
-''');
- await resolveTestUnit('''
-main() {
- Test t = null;
-}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT1, '''
-import '../lib.dart';
-
-main() {
- Test t = null;
-}
-''');
- }
-
- test_importLibraryProject_withClass_inRelativeFolder() async {
- testFile = '/project/bin/test.dart';
- addSource('/project/lib/sub/folder/lib.dart', '''
-library lib;
-class Test {}
-''');
- await resolveTestUnit('''
-main() {
- Test t = null;
-}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT1, '''
-import '../lib/sub/folder/lib.dart';
-
-main() {
- Test t = null;
-}
-''');
- }
-
- test_importLibraryProject_withClass_inSameFolder() async {
- testFile = '/project/bin/test.dart';
- addSource('/project/bin/lib.dart', '''
-library lib;
-class Test {}
-''');
- await resolveTestUnit('''
-main() {
- Test t = null;
-}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT1, '''
-import 'lib.dart';
-
-main() {
- Test t = null;
-}
-''');
- }
-
- test_importLibraryProject_withClass_instanceCreation_const() async {
- testFile = '/project/lib/test.dart';
- addSource('/project/lib/lib.dart', '''
-class Test {
- const Test();
-}
-''');
- await resolveTestUnit('''
-main() {
- return const Test();
-}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT1, '''
-import 'lib.dart';
-
-main() {
- return const Test();
-}
-''');
- }
-
- test_importLibraryProject_withClass_instanceCreation_const_namedConstructor() async {
- testFile = '/project/lib/test.dart';
- addSource('/project/lib/lib.dart', '''
-class Test {
- const Test.named();
-}
-''');
- await resolveTestUnit('''
-main() {
- const Test.named();
-}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT1, '''
-import 'lib.dart';
-
-main() {
- const Test.named();
-}
-''');
- }
-
- test_importLibraryProject_withClass_instanceCreation_implicit() async {
- testFile = '/project/lib/test.dart';
- addSource('/project/lib/lib.dart', '''
-class Test {
- const Test();
-}
-''');
- await resolveTestUnit('''
-main() {
- return Test();
-}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT1, '''
-import 'lib.dart';
-
-main() {
- return Test();
-}
-''');
- }
-
- test_importLibraryProject_withClass_instanceCreation_new() async {
- testFile = '/project/lib/test.dart';
- addSource('/project/lib/lib.dart', '''
-class Test {
- const Test();
-}
-''');
- await resolveTestUnit('''
-main() {
- return new Test();
-}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT1, '''
-import 'lib.dart';
-
-main() {
- return new Test();
-}
-''');
- }
-
- test_importLibraryProject_withClass_instanceCreation_new_namedConstructor() async {
- testFile = '/project/lib/test.dart';
- addSource('/project/lib/lib.dart', '''
-class Test {
- Test.named();
-}
-''');
- await resolveTestUnit('''
-main() {
- new Test.named();
-}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT1, '''
-import 'lib.dart';
-
-main() {
- new Test.named();
-}
-''');
- }
-
- test_importLibraryProject_withFunction() async {
- testFile = '/project/lib/test.dart';
- addSource('/project/lib/lib.dart', '''
-library lib;
-myFunction() {}
-''');
- await resolveTestUnit('''
-main() {
- myFunction();
-}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT1, '''
-import 'lib.dart';
-
-main() {
- myFunction();
-}
-''');
- }
-
- test_importLibraryProject_withFunction_unresolvedMethod() async {
- testFile = '/project/lib/test.dart';
- addSource('/project/lib/lib.dart', '''
-library lib;
-myFunction() {}
-''');
- await resolveTestUnit('''
-class A {
- main() {
- myFunction();
- }
-}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT1, '''
-import 'lib.dart';
-
-class A {
- main() {
- myFunction();
- }
-}
-''');
- }
-
- test_importLibraryProject_withFunctionTypeAlias() async {
- testFile = '/project/bin/test.dart';
- addSource('/project/bin/lib.dart', '''
-library lib;
-typedef MyFunction();
-''');
- await resolveTestUnit('''
-main() {
- MyFunction t = null;
-}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT1, '''
-import 'lib.dart';
-
-main() {
- MyFunction t = null;
-}
-''');
- }
-
- test_importLibraryProject_withTopLevelVariable() async {
- testFile = '/project/lib/test.dart';
- addSource('/project/lib/lib.dart', '''
-library lib;
-int MY_VAR = 42;
-''');
- await resolveTestUnit('''
-main() {
- print(MY_VAR);
-}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT1, '''
-import 'lib.dart';
-
-main() {
- print(MY_VAR);
-}
-''');
- }
-
- test_importLibrarySdk_withClass_AsExpression() async {
- await resolveTestUnit('''
-main(p) {
- p as Future;
-}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, '''
-import 'dart:async';
-
-main(p) {
- p as Future;
-}
-''');
- }
-
- test_importLibrarySdk_withClass_instanceCreation_explicitNew() async {
- await resolveTestUnit('''
-class C {
- foo() {
- new Future();
- }
-}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, '''
-import 'dart:async';
-
-class C {
- foo() {
- new Future();
- }
-}
-''');
- }
-
- test_importLibrarySdk_withClass_instanceCreation_explicitNew_namedConstructor() async {
- await resolveTestUnit('''
-class C {
- foo() {
- new Future.value(0);
- }
-}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, '''
-import 'dart:async';
-
-class C {
- foo() {
- new Future.value(0);
- }
-}
-''');
- }
-
- test_importLibrarySdk_withClass_instanceCreation_implicitNew() async {
- configurePreviewDart2();
- await resolveTestUnit('''
-class C {
- foo() {
- Future();
- }
-}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, '''
-import 'dart:async';
-
-class C {
- foo() {
- Future();
- }
-}
-''');
- }
-
- test_importLibrarySdk_withClass_instanceCreation_implicitNew_namedConstructor() async {
- configurePreviewDart2();
- await resolveTestUnit('''
-class C {
- foo() {
- Future.value(0);
- }
-}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, '''
-import 'dart:async';
-
-class C {
- foo() {
- Future.value(0);
- }
-}
-''');
- }
-
- test_importLibrarySdk_withClass_invocationTarget() async {
- await resolveTestUnit('''
-main() {
- Future.wait(null);
-}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, '''
-import 'dart:async';
-
-main() {
- Future.wait(null);
-}
-''');
- }
-
- test_importLibrarySdk_withClass_IsExpression() async {
- await resolveTestUnit('''
-main(p) {
- p is Future;
-}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, '''
-import 'dart:async';
-
-main(p) {
- p is Future;
-}
-''');
- }
-
- test_importLibrarySdk_withClass_itemOfList() async {
- await resolveTestUnit('''
-main() {
- var a = [Future];
-}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, '''
-import 'dart:async';
-
-main() {
- var a = [Future];
-}
-''');
- }
-
- test_importLibrarySdk_withClass_itemOfList_inAnnotation() async {
- errorFilter = (AnalysisError error) {
- return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER;
- };
- await resolveTestUnit('''
-class MyAnnotation {
- const MyAnnotation(a, b);
-}
-@MyAnnotation(int, const [Future])
-main() {}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, '''
-import 'dart:async';
-
-class MyAnnotation {
- const MyAnnotation(a, b);
-}
-@MyAnnotation(int, const [Future])
-main() {}
-''');
- }
-
- test_importLibrarySdk_withClass_typeAnnotation() async {
- await resolveTestUnit('''
-main() {
- Future f = null;
-}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, '''
-import 'dart:async';
-
-main() {
- Future f = null;
-}
-''');
- }
-
- test_importLibrarySdk_withClass_typeAnnotation_PrefixedIdentifier() async {
- await resolveTestUnit('''
-main() {
- Future.wait;
-}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, '''
-import 'dart:async';
-
-main() {
- Future.wait;
-}
-''');
- }
-
- test_importLibrarySdk_withClass_typeArgument() async {
- await resolveTestUnit('''
-main() {
- List<Future> futures = [];
-}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, '''
-import 'dart:async';
-
-main() {
- List<Future> futures = [];
-}
-''');
- }
-
- test_importLibrarySdk_withTopLevelVariable() async {
- await resolveTestUnit('''
-main() {
- print(PI);
-}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, '''
-import 'dart:math';
-
-main() {
- print(PI);
-}
-''');
- }
-
- test_importLibrarySdk_withTopLevelVariable_annotation() async {
- await resolveTestUnit('''
-@PI
-main() {
-}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, '''
-import 'dart:math';
-
-@PI
-main() {
-}
-''');
- }
-
- test_importLibraryShow_project() async {
- testFile = '/project/bin/test.dart';
- addSource('/project/bin/lib.dart', '''
-class A {}
-class B {}
-''');
- await resolveTestUnit('''
-import 'lib.dart' show A;
-main() {
- A a;
- B b;
-}
-''');
- await assertNoFix(DartFixKind.IMPORT_LIBRARY_PROJECT1);
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_SHOW, '''
-import 'lib.dart' show A, B;
-main() {
- A a;
- B b;
-}
-''');
- }
-
- test_importLibraryShow_sdk() async {
- await resolveTestUnit('''
-import 'dart:async' show Stream;
-main() {
- Stream s = null;
- Future f = null;
-}
-''');
- await assertNoFix(DartFixKind.IMPORT_LIBRARY_SDK);
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_SHOW, '''
-import 'dart:async' show Future, Stream;
-main() {
- Stream s = null;
- Future f = null;
-}
-''');
- }
-
- test_impreciseIntAsDouble() async {
- await resolveTestUnit('''
-double x = 1000000000000000000000000;
-''');
- await assertHasFix(DartFixKind.CHANGE_TO_NEAREST_PRECISE_VALUE, '''
-double x = 999999999999999983222784;
-''');
- }
-
- test_impreciseIntAsDouble_asCapitalHex() async {
- await resolveTestUnit('''
-double x = 0X1000000000000000000000001;
-''');
- await assertHasFix(DartFixKind.CHANGE_TO_NEAREST_PRECISE_VALUE, '''
-double x = 0x1000000000000000000000000;
-''');
- }
-
- test_impreciseIntAsDouble_asHex() async {
- await resolveTestUnit('''
-double x = 0x1000000000000000000000001;
-''');
- await assertHasFix(DartFixKind.CHANGE_TO_NEAREST_PRECISE_VALUE, '''
-double x = 0x1000000000000000000000000;
-''');
- }
-
- test_impreciseIntAsDouble_maxValue() async {
- await resolveTestUnit('''
-double x = 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;
-''');
- await assertHasFix(DartFixKind.CHANGE_TO_NEAREST_PRECISE_VALUE, '''
-double x = 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368;
-''');
- }
-
- test_impreciseIntAsDouble_maxValue_asHex() async {
- await resolveTestUnit('''
-double x = 0x100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;
-''');
- await assertHasFix(DartFixKind.CHANGE_TO_NEAREST_PRECISE_VALUE, '''
-double x = 0xFFFFFFFFFFFFF800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;
-''');
- }
-
- test_isNotNull() async {
- await resolveTestUnit('''
-main(p) {
- p is! Null;
-}
-''');
- await assertHasFix(DartFixKind.USE_NOT_EQ_NULL, '''
-main(p) {
- p != null;
-}
-''');
- }
-
- test_isNotNull_all() async {
- await resolveTestUnit('''
-main(p, q) {
- p is! Null;
- q is! Null;
-}
-''');
- await assertHasFixAllFix(
- HintCode.TYPE_CHECK_IS_NOT_NULL, DartFixKind.USE_NOT_EQ_NULL, '''
-main(p, q) {
- p != null;
- q != null;
-}
-''');
- }
-
- test_isNull() async {
- await resolveTestUnit('''
-main(p) {
- p is Null;
-}
-''');
- await assertHasFix(DartFixKind.USE_EQ_EQ_NULL, '''
-main(p) {
- p == null;
-}
-''');
- }
-
- test_isNull_all() async {
- await resolveTestUnit('''
-main(p, q) {
- p is Null;
- q is Null;
-}
-''');
- await assertHasFixAllFix(
- HintCode.TYPE_CHECK_IS_NULL, DartFixKind.USE_EQ_EQ_NULL, '''
-main(p, q) {
- p == null;
- q == null;
-}
-''');
- }
-
- test_makeEnclosingClassAbstract_declaresAbstractMethod() async {
- await resolveTestUnit('''
-class A {
- m();
-}
-''');
- await assertHasFix(DartFixKind.MAKE_CLASS_ABSTRACT, '''
-abstract class A {
- m();
-}
-''');
- }
-
- test_makeEnclosingClassAbstract_inheritsAbstractMethod() async {
- await resolveTestUnit('''
-abstract class A {
- m();
-}
-class B extends A {
-}
-''');
- await assertHasFix(DartFixKind.MAKE_CLASS_ABSTRACT, '''
-abstract class A {
- m();
-}
-abstract class B extends A {
-}
-''');
- }
-
- test_makeFieldNotFinal_hasType() async {
- await resolveTestUnit('''
-class A {
- final int fff = 1;
- main() {
- fff = 2;
- }
-}
-''');
- await assertHasFix(DartFixKind.MAKE_FIELD_NOT_FINAL, '''
-class A {
- int fff = 1;
- main() {
- fff = 2;
- }
-}
-''');
- }
-
- test_makeFieldNotFinal_noType() async {
- await resolveTestUnit('''
-class A {
- final fff = 1;
- main() {
- fff = 2;
- }
-}
-''');
- await assertHasFix(DartFixKind.MAKE_FIELD_NOT_FINAL, '''
-class A {
- var fff = 1;
- main() {
- fff = 2;
- }
-}
-''');
- }
-
- test_moveTypeArgumentsToClass_explicitConst() async {
- await resolveTestUnit('''
-main() {
- const C.named<int>();
-}
-class C<E> {
- const C.named();
-}
-''');
- await assertHasFix(DartFixKind.MOVE_TYPE_ARGUMENTS_TO_CLASS, '''
-main() {
- const C<int>.named();
-}
-class C<E> {
- const C.named();
-}
-''');
- }
-
- test_moveTypeArgumentsToClass_explicitNew() async {
- await resolveTestUnit('''
-main() {
- new C.named<int>();
-}
-class C<E> {
- C.named();
-}
-''');
- await assertHasFix(DartFixKind.MOVE_TYPE_ARGUMENTS_TO_CLASS, '''
-main() {
- new C<int>.named();
-}
-class C<E> {
- C.named();
-}
-''');
- }
-
- test_moveTypeArgumentsToClass_explicitNew_BAD_alreadyThere() async {
- await resolveTestUnit('''
-main() {
- new C<String>.named<int>();
-}
-class C<E> {
- C.named();
-}
-''');
- await assertNoFix(DartFixKind.MOVE_TYPE_ARGUMENTS_TO_CLASS);
- }
-
- test_moveTypeArgumentsToClass_explicitNew_BAD_wrongNumber() async {
- await resolveTestUnit('''
-main() {
- new C.named<int, String>();
-}
-class C<E> {
- C.named();
-}
-''');
- await assertNoFix(DartFixKind.MOVE_TYPE_ARGUMENTS_TO_CLASS);
- }
-
- test_moveTypeArgumentsToClass_implicitConst() async {
- await resolveTestUnit('''
-main() {
- const C c = C.named<int>();
-}
-class C<E> {
- const C.named();
-}
-''');
- await assertHasFix(DartFixKind.MOVE_TYPE_ARGUMENTS_TO_CLASS, '''
-main() {
- const C c = C<int>.named();
-}
-class C<E> {
- const C.named();
-}
-''');
- }
-
- test_moveTypeArgumentsToClass_implicitNew() async {
- await resolveTestUnit('''
-main() {
- C.named<int>();
-}
-class C<E> {
- C.named();
-}
-''');
- await assertHasFix(DartFixKind.MOVE_TYPE_ARGUMENTS_TO_CLASS, '''
-main() {
- C<int>.named();
-}
-class C<E> {
- C.named();
-}
-''');
- }
-
- test_noException_1() async {
- await resolveTestUnit('''
-main(p) {
- p i s Null;
-}''');
- List<AnalysisError> errors = await _computeErrors();
- for (var error in errors) {
- await _computeFixes(error);
- }
- }
-
- test_nonBoolCondition_addNotNull() async {
- await resolveTestUnit('''
-main(String p) {
- if (p) {
- print(p);
- }
-}
-''');
- await assertHasFix(DartFixKind.ADD_NE_NULL, '''
-main(String p) {
- if (p != null) {
- print(p);
- }
-}
-''');
- }
-
- test_nonBoolCondition_addNotNull_all() async {
- await resolveTestUnit('''
-main(String p, String q) {
- if (p) {
- print(p);
- }
- if (q) {
- print(q);
- }
-}
-''');
- await assertHasFixAllFix(
- StaticTypeWarningCode.NON_BOOL_CONDITION, DartFixKind.ADD_NE_NULL, '''
-main(String p, String q) {
- if (p != null) {
- print(p);
- }
- if (q != null) {
- print(q);
- }
-}
-''');
- }
-
- test_removeDeadCode_condition() async {
- await resolveTestUnit('''
-main(int p) {
- if (true || p > 5) {
- print(1);
- }
-}
-''');
- await assertHasFix(DartFixKind.REMOVE_DEAD_CODE, '''
-main(int p) {
- if (true) {
- print(1);
- }
-}
-''');
- }
-
- test_removeDeadCode_statements_one() async {
- await resolveTestUnit('''
-int main() {
- print(0);
- return 42;
- print(1);
-}
-''');
- await assertHasFix(DartFixKind.REMOVE_DEAD_CODE, '''
-int main() {
- print(0);
- return 42;
-}
-''');
- }
-
- test_removeDeadCode_statements_two() async {
- await resolveTestUnit('''
-int main() {
- print(0);
- return 42;
- print(1);
- print(2);
-}
-''');
- await assertHasFix(DartFixKind.REMOVE_DEAD_CODE, '''
-int main() {
- print(0);
- return 42;
-}
-''');
- }
-
- test_removeParentheses_inGetterDeclaration() async {
- await resolveTestUnit('''
-class A {
- int get foo() => 0;
-}
-''');
- await assertHasFix(DartFixKind.REMOVE_PARAMETERS_IN_GETTER_DECLARATION, '''
-class A {
- int get foo => 0;
-}
-''');
- }
-
- test_removeParentheses_inGetterInvocation() async {
- await resolveTestUnit('''
-class A {
- int get foo => 0;
-}
-main(A a) {
- a.foo();
-}
-''');
- await assertHasFix(DartFixKind.REMOVE_PARENTHESIS_IN_GETTER_INVOCATION, '''
-class A {
- int get foo => 0;
-}
-main(A a) {
- a.foo;
-}
-''');
- }
-
- test_removeTypeArguments_explicitConst() async {
- await resolveTestUnit('''
-main() {
- const C.named<int>();
-}
-class C<E> {
- const C.named();
-}
-''');
- await assertHasFix(DartFixKind.REMOVE_TYPE_ARGUMENTS, '''
-main() {
- const C.named();
-}
-class C<E> {
- const C.named();
-}
-''');
- }
-
- test_removeTypeArguments_explicitNew() async {
- await resolveTestUnit('''
-main() {
- new C.named<int>();
-}
-class C<E> {
- C.named();
-}
-''');
- await assertHasFix(DartFixKind.REMOVE_TYPE_ARGUMENTS, '''
-main() {
- new C.named();
-}
-class C<E> {
- C.named();
-}
-''');
- }
-
- test_removeTypeArguments_implicitConst() async {
- await resolveTestUnit('''
-main() {
- const C c = C.named<int>();
-}
-class C<E> {
- const C.named();
-}
-''');
- await assertHasFix(DartFixKind.REMOVE_TYPE_ARGUMENTS, '''
-main() {
- const C c = C.named();
-}
-class C<E> {
- const C.named();
-}
-''');
- }
-
- test_removeTypeArguments_implicitNew() async {
- await resolveTestUnit('''
-main() {
- C.named<int>();
-}
-class C<E> {
- C.named();
-}
-''');
- await assertHasFix(DartFixKind.REMOVE_TYPE_ARGUMENTS, '''
-main() {
- C.named();
-}
-class C<E> {
- C.named();
-}
-''');
- }
-
- test_removeUnnecessaryCast_assignment() async {
- await resolveTestUnit('''
-main(Object p) {
- if (p is String) {
- String v = ((p as String));
- }
-}
-''');
- await assertHasFix(DartFixKind.REMOVE_UNNECESSARY_CAST, '''
-main(Object p) {
- if (p is String) {
- String v = p;
- }
-}
-''');
- }
-
- test_removeUnnecessaryCast_assignment_all() async {
- await resolveTestUnit('''
-main(Object p, Object q) {
- if (p is String) {
- String v = ((p as String));
- }
- if (q is int) {
- int v = ((q as int));
- }
-}
-''');
- await assertHasFixAllFix(
- HintCode.UNNECESSARY_CAST, DartFixKind.REMOVE_UNNECESSARY_CAST, '''
-main(Object p, Object q) {
- if (p is String) {
- String v = p;
- }
- if (q is int) {
- int v = q;
- }
-}
-''');
- }
-
- test_removeUnusedCatchClause() async {
- errorFilter = (AnalysisError error) => true;
- await resolveTestUnit('''
-main() {
- try {
- throw 42;
- } on int catch (e) {
- }
-}
-''');
- await assertHasFix(DartFixKind.REMOVE_UNUSED_CATCH_CLAUSE, '''
-main() {
- try {
- throw 42;
- } on int {
- }
-}
-''');
- }
-
- test_removeUnusedCatchStack() async {
- errorFilter = (AnalysisError error) => true;
- await resolveTestUnit('''
-main() {
- try {
- throw 42;
- } catch (e, stack) {
- }
-}
-''');
- await assertHasFix(DartFixKind.REMOVE_UNUSED_CATCH_STACK, '''
-main() {
- try {
- throw 42;
- } catch (e) {
- }
-}
-''');
- }
-
- test_removeUnusedImport() async {
- await resolveTestUnit('''
-import 'dart:math';
-main() {
-}
-''');
- await assertHasFix(DartFixKind.REMOVE_UNUSED_IMPORT, '''
-main() {
-}
-''');
- }
-
- test_removeUnusedImport_all() async {
- await resolveTestUnit('''
-import 'dart:math';
-import 'dart:math';
-import 'dart:math';
-main() {
-}
-''');
- await assertHasFixAllFix(
- HintCode.UNUSED_IMPORT, DartFixKind.REMOVE_UNUSED_IMPORT, '''
-main() {
-}
-''');
- }
-
- test_removeUnusedImport_all_diverseImports() async {
- await resolveTestUnit('''
-import 'dart:math';
-import 'dart:math';
-import 'dart:async';
-main() {
-}
-''');
- await assertHasFixAllFix(
- HintCode.UNUSED_IMPORT, DartFixKind.REMOVE_UNUSED_IMPORT, '''
-main() {
-}
-''');
- }
-
- test_removeUnusedImport_all_diverseImports2() async {
- await resolveTestUnit('''
-import 'dart:async';
-import 'dart:math' as math;
-import 'dart:async';
-
-var tau = math.pi * 2;
-
-main() {
-}
-''');
- await assertHasFixAllFix(
- HintCode.UNUSED_IMPORT, DartFixKind.REMOVE_UNUSED_IMPORT, '''
-import 'dart:math' as math;
-
-var tau = math.pi * 2;
-
-main() {
-}
-''');
- }
-
- test_removeUnusedImport_all_singleLine() async {
- await resolveTestUnit('''
-import 'dart:math'; import 'dart:math'; import 'dart:math';
-main() {
-}
-''');
- await assertHasFixAllFix(
- HintCode.UNUSED_IMPORT, DartFixKind.REMOVE_UNUSED_IMPORT, '''
-main() {
-}
-''');
- }
-
- test_removeUnusedImport_anotherImportOnLine() async {
- await resolveTestUnit('''
-import 'dart:math'; import 'dart:async';
-
-main() {
- Future f;
-}
-''');
- await assertHasFix(DartFixKind.REMOVE_UNUSED_IMPORT, '''
-import 'dart:async';
-
-main() {
- Future f;
-}
-''');
- }
-
- test_removeUnusedImport_severalLines() async {
- await resolveTestUnit('''
-import
- 'dart:math';
-main() {
-}
-''');
- await assertHasFix(DartFixKind.REMOVE_UNUSED_IMPORT, '''
-main() {
-}
-''');
- }
-
- test_replaceVarWithDynamic() async {
- errorFilter = (AnalysisError error) {
- return error.errorCode == ParserErrorCode.VAR_AS_TYPE_NAME;
- };
- await resolveTestUnit('''
-class A {
- Map<String, var> m;
-}
-''');
- await assertHasFix(DartFixKind.REPLACE_VAR_WITH_DYNAMIC, '''
-class A {
- Map<String, dynamic> m;
-}
-''');
- }
-
- test_replaceWithConstInstanceCreation_explicitNew() async {
- await resolveTestUnit('''
-class A {
- const A();
-}
-const a = new A();
-''');
- await assertHasFix(DartFixKind.USE_CONST, '''
-class A {
- const A();
-}
-const a = const A();
-''');
- }
-
- test_undefinedClass_useSimilar_BAD_prefixed() async {
- await resolveTestUnit('''
-import 'dart:async' as c;
-main() {
- c.Fture v = null;
-}
-''');
- await assertHasFix(DartFixKind.CHANGE_TO, '''
-import 'dart:async' as c;
-main() {
- c.Future v = null;
-}
-''');
- }
-
- test_undefinedClass_useSimilar_fromImport() async {
- await resolveTestUnit('''
-main() {
- Stirng s = 'abc';
-}
-''');
- await assertHasFix(DartFixKind.CHANGE_TO, '''
-main() {
- String s = 'abc';
-}
-''');
- }
-
- test_undefinedClass_useSimilar_fromThisLibrary() async {
- await resolveTestUnit('''
-class MyClass {}
-main() {
- MyCalss v = null;
-}
-''');
- await assertHasFix(DartFixKind.CHANGE_TO, '''
-class MyClass {}
-main() {
- MyClass v = null;
-}
-''');
- }
-
- test_undefinedFunction_create_bottomArgument() async {
- await resolveTestUnit('''
-main() {
- test(throw 42);
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FUNCTION, '''
-main() {
- test(throw 42);
-}
-
-void test(param0) {
-}
-''');
- }
-
- test_undefinedFunction_create_duplicateArgumentNames() async {
- await resolveTestUnit('''
-class C {
- int x;
-}
-
-foo(C c1, C c2) {
- bar(c1.x, c2.x);
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FUNCTION, '''
-class C {
- int x;
-}
-
-foo(C c1, C c2) {
- bar(c1.x, c2.x);
-}
-
-void bar(int x, int x2) {
-}
-''');
- }
-
- test_undefinedFunction_create_dynamicArgument() async {
- await resolveTestUnit('''
-main() {
- dynamic v;
- test(v);
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FUNCTION, '''
-main() {
- dynamic v;
- test(v);
-}
-
-void test(v) {
-}
-''');
- }
-
- test_undefinedFunction_create_dynamicReturnType() async {
- await resolveTestUnit('''
-main() {
- dynamic v = test();
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FUNCTION, '''
-main() {
- dynamic v = test();
-}
-
-test() {
-}
-''');
- }
-
- test_undefinedFunction_create_fromFunction() async {
- await resolveTestUnit('''
-main() {
- int v = myUndefinedFunction(1, 2.0, '3');
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FUNCTION, '''
-main() {
- int v = myUndefinedFunction(1, 2.0, '3');
-}
-
-int myUndefinedFunction(int i, double d, String s) {
-}
-''');
- }
-
- test_undefinedFunction_create_fromMethod() async {
- await resolveTestUnit('''
-class A {
- main() {
- int v = myUndefinedFunction(1, 2.0, '3');
- }
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FUNCTION, '''
-class A {
- main() {
- int v = myUndefinedFunction(1, 2.0, '3');
- }
-}
-
-int myUndefinedFunction(int i, double d, String s) {
-}
-''');
- }
-
- test_undefinedFunction_create_generic_BAD() async {
- await resolveTestUnit('''
-class A<T> {
- Map<int, T> items;
- main() {
- process(items);
- }
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FUNCTION, '''
-class A<T> {
- Map<int, T> items;
- main() {
- process(items);
- }
-}
-
-void process(Map items) {
-}
-''');
- }
-
- test_undefinedFunction_create_generic_OK() async {
- await resolveTestUnit('''
-class A {
- List<int> items;
- main() {
- process(items);
- }
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FUNCTION, '''
-class A {
- List<int> items;
- main() {
- process(items);
- }
-}
-
-void process(List<int> items) {
-}
-''');
- _assertLinkedGroup(
- change.linkedEditGroups[2],
- ['List<int> items) {'],
- expectedSuggestions(LinkedEditSuggestionKind.TYPE,
- ['List<int>', 'Iterable<int>', 'Object']));
- }
-
- test_undefinedFunction_create_importType() async {
- addSource('/project/lib.dart', r'''
-library lib;
-import 'dart:async';
-Future getFuture() => null;
-''');
- await resolveTestUnit('''
-import 'lib.dart';
-main() {
- test(getFuture());
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FUNCTION, '''
-import 'dart:async';
-
-import 'lib.dart';
-main() {
- test(getFuture());
-}
-
-void test(Future future) {
-}
-''');
- }
-
- test_undefinedFunction_create_nullArgument() async {
- await resolveTestUnit('''
-main() {
- test(null);
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FUNCTION, '''
-main() {
- test(null);
-}
-
-void test(param0) {
-}
-''');
- }
-
- test_undefinedFunction_create_returnType_bool_expressions() async {
- await assert_undefinedFunction_create_returnType_bool("!test();");
- await assert_undefinedFunction_create_returnType_bool("b && test();");
- await assert_undefinedFunction_create_returnType_bool("test() && b;");
- await assert_undefinedFunction_create_returnType_bool("b || test();");
- await assert_undefinedFunction_create_returnType_bool("test() || b;");
- }
-
- test_undefinedFunction_create_returnType_bool_statements() async {
- await assert_undefinedFunction_create_returnType_bool("assert ( test() );");
- await assert_undefinedFunction_create_returnType_bool("if ( test() ) {}");
- await assert_undefinedFunction_create_returnType_bool(
- "while ( test() ) {}");
- await assert_undefinedFunction_create_returnType_bool(
- "do {} while ( test() );");
- }
-
- test_undefinedFunction_create_returnType_fromAssignment_eq() async {
- await resolveTestUnit('''
-main() {
- int v;
- v = myUndefinedFunction();
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FUNCTION, '''
-main() {
- int v;
- v = myUndefinedFunction();
-}
-
-int myUndefinedFunction() {
-}
-''');
- }
-
- test_undefinedFunction_create_returnType_fromAssignment_plusEq() async {
- await resolveTestUnit('''
-main() {
- int v;
- v += myUndefinedFunction();
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FUNCTION, '''
-main() {
- int v;
- v += myUndefinedFunction();
-}
-
-num myUndefinedFunction() {
-}
-''');
- }
-
- test_undefinedFunction_create_returnType_fromBinary_right() async {
- await resolveTestUnit('''
-main() {
- 0 + myUndefinedFunction();
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FUNCTION, '''
-main() {
- 0 + myUndefinedFunction();
-}
-
-num myUndefinedFunction() {
-}
-''');
- }
-
- test_undefinedFunction_create_returnType_fromInitializer() async {
- await resolveTestUnit('''
-main() {
- int v = myUndefinedFunction();
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FUNCTION, '''
-main() {
- int v = myUndefinedFunction();
-}
-
-int myUndefinedFunction() {
-}
-''');
- }
-
- test_undefinedFunction_create_returnType_fromInvocationArgument() async {
- await resolveTestUnit('''
-foo(int p) {}
-main() {
- foo( myUndefinedFunction() );
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FUNCTION, '''
-foo(int p) {}
-main() {
- foo( myUndefinedFunction() );
-}
-
-int myUndefinedFunction() {
-}
-''');
- }
-
- test_undefinedFunction_create_returnType_fromReturn() async {
- await resolveTestUnit('''
-int main() {
- return myUndefinedFunction();
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FUNCTION, '''
-int main() {
- return myUndefinedFunction();
-}
-
-int myUndefinedFunction() {
-}
-''');
- }
-
- test_undefinedFunction_create_returnType_void() async {
- await resolveTestUnit('''
-main() {
- myUndefinedFunction();
-}
-''');
- await assertHasFix(DartFixKind.CREATE_FUNCTION, '''
-main() {
- myUndefinedFunction();
-}
-
-void myUndefinedFunction() {
-}
-''');
- }
-
- test_undefinedFunction_useSimilar_fromImport() async {
- await resolveTestUnit('''
-main() {
- pritn(0);
-}
-''');
- await assertHasFix(DartFixKind.CHANGE_TO, '''
-main() {
- print(0);
-}
-''');
- }
-
- test_undefinedFunction_useSimilar_prefixed_fromImport() async {
- await resolveTestUnit('''
-import 'dart:core' as c;
-main() {
- c.prnt(42);
-}
-''');
- await assertHasFix(DartFixKind.CHANGE_TO, '''
-import 'dart:core' as c;
-main() {
- c.print(42);
-}
-''');
- }
-
- test_undefinedFunction_useSimilar_prefixed_ignoreLocal() async {
- await resolveTestUnit('''
-import 'dart:async' as c;
-main() {
- c.main();
-}
-''');
- await assertNoFix(DartFixKind.CHANGE_TO);
- }
-
- test_undefinedFunction_useSimilar_thisLibrary() async {
- await resolveTestUnit('''
-myFunction() {}
-main() {
- myFuntcion();
-}
-''');
- await assertHasFix(DartFixKind.CHANGE_TO, '''
-myFunction() {}
-main() {
- myFunction();
-}
-''');
- }
-
- test_undefinedGetter_useSimilar_hint() async {
- await resolveTestUnit('''
-class A {
- int myField;
-}
-main(A a) {
- var x = a;
- print(x.myFild);
-}
-''');
- await assertHasFix(DartFixKind.CHANGE_TO, '''
-class A {
- int myField;
-}
-main(A a) {
- var x = a;
- print(x.myField);
-}
-''');
- }
-
- test_undefinedGetter_useSimilar_qualified() async {
- await resolveTestUnit('''
-class A {
- int myField;
-}
-main(A a) {
- print(a.myFild);
-}
-''');
- await assertHasFix(DartFixKind.CHANGE_TO, '''
-class A {
- int myField;
-}
-main(A a) {
- print(a.myField);
-}
-''');
- }
-
- test_undefinedGetter_useSimilar_qualified_static() async {
- await resolveTestUnit('''
-class A {
- static int MY_NAME = 1;
-}
-main() {
- A.MY_NAM;
-}
-''');
- await assertHasFix(DartFixKind.CHANGE_TO, '''
-class A {
- static int MY_NAME = 1;
-}
-main() {
- A.MY_NAME;
-}
-''');
- }
-
- test_undefinedGetter_useSimilar_unqualified() async {
- await resolveTestUnit('''
-class A {
- int myField;
- main() {
- print(myFild);
- }
-}
-''');
- await assertHasFix(DartFixKind.CHANGE_TO, '''
-class A {
- int myField;
- main() {
- print(myField);
- }
-}
-''');
- }
-
- test_undefinedMethod_create_BAD_inSDK() async {
- await resolveTestUnit('''
-main() {
- List.foo();
-}
-''');
- await assertNoFix(DartFixKind.CREATE_METHOD);
- }
-
- test_undefinedMethod_create_BAD_targetIsEnum() async {
- await resolveTestUnit('''
-enum MyEnum {A, B}
-main() {
- MyEnum.foo();
-}
-''');
- await assertNoFix(DartFixKind.CREATE_METHOD);
- }
-
- test_undefinedMethod_create_generic_BAD_argumentType() async {
- await resolveTestUnit('''
-class A<T> {
- B b;
- Map<int, T> items;
- main() {
- b.process(items);
- }
-}
-
-class B {
-}
-''');
- await assertHasFix(DartFixKind.CREATE_METHOD, '''
-class A<T> {
- B b;
- Map<int, T> items;
- main() {
- b.process(items);
- }
-}
-
-class B {
- void process(Map items) {}
-}
-''');
- }
-
- test_undefinedMethod_create_generic_BAD_returnType() async {
- await resolveTestUnit('''
-class A<T> {
- main() {
- T t = new B().compute();
- }
-}
-
-class B {
-}
-''');
- await assertHasFix(DartFixKind.CREATE_METHOD, '''
-class A<T> {
- main() {
- T t = new B().compute();
- }
-}
-
-class B {
- compute() {}
-}
-''');
- }
-
- test_undefinedMethod_create_generic_OK_literal() async {
- await resolveTestUnit('''
-class A {
- B b;
- List<int> items;
- main() {
- b.process(items);
- }
-}
-
-class B {}
-''');
- await assertHasFix(DartFixKind.CREATE_METHOD, '''
-class A {
- B b;
- List<int> items;
- main() {
- b.process(items);
- }
-}
-
-class B {
- void process(List<int> items) {}
-}
-''');
- }
-
- test_undefinedMethod_create_generic_OK_local() async {
- await resolveTestUnit('''
-class A<T> {
- List<T> items;
- main() {
- process(items);
- }
-}
-''');
- await assertHasFix(DartFixKind.CREATE_METHOD, '''
-class A<T> {
- List<T> items;
- main() {
- process(items);
- }
-
- void process(List<T> items) {}
-}
-''');
- }
-
- test_undefinedMethod_createQualified_emptyClassBody() async {
- await resolveTestUnit('''
-class A {}
-main() {
- A.myUndefinedMethod();
-}
-''');
- await assertHasFix(DartFixKind.CREATE_METHOD, '''
-class A {
- static void myUndefinedMethod() {}
-}
-main() {
- A.myUndefinedMethod();
-}
-''');
- }
-
- test_undefinedMethod_createQualified_fromClass() async {
- await resolveTestUnit('''
-class A {
-}
-main() {
- A.myUndefinedMethod();
-}
-''');
- await assertHasFix(DartFixKind.CREATE_METHOD, '''
-class A {
- static void myUndefinedMethod() {}
-}
-main() {
- A.myUndefinedMethod();
-}
-''');
- }
-
- test_undefinedMethod_createQualified_fromClass_hasOtherMember() async {
- await resolveTestUnit('''
-class A {
- foo() {}
-}
-main() {
- A.myUndefinedMethod();
-}
-''');
- await assertHasFix(DartFixKind.CREATE_METHOD, '''
-class A {
- foo() {}
-
- static void myUndefinedMethod() {}
-}
-main() {
- A.myUndefinedMethod();
-}
-''');
- }
-
- test_undefinedMethod_createQualified_fromInstance() async {
- await resolveTestUnit('''
-class A {
-}
-main(A a) {
- a.myUndefinedMethod();
-}
-''');
- await assertHasFix(DartFixKind.CREATE_METHOD, '''
-class A {
- void myUndefinedMethod() {}
-}
-main(A a) {
- a.myUndefinedMethod();
-}
-''');
- }
-
- test_undefinedMethod_createQualified_targetIsFunctionType() async {
- await resolveTestUnit('''
-typedef A();
-main() {
- A.myUndefinedMethod();
-}
-''');
- await assertNoFix(DartFixKind.CREATE_METHOD);
- }
-
- test_undefinedMethod_createQualified_targetIsUnresolved() async {
- await resolveTestUnit('''
-main() {
- NoSuchClass.myUndefinedMethod();
-}
-''');
- await assertNoFix(DartFixKind.CREATE_METHOD);
- }
-
- test_undefinedMethod_createUnqualified_duplicateArgumentNames() async {
- await resolveTestUnit('''
-class C {
- int x;
-}
-
-class D {
- foo(C c1, C c2) {
- bar(c1.x, c2.x);
- }
-}''');
- await assertHasFix(DartFixKind.CREATE_METHOD, '''
-class C {
- int x;
-}
-
-class D {
- foo(C c1, C c2) {
- bar(c1.x, c2.x);
- }
-
- void bar(int x, int x2) {}
-}''');
- }
-
- test_undefinedMethod_createUnqualified_parameters() async {
- await resolveTestUnit('''
-class A {
- main() {
- myUndefinedMethod(0, 1.0, '3');
- }
-}
-''');
- await assertHasFix(DartFixKind.CREATE_METHOD, '''
-class A {
- main() {
- myUndefinedMethod(0, 1.0, '3');
- }
-
- void myUndefinedMethod(int i, double d, String s) {}
-}
-''');
- // linked positions
- int index = 0;
- _assertLinkedGroup(
- change.linkedEditGroups[index++], ['void myUndefinedMethod(']);
- _assertLinkedGroup(change.linkedEditGroups[index++],
- ['myUndefinedMethod(0', 'myUndefinedMethod(int']);
- _assertLinkedGroup(
- change.linkedEditGroups[index++],
- ['int i'],
- expectedSuggestions(LinkedEditSuggestionKind.TYPE,
- ['int', 'num', 'Object', 'Comparable<num>']));
- _assertLinkedGroup(change.linkedEditGroups[index++], ['i,']);
- _assertLinkedGroup(
- change.linkedEditGroups[index++],
- ['double d'],
- expectedSuggestions(LinkedEditSuggestionKind.TYPE,
- ['double', 'num', 'Object', 'Comparable<num>']));
- _assertLinkedGroup(change.linkedEditGroups[index++], ['d,']);
- _assertLinkedGroup(
- change.linkedEditGroups[index++],
- ['String s'],
- expectedSuggestions(LinkedEditSuggestionKind.TYPE,
- ['String', 'Object', 'Comparable<String>']));
- _assertLinkedGroup(change.linkedEditGroups[index++], ['s)']);
- }
-
- test_undefinedMethod_createUnqualified_parameters_named() async {
- await resolveTestUnit('''
-class A {
- main() {
- myUndefinedMethod(0, bbb: 1.0, ccc: '2');
- }
-}
-''');
- await assertHasFix(DartFixKind.CREATE_METHOD, '''
-class A {
- main() {
- myUndefinedMethod(0, bbb: 1.0, ccc: '2');
- }
-
- void myUndefinedMethod(int i, {double bbb, String ccc}) {}
-}
-''');
- // linked positions
- int index = 0;
- _assertLinkedGroup(
- change.linkedEditGroups[index++], ['void myUndefinedMethod(']);
- _assertLinkedGroup(change.linkedEditGroups[index++],
- ['myUndefinedMethod(0', 'myUndefinedMethod(int']);
- _assertLinkedGroup(
- change.linkedEditGroups[index++],
- ['int i'],
- expectedSuggestions(LinkedEditSuggestionKind.TYPE,
- ['int', 'num', 'Object', 'Comparable<num>']));
- _assertLinkedGroup(change.linkedEditGroups[index++], ['i,']);
- _assertLinkedGroup(
- change.linkedEditGroups[index++],
- ['double bbb'],
- expectedSuggestions(LinkedEditSuggestionKind.TYPE,
- ['double', 'num', 'Object', 'Comparable<num>']));
- _assertLinkedGroup(
- change.linkedEditGroups[index++],
- ['String ccc'],
- expectedSuggestions(LinkedEditSuggestionKind.TYPE,
- ['String', 'Object', 'Comparable<String>']));
- }
-
- test_undefinedMethod_createUnqualified_returnType() async {
- await resolveTestUnit('''
-class A {
- main() {
- int v = myUndefinedMethod();
- }
-}
-''');
- await assertHasFix(DartFixKind.CREATE_METHOD, '''
-class A {
- main() {
- int v = myUndefinedMethod();
- }
-
- int myUndefinedMethod() {}
-}
-''');
- // linked positions
- _assertLinkedGroup(change.linkedEditGroups[0], ['int myUndefinedMethod(']);
- _assertLinkedGroup(change.linkedEditGroups[1],
- ['myUndefinedMethod();', 'myUndefinedMethod() {']);
- }
-
- test_undefinedMethod_createUnqualified_staticFromField() async {
- await resolveTestUnit('''
-class A {
- static var f = myUndefinedMethod();
-}
-''');
- await assertHasFix(DartFixKind.CREATE_METHOD, '''
-class A {
- static var f = myUndefinedMethod();
-
- static myUndefinedMethod() {}
-}
-''');
- }
-
- test_undefinedMethod_createUnqualified_staticFromMethod() async {
- await resolveTestUnit('''
-class A {
- static main() {
- myUndefinedMethod();
- }
-}
-''');
- await assertHasFix(DartFixKind.CREATE_METHOD, '''
-class A {
- static main() {
- myUndefinedMethod();
- }
-
- static void myUndefinedMethod() {}
-}
-''');
- }
-
- test_undefinedMethod_hint_createQualified_fromInstance() async {
- await resolveTestUnit('''
-class A {
-}
-main() {
- var a = new A();
- a.myUndefinedMethod();
-}
-''');
- await assertHasFix(DartFixKind.CREATE_METHOD, '''
-class A {
- void myUndefinedMethod() {}
-}
-main() {
- var a = new A();
- a.myUndefinedMethod();
-}
-''');
- }
-
- test_undefinedMethod_parameterType_differentPrefixInTargetUnit() async {
- String code2 = r'''
-library test2;
-import 'test3.dart' as bbb;
-export 'test3.dart';
-class D {
-}
-''';
- addSource('/project/test2.dart', code2);
- addSource('/project/test3.dart', r'''
-library test3;
-class E {}
-''');
- await resolveTestUnit('''
-library test;
-import 'test2.dart' as aaa;
-main(aaa.D d, aaa.E e) {
- d.foo(e);
-}
-''');
- AnalysisError error = await _findErrorToFix();
- fix = await _assertHasFix(DartFixKind.CREATE_METHOD, error);
- change = fix.change;
- // apply to "test2.dart"
- List<SourceFileEdit> fileEdits = change.edits;
- expect(fileEdits, hasLength(1));
- SourceFileEdit fileEdit = change.edits[0];
- expect(fileEdit.file, convertPath('/project/test2.dart'));
- expect(SourceEdit.applySequence(code2, fileEdit.edits), r'''
-library test2;
-import 'test3.dart' as bbb;
-export 'test3.dart';
-class D {
- void foo(bbb.E e) {}
-}
-''');
- }
-
- test_undefinedMethod_parameterType_inTargetUnit() async {
- String code2 = r'''
-library test2;
-class D {
-}
-class E {}
-''';
- addSource('/project/test2.dart', code2);
- await resolveTestUnit('''
-library test;
-import 'test2.dart' as test2;
-main(test2.D d, test2.E e) {
- d.foo(e);
-}
-''');
- AnalysisError error = await _findErrorToFix();
- fix = await _assertHasFix(DartFixKind.CREATE_METHOD, error);
- change = fix.change;
- // apply to "test2.dart"
- List<SourceFileEdit> fileEdits = change.edits;
- expect(fileEdits, hasLength(1));
- SourceFileEdit fileEdit = change.edits[0];
- expect(fileEdit.file, convertPath('/project/test2.dart'));
- expect(SourceEdit.applySequence(code2, fileEdit.edits), r'''
-library test2;
-class D {
- void foo(E e) {}
-}
-class E {}
-''');
- }
-
- test_undefinedMethod_useSimilar_ignoreOperators() async {
- await resolveTestUnit('''
-main(Object object) {
- object.then();
-}
-''');
- await assertNoFix(DartFixKind.CHANGE_TO);
- }
-
- test_undefinedMethod_useSimilar_qualified() async {
- await resolveTestUnit('''
-class A {
- myMethod() {}
-}
-main() {
- A a = new A();
- a.myMehtod();
-}
-''');
- await assertHasFix(DartFixKind.CHANGE_TO, '''
-class A {
- myMethod() {}
-}
-main() {
- A a = new A();
- a.myMethod();
-}
-''');
- }
-
- test_undefinedMethod_useSimilar_unqualified_superClass() async {
- await resolveTestUnit('''
-class A {
- myMethod() {}
-}
-class B extends A {
- main() {
- myMehtod();
- }
-}
-''');
- await assertHasFix(DartFixKind.CHANGE_TO, '''
-class A {
- myMethod() {}
-}
-class B extends A {
- main() {
- myMethod();
- }
-}
-''');
- }
-
- test_undefinedMethod_useSimilar_unqualified_thisClass() async {
- await resolveTestUnit('''
-class A {
- myMethod() {}
- main() {
- myMehtod();
- }
-}
-''');
- await assertHasFix(DartFixKind.CHANGE_TO, '''
-class A {
- myMethod() {}
- main() {
- myMethod();
- }
-}
-''');
- }
-
- test_undefinedParameter_convertFlutterChild_BAD_listNotWidget() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-build() {
- return new Container(
- child: new Row(
- child: <Widget>[
- new Container(),
- null,
- ],
- ),
- );
-}
-''');
- await assertNoFix(DartFixKind.CONVERT_FLUTTER_CHILD);
- }
-
- test_undefinedParameter_convertFlutterChild_OK_hasList() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-build() {
- return new Container(
- child: new Row(
- child: [
- new Text('111'),
- new Text('222'),
- ],
- ),
- );
-}
-''');
- await assertHasFix(DartFixKind.CONVERT_FLUTTER_CHILD, '''
-import 'package:flutter/widgets.dart';
-build() {
- return new Container(
- child: new Row(
- children: <Widget>[
- new Text('111'),
- new Text('222'),
- ],
- ),
- );
-}
-''');
- }
-
- test_undefinedParameter_convertFlutterChild_OK_hasTypedList() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-build() {
- return new Container(
- child: new Row(
- child: <Widget>[
- new Text('111'),
- new Text('222'),
- ],
- ),
- );
-}
-''');
- await assertHasFix(DartFixKind.CONVERT_FLUTTER_CHILD, '''
-import 'package:flutter/widgets.dart';
-build() {
- return new Container(
- child: new Row(
- children: <Widget>[
- new Text('111'),
- new Text('222'),
- ],
- ),
- );
-}
-''');
- }
-
- test_undefinedParameter_convertFlutterChild_OK_multiLine() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/material.dart';
-build() {
- return new Scaffold(
- body: new Row(
- child: new Container(
- width: 200.0,
- height: 300.0,
- ),
- ),
- );
-}
-''');
- await assertHasFix(DartFixKind.CONVERT_FLUTTER_CHILD, '''
-import 'package:flutter/material.dart';
-build() {
- return new Scaffold(
- body: new Row(
- children: <Widget>[
- new Container(
- width: 200.0,
- height: 300.0,
- ),
- ],
- ),
- );
-}
-''');
- }
-
- test_undefinedParameter_convertFlutterChild_OK_widgetVariable() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/material.dart';
-build() {
- var text = new Text('foo');
- new Row(
- child: text,
- );
-}
-''');
- await assertHasFix(DartFixKind.CONVERT_FLUTTER_CHILD, '''
-import 'package:flutter/material.dart';
-build() {
- var text = new Text('foo');
- new Row(
- children: <Widget>[text],
- );
-}
-''');
- }
-
- test_undefinedParameter_convertFlutterChildren_BAD_notWidget() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-build() {
- return new Center(
- children: [
- new Object(),
- ],
- );
-}
-''');
- await assertNoFix(DartFixKind.CONVERT_FLUTTER_CHILDREN);
- }
-
- test_undefinedParameter_convertFlutterChildren_OK_multiLine() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-build() {
- return new Center(
- children: [
- new Container(
- width: 200.0,
- height: 300.0,
- ),
- ],
- );
-}
-''');
- await assertHasFix(DartFixKind.CONVERT_FLUTTER_CHILDREN, '''
-import 'package:flutter/widgets.dart';
-build() {
- return new Center(
- child: new Container(
- width: 200.0,
- height: 300.0,
- ),
- );
-}
-''');
- }
-
- test_undefinedParameter_convertFlutterChildren_OK_singleLine() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-build() {
- return new Center(
- children: [
- new Text('foo'),
- ],
- );
-}
-''');
- await assertHasFix(DartFixKind.CONVERT_FLUTTER_CHILDREN, '''
-import 'package:flutter/widgets.dart';
-build() {
- return new Center(
- child: new Text('foo'),
- );
-}
-''');
- }
-
- test_undefinedParameter_convertFlutterChildren_OK_singleLine2() async {
- addFlutterPackage();
- await resolveTestUnit('''
-import 'package:flutter/widgets.dart';
-build() {
- var text = new Text('foo');
- new Center(
- children: [text],
- );
-}
-''');
- await assertHasFix(DartFixKind.CONVERT_FLUTTER_CHILDREN, '''
-import 'package:flutter/widgets.dart';
-build() {
- var text = new Text('foo');
- new Center(
- child: text,
- );
-}
-''');
- }
-
- test_undefinedSetter_useSimilar_hint() async {
- await resolveTestUnit('''
-class A {
- int myField;
-}
-main(A a) {
- var x = a;
- x.myFild = 42;
-}
-''');
- await assertHasFix(DartFixKind.CHANGE_TO, '''
-class A {
- int myField;
-}
-main(A a) {
- var x = a;
- x.myField = 42;
-}
-''');
- }
-
- test_undefinedSetter_useSimilar_qualified() async {
- await resolveTestUnit('''
-class A {
- int myField;
-}
-main(A a) {
- a.myFild = 42;
-}
-''');
- await assertHasFix(DartFixKind.CHANGE_TO, '''
-class A {
- int myField;
-}
-main(A a) {
- a.myField = 42;
-}
-''');
- }
-
- test_undefinedSetter_useSimilar_unqualified() async {
- await resolveTestUnit('''
-class A {
- int myField;
- main() {
- myFild = 42;
- }
-}
-''');
- await assertHasFix(DartFixKind.CHANGE_TO, '''
-class A {
- int myField;
- main() {
- myField = 42;
- }
-}
-''');
- }
-
- test_useEffectiveIntegerDivision() async {
- await resolveTestUnit('''
-main() {
- var a = 5;
- var b = 2;
- print((a / b).toInt());
-}
-''');
- await assertHasFix(DartFixKind.USE_EFFECTIVE_INTEGER_DIVISION, '''
-main() {
- var a = 5;
- var b = 2;
- print(a ~/ b);
-}
-''');
- }
-
- test_useImportPrefix_withClass() async {
- await resolveTestUnit('''
-import 'dart:async' as pref;
-main() {
- pref.Stream s = null;
- Future f = null;
-}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PREFIX, '''
-import 'dart:async' as pref;
-main() {
- pref.Stream s = null;
- pref.Future f = null;
-}
-''');
- }
-
- test_useImportPrefix_withTopLevelVariable() async {
- await resolveTestUnit('''
-import 'dart:math' as pref;
-main() {
- print(pref.E);
- print(PI);
-}
-''');
- await assertHasFix(DartFixKind.IMPORT_LIBRARY_PREFIX, '''
-import 'dart:math' as pref;
-main() {
- print(pref.E);
- print(pref.PI);
-}
-''');
- }
-
- void _addMetaPackageSource() {
- addPackageSource('meta', 'meta.dart', r'''
-library meta;
-
-const Required required = const Required();
-
-class Required {
- final String reason;
- const Required([this.reason]);
-}
-''');
- }
-}
-
-@reflectiveTest
-class LintFixTest extends BaseFixProcessorTest {
- AnalysisError error;
-
- Future applyFix(FixKind kind) async {
- fix = await _assertHasFix(kind, error);
- change = fix.change;
- // apply to "file"
- List<SourceFileEdit> fileEdits = change.edits;
- expect(fileEdits, hasLength(1));
- resultCode = SourceEdit.applySequence(testCode, change.edits[0].edits);
- }
-
- @override
- assertNoFix(FixKind kind) async {
- await _assertNoFix(kind, error);
- }
-
- Future<void> findLint(String src, String lintCode, {int length: 1}) async {
- int errorOffset = src.indexOf('/*LINT*/');
- await resolveTestUnit(src.replaceAll('/*LINT*/', ''));
- error = new AnalysisError(
- resolutionMap.elementDeclaredByCompilationUnit(testUnit).source,
- errorOffset,
- length,
- new LintCode(lintCode, '<ignored>'));
- }
-
- test_addRequiredAnnotation() async {
- String src = '''
-void function({String /*LINT*/param}) {
- assert(param != null);
-}
-''';
- await findLint(src, LintNames.always_require_non_null_named_parameters);
- await applyFix(DartFixKind.LINT_ADD_REQUIRED);
- verifyResult('''
-void function({@required String param}) {
- assert(param != null);
-}
-''');
- }
-
- test_isNotEmpty() async {
- String src = '''
-f(c) {
- if (/*LINT*/!c.isEmpty) {}
-}
-''';
- await findLint(src, LintNames.prefer_is_not_empty);
-
- await applyFix(DartFixKind.USE_IS_NOT_EMPTY);
-
- verifyResult('''
-f(c) {
- if (c.isNotEmpty) {}
-}
-''');
- }
-
- test_lint_addMissingOverride_field() async {
- String src = '''
-class abstract Test {
- int get t;
-}
-class Sub extends Test {
- int /*LINT*/t = 42;
-}
-''';
- await findLint(src, LintNames.annotate_overrides);
-
- await applyFix(DartFixKind.LINT_ADD_OVERRIDE);
-
- verifyResult('''
-class abstract Test {
- int get t;
-}
-class Sub extends Test {
- @override
- int t = 42;
-}
-''');
- }
-
- test_lint_addMissingOverride_getter() async {
- String src = '''
-class Test {
- int get t => null;
-}
-class Sub extends Test {
- int get /*LINT*/t => null;
-}
-''';
- await findLint(src, LintNames.annotate_overrides);
-
- await applyFix(DartFixKind.LINT_ADD_OVERRIDE);
-
- verifyResult('''
-class Test {
- int get t => null;
-}
-class Sub extends Test {
- @override
- int get t => null;
-}
-''');
- }
-
- test_lint_addMissingOverride_method() async {
- String src = '''
-class Test {
- void t() { }
-}
-class Sub extends Test {
- void /*LINT*/t() { }
-}
-''';
- await findLint(src, LintNames.annotate_overrides);
-
- await applyFix(DartFixKind.LINT_ADD_OVERRIDE);
-
- verifyResult('''
-class Test {
- void t() { }
-}
-class Sub extends Test {
- @override
- void t() { }
-}
-''');
- }
-
- test_lint_addMissingOverride_method_with_doc_comment() async {
- String src = '''
-class Test {
- void t() { }
-}
-class Sub extends Test {
- /// Doc comment.
- void /*LINT*/t() { }
-}
-''';
- await findLint(src, LintNames.annotate_overrides);
-
- await applyFix(DartFixKind.LINT_ADD_OVERRIDE);
-
- verifyResult('''
-class Test {
- void t() { }
-}
-class Sub extends Test {
- /// Doc comment.
- @override
- void t() { }
-}
-''');
- }
-
- test_lint_addMissingOverride_method_with_doc_comment_2() async {
- String src = '''
-class Test {
- void t() { }
-}
-class Sub extends Test {
- /**
- * Doc comment.
- */
- void /*LINT*/t() { }
-}
-''';
- await findLint(src, LintNames.annotate_overrides);
-
- await applyFix(DartFixKind.LINT_ADD_OVERRIDE);
-
- verifyResult('''
-class Test {
- void t() { }
-}
-class Sub extends Test {
- /**
- * Doc comment.
- */
- @override
- void t() { }
-}
-''');
- }
-
- test_lint_addMissingOverride_method_with_doc_comment_and_metadata() async {
- String src = '''
-class Test {
- void t() { }
-}
-class Sub extends Test {
- /// Doc comment.
- @foo
- void /*LINT*/t() { }
-}
-''';
- await findLint(src, LintNames.annotate_overrides);
-
- await applyFix(DartFixKind.LINT_ADD_OVERRIDE);
-
- verifyResult('''
-class Test {
- void t() { }
-}
-class Sub extends Test {
- /// Doc comment.
- @override
- @foo
- void t() { }
-}
-''');
- }
-
- test_lint_addMissingOverride_method_with_non_doc_comment() async {
- String src = '''
-class Test {
- void t() { }
-}
-class Sub extends Test {
- // Non-doc comment.
- void /*LINT*/t() { }
-}
-''';
- await findLint(src, LintNames.annotate_overrides);
-
- await applyFix(DartFixKind.LINT_ADD_OVERRIDE);
-
- verifyResult('''
-class Test {
- void t() { }
-}
-class Sub extends Test {
- // Non-doc comment.
- @override
- void t() { }
-}
-''');
- }
-
- test_lint_removeInterpolationBraces() async {
- String src = r'''
-main() {
- var v = 42;
- print('v: /*LINT*/${ v}');
-}
-''';
- await findLint(src, LintNames.unnecessary_brace_in_string_interp,
- length: 4);
- await applyFix(DartFixKind.LINT_REMOVE_INTERPOLATION_BRACES);
- verifyResult(r'''
-main() {
- var v = 42;
- print('v: $v');
-}
-''');
- }
-
- test_makeFieldFinal_noKeyword() async {
- String src = '''
-class C {
- /*LINT*/f = 2;
-}
-''';
- await findLint(src, LintNames.prefer_final_fields);
-
- await applyFix(DartFixKind.MAKE_FINAL);
-
- verifyResult('''
-class C {
- final f = 2;
-}
-''');
- }
-
- test_makeFieldFinal_type() async {
- String src = '''
-class C {
- int /*LINT*/f = 2;
-}
-''';
- await findLint(src, LintNames.prefer_final_fields);
-
- await applyFix(DartFixKind.MAKE_FINAL);
-
- verifyResult('''
-class C {
- final int f = 2;
-}
-''');
- }
-
- test_makeFieldFinal_var() async {
- String src = '''
-class C {
- var /*LINT*/f = 2;
-}
-''';
- await findLint(src, LintNames.prefer_final_fields);
-
- await applyFix(DartFixKind.MAKE_FINAL);
-
- verifyResult('''
-class C {
- final f = 2;
-}
-''');
- }
-
- test_makeLocalFinal_type() async {
- String src = '''
-bad() {
- int /*LINT*/x = 2;
-}
-''';
- await findLint(src, LintNames.prefer_final_locals);
-
- await applyFix(DartFixKind.MAKE_FINAL);
-
- verifyResult('''
-bad() {
- final int x = 2;
-}
-''');
- }
-
- test_makeLocalFinal_var() async {
- String src = '''
-bad() {
- var /*LINT*/x = 2;
-}
-''';
- await findLint(src, LintNames.prefer_final_locals);
-
- await applyFix(DartFixKind.MAKE_FINAL);
-
- verifyResult('''
-bad() {
- final x = 2;
-}
-''');
- }
-
- test_removeAwait_intLiteral() async {
- String src = '''
-bad() async {
- print(/*LINT*/await 23);
-}
-''';
- await findLint(src, LintNames.await_only_futures);
-
- await applyFix(DartFixKind.REMOVE_AWAIT);
-
- verifyResult('''
-bad() async {
- print(23);
-}
-''');
- }
-
- test_removeAwait_StringLiteral() async {
- String src = '''
-bad() async {
- print(/*LINT*/await 'hola');
-}
-''';
- await findLint(src, LintNames.await_only_futures);
-
- await applyFix(DartFixKind.REMOVE_AWAIT);
-
- verifyResult('''
-bad() async {
- print('hola');
-}
-''');
- }
-
- test_removeEmptyCatch_newLine() async {
- String src = '''
-void foo() {
- try {}
- catch (e) {/*LINT*/}
- finally {}
-}
-''';
- await findLint(src, LintNames.empty_catches);
-
- await applyFix(DartFixKind.REMOVE_EMPTY_CATCH);
-
- verifyResult('''
-void foo() {
- try {}
- finally {}
-}
-''');
- }
-
- test_removeEmptyCatch_sameLine() async {
- String src = '''
-void foo() {
- try {} catch (e) {/*LINT*/} finally {}
-}
-''';
- await findLint(src, LintNames.empty_catches);
-
- await applyFix(DartFixKind.REMOVE_EMPTY_CATCH);
-
- verifyResult('''
-void foo() {
- try {} finally {}
-}
-''');
- }
-
- test_removeEmptyConstructorBody() async {
- String src = '''
-class C {
- C() {/*LINT*/}
-}
-''';
- await findLint(src, LintNames.empty_constructor_bodies);
-
- await applyFix(DartFixKind.REMOVE_EMPTY_CONSTRUCTOR_BODY);
-
- verifyResult('''
-class C {
- C();
-}
-''');
- }
-
- test_removeEmptyElse_newLine() async {
- String src = '''
-void foo(bool cond) {
- if (cond) {
- //
- }
- else /*LINT*/;
-}
-''';
- await findLint(src, LintNames.avoid_empty_else);
-
- await applyFix(DartFixKind.REMOVE_EMPTY_ELSE);
-
- verifyResult('''
-void foo(bool cond) {
- if (cond) {
- //
- }
-}
-''');
- }
-
- test_removeEmptyElse_sameLine() async {
- String src = '''
-void foo(bool cond) {
- if (cond) {
- //
- } else /*LINT*/;
-}
-''';
- await findLint(src, LintNames.avoid_empty_else);
-
- await applyFix(DartFixKind.REMOVE_EMPTY_ELSE);
-
- verifyResult('''
-void foo(bool cond) {
- if (cond) {
- //
- }
-}
-''');
- }
-
- test_removeEmptyStatement_insideBlock() async {
- String src = '''
-void foo() {
- while(true) {
- /*LINT*/;
- }
-}
-''';
- await findLint(src, LintNames.empty_statements);
-
- await applyFix(DartFixKind.REMOVE_EMPTY_STATEMENT);
-
- verifyResult('''
-void foo() {
- while(true) {
- }
-}
-''');
- }
-
- test_removeEmptyStatement_outOfBlock_otherLine() async {
- String src = '''
-void foo() {
- while(true)
- /*LINT*/;
- print('hi');
-}
-''';
- await findLint(src, LintNames.empty_statements);
-
- await applyFix(DartFixKind.REPLACE_WITH_BRACKETS);
-
- verifyResult('''
-void foo() {
- while(true) {}
- print('hi');
-}
-''');
- }
-
- test_removeEmptyStatement_outOfBlock_sameLine() async {
- String src = '''
-void foo() {
- while(true)/*LINT*/;
- print('hi');
-}
-''';
- await findLint(src, LintNames.empty_statements);
-
- await applyFix(DartFixKind.REPLACE_WITH_BRACKETS);
-
- verifyResult('''
-void foo() {
- while(true) {}
- print('hi');
-}
-''');
- }
-
- test_removeInitializer_field() async {
- String src = '''
-class Test {
- int /*LINT*/x = null;
-}
-''';
- await findLint(src, LintNames.avoid_init_to_null);
-
- await applyFix(DartFixKind.REMOVE_INITIALIZER);
-
- verifyResult('''
-class Test {
- int x;
-}
-''');
- }
-
- test_removeInitializer_listOfVariableDeclarations() async {
- String src = '''
-String a = 'a', /*LINT*/b = null, c = 'c';
-''';
- await findLint(src, LintNames.avoid_init_to_null);
-
- await applyFix(DartFixKind.REMOVE_INITIALIZER);
-
- verifyResult('''
-String a = 'a', b, c = 'c';
-''');
- }
-
- test_removeInitializer_topLevel() async {
- String src = '''
-var /*LINT*/x = null;
-''';
- await findLint(src, LintNames.avoid_init_to_null);
-
- await applyFix(DartFixKind.REMOVE_INITIALIZER);
-
- verifyResult('''
-var x;
-''');
- }
-
- test_removeMethodDeclaration_getter() async {
- String src = '''
-class A {
- int x;
-}
-class B extends A {
- @override
- int get /*LINT*/x => super.x;
-}
-''';
- await findLint(src, LintNames.unnecessary_override);
-
- await applyFix(DartFixKind.REMOVE_METHOD_DECLARATION);
-
- verifyResult('''
-class A {
- int x;
-}
-class B extends A {
-}
-''');
- }
-
- test_removeMethodDeclaration_method() async {
- String src = '''
-class A {
- @override
- String /*LINT*/toString() => super.toString();
-}
-''';
- await findLint(src, LintNames.unnecessary_override);
-
- await applyFix(DartFixKind.REMOVE_METHOD_DECLARATION);
-
- verifyResult('''
-class A {
-}
-''');
- }
-
- test_removeMethodDeclaration_setter() async {
- String src = '''
-class A {
- int x;
-}
-class B extends A {
- @override
- set /*LINT*/x(int other) {
- this.x = other;
- }
-}
-''';
- await findLint(src, LintNames.unnecessary_override);
-
- await applyFix(DartFixKind.REMOVE_METHOD_DECLARATION);
-
- verifyResult('''
-class A {
- int x;
-}
-class B extends A {
-}
-''');
- }
-
- test_removeThisExpression_methodInvocation_oneCharacterOperator() async {
- String src = '''
-class A {
- void foo() {
- /*LINT*/this.foo();
- }
-}
-''';
- await findLint(src, LintNames.unnecessary_this);
-
- await applyFix(DartFixKind.REMOVE_THIS_EXPRESSION);
-
- verifyResult('''
-class A {
- void foo() {
- foo();
- }
-}
-''');
- }
-
- test_removeThisExpression_methodInvocation_twoCharactersOperator() async {
- String src = '''
-class A {
- void foo() {
- /*LINT*/this?.foo();
- }
-}
-''';
- await findLint(src, LintNames.unnecessary_this);
-
- await applyFix(DartFixKind.REMOVE_THIS_EXPRESSION);
-
- verifyResult('''
-class A {
- void foo() {
- foo();
- }
-}
-''');
- }
-
- test_removeThisExpression_notAThisExpression() async {
- String src = '''
-void foo() {
- final /*LINT*/this.id;
-}
-''';
- await findLint(src, LintNames.unnecessary_this);
-
- await assertNoFix(DartFixKind.REMOVE_THIS_EXPRESSION);
- }
-
- test_removeThisExpression_propertyAccess_oneCharacterOperator() async {
- String src = '''
-class A {
- int x;
- void foo() {
- /*LINT*/this.x = 2;
- }
-}
-''';
- await findLint(src, LintNames.unnecessary_this);
-
- await applyFix(DartFixKind.REMOVE_THIS_EXPRESSION);
-
- verifyResult('''
-class A {
- int x;
- void foo() {
- x = 2;
- }
-}
-''');
- }
-
- test_removeThisExpression_propertyAccess_twoCharactersOperator() async {
- String src = '''
-class A {
- int x;
- void foo() {
- /*LINT*/this?.x = 2;
- }
-}
-''';
- await findLint(src, LintNames.unnecessary_this);
-
- await applyFix(DartFixKind.REMOVE_THIS_EXPRESSION);
-
- verifyResult('''
-class A {
- int x;
- void foo() {
- x = 2;
- }
-}
-''');
- }
-
- test_removeTypeAnnotation_avoidAnnotatingWithDynamic_InsideFunctionTypedFormalParameter() async {
- String src = '''
-bad(void foo(/*LINT*/dynamic x)) {
- return null;
-}
-''';
- await findLint(src, LintNames.avoid_annotating_with_dynamic);
-
- await applyFix(DartFixKind.REMOVE_TYPE_NAME);
-
- verifyResult('''
-bad(void foo(x)) {
- return null;
-}
-''');
- }
-
- test_removeTypeAnnotation_avoidAnnotatingWithDynamic_NamedParameter() async {
- String src = '''
-bad({/*LINT*/dynamic defaultValue}) {
- return null;
-}
-''';
- await findLint(src, LintNames.avoid_annotating_with_dynamic);
-
- await applyFix(DartFixKind.REMOVE_TYPE_NAME);
-
- verifyResult('''
-bad({defaultValue}) {
- return null;
-}
-''');
- }
-
- test_removeTypeAnnotation_avoidAnnotatingWithDynamic_NormalParameter() async {
- String src = '''
-bad(/*LINT*/dynamic defaultValue) {
- return null;
-}
-''';
- await findLint(src, LintNames.avoid_annotating_with_dynamic);
-
- await applyFix(DartFixKind.REMOVE_TYPE_NAME);
-
- verifyResult('''
-bad(defaultValue) {
- return null;
-}
-''');
- }
-
- test_removeTypeAnnotation_avoidAnnotatingWithDynamic_OptionalParameter() async {
- String src = '''
-bad([/*LINT*/dynamic defaultValue]) {
- return null;
-}
-''';
- await findLint(src, LintNames.avoid_annotating_with_dynamic);
-
- await applyFix(DartFixKind.REMOVE_TYPE_NAME);
-
- verifyResult('''
-bad([defaultValue]) {
- return null;
-}
-''');
- }
-
- test_removeTypeAnnotation_avoidReturnTypesOnSetters_void() async {
- String src = '''
-/*LINT*/void set speed2(int ms) {}
-''';
- await findLint(src, LintNames.avoid_return_types_on_setters);
-
- await applyFix(DartFixKind.REMOVE_TYPE_NAME);
-
- verifyResult('''
-set speed2(int ms) {}
-''');
- }
-
- test_removeTypeAnnotation_avoidTypesOnClosureParameters_FunctionTypedFormalParameter() async {
- String src = '''
-var functionWithFunction = (/*LINT*/int f(int x)) => f(0);
-''';
- await findLint(src, LintNames.avoid_types_on_closure_parameters);
-
- await applyFix(DartFixKind.REPLACE_WITH_IDENTIFIER);
-
- verifyResult('''
-var functionWithFunction = (f) => f(0);
-''');
- }
-
- test_removeTypeAnnotation_avoidTypesOnClosureParameters_NamedParameter() async {
- String src = '''
-var x = ({/*LINT*/Future<int> defaultValue}) {
- return null;
-};
-''';
- await findLint(src, LintNames.avoid_types_on_closure_parameters);
-
- await applyFix(DartFixKind.REMOVE_TYPE_NAME);
-
- verifyResult('''
-var x = ({defaultValue}) {
- return null;
-};
-''');
- }
-
- test_removeTypeAnnotation_avoidTypesOnClosureParameters_NormalParameter() async {
- String src = '''
-var x = (/*LINT*/Future<int> defaultValue) {
- return null;
-};
-''';
- await findLint(src, LintNames.avoid_types_on_closure_parameters);
-
- await applyFix(DartFixKind.REMOVE_TYPE_NAME);
-
- verifyResult('''
-var x = (defaultValue) {
- return null;
-};
-''');
- }
-
- test_removeTypeAnnotation_avoidTypesOnClosureParameters_OptionalParameter() async {
- String src = '''
-var x = ([/*LINT*/Future<int> defaultValue]) {
- return null;
-};
-''';
- await findLint(src, LintNames.avoid_types_on_closure_parameters);
-
- await applyFix(DartFixKind.REMOVE_TYPE_NAME);
-
- verifyResult('''
-var x = ([defaultValue]) {
- return null;
-};
-''');
- }
-
- test_removeTypeAnnotation_typeInitFormals_void() async {
- String src = '''
-class C {
- int f;
- C(/*LINT*/int this.f);
-}
-''';
- await findLint(src, LintNames.type_init_formals);
-
- await applyFix(DartFixKind.REMOVE_TYPE_NAME);
-
- verifyResult('''
-class C {
- int f;
- C(this.f);
-}
-''');
- }
-
- test_renameToCamelCase_BAD_parameter_optionalNamed() async {
- String src = '''
-foo({int /*LINT*/my_integer_variable}) {
- print(my_integer_variable);
-}
-''';
- await findLint(src, LintNames.non_constant_identifier_names);
- await assertNoFix(DartFixKind.RENAME_TO_CAMEL_CASE);
- }
-
- test_renameToCamelCase_OK_localVariable() async {
- String src = '''
-main() {
- int /*LINT*/my_integer_variable = 42;
- int foo;
- print(my_integer_variable);
- print(foo);
-}
-''';
- await findLint(src, LintNames.non_constant_identifier_names);
-
- await applyFix(DartFixKind.RENAME_TO_CAMEL_CASE);
-
- verifyResult('''
-main() {
- int myIntegerVariable = 42;
- int foo;
- print(myIntegerVariable);
- print(foo);
-}
-''');
- }
-
- test_renameToCamelCase_OK_parameter_closure() async {
- String src = '''
-main() {
- [0, 1, 2].forEach((/*LINT*/my_integer_variable) {
- print(my_integer_variable);
- });
-}
-''';
- await findLint(src, LintNames.non_constant_identifier_names);
-
- await applyFix(DartFixKind.RENAME_TO_CAMEL_CASE);
-
- verifyResult('''
-main() {
- [0, 1, 2].forEach((myIntegerVariable) {
- print(myIntegerVariable);
- });
-}
-''');
- }
-
- test_renameToCamelCase_OK_parameter_function() async {
- String src = '''
-main(int /*LINT*/my_integer_variable) {
- print(my_integer_variable);
-}
-''';
- await findLint(src, LintNames.non_constant_identifier_names);
-
- await applyFix(DartFixKind.RENAME_TO_CAMEL_CASE);
-
- verifyResult('''
-main(int myIntegerVariable) {
- print(myIntegerVariable);
-}
-''');
- }
-
- test_renameToCamelCase_OK_parameter_method() async {
- String src = '''
-class A {
- main(int /*LINT*/my_integer_variable) {
- print(my_integer_variable);
- }
-}
-''';
- await findLint(src, LintNames.non_constant_identifier_names);
-
- await applyFix(DartFixKind.RENAME_TO_CAMEL_CASE);
-
- verifyResult('''
-class A {
- main(int myIntegerVariable) {
- print(myIntegerVariable);
- }
-}
-''');
- }
-
- test_renameToCamelCase_OK_parameter_optionalPositional() async {
- String src = '''
-main([int /*LINT*/my_integer_variable]) {
- print(my_integer_variable);
-}
-''';
- await findLint(src, LintNames.non_constant_identifier_names);
-
- await applyFix(DartFixKind.RENAME_TO_CAMEL_CASE);
-
- verifyResult('''
-main([int myIntegerVariable]) {
- print(myIntegerVariable);
-}
-''');
- }
-
- test_replaceFinalWithConst_method() async {
- String src = '''
-/*LINT*/final int a = 1;
-''';
- await findLint(src, LintNames.prefer_const_declarations);
-
- await applyFix(DartFixKind.REPLACE_FINAL_WITH_CONST);
-
- verifyResult('''
-const int a = 1;
-''');
- }
-
- test_replaceWithConditionalAssignment_withCodeBeforeAndAfter() async {
- String src = '''
-class Person {
- String _fullName;
- void foo() {
- print('hi');
- /*LINT*/if (_fullName == null) {
- _fullName = getFullUserName(this);
- }
- print('hi');
- }
-}
-''';
- await findLint(src, LintNames.prefer_conditional_assignment);
-
- await applyFix(DartFixKind.REPLACE_WITH_CONDITIONAL_ASSIGNMENT);
-
- verifyResult('''
-class Person {
- String _fullName;
- void foo() {
- print('hi');
- _fullName ??= getFullUserName(this);
- print('hi');
- }
-}
-''');
- }
-
- test_replaceWithConditionalAssignment_withOneBlock() async {
- String src = '''
-class Person {
- String _fullName;
- void foo() {
- /*LINT*/if (_fullName == null) {
- _fullName = getFullUserName(this);
- }
- }
-}
-''';
- await findLint(src, LintNames.prefer_conditional_assignment);
-
- await applyFix(DartFixKind.REPLACE_WITH_CONDITIONAL_ASSIGNMENT);
-
- verifyResult('''
-class Person {
- String _fullName;
- void foo() {
- _fullName ??= getFullUserName(this);
- }
-}
-''');
- }
-
- test_replaceWithConditionalAssignment_withoutBlock() async {
- String src = '''
-class Person {
- String _fullName;
- void foo() {
- /*LINT*/if (_fullName == null)
- _fullName = getFullUserName(this);
- }
-}
-''';
- await findLint(src, LintNames.prefer_conditional_assignment);
-
- await applyFix(DartFixKind.REPLACE_WITH_CONDITIONAL_ASSIGNMENT);
-
- verifyResult('''
-class Person {
- String _fullName;
- void foo() {
- _fullName ??= getFullUserName(this);
- }
-}
-''');
- }
-
- test_replaceWithConditionalAssignment_withTwoBlock() async {
- String src = '''
-class Person {
- String _fullName;
- void foo() {
- /*LINT*/if (_fullName == null) {{
- _fullName = getFullUserName(this);
- }}
- }
-}
-''';
- await findLint(src, LintNames.prefer_conditional_assignment);
-
- await applyFix(DartFixKind.REPLACE_WITH_CONDITIONAL_ASSIGNMENT);
-
- verifyResult('''
-class Person {
- String _fullName;
- void foo() {
- _fullName ??= getFullUserName(this);
- }
-}
-''');
- }
-
- test_replaceWithLiteral_linkedHashMap_withCommentsInGeneric() async {
- String src = '''
-import 'dart:collection';
-
-final a = /*LINT*/new LinkedHashMap<int,/*comment*/int>();
-''';
- await findLint(src, LintNames.prefer_collection_literals);
-
- await applyFix(DartFixKind.REPLACE_WITH_LITERAL);
-
- verifyResult('''
-import 'dart:collection';
-
-final a = <int,/*comment*/int>{};
-''');
- }
-
- test_replaceWithLiteral_linkedHashMap_withDynamicGenerics() async {
- String src = '''
-import 'dart:collection';
-
-final a = /*LINT*/new LinkedHashMap<dynamic,dynamic>();
-''';
- await findLint(src, LintNames.prefer_collection_literals);
-
- await applyFix(DartFixKind.REPLACE_WITH_LITERAL);
-
- verifyResult('''
-import 'dart:collection';
-
-final a = <dynamic,dynamic>{};
-''');
- }
-
- test_replaceWithLiteral_linkedHashMap_withGeneric() async {
- String src = '''
-import 'dart:collection';
-
-final a = /*LINT*/new LinkedHashMap<int,int>();
-''';
- await findLint(src, LintNames.prefer_collection_literals);
-
- await applyFix(DartFixKind.REPLACE_WITH_LITERAL);
-
- verifyResult('''
-import 'dart:collection';
-
-final a = <int,int>{};
-''');
- }
-
- test_replaceWithLiteral_linkedHashMap_withoutGeneric() async {
- String src = '''
-import 'dart:collection';
-
-final a = /*LINT*/new LinkedHashMap();
-''';
- await findLint(src, LintNames.prefer_collection_literals);
-
- await applyFix(DartFixKind.REPLACE_WITH_LITERAL);
-
- verifyResult('''
-import 'dart:collection';
-
-final a = {};
-''');
- }
-
- test_replaceWithLiteral_list_withGeneric() async {
- String src = '''
-final a = /*LINT*/new List<int>();
-''';
- await findLint(src, LintNames.prefer_collection_literals);
-
- await applyFix(DartFixKind.REPLACE_WITH_LITERAL);
-
- verifyResult('''
-final a = <int>[];
-''');
- }
-
- test_replaceWithLiteral_list_withoutGeneric() async {
- String src = '''
-final a = /*LINT*/new List();
-''';
- await findLint(src, LintNames.prefer_collection_literals);
-
- await applyFix(DartFixKind.REPLACE_WITH_LITERAL);
-
- verifyResult('''
-final a = [];
-''');
- }
-
- test_replaceWithLiteral_map_withGeneric() async {
- String src = '''
-final a = /*LINT*/new Map<int,int>();
-''';
- await findLint(src, LintNames.prefer_collection_literals);
-
- await applyFix(DartFixKind.REPLACE_WITH_LITERAL);
-
- verifyResult('''
-final a = <int,int>{};
-''');
- }
-
- test_replaceWithLiteral_map_withoutGeneric() async {
- String src = '''
-final a = /*LINT*/new Map();
-''';
- await findLint(src, LintNames.prefer_collection_literals);
-
- await applyFix(DartFixKind.REPLACE_WITH_LITERAL);
-
- verifyResult('''
-final a = {};
-''');
- }
-
- test_replaceWithTearOff_function_oneParameter() async {
- String src = '''
-final x = /*LINT*/(name) {
- print(name);
-};
-''';
- await findLint(src, LintNames.unnecessary_lambdas);
-
- await applyFix(DartFixKind.REPLACE_WITH_TEAR_OFF);
-
- verifyResult('''
-final x = print;
-''');
- }
-
- test_replaceWithTearOff_function_zeroParameters() async {
- String src = '''
-void foo(){}
-Function finalVar() {
- return /*LINT*/() {
- foo();
- };
-}
-''';
- await findLint(src, LintNames.unnecessary_lambdas);
-
- await applyFix(DartFixKind.REPLACE_WITH_TEAR_OFF);
-
- verifyResult('''
-void foo(){}
-Function finalVar() {
- return foo;
-}
-''');
- }
-
- test_replaceWithTearOff_lambda_asArgument() async {
- String src = '''
-void foo() {
- bool isPair(int a) => a % 2 == 0;
- final finalList = <int>[];
- finalList.where(/*LINT*/(number) =>
- isPair(number));
-}
-''';
- await findLint(src, LintNames.unnecessary_lambdas);
-
- await applyFix(DartFixKind.REPLACE_WITH_TEAR_OFF);
-
- verifyResult('''
-void foo() {
- bool isPair(int a) => a % 2 == 0;
- final finalList = <int>[];
- finalList.where(isPair);
-}
-''');
- }
-
- test_replaceWithTearOff_method_oneParameter() async {
- String src = '''
-var a = /*LINT*/(x) => finalList.remove(x);
-''';
- await findLint(src, LintNames.unnecessary_lambdas);
-
- await applyFix(DartFixKind.REPLACE_WITH_TEAR_OFF);
-
- verifyResult('''
-var a = finalList.remove;
-''');
- }
-
- test_replaceWithTearOff_method_zeroParameter() async {
- String src = '''
-final Object a;
-Function finalVar() {
- return /*LINT*/() {
- return a.toString();
- };
-}
-''';
- await findLint(src, LintNames.unnecessary_lambdas);
-
- await applyFix(DartFixKind.REPLACE_WITH_TEAR_OFF);
-
- verifyResult('''
-final Object a;
-Function finalVar() {
- return a.toString;
-}
-''');
- }
-
- void verifyResult(String expectedResult) {
- expect(resultCode, expectedResult);
- }
-}
-
-class _DartFixContextImpl implements DartFixContext {
- @override
- final ResourceProvider resourceProvider;
-
- @override
- final AnalysisDriver analysisDriver;
-
- @override
- final AstProvider astProvider;
-
- @override
- final CompilationUnit unit;
-
- @override
- final AnalysisError error;
-
- @override
- final List<AnalysisError> errors;
-
- _DartFixContextImpl(this.resourceProvider, this.analysisDriver,
- this.astProvider, this.unit, this.error, this.errors);
-
- @override
- GetTopLevelDeclarations get getTopLevelDeclarations =>
- analysisDriver.getTopLevelNameDeclarations;
-}
diff --git a/pkg/analysis_server/test/services/correction/organize_directives_test.dart b/pkg/analysis_server/test/services/correction/organize_directives_test.dart
index d2b6796..ff56f55 100644
--- a/pkg/analysis_server/test/services/correction/organize_directives_test.dart
+++ b/pkg/analysis_server/test/services/correction/organize_directives_test.dart
@@ -5,8 +5,8 @@
import 'dart:async';
import 'package:analysis_server/src/services/correction/organize_directives.dart';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/error/error.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart'
hide AnalysisError;
import 'package:test/test.dart';
@@ -96,8 +96,8 @@
}
test_remove_unresolvedDirectives() async {
- addSource('/project/existing_part1.dart', 'part of lib;');
- addSource('/project/existing_part2.dart', 'part of lib;');
+ addSource('/home/test/lib/existing_part1.dart', 'part of lib;');
+ addSource('/home/test/lib/existing_part2.dart', 'part of lib;');
await _computeUnitAndErrors(r'''
library lib;
@@ -335,7 +335,8 @@
Future<void> _computeUnitAndErrors(String code) async {
addTestSource(code);
- AnalysisResult result = await driver.getResult(testSource.fullName);
+ ResolvedUnitResult result =
+ await session.getResolvedUnit(testSource.fullName);
testUnit = result.unit;
testErrors = result.errors;
}
diff --git a/pkg/analysis_server/test/services/correction/sort_members_test.dart b/pkg/analysis_server/test/services/correction/sort_members_test.dart
index d89bb36..81001fa 100644
--- a/pkg/analysis_server/test/services/correction/sort_members_test.dart
+++ b/pkg/analysis_server/test/services/correction/sort_members_test.dart
@@ -5,7 +5,7 @@
import 'dart:async';
import 'package:analysis_server/src/services/correction/sort_members.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -512,6 +512,24 @@
''');
}
+ test_mixinMembers_method() async {
+ await _parseTestUnit(r'''
+mixin A {
+ c() {}
+ a() {}
+ b() {}
+}
+''');
+ // validate change
+ _assertSort(r'''
+mixin A {
+ a() {}
+ b() {}
+ c() {}
+}
+''');
+ }
+
test_unitMembers_class() async {
await _parseTestUnit(r'''
class C {}
@@ -664,6 +682,20 @@
''');
}
+ test_unitMembers_genericTypeAlias() async {
+ await _parseTestUnit(r'''
+typedef FC = void Function();
+typedef FA = void Function();
+typedef FB = void Function();
+''');
+ // validate change
+ _assertSort(r'''
+typedef FA = void Function();
+typedef FB = void Function();
+typedef FC = void Function();
+''');
+ }
+
test_unitMembers_importsAndDeclarations() async {
await _parseTestUnit(r'''
import 'dart:a';
@@ -711,6 +743,8 @@
await _parseTestUnit(r'''
_mmm() {}
typedef nnn();
+typedef GTAF3 = void Function();
+typedef _GTAF2 = void Function();
_nnn() {}
typedef mmm();
typedef _nnn();
@@ -724,6 +758,7 @@
var nnn;
var _mmm;
var _nnn;
+typedef GTAF1 = void Function();
set nnn(x) {}
get mmm => null;
set mmm(x) {}
@@ -752,6 +787,9 @@
nnn() {}
_mmm() {}
_nnn() {}
+typedef GTAF1 = void Function();
+typedef GTAF3 = void Function();
+typedef _GTAF2 = void Function();
typedef mmm();
typedef nnn();
typedef _mmm();
@@ -763,6 +801,19 @@
''');
}
+ test_unitMembers_mixin() async {
+ await _parseTestUnit(r'''
+mixin C {}
+mixin A {}
+mixin B {}
+''');
+ _assertSort(r'''
+mixin A {}
+mixin B {}
+mixin C {}
+''');
+ }
+
test_unitMembers_topLevelVariable() async {
await _parseTestUnit(r'''
int c;
@@ -804,7 +855,7 @@
Future<void> _parseTestUnit(String code) async {
addTestSource(code);
- ParseResult result = await driver.parseFile(testSource.fullName);
+ ParsedUnitResult result = session.getParsedUnit(testSource.fullName);
testUnit = result.unit;
}
}
diff --git a/pkg/analysis_server/test/services/correction/status_test.dart b/pkg/analysis_server/test/services/correction/status_test.dart
index cce27cd..eb27ec2 100644
--- a/pkg/analysis_server/test/services/correction/status_test.dart
+++ b/pkg/analysis_server/test/services/correction/status_test.dart
@@ -29,7 +29,7 @@
Element element = findElement('MyClass');
// check
Location location = newLocation_fromElement(element);
- expect(location.file, convertPath('/project/test.dart'));
+ expect(location.file, testFile);
expect(location.offset, 6);
expect(location.length, 7);
expect(location.startLine, 1);
@@ -52,7 +52,7 @@
sourceRange);
// check
Location location = newLocation_fromMatch(match);
- expect(location.file, convertPath('/project/test.dart'));
+ expect(location.file, testFile);
expect(location.offset, sourceRange.offset);
expect(location.length, sourceRange.length);
}
@@ -65,7 +65,7 @@
AstNode node = findNodeAtString('main');
// check
Location location = newLocation_fromNode(node);
- expect(location.file, convertPath('/project/test.dart'));
+ expect(location.file, testFile);
expect(location.offset, node.offset);
expect(location.length, node.length);
}
@@ -75,7 +75,7 @@
SourceRange sourceRange = new SourceRange(10, 20);
// check
Location location = newLocation_fromUnit(testUnit, sourceRange);
- expect(location.file, convertPath('/project/test.dart'));
+ expect(location.file, testFile);
expect(location.offset, sourceRange.offset);
expect(location.length, sourceRange.length);
}
diff --git a/pkg/analysis_server/test/services/correction/strings_test.dart b/pkg/analysis_server/test/services/correction/strings_test.dart
index abd4493..a7a68e7 100644
--- a/pkg/analysis_server/test/services/correction/strings_test.dart
+++ b/pkg/analysis_server/test/services/correction/strings_test.dart
@@ -133,13 +133,6 @@
expect(isWhitespace('A'.codeUnitAt(0)), isFalse);
}
- void test_remove() {
- expect(remove(null, 'x'), null);
- expect(remove('abc', null), 'abc');
- expect(remove('abc abbc abbbc', 'b'), 'ac ac ac');
- expect(remove('abc abbc abbbc', 'bc'), 'a ab abb');
- }
-
void test_removeEnd() {
expect(removeEnd(null, 'x'), null);
expect(removeEnd('abc', null), 'abc');
@@ -165,11 +158,4 @@
expect(shorten('0123456789abcdef', 11), '0123...cdef');
expect(shorten('0123456789abcdef', 12), '01234...cdef');
}
-
- void test_substringAfterLast() {
- expect(substringAfterLast('', '/'), '');
- expect(substringAfterLast('abc', ''), '');
- expect(substringAfterLast('abc', 'd'), 'abc');
- expect(substringAfterLast('abcbde', 'b'), 'de');
- }
}
diff --git a/pkg/analysis_server/test/services/correction/test_all.dart b/pkg/analysis_server/test/services/correction/test_all.dart
index 4183ef1..e098648 100644
--- a/pkg/analysis_server/test/services/correction/test_all.dart
+++ b/pkg/analysis_server/test/services/correction/test_all.dart
@@ -1,12 +1,10 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'assist_test.dart' as assist_test;
import 'change_test.dart' as change_test;
-import 'fix_test.dart' as fix_test;
import 'levenshtein_test.dart' as levenshtein_test;
import 'name_suggestion_test.dart' as name_suggestion_test;
import 'organize_directives_test.dart' as organize_directives_test;
@@ -18,9 +16,7 @@
/// Utility for manually running all tests.
main() {
defineReflectiveSuite(() {
- assist_test.main();
change_test.main();
- fix_test.main();
levenshtein_test.main();
name_suggestion_test.main();
organize_directives_test.main();
diff --git a/pkg/analysis_server/test/services/correction/util_test.dart b/pkg/analysis_server/test/services/correction/util_test.dart
index 3e1981c..53eaa7c 100644
--- a/pkg/analysis_server/test/services/correction/util_test.dart
+++ b/pkg/analysis_server/test/services/correction/util_test.dart
@@ -35,7 +35,8 @@
''');
IfStatement ifStatement = findNodeAtString('if (');
Expression condition = ifStatement.condition;
- String result = new CorrectionUtils(testUnit).invertCondition(condition);
+ String result =
+ new CorrectionUtils(testAnalysisResult).invertCondition(condition);
expect(result, expected);
}
@@ -45,7 +46,7 @@
import 'dart:math';
''');
Source newLibrary = _getDartSource('dart:collection');
- _assertAddLibraryImport(<Source>[newLibrary], '''
+ await _assertAddLibraryImport(<Source>[newLibrary], '''
import 'dart:async';
import 'dart:collection';
import 'dart:math';
@@ -58,7 +59,7 @@
import 'dart:math';
''');
Source newLibrary = _getDartSource('dart:async');
- _assertAddLibraryImport(<Source>[newLibrary], '''
+ await _assertAddLibraryImport(<Source>[newLibrary], '''
import 'dart:async';
import 'dart:collection';
import 'dart:math';
@@ -71,7 +72,7 @@
import 'dart:collection';
''');
Source newLibrary = _getDartSource('dart:math');
- _assertAddLibraryImport(<Source>[newLibrary], '''
+ await _assertAddLibraryImport(<Source>[newLibrary], '''
import 'dart:async';
import 'dart:collection';
import 'dart:math';
@@ -85,7 +86,7 @@
''');
Source newLibrary1 = _getDartSource('dart:async');
Source newLibrary2 = _getDartSource('dart:html');
- _assertAddLibraryImport(<Source>[newLibrary1, newLibrary2], '''
+ await _assertAddLibraryImport(<Source>[newLibrary1, newLibrary2], '''
import 'dart:async';
import 'dart:collection';
import 'dart:html';
@@ -100,7 +101,7 @@
''');
Source newLibrary1 = _getDartSource('dart:async');
Source newLibrary2 = _getDartSource('dart:collection');
- _assertAddLibraryImport(<Source>[newLibrary1, newLibrary2], '''
+ await _assertAddLibraryImport(<Source>[newLibrary1, newLibrary2], '''
import 'dart:async';
import 'dart:collection';
import 'dart:html';
@@ -115,7 +116,7 @@
''');
Source newLibrary1 = _getDartSource('dart:html');
Source newLibrary2 = _getDartSource('dart:math');
- _assertAddLibraryImport(<Source>[newLibrary1, newLibrary2], '''
+ await _assertAddLibraryImport(<Source>[newLibrary1, newLibrary2], '''
import 'dart:async';
import 'dart:collection';
import 'dart:html';
@@ -131,7 +132,7 @@
''');
Source newLibrary1 = _getDartSource('dart:math');
Source newLibrary2 = _getDartSource('dart:async');
- _assertAddLibraryImport(<Source>[newLibrary1, newLibrary2], '''
+ await _assertAddLibraryImport(<Source>[newLibrary1, newLibrary2], '''
library test;
import 'dart:async';
@@ -149,7 +150,7 @@
''');
Source newLibrary1 = _getDartSource('dart:math');
Source newLibrary2 = _getDartSource('dart:async');
- _assertAddLibraryImport(<Source>[newLibrary1, newLibrary2], '''
+ await _assertAddLibraryImport(<Source>[newLibrary1, newLibrary2], '''
/// Comment.
import 'dart:async';
@@ -167,7 +168,7 @@
''');
Source newLibrary1 = _getDartSource('dart:math');
Source newLibrary2 = _getDartSource('dart:async');
- _assertAddLibraryImport(<Source>[newLibrary1, newLibrary2], '''
+ await _assertAddLibraryImport(<Source>[newLibrary1, newLibrary2], '''
#!/bin/dart
import 'dart:async';
@@ -183,7 +184,7 @@
''');
Source newLibrary1 = _getDartSource('dart:math');
Source newLibrary2 = _getDartSource('dart:async');
- _assertAddLibraryImport(<Source>[newLibrary1, newLibrary2], '''
+ await _assertAddLibraryImport(<Source>[newLibrary1, newLibrary2], '''
import 'dart:async';
import 'dart:math';
@@ -192,14 +193,14 @@
}
test_addLibraryImports_package_hasDart_hasPackages_insertAfter() async {
- addPackageSource('aaa', 'aaa.dart', '');
+ addPackageFile('aaa', 'aaa.dart', '');
await resolveTestUnit('''
import 'dart:async';
import 'package:aaa/aaa.dart';
''');
Source newLibrary = _getSource('/lib/bbb.dart', 'package:bbb/bbb.dart');
- _assertAddLibraryImport(<Source>[newLibrary], '''
+ await _assertAddLibraryImport(<Source>[newLibrary], '''
import 'dart:async';
import 'package:aaa/aaa.dart';
@@ -208,14 +209,14 @@
}
test_addLibraryImports_package_hasDart_hasPackages_insertBefore() async {
- addPackageSource('bbb', 'bbb.dart', '');
+ addPackageFile('bbb', 'bbb.dart', '');
await resolveTestUnit('''
import 'dart:async';
import 'package:bbb/bbb.dart';
''');
Source newLibrary = _getSource('/lib/aaa.dart', 'package:aaa/aaa.dart');
- _assertAddLibraryImport(<Source>[newLibrary], '''
+ await _assertAddLibraryImport(<Source>[newLibrary], '''
import 'dart:async';
import 'package:aaa/aaa.dart';
@@ -224,15 +225,15 @@
}
test_addLibraryImports_package_hasImports_between() async {
- addPackageSource('aaa', 'aaa.dart', '');
- addPackageSource('ddd', 'ddd.dart', '');
+ addPackageFile('aaa', 'aaa.dart', '');
+ addPackageFile('ddd', 'ddd.dart', '');
await resolveTestUnit('''
import 'package:aaa/aaa.dart';
import 'package:ddd/ddd.dart';
''');
Source newLibrary1 = _getSource('/lib/bbb.dart', 'package:bbb/bbb.dart');
Source newLibrary2 = _getSource('/lib/ccc.dart', 'package:ccc/ccc.dart');
- _assertAddLibraryImport(<Source>[newLibrary1, newLibrary2], '''
+ await _assertAddLibraryImport(<Source>[newLibrary1, newLibrary2], '''
import 'package:aaa/aaa.dart';
import 'package:bbb/bbb.dart';
import 'package:ccc/ccc.dart';
@@ -285,10 +286,11 @@
await assert_invertCondition('(((b1)))', '!b1');
}
- void _assertAddLibraryImport(List<Source> newLibraries, String expectedCode) {
+ Future<void> _assertAddLibraryImport(
+ List<Source> newLibraries, String expectedCode) async {
SourceChange change = new SourceChange('');
- addLibraryImports(resourceProvider.pathContext, change, testLibraryElement,
- newLibraries.toSet());
+ await addLibraryImports(testAnalysisResult.session, change,
+ testLibraryElement, newLibraries.toSet());
SourceFileEdit testEdit = change.getFileEdit(testFile);
expect(testEdit, isNotNull);
String resultCode = SourceEdit.applySequence(testCode, testEdit.edits);
diff --git a/pkg/analysis_server/test/services/linter/linter_test.dart b/pkg/analysis_server/test/services/linter/linter_test.dart
index 19272d8..3965bba 100644
--- a/pkg/analysis_server/test/services/linter/linter_test.dart
+++ b/pkg/analysis_server/test/services/linter/linter_test.dart
@@ -1,8 +1,9 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2015, 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:analyzer/analyzer.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analysis_server/test/services/refactoring/abstract_refactoring.dart b/pkg/analysis_server/test/services/refactoring/abstract_refactoring.dart
index 7acb0ce..213972f 100644
--- a/pkg/analysis_server/test/services/refactoring/abstract_refactoring.dart
+++ b/pkg/analysis_server/test/services/refactoring/abstract_refactoring.dart
@@ -8,11 +8,7 @@
import 'package:analysis_server/src/services/refactoring/refactoring.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
import 'package:analysis_server/src/services/search/search_engine_internal.dart';
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/element/element.dart' show Element;
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/dart/analysis/ast_provider_driver.dart';
-import 'package:analyzer/src/dart/element/ast_provider.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart'
show
@@ -44,7 +40,6 @@
*/
abstract class RefactoringTest extends AbstractSingleUnitTest {
SearchEngine searchEngine;
- AstProvider astProvider;
SourceChange refactoringChange;
@@ -151,14 +146,6 @@
expect(actualCode, expectedCode);
}
- /**
- * Completes with a fully resolved unit that contains the [element].
- */
- Future<CompilationUnit> getResolvedUnitWithElement(Element element) async {
- return element.context
- .resolveCompilationUnit(element.source, element.library);
- }
-
Future<void> indexTestUnit(String code) async {
await resolveTestUnit(code);
}
@@ -170,6 +157,5 @@
void setUp() {
super.setUp();
searchEngine = new SearchEngineImpl([driver]);
- astProvider = new AstProviderForDriver(driver);
}
}
diff --git a/pkg/analysis_server/test/services/refactoring/abstract_rename.dart b/pkg/analysis_server/test/services/refactoring/abstract_rename.dart
index 400bb3d..fec6d34 100644
--- a/pkg/analysis_server/test/services/refactoring/abstract_rename.dart
+++ b/pkg/analysis_server/test/services/refactoring/abstract_rename.dart
@@ -56,7 +56,8 @@
*/
void createRenameRefactoringForElement(Element element) {
var workspace = new RefactoringWorkspace([driver], searchEngine);
- refactoring = new RenameRefactoring(workspace, astProvider, element);
+ var session = testAnalysisResult.session;
+ refactoring = new RenameRefactoring(workspace, session, element);
expect(refactoring, isNotNull, reason: "No refactoring for '$element'.");
}
diff --git a/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart b/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart
index 6702055..abac0c8 100644
--- a/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart
@@ -87,7 +87,7 @@
}
test_change_multipleFiles() async {
- await indexUnit('/project/other.dart', r'''
+ await indexUnit('/home/test/lib/other.dart', r'''
class A {
int get test => 1;
}
@@ -153,7 +153,7 @@
void _createRefactoringForElement(ExecutableElement element) {
refactoring = new ConvertGetterToMethodRefactoring(
- searchEngine, astProvider, element);
+ searchEngine, testAnalysisResult.session, element);
}
void _createRefactoringForString(String search) {
diff --git a/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart b/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart
index 60f38f8..129cf15 100644
--- a/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart
@@ -89,7 +89,7 @@
}
test_change_multipleFiles() async {
- await indexUnit('/project/other.dart', r'''
+ await indexUnit('/home/test/lib/other.dart', r'''
class A {
int test() => 1;
}
@@ -205,7 +205,7 @@
void _createRefactoringForElement(ExecutableElement element) {
refactoring = new ConvertMethodToGetterRefactoring(
- searchEngine, astProvider, element);
+ searchEngine, testAnalysisResult.session, element);
}
void _createRefactoringForString(String search) {
diff --git a/pkg/analysis_server/test/services/refactoring/extract_method_test.dart b/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
index 35a31ee..420f69a 100644
--- a/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -1516,10 +1516,10 @@
await indexTestUnit('''
import 'asyncLib.dart';
main() {
- var a = newFuture();
+ var a = newCompleter();
}
''');
- _createRefactoringForString('newFuture()');
+ _createRefactoringForString('newCompleter()');
// apply refactoring
return _assertSuccessfulRefactoring('''
import 'asyncLib.dart';
@@ -1528,7 +1528,7 @@
var a = res();
}
-Future<int> res() => newFuture();
+Completer<int> res() => newCompleter();
''');
}
@@ -2527,7 +2527,7 @@
await indexTestUnit('''
import 'asyncLib.dart';
main() {
- var v = newFuture();
+ var v = newCompleter();
// start
print(v);
// end
@@ -2539,20 +2539,19 @@
import 'asyncLib.dart';
import 'dart:async';
main() {
- var v = newFuture();
+ var v = newCompleter();
// start
res(v);
// end
}
-void res(Future<int> v) {
+void res(Completer<int> v) {
print(v);
}
''');
}
test_statements_parameters_localFunction() async {
- _addLibraryReturningAsync();
await indexTestUnit('''
class C {
int f(int a) {
@@ -2837,10 +2836,10 @@
}
void _addLibraryReturningAsync() {
- addSource('/project/asyncLib.dart', r'''
-library asyncLib;
+ addSource('/home/test/lib/asyncLib.dart', r'''
import 'dart:async';
-Future<int> newFuture() => null;
+
+Completer<int> newCompleter() => null;
''');
}
@@ -2880,7 +2879,7 @@
void _createRefactoring(int offset, int length) {
refactoring = new ExtractMethodRefactoring(
- searchEngine, astProvider, testAnalysisResult, offset, length);
+ searchEngine, testAnalysisResult, offset, length);
refactoring.name = 'res';
}
diff --git a/pkg/analysis_server/test/services/refactoring/inline_local_test.dart b/pkg/analysis_server/test/services/refactoring/inline_local_test.dart
index 0c4ac76..41e32b8 100644
--- a/pkg/analysis_server/test/services/refactoring/inline_local_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/inline_local_test.dart
@@ -634,6 +634,9 @@
void _createRefactoring(String search) {
int offset = findOffset(search);
refactoring = new InlineLocalRefactoring(
- searchEngine, astProvider, testAnalysisResult, offset);
+ searchEngine,
+ testAnalysisResult,
+ offset,
+ );
}
}
diff --git a/pkg/analysis_server/test/services/refactoring/inline_method_test.dart b/pkg/analysis_server/test/services/refactoring/inline_method_test.dart
index a508984..077035c 100644
--- a/pkg/analysis_server/test/services/refactoring/inline_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/inline_method_test.dart
@@ -1756,6 +1756,9 @@
void _createRefactoring(String search) {
int offset = findOffset(search);
refactoring = new InlineMethodRefactoring(
- searchEngine, astProvider, testAnalysisResult, offset);
+ searchEngine,
+ testAnalysisResult,
+ offset,
+ );
}
}
diff --git a/pkg/analysis_server/test/services/refactoring/move_file_test.dart b/pkg/analysis_server/test/services/refactoring/move_file_test.dart
index 2616261..dd52924 100644
--- a/pkg/analysis_server/test/services/refactoring/move_file_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/move_file_test.dart
@@ -23,10 +23,10 @@
MoveFileRefactoring refactoring;
test_file_containing_imports_exports_parts() async {
- String pathA = '/project/000/1111/a.dart';
- String pathB = '/project/000/1111/b.dart';
- String pathC = '/project/000/1111/22/c.dart';
- testFile = '/project/000/1111/test.dart';
+ String pathA = '/home/test/000/1111/a.dart';
+ String pathB = '/home/test/000/1111/b.dart';
+ String pathC = '/home/test/000/1111/22/c.dart';
+ testFile = '/home/test/000/1111/test.dart';
addSource('/absolute/uri.dart', '');
addSource(pathA, 'part of lib;');
addSource(pathB, "import 'test.dart';");
@@ -40,7 +40,7 @@
part '${convertAbsolutePathToUri('/absolute/uri.dart')}';
''');
// perform refactoring
- _createRefactoring('/project/000/1111/22/new_name.dart');
+ _createRefactoring('/home/test/000/1111/22/new_name.dart');
await _assertSuccessfulRefactoring();
assertNoFileChange(pathA);
assertFileChangeResult(pathB, "import '22/new_name.dart';");
@@ -55,15 +55,30 @@
''');
}
+ test_file_imported_with_package_uri() async {
+ newFile('/home/test/lib/old_name.dart', content: '');
+ addTestSource(r'''
+import 'package:test/old_name.dart';
+''');
+
+ _createRefactoring('/home/test/lib/222/new_name.dart',
+ oldName: '/home/test/lib/old_name.dart');
+ await _assertSuccessfulRefactoring();
+
+ assertFileChangeResult(testFile, '''
+import 'package:test/222/new_name.dart';
+''');
+ }
+
test_file_importedLibrary_down() async {
- String pathA = '/project/000/1111/a.dart';
- testFile = '/project/000/1111/test.dart';
+ String pathA = '/home/test/000/1111/a.dart';
+ testFile = '/home/test/000/1111/test.dart';
addSource(pathA, '''
import 'test.dart';
''');
addTestSource('');
// perform refactoring
- _createRefactoring('/project/000/1111/22/new_name.dart');
+ _createRefactoring('/home/test/000/1111/22/new_name.dart');
await _assertSuccessfulRefactoring();
assertFileChangeResult(pathA, '''
import '22/new_name.dart';
@@ -72,14 +87,14 @@
}
test_file_importedLibrary_sideways() async {
- String pathA = '/project/000/1111/a.dart';
- testFile = '/project/000/1111/sub/folder/test.dart';
+ String pathA = '/home/test/000/1111/a.dart';
+ testFile = '/home/test/000/1111/sub/folder/test.dart';
addSource(pathA, '''
import 'sub/folder/test.dart';
''');
addTestSource('');
// perform refactoring
- _createRefactoring('/project/000/new/folder/name/new_name.dart');
+ _createRefactoring('/home/test/000/new/folder/name/new_name.dart');
await _assertSuccessfulRefactoring();
assertFileChangeResult(pathA, '''
import '../new/folder/name/new_name.dart';
@@ -88,14 +103,14 @@
}
test_file_importedLibrary_up() async {
- String pathA = '/project/000/1111/a.dart';
- testFile = '/project/000/1111/22/test.dart';
+ String pathA = '/home/test/000/1111/a.dart';
+ testFile = '/home/test/000/1111/22/test.dart';
addSource(pathA, '''
import '22/test.dart';
''');
addTestSource('');
// perform refactoring
- _createRefactoring('/project/000/1111/new_name.dart');
+ _createRefactoring('/home/test/000/1111/new_name.dart');
await _assertSuccessfulRefactoring();
assertFileChangeResult(pathA, '''
import 'new_name.dart';
@@ -103,33 +118,13 @@
assertNoFileChange(testFile);
}
- test_file_imported_with_package_uri() async {
- // Set up package uri resolution for local package.
- packageMap['my_package'] = [getFolder('/project/lib')];
- configureDriver();
-
- String pathA = '/project/000/1111/a.dart';
- testFile = '/project/lib/test.dart';
- addSource(pathA, '''
- import 'package:my_package/test.dart';
- ''');
- addTestSource('');
- // perform refactoring
- _createRefactoring('/project/lib/222/new_name.dart');
- await _assertSuccessfulRefactoring();
- assertFileChangeResult(pathA, '''
- import 'package:my_package/222/new_name.dart';
- ''');
- assertNoFileChange(testFile);
- }
-
@failingTest
test_file_referenced_by_multiple_libraries() async {
// This test fails because the search index doesn't support multiple uris for
// a library, so only one of them is updated.
- String pathA = '/project/000/1111/a.dart';
- String pathB = '/project/000/b.dart';
- testFile = '/project/000/1111/22/test.dart';
+ String pathA = '/home/test/000/1111/a.dart';
+ String pathB = '/home/test/000/b.dart';
+ testFile = '/home/test/000/1111/22/test.dart';
addSource(pathA, '''
library lib;
part '22/test.dart';
@@ -142,7 +137,7 @@
part of lib;
''');
// perform refactoring
- _createRefactoring('/project/000/1111/22/new_name.dart');
+ _createRefactoring('/home/test/000/1111/22/new_name.dart');
await _assertSuccessfulRefactoring();
assertFileChangeResult(pathA, '''
library lib;
@@ -156,8 +151,8 @@
}
test_file_referenced_by_part() async {
- String pathA = '/project/000/1111/a.dart';
- testFile = '/project/000/1111/22/test.dart';
+ String pathA = '/home/test/000/1111/a.dart';
+ testFile = '/home/test/000/1111/22/test.dart';
addSource(pathA, '''
library lib;
part '22/test.dart';
@@ -166,7 +161,7 @@
part of lib;
''');
// perform refactoring
- _createRefactoring('/project/000/1111/22/new_name.dart');
+ _createRefactoring('/home/test/000/1111/22/new_name.dart');
await _assertSuccessfulRefactoring();
assertFileChangeResult(pathA, '''
library lib;
@@ -190,11 +185,11 @@
}
test_nonexistent_file_returns_failure() async {
- _createRefactoring(convertPath('/project/test_missing_new.dart'),
- oldName: convertPath('/project/test_missing.dart'));
+ _createRefactoring(convertPath('/home/test/test_missing_new.dart'),
+ oldName: convertPath('/home/test/test_missing.dart'));
await _assertFailedRefactoring(RefactoringProblemSeverity.FATAL,
expectedMessage:
- '${convertPath('/project/test_missing.dart')} does not exist.');
+ '${convertPath('/home/test/test_missing.dart')} does not exist.');
}
@failingTest
@@ -205,18 +200,18 @@
}
test_projectFolder() async {
- _createRefactoring('/project2', oldName: '/project');
+ _createRefactoring('/home/test2', oldName: '/home/test');
await _assertFailedRefactoring(RefactoringProblemSeverity.FATAL,
- expectedMessage:
- 'Renaming an analysis root is not supported (${convertPath('/project')})');
+ expectedMessage: 'Renaming an analysis root is not supported '
+ '(${convertPath('/home/test')})');
}
test_renaming_part_that_uses_uri_in_part_of() async {
// If the file is a part in a library, and the part-of directive uses a URI
// rather than a library name, that will need updating too (if the relative
// path to the parent changes).
- String pathA = '/project/000/1111/a.dart';
- testFile = '/project/000/1111/22/test.dart';
+ String pathA = '/home/test/000/1111/a.dart';
+ testFile = '/home/test/000/1111/22/test.dart';
addSource(pathA, '''
library lib;
part '22/test.dart';
@@ -225,7 +220,7 @@
part of '../a.dart';
''');
// perform refactoring
- _createRefactoring('/project/000/1111/22/33/test.dart');
+ _createRefactoring('/home/test/000/1111/22/33/test.dart');
await _assertSuccessfulRefactoring();
assertFileChangeResult(pathA, '''
library lib;
@@ -236,6 +231,13 @@
''');
}
+ Future _assertFailedRefactoring(RefactoringProblemSeverity expectedSeverity,
+ {String expectedMessage}) async {
+ RefactoringStatus status = await refactoring.checkAllConditions();
+ assertRefactoringStatus(status, expectedSeverity,
+ expectedMessage: expectedMessage);
+ }
+
/**
* Checks that all conditions are OK.
*/
@@ -257,11 +259,4 @@
}
refactoring.newFile = convertPath(newName);
}
-
- Future _assertFailedRefactoring(RefactoringProblemSeverity expectedSeverity,
- {String expectedMessage}) async {
- RefactoringStatus status = await refactoring.checkAllConditions();
- assertRefactoringStatus(status, expectedSeverity,
- expectedMessage: expectedMessage);
- }
}
diff --git a/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart b/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart
index a7e9148..90957df 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart
@@ -157,7 +157,7 @@
test() {}
}
''');
- await indexUnit('/project/lib.dart', '''
+ await indexUnit('/home/test/lib/lib.dart', '''
library my.lib;
import 'test.dart';
@@ -356,7 +356,7 @@
newName() {} // marker
}
''';
- await indexUnit('/project/lib.dart', libCode);
+ await indexUnit('/home/test/lib/lib.dart', libCode);
await indexTestUnit('''
import 'lib.dart';
class B extends A {
@@ -715,17 +715,18 @@
}
test_createChange_MethodElement_potential_inPubCache() async {
- String pkgLib = '/.pub-cache/lib.dart';
- await indexUnit(pkgLib, r'''
+ var externalPath = addPackageFile('aaa', 'lib.dart', r'''
processObj(p) {
p.test();
}
-''');
+''').path;
await indexTestUnit('''
-import '${convertAbsolutePathToUri(pkgLib)}';
+import 'package:aaa/lib.dart';
+
class A {
test() {}
}
+
main(var a) {
a.test();
}
@@ -737,15 +738,17 @@
refactoring.newName = 'newName';
// validate change
await assertSuccessfulRefactoring('''
-import '${convertAbsolutePathToUri('/.pub-cache/lib.dart')}';
+import 'package:aaa/lib.dart';
+
class A {
newName() {}
}
+
main(var a) {
a.newName();
}
''');
- SourceFileEdit fileEdit = refactoringChange.getFileEdit(pkgLib);
+ SourceFileEdit fileEdit = refactoringChange.getFileEdit(externalPath);
expect(fileEdit, isNull);
}
@@ -783,6 +786,94 @@
assertNoFileChange('/lib.dart');
}
+ test_createChange_outsideOfProject_declarationInPackage() async {
+ addPackageFile('aaa', 'aaa.dart', r'''
+class A {
+ void test() {}
+}
+
+void foo(A a) {
+ a.test();
+}
+''');
+ await indexTestUnit('''
+import 'package:aaa/aaa.dart';
+
+class B extends A {
+ void test() {}
+}
+
+main(A a, B b) {
+ a.test();
+ b.test();
+}
+''');
+ createRenameRefactoringAtString('test() {}');
+ refactoring.newName = 'newName';
+
+ await assertSuccessfulRefactoring('''
+import 'package:aaa/aaa.dart';
+
+class B extends A {
+ void newName() {}
+}
+
+main(A a, B b) {
+ a.newName();
+ b.newName();
+}
+''');
+
+ expect(refactoringChange.edits, hasLength(1));
+ expect(refactoringChange.edits[0].file, testFile);
+ }
+
+ test_createChange_outsideOfProject_referenceInPart() async {
+ newFile('/home/part.dart', content: r'''
+part of test;
+
+void foo(A a) {
+ a.test();
+}
+''');
+
+ // To use file:// URI.
+ testFile = convertPath('/home/test/bin/test.dart');
+
+ await indexTestUnit('''
+library test;
+
+part '../../part.dart';
+
+class A {
+ void test() {}
+}
+
+main(A a) {
+ a.test();
+}
+''');
+ createRenameRefactoringAtString('test() {}');
+ refactoring.newName = 'newName';
+
+ await assertSuccessfulRefactoring('''
+library test;
+
+part '../../part.dart';
+
+class A {
+ void newName() {}
+}
+
+main(A a) {
+ a.newName();
+}
+''');
+
+ expect(refactoringChange.edits, hasLength(1));
+ expect(refactoringChange.edits[0].file, testFile);
+ }
+
test_createChange_PropertyAccessorElement_getter() async {
await indexTestUnit('''
class A {
diff --git a/pkg/analysis_server/test/services/refactoring/rename_library_test.dart b/pkg/analysis_server/test/services/refactoring/rename_library_test.dart
index 19d2a4d..dc1df38 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_library_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_library_test.dart
@@ -40,7 +40,7 @@
}
test_createChange() async {
- addSource('/project/part.dart', '''
+ addSource('/home/test/lib/part.dart', '''
part of my.app;
''');
await indexTestUnit('''
@@ -57,13 +57,13 @@
library the.new.name;
part 'part.dart';
''');
- assertFileChangeResult('/project/part.dart', '''
+ assertFileChangeResult('/home/test/lib/part.dart', '''
part of the.new.name;
''');
}
test_createChange_hasWhitespaces() async {
- addSource('/project/part.dart', '''
+ addSource('/home/test/lib/part.dart', '''
part of my . app;
''');
await indexTestUnit('''
@@ -80,7 +80,7 @@
library the.new.name;
part 'part.dart';
''');
- assertFileChangeResult('/project/part.dart', '''
+ assertFileChangeResult('/home/test/lib/part.dart', '''
part of the.new.name;
''');
}
diff --git a/pkg/analysis_server/test/services/refactoring/rename_local_test.dart b/pkg/analysis_server/test/services/refactoring/rename_local_test.dart
index 6b8c273..25359cd 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_local_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_local_test.dart
@@ -442,29 +442,42 @@
}
test_createChange_parameter_named_inOtherFile() async {
- await indexTestUnit('''
+ var a = convertPath('/home/test/lib/a.dart');
+ var b = convertPath('/home/test/lib/b.dart');
+
+ newFile(a, content: r'''
class A {
A({test});
}
''');
- await indexUnit('/project/test2.dart', '''
-import 'test.dart';
+ newFile(b, content: r'''
+import 'a.dart';
+
main() {
new A(test: 2);
}
''');
- // configure refactoring
+ driver.addFile(a);
+ driver.addFile(b);
+
+ var session = driver.currentSession;
+ testAnalysisResult = await session.getResolvedUnit(a);
+ testFile = testAnalysisResult.path;
+ testCode = testAnalysisResult.content;
+ testUnit = testAnalysisResult.unit;
+
createRenameRefactoringAtString('test});');
expect(refactoring.refactoringName, 'Rename Parameter');
refactoring.newName = 'newName';
- // validate change
+
await assertSuccessfulRefactoring('''
class A {
A({newName});
}
''');
- assertFileChangeResult('/project/test2.dart', '''
-import 'test.dart';
+ assertFileChangeResult(b, '''
+import 'a.dart';
+
main() {
new A(newName: 2);
}
@@ -472,7 +485,7 @@
}
test_createChange_parameter_named_updateHierarchy() async {
- await indexUnit('/project/test2.dart', '''
+ await indexUnit('/home/test/lib/test2.dart', '''
library test2;
class A {
void foo({int test: 1}) {
@@ -516,7 +529,7 @@
}
}
''');
- assertFileChangeResult('/project/test2.dart', '''
+ assertFileChangeResult('/home/test/lib/test2.dart', '''
library test2;
class A {
void foo({int newName: 1}) {
diff --git a/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart b/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart
index 7ace7de..1f23392 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart
@@ -69,7 +69,7 @@
await indexTestUnit('''
class Test {}
''');
- await indexUnit(convertPath('/project/lib.dart'), '''
+ await indexUnit('/home/test/lib/lib.dart', '''
library my.lib;
import 'test.dart';
@@ -109,7 +109,7 @@
await indexTestUnit('''
class Test {}
''');
- await indexUnit(convertPath('/project/lib.dart'), '''
+ await indexUnit('/home/test/lib/lib.dart', '''
library my.lib;
import 'test.dart';
class A {
@@ -230,11 +230,11 @@
}
test_checkInitialConditions_outsideOfProject() async {
- addSource('/other/lib.dart', r'''
+ addPackageFile('aaa', 'lib.dart', r'''
class A {}
''');
await indexTestUnit('''
-import "${convertAbsolutePathToUri('/other/lib.dart')}";
+import "package:aaa/lib.dart";
main() {
A a;
}
@@ -587,7 +587,7 @@
}
test_createChange_FunctionElement_imported() async {
- await indexUnit('/project/foo.dart', r'''
+ await indexUnit('/home/test/lib/foo.dart', r'''
test() {}
foo() {}
''');
@@ -614,7 +614,7 @@
foo();
}
''');
- assertFileChangeResult('/project/foo.dart', '''
+ assertFileChangeResult('/home/test/lib/foo.dart', '''
newName() {}
foo() {}
''');
@@ -644,6 +644,42 @@
''');
}
+ test_createChange_outsideOfProject_referenceInPart() async {
+ newFile('/home/part.dart', content: r'''
+part of test;
+
+Test test2;
+''');
+
+ // To use file:// URI.
+ testFile = convertPath('/home/test/bin/test.dart');
+
+ await indexTestUnit('''
+library test;
+
+part '../../part.dart';
+
+class Test {}
+
+Test test;
+''');
+ createRenameRefactoringAtString('Test {}');
+ refactoring.newName = 'NewName';
+
+ await assertSuccessfulRefactoring('''
+library test;
+
+part '../../part.dart';
+
+class NewName {}
+
+NewName test;
+''');
+
+ expect(refactoringChange.edits, hasLength(1));
+ expect(refactoringChange.edits[0].file, testFile);
+ }
+
test_createChange_PropertyAccessorElement_getter_declaration() async {
await _test_createChange_PropertyAccessorElement("test {}");
}
diff --git a/pkg/analysis_server/test/services/search/search_engine_test.dart b/pkg/analysis_server/test/services/search/search_engine_test.dart
index 009e5fc..16488d7 100644
--- a/pkg/analysis_server/test/services/search/search_engine_test.dart
+++ b/pkg/analysis_server/test/services/search/search_engine_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -7,21 +7,20 @@
import 'package:analysis_server/src/services/search/search_engine.dart';
import 'package:analysis_server/src/services/search/search_engine_internal.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
+import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/source/package_map_resolver.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
-import 'package:analyzer/src/dart/analysis/byte_store.dart';
-import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../mock_sdk.dart';
-
main() {
defineReflectiveSuite(() {
defineReflectiveTests(SearchEngineImplTest);
@@ -29,7 +28,7 @@
}
@reflectiveTest
-class SearchEngineImplTest extends Object with ResourceProviderMixin {
+class SearchEngineImplTest with ResourceProviderMixin {
DartSdk sdk;
final ByteStore byteStore = new MemoryByteStore();
final FileContentOverlay contentOverlay = new FileContentOverlay();
@@ -496,7 +495,8 @@
contentOverlay,
null,
new SourceFactory(resolvers, null, resourceProvider),
- new AnalysisOptionsImpl());
+ new AnalysisOptionsImpl(),
+ enableIndex: true);
}
static void _assertContainsClass(Set<ClassElement> subtypes, String name) {
diff --git a/pkg/analysis_server/test/src/computer/closingLabels_computer_test.dart b/pkg/analysis_server/test/src/computer/closingLabels_computer_test.dart
index 1c5ec8d..f748909 100644
--- a/pkg/analysis_server/test/src/computer/closingLabels_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/closingLabels_computer_test.dart
@@ -24,7 +24,7 @@
setUp() {
super.setUp();
- sourcePath = resourceProvider.convertPath('/p/lib/source.dart');
+ sourcePath = convertPath('/home/test/lib/test.dart');
}
test_adjacentLinesExcluded() async {
@@ -400,7 +400,7 @@
Future<List<ClosingLabel>> _computeElements(String sourceContent) async {
newFile(sourcePath, content: sourceContent);
- ResolveResult result = await driver.getResult(sourcePath);
+ ResolvedUnitResult result = await session.getResolvedUnit(sourcePath);
DartUnitClosingLabelsComputer computer =
new DartUnitClosingLabelsComputer(result.lineInfo, result.unit);
return computer.compute();
diff --git a/pkg/analysis_server/test/src/computer/folding_computer_test.dart b/pkg/analysis_server/test/src/computer/folding_computer_test.dart
index dee139a..8fcde2d 100644
--- a/pkg/analysis_server/test/src/computer/folding_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/folding_computer_test.dart
@@ -24,7 +24,7 @@
setUp() {
super.setUp();
- sourcePath = resourceProvider.convertPath('/p/lib/source.dart');
+ sourcePath = convertPath('/home/test/lib/test.dart');
}
test_annotations() async {
@@ -449,7 +449,7 @@
Future<List<FoldingRegion>> _computeRegions(String sourceContent) async {
newFile(sourcePath, content: sourceContent);
- ResolveResult result = await driver.getResult(sourcePath);
+ ResolvedUnitResult result = await session.getResolvedUnit(sourcePath);
DartUnitFoldingComputer computer =
new DartUnitFoldingComputer(result.lineInfo, result.unit);
return computer.compute();
diff --git a/pkg/analysis_server/test/src/computer/import_elements_computer_test.dart b/pkg/analysis_server/test/src/computer/import_elements_computer_test.dart
index 3d5f23b..731ca5f 100644
--- a/pkg/analysis_server/test/src/computer/import_elements_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/import_elements_computer_test.dart
@@ -6,9 +6,8 @@
import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analysis_server/src/computer/import_elements_computer.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
-import 'package:analyzer/src/generated/source.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -52,13 +51,13 @@
Future<void> createBuilder(String content) async {
originalContent = content;
newFile(path, content: content);
- AnalysisResult result = await driver.getResult(path);
+ ResolvedUnitResult result = await session.getResolvedUnit(path);
computer = new ImportElementsComputer(resourceProvider, result);
}
void setUp() {
super.setUp();
- path = resourceProvider.convertPath('/test.dart');
+ path = convertPath('/home/test/lib/test.dart');
}
test_createEdits_addImport_noDirectives() async {
@@ -69,7 +68,7 @@
''');
await computeChanges(<ImportedElements>[
new ImportedElements(
- convertPath('/lib/math/math.dart'), '', <String>['Random'])
+ convertPath('/sdk/lib/math/math.dart'), '', <String>['Random'])
]);
assertChanges('''
import 'dart:math';
@@ -81,12 +80,12 @@
}
test_createEdits_addImport_noPrefix() async {
- Source fooSource = addPackageSource('pkg', 'foo.dart', '');
+ var fooFile = addPackageFile('pkg', 'foo.dart', '');
await createBuilder('''
import 'package:pkg/foo.dart' as foo;
''');
await computeChanges(<ImportedElements>[
- new ImportedElements(fooSource.fullName, '', <String>['A'])
+ new ImportedElements(fooFile.path, '', <String>['A'])
]);
assertChanges('''
import 'package:pkg/foo.dart' as foo;
@@ -95,12 +94,12 @@
}
test_createEdits_addImport_prefix() async {
- Source fooSource = addPackageSource('pkg', 'foo.dart', '');
+ var fooFile = addPackageFile('pkg', 'foo.dart', '');
await createBuilder('''
import 'package:pkg/foo.dart';
''');
await computeChanges(<ImportedElements>[
- new ImportedElements(fooSource.fullName, 'foo', <String>['A'])
+ new ImportedElements(fooFile.path, 'foo', <String>['A'])
]);
assertChanges('''
import 'package:pkg/foo.dart';
@@ -109,13 +108,13 @@
}
test_createEdits_addShow_multipleNames() async {
- Source fooSource = addPackageSource('pkg', 'foo.dart', '');
+ var fooFile = addPackageFile('pkg', 'foo.dart', '');
await createBuilder('''
import 'package:pkg/foo.dart' show B;
import 'package:pkg/foo.dart' as foo;
''');
await computeChanges(<ImportedElements>[
- new ImportedElements(fooSource.fullName, '', <String>['A', 'C'])
+ new ImportedElements(fooFile.path, '', <String>['A', 'C'])
]);
assertChanges('''
import 'package:pkg/foo.dart' show B, A, C;
@@ -124,12 +123,12 @@
}
test_createEdits_addShow_removeHide() async {
- Source fooSource = addPackageSource('pkg', 'foo.dart', '');
+ var fooFile = addPackageFile('pkg', 'foo.dart', '');
await createBuilder('''
import 'package:pkg/foo.dart' show A, B hide C, D;
''');
await computeChanges(<ImportedElements>[
- new ImportedElements(fooSource.fullName, '', <String>['C'])
+ new ImportedElements(fooFile.path, '', <String>['C'])
]);
assertChanges('''
import 'package:pkg/foo.dart' show A, B, C hide D;
@@ -137,12 +136,12 @@
}
test_createEdits_addShow_singleName_noPrefix() async {
- Source fooSource = addPackageSource('pkg', 'foo.dart', '');
+ var fooFile = addPackageFile('pkg', 'foo.dart', '');
await createBuilder('''
import 'package:pkg/foo.dart' show B;
''');
await computeChanges(<ImportedElements>[
- new ImportedElements(fooSource.fullName, '', <String>['A'])
+ new ImportedElements(fooFile.path, '', <String>['A'])
]);
assertChanges('''
import 'package:pkg/foo.dart' show B, A;
@@ -150,13 +149,13 @@
}
test_createEdits_addShow_singleName_prefix() async {
- Source fooSource = addPackageSource('pkg', 'foo.dart', '');
+ var fooFile = addPackageFile('pkg', 'foo.dart', '');
await createBuilder('''
import 'package:pkg/foo.dart' show C;
import 'package:pkg/foo.dart' as foo show B;
''');
await computeChanges(<ImportedElements>[
- new ImportedElements(fooSource.fullName, 'foo', <String>['A'])
+ new ImportedElements(fooFile.path, 'foo', <String>['A'])
]);
assertChanges('''
import 'package:pkg/foo.dart' show C;
@@ -165,34 +164,34 @@
}
test_createEdits_alreadyImported_noCombinators() async {
- Source fooSource = addPackageSource('pkg', 'foo.dart', '');
+ var fooFile = addPackageFile('pkg', 'foo.dart', '');
await createBuilder('''
import 'package:pkg/foo.dart';
''');
await computeChanges(<ImportedElements>[
- new ImportedElements(fooSource.fullName, '', <String>['A', 'B'])
+ new ImportedElements(fooFile.path, '', <String>['A', 'B'])
]);
assertNoChanges();
}
test_createEdits_alreadyImported_withPrefix() async {
- Source fooSource = addPackageSource('pkg', 'foo.dart', '');
+ var fooFile = addPackageFile('pkg', 'foo.dart', '');
await createBuilder('''
import 'package:pkg/foo.dart' as foo;
''');
await computeChanges(<ImportedElements>[
- new ImportedElements(fooSource.fullName, 'foo', <String>['A', 'B'])
+ new ImportedElements(fooFile.path, 'foo', <String>['A', 'B'])
]);
assertNoChanges();
}
test_createEdits_alreadyImported_withShow() async {
- Source fooSource = addPackageSource('pkg', 'foo.dart', '');
+ var fooFile = addPackageFile('pkg', 'foo.dart', '');
await createBuilder('''
import 'package:pkg/foo.dart' show A;
''');
await computeChanges(<ImportedElements>[
- new ImportedElements(fooSource.fullName, '', <String>['A'])
+ new ImportedElements(fooFile.path, '', <String>['A'])
]);
assertNoChanges();
}
@@ -210,12 +209,12 @@
}
test_createEdits_invalidUri() async {
- Source fooSource = addPackageSource('pkg', 'foo.dart', '');
+ var fooFile = addPackageFile('pkg', 'foo.dart', '');
await createBuilder('''
import 'pakage:pkg/foo.dart';
''');
await computeChanges(<ImportedElements>[
- new ImportedElements(fooSource.fullName, '', <String>['A'])
+ new ImportedElements(fooFile.path, '', <String>['A'])
]);
assertChanges('''
import 'pakage:pkg/foo.dart';
@@ -230,12 +229,12 @@
}
test_createEdits_removeHide_firstInCombinator() async {
- Source fooSource = addPackageSource('pkg', 'foo.dart', '');
+ var fooFile = addPackageFile('pkg', 'foo.dart', '');
await createBuilder('''
import 'package:pkg/foo.dart' hide A, B, C;
''');
await computeChanges(<ImportedElements>[
- new ImportedElements(fooSource.fullName, '', <String>['A'])
+ new ImportedElements(fooFile.path, '', <String>['A'])
]);
assertChanges('''
import 'package:pkg/foo.dart' hide B, C;
@@ -243,12 +242,12 @@
}
test_createEdits_removeHide_lastInCombinator() async {
- Source fooSource = addPackageSource('pkg', 'foo.dart', '');
+ var fooFile = addPackageFile('pkg', 'foo.dart', '');
await createBuilder('''
import 'package:pkg/foo.dart' hide A, B, C;
''');
await computeChanges(<ImportedElements>[
- new ImportedElements(fooSource.fullName, '', <String>['C'])
+ new ImportedElements(fooFile.path, '', <String>['C'])
]);
assertChanges('''
import 'package:pkg/foo.dart' hide A, B;
@@ -256,12 +255,12 @@
}
test_createEdits_removeHide_middleInCombinator() async {
- Source fooSource = addPackageSource('pkg', 'foo.dart', '');
+ var fooFile = addPackageFile('pkg', 'foo.dart', '');
await createBuilder('''
import 'package:pkg/foo.dart' hide A, B, C;
''');
await computeChanges(<ImportedElements>[
- new ImportedElements(fooSource.fullName, '', <String>['B'])
+ new ImportedElements(fooFile.path, '', <String>['B'])
]);
assertChanges('''
import 'package:pkg/foo.dart' hide A, C;
@@ -269,12 +268,12 @@
}
test_createEdits_removeHide_multipleCombinators() async {
- Source fooSource = addPackageSource('pkg', 'foo.dart', '');
+ var fooFile = addPackageFile('pkg', 'foo.dart', '');
await createBuilder('''
import 'package:pkg/foo.dart' hide A, B, C hide A, B, C;
''');
await computeChanges(<ImportedElements>[
- new ImportedElements(fooSource.fullName, '', <String>['B'])
+ new ImportedElements(fooFile.path, '', <String>['B'])
]);
assertChanges('''
import 'package:pkg/foo.dart' hide A, C hide A, C;
@@ -282,12 +281,12 @@
}
test_createEdits_removeHide_multipleNames() async {
- Source fooSource = addPackageSource('pkg', 'foo.dart', '');
+ var fooFile = addPackageFile('pkg', 'foo.dart', '');
await createBuilder('''
import 'package:pkg/foo.dart' hide A, B, C hide D, E, F hide G, H, I;
''');
await computeChanges(<ImportedElements>[
- new ImportedElements(fooSource.fullName, '', <String>['A', 'E', 'I'])
+ new ImportedElements(fooFile.path, '', <String>['A', 'E', 'I'])
]);
assertChanges('''
import 'package:pkg/foo.dart' hide B, C hide D, F hide G, H;
@@ -295,12 +294,12 @@
}
test_createEdits_removeHideCombinator_first() async {
- Source fooSource = addPackageSource('pkg', 'foo.dart', '');
+ var fooFile = addPackageFile('pkg', 'foo.dart', '');
await createBuilder('''
import 'package:pkg/foo.dart' hide A hide B hide C;
''');
await computeChanges(<ImportedElements>[
- new ImportedElements(fooSource.fullName, '', <String>['A'])
+ new ImportedElements(fooFile.path, '', <String>['A'])
]);
assertChanges('''
import 'package:pkg/foo.dart' hide B hide C;
@@ -308,12 +307,12 @@
}
test_createEdits_removeHideCombinator_last() async {
- Source fooSource = addPackageSource('pkg', 'foo.dart', '');
+ var fooFile = addPackageFile('pkg', 'foo.dart', '');
await createBuilder('''
import 'package:pkg/foo.dart' hide A hide B hide C;
''');
await computeChanges(<ImportedElements>[
- new ImportedElements(fooSource.fullName, '', <String>['C'])
+ new ImportedElements(fooFile.path, '', <String>['C'])
]);
assertChanges('''
import 'package:pkg/foo.dart' hide A hide B;
@@ -321,12 +320,12 @@
}
test_createEdits_removeHideCombinator_middle() async {
- Source fooSource = addPackageSource('pkg', 'foo.dart', '');
+ var fooFile = addPackageFile('pkg', 'foo.dart', '');
await createBuilder('''
import 'package:pkg/foo.dart' hide A hide B hide C;
''');
await computeChanges(<ImportedElements>[
- new ImportedElements(fooSource.fullName, '', <String>['B'])
+ new ImportedElements(fooFile.path, '', <String>['B'])
]);
assertChanges('''
import 'package:pkg/foo.dart' hide A hide C;
@@ -334,12 +333,12 @@
}
test_createEdits_removeHideCombinator_only() async {
- Source fooSource = addPackageSource('pkg', 'foo.dart', '');
+ var fooFile = addPackageFile('pkg', 'foo.dart', '');
await createBuilder('''
import 'package:pkg/foo.dart' hide A;
''');
await computeChanges(<ImportedElements>[
- new ImportedElements(fooSource.fullName, '', <String>['A'])
+ new ImportedElements(fooFile.path, '', <String>['A'])
]);
assertChanges('''
import 'package:pkg/foo.dart';
@@ -347,12 +346,12 @@
}
test_createEdits_removeHideCombinator_only_multiple() async {
- Source fooSource = addPackageSource('pkg', 'foo.dart', '');
+ var fooFile = addPackageFile('pkg', 'foo.dart', '');
await createBuilder('''
import 'package:pkg/foo.dart' hide A, B;
''');
await computeChanges(<ImportedElements>[
- new ImportedElements(fooSource.fullName, '', <String>['A', 'B'])
+ new ImportedElements(fooFile.path, '', <String>['A', 'B'])
]);
assertChanges('''
import 'package:pkg/foo.dart';
diff --git a/pkg/analysis_server/test/src/computer/imported_elements_computer_test.dart b/pkg/analysis_server/test/src/computer/imported_elements_computer_test.dart
index 55c106b..8a5dad4 100644
--- a/pkg/analysis_server/test/src/computer/imported_elements_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/imported_elements_computer_test.dart
@@ -24,7 +24,7 @@
setUp() {
super.setUp();
- sourcePath = resourceProvider.convertPath('/p/lib/source.dart');
+ sourcePath = convertPath('/home/test/lib/test.dart');
}
test_dartAsync_noPrefix() async {
@@ -43,7 +43,7 @@
ImportedElements elements2 = elementsList[1];
ImportedElements asyncElements;
ImportedElements coreElements;
- if (elements1.path == convertPath('/lib/core/core.dart')) {
+ if (elements1.path == convertPath('/sdk/lib/core/core.dart')) {
coreElements = elements1;
asyncElements = elements2;
} else {
@@ -51,12 +51,12 @@
asyncElements = elements1;
}
expect(coreElements, isNotNull);
- expect(coreElements.path, convertPath('/lib/core/core.dart'));
+ expect(coreElements.path, convertPath('/sdk/lib/core/core.dart'));
expect(coreElements.prefix, '');
expect(coreElements.elements, unorderedEquals(['String']));
expect(asyncElements, isNotNull);
- expect(asyncElements.path, convertPath('/lib/async/async.dart'));
+ expect(asyncElements.path, convertPath('/sdk/lib/async/async.dart'));
expect(asyncElements.prefix, '');
expect(asyncElements.elements, unorderedEquals(['Future']));
}
@@ -77,7 +77,7 @@
ImportedElements elements2 = elementsList[1];
ImportedElements asyncElements;
ImportedElements coreElements;
- if (elements1.path == convertPath('/lib/core/core.dart')) {
+ if (elements1.path == convertPath('/sdk/lib/core/core.dart')) {
coreElements = elements1;
asyncElements = elements2;
} else {
@@ -85,12 +85,12 @@
asyncElements = elements1;
}
expect(coreElements, isNotNull);
- expect(coreElements.path, convertPath('/lib/core/core.dart'));
+ expect(coreElements.path, convertPath('/sdk/lib/core/core.dart'));
expect(coreElements.prefix, '');
expect(coreElements.elements, unorderedEquals(['String']));
expect(asyncElements, isNotNull);
- expect(asyncElements.path, convertPath('/lib/async/async.dart'));
+ expect(asyncElements.path, convertPath('/sdk/lib/async/async.dart'));
expect(asyncElements.prefix, 'a');
expect(asyncElements.elements, unorderedEquals(['Future']));
}
@@ -108,7 +108,7 @@
expect(elementsList, hasLength(1));
ImportedElements elements = elementsList[0];
expect(elements, isNotNull);
- expect(elements.path, convertPath('/lib/core/core.dart'));
+ expect(elements.path, convertPath('/sdk/lib/core/core.dart'));
expect(elements.prefix, '');
expect(elements.elements, unorderedEquals(['String']));
}
@@ -127,7 +127,7 @@
expect(elementsList, hasLength(1));
ImportedElements elements = elementsList[0];
expect(elements, isNotNull);
- expect(elements.path, convertPath('/lib/core/core.dart'));
+ expect(elements.path, convertPath('/sdk/lib/core/core.dart'));
expect(elements.prefix, 'core');
expect(elements.elements, unorderedEquals(['String']));
}
@@ -146,7 +146,7 @@
expect(elementsList, hasLength(1));
ImportedElements elements = elementsList[0];
expect(elements, isNotNull);
- expect(elements.path, convertPath('/lib/math/math.dart'));
+ expect(elements.path, convertPath('/sdk/lib/math/math.dart'));
expect(elements.prefix, '');
expect(elements.elements, unorderedEquals(['Random']));
}
@@ -170,13 +170,13 @@
ImportedElements mathElements = elementsList[0];
expect(mathElements, isNotNull);
- expect(mathElements.path, convertPath('/lib/math/math.dart'));
+ expect(mathElements.path, convertPath('/sdk/lib/math/math.dart'));
expect(mathElements.prefix, '');
expect(mathElements.elements, unorderedEquals(['Random']));
ImportedElements coreElements = elementsList[1];
expect(coreElements, isNotNull);
- expect(coreElements.path, convertPath('/lib/core/core.dart'));
+ expect(coreElements.path, convertPath('/sdk/lib/core/core.dart'));
expect(coreElements.prefix, '');
expect(coreElements.elements, unorderedEquals(['String', 'print']));
}
@@ -236,7 +236,7 @@
}
test_package_multipleInSame() async {
- addPackageSource('foo', 'foo.dart', '''
+ addPackageFile('foo', 'foo.dart', '''
class A {
static String a = '';
}
@@ -256,13 +256,13 @@
expect(elementsList, hasLength(1));
ImportedElements elements = elementsList[0];
expect(elements, isNotNull);
- expect(elements.path, convertPath('/pubcache/foo/lib/foo.dart'));
+ expect(elements.path, convertPath('/.pub-cache/foo/lib/foo.dart'));
expect(elements.prefix, '');
expect(elements.elements, unorderedEquals(['A', 'B']));
}
test_package_noPrefix() async {
- addPackageSource('foo', 'foo.dart', '''
+ addPackageFile('foo', 'foo.dart', '''
class Foo {
static String first = '';
}
@@ -279,13 +279,13 @@
expect(elementsList, hasLength(1));
ImportedElements elements = elementsList[0];
expect(elements, isNotNull);
- expect(elements.path, convertPath('/pubcache/foo/lib/foo.dart'));
+ expect(elements.path, convertPath('/.pub-cache/foo/lib/foo.dart'));
expect(elements.prefix, '');
expect(elements.elements, unorderedEquals(['Foo']));
}
test_package_prefix_selected() async {
- addPackageSource('foo', 'foo.dart', '''
+ addPackageFile('foo', 'foo.dart', '''
class Foo {
static String first = '';
}
@@ -302,13 +302,13 @@
expect(elementsList, hasLength(1));
ImportedElements elements = elementsList[0];
expect(elements, isNotNull);
- expect(elements.path, convertPath('/pubcache/foo/lib/foo.dart'));
+ expect(elements.path, convertPath('/.pub-cache/foo/lib/foo.dart'));
expect(elements.prefix, 'f');
expect(elements.elements, unorderedEquals(['Foo']));
}
test_package_prefix_unselected() async {
- addPackageSource('foo', 'foo.dart', '''
+ addPackageFile('foo', 'foo.dart', '''
class Foo {
static String first = '';
}
@@ -325,13 +325,13 @@
expect(elementsList, hasLength(1));
ImportedElements elements = elementsList[0];
expect(elements, isNotNull);
- expect(elements.path, convertPath('/pubcache/foo/lib/foo.dart'));
+ expect(elements.path, convertPath('/.pub-cache/foo/lib/foo.dart'));
expect(elements.prefix, '');
expect(elements.elements, unorderedEquals(['Foo']));
}
test_package_prefixedAndNot() async {
- addPackageSource('foo', 'foo.dart', '''
+ addPackageFile('foo', 'foo.dart', '''
class Foo {
static String first = '';
static String second = '';
@@ -362,12 +362,13 @@
}
expect(notPrefixedElements, isNotNull);
- expect(notPrefixedElements.path, convertPath('/pubcache/foo/lib/foo.dart'));
+ expect(
+ notPrefixedElements.path, convertPath('/.pub-cache/foo/lib/foo.dart'));
expect(notPrefixedElements.prefix, '');
expect(notPrefixedElements.elements, unorderedEquals(['Foo']));
expect(prefixedElements, isNotNull);
- expect(prefixedElements.path, convertPath('/pubcache/foo/lib/foo.dart'));
+ expect(prefixedElements.path, convertPath('/.pub-cache/foo/lib/foo.dart'));
expect(prefixedElements.prefix, 'f');
expect(prefixedElements.elements, unorderedEquals(['Foo']));
}
@@ -392,7 +393,7 @@
Future<List<ImportedElements>> _computeElements(
String sourceContent, int offset, int length) async {
newFile(sourcePath, content: sourceContent);
- ResolveResult result = await driver.getResult(sourcePath);
+ ResolvedUnitResult result = await session.getResolvedUnit(sourcePath);
ImportedElementsComputer computer =
new ImportedElementsComputer(result.unit, offset, length);
return computer.compute();
diff --git a/pkg/analysis_server/test/src/computer/outline_computer_test.dart b/pkg/analysis_server/test/src/computer/outline_computer_test.dart
index 340045a..eb45aad 100644
--- a/pkg/analysis_server/test/src/computer/outline_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/outline_computer_test.dart
@@ -5,7 +5,6 @@
import 'dart:async';
import 'package:analysis_server/src/computer/computer_outline.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:meta/meta.dart';
import 'package:test/test.dart';
@@ -27,15 +26,15 @@
@override
void setUp() {
super.setUp();
- testPath = resourceProvider.convertPath('/test.dart');
+ testPath = convertPath('/home/test/lib/test.dart');
}
Future<Outline> _computeOutline(String code) async {
testCode = code;
newFile(testPath, content: code);
- AnalysisResult analysisResult = await driver.getResult(testPath);
+ var resolveResult = await session.getResolvedUnit(testPath);
return new DartUnitOutlineComputer(
- testPath, analysisResult.lineInfo, analysisResult.unit,
+ testPath, resolveResult.lineInfo, resolveResult.unit,
withBasicFlutter: true)
.compute();
}
@@ -558,7 +557,7 @@
}
test_isTest_isTestGroup() async {
- addMetaPackageSource();
+ addMetaPackage();
Outline outline = await _computeOutline('''
import 'package:meta/meta.dart';
@@ -1057,6 +1056,7 @@
Outline unitOutline = await _computeOutline('''
typedef String FTA<K, V>(int i, String s);
typedef FTB(int p);
+typedef GTAF<T> = void Function<S>(T t, S s);
class A<T> {}
class B {}
class CTA<T> = A<T> with B;
@@ -1067,7 +1067,7 @@
set propB(int v) {}
''');
List<Outline> topOutlines = unitOutline.children;
- expect(topOutlines, hasLength(10));
+ expect(topOutlines, hasLength(11));
// FTA
{
Outline outline = topOutlines[0];
@@ -1098,9 +1098,24 @@
expect(element.parameters, "(int p)");
expect(element.returnType, "");
}
+ // GenericTypeAlias - function
+ {
+ Outline outline = topOutlines[2];
+ Element element = outline.element;
+ expect(element.kind, ElementKind.FUNCTION_TYPE_ALIAS);
+ expect(element.name, "GTAF");
+ expect(element.typeParameters, '<T>');
+ {
+ Location location = element.location;
+ expect(location.offset, testCode.indexOf("GTAF<T> ="));
+ expect(location.length, "GTAF".length);
+ }
+ expect(element.parameters, "(T t, S s)");
+ expect(element.returnType, "void");
+ }
// CTA
{
- Outline outline = topOutlines[4];
+ Outline outline = topOutlines[5];
Element element = outline.element;
expect(element.kind, ElementKind.CLASS_TYPE_ALIAS);
expect(element.name, "CTA");
@@ -1115,7 +1130,7 @@
}
// CTB
{
- Outline outline = topOutlines[5];
+ Outline outline = topOutlines[6];
Element element = outline.element;
expect(element.kind, ElementKind.CLASS_TYPE_ALIAS);
expect(element.name, 'CTB');
@@ -1124,7 +1139,7 @@
}
// fA
{
- Outline outline = topOutlines[6];
+ Outline outline = topOutlines[7];
Element element = outline.element;
expect(element.kind, ElementKind.FUNCTION);
expect(element.name, "fA");
@@ -1138,7 +1153,7 @@
}
// fB
{
- Outline outline = topOutlines[7];
+ Outline outline = topOutlines[8];
Element element = outline.element;
expect(element.kind, ElementKind.FUNCTION);
expect(element.name, "fB");
@@ -1152,7 +1167,7 @@
}
// propA
{
- Outline outline = topOutlines[8];
+ Outline outline = topOutlines[9];
Element element = outline.element;
expect(element.kind, ElementKind.GETTER);
expect(element.name, "propA");
@@ -1166,7 +1181,7 @@
}
// propB
{
- Outline outline = topOutlines[9];
+ Outline outline = topOutlines[10];
Element element = outline.element;
expect(element.kind, ElementKind.SETTER);
expect(element.name, "propB");
diff --git a/pkg/analysis_server/test/src/domains/execution/completion_test.dart b/pkg/analysis_server/test/src/domains/execution/completion_test.dart
index 4ba0ecd..41529c6 100644
--- a/pkg/analysis_server/test/src/domains/execution/completion_test.dart
+++ b/pkg/analysis_server/test/src/domains/execution/completion_test.dart
@@ -25,7 +25,7 @@
RuntimeCompletionResult result;
void addContextFile(String content) {
- contextFile = convertPath('/test/lib/context.dart');
+ contextFile = convertPath('/home/test/lib/context.dart');
addSource(contextFile, content);
contextOffset = content.indexOf('// context line');
@@ -131,13 +131,13 @@
}
test_inPart() async {
- addSource('/test/lib/a.dart', r'''
+ addSource('/home/test/lib/a.dart', r'''
part 'b.dart';
part 'context.dart';
int a;
''');
- addSource('/test/lib/b.dart', r'''
+ addSource('/home/test/lib/b.dart', r'''
part of 'a.dart';
double b;
diff --git a/pkg/analysis_server/test/src/domains/execution/test_all.dart b/pkg/analysis_server/test/src/domains/execution/test_all.dart
new file mode 100644
index 0000000..20e6141
--- /dev/null
+++ b/pkg/analysis_server/test/src/domains/execution/test_all.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2018, 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:test_reflective_loader/test_reflective_loader.dart';
+
+import 'completion_test.dart' as completion_test;
+
+main() {
+ defineReflectiveSuite(() {
+ completion_test.main();
+ });
+}
diff --git a/pkg/analysis_server/test/src/domains/test_all.dart b/pkg/analysis_server/test/src/domains/test_all.dart
new file mode 100644
index 0000000..81a4c82
--- /dev/null
+++ b/pkg/analysis_server/test/src/domains/test_all.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2018, 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:test_reflective_loader/test_reflective_loader.dart';
+
+import 'execution/test_all.dart' as execution_test;
+
+main() {
+ defineReflectiveSuite(() {
+ execution_test.main();
+ });
+}
diff --git a/pkg/analysis_server/test/src/flutter/flutter_correction_test.dart b/pkg/analysis_server/test/src/flutter/flutter_correction_test.dart
index 4501d68..1d7ba263 100644
--- a/pkg/analysis_server/test/src/flutter/flutter_correction_test.dart
+++ b/pkg/analysis_server/test/src/flutter/flutter_correction_test.dart
@@ -125,11 +125,9 @@
void _createCorrections() {
corrections = new FlutterCorrections(
- file: testFile,
- fileContent: testCode,
- selectionOffset: offset,
- selectionLength: length,
- session: testAnalysisResult.session,
- unit: testUnit);
+ resolveResult: testAnalysisResult,
+ selectionOffset: offset,
+ selectionLength: length,
+ );
}
}
diff --git a/pkg/analysis_server/test/src/flutter/flutter_outline_computer_test.dart b/pkg/analysis_server/test/src/flutter/flutter_outline_computer_test.dart
index e4b62c4..947fb79 100644
--- a/pkg/analysis_server/test/src/flutter/flutter_outline_computer_test.dart
+++ b/pkg/analysis_server/test/src/flutter/flutter_outline_computer_test.dart
@@ -6,7 +6,7 @@
import 'package:analysis_server/src/flutter/flutter_outline_computer.dart';
import 'package:analysis_server/src/protocol_server.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -22,13 +22,13 @@
class FlutterOutlineComputerTest extends AbstractContextTest {
String testPath;
String testCode;
- AnalysisResult analysisResult;
+ ResolvedUnitResult resolveResult;
FlutterOutlineComputer computer;
@override
void setUp() {
super.setUp();
- testPath = resourceProvider.convertPath('/test.dart');
+ testPath = convertPath('/home/test/lib/test.dart');
addFlutterPackage();
}
@@ -288,7 +288,7 @@
}
test_parentAssociationLabel() async {
- newFile('/a.dart', content: r'''
+ newFile('/home/test/lib/a.dart', content: r'''
import 'package:flutter/widgets.dart';
class WidgetA extends StatelessWidget {
@@ -359,7 +359,7 @@
test_render_BAD_part() async {
// Use test.dart as a part of a library.
// Add the library to the driver so that it is analyzed before the part.
- var libPath = newFile('/test_lib.dart', content: r'''
+ var libPath = newFile('/home/test/lib/test_lib.dart', content: r'''
part 'test.dart';
import 'package:flutter/widgets.dart';
''').path;
@@ -379,7 +379,7 @@
''');
// Analysis is successful, no errors.
- expect(analysisResult.errors, isEmpty);
+ expect(resolveResult.errors, isEmpty);
// No instrumentation, because not a library.
expect(computer.instrumentedCode, isNull);
@@ -431,8 +431,7 @@
}
test_render_instrumentedCode_rewriteUri_file() async {
- testPath = resourceProvider.convertPath('/home/user/test/test.dart');
- var libFile = newFile('/home/user/test/my_lib.dart', content: '');
+ newFile('/home/test/lib/my_lib.dart');
await _computeOutline('''
import 'package:flutter/widgets.dart';
@@ -451,7 +450,7 @@
computer.instrumentedCode,
'''
import 'package:flutter/widgets.dart';
-import '${libFile.toUri()}';
+import 'package:test/my_lib.dart';
class MyWidget extends StatelessWidget {
MyWidget.forDesignTime();
@@ -466,11 +465,7 @@
}
test_render_instrumentedCode_rewriteUri_package() async {
- packageMap['test'] = [newFolder('/home/user/test/lib')];
-
- testPath = resourceProvider.convertPath('/home/user/test/lib/test.dart');
- newFile('/home/user/test/lib/my_lib.dart', content: '');
- configureDriver();
+ newFile('/home/test/lib/my_lib.dart');
await _computeOutline('''
import 'package:flutter/widgets.dart';
@@ -630,9 +625,9 @@
Future<FlutterOutline> _computeOutline(String code) async {
testCode = code;
newFile(testPath, content: code);
- analysisResult = await driver.getResult(testPath);
- computer = new FlutterOutlineComputer(
- testPath, testCode, analysisResult.lineInfo, analysisResult.unit);
+ resolveResult = await session.getResolvedUnit(testPath);
+ computer = new FlutterOutlineComputer(testPath, testCode,
+ resolveResult.lineInfo, resolveResult.unit, resolveResult.typeProvider);
return computer.compute();
}
diff --git a/pkg/analysis_server/test/src/lsp/lsp_packet_transformer_test.dart b/pkg/analysis_server/test/src/lsp/lsp_packet_transformer_test.dart
new file mode 100644
index 0000000..884a8cf
--- /dev/null
+++ b/pkg/analysis_server/test/src/lsp/lsp_packet_transformer_test.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2018, 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:convert';
+
+import 'package:analysis_server/src/lsp/lsp_packet_transformer.dart';
+import 'package:test/test.dart';
+
+main() {
+ group('lsp_packet_transformer', () {
+ test('transforms data received as individual bytes', () async {
+ final payload = '{ json payload }';
+ final lspPacket = makeLspPacket(payload);
+ final output = await new Stream.fromIterable([lspPacket])
+ .transform(new LspPacketTransformer())
+ .toList();
+ expect(output, equals([payload]));
+ });
+
+ test('transforms data received in chunks', () async {
+ final payload = '{ json\n payload\n }';
+ final lspPacket = makeLspPacket(payload);
+ // Separate each byte into it's own "packet" to simulate chunked data
+ // where all the bytes for a single LSP packet don't arrive in one
+ // item to the stream.
+ final dataPackets = lspPacket.map((b) => [b]);
+ final output = await new Stream.fromIterable(dataPackets)
+ .transform(new LspPacketTransformer())
+ .toList();
+ expect(output, equals([payload]));
+ });
+
+ test('handles unicode characters', () async {
+ // This file is saved as UTF8.
+ final payload = '{ json payload 🎉 }';
+ final lspPacket = makeLspPacket(payload);
+ final output = await new Stream.fromIterable([lspPacket])
+ .transform(new LspPacketTransformer())
+ .toList();
+ expect(output, equals([payload]));
+ });
+ });
+}
+
+List<int> makeLspPacket(String json, [String contentType]) {
+ final utf8EncodedBody = utf8.encode(json);
+ final header = 'Content-Length: ${utf8EncodedBody.length}\r\n'
+ 'Content-Type: application/vscode-jsonrpc; charset=utf-8\r\n\r\n';
+ final asciiEncodedHeader = ascii.encode(header);
+
+ return asciiEncodedHeader.followedBy(utf8EncodedBody).toList();
+}
diff --git a/pkg/analysis_server/test/src/plugin/plugin_locator_test.dart b/pkg/analysis_server/test/src/plugin/plugin_locator_test.dart
index db3d3f9..a01ca1f 100644
--- a/pkg/analysis_server/test/src/plugin/plugin_locator_test.dart
+++ b/pkg/analysis_server/test/src/plugin/plugin_locator_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// 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.
@@ -14,7 +14,7 @@
}
@reflectiveTest
-class PluginLocatorTest extends Object with ResourceProviderMixin {
+class PluginLocatorTest with ResourceProviderMixin {
String packageRoot;
String pubspecPath;
String defaultDirPath;
diff --git a/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart b/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
index 6837470..186e284 100644
--- a/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
+++ b/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// 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.
@@ -405,7 +405,7 @@
}
@reflectiveTest
-class PluginManagerTest extends Object with ResourceProviderMixin {
+class PluginManagerTest with ResourceProviderMixin {
String byteStorePath;
String sdkPath;
TestNotificationManager notificationManager;
@@ -535,7 +535,7 @@
}
@reflectiveTest
-class PluginSessionTest extends Object with ResourceProviderMixin {
+class PluginSessionTest with ResourceProviderMixin {
TestNotificationManager notificationManager;
String pluginPath;
String executionPath;
diff --git a/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart b/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
index 058ee15..ca02919 100644
--- a/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
+++ b/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// 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.
@@ -8,24 +8,24 @@
import 'package:analysis_server/src/plugin/plugin_locator.dart';
import 'package:analysis_server/src/plugin/plugin_manager.dart';
import 'package:analysis_server/src/plugin/plugin_watcher.dart';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/context/context_root.dart';
+import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
+import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/dart/analysis/session.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/source/package_map_resolver.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
-import 'package:analyzer/src/dart/analysis/byte_store.dart';
-import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:path/path.dart' as path;
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../mock_sdk.dart';
-
main() {
defineReflectiveSuite(() {
defineReflectiveTests(PluginWatcherTest);
@@ -33,7 +33,7 @@
}
@reflectiveTest
-class PluginWatcherTest extends Object with ResourceProviderMixin {
+class PluginWatcherTest with ResourceProviderMixin {
TestPluginManager manager;
PluginWatcher watcher;
@@ -119,7 +119,7 @@
AnalysisSession currentSession;
AnalysisOptionsImpl analysisOptions = new AnalysisOptionsImpl();
- final _resultController = new StreamController<AnalysisResult>();
+ final _resultController = new StreamController<ResolvedUnitResult>();
TestDriver(this.resourceProvider, ContextRoot contextRoot) {
path.Context pathContext = resourceProvider.pathContext;
@@ -147,12 +147,11 @@
currentSession = new AnalysisSessionImpl(this);
}
- Stream<AnalysisResult> get results => _resultController.stream;
+ Stream<ResolvedUnitResult> get results => _resultController.stream;
Future<void> computeResult(String uri) {
FileState file = fsState.getFileForUri(Uri.parse(uri));
- AnalysisResult result = new AnalysisResult(this, null, file.path, null,
- true, null, null, false, null, null, null, null);
+ var result = new _ResolvedUnitResultMock(currentSession, file.path);
_resultController.add(result);
return new Future.delayed(new Duration(milliseconds: 1));
}
@@ -182,3 +181,15 @@
removedContextRoots.add(contextRoot);
}
}
+
+class _ResolvedUnitResultMock implements ResolvedUnitResult {
+ @override
+ final AnalysisSession session;
+
+ @override
+ final String path;
+
+ _ResolvedUnitResultMock(this.session, this.path);
+
+ noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/add_type_annotation_test.dart b/pkg/analysis_server/test/src/services/correction/assist/add_type_annotation_test.dart
new file mode 100644
index 0000000..9d1e8fb
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/add_type_annotation_test.dart
@@ -0,0 +1,576 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AddTypeAnnotationTest);
+ });
+}
+
+@reflectiveTest
+class AddTypeAnnotationTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.ADD_TYPE_ANNOTATION;
+
+ test_classField_final() async {
+ await resolveTestUnit('''
+class A {
+ final f = 0;
+}
+''');
+ await assertHasAssistAt('final ', '''
+class A {
+ final int f = 0;
+}
+''');
+ }
+
+ test_classField_int() async {
+ await resolveTestUnit('''
+class A {
+ var f = 0;
+}
+''');
+ await await assertHasAssistAt('var ', '''
+class A {
+ int f = 0;
+}
+''');
+ }
+
+ test_declaredIdentifier() async {
+ await resolveTestUnit('''
+main(List<String> items) {
+ for (var item in items) {
+ }
+}
+''');
+ // on identifier
+ await assertHasAssistAt('item in', '''
+main(List<String> items) {
+ for (String item in items) {
+ }
+}
+''');
+ // on "for"
+ await assertHasAssistAt('for (', '''
+main(List<String> items) {
+ for (String item in items) {
+ }
+}
+''');
+ }
+
+ test_declaredIdentifier_addImport_dartUri() async {
+ addSource('/home/test/lib/my_lib.dart', r'''
+import 'dart:collection';
+List<HashMap<String, int>> getMap() => null;
+''');
+ await resolveTestUnit('''
+import 'my_lib.dart';
+main() {
+ for (var map in getMap()) {
+ }
+}
+''');
+ await assertHasAssistAt('map in', '''
+import 'dart:collection';
+
+import 'my_lib.dart';
+main() {
+ for (HashMap<String, int> map in getMap()) {
+ }
+}
+''');
+ }
+
+ test_declaredIdentifier_final() async {
+ await resolveTestUnit('''
+main(List<String> items) {
+ for (final item in items) {
+ }
+}
+''');
+ await assertHasAssistAt('item in', '''
+main(List<String> items) {
+ for (final String item in items) {
+ }
+}
+''');
+ }
+
+ test_declaredIdentifier_generic() async {
+ await resolveTestUnit('''
+class A<T> {
+ main(List<List<T>> items) {
+ for (var item in items) {
+ }
+ }
+}
+''');
+ await assertHasAssistAt('item in', '''
+class A<T> {
+ main(List<List<T>> items) {
+ for (List<T> item in items) {
+ }
+ }
+}
+''');
+ }
+
+ test_declaredIdentifier_hasTypeAnnotation() async {
+ await resolveTestUnit('''
+main(List<String> items) {
+ for (String item in items) {
+ }
+}
+''');
+ await assertNoAssistAt('item in');
+ }
+
+ test_declaredIdentifier_inForEachBody() async {
+ await resolveTestUnit('''
+main(List<String> items) {
+ for (var item in items) {
+ 42;
+ }
+}
+''');
+ await assertNoAssistAt('42;');
+ }
+
+ test_declaredIdentifier_unknownType() async {
+ verifyNoTestUnitErrors = false;
+ await resolveTestUnit('''
+main() {
+ for (var item in unknownList) {
+ }
+}
+''');
+ await assertNoAssistAt('item in');
+ }
+
+ test_local_addImport_dartUri() async {
+ addSource('/home/test/lib/my_lib.dart', r'''
+import 'dart:collection';
+HashMap<String, int> getMap() => null;
+''');
+ await resolveTestUnit('''
+import 'my_lib.dart';
+main() {
+ var v = getMap();
+}
+''');
+ await assertHasAssistAt('v =', '''
+import 'dart:collection';
+
+import 'my_lib.dart';
+main() {
+ HashMap<String, int> v = getMap();
+}
+''');
+ }
+
+ test_local_addImport_notLibraryUnit() async {
+ addSource('/home/test/lib/my_lib.dart', r'''
+import 'dart:collection';
+HashMap<String, int> getMap() => null;
+''');
+
+ var appCode = r'''
+library my_app;
+import 'my_lib.dart';
+part 'test.dart';
+''';
+ var partCode = r'''
+part of my_app;
+main() {
+ var /*caret*/v = getMap();
+}
+''';
+
+ var appPath = convertPath('/home/test/lib/app.dart');
+ addSource(appPath, appCode);
+ addSource(testFile, partCode);
+ await resolveTestUnit(partCode);
+
+ await assertHasAssist('''
+part of my_app;
+main() {
+ HashMap<String, int> /*caret*/v = getMap();
+}
+''', additionallyChangedFiles: {
+ appPath: [
+ appCode,
+ '''
+library my_app;
+import 'dart:collection';
+
+import 'my_lib.dart';
+part 'test.dart';
+'''
+ ]
+ });
+ }
+
+ test_local_addImport_relUri() async {
+ testFile = convertPath('/home/test/bin/test.dart');
+ addSource('/home/test/bin/aa/bbb/lib_a.dart', r'''
+class MyClass {}
+''');
+ addSource('/home/test/bin/ccc/lib_b.dart', r'''
+import '../aa/bbb/lib_a.dart';
+MyClass newMyClass() => null;
+''');
+ await resolveTestUnit('''
+import 'ccc/lib_b.dart';
+main() {
+ var v = newMyClass();
+}
+''');
+ await assertHasAssistAt('v =', '''
+import 'aa/bbb/lib_a.dart';
+import 'ccc/lib_b.dart';
+main() {
+ MyClass v = newMyClass();
+}
+''');
+ }
+
+ test_local_bottom() async {
+ await resolveTestUnit('''
+main() {
+ var v = throw 42;
+}
+''');
+ await assertNoAssistAt('var ');
+ }
+
+ test_local_Function() async {
+ await resolveTestUnit('''
+main() {
+ var v = () => 1;
+}
+''');
+ await assertHasAssistAt('v =', '''
+main() {
+ int Function() v = () => 1;
+}
+''');
+ }
+
+ test_local_generic_literal() async {
+ await resolveTestUnit('''
+class A {
+ main(List<int> items) {
+ var v = items;
+ }
+}
+''');
+ await assertHasAssistAt('v =', '''
+class A {
+ main(List<int> items) {
+ List<int> v = items;
+ }
+}
+''');
+ }
+
+ test_local_generic_local() async {
+ await resolveTestUnit('''
+class A<T> {
+ main(List<T> items) {
+ var v = items;
+ }
+}
+''');
+ await assertHasAssistAt('v =', '''
+class A<T> {
+ main(List<T> items) {
+ List<T> v = items;
+ }
+}
+''');
+ }
+
+ test_local_hasTypeAnnotation() async {
+ await resolveTestUnit('''
+main() {
+ int v = 42;
+}
+''');
+ await assertNoAssistAt(' = 42');
+ }
+
+ test_local_int() async {
+ await resolveTestUnit('''
+main() {
+ var v = 0;
+}
+''');
+ await assertHasAssistAt('v =', '''
+main() {
+ int v = 0;
+}
+''');
+ }
+
+ test_local_List() async {
+ await resolveTestUnit('''
+main() {
+ var v = <String>[];
+}
+''');
+ await assertHasAssistAt('v =', '''
+main() {
+ List<String> v = <String>[];
+}
+''');
+ }
+
+ test_local_localType() async {
+ await resolveTestUnit('''
+class C {}
+C f() => null;
+main() {
+ var x = f();
+}
+''');
+ await assertHasAssistAt('x =', '''
+class C {}
+C f() => null;
+main() {
+ C x = f();
+}
+''');
+ }
+
+ test_local_multiple() async {
+ await resolveTestUnit('''
+main() {
+ var a = 1, b = '';
+}
+''');
+ await assertNoAssistAt('var ');
+ }
+
+ test_local_noValue() async {
+ verifyNoTestUnitErrors = false;
+ await resolveTestUnit('''
+main() {
+ var v;
+}
+''');
+ await assertNoAssistAt('var ');
+ }
+
+ test_local_null() async {
+ await resolveTestUnit('''
+main() {
+ var v = null;
+}
+''');
+ await assertNoAssistAt('var ');
+ }
+
+ test_local_onInitializer() async {
+ await resolveTestUnit('''
+main() {
+ var abc = 0;
+}
+''');
+ await assertNoAssistAt('0;');
+ }
+
+ test_local_onName() async {
+ await resolveTestUnit('''
+main() {
+ var abc = 0;
+}
+''');
+ await assertHasAssistAt('bc', '''
+main() {
+ int abc = 0;
+}
+''');
+ }
+
+ test_local_onVar() async {
+ await resolveTestUnit('''
+main() {
+ var v = 0;
+}
+''');
+ await assertHasAssistAt('var ', '''
+main() {
+ int v = 0;
+}
+''');
+ }
+
+ test_local_unknown() async {
+ verifyNoTestUnitErrors = false;
+ await resolveTestUnit('''
+main() {
+ var v = unknownVar;
+}
+''');
+ await assertNoAssistAt('var ');
+ }
+
+ test_parameter() async {
+ await resolveTestUnit('''
+foo(f(int p)) {}
+main() {
+ foo((test) {});
+}
+''');
+ await assertHasAssistAt('test', '''
+foo(f(int p)) {}
+main() {
+ foo((int test) {});
+}
+''');
+ }
+
+ test_parameter_hasExplicitType() async {
+ await resolveTestUnit('''
+foo(f(int p)) {}
+main() {
+ foo((num test) {});
+}
+''');
+ await assertNoAssistAt('test');
+ }
+
+ test_parameter_noPropagatedType() async {
+ await resolveTestUnit('''
+foo(f(p)) {}
+main() {
+ foo((test) {});
+}
+''');
+ await assertNoAssistAt('test');
+ }
+
+ test_privateType_closureParameter() async {
+ addSource('/home/test/lib/my_lib.dart', '''
+library my_lib;
+class A {}
+class _B extends A {}
+foo(f(_B p)) {}
+''');
+ await resolveTestUnit('''
+import 'my_lib.dart';
+main() {
+ foo((test) {});
+}
+ ''');
+ await assertNoAssistAt('test)');
+ }
+
+ test_privateType_declaredIdentifier() async {
+ addSource('/home/test/lib/my_lib.dart', '''
+library my_lib;
+class A {}
+class _B extends A {}
+List<_B> getValues() => [];
+''');
+ await resolveTestUnit('''
+import 'my_lib.dart';
+class A<T> {
+ main() {
+ for (var item in getValues()) {
+ }
+ }
+}
+''');
+ await assertNoAssistAt('var item');
+ }
+
+ test_privateType_list() async {
+ // This is now failing because we're suggesting "List" rather than nothing.
+ // Is it really better to produce nothing?
+ addSource('/home/test/lib/my_lib.dart', '''
+library my_lib;
+class A {}
+class _B extends A {}
+List<_B> getValues() => [];
+''');
+ await resolveTestUnit('''
+import 'my_lib.dart';
+main() {
+ var v = getValues();
+}
+''');
+ await assertHasAssistAt('var ', '''
+import 'my_lib.dart';
+main() {
+ List v = getValues();
+}
+''');
+ }
+
+ test_privateType_sameLibrary() async {
+ await resolveTestUnit('''
+class _A {}
+_A getValue() => new _A();
+main() {
+ var v = getValue();
+}
+''');
+ await assertHasAssistAt('var ', '''
+class _A {}
+_A getValue() => new _A();
+main() {
+ _A v = getValue();
+}
+''');
+ }
+
+ test_privateType_variable() async {
+ addSource('/home/test/lib/my_lib.dart', '''
+library my_lib;
+class A {}
+class _B extends A {}
+_B getValue() => new _B();
+''');
+ await resolveTestUnit('''
+import 'my_lib.dart';
+main() {
+ var v = getValue();
+}
+''');
+ await assertNoAssistAt('var ');
+ }
+
+ test_topLevelField_int() async {
+ await resolveTestUnit('''
+var V = 0;
+''');
+ await assertHasAssistAt('var ', '''
+int V = 0;
+''');
+ }
+
+ test_topLevelField_multiple() async {
+ await resolveTestUnit('''
+var A = 1, V = '';
+''');
+ await assertNoAssistAt('var ');
+ }
+
+ test_topLevelField_noValue() async {
+ await resolveTestUnit('''
+var V;
+''');
+ await assertNoAssistAt('var ');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/assign_to_local_variable_test.dart b/pkg/analysis_server/test/src/services/correction/assist/assign_to_local_variable_test.dart
new file mode 100644
index 0000000..1668ea4
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/assign_to_local_variable_test.dart
@@ -0,0 +1,100 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AssignToLocalVariableTest);
+ });
+}
+
+@reflectiveTest
+class AssignToLocalVariableTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.ASSIGN_TO_LOCAL_VARIABLE;
+
+ test_alreadyAssignment() async {
+ await resolveTestUnit('''
+main() {
+ var vvv;
+ vvv = 42;
+}
+''');
+ await assertNoAssistAt('vvv =');
+ }
+
+ test_inClosure() async {
+ await resolveTestUnit(r'''
+main() {
+ print(() {
+ 12345;
+ });
+}
+''');
+ await assertHasAssistAt('345', '''
+main() {
+ print(() {
+ var i = 12345;
+ });
+}
+''');
+ }
+
+ test_invocation() async {
+ await resolveTestUnit('''
+main() {
+ List<int> bytes;
+ readBytes();
+}
+List<int> readBytes() => <int>[];
+''');
+ await assertHasAssistAt('readBytes();', '''
+main() {
+ List<int> bytes;
+ var readBytes = readBytes();
+}
+List<int> readBytes() => <int>[];
+''');
+ assertLinkedGroup(
+ 0,
+ ['readBytes = '],
+ expectedSuggestions(LinkedEditSuggestionKind.VARIABLE,
+ ['list', 'bytes2', 'readBytes']));
+ }
+
+ test_invocationArgument() async {
+ await resolveTestUnit(r'''
+main() {
+ f(12345);
+}
+void f(p) {}
+''');
+ await assertNoAssistAt('345');
+ }
+
+ test_throw() async {
+ await resolveTestUnit('''
+main() {
+ throw 42;
+}
+''');
+ await assertNoAssistAt('throw ');
+ }
+
+ test_void() async {
+ await resolveTestUnit('''
+main() {
+ f();
+}
+void f() {}
+''');
+ await assertNoAssistAt('f();');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/assist_processor.dart b/pkg/analysis_server/test/src/services/correction/assist/assist_processor.dart
new file mode 100644
index 0000000..450bc7e
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/assist_processor.dart
@@ -0,0 +1,178 @@
+// Copyright (c) 2018, 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/plugin/edit/assist/assist_core.dart';
+import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analysis_server/src/services/correction/assist_internal.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart'
+ hide AnalysisError;
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test/test.dart';
+
+import '../../../../abstract_single_unit.dart';
+
+/// A base class defining support for writing assist processor tests.
+abstract class AssistProcessorTest extends AbstractSingleUnitTest {
+ int _offset;
+ int _length;
+
+ SourceChange _change;
+ String _resultCode;
+
+ /// Return the kind of assist expected by this class.
+ AssistKind get kind;
+
+ void assertExitPosition({String before, String after}) {
+ Position exitPosition = _change.selection;
+ expect(exitPosition, isNotNull);
+ expect(exitPosition.file, testFile);
+ if (before != null) {
+ expect(exitPosition.offset, _resultCode.indexOf(before));
+ } else if (after != null) {
+ expect(exitPosition.offset, _resultCode.indexOf(after) + after.length);
+ } else {
+ fail("One of 'before' or 'after' expected.");
+ }
+ }
+
+ /// Asserts that there is an assist of the given [kind] at [_offset] which
+ /// produces the [expected] code when applied to [testCode]. The map of
+ /// [additionallyChangedFiles] can be used to test assists that can modify
+ /// more than the test file. The keys are expected to be the paths to the
+ /// files that are modified (other than the test file) and the values are
+ /// pairs of source code: the states of the code before and after the edits
+ /// have been applied.
+ Future<void> assertHasAssist(String expected,
+ {Map<String, List<String>> additionallyChangedFiles}) async {
+ _setSelection();
+ Assist assist = await _assertHasAssist();
+ _change = assist.change;
+ expect(_change.id, kind.id);
+ // apply to "file"
+ List<SourceFileEdit> fileEdits = _change.edits;
+ if (additionallyChangedFiles == null) {
+ expect(fileEdits, hasLength(1));
+ _resultCode = SourceEdit.applySequence(testCode, _change.edits[0].edits);
+ expect(_resultCode, expected);
+ } else {
+ expect(fileEdits, hasLength(additionallyChangedFiles.length + 1));
+ _resultCode = SourceEdit.applySequence(
+ testCode, _change.getFileEdit(testFile).edits);
+ expect(_resultCode, expected);
+ for (String filePath in additionallyChangedFiles.keys) {
+ List<String> pair = additionallyChangedFiles[filePath];
+ String resultCode = SourceEdit.applySequence(
+ pair[0], _change.getFileEdit(filePath).edits);
+ expect(resultCode, pair[1]);
+ }
+ }
+ }
+
+ /// Asserts that there is an [Assist] of the given [kind] at the offset of the
+ /// given [snippet] which produces the [expected] code when applied to [testCode].
+ Future<void> assertHasAssistAt(String snippet, String expected,
+ {int length = 0}) async {
+ _offset = findOffset(snippet);
+ _length = length;
+ Assist assist = await _assertHasAssist();
+ _change = assist.change;
+ expect(_change.id, kind.id);
+ // apply to "file"
+ List<SourceFileEdit> fileEdits = _change.edits;
+ expect(fileEdits, hasLength(1));
+ _resultCode = SourceEdit.applySequence(testCode, _change.edits[0].edits);
+ expect(_resultCode, expected);
+ }
+
+ void assertLinkedGroup(int groupIndex, List<String> expectedStrings,
+ [List<LinkedEditSuggestion> expectedSuggestions]) {
+ LinkedEditGroup group = _change.linkedEditGroups[groupIndex];
+ List<Position> expectedPositions = _findResultPositions(expectedStrings);
+ expect(group.positions, unorderedEquals(expectedPositions));
+ if (expectedSuggestions != null) {
+ expect(group.suggestions, unorderedEquals(expectedSuggestions));
+ }
+ }
+
+ /// Asserts that there is no [Assist] of the given [kind] at [_offset].
+ Future<void> assertNoAssist() async {
+ _setSelection();
+ List<Assist> assists = await _computeAssists();
+ for (Assist assist in assists) {
+ if (assist.kind == kind) {
+ fail('Unexpected assist $kind in\n${assists.join('\n')}');
+ }
+ }
+ }
+
+ /// Asserts that there is no [Assist] of the given [kind] at the offset of the
+ /// given [snippet].
+ Future<void> assertNoAssistAt(String snippet, {int length = 0}) async {
+ _offset = findOffset(snippet);
+ _length = length;
+ List<Assist> assists = await _computeAssists();
+ for (Assist assist in assists) {
+ if (assist.kind == kind) {
+ fail('Unexpected assist $kind in\n${assists.join('\n')}');
+ }
+ }
+ }
+
+ List<LinkedEditSuggestion> expectedSuggestions(
+ LinkedEditSuggestionKind kind, List<String> values) {
+ return values.map((value) {
+ return new LinkedEditSuggestion(value, kind);
+ }).toList();
+ }
+
+ /// Computes assists and verifies that there is an assist of the given kind.
+ Future<Assist> _assertHasAssist() async {
+ List<Assist> assists = await _computeAssists();
+ for (Assist assist in assists) {
+ if (assist.kind == kind) {
+ return assist;
+ }
+ }
+ fail('Expected to find assist $kind in\n${assists.join('\n')}');
+ }
+
+ Future<List<Assist>> _computeAssists() async {
+ var context = new DartAssistContextImpl(
+ testAnalysisResult,
+ _offset,
+ _length,
+ );
+ var processor = new AssistProcessor(context);
+ return await processor.compute();
+ }
+
+ List<Position> _findResultPositions(List<String> searchStrings) {
+ List<Position> positions = <Position>[];
+ for (String search in searchStrings) {
+ int offset = _resultCode.indexOf(search);
+ positions.add(new Position(testFile, offset));
+ }
+ return positions;
+ }
+
+ void _setSelection() {
+ _offset = testCode.indexOf('/*caret*/');
+ if (_offset >= 0) {
+ _offset += '/*caret*/'.length;
+ _length = 0;
+ } else {
+ _offset = testCode.indexOf('// start\n');
+ if (_offset >= 0) {
+ _offset += '// start\n'.length;
+ _length = testCode.indexOf('// end') - _offset;
+ } else {
+ _offset = 0;
+ _length = 0;
+ }
+ }
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_class_to_mixin_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_class_to_mixin_test.dart
new file mode 100644
index 0000000..ce8a4d3
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_class_to_mixin_test.dart
@@ -0,0 +1,409 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConvertClassToMixinTest);
+ });
+}
+
+@reflectiveTest
+class ConvertClassToMixinTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.CONVERT_CLASS_TO_MIXIN;
+
+ test_abstract() async {
+ await resolveTestUnit('''
+abstract class A {}
+''');
+ await assertHasAssistAt('A', '''
+mixin A {}
+''');
+ }
+
+ test_extends_noSuper() async {
+ await resolveTestUnit('''
+class A {}
+class B extends A {}
+''');
+ await assertHasAssistAt('B', '''
+class A {}
+mixin B implements A {}
+''');
+ }
+
+ test_extends_super() async {
+ await resolveTestUnit('''
+class A {
+ a() {}
+}
+class B extends A {
+ b() {
+ super.a();
+ }
+}
+''');
+ await assertHasAssistAt('B', '''
+class A {
+ a() {}
+}
+mixin B on A {
+ b() {
+ super.a();
+ }
+}
+''');
+ }
+
+ test_extends_superSuper() async {
+ await resolveTestUnit('''
+class A {
+ a() {}
+}
+class B extends A {}
+class C extends B {
+ c() {
+ super.a();
+ }
+}
+''');
+ await assertHasAssistAt('C', '''
+class A {
+ a() {}
+}
+class B extends A {}
+mixin C on B {
+ c() {
+ super.a();
+ }
+}
+''');
+ }
+
+ test_extendsImplements_noSuper() async {
+ await resolveTestUnit('''
+class A {}
+class B {}
+class C extends A implements B {}
+''');
+ await assertHasAssistAt('C', '''
+class A {}
+class B {}
+mixin C implements A, B {}
+''');
+ }
+
+ test_extendsImplements_super_extends() async {
+ await resolveTestUnit('''
+class A {
+ a() {}
+}
+class B {}
+class C extends A implements B {
+ c() {
+ super.a();
+ }
+}
+''');
+ await assertHasAssistAt('C', '''
+class A {
+ a() {}
+}
+class B {}
+mixin C on A implements B {
+ c() {
+ super.a();
+ }
+}
+''');
+ }
+
+ test_extendsWith_noSuper() async {
+ await resolveTestUnit('''
+class A {}
+class B {}
+class C extends A with B {}
+''');
+ await assertHasAssistAt('C', '''
+class A {}
+class B {}
+mixin C implements A, B {}
+''');
+ }
+
+ test_extendsWith_super_both() async {
+ await resolveTestUnit('''
+class A {
+ a() {}
+}
+class B {
+ b() {}
+}
+class C extends A with B {
+ c() {
+ super.a();
+ super.b();
+ }
+}
+''');
+ await assertHasAssistAt('C', '''
+class A {
+ a() {}
+}
+class B {
+ b() {}
+}
+mixin C on A, B {
+ c() {
+ super.a();
+ super.b();
+ }
+}
+''');
+ }
+
+ test_extendsWith_super_extends() async {
+ await resolveTestUnit('''
+class A {
+ a() {}
+}
+class B {
+ b() {}
+}
+class C extends A with B {
+ c() {
+ super.a();
+ }
+}
+''');
+ await assertHasAssistAt('C', '''
+class A {
+ a() {}
+}
+class B {
+ b() {}
+}
+mixin C on A implements B {
+ c() {
+ super.a();
+ }
+}
+''');
+ }
+
+ test_extendsWith_super_with() async {
+ await resolveTestUnit('''
+class A {
+ a() {}
+}
+class B {
+ b() {}
+}
+class C extends A with B {
+ c() {
+ super.b();
+ }
+}
+''');
+ await assertHasAssistAt('C', '''
+class A {
+ a() {}
+}
+class B {
+ b() {}
+}
+mixin C on B implements A {
+ c() {
+ super.b();
+ }
+}
+''');
+ }
+
+ test_extendsWithImplements_noSuper() async {
+ await resolveTestUnit('''
+class A {}
+class B {}
+class C {}
+class D extends A with B implements C {}
+''');
+ await assertHasAssistAt('D', '''
+class A {}
+class B {}
+class C {}
+mixin D implements A, B, C {}
+''');
+ }
+
+ test_extendsWithImplements_super_both() async {
+ await resolveTestUnit('''
+class A {
+ a() {}
+}
+class B {
+ b() {}
+}
+class C {}
+class D extends A with B implements C {
+ d() {
+ super.a();
+ super.b();
+ }
+}
+''');
+ await assertHasAssistAt('D', '''
+class A {
+ a() {}
+}
+class B {
+ b() {}
+}
+class C {}
+mixin D on A, B implements C {
+ d() {
+ super.a();
+ super.b();
+ }
+}
+''');
+ }
+
+ test_extendsWithImplements_super_extends() async {
+ await resolveTestUnit('''
+class A {
+ a() {}
+}
+class B {
+ b() {}
+}
+class C {}
+class D extends A with B implements C {
+ d() {
+ super.a();
+ }
+}
+''');
+ await assertHasAssistAt('D', '''
+class A {
+ a() {}
+}
+class B {
+ b() {}
+}
+class C {}
+mixin D on A implements B, C {
+ d() {
+ super.a();
+ }
+}
+''');
+ }
+
+ test_extendsWithImplements_super_with() async {
+ await resolveTestUnit('''
+class A {
+ a() {}
+}
+class B {
+ b() {}
+}
+class C {}
+class D extends A with B implements C {
+ d() {
+ super.b();
+ }
+}
+''');
+ await assertHasAssistAt('D', '''
+class A {
+ a() {}
+}
+class B {
+ b() {}
+}
+class C {}
+mixin D on B implements A, C {
+ d() {
+ super.b();
+ }
+}
+''');
+ }
+
+ test_implements() async {
+ await resolveTestUnit('''
+class A {}
+class B implements A {}
+''');
+ await assertHasAssistAt('B', '''
+class A {}
+mixin B implements A {}
+''');
+ }
+
+ test_noClauses_invalidSelection() async {
+ await resolveTestUnit('''
+class A {}
+''');
+ await assertNoAssistAt('{}');
+ }
+
+ test_noClauses_selectKeyword() async {
+ await resolveTestUnit('''
+class A {}
+''');
+ await assertHasAssistAt('class', '''
+mixin A {}
+''');
+ }
+
+ test_noClauses_selectName() async {
+ await resolveTestUnit('''
+class A {}
+''');
+ await assertHasAssistAt('A', '''
+mixin A {}
+''');
+ }
+
+ test_with_noSuper() async {
+ await resolveTestUnit('''
+class A {}
+class B with A {}
+''');
+ await assertHasAssistAt('B', '''
+class A {}
+mixin B implements A {}
+''');
+ }
+
+ test_with_super() async {
+ await resolveTestUnit('''
+class A {
+ a() {}
+}
+class B with A {
+ b() {
+ super.a();
+ }
+}
+''');
+ await assertHasAssistAt('B', '''
+class A {
+ a() {}
+}
+mixin B on A {
+ b() {
+ super.a();
+ }
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_documentation_into_block_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_documentation_into_block_test.dart
new file mode 100644
index 0000000..895f645
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_documentation_into_block_test.dart
@@ -0,0 +1,96 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConvertDocumentationIntoBlockTest);
+ });
+}
+
+@reflectiveTest
+class ConvertDocumentationIntoBlockTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.CONVERT_DOCUMENTATION_INTO_BLOCK;
+
+ test_alreadyBlock() async {
+ await resolveTestUnit('''
+/**
+ * AAAAAAA
+ */
+class A {}
+''');
+ await assertNoAssistAt('AAA');
+ }
+
+ test_noSpaceBeforeText() async {
+ await resolveTestUnit('''
+class A {
+ /// AAAAA
+ ///BBBBB
+ ///
+ /// CCCCC
+ mmm() {}
+}
+''');
+ await assertHasAssistAt('AAAAA', '''
+class A {
+ /**
+ * AAAAA
+ *BBBBB
+ *
+ * CCCCC
+ */
+ mmm() {}
+}
+''');
+ }
+
+ test_notDocumentation() async {
+ await resolveTestUnit('''
+// AAAA
+class A {}
+''');
+ await assertNoAssistAt('AAA');
+ }
+
+ test_onReference() async {
+ await resolveTestUnit('''
+/// AAAAAAA [int] AAAAAAA
+class A {}
+''');
+ await assertHasAssistAt('nt]', '''
+/**
+ * AAAAAAA [int] AAAAAAA
+ */
+class A {}
+''');
+ }
+
+ test_onText() async {
+ await resolveTestUnit('''
+class A {
+ /// AAAAAAA [int] AAAAAAA
+ /// BBBBBBBB BBBB BBBB
+ /// CCC [A] CCCCCCCCCCC
+ mmm() {}
+}
+''');
+ await assertHasAssistAt('AAA [', '''
+class A {
+ /**
+ * AAAAAAA [int] AAAAAAA
+ * BBBBBBBB BBBB BBBB
+ * CCC [A] CCCCCCCCCCC
+ */
+ mmm() {}
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_documentation_into_line_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_documentation_into_line_test.dart
new file mode 100644
index 0000000..535bf55
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_documentation_into_line_test.dart
@@ -0,0 +1,112 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConvertDocumentationIntoLineTest);
+ });
+}
+
+@reflectiveTest
+class ConvertDocumentationIntoLineTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.CONVERT_DOCUMENTATION_INTO_LINE;
+
+ test_alreadyLine() async {
+ await resolveTestUnit('''
+/// AAAAAAA
+class A {}
+''');
+ await assertNoAssistAt('AAA');
+ }
+
+ test_hasEmptyLine() async {
+ await resolveTestUnit('''
+class A {
+ /**
+ * AAAAAAA [int] AAAAAAA
+ *
+ * BBBBBBBB BBBB BBBB
+ */
+ mmm() {}
+}
+''');
+ await assertHasAssistAt('AAA [', '''
+class A {
+ /// AAAAAAA [int] AAAAAAA
+ ///
+ /// BBBBBBBB BBBB BBBB
+ mmm() {}
+}
+''');
+ }
+
+ test_notDocumentation() async {
+ await resolveTestUnit('''
+/* AAAA */
+class A {}
+''');
+ await assertNoAssistAt('AAA');
+ }
+
+ test_onReference() async {
+ await resolveTestUnit('''
+/**
+ * AAAAAAA [int] AAAAAAA
+ */
+class A {}
+''');
+ await assertHasAssistAt('nt]', '''
+/// AAAAAAA [int] AAAAAAA
+class A {}
+''');
+ }
+
+ test_onText() async {
+ await resolveTestUnit('''
+class A {
+ /**
+ * AAAAAAA [int] AAAAAAA
+ * BBBBBBBB BBBB BBBB
+ * CCC [A] CCCCCCCCCCC
+ */
+ mmm() {}
+}
+''');
+ await assertHasAssistAt('AAA [', '''
+class A {
+ /// AAAAAAA [int] AAAAAAA
+ /// BBBBBBBB BBBB BBBB
+ /// CCC [A] CCCCCCCCCCC
+ mmm() {}
+}
+''');
+ }
+
+ test_onText_hasFirstLine() async {
+ await resolveTestUnit('''
+class A {
+ /** AAAAAAA [int] AAAAAAA
+ * BBBBBBBB BBBB BBBB
+ * CCC [A] CCCCCCCCCCC
+ */
+ mmm() {}
+}
+''');
+ await assertHasAssistAt('AAA [', '''
+class A {
+ /// AAAAAAA [int] AAAAAAA
+ /// BBBBBBBB BBBB BBBB
+ /// CCC [A] CCCCCCCCCCC
+ mmm() {}
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_into_async_body_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_into_async_body_test.dart
new file mode 100644
index 0000000..170a3c4
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_into_async_body_test.dart
@@ -0,0 +1,149 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConvertIntoAsyncBodyTest);
+ });
+}
+
+@reflectiveTest
+class ConvertIntoAsyncBodyTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.CONVERT_INTO_ASYNC_BODY;
+
+ test_async() async {
+ await resolveTestUnit('''
+import 'dart:async';
+Future<String> f() async => '';
+''');
+ await assertNoAssistAt('=>');
+ }
+
+ test_asyncStar() async {
+ await resolveTestUnit('''
+import 'dart:async';
+Stream<String> f() async* {}
+''');
+ await assertNoAssistAt('{}');
+ }
+
+ test_closure() async {
+ await resolveTestUnit('''
+main() {
+ f(() => 123);
+}
+f(g) {}
+''');
+ await assertHasAssistAt('=>', '''
+main() {
+ f(() async => 123);
+}
+f(g) {}
+''');
+ }
+
+ test_constructor() async {
+ await resolveTestUnit('''
+class C {
+ C() {}
+}
+''');
+ await assertNoAssistAt('{}');
+ }
+
+ test_function() async {
+ await resolveTestUnit('''
+String f() => '';
+''');
+ await assertHasAssistAt('=>', '''
+Future<String> f() async => '';
+''');
+ }
+
+ test_getter_expression_noSpace() async {
+ await resolveTestUnit('''
+class C {
+ int get g=>0;
+}
+''');
+ await assertHasAssistAt('get g', '''
+class C {
+ Future<int> get g async =>0;
+}
+''');
+ }
+
+ test_inBody_block() async {
+ await resolveTestUnit('''
+class C {
+ void foo() {
+ print(42);
+ }
+}
+''');
+ await assertNoAssistAt('print');
+ }
+
+ test_inBody_expression() async {
+ await resolveTestUnit('''
+class C {
+ void foo() => print(42);
+}
+''');
+ await assertNoAssistAt('print');
+ }
+
+ test_method() async {
+ await resolveTestUnit('''
+class C {
+ int m() { return 0; }
+}
+''');
+ await assertHasAssistAt('{ return', '''
+class C {
+ Future<int> m() async { return 0; }
+}
+''');
+ }
+
+ test_method_abstract() async {
+ await resolveTestUnit('''
+abstract class C {
+ int m();
+}
+''');
+ await assertHasAssistAt('m()', '''
+abstract class C {
+ Future<int> m();
+}
+''');
+ }
+
+ test_method_noReturnType() async {
+ await resolveTestUnit('''
+class C {
+ m() { return 0; }
+}
+''');
+ await assertHasAssistAt('{ return', '''
+class C {
+ m() async { return 0; }
+}
+''');
+ }
+
+ test_syncStar() async {
+ await resolveTestUnit('''
+Iterable<String> f() sync* {}
+''');
+ await assertNoAssistAt('{}');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_into_block_body_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_into_block_body_test.dart
new file mode 100644
index 0000000..4d3fa9c
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_into_block_body_test.dart
@@ -0,0 +1,162 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConvertIntoBlockBodyTest);
+ });
+}
+
+@reflectiveTest
+class ConvertIntoBlockBodyTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.CONVERT_INTO_BLOCK_BODY;
+
+ test_async() async {
+ await resolveTestUnit('''
+class A {
+ mmm() async => 123;
+}
+''');
+ await assertHasAssistAt('mmm()', '''
+class A {
+ mmm() async {
+ return 123;
+ }
+}
+''');
+ }
+
+ test_closure() async {
+ await resolveTestUnit('''
+setup(x) {}
+main() {
+ setup(() => 42);
+}
+''');
+ await assertHasAssistAt('() => 42', '''
+setup(x) {}
+main() {
+ setup(() {
+ return 42;
+ });
+}
+''');
+ assertExitPosition(after: '42;');
+ }
+
+ test_closure_voidExpression() async {
+ await resolveTestUnit('''
+setup(x) {}
+main() {
+ setup(() => print('done'));
+}
+''');
+ await assertHasAssistAt('() => print', '''
+setup(x) {}
+main() {
+ setup(() {
+ print('done');
+ });
+}
+''');
+ assertExitPosition(after: "');");
+ }
+
+ test_constructor() async {
+ await resolveTestUnit('''
+class A {
+ factory A() => null;
+}
+''');
+ await assertHasAssistAt('A()', '''
+class A {
+ factory A() {
+ return null;
+ }
+}
+''');
+ }
+
+ test_inExpression() async {
+ await resolveTestUnit('''
+main() => 123;
+''');
+ await assertNoAssistAt('123;');
+ }
+
+ test_method() async {
+ await resolveTestUnit('''
+class A {
+ mmm() => 123;
+}
+''');
+ await assertHasAssistAt('mmm()', '''
+class A {
+ mmm() {
+ return 123;
+ }
+}
+''');
+ }
+
+ test_noEnclosingFunction() async {
+ await resolveTestUnit('''
+var v = 123;
+''');
+ await assertNoAssistAt('v =');
+ }
+
+ test_notExpressionBlock() async {
+ await resolveTestUnit('''
+fff() {
+ return 123;
+}
+''');
+ await assertNoAssistAt('fff() {');
+ }
+
+ test_onArrow() async {
+ await resolveTestUnit('''
+fff() => 123;
+''');
+ await assertHasAssistAt('=>', '''
+fff() {
+ return 123;
+}
+''');
+ }
+
+ test_onName() async {
+ await resolveTestUnit('''
+fff() => 123;
+''');
+ await assertHasAssistAt('fff()', '''
+fff() {
+ return 123;
+}
+''');
+ }
+
+ test_throw() async {
+ await resolveTestUnit('''
+class A {
+ mmm() => throw 'error';
+}
+''');
+ await assertHasAssistAt('mmm()', '''
+class A {
+ mmm() {
+ throw 'error';
+ }
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_into_expression_body_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_into_expression_body_test.dart
new file mode 100644
index 0000000..cb7e2e2
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_into_expression_body_test.dart
@@ -0,0 +1,184 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConvertIntoExpressionBodyTest);
+ });
+}
+
+@reflectiveTest
+class ConvertIntoExpressionBodyTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.CONVERT_INTO_EXPRESSION_BODY;
+
+ test_already() async {
+ await resolveTestUnit('''
+fff() => 42;
+''');
+ await assertNoAssistAt('fff()');
+ }
+
+ test_async() async {
+ await resolveTestUnit('''
+class A {
+ mmm() async {
+ return 42;
+ }
+}
+''');
+ await assertHasAssistAt('mmm', '''
+class A {
+ mmm() async => 42;
+}
+''');
+ }
+
+ test_closure() async {
+ await resolveTestUnit('''
+setup(x) {}
+main() {
+ setup(() {
+ return 42;
+ });
+}
+''');
+ await assertHasAssistAt('return', '''
+setup(x) {}
+main() {
+ setup(() => 42);
+}
+''');
+ }
+
+ test_closure_voidExpression() async {
+ await resolveTestUnit('''
+setup(x) {}
+main() {
+ setup((_) {
+ print('test');
+ });
+}
+''');
+ await assertHasAssistAt('(_) {', '''
+setup(x) {}
+main() {
+ setup((_) => print('test'));
+}
+''');
+ }
+
+ test_constructor() async {
+ await resolveTestUnit('''
+class A {
+ factory A() {
+ return null;
+ }
+}
+''');
+ await assertHasAssistAt('A()', '''
+class A {
+ factory A() => null;
+}
+''');
+ }
+
+ test_function_onBlock() async {
+ await resolveTestUnit('''
+fff() {
+ return 42;
+}
+''');
+ await assertHasAssistAt('{', '''
+fff() => 42;
+''');
+ }
+
+ test_function_onName() async {
+ await resolveTestUnit('''
+fff() {
+ return 42;
+}
+''');
+ await assertHasAssistAt('ff()', '''
+fff() => 42;
+''');
+ }
+
+ test_inExpression() async {
+ await resolveTestUnit('''
+main() {
+ return 42;
+}
+''');
+ await assertNoAssistAt('42;');
+ }
+
+ test_method_onBlock() async {
+ await resolveTestUnit('''
+class A {
+ m() { // marker
+ return 42;
+ }
+}
+''');
+ await assertHasAssistAt('{ // marker', '''
+class A {
+ m() => 42;
+}
+''');
+ }
+
+ test_moreThanOneStatement() async {
+ await resolveTestUnit('''
+fff() {
+ var v = 42;
+ return v;
+}
+''');
+ await assertNoAssistAt('fff()');
+ }
+
+ test_noEnclosingFunction() async {
+ await resolveTestUnit('''
+var V = 42;
+''');
+ await assertNoAssistAt('V = ');
+ }
+
+ test_noReturn() async {
+ await resolveTestUnit('''
+fff() {
+ var v = 42;
+}
+''');
+ await assertNoAssistAt('fff()');
+ }
+
+ test_noReturnValue() async {
+ await resolveTestUnit('''
+fff() {
+ return;
+}
+''');
+ await assertNoAssistAt('fff()');
+ }
+
+ test_topFunction_onReturnStatement() async {
+ await resolveTestUnit('''
+fff() {
+ return 42;
+}
+''');
+ await assertHasAssistAt('return', '''
+fff() => 42;
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_into_final_field_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_into_final_field_test.dart
new file mode 100644
index 0000000..4fa51fa
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_into_final_field_test.dart
@@ -0,0 +1,194 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConvertIntoFinalFieldTest);
+ });
+}
+
+@reflectiveTest
+class ConvertIntoFinalFieldTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.CONVERT_INTO_FINAL_FIELD;
+
+ test_blockBody_onlyReturnStatement() async {
+ await resolveTestUnit('''
+class A {
+ int get foo {
+ return 1 + 2;
+ }
+}
+''');
+ await assertHasAssistAt('get foo', '''
+class A {
+ final int foo = 1 + 2;
+}
+''');
+ }
+
+ test_hasOverride() async {
+ await resolveTestUnit('''
+const myAnnotation = const Object();
+class A {
+ @myAnnotation
+ int get foo => 42;
+}
+''');
+ await assertHasAssistAt('get foo', '''
+const myAnnotation = const Object();
+class A {
+ @myAnnotation
+ final int foo = 42;
+}
+''');
+ }
+
+ test_hasSetter_inSuper() async {
+ await resolveTestUnit('''
+class A {
+ void set foo(_) {}
+}
+class B extends A {
+ int get foo => null;
+}
+''');
+ await assertHasAssistAt('get foo', '''
+class A {
+ void set foo(_) {}
+}
+class B extends A {
+ final int foo;
+}
+''');
+ }
+
+ test_hasSetter_inThisClass() async {
+ await resolveTestUnit('''
+class A {
+ int get foo => null;
+ void set foo(_) {}
+}
+''');
+ await assertNoAssistAt('get foo');
+ }
+
+ test_noReturnType() async {
+ await resolveTestUnit('''
+class A {
+ get foo => 42;
+}
+''');
+ await assertHasAssistAt('get foo', '''
+class A {
+ final foo = 42;
+}
+''');
+ }
+
+ test_noReturnType_static() async {
+ await resolveTestUnit('''
+class A {
+ static get foo => 42;
+}
+''');
+ await assertHasAssistAt('get foo', '''
+class A {
+ static final foo = 42;
+}
+''');
+ }
+
+ test_notExpressionBody() async {
+ await resolveTestUnit('''
+class A {
+ int get foo {
+ int v = 1 + 2;
+ return v + 3;
+ }
+}
+''');
+ await assertNoAssistAt('get foo');
+ }
+
+ test_notGetter() async {
+ await resolveTestUnit('''
+class A {
+ int foo() => 42;
+}
+''');
+ await assertNoAssistAt('foo');
+ }
+
+ test_notNull() async {
+ await resolveTestUnit('''
+class A {
+ int get foo => 1 + 2;
+}
+''');
+ await assertHasAssistAt('get foo', '''
+class A {
+ final int foo = 1 + 2;
+}
+''');
+ }
+
+ test_null() async {
+ await resolveTestUnit('''
+class A {
+ int get foo => null;
+}
+''');
+ await assertHasAssistAt('get foo', '''
+class A {
+ final int foo;
+}
+''');
+ }
+
+ test_onName() async {
+ await resolveTestUnit('''
+class A {
+ int get foo => 42;
+}
+''');
+ await assertHasAssistAt('foo', '''
+class A {
+ final int foo = 42;
+}
+''');
+ }
+
+ test_onReturnType_parameterized() async {
+ await resolveTestUnit('''
+class A {
+ List<int> get foo => null;
+}
+''');
+ await assertHasAssistAt('nt> get', '''
+class A {
+ final List<int> foo;
+}
+''');
+ }
+
+ test_onReturnType_simple() async {
+ await resolveTestUnit('''
+class A {
+ int get foo => 42;
+}
+''');
+ await assertHasAssistAt('int get', '''
+class A {
+ final int foo = 42;
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_into_for_index_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_into_for_index_test.dart
new file mode 100644
index 0000000..5816d3a
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_into_for_index_test.dart
@@ -0,0 +1,168 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConvertIntoForIndexTest);
+ });
+}
+
+@reflectiveTest
+class ConvertIntoForIndexTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.CONVERT_INTO_FOR_INDEX;
+
+ test_bodyNotBlock() async {
+ await resolveTestUnit('''
+main(List<String> items) {
+ for (String item in items) print(item);
+}
+''');
+ await assertNoAssistAt('for (String');
+ }
+
+ test_doesNotDeclareVariable() async {
+ await resolveTestUnit('''
+main(List<String> items) {
+ String item;
+ for (item in items) {
+ print(item);
+ }
+}
+''');
+ await assertNoAssistAt('for (item');
+ }
+
+ test_iterableIsNotVariable() async {
+ await resolveTestUnit('''
+main() {
+ for (String item in ['a', 'b', 'c']) {
+ print(item);
+ }
+}
+''');
+ await assertNoAssistAt('for (String');
+ }
+
+ test_iterableNotList() async {
+ await resolveTestUnit('''
+main(Iterable<String> items) {
+ for (String item in items) {
+ print(item);
+ }
+}
+''');
+ await assertNoAssistAt('for (String');
+ }
+
+ test_onDeclaredIdentifier_name() async {
+ await resolveTestUnit('''
+main(List<String> items) {
+ for (String item in items) {
+ print(item);
+ }
+}
+''');
+ await assertHasAssistAt('item in', '''
+main(List<String> items) {
+ for (int i = 0; i < items.length; i++) {
+ String item = items[i];
+ print(item);
+ }
+}
+''');
+ }
+
+ test_onDeclaredIdentifier_type() async {
+ await resolveTestUnit('''
+main(List<String> items) {
+ for (String item in items) {
+ print(item);
+ }
+}
+''');
+ await assertHasAssistAt('tring item', '''
+main(List<String> items) {
+ for (int i = 0; i < items.length; i++) {
+ String item = items[i];
+ print(item);
+ }
+}
+''');
+ }
+
+ test_onFor() async {
+ await resolveTestUnit('''
+main(List<String> items) {
+ for (String item in items) {
+ print(item);
+ }
+}
+''');
+ await assertHasAssistAt('for (String', '''
+main(List<String> items) {
+ for (int i = 0; i < items.length; i++) {
+ String item = items[i];
+ print(item);
+ }
+}
+''');
+ }
+
+ test_usesI() async {
+ await resolveTestUnit('''
+main(List<String> items) {
+ for (String item in items) {
+ int i = 0;
+ }
+}
+''');
+ await assertHasAssistAt('for (String', '''
+main(List<String> items) {
+ for (int j = 0; j < items.length; j++) {
+ String item = items[j];
+ int i = 0;
+ }
+}
+''');
+ }
+
+ test_usesIJ() async {
+ await resolveTestUnit('''
+main(List<String> items) {
+ for (String item in items) {
+ print(item);
+ int i = 0, j = 1;
+ }
+}
+''');
+ await assertHasAssistAt('for (String', '''
+main(List<String> items) {
+ for (int k = 0; k < items.length; k++) {
+ String item = items[k];
+ print(item);
+ int i = 0, j = 1;
+ }
+}
+''');
+ }
+
+ test_usesIJK() async {
+ await resolveTestUnit('''
+main(List<String> items) {
+ for (String item in items) {
+ print(item);
+ int i, j, k;
+ }
+}
+''');
+ await assertNoAssistAt('for (String');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_into_generic_function_syntax_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_into_generic_function_syntax_test.dart
new file mode 100644
index 0000000..e9b034e
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_into_generic_function_syntax_test.dart
@@ -0,0 +1,103 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConvertIntoGenericFunctionSyntaxTest);
+ });
+}
+
+@reflectiveTest
+class ConvertIntoGenericFunctionSyntaxTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.CONVERT_INTO_GENERIC_FUNCTION_SYNTAX;
+
+ test_functionTypeAlias_insideParameterList() async {
+ await resolveTestUnit('''
+typedef String F(int x, int y);
+''');
+ await assertNoAssistAt('x,');
+ }
+
+ test_functionTypeAlias_noParameterTypes() async {
+ await resolveTestUnit('''
+typedef String F(x);
+''');
+ await assertNoAssistAt('def');
+ }
+
+ test_functionTypeAlias_noReturnType_noTypeParameters() async {
+ await resolveTestUnit('''
+typedef String F(int x);
+''');
+ await assertHasAssistAt('def', '''
+typedef F = String Function(int x);
+''');
+ }
+
+ test_functionTypeAlias_noReturnType_typeParameters() async {
+ await resolveTestUnit('''
+typedef F<P, R>(P x);
+''');
+ await assertHasAssistAt('def', '''
+typedef F<P, R> = Function(P x);
+''');
+ }
+
+ test_functionTypeAlias_returnType_noTypeParameters() async {
+ await resolveTestUnit('''
+typedef String F(int x);
+''');
+ await assertHasAssistAt('def', '''
+typedef F = String Function(int x);
+''');
+ }
+
+ test_functionTypeAlias_returnType_typeParameters() async {
+ await resolveTestUnit('''
+typedef R F<P, R>(P x);
+''');
+ await assertHasAssistAt('def', '''
+typedef F<P, R> = R Function(P x);
+''');
+ }
+
+ test_functionTypedParameter_insideParameterList() async {
+ await resolveTestUnit('''
+g(String f(int x, int y)) {}
+''');
+ await assertNoAssistAt('x,');
+ }
+
+ test_functionTypedParameter_noParameterTypes() async {
+ await resolveTestUnit('''
+g(String f(x)) {}
+''');
+ await assertNoAssistAt('f(');
+ }
+
+ test_functionTypedParameter_noReturnType_noTypeParameters() async {
+ await resolveTestUnit('''
+g(f(int x)) {}
+''');
+ await assertHasAssistAt('f(', '''
+g(Function(int x) f) {}
+''');
+ }
+
+ test_functionTypedParameter_returnType() async {
+ await resolveTestUnit('''
+g(String f(int x)) {}
+''');
+ await assertHasAssistAt('f(', '''
+g(String Function(int x) f) {}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_into_getter_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_into_getter_test.dart
new file mode 100644
index 0000000..f3348c2
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_into_getter_test.dart
@@ -0,0 +1,79 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConvertIntoGetterTest);
+ });
+}
+
+@reflectiveTest
+class ConvertIntoGetterTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.CONVERT_INTO_GETTER;
+
+ test_noInitializer() async {
+ verifyNoTestUnitErrors = false;
+ await resolveTestUnit('''
+class A {
+ final int foo;
+}
+''');
+ await assertNoAssistAt('foo');
+ }
+
+ test_notFinal() async {
+ await resolveTestUnit('''
+class A {
+ int foo = 1;
+}
+''');
+ await assertNoAssistAt('foo');
+ }
+
+ test_notSingleField() async {
+ await resolveTestUnit('''
+class A {
+ final int foo = 1, bar = 2;
+}
+''');
+ await assertNoAssistAt('foo');
+ }
+
+ test_noType() async {
+ await resolveTestUnit('''
+class A {
+ final foo = 42;
+}
+''');
+ await assertHasAssistAt('foo =', '''
+class A {
+ get foo => 42;
+}
+''');
+ }
+
+ test_type() async {
+ await resolveTestUnit('''
+const myAnnotation = const Object();
+class A {
+ @myAnnotation
+ final int foo = 1 + 2;
+}
+''');
+ await assertHasAssistAt('foo =', '''
+const myAnnotation = const Object();
+class A {
+ @myAnnotation
+ int get foo => 1 + 2;
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_into_is_not_empty_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_into_is_not_empty_test.dart
new file mode 100644
index 0000000..cd522a7
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_into_is_not_empty_test.dart
@@ -0,0 +1,100 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConvertIntoIsNotEmptyTest);
+ });
+}
+
+@reflectiveTest
+class ConvertIntoIsNotEmptyTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY;
+
+ test_noBang() async {
+ verifyNoTestUnitErrors = false;
+ await resolveTestUnit('''
+main(String str) {
+ ~str.isEmpty;
+}
+''');
+ await assertNoAssistAt('isEmpty;');
+ }
+
+ test_noIsNotEmpty() async {
+ await resolveTestUnit('''
+class A {
+ bool get isEmpty => false;
+}
+main(A a) {
+ !a.isEmpty;
+}
+''');
+ await assertNoAssistAt('isEmpty;');
+ }
+
+ test_notInPrefixExpression() async {
+ await resolveTestUnit('''
+main(String str) {
+ str.isEmpty;
+}
+''');
+ await assertNoAssistAt('isEmpty;');
+ }
+
+ test_notIsEmpty() async {
+ await resolveTestUnit('''
+main(int p) {
+ !p.isEven;
+}
+''');
+ await assertNoAssistAt('isEven;');
+ }
+
+ test_on_isEmpty() async {
+ await resolveTestUnit('''
+main(String str) {
+ !str.isEmpty;
+}
+''');
+ await assertHasAssistAt('isEmpty', '''
+main(String str) {
+ str.isNotEmpty;
+}
+''');
+ }
+
+ test_on_str() async {
+ await resolveTestUnit('''
+main(String str) {
+ !str.isEmpty;
+}
+''');
+ await assertHasAssistAt('str.', '''
+main(String str) {
+ str.isNotEmpty;
+}
+''');
+ }
+
+ test_propertyAccess() async {
+ await resolveTestUnit('''
+main(String str) {
+ !'text'.isEmpty;
+}
+''');
+ await assertHasAssistAt('isEmpty', '''
+main(String str) {
+ 'text'.isNotEmpty;
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_into_is_not_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_into_is_not_test.dart
new file mode 100644
index 0000000..f7e1ae1
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_into_is_not_test.dart
@@ -0,0 +1,195 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConvertIntoIsNotTest);
+ });
+}
+
+@reflectiveTest
+class ConvertIntoIsNotTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.CONVERT_INTO_IS_NOT;
+
+ test_childOfIs_left() async {
+ await resolveTestUnit('''
+main(p) {
+ !(p is String);
+}
+''');
+ await assertHasAssistAt('p is', '''
+main(p) {
+ p is! String;
+}
+''');
+ }
+
+ test_childOfIs_right() async {
+ await resolveTestUnit('''
+main(p) {
+ !(p is String);
+}
+''');
+ await assertHasAssistAt('String)', '''
+main(p) {
+ p is! String;
+}
+''');
+ }
+
+ test_is() async {
+ await resolveTestUnit('''
+main(p) {
+ !(p is String);
+}
+''');
+ await assertHasAssistAt('is String', '''
+main(p) {
+ p is! String;
+}
+''');
+ }
+
+ test_is_alreadyIsNot() async {
+ await resolveTestUnit('''
+main(p) {
+ p is! String;
+}
+''');
+ await assertNoAssistAt('is!');
+ }
+
+ test_is_higherPrecedencePrefix() async {
+ await resolveTestUnit('''
+main(p) {
+ !!(p is String);
+}
+''');
+ await assertHasAssistAt('is String', '''
+main(p) {
+ !(p is! String);
+}
+''');
+ }
+
+ test_is_noEnclosingParenthesis() async {
+ await resolveTestUnit('''
+main(p) {
+ p is String;
+}
+''');
+ await assertNoAssistAt('is String');
+ }
+
+ test_is_noPrefix() async {
+ await resolveTestUnit('''
+main(p) {
+ (p is String);
+}
+''');
+ await assertNoAssistAt('is String');
+ }
+
+ test_is_not_higherPrecedencePrefix() async {
+ await resolveTestUnit('''
+main(p) {
+ !!(p is String);
+}
+''');
+ await assertHasAssistAt('!(p', '''
+main(p) {
+ !(p is! String);
+}
+''');
+ }
+
+ test_is_notIsExpression() async {
+ await resolveTestUnit('''
+main(p) {
+ 123 + 456;
+}
+''');
+ await assertNoAssistAt('123 +');
+ }
+
+ test_is_notTheNotOperator() async {
+ verifyNoTestUnitErrors = false;
+ await resolveTestUnit('''
+main(p) {
+ ++(p is String);
+}
+''');
+ await assertNoAssistAt('is String');
+ }
+
+ test_not() async {
+ await resolveTestUnit('''
+main(p) {
+ !(p is String);
+}
+''');
+ await assertHasAssistAt('!(p', '''
+main(p) {
+ p is! String;
+}
+''');
+ }
+
+ test_not_alreadyIsNot() async {
+ await resolveTestUnit('''
+main(p) {
+ !(p is! String);
+}
+''');
+ await assertNoAssistAt('!(p');
+ }
+
+ test_not_noEnclosingParenthesis() async {
+ await resolveTestUnit('''
+main(p) {
+ !p;
+}
+''');
+ await assertNoAssistAt('!p');
+ }
+
+ test_not_notIsExpression() async {
+ await resolveTestUnit('''
+main(p) {
+ !(p == null);
+}
+''');
+ await assertNoAssistAt('!(p');
+ }
+
+ test_not_notTheNotOperator() async {
+ verifyNoTestUnitErrors = false;
+ await resolveTestUnit('''
+main(p) {
+ ++(p is String);
+}
+''');
+ await assertNoAssistAt('++(');
+ }
+
+ test_parentheses() async {
+ await resolveTestUnit('''
+main(p) {
+ !(p is String);
+}
+''');
+ await assertHasAssistAt('(p is', '''
+main(p) {
+ p is! String;
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_part_of_to_uri_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_part_of_to_uri_test.dart
new file mode 100644
index 0000000..381e803
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_part_of_to_uri_test.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConvertPartOfToUriTest);
+ });
+}
+
+@reflectiveTest
+class ConvertPartOfToUriTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.CONVERT_PART_OF_TO_URI;
+
+ test_nonSibling() async {
+ addSource('/pkg/lib/foo.dart', '''
+library foo;
+part 'src/bar.dart';
+''');
+ testFile = convertPath('/pkg/lib/src/bar.dart');
+ await resolveTestUnit('''
+part of foo;
+''');
+ await assertHasAssistAt('foo', '''
+part of '../foo.dart';
+''');
+ }
+
+ test_sibling() async {
+ addSource('/pkg/foo.dart', '''
+library foo;
+part 'bar.dart';
+''');
+ testFile = convertPath('/pkg/bar.dart');
+ await resolveTestUnit('''
+part of foo;
+''');
+ await assertHasAssistAt('foo', '''
+part of 'foo.dart';
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_double_quoted_string_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_double_quoted_string_test.dart
new file mode 100644
index 0000000..5711b07
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_double_quoted_string_test.dart
@@ -0,0 +1,143 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConvertToDoubleQuotedStringTest);
+ });
+}
+
+@reflectiveTest
+class ConvertToDoubleQuotedStringTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.CONVERT_TO_DOUBLE_QUOTED_STRING;
+
+ test_one_embeddedTarget() async {
+ await resolveTestUnit('''
+main() {
+ print('a"b"c');
+}
+''');
+ await assertNoAssistAt("'a");
+ }
+
+ test_one_enclosingTarget() async {
+ await resolveTestUnit('''
+main() {
+ print("abc");
+}
+''');
+ await assertNoAssistAt('"ab');
+ }
+
+ test_one_interpolation() async {
+ await resolveTestUnit(r'''
+main() {
+ var b = 'b';
+ var c = 'c';
+ print('a $b-${c} d');
+}
+''');
+ await assertHasAssistAt(r"'a $b", r'''
+main() {
+ var b = 'b';
+ var c = 'c';
+ print("a $b-${c} d");
+}
+''');
+ }
+
+ test_one_raw() async {
+ await resolveTestUnit('''
+main() {
+ print(r'abc');
+}
+''');
+ await assertHasAssistAt("'ab", '''
+main() {
+ print(r"abc");
+}
+''');
+ }
+
+ test_one_simple() async {
+ await resolveTestUnit('''
+main() {
+ print('abc');
+}
+''');
+ await assertHasAssistAt("'ab", '''
+main() {
+ print("abc");
+}
+''');
+ }
+
+ test_three_embeddedTarget() async {
+ await resolveTestUnit("""
+main() {
+ print('''a""\"c''');
+}
+""");
+ await assertNoAssistAt("'a");
+ }
+
+ test_three_enclosingTarget() async {
+ await resolveTestUnit('''
+main() {
+ print("""abc""");
+}
+''');
+ await assertNoAssistAt('"ab');
+ }
+
+ test_three_interpolation() async {
+ await resolveTestUnit(r"""
+main() {
+ var b = 'b';
+ var c = 'c';
+ print('''a $b-${c} d''');
+}
+""");
+ await assertHasAssistAt(r"'a $b", r'''
+main() {
+ var b = 'b';
+ var c = 'c';
+ print("""a $b-${c} d""");
+}
+''');
+ }
+
+ test_three_raw() async {
+ await resolveTestUnit("""
+main() {
+ print(r'''abc''');
+}
+""");
+ await assertHasAssistAt("'ab", '''
+main() {
+ print(r"""abc""");
+}
+''');
+ }
+
+ test_three_simple() async {
+ await resolveTestUnit("""
+main() {
+ print('''abc''');
+}
+""");
+ await assertHasAssistAt("'ab", '''
+main() {
+ print("""abc""");
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_field_parameter_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_field_parameter_test.dart
new file mode 100644
index 0000000..2cf9958
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_field_parameter_test.dart
@@ -0,0 +1,110 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConvertToFieldParameterTest);
+ });
+}
+
+@reflectiveTest
+class ConvertToFieldParameterTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.CONVERT_TO_FIELD_PARAMETER;
+
+ test_additionalUse() async {
+ await resolveTestUnit('''
+class A {
+ int aaa2;
+ int bbb2;
+ A(int aaa) : aaa2 = aaa, bbb2 = aaa;
+}
+''');
+ await assertNoAssistAt('aaa)');
+ }
+
+ test_firstInitializer() async {
+ await resolveTestUnit('''
+class A {
+ int aaa2;
+ int bbb2;
+ A(int aaa, int bbb) : aaa2 = aaa, bbb2 = bbb;
+}
+''');
+ await assertHasAssistAt('aaa, ', '''
+class A {
+ int aaa2;
+ int bbb2;
+ A(this.aaa2, int bbb) : bbb2 = bbb;
+}
+''');
+ }
+
+ test_notPureAssignment() async {
+ await resolveTestUnit('''
+class A {
+ int aaa2;
+ A(int aaa) : aaa2 = aaa * 2;
+}
+''');
+ await assertNoAssistAt('aaa)');
+ }
+
+ test_onParameterName_inInitializer() async {
+ await resolveTestUnit('''
+class A {
+ int test2;
+ A(int test) : test2 = test {
+ }
+}
+''');
+ await assertHasAssistAt('test {', '''
+class A {
+ int test2;
+ A(this.test2) {
+ }
+}
+''');
+ }
+
+ test_onParameterName_inParameters() async {
+ await resolveTestUnit('''
+class A {
+ int test;
+ A(int test) : test = test {
+ }
+}
+''');
+ await assertHasAssistAt('test)', '''
+class A {
+ int test;
+ A(this.test) {
+ }
+}
+''');
+ }
+
+ test_secondInitializer() async {
+ await resolveTestUnit('''
+class A {
+ int aaa2;
+ int bbb2;
+ A(int aaa, int bbb) : aaa2 = aaa, bbb2 = bbb;
+}
+''');
+ await assertHasAssistAt('bbb)', '''
+class A {
+ int aaa2;
+ int bbb2;
+ A(int aaa, this.bbb2) : aaa2 = aaa;
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_int_literal_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_int_literal_test.dart
new file mode 100644
index 0000000..d76730c
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_int_literal_test.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConvertToIntLiteralTest);
+ });
+}
+
+@reflectiveTest
+class ConvertToIntLiteralTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.CONVERT_TO_INT_LITERAL;
+
+ test_decimal() async {
+ await resolveTestUnit('''
+const double myDouble = /*caret*/42.0;
+''');
+ await assertHasAssist('''
+const double myDouble = /*caret*/42;
+''');
+ }
+
+ test_notDouble() async {
+ await resolveTestUnit('''
+const double myDouble = /*caret*/42;
+''');
+ await assertNoAssist();
+ }
+
+ test_scientific() async {
+ await resolveTestUnit('''
+const double myDouble = /*caret*/4.2e1;
+''');
+ await assertHasAssist('''
+const double myDouble = /*caret*/42;
+''');
+ }
+
+ test_tooBig() async {
+ await resolveTestUnit('''
+const double myDouble = /*caret*/4.2e99999;
+''');
+ await assertNoAssist();
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_normal_parameter_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_normal_parameter_test.dart
new file mode 100644
index 0000000..f5ddc23
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_normal_parameter_test.dart
@@ -0,0 +1,72 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConvertToNormalParameterTest);
+ });
+}
+
+@reflectiveTest
+class ConvertToNormalParameterTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.CONVERT_TO_NORMAL_PARAMETER;
+
+ test_dynamic() async {
+ await resolveTestUnit('''
+class A {
+ var test;
+ A(this.test) {
+ }
+}
+''');
+ await assertHasAssistAt('test)', '''
+class A {
+ var test;
+ A(test) : test = test {
+ }
+}
+''');
+ }
+
+ test_firstInitializer() async {
+ await resolveTestUnit('''
+class A {
+ int test;
+ A(this.test) {
+ }
+}
+''');
+ await assertHasAssistAt('test)', '''
+class A {
+ int test;
+ A(int test) : test = test {
+ }
+}
+''');
+ }
+
+ test_secondInitializer() async {
+ await resolveTestUnit('''
+class A {
+ double aaa;
+ int bbb;
+ A(this.bbb) : aaa = 1.0;
+}
+''');
+ await assertHasAssistAt('bbb)', '''
+class A {
+ double aaa;
+ int bbb;
+ A(int bbb) : aaa = 1.0, bbb = bbb;
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_single_quoted_string_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_single_quoted_string_test.dart
new file mode 100644
index 0000000..161f62c
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_single_quoted_string_test.dart
@@ -0,0 +1,143 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConvertToSingleQuotedStringTest);
+ });
+}
+
+@reflectiveTest
+class ConvertToSingleQuotedStringTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.CONVERT_TO_SINGLE_QUOTED_STRING;
+
+ test_one_embeddedTarget() async {
+ await resolveTestUnit('''
+main() {
+ print("a'b'c");
+}
+''');
+ await assertNoAssistAt('"a');
+ }
+
+ test_one_enclosingTarget() async {
+ await resolveTestUnit('''
+main() {
+ print('abc');
+}
+''');
+ await assertNoAssistAt("'ab");
+ }
+
+ test_one_interpolation() async {
+ await resolveTestUnit(r'''
+main() {
+ var b = 'b';
+ var c = 'c';
+ print("a $b-${c} d");
+}
+''');
+ await assertHasAssistAt(r'"a $b', r'''
+main() {
+ var b = 'b';
+ var c = 'c';
+ print('a $b-${c} d');
+}
+''');
+ }
+
+ test_one_raw() async {
+ await resolveTestUnit('''
+main() {
+ print(r"abc");
+}
+''');
+ await assertHasAssistAt('"ab', '''
+main() {
+ print(r'abc');
+}
+''');
+ }
+
+ test_one_simple() async {
+ await resolveTestUnit('''
+main() {
+ print("abc");
+}
+''');
+ await assertHasAssistAt('"ab', '''
+main() {
+ print('abc');
+}
+''');
+ }
+
+ test_three_embeddedTarget() async {
+ await resolveTestUnit('''
+main() {
+ print("""a''\'bc""");
+}
+''');
+ await assertNoAssistAt('"a');
+ }
+
+ test_three_enclosingTarget() async {
+ await resolveTestUnit("""
+main() {
+ print('''abc''');
+}
+""");
+ await assertNoAssistAt("'ab");
+ }
+
+ test_three_interpolation() async {
+ await resolveTestUnit(r'''
+main() {
+ var b = 'b';
+ var c = 'c';
+ print("""a $b-${c} d""");
+}
+''');
+ await assertHasAssistAt(r'"a $b', r"""
+main() {
+ var b = 'b';
+ var c = 'c';
+ print('''a $b-${c} d''');
+}
+""");
+ }
+
+ test_three_raw() async {
+ await resolveTestUnit('''
+main() {
+ print(r"""abc""");
+}
+''');
+ await assertHasAssistAt('"ab', """
+main() {
+ print(r'''abc''');
+}
+""");
+ }
+
+ test_three_simple() async {
+ await resolveTestUnit('''
+main() {
+ print("""abc""");
+}
+''');
+ await assertHasAssistAt('"ab', """
+main() {
+ print('''abc''');
+}
+""");
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/encapsulate_field_test.dart b/pkg/analysis_server/test/src/services/correction/assist/encapsulate_field_test.dart
new file mode 100644
index 0000000..98e3baf
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/encapsulate_field_test.dart
@@ -0,0 +1,164 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(EncapsulateFieldTest);
+ });
+}
+
+@reflectiveTest
+class EncapsulateFieldTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.ENCAPSULATE_FIELD;
+
+ test_alreadyPrivate() async {
+ await resolveTestUnit('''
+class A {
+ int _test = 42;
+}
+main(A a) {
+ print(a._test);
+}
+''');
+ await assertNoAssistAt('_test =');
+ }
+
+ test_documentation() async {
+ await resolveTestUnit('''
+class A {
+ /// AAA
+ /// BBB
+ int test;
+}
+''');
+ await assertHasAssistAt('test;', '''
+class A {
+ /// AAA
+ /// BBB
+ int _test;
+
+ /// AAA
+ /// BBB
+ int get test => _test;
+
+ /// AAA
+ /// BBB
+ set test(int test) {
+ _test = test;
+ }
+}
+''');
+ }
+
+ test_final() async {
+ await resolveTestUnit('''
+class A {
+ final int test = 42;
+}
+''');
+ await assertNoAssistAt('test =');
+ }
+
+ test_hasType() async {
+ await resolveTestUnit('''
+class A {
+ int test = 42;
+ A(this.test);
+}
+main(A a) {
+ print(a.test);
+}
+''');
+ await assertHasAssistAt('test = 42', '''
+class A {
+ int _test = 42;
+
+ int get test => _test;
+
+ set test(int test) {
+ _test = test;
+ }
+ A(this._test);
+}
+main(A a) {
+ print(a.test);
+}
+''');
+ }
+
+ test_multipleFields() async {
+ await resolveTestUnit('''
+class A {
+ int aaa, bbb, ccc;
+}
+main(A a) {
+ print(a.bbb);
+}
+''');
+ await assertNoAssistAt('bbb, ');
+ }
+
+ test_notOnName() async {
+ await resolveTestUnit('''
+class A {
+ int test = 1 + 2 + 3;
+}
+''');
+ await assertNoAssistAt('+ 2');
+ }
+
+ test_noType() async {
+ await resolveTestUnit('''
+class A {
+ var test = 42;
+}
+main(A a) {
+ print(a.test);
+}
+''');
+ await assertHasAssistAt('test = 42', '''
+class A {
+ var _test = 42;
+
+ get test => _test;
+
+ set test(test) {
+ _test = test;
+ }
+}
+main(A a) {
+ print(a.test);
+}
+''');
+ }
+
+ test_parseError() async {
+ verifyNoTestUnitErrors = false;
+ await resolveTestUnit('''
+class A {
+ int; // marker
+}
+main(A a) {
+ print(a.test);
+}
+''');
+ await assertNoAssistAt('; // marker');
+ }
+
+ test_static() async {
+ await resolveTestUnit('''
+class A {
+ static int test = 42;
+}
+''');
+ await assertNoAssistAt('test =');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/exchange_operands_test.dart b/pkg/analysis_server/test/src/services/correction/assist/exchange_operands_test.dart
new file mode 100644
index 0000000..8bbcd52
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/exchange_operands_test.dart
@@ -0,0 +1,177 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ExchangeOperandsTest);
+ });
+}
+
+@reflectiveTest
+class ExchangeOperandsTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.EXCHANGE_OPERANDS;
+
+ test_compare() async {
+ const initialOperators = const ['<', '<=', '>', '>='];
+ const resultOperators = const ['>', '>=', '<', '<='];
+ for (int i = 0; i <= 0; i++) {
+ String initialOperator = initialOperators[i];
+ String resultOperator = resultOperators[i];
+ await resolveTestUnit('''
+bool main(int a, int b) {
+ return a $initialOperator b;
+}
+''');
+ await assertHasAssistAt(initialOperator, '''
+bool main(int a, int b) {
+ return b $resultOperator a;
+}
+''');
+ }
+ }
+
+ test_extended_mixOperator_1() async {
+ await resolveTestUnit('''
+main() {
+ 1 * 2 * 3 + 4;
+}
+''');
+ await assertHasAssistAt('* 2', '''
+main() {
+ 2 * 3 * 1 + 4;
+}
+''');
+ }
+
+ test_extended_mixOperator_2() async {
+ await resolveTestUnit('''
+main() {
+ 1 + 2 - 3 + 4;
+}
+''');
+ await assertHasAssistAt('+ 2', '''
+main() {
+ 2 + 1 - 3 + 4;
+}
+''');
+ }
+
+ test_extended_sameOperator_afterFirst() async {
+ await resolveTestUnit('''
+main() {
+ 1 + 2 + 3;
+}
+''');
+ await assertHasAssistAt('+ 2', '''
+main() {
+ 2 + 3 + 1;
+}
+''');
+ }
+
+ test_extended_sameOperator_afterSecond() async {
+ await resolveTestUnit('''
+main() {
+ 1 + 2 + 3;
+}
+''');
+ await assertHasAssistAt('+ 3', '''
+main() {
+ 3 + 1 + 2;
+}
+''');
+ }
+
+ test_extraLength() async {
+ await resolveTestUnit('''
+main() {
+ 111 + 222;
+}
+''');
+ await assertNoAssistAt('+ 222', length: 3);
+ }
+
+ test_onOperand() async {
+ await resolveTestUnit('''
+main() {
+ 111 + 222;
+}
+''');
+ await assertNoAssistAt('11 +', length: 3);
+ }
+
+ test_selectionWithBinary() async {
+ await resolveTestUnit('''
+main() {
+ 1 + 2 + 3;
+}
+''');
+ await assertNoAssistAt('1 + 2 + 3', length: '1 + 2 + 3'.length);
+ }
+
+ test_simple_afterOperator() async {
+ await resolveTestUnit('''
+main() {
+ 1 + 2;
+}
+''');
+ await assertHasAssistAt(' 2', '''
+main() {
+ 2 + 1;
+}
+''');
+ }
+
+ test_simple_beforeOperator() async {
+ await resolveTestUnit('''
+main() {
+ 1 + 2;
+}
+''');
+ await assertHasAssistAt('+ 2', '''
+main() {
+ 2 + 1;
+}
+''');
+ }
+
+ test_simple_fullSelection() async {
+ await resolveTestUnit('''
+main() {
+ 1 + 2;
+}
+''');
+ await assertHasAssistAt(
+ '1 + 2',
+ '''
+main() {
+ 2 + 1;
+}
+''',
+ length: '1 + 2'.length);
+ }
+
+ test_simple_withLength() async {
+ await resolveTestUnit('''
+main() {
+ 1 + 2;
+}
+''');
+ await assertHasAssistAt(
+ '+ 2',
+ '''
+main() {
+ 2 + 1;
+}
+''',
+ length: 2);
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_convert_to_children_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_convert_to_children_test.dart
new file mode 100644
index 0000000..8d34099
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_convert_to_children_test.dart
@@ -0,0 +1,158 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(FlutterConvertToChildrenTest);
+ });
+}
+
+@reflectiveTest
+class FlutterConvertToChildrenTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.FLUTTER_CONVERT_TO_CHILDREN;
+
+ test_childUnresolved() async {
+ addFlutterPackage();
+ verifyNoTestUnitErrors = false;
+ await resolveTestUnit('''
+import 'package:flutter/material.dart';
+build() {
+ return new Row(
+ /*caret*/child: new Container()
+ );
+}
+''');
+ await assertNoAssist();
+ }
+
+ test_multiLine() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/material.dart';
+build() {
+ return new Scaffold(
+// start
+ body: new Center(
+ /*caret*/child: new Container(
+ width: 200.0,
+ height: 300.0,
+ ),
+ key: null,
+ ),
+// end
+ );
+}
+''');
+ await assertHasAssist('''
+import 'package:flutter/material.dart';
+build() {
+ return new Scaffold(
+// start
+ body: new Center(
+ /*caret*/children: <Widget>[
+ new Container(
+ width: 200.0,
+ height: 300.0,
+ ),
+ ],
+ key: null,
+ ),
+// end
+ );
+}
+''');
+ }
+
+ test_newlineChild() async {
+ // This case could occur with deeply nested constructors, common in Flutter.
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/material.dart';
+build() {
+ return new Scaffold(
+// start
+ body: new Center(
+ /*caret*/child:
+ new Container(
+ width: 200.0,
+ height: 300.0,
+ ),
+ key: null,
+ ),
+// end
+ );
+}
+''');
+ await assertHasAssist('''
+import 'package:flutter/material.dart';
+build() {
+ return new Scaffold(
+// start
+ body: new Center(
+ /*caret*/children: <Widget>[
+ new Container(
+ width: 200.0,
+ height: 300.0,
+ ),
+ ],
+ key: null,
+ ),
+// end
+ );
+}
+''');
+ }
+
+ test_notOnChild() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/material.dart';
+build() {
+ return new Scaffold(
+ body: /*caret*/new Center(
+ child: new Container(),
+ ),
+ );
+}
+''');
+ await assertNoAssist();
+ }
+
+ test_singleLine() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/material.dart';
+build() {
+ return new Scaffold(
+// start
+ body: new Center(
+ /*caret*/child: new GestureDetector(),
+ key: null,
+ ),
+// end
+ );
+}
+''');
+ await assertHasAssist('''
+import 'package:flutter/material.dart';
+build() {
+ return new Scaffold(
+// start
+ body: new Center(
+ /*caret*/children: <Widget>[new GestureDetector()],
+ key: null,
+ ),
+// end
+ );
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_convert_to_stateful_widget_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_convert_to_stateful_widget_test.dart
new file mode 100644
index 0000000..977ea72
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_convert_to_stateful_widget_test.dart
@@ -0,0 +1,403 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(FlutterConvertToStatefulWidgetTest);
+ });
+}
+
+@reflectiveTest
+class FlutterConvertToStatefulWidgetTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.FLUTTER_CONVERT_TO_STATEFUL_WIDGET;
+
+ test_empty() async {
+ addFlutterPackage();
+ await resolveTestUnit(r'''
+import 'package:flutter/material.dart';
+
+class /*caret*/MyWidget extends StatelessWidget {
+ @override
+ Widget build(BuildContext context) {
+ return new Container();
+ }
+}
+''');
+ await assertHasAssist(r'''
+import 'package:flutter/material.dart';
+
+class /*caret*/MyWidget extends StatefulWidget {
+ @override
+ MyWidgetState createState() {
+ return new MyWidgetState();
+ }
+}
+
+class MyWidgetState extends State<MyWidget> {
+ @override
+ Widget build(BuildContext context) {
+ return new Container();
+ }
+}
+''');
+ }
+
+ test_fields() async {
+ addFlutterPackage();
+ await resolveTestUnit(r'''
+import 'package:flutter/material.dart';
+
+class /*caret*/MyWidget extends StatelessWidget {
+ static String staticField1;
+ final String instanceField1;
+ final String instanceField2;
+ String instanceField3;
+ static String staticField2;
+ String instanceField4;
+ String instanceField5;
+ static String staticField3;
+
+ MyWidget(this.instanceField1) : instanceField2 = '' {
+ instanceField3 = '';
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ instanceField4 = instanceField1;
+ return new Row(
+ children: [
+ new Text(instanceField1),
+ new Text(instanceField2),
+ new Text(instanceField3),
+ new Text(instanceField4),
+ new Text(instanceField5),
+ new Text(staticField1),
+ new Text(staticField2),
+ new Text(staticField3),
+ ],
+ );
+ }
+}
+''');
+ await assertHasAssist(r'''
+import 'package:flutter/material.dart';
+
+class /*caret*/MyWidget extends StatefulWidget {
+ static String staticField1;
+ final String instanceField1;
+ final String instanceField2;
+ String instanceField3;
+ static String staticField2;
+ static String staticField3;
+
+ MyWidget(this.instanceField1) : instanceField2 = '' {
+ instanceField3 = '';
+ }
+
+ @override
+ MyWidgetState createState() {
+ return new MyWidgetState();
+ }
+}
+
+class MyWidgetState extends State<MyWidget> {
+ String instanceField4;
+
+ String instanceField5;
+
+ @override
+ Widget build(BuildContext context) {
+ instanceField4 = widget.instanceField1;
+ return new Row(
+ children: [
+ new Text(widget.instanceField1),
+ new Text(widget.instanceField2),
+ new Text(widget.instanceField3),
+ new Text(instanceField4),
+ new Text(instanceField5),
+ new Text(MyWidget.staticField1),
+ new Text(MyWidget.staticField2),
+ new Text(MyWidget.staticField3),
+ ],
+ );
+ }
+}
+''');
+ }
+
+ test_getters() async {
+ addFlutterPackage();
+ await resolveTestUnit(r'''
+import 'package:flutter/material.dart';
+
+class /*caret*/MyWidget extends StatelessWidget {
+ @override
+ Widget build(BuildContext context) {
+ return new Row(
+ children: [
+ new Text(staticGetter1),
+ new Text(staticGetter2),
+ new Text(instanceGetter1),
+ new Text(instanceGetter2),
+ ],
+ );
+ }
+
+ static String get staticGetter1 => '';
+
+ String get instanceGetter1 => '';
+
+ static String get staticGetter2 => '';
+
+ String get instanceGetter2 => '';
+}
+''');
+ await assertHasAssist(r'''
+import 'package:flutter/material.dart';
+
+class /*caret*/MyWidget extends StatefulWidget {
+ @override
+ MyWidgetState createState() {
+ return new MyWidgetState();
+ }
+
+ static String get staticGetter1 => '';
+
+ static String get staticGetter2 => '';
+}
+
+class MyWidgetState extends State<MyWidget> {
+ @override
+ Widget build(BuildContext context) {
+ return new Row(
+ children: [
+ new Text(MyWidget.staticGetter1),
+ new Text(MyWidget.staticGetter2),
+ new Text(instanceGetter1),
+ new Text(instanceGetter2),
+ ],
+ );
+ }
+
+ String get instanceGetter1 => '';
+
+ String get instanceGetter2 => '';
+}
+''');
+ }
+
+ test_methods() async {
+ addFlutterPackage();
+ await resolveTestUnit(r'''
+import 'package:flutter/material.dart';
+
+class /*caret*/MyWidget extends StatelessWidget {
+ static String staticField;
+ final String instanceField1;
+ String instanceField2;
+
+ MyWidget(this.instanceField1);
+
+ @override
+ Widget build(BuildContext context) {
+ return new Row(
+ children: [
+ new Text(instanceField1),
+ new Text(instanceField2),
+ new Text(staticField),
+ ],
+ );
+ }
+
+ void instanceMethod1() {
+ instanceMethod1();
+ instanceMethod2();
+ staticMethod1();
+ }
+
+ static void staticMethod1() {
+ print('static 1');
+ }
+
+ void instanceMethod2() {
+ print('instance 2');
+ }
+
+ static void staticMethod2() {
+ print('static 2');
+ }
+}
+''');
+ await assertHasAssist(r'''
+import 'package:flutter/material.dart';
+
+class /*caret*/MyWidget extends StatefulWidget {
+ static String staticField;
+ final String instanceField1;
+
+ MyWidget(this.instanceField1);
+
+ @override
+ MyWidgetState createState() {
+ return new MyWidgetState();
+ }
+
+ static void staticMethod1() {
+ print('static 1');
+ }
+
+ static void staticMethod2() {
+ print('static 2');
+ }
+}
+
+class MyWidgetState extends State<MyWidget> {
+ String instanceField2;
+
+ @override
+ Widget build(BuildContext context) {
+ return new Row(
+ children: [
+ new Text(widget.instanceField1),
+ new Text(instanceField2),
+ new Text(MyWidget.staticField),
+ ],
+ );
+ }
+
+ void instanceMethod1() {
+ instanceMethod1();
+ instanceMethod2();
+ MyWidget.staticMethod1();
+ }
+
+ void instanceMethod2() {
+ print('instance 2');
+ }
+}
+''');
+ }
+
+ test_notClass() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/material.dart';
+/*caret*/main() {}
+''');
+ assertNoAssist();
+ }
+
+ test_notStatelessWidget() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/material.dart';
+class /*caret*/MyWidget extends Text {
+ MyWidget() : super('');
+}
+''');
+ assertNoAssist();
+ }
+
+ test_notWidget() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/material.dart';
+class /*caret*/MyWidget {}
+''');
+ assertNoAssist();
+ }
+
+ test_simple() async {
+ addFlutterPackage();
+ await resolveTestUnit(r'''
+import 'package:flutter/material.dart';
+
+class /*caret*/MyWidget extends StatelessWidget {
+ final String aaa;
+ final String bbb;
+
+ const MyWidget(this.aaa, this.bbb);
+
+ @override
+ Widget build(BuildContext context) {
+ return new Row(
+ children: [
+ new Text(aaa),
+ new Text(bbb),
+ new Text('$aaa'),
+ new Text('${bbb}'),
+ ],
+ );
+ }
+}
+''');
+ await assertHasAssist(r'''
+import 'package:flutter/material.dart';
+
+class /*caret*/MyWidget extends StatefulWidget {
+ final String aaa;
+ final String bbb;
+
+ const MyWidget(this.aaa, this.bbb);
+
+ @override
+ MyWidgetState createState() {
+ return new MyWidgetState();
+ }
+}
+
+class MyWidgetState extends State<MyWidget> {
+ @override
+ Widget build(BuildContext context) {
+ return new Row(
+ children: [
+ new Text(widget.aaa),
+ new Text(widget.bbb),
+ new Text('${widget.aaa}'),
+ new Text('${widget.bbb}'),
+ ],
+ );
+ }
+}
+''');
+ }
+
+ test_tail() async {
+ addFlutterPackage();
+ await resolveTestUnit(r'''
+import 'package:flutter/material.dart';
+
+class /*caret*/MyWidget extends StatelessWidget {
+ @override
+ Widget build(BuildContext context) {
+ return new Container();
+ }
+}
+''');
+ await assertHasAssist(r'''
+import 'package:flutter/material.dart';
+
+class /*caret*/MyWidget extends StatefulWidget {
+ @override
+ MyWidgetState createState() {
+ return new MyWidgetState();
+ }
+}
+
+class MyWidgetState extends State<MyWidget> {
+ @override
+ Widget build(BuildContext context) {
+ return new Container();
+ }
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_move_down_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_move_down_test.dart
new file mode 100644
index 0000000..5885e70
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_move_down_test.dart
@@ -0,0 +1,80 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(FlutterMoveDownTest);
+ });
+}
+
+@reflectiveTest
+class FlutterMoveDownTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.FLUTTER_MOVE_DOWN;
+
+ test_first() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/material.dart';
+main() {
+ new Column(
+ children: <Widget>[
+ new Text('aaa'),
+ /*caret*/new Text('bbbbbb'),
+ new Text('ccccccccc'),
+ ],
+ );
+}
+''');
+ await assertHasAssist('''
+import 'package:flutter/material.dart';
+main() {
+ new Column(
+ children: <Widget>[
+ new Text('aaa'),
+ /*caret*/new Text('ccccccccc'),
+ new Text('bbbbbb'),
+ ],
+ );
+}
+''');
+ assertExitPosition(before: "new Text('bbbbbb')");
+ }
+
+ test_last() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/material.dart';
+main() {
+ new Column(
+ children: <Widget>[
+ new Text('aaa'),
+ new Text('bbb'),
+ /*caret*/new Text('ccc'),
+ ],
+ );
+}
+''');
+ await assertNoAssist();
+ }
+
+ test_notInList() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/material.dart';
+main() {
+ new Center(
+ child: /*caret*/new Text('aaa'),
+ );
+}
+''');
+ await assertNoAssist();
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_move_up_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_move_up_test.dart
new file mode 100644
index 0000000..771bb73
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_move_up_test.dart
@@ -0,0 +1,80 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(FlutterMoveUpTest);
+ });
+}
+
+@reflectiveTest
+class FlutterMoveUpTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.FLUTTER_MOVE_UP;
+
+ test_first() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/material.dart';
+main() {
+ new Column(
+ children: <Widget>[
+ /*caret*/new Text('aaa'),
+ new Text('bbb'),
+ new Text('ccc'),
+ ],
+ );
+}
+''');
+ await assertNoAssist();
+ }
+
+ test_last() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/material.dart';
+main() {
+ new Column(
+ children: <Widget>[
+ new Text('aaa'),
+ /*caret*/new Text('bbbbbb'),
+ new Text('ccccccccc'),
+ ],
+ );
+}
+''');
+ await assertHasAssist('''
+import 'package:flutter/material.dart';
+main() {
+ new Column(
+ children: <Widget>[
+ new Text('bbbbbb'),
+ /*caret*/new Text('aaa'),
+ new Text('ccccccccc'),
+ ],
+ );
+}
+''');
+ assertExitPosition(before: "new Text('bbbbbb')");
+ }
+
+ test_notInList() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/material.dart';
+main() {
+ new Center(
+ child: /*caret*/new Text('aaa'),
+ );
+}
+''');
+ await assertNoAssist();
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_remove_widget_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_remove_widget_test.dart
new file mode 100644
index 0000000..842b191
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_remove_widget_test.dart
@@ -0,0 +1,236 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(FlutterRemoveWidgetTest);
+ });
+}
+
+@reflectiveTest
+class FlutterRemoveWidgetTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.FLUTTER_REMOVE_WIDGET;
+
+ test_childIntoChild_multiLine() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/material.dart';
+main() {
+ new Column(
+ children: <Widget>[
+ new Center(
+ child: new /*caret*/Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: new Center(
+ heightFactor: 0.5,
+ child: new Text('foo'),
+ ),
+ ),
+ ),
+ ],
+ );
+}
+''');
+ await assertHasAssist('''
+import 'package:flutter/material.dart';
+main() {
+ new Column(
+ children: <Widget>[
+ new Center(
+ child: new Center(
+ heightFactor: 0.5,
+ child: new Text('foo'),
+ ),
+ ),
+ ],
+ );
+}
+''');
+ }
+
+ test_childIntoChild_singleLine() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/material.dart';
+main() {
+ new Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: new /*caret*/Center(
+ heightFactor: 0.5,
+ child: new Text('foo'),
+ ),
+ );
+}
+''');
+ await assertHasAssist('''
+import 'package:flutter/material.dart';
+main() {
+ new Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: new Text('foo'),
+ );
+}
+''');
+ }
+
+ test_childIntoChildren() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/material.dart';
+main() {
+ new Column(
+ children: <Widget>[
+ new Text('foo'),
+ new /*caret*/Center(
+ heightFactor: 0.5,
+ child: new Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: new Text('bar'),
+ ),
+ ),
+ new Text('baz'),
+ ],
+ );
+}
+''');
+ await assertHasAssist('''
+import 'package:flutter/material.dart';
+main() {
+ new Column(
+ children: <Widget>[
+ new Text('foo'),
+ new Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: new Text('bar'),
+ ),
+ new Text('baz'),
+ ],
+ );
+}
+''');
+ }
+
+ test_childrenMultipleIntoChild() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/material.dart';
+main() {
+ new Center(
+ child: new /*caret*/Row(
+ children: [
+ new Text('aaa'),
+ new Text('bbb'),
+ ],
+ ),
+ );
+}
+''');
+ await assertNoAssist();
+ }
+
+ test_childrenOneIntoChild() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/material.dart';
+main() {
+ new Center(
+ child: /*caret*/new Column(
+ children: [
+ new Text('foo'),
+ ],
+ ),
+ );
+}
+''');
+ await assertHasAssist('''
+import 'package:flutter/material.dart';
+main() {
+ new Center(
+ child: /*caret*/new Text('foo'),
+ );
+}
+''');
+ }
+
+ test_childrenOneIntoReturn() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/material.dart';
+main() {
+ return /*caret*/new Column(
+ children: [
+ new Text('foo'),
+ ],
+ );
+}
+''');
+ await assertHasAssist('''
+import 'package:flutter/material.dart';
+main() {
+ return /*caret*/new Text('foo');
+}
+''');
+ }
+
+ test_intoChildren() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/material.dart';
+main() {
+ new Column(
+ children: <Widget>[
+ new Text('aaa'),
+ new /*caret*/Column(
+ children: [
+ new Row(
+ children: [
+ new Text('bbb'),
+ new Text('ccc'),
+ ],
+ ),
+ new Row(
+ children: [
+ new Text('ddd'),
+ new Text('eee'),
+ ],
+ ),
+ ],
+ ),
+ new Text('fff'),
+ ],
+ );
+}
+''');
+ await assertHasAssist('''
+import 'package:flutter/material.dart';
+main() {
+ new Column(
+ children: <Widget>[
+ new Text('aaa'),
+ new Row(
+ children: [
+ new Text('bbb'),
+ new Text('ccc'),
+ ],
+ ),
+ new Row(
+ children: [
+ new Text('ddd'),
+ new Text('eee'),
+ ],
+ ),
+ new Text('fff'),
+ ],
+ );
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_swap_with_child_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_swap_with_child_test.dart
new file mode 100644
index 0000000..03b6f84
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_swap_with_child_test.dart
@@ -0,0 +1,112 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(FlutterSwapWithChildTest);
+ });
+}
+
+@reflectiveTest
+class FlutterSwapWithChildTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.FLUTTER_SWAP_WITH_CHILD;
+
+ test_aroundCenter() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/material.dart';
+build() {
+ return new Scaffold(
+ body: new /*caret*/GestureDetector(
+ onTap: () => startResize(),
+ child: new Center(
+ child: new Container(
+ width: 200.0,
+ height: 300.0,
+ ),
+ key: null,
+ ),
+ ),
+ );
+}
+startResize() {}
+''');
+ await assertHasAssist('''
+import 'package:flutter/material.dart';
+build() {
+ return new Scaffold(
+ body: new Center(
+ key: null,
+ child: new /*caret*/GestureDetector(
+ onTap: () => startResize(),
+ child: new Container(
+ width: 200.0,
+ height: 300.0,
+ ),
+ ),
+ ),
+ );
+}
+startResize() {}
+''');
+ }
+
+ test_notFormatted() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/material.dart';
+
+class Foo extends StatefulWidget {
+ @override
+ _State createState() => new _State();
+}
+
+class _State extends State<Foo> {
+ @override
+ Widget build(BuildContext context) {
+ return new /*caret*/Expanded(
+ flex: 2,
+ child: new GestureDetector(
+ child: new Text(
+ 'foo',
+ ), onTap: () {
+ print(42);
+ },
+ ),
+ );
+ }
+}''');
+ await assertHasAssist('''
+import 'package:flutter/material.dart';
+
+class Foo extends StatefulWidget {
+ @override
+ _State createState() => new _State();
+}
+
+class _State extends State<Foo> {
+ @override
+ Widget build(BuildContext context) {
+ return new GestureDetector(
+ onTap: () {
+ print(42);
+ },
+ child: new /*caret*/Expanded(
+ flex: 2,
+ child: new Text(
+ 'foo',
+ ),
+ ),
+ );
+ }
+}''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_swap_with_parent_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_swap_with_parent_test.dart
new file mode 100644
index 0000000..d5ad1d3
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_swap_with_parent_test.dart
@@ -0,0 +1,160 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(FlutterSwapWithParentTest);
+ });
+}
+
+@reflectiveTest
+class FlutterSwapWithParentTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.FLUTTER_SWAP_WITH_PARENT;
+
+ test_inCenter() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/material.dart';
+build() {
+ return new Scaffold(
+ body: new Center(
+ child: new /*caret*/GestureDetector(
+ onTap: () => startResize(),
+ child: new Container(
+ width: 200.0,
+ height: 300.0,
+ ),
+ ),
+ key: null,
+ ),
+ );
+}
+startResize() {}
+''');
+ await assertHasAssist('''
+import 'package:flutter/material.dart';
+build() {
+ return new Scaffold(
+ body: new /*caret*/GestureDetector(
+ onTap: () => startResize(),
+ child: new Center(
+ key: null,
+ child: new Container(
+ width: 200.0,
+ height: 300.0,
+ ),
+ ),
+ ),
+ );
+}
+startResize() {}
+''');
+ }
+
+ test_notFormatted() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/material.dart';
+
+class Foo extends StatefulWidget {
+ @override
+ _State createState() => new _State();
+}
+
+class _State extends State<Foo> {
+ @override
+ Widget build(BuildContext context) {
+ return new GestureDetector(
+ child: new /*caret*/Expanded(
+ child: new Text(
+ 'foo',
+ ),
+ flex: 2,
+ ), onTap: () {
+ print(42);
+ },
+ );
+ }
+}''');
+ await assertHasAssist('''
+import 'package:flutter/material.dart';
+
+class Foo extends StatefulWidget {
+ @override
+ _State createState() => new _State();
+}
+
+class _State extends State<Foo> {
+ @override
+ Widget build(BuildContext context) {
+ return new /*caret*/Expanded(
+ flex: 2,
+ child: new GestureDetector(
+ onTap: () {
+ print(42);
+ },
+ child: new Text(
+ 'foo',
+ ),
+ ),
+ );
+ }
+}''');
+ }
+
+ test_outerIsInChildren() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/material.dart';
+main() {
+ new Column(
+ children: [
+ new Column(
+ children: [
+ new Padding(
+ padding: new EdgeInsets.all(16.0),
+ child: new /*caret*/Center(
+ child: new Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: <Widget>[],
+ ),
+ ),
+ ),
+ ],
+ ),
+ ],
+ );
+}
+''');
+ await assertHasAssist('''
+import 'package:flutter/material.dart';
+main() {
+ new Column(
+ children: [
+ new Column(
+ children: [
+ new /*caret*/Center(
+ child: new Padding(
+ padding: new EdgeInsets.all(16.0),
+ child: new Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: <Widget>[],
+ ),
+ ),
+ ),
+ ],
+ ),
+ ],
+ );
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_center_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_center_test.dart
new file mode 100644
index 0000000..4e300e2
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_center_test.dart
@@ -0,0 +1,84 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(FlutterWrapCenterTest);
+ });
+}
+
+@reflectiveTest
+class FlutterWrapCenterTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.FLUTTER_WRAP_CENTER;
+
+ test_aroundCenter() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+class FakeFlutter {
+ main() {
+ return /*caret*/new Center();
+ }
+}
+''');
+ await assertNoAssist();
+ }
+
+ test_aroundContainer() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+class FakeFlutter {
+ main() {
+ return /*caret*/new Container();
+ }
+}
+''');
+ await assertHasAssist('''
+import 'package:flutter/widgets.dart';
+class FakeFlutter {
+ main() {
+ return /*caret*/Center(child: new Container());
+ }
+}
+''');
+ }
+
+ test_aroundNamedConstructor() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+
+class MyWidget extends StatelessWidget {
+ MyWidget.named();
+
+ Widget build(BuildContext context) => null;
+}
+
+main() {
+ return MyWidget./*caret*/named();
+}
+''');
+ await assertHasAssist('''
+import 'package:flutter/widgets.dart';
+
+class MyWidget extends StatelessWidget {
+ MyWidget.named();
+
+ Widget build(BuildContext context) => null;
+}
+
+main() {
+ return Center(child: MyWidget./*caret*/named());
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_column_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_column_test.dart
new file mode 100644
index 0000000..cad4036
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_column_test.dart
@@ -0,0 +1,91 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(FlutterWrapColumnTest);
+ });
+}
+
+@reflectiveTest
+class FlutterWrapColumnTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.FLUTTER_WRAP_COLUMN;
+
+ test_coveredByWidget() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+
+class FakeFlutter {
+ main() {
+ return new Container(
+ child: new /*caret*/Text('aaa'),
+ );
+ }
+}
+''');
+ await assertHasAssist('''
+import 'package:flutter/widgets.dart';
+
+class FakeFlutter {
+ main() {
+ return new Container(
+ child: Column(
+ children: <Widget>[
+ new /*caret*/Text('aaa'),
+ ],
+ ),
+ );
+ }
+}
+''');
+ }
+
+ test_coversWidgets() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+
+class FakeFlutter {
+ main() {
+ return new Row(children: [
+ new Text('aaa'),
+// start
+ new Text('bbb'),
+ new Text('ccc'),
+// end
+ new Text('ddd'),
+ ]);
+ }
+}
+''');
+ await assertHasAssist('''
+import 'package:flutter/widgets.dart';
+
+class FakeFlutter {
+ main() {
+ return new Row(children: [
+ new Text('aaa'),
+// start
+ Column(
+ children: <Widget>[
+ new Text('bbb'),
+ new Text('ccc'),
+ ],
+ ),
+// end
+ new Text('ddd'),
+ ]);
+ }
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_container_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_container_test.dart
new file mode 100644
index 0000000..15f8433
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_container_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(FlutterWrapContainerTest);
+ });
+}
+
+@reflectiveTest
+class FlutterWrapContainerTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.FLUTTER_WRAP_CONTAINER;
+
+ test_aroundContainer() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+main() {
+ return /*caret*/new Container();
+}
+''');
+ await assertNoAssist();
+ }
+
+ test_aroundText() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+main() {
+ /*caret*/new Text('a');
+}
+''');
+ await assertHasAssist('''
+import 'package:flutter/widgets.dart';
+main() {
+ /*caret*/Container(child: new Text('a'));
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_generic_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_generic_test.dart
new file mode 100644
index 0000000..30b416b
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_generic_test.dart
@@ -0,0 +1,313 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(FlutterWrapGenericTest);
+ });
+}
+
+@reflectiveTest
+class FlutterWrapGenericTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.FLUTTER_WRAP_GENERIC;
+
+ test_minimal() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+/*caret*/x(){}
+''');
+ await assertNoAssist();
+ }
+
+ test_multiLine() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+build() {
+ return new Container(
+ child: new Row(
+// start
+ children: [/*caret*/
+ new Text('111'),
+ new Text('222'),
+ new Container(),
+ ],
+// end
+ ),
+ );
+}
+''');
+ await assertHasAssist('''
+import 'package:flutter/widgets.dart';
+build() {
+ return new Container(
+ child: new Row(
+// start
+ children: [
+ new widget(
+ children: [/*caret*/
+ new Text('111'),
+ new Text('222'),
+ new Container(),
+ ],
+ ),
+ ],
+// end
+ ),
+ );
+}
+''');
+ }
+
+ test_multiLine_inListLiteral() async {
+ verifyNoTestUnitErrors = false;
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+build() {
+ return new Container(
+ child: new Row(
+ children: [/*caret*/
+// start
+ new Transform(),
+ new Object(),
+ new AspectRatio(),
+// end
+ ],
+ ),
+ );
+}
+''');
+ await assertNoAssist();
+ }
+
+ test_multiLines() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+class FakeFlutter {
+ main() {
+ return new Container(
+// start
+ child: new /*caret*/DefaultTextStyle(
+ child: new Row(
+ children: <Widget>[
+ new Container(
+ ),
+ ],
+ ),
+ ),
+// end
+ );
+ }
+}
+''');
+ await assertHasAssist('''
+import 'package:flutter/widgets.dart';
+class FakeFlutter {
+ main() {
+ return new Container(
+// start
+ child: widget(
+ child: new /*caret*/DefaultTextStyle(
+ child: new Row(
+ children: <Widget>[
+ new Container(
+ ),
+ ],
+ ),
+ ),
+ ),
+// end
+ );
+ }
+}
+''');
+ }
+
+ test_multiLines_eol2() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+class FakeFlutter {\r
+ main() {\r
+ return new Container(\r
+// start\r
+ child: new /*caret*/DefaultTextStyle(\r
+ child: new Row(\r
+ children: <Widget>[\r
+ new Container(\r
+ ),\r
+ ],\r
+ ),\r
+ ),\r
+// end\r
+ );\r
+ }\r
+}\r
+''');
+ await assertHasAssist('''
+import 'package:flutter/widgets.dart';
+class FakeFlutter {\r
+ main() {\r
+ return new Container(\r
+// start\r
+ child: widget(\r
+ child: new /*caret*/DefaultTextStyle(\r
+ child: new Row(\r
+ children: <Widget>[\r
+ new Container(\r
+ ),\r
+ ],\r
+ ),\r
+ ),\r
+ ),\r
+// end\r
+ );\r
+ }\r
+}\r
+''');
+ }
+
+ test_prefixedIdentifier_identifier() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+
+abstract class Foo extends Widget {
+ Widget bar;
+}
+
+main(Foo foo) {
+ return foo./*caret*/bar;
+}
+''');
+ await assertHasAssist('''
+import 'package:flutter/widgets.dart';
+
+abstract class Foo extends Widget {
+ Widget bar;
+}
+
+main(Foo foo) {
+ return widget(child: foo./*caret*/bar);
+}
+''');
+ }
+
+ test_prefixedIdentifier_prefix() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+
+abstract class Foo extends Widget {
+ Widget bar;
+}
+
+main(Foo foo) {
+ return /*caret*/foo.bar;
+}
+''');
+ await assertHasAssist('''
+import 'package:flutter/widgets.dart';
+
+abstract class Foo extends Widget {
+ Widget bar;
+}
+
+main(Foo foo) {
+ return /*caret*/widget(child: foo.bar);
+}
+''');
+ }
+
+ test_singleLine() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+class FakeFlutter {
+ main() {
+ var obj;
+// start
+ return new Row(children: [/*caret*/ new Container()]);
+// end
+ }
+}
+''');
+ await assertNoAssist();
+ }
+
+ test_singleLine1() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+class FakeFlutter {
+ main() {
+// start
+ return /*caret*/new Container();
+// end
+ }
+}
+''');
+ await assertHasAssist('''
+import 'package:flutter/widgets.dart';
+class FakeFlutter {
+ main() {
+// start
+ return /*caret*/widget(child: new Container());
+// end
+ }
+}
+''');
+ }
+
+ test_singleLine2() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+class FakeFlutter {
+ main() {
+ return new ClipRect./*caret*/rect();
+ }
+}
+''');
+ await assertHasAssist('''
+import 'package:flutter/widgets.dart';
+class FakeFlutter {
+ main() {
+ return widget(child: new ClipRect./*caret*/rect());
+ }
+}
+''');
+ }
+
+ test_variable() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+class FakeFlutter {
+ main() {
+ var container = new Container();
+ return /*caret*/container;
+ }
+}
+''');
+ await assertHasAssist('''
+import 'package:flutter/widgets.dart';
+class FakeFlutter {
+ main() {
+ var container = new Container();
+ return /*caret*/widget(child: container);
+ }
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_padding_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_padding_test.dart
new file mode 100644
index 0000000..50b927b
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_padding_test.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(FlutterWrapPaddingTest);
+ });
+}
+
+@reflectiveTest
+class FlutterWrapPaddingTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.FLUTTER_WRAP_PADDING;
+
+ test_aroundContainer() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+class FakeFlutter {
+ main() {
+ return /*caret*/new Container();
+ }
+}
+''');
+ await assertHasAssist('''
+import 'package:flutter/widgets.dart';
+class FakeFlutter {
+ main() {
+ return /*caret*/Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: new Container(),
+ );
+ }
+}
+''');
+ }
+
+ test_aroundPadding() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+class FakeFlutter {
+ main() {
+ return /*caret*/new Padding();
+ }
+}
+''');
+ await assertNoAssist();
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_row_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_row_test.dart
new file mode 100644
index 0000000..c18ac34
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_row_test.dart
@@ -0,0 +1,61 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(FlutterWrapRowTest);
+ });
+}
+
+@reflectiveTest
+class FlutterWrapRowTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.FLUTTER_WRAP_ROW;
+
+ test_twoWidgets() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+
+class FakeFlutter {
+ main() {
+ return new Column(children: [
+ new Text('aaa'),
+// start
+ new Text('bbb'),
+ new Text('ccc'),
+// end
+ new Text('ddd'),
+ ]);
+ }
+}
+''');
+ await assertHasAssist('''
+import 'package:flutter/widgets.dart';
+
+class FakeFlutter {
+ main() {
+ return new Column(children: [
+ new Text('aaa'),
+// start
+ Row(
+ children: <Widget>[
+ new Text('bbb'),
+ new Text('ccc'),
+ ],
+ ),
+// end
+ new Text('ddd'),
+ ]);
+ }
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_stream_builder_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_stream_builder_test.dart
new file mode 100644
index 0000000..be7d5c2
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_stream_builder_test.dart
@@ -0,0 +1,59 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(FlutterWrapStreamBuilderTest);
+ });
+}
+
+@reflectiveTest
+class FlutterWrapStreamBuilderTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.FLUTTER_WRAP_STREAM_BUILDER;
+
+ test_aroundStreamBuilder() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+
+main() {
+ /*caret*/StreamBuilder(
+ stream: null,
+ builder: (context, snapshot) => null,
+ );
+}
+''');
+ await assertNoAssist();
+ }
+
+ test_aroundText() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+
+main() {
+ /*caret*/new Text('a');
+}
+''');
+ await assertHasAssist('''
+import 'package:flutter/widgets.dart';
+
+main() {
+ /*caret*/StreamBuilder<Object>(
+ stream: null,
+ builder: (context, snapshot) {
+ return new Text('a');
+ }
+ );
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/import_add_show_test.dart b/pkg/analysis_server/test/src/services/correction/assist/import_add_show_test.dart
new file mode 100644
index 0000000..4c62dde
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/import_add_show_test.dart
@@ -0,0 +1,101 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ImportAddShowTest);
+ });
+}
+
+@reflectiveTest
+class ImportAddShowTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.IMPORT_ADD_SHOW;
+
+ test_hasShow() async {
+ await resolveTestUnit('''
+import 'dart:math' show PI;
+main() {
+ PI;
+}
+''');
+ await assertNoAssistAt('import ');
+ }
+
+ test_hasUnresolvedIdentifier() async {
+ await resolveTestUnit('''
+import 'dart:math';
+main(x) {
+ PI;
+ return x.foo();
+}
+''');
+ await assertHasAssistAt('import ', '''
+import 'dart:math' show PI;
+main(x) {
+ PI;
+ return x.foo();
+}
+''');
+ }
+
+ test_onDirective() async {
+ await resolveTestUnit('''
+import 'dart:math';
+main() {
+ PI;
+ E;
+ max(1, 2);
+}
+''');
+ await assertHasAssistAt('import ', '''
+import 'dart:math' show E, PI, max;
+main() {
+ PI;
+ E;
+ max(1, 2);
+}
+''');
+ }
+
+ test_onUri() async {
+ await resolveTestUnit('''
+import 'dart:math';
+main() {
+ PI;
+ E;
+ max(1, 2);
+}
+''');
+ await assertHasAssistAt('art:math', '''
+import 'dart:math' show E, PI, max;
+main() {
+ PI;
+ E;
+ max(1, 2);
+}
+''');
+ }
+
+ test_unresolvedUri() async {
+ verifyNoTestUnitErrors = false;
+ await resolveTestUnit('''
+import '/no/such/lib.dart';
+''');
+ await assertNoAssistAt('import ');
+ }
+
+ test_unused() async {
+ await resolveTestUnit('''
+import 'dart:math';
+''');
+ await assertNoAssistAt('import ');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/introduce_local_cast_type_test.dart b/pkg/analysis_server/test/src/services/correction/assist/introduce_local_cast_type_test.dart
new file mode 100644
index 0000000..2201266
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/introduce_local_cast_type_test.dart
@@ -0,0 +1,127 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(IntroduceLocalCastTypeTest);
+ });
+}
+
+@reflectiveTest
+class IntroduceLocalCastTypeTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE;
+
+ test_introduceLocalTestedType_notBlock() async {
+ await resolveTestUnit('''
+main(p) {
+ if (p is String)
+ print('not a block');
+}
+''');
+ await assertNoAssistAt('if (p');
+ }
+
+ test_introduceLocalTestedType_notIsExpression() async {
+ await resolveTestUnit('''
+main(p) {
+ if (p == null) {
+ }
+}
+''');
+ await assertNoAssistAt('if (p');
+ }
+
+ test_introduceLocalTestedType_notStatement() async {
+ await resolveTestUnit('''
+class C {
+ bool b;
+ C(v) : b = v is int;
+}''');
+ await assertNoAssistAt('is int');
+ }
+
+ test_introduceLocalTestedType_if_is() async {
+ await resolveTestUnit('''
+class MyTypeName {}
+main(p) {
+ if (p is MyTypeName) {
+ }
+ p = null;
+}
+''');
+ String expected = '''
+class MyTypeName {}
+main(p) {
+ if (p is MyTypeName) {
+ MyTypeName myTypeName = p;
+ }
+ p = null;
+}
+''';
+ await assertHasAssistAt('is MyType', expected);
+ assertLinkedGroup(
+ 0,
+ ['myTypeName = '],
+ expectedSuggestions(LinkedEditSuggestionKind.VARIABLE,
+ ['myTypeName', 'typeName', 'name']));
+ // another good location
+ await assertHasAssistAt('if (p', expected);
+ }
+
+ test_introduceLocalTestedType_if_isNot() async {
+ await resolveTestUnit('''
+class MyTypeName {}
+main(p) {
+ if (p is! MyTypeName) {
+ return;
+ }
+}
+''');
+ String expected = '''
+class MyTypeName {}
+main(p) {
+ if (p is! MyTypeName) {
+ return;
+ }
+ MyTypeName myTypeName = p;
+}
+''';
+ await assertHasAssistAt('is! MyType', expected);
+ assertLinkedGroup(
+ 0,
+ ['myTypeName = '],
+ expectedSuggestions(LinkedEditSuggestionKind.VARIABLE,
+ ['myTypeName', 'typeName', 'name']));
+ // another good location
+ await assertHasAssistAt('if (p', expected);
+ }
+
+ test_introduceLocalTestedType_while() async {
+ await resolveTestUnit('''
+main(p) {
+ while (p is String) {
+ }
+ p = null;
+}
+''');
+ String expected = '''
+main(p) {
+ while (p is String) {
+ String s = p;
+ }
+ p = null;
+}
+''';
+ await assertHasAssistAt('is String', expected);
+ await assertHasAssistAt('while (p', expected);
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/invert_if_statement_test.dart b/pkg/analysis_server/test/src/services/correction/assist/invert_if_statement_test.dart
new file mode 100644
index 0000000..54ba0aa
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/invert_if_statement_test.dart
@@ -0,0 +1,61 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(InvertIfStatementTest);
+ });
+}
+
+@reflectiveTest
+class InvertIfStatementTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.INVERT_IF_STATEMENT;
+
+ test_blocks() async {
+ await resolveTestUnit('''
+main() {
+ if (true) {
+ 0;
+ } else {
+ 1;
+ }
+}
+''');
+ await assertHasAssistAt('if (', '''
+main() {
+ if (false) {
+ 1;
+ } else {
+ 0;
+ }
+}
+''');
+ }
+
+ test_statements() async {
+ await resolveTestUnit('''
+main() {
+ if (true)
+ 0;
+ else
+ 1;
+}
+''');
+ await assertHasAssistAt('if (', '''
+main() {
+ if (false)
+ 1;
+ else
+ 0;
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/join_if_with_inner_test.dart b/pkg/analysis_server/test/src/services/correction/assist/join_if_with_inner_test.dart
new file mode 100644
index 0000000..a57c603
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/join_if_with_inner_test.dart
@@ -0,0 +1,255 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(JoinInWithInnerTest);
+ });
+}
+
+@reflectiveTest
+class JoinInWithInnerTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.JOIN_IF_WITH_INNER;
+
+ test_conditionAndOr() async {
+ await resolveTestUnit('''
+main() {
+ if (1 == 1) {
+ if (2 == 2 || 3 == 3) {
+ print(0);
+ }
+ }
+}
+''');
+ await assertHasAssistAt('if (1 ==', '''
+main() {
+ if (1 == 1 && (2 == 2 || 3 == 3)) {
+ print(0);
+ }
+}
+''');
+ }
+
+ test_conditionInvocation() async {
+ await resolveTestUnit('''
+main() {
+ if (isCheck()) {
+ if (2 == 2) {
+ print(0);
+ }
+ }
+}
+bool isCheck() => false;
+''');
+ await assertHasAssistAt('if (isCheck', '''
+main() {
+ if (isCheck() && 2 == 2) {
+ print(0);
+ }
+}
+bool isCheck() => false;
+''');
+ }
+
+ test_conditionOrAnd() async {
+ await resolveTestUnit('''
+main() {
+ if (1 == 1 || 2 == 2) {
+ if (3 == 3) {
+ print(0);
+ }
+ }
+}
+''');
+ await assertHasAssistAt('if (1 ==', '''
+main() {
+ if ((1 == 1 || 2 == 2) && 3 == 3) {
+ print(0);
+ }
+}
+''');
+ }
+
+ test_innerNotIf() async {
+ await resolveTestUnit('''
+main() {
+ if (1 == 1) {
+ print(0);
+ }
+}
+''');
+ await assertNoAssistAt('if (1 ==');
+ }
+
+ test_innerWithElse() async {
+ await resolveTestUnit('''
+main() {
+ if (1 == 1) {
+ if (2 == 2) {
+ print(0);
+ } else {
+ print(1);
+ }
+ }
+}
+''');
+ await assertNoAssistAt('if (1 ==');
+ }
+
+ test_onCondition() async {
+ await resolveTestUnit('''
+main() {
+ if (1 == 1) {
+ if (2 == 2) {
+ print(0);
+ }
+ }
+}
+''');
+ await assertHasAssistAt('1 ==', '''
+main() {
+ if (1 == 1 && 2 == 2) {
+ print(0);
+ }
+}
+''');
+ }
+
+ test_simpleConditions_block_block() async {
+ await resolveTestUnit('''
+main() {
+ if (1 == 1) {
+ if (2 == 2) {
+ print(0);
+ }
+ }
+}
+''');
+ await assertHasAssistAt('if (1 ==', '''
+main() {
+ if (1 == 1 && 2 == 2) {
+ print(0);
+ }
+}
+''');
+ }
+
+ test_simpleConditions_block_single() async {
+ await resolveTestUnit('''
+main() {
+ if (1 == 1) {
+ if (2 == 2)
+ print(0);
+ }
+}
+''');
+ await assertHasAssistAt('if (1 ==', '''
+main() {
+ if (1 == 1 && 2 == 2) {
+ print(0);
+ }
+}
+''');
+ }
+
+ test_simpleConditions_single_blockMulti() async {
+ await resolveTestUnit('''
+main() {
+ if (1 == 1) {
+ if (2 == 2) {
+ print(1);
+ print(2);
+ print(3);
+ }
+ }
+}
+''');
+ await assertHasAssistAt('if (1 ==', '''
+main() {
+ if (1 == 1 && 2 == 2) {
+ print(1);
+ print(2);
+ print(3);
+ }
+}
+''');
+ }
+
+ test_simpleConditions_single_blockOne() async {
+ await resolveTestUnit('''
+main() {
+ if (1 == 1)
+ if (2 == 2) {
+ print(0);
+ }
+}
+''');
+ await assertHasAssistAt('if (1 ==', '''
+main() {
+ if (1 == 1 && 2 == 2) {
+ print(0);
+ }
+}
+''');
+ }
+
+ test_statementAfterInner() async {
+ await resolveTestUnit('''
+main() {
+ if (1 == 1) {
+ if (2 == 2) {
+ print(2);
+ }
+ print(1);
+ }
+}
+''');
+ await assertNoAssistAt('if (1 ==');
+ }
+
+ test_statementBeforeInner() async {
+ await resolveTestUnit('''
+main() {
+ if (1 == 1) {
+ print(1);
+ if (2 == 2) {
+ print(2);
+ }
+ }
+}
+''');
+ await assertNoAssistAt('if (1 ==');
+ }
+
+ test_targetNotIf() async {
+ await resolveTestUnit('''
+main() {
+ print(0);
+}
+''');
+ await assertNoAssistAt('print');
+ }
+
+ test_targetWithElse() async {
+ await resolveTestUnit('''
+main() {
+ if (1 == 1) {
+ if (2 == 2) {
+ print(0);
+ }
+ } else {
+ print(1);
+ }
+}
+''');
+ await assertNoAssistAt('if (1 ==');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/join_if_with_outer_test.dart b/pkg/analysis_server/test/src/services/correction/assist/join_if_with_outer_test.dart
new file mode 100644
index 0000000..ffbd3ab
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/join_if_with_outer_test.dart
@@ -0,0 +1,255 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(JoinIfWithOuterTest);
+ });
+}
+
+@reflectiveTest
+class JoinIfWithOuterTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.JOIN_IF_WITH_OUTER;
+
+ test_conditionAndOr() async {
+ await resolveTestUnit('''
+main() {
+ if (1 == 1) {
+ if (2 == 2 || 3 == 3) {
+ print(0);
+ }
+ }
+}
+''');
+ await assertHasAssistAt('if (2 ==', '''
+main() {
+ if (1 == 1 && (2 == 2 || 3 == 3)) {
+ print(0);
+ }
+}
+''');
+ }
+
+ test_conditionInvocation() async {
+ await resolveTestUnit('''
+main() {
+ if (1 == 1) {
+ if (isCheck()) {
+ print(0);
+ }
+ }
+}
+bool isCheck() => false;
+''');
+ await assertHasAssistAt('if (isCheck', '''
+main() {
+ if (1 == 1 && isCheck()) {
+ print(0);
+ }
+}
+bool isCheck() => false;
+''');
+ }
+
+ test_conditionOrAnd() async {
+ await resolveTestUnit('''
+main() {
+ if (1 == 1 || 2 == 2) {
+ if (3 == 3) {
+ print(0);
+ }
+ }
+}
+''');
+ await assertHasAssistAt('if (3 == 3', '''
+main() {
+ if ((1 == 1 || 2 == 2) && 3 == 3) {
+ print(0);
+ }
+}
+''');
+ }
+
+ test_onCondition() async {
+ await resolveTestUnit('''
+main() {
+ if (1 == 1) {
+ if (2 == 2) {
+ print(0);
+ }
+ }
+}
+''');
+ await assertHasAssistAt('if (2 == 2', '''
+main() {
+ if (1 == 1 && 2 == 2) {
+ print(0);
+ }
+}
+''');
+ }
+
+ test_outerNotIf() async {
+ await resolveTestUnit('''
+main() {
+ if (1 == 1) {
+ print(0);
+ }
+}
+''');
+ await assertNoAssistAt('if (1 == 1');
+ }
+
+ test_outerWithElse() async {
+ await resolveTestUnit('''
+main() {
+ if (1 == 1) {
+ if (2 == 2) {
+ print(0);
+ }
+ } else {
+ print(1);
+ }
+}
+''');
+ await assertNoAssistAt('if (2 == 2');
+ }
+
+ test_simpleConditions_block_block() async {
+ await resolveTestUnit('''
+main() {
+ if (1 == 1) {
+ if (2 == 2) {
+ print(0);
+ }
+ }
+}
+''');
+ await assertHasAssistAt('if (2 == 2', '''
+main() {
+ if (1 == 1 && 2 == 2) {
+ print(0);
+ }
+}
+''');
+ }
+
+ test_simpleConditions_block_single() async {
+ await resolveTestUnit('''
+main() {
+ if (1 == 1) {
+ if (2 == 2)
+ print(0);
+ }
+}
+''');
+ await assertHasAssistAt('if (2 == 2', '''
+main() {
+ if (1 == 1 && 2 == 2) {
+ print(0);
+ }
+}
+''');
+ }
+
+ test_simpleConditions_single_blockMulti() async {
+ await resolveTestUnit('''
+main() {
+ if (1 == 1) {
+ if (2 == 2) {
+ print(1);
+ print(2);
+ print(3);
+ }
+ }
+}
+''');
+ await assertHasAssistAt('if (2 == 2', '''
+main() {
+ if (1 == 1 && 2 == 2) {
+ print(1);
+ print(2);
+ print(3);
+ }
+}
+''');
+ }
+
+ test_simpleConditions_single_blockOne() async {
+ await resolveTestUnit('''
+main() {
+ if (1 == 1)
+ if (2 == 2) {
+ print(0);
+ }
+}
+''');
+ await assertHasAssistAt('if (2 == 2', '''
+main() {
+ if (1 == 1 && 2 == 2) {
+ print(0);
+ }
+}
+''');
+ }
+
+ test_statementAfterInner() async {
+ await resolveTestUnit('''
+main() {
+ if (1 == 1) {
+ if (2 == 2) {
+ print(2);
+ }
+ print(1);
+ }
+}
+''');
+ await assertNoAssistAt('if (2 == 2');
+ }
+
+ test_statementBeforeInner() async {
+ await resolveTestUnit('''
+main() {
+ if (1 == 1) {
+ print(1);
+ if (2 == 2) {
+ print(2);
+ }
+ }
+}
+''');
+ await assertNoAssistAt('if (2 == 2');
+ }
+
+ test_targetNotIf() async {
+ await resolveTestUnit('''
+main() {
+ print(0);
+}
+''');
+ await assertNoAssistAt('print');
+ }
+
+ test_targetWithElse() async {
+ await resolveTestUnit('''
+main() {
+ if (1 == 1) {
+ if (2 == 2) {
+ print(0);
+ } else {
+ print(1);
+ }
+ }
+}
+''');
+ await assertNoAssistAt('if (2 == 2');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/join_variable_declaration_test.dart b/pkg/analysis_server/test/src/services/correction/assist/join_variable_declaration_test.dart
new file mode 100644
index 0000000..3216240
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/join_variable_declaration_test.dart
@@ -0,0 +1,220 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(JoinVariableDeclarationTest);
+ });
+}
+
+@reflectiveTest
+class JoinVariableDeclarationTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.JOIN_VARIABLE_DECLARATION;
+
+ test_onAssignment() async {
+ await resolveTestUnit('''
+main() {
+ var v;
+ v = 1;
+}
+''');
+ await assertHasAssistAt('v =', '''
+main() {
+ var v = 1;
+}
+''');
+ }
+
+ test_onAssignment_hasInitializer() async {
+ await resolveTestUnit('''
+main() {
+ var v = 1;
+ v = 2;
+}
+''');
+ await assertNoAssistAt('v = 2');
+ }
+
+ test_onAssignment_notAdjacent() async {
+ await resolveTestUnit('''
+main() {
+ var v;
+ var bar;
+ v = 1;
+}
+''');
+ await assertNoAssistAt('v = 1');
+ }
+
+ test_onAssignment_notAssignment() async {
+ await resolveTestUnit('''
+main() {
+ var v;
+ v += 1;
+}
+''');
+ await assertNoAssistAt('v += 1');
+ }
+
+ test_onAssignment_notDeclaration() async {
+ await resolveTestUnit('''
+main(var v) {
+ v = 1;
+}
+''');
+ await assertNoAssistAt('v = 1');
+ }
+
+ test_onAssignment_notLeftArgument() async {
+ await resolveTestUnit('''
+main() {
+ var v;
+ 1 + v; // marker
+}
+''');
+ await assertNoAssistAt('v; // marker');
+ }
+
+ test_onAssignment_notOneVariable() async {
+ await resolveTestUnit('''
+main() {
+ var v, v2;
+ v = 1;
+}
+''');
+ await assertNoAssistAt('v = 1');
+ }
+
+ test_onAssignment_notResolved() async {
+ verifyNoTestUnitErrors = false;
+ await resolveTestUnit('''
+main() {
+ var v;
+ x = 1;
+}
+''');
+ await assertNoAssistAt('x = 1');
+ }
+
+ test_onAssignment_notSameBlock() async {
+ await resolveTestUnit('''
+main() {
+ var v;
+ {
+ v = 1;
+ }
+}
+''');
+ await assertNoAssistAt('v = 1');
+ }
+
+ test_onDeclaration_hasInitializer() async {
+ await resolveTestUnit('''
+main() {
+ var v = 1;
+ v = 2;
+}
+''');
+ await assertNoAssistAt('v = 1');
+ }
+
+ test_onDeclaration_lastStatement() async {
+ await resolveTestUnit('''
+main() {
+ if (true)
+ var v;
+}
+''');
+ await assertNoAssistAt('v;');
+ }
+
+ test_onDeclaration_nextNotAssignmentExpression() async {
+ await resolveTestUnit('''
+main() {
+ var v;
+ 42;
+}
+''');
+ await assertNoAssistAt('v;');
+ }
+
+ test_onDeclaration_nextNotExpressionStatement() async {
+ await resolveTestUnit('''
+main() {
+ var v;
+ if (true) return;
+}
+''');
+ await assertNoAssistAt('v;');
+ }
+
+ test_onDeclaration_nextNotPureAssignment() async {
+ await resolveTestUnit('''
+main() {
+ var v;
+ v += 1;
+}
+''');
+ await assertNoAssistAt('v;');
+ }
+
+ test_onDeclaration_notOneVariable() async {
+ await resolveTestUnit('''
+main() {
+ var v, v2;
+ v = 1;
+}
+''');
+ await assertNoAssistAt('v, ');
+ }
+
+ test_onDeclaration_onName() async {
+ await resolveTestUnit('''
+main() {
+ var v;
+ v = 1;
+}
+''');
+ await assertHasAssistAt('v;', '''
+main() {
+ var v = 1;
+}
+''');
+ }
+
+ test_onDeclaration_onType() async {
+ await resolveTestUnit('''
+main() {
+ int v;
+ v = 1;
+}
+''');
+ await assertHasAssistAt('int v', '''
+main() {
+ int v = 1;
+}
+''');
+ }
+
+ test_onDeclaration_onVar() async {
+ await resolveTestUnit('''
+main() {
+ var v;
+ v = 1;
+}
+''');
+ await assertHasAssistAt('var v', '''
+main() {
+ var v = 1;
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/remove_type_annotation_test.dart b/pkg/analysis_server/test/src/services/correction/assist/remove_type_annotation_test.dart
new file mode 100644
index 0000000..f57eee3
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/remove_type_annotation_test.dart
@@ -0,0 +1,147 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RemoveTypeAnnotationTest);
+ });
+}
+
+@reflectiveTest
+class RemoveTypeAnnotationTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.REMOVE_TYPE_ANNOTATION;
+
+ test_classField() async {
+ await resolveTestUnit('''
+class A {
+ int v = 1;
+}
+''');
+ await assertHasAssistAt('v = ', '''
+class A {
+ var v = 1;
+}
+''');
+ }
+
+ test_classField_final() async {
+ await resolveTestUnit('''
+class A {
+ final int v = 1;
+}
+''');
+ await assertHasAssistAt('v = ', '''
+class A {
+ final v = 1;
+}
+''');
+ }
+
+ test_field_noInitializer() async {
+ await resolveTestUnit('''
+class A {
+ int v;
+}
+''');
+ await assertNoAssistAt('v;');
+ }
+
+ test_localVariable_noInitializer() async {
+ await resolveTestUnit('''
+main() {
+ int v;
+}
+''');
+ await assertNoAssistAt('v;');
+ }
+
+ test_localVariable_onInitializer() async {
+ await resolveTestUnit('''
+main() {
+ final int v = 1;
+}
+''');
+ await assertNoAssistAt('1;');
+ }
+
+ test_localVariable() async {
+ await resolveTestUnit('''
+main() {
+ int a = 1, b = 2;
+}
+''');
+ await assertHasAssistAt('int ', '''
+main() {
+ var a = 1, b = 2;
+}
+''');
+ }
+
+ test_localVariable_const() async {
+ await resolveTestUnit('''
+main() {
+ const int v = 1;
+}
+''');
+ await assertHasAssistAt('int ', '''
+main() {
+ const v = 1;
+}
+''');
+ }
+
+ test_localVariable_final() async {
+ await resolveTestUnit('''
+main() {
+ final int v = 1;
+}
+''');
+ await assertHasAssistAt('int ', '''
+main() {
+ final v = 1;
+}
+''');
+ }
+
+ test_topLevelVariable_noInitializer() async {
+ verifyNoTestUnitErrors = false;
+ await resolveTestUnit('''
+int v;
+''');
+ await assertNoAssistAt('v;');
+ }
+
+ test_topLevelVariable_syntheticName() async {
+ verifyNoTestUnitErrors = false;
+ await resolveTestUnit('''
+MyType
+''');
+ await assertNoAssistAt('MyType');
+ }
+
+ test_topLevelVariable() async {
+ await resolveTestUnit('''
+int V = 1;
+''');
+ await assertHasAssistAt('int ', '''
+var V = 1;
+''');
+ }
+
+ test_topLevelVariable_final() async {
+ await resolveTestUnit('''
+final int V = 1;
+''');
+ await assertHasAssistAt('int ', '''
+final V = 1;
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/replace_conditional_with_if_else_test.dart b/pkg/analysis_server/test/src/services/correction/assist/replace_conditional_with_if_else_test.dart
new file mode 100644
index 0000000..4ef97dd
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/replace_conditional_with_if_else_test.dart
@@ -0,0 +1,103 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ReplaceConditionalWithIfElseTest);
+ });
+}
+
+@reflectiveTest
+class ReplaceConditionalWithIfElseTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE;
+
+ test_assignment() async {
+ await resolveTestUnit('''
+main() {
+ var v;
+ v = true ? 111 : 222;
+}
+''');
+ // on conditional
+ await assertHasAssistAt('11 :', '''
+main() {
+ var v;
+ if (true) {
+ v = 111;
+ } else {
+ v = 222;
+ }
+}
+''');
+ // on variable
+ await assertHasAssistAt('v =', '''
+main() {
+ var v;
+ if (true) {
+ v = 111;
+ } else {
+ v = 222;
+ }
+}
+''');
+ }
+
+ test_noEnclosingStatement() async {
+ await resolveTestUnit('''
+var v = true ? 111 : 222;
+''');
+ await assertNoAssistAt('? 111');
+ }
+
+ test_notConditional() async {
+ await resolveTestUnit('''
+main() {
+ var v = 42;
+}
+''');
+ await assertNoAssistAt('v = 42');
+ }
+
+ test_return() async {
+ await resolveTestUnit('''
+main() {
+ return true ? 111 : 222;
+}
+''');
+ await assertHasAssistAt('return ', '''
+main() {
+ if (true) {
+ return 111;
+ } else {
+ return 222;
+ }
+}
+''');
+ }
+
+ test_variableDeclaration() async {
+ await resolveTestUnit('''
+main() {
+ int a = 1, vvv = true ? 111 : 222, b = 2;
+}
+''');
+ await assertHasAssistAt('11 :', '''
+main() {
+ int a = 1, vvv, b = 2;
+ if (true) {
+ vvv = 111;
+ } else {
+ vvv = 222;
+ }
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/replace_if_else_with_conditional_test.dart b/pkg/analysis_server/test/src/services/correction/assist/replace_if_else_with_conditional_test.dart
new file mode 100644
index 0000000..a21af08
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/replace_if_else_with_conditional_test.dart
@@ -0,0 +1,95 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ReplaceIfElseWithConditionalTest);
+ });
+}
+
+@reflectiveTest
+class ReplaceIfElseWithConditionalTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.REPLACE_IF_ELSE_WITH_CONDITIONAL;
+
+ test_assignment() async {
+ await resolveTestUnit('''
+main() {
+ int vvv;
+ if (true) {
+ vvv = 111;
+ } else {
+ vvv = 222;
+ }
+}
+''');
+ await assertHasAssistAt('if (true)', '''
+main() {
+ int vvv;
+ vvv = true ? 111 : 222;
+}
+''');
+ }
+
+ test_expressionVsReturn() async {
+ await resolveTestUnit('''
+main() {
+ if (true) {
+ print(42);
+ } else {
+ return;
+ }
+}
+''');
+ await assertNoAssistAt('else');
+ }
+
+ test_notIfStatement() async {
+ await resolveTestUnit('''
+main() {
+ print(0);
+}
+''');
+ await assertNoAssistAt('print');
+ }
+
+ test_notSingleStatement() async {
+ await resolveTestUnit('''
+main() {
+ int vvv;
+ if (true) {
+ print(0);
+ vvv = 111;
+ } else {
+ print(0);
+ vvv = 222;
+ }
+}
+''');
+ await assertNoAssistAt('if (true)');
+ }
+
+ test_return() async {
+ await resolveTestUnit('''
+main() {
+ if (true) {
+ return 111;
+ } else {
+ return 222;
+ }
+}
+''');
+ await assertHasAssistAt('if (true)', '''
+main() {
+ return true ? 111 : 222;
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/split_and_condition_test.dart b/pkg/analysis_server/test/src/services/correction/assist/split_and_condition_test.dart
new file mode 100644
index 0000000..31127f0
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/split_and_condition_test.dart
@@ -0,0 +1,158 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(SplitAndConditionTest);
+ });
+}
+
+@reflectiveTest
+class SplitAndConditionTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.SPLIT_AND_CONDITION;
+
+ test_hasElse() async {
+ await resolveTestUnit('''
+main() {
+ if (1 == 1 && 2 == 2) {
+ print(1);
+ } else {
+ print(2);
+ }
+}
+''');
+ await assertNoAssistAt('&& 2');
+ }
+
+ test_innerAndExpression() async {
+ await resolveTestUnit('''
+main() {
+ if (1 == 1 && 2 == 2 && 3 == 3) {
+ print(0);
+ }
+}
+''');
+ await assertHasAssistAt('&& 2 == 2', '''
+main() {
+ if (1 == 1) {
+ if (2 == 2 && 3 == 3) {
+ print(0);
+ }
+ }
+}
+''');
+ }
+
+ test_notAnd() async {
+ await resolveTestUnit('''
+main() {
+ if (1 == 1 || 2 == 2) {
+ print(0);
+ }
+}
+''');
+ await assertNoAssistAt('|| 2');
+ }
+
+ test_notOnOperator() async {
+ await resolveTestUnit('''
+main() {
+ if (1 == 1 && 2 == 2) {
+ print(0);
+ }
+ print(3 == 3 && 4 == 4);
+}
+''');
+ await assertNoAssistAt('main() {');
+ }
+
+ test_notPartOfIf() async {
+ await resolveTestUnit('''
+main() {
+ print(1 == 1 && 2 == 2);
+}
+''');
+ await assertNoAssistAt('&& 2');
+ }
+
+ test_notTopLevelAnd() async {
+ await resolveTestUnit('''
+main() {
+ if (true || (1 == 1 && 2 == 2)) {
+ print(0);
+ }
+ if (true && (3 == 3 && 4 == 4)) {
+ print(0);
+ }
+}
+''');
+ await assertNoAssistAt('&& 2');
+ await assertNoAssistAt('&& 4');
+ }
+
+ test_selectionTooLarge() async {
+ await resolveTestUnit('''
+main() {
+ if (1 == 1
+// start
+&& 2
+// end
+== 2
+) {
+ print(0);
+ }
+ print(3 == 3 && 4 == 4);
+}
+''');
+ await assertNoAssist();
+ }
+
+ test_thenBlock() async {
+ await resolveTestUnit('''
+main() {
+ if (true && false) {
+ print(0);
+ if (3 == 3) {
+ print(1);
+ }
+ }
+}
+''');
+ await assertHasAssistAt('&& false', '''
+main() {
+ if (true) {
+ if (false) {
+ print(0);
+ if (3 == 3) {
+ print(1);
+ }
+ }
+ }
+}
+''');
+ }
+
+ test_thenStatement() async {
+ await resolveTestUnit('''
+main() {
+ if (true && false)
+ print(0);
+}
+''');
+ await assertHasAssistAt('&& false', '''
+main() {
+ if (true)
+ if (false)
+ print(0);
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/split_variable_declaration_test.dart b/pkg/analysis_server/test/src/services/correction/assist/split_variable_declaration_test.dart
new file mode 100644
index 0000000..2d88afc
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/split_variable_declaration_test.dart
@@ -0,0 +1,87 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(SplitVariableDeclarationTest);
+ });
+}
+
+@reflectiveTest
+class SplitVariableDeclarationTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.SPLIT_VARIABLE_DECLARATION;
+
+ test_notOneVariable() async {
+ await resolveTestUnit('''
+main() {
+ var v = 1, v2;
+}
+''');
+ await assertNoAssistAt('v = 1');
+ }
+
+ test_onName() async {
+ await resolveTestUnit('''
+main() {
+ var v = 1;
+}
+''');
+ await assertHasAssistAt('v =', '''
+main() {
+ var v;
+ v = 1;
+}
+''');
+ }
+
+ test_onType() async {
+ await resolveTestUnit('''
+main() {
+ int v = 1;
+}
+''');
+ await assertHasAssistAt('int ', '''
+main() {
+ int v;
+ v = 1;
+}
+''');
+ }
+
+ @failingTest
+ test_onType_prefixedByComment() async {
+ await resolveTestUnit('''
+main() {
+ /*comment*/int v = 1;
+}
+''');
+ await assertHasAssistAt('int ', '''
+main() {
+ /*comment*/int v;
+ v = 1;
+}
+''');
+ }
+
+ test_onVar() async {
+ await resolveTestUnit('''
+main() {
+ var v = 1;
+}
+''');
+ await assertHasAssistAt('var ', '''
+main() {
+ var v;
+ v = 1;
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/surround_with_block_test.dart b/pkg/analysis_server/test/src/services/correction/assist/surround_with_block_test.dart
new file mode 100644
index 0000000..f4647be
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/surround_with_block_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(SurroundWithBlockTest);
+ });
+}
+
+@reflectiveTest
+class SurroundWithBlockTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.SURROUND_WITH_BLOCK;
+
+ test_twoStatements() async {
+ await resolveTestUnit('''
+main() {
+// start
+ print(0);
+ print(1);
+// end
+}
+''');
+ await assertHasAssist('''
+main() {
+// start
+ {
+ print(0);
+ print(1);
+ }
+// end
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/surround_with_do_while_test.dart b/pkg/analysis_server/test/src/services/correction/assist/surround_with_do_while_test.dart
new file mode 100644
index 0000000..96fbd14
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/surround_with_do_while_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(SurroundWithDoWhileTest);
+ });
+}
+
+@reflectiveTest
+class SurroundWithDoWhileTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.SURROUND_WITH_DO_WHILE;
+
+ test_twoStatements() async {
+ await resolveTestUnit('''
+main() {
+// start
+ print(0);
+ print(1);
+// end
+}
+''');
+ await assertHasAssist('''
+main() {
+// start
+ do {
+ print(0);
+ print(1);
+ } while (condition);
+// end
+}
+''');
+ assertLinkedGroup(0, ['condition);']);
+ assertExitPosition(after: 'condition);');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/surround_with_for_in_test.dart b/pkg/analysis_server/test/src/services/correction/assist/surround_with_for_in_test.dart
new file mode 100644
index 0000000..c775e1c
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/surround_with_for_in_test.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(SurroundWithForInTest);
+ });
+}
+
+@reflectiveTest
+class SurroundWithForInTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.SURROUND_WITH_FOR_IN;
+
+ test_twoStatements() async {
+ await resolveTestUnit('''
+main() {
+// start
+ print(0);
+ print(1);
+// end
+}
+''');
+ await assertHasAssist('''
+main() {
+// start
+ for (var item in iterable) {
+ print(0);
+ print(1);
+ }
+// end
+}
+''');
+ assertLinkedGroup(0, ['item']);
+ assertLinkedGroup(1, ['iterable']);
+ assertExitPosition(after: ' }');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/surround_with_for_test.dart b/pkg/analysis_server/test/src/services/correction/assist/surround_with_for_test.dart
new file mode 100644
index 0000000..770684c
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/surround_with_for_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(SurroundWithForTest);
+ });
+}
+
+@reflectiveTest
+class SurroundWithForTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.SURROUND_WITH_FOR;
+
+ test_twoStatements() async {
+ await resolveTestUnit('''
+main() {
+// start
+ print(0);
+ print(1);
+// end
+}
+''');
+ await assertHasAssist('''
+main() {
+// start
+ for (var v = init; condition; increment) {
+ print(0);
+ print(1);
+ }
+// end
+}
+''');
+ assertLinkedGroup(0, ['v =']);
+ assertLinkedGroup(1, ['init;']);
+ assertLinkedGroup(2, ['condition;']);
+ assertLinkedGroup(3, ['increment']);
+ assertExitPosition(after: ' }');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/surround_with_if_test.dart b/pkg/analysis_server/test/src/services/correction/assist/surround_with_if_test.dart
new file mode 100644
index 0000000..de8df15
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/surround_with_if_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(SurroundWithIfTest);
+ });
+}
+
+@reflectiveTest
+class SurroundWithIfTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.SURROUND_WITH_IF;
+
+ test_twoStatements() async {
+ await resolveTestUnit('''
+main() {
+// start
+ print(0);
+ print(1);
+// end
+}
+''');
+ await assertHasAssist('''
+main() {
+// start
+ if (condition) {
+ print(0);
+ print(1);
+ }
+// end
+}
+''');
+ assertLinkedGroup(0, ['condition']);
+ assertExitPosition(after: ' }');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/surround_with_try_catch_test.dart b/pkg/analysis_server/test/src/services/correction/assist/surround_with_try_catch_test.dart
new file mode 100644
index 0000000..f39a5e0
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/surround_with_try_catch_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(SurroundWithTryCatchTest);
+ });
+}
+
+@reflectiveTest
+class SurroundWithTryCatchTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.SURROUND_WITH_TRY_CATCH;
+
+ test_twoStatements() async {
+ await resolveTestUnit('''
+main() {
+// start
+ print(0);
+ print(1);
+// end
+}
+''');
+ await assertHasAssist('''
+main() {
+// start
+ try {
+ print(0);
+ print(1);
+ } on Exception catch (e) {
+ // TODO
+ }
+// end
+}
+''');
+ assertLinkedGroup(0, ['Exception']);
+ assertLinkedGroup(1, ['e) {']);
+ assertLinkedGroup(2, ['// TODO']);
+ assertExitPosition(after: '// TODO');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/surround_with_try_finally_test.dart b/pkg/analysis_server/test/src/services/correction/assist/surround_with_try_finally_test.dart
new file mode 100644
index 0000000..7e9267c
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/surround_with_try_finally_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(SurroundWithTryFinallyTest);
+ });
+}
+
+@reflectiveTest
+class SurroundWithTryFinallyTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.SURROUND_WITH_TRY_FINALLY;
+
+ test_twoStatements() async {
+ await resolveTestUnit('''
+main() {
+// start
+ print(0);
+ print(1);
+// end
+}
+''');
+ await assertHasAssist('''
+main() {
+// start
+ try {
+ print(0);
+ print(1);
+ } finally {
+ // TODO
+ }
+// end
+}
+''');
+ assertLinkedGroup(0, ['// TODO']);
+ assertExitPosition(after: '// TODO');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/surround_with_while_test.dart b/pkg/analysis_server/test/src/services/correction/assist/surround_with_while_test.dart
new file mode 100644
index 0000000..939e211
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/surround_with_while_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2018, 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/src/services/correction/assist.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(SurroundWithWhileTest);
+ });
+}
+
+@reflectiveTest
+class SurroundWithWhileTest extends AssistProcessorTest {
+ @override
+ AssistKind get kind => DartAssistKind.SURROUND_WITH_WHILE;
+
+ test_twoStatements() async {
+ await resolveTestUnit('''
+main() {
+// start
+ print(0);
+ print(1);
+// end
+}
+''');
+ await assertHasAssist('''
+main() {
+// start
+ while (condition) {
+ print(0);
+ print(1);
+ }
+// end
+}
+''');
+ assertLinkedGroup(0, ['condition']);
+ assertExitPosition(after: ' }');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/test_all.dart b/pkg/analysis_server/test/src/services/correction/assist/test_all.dart
new file mode 100644
index 0000000..be58fce
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/test_all.dart
@@ -0,0 +1,129 @@
+// Copyright (c) 2018, 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:test_reflective_loader/test_reflective_loader.dart';
+
+import 'add_type_annotation_test.dart' as add_type_annotation;
+import 'assign_to_local_variable_test.dart' as assign_to_local_variable;
+import 'convert_class_to_mixin_test.dart' as convert_class_to_mixin;
+import 'convert_documentation_into_block_test.dart'
+ as convert_documentation_into_block;
+import 'convert_documentation_into_line_test.dart'
+ as convert_documentation_into_line;
+import 'convert_into_async_body_test.dart' as convert_into_async_body;
+import 'convert_into_block_body_test.dart' as convert_into_block_body;
+import 'convert_into_expression_body_test.dart' as convert_into_expression_body;
+import 'convert_into_final_field_test.dart' as convert_into_final_field;
+import 'convert_into_for_index_test.dart' as convert_into_for_index;
+import 'convert_into_generic_function_syntax_test.dart'
+ as convert_into_generic_function_syntax;
+import 'convert_into_getter_test.dart' as convert_into_getter;
+import 'convert_into_is_not_empty_test.dart' as convert_into_is_not_empty;
+import 'convert_into_is_not_test.dart' as convert_into_is_not;
+import 'convert_part_of_to_uri_test.dart' as convert_part_of_to_uri;
+import 'convert_to_double_quoted_string_test.dart'
+ as convert_to_double_quoted_string;
+import 'convert_to_field_parameter_test.dart' as convert_to_field_parameter;
+import 'convert_to_int_literal_test.dart' as convert_to_int_literal;
+import 'convert_to_normal_parameter_test.dart' as convert_to_normal_parameter;
+import 'convert_to_single_quoted_string_test.dart'
+ as convert_to_single_quoted_string;
+import 'encapsulate_field_test.dart' as encapsulate_field;
+import 'exchange_operands_test.dart' as exchange_operands;
+import 'flutter_convert_to_children_test.dart' as flutter_convert_to_children;
+import 'flutter_convert_to_stateful_widget_test.dart'
+ as flutter_convert_to_stateful_widget;
+import 'flutter_move_down_test.dart' as flutter_move_down;
+import 'flutter_move_up_test.dart' as flutter_move_up;
+import 'flutter_remove_widget_test.dart' as flutter_remove_widget;
+import 'flutter_swap_with_child_test.dart' as flutter_swap_with_child;
+import 'flutter_swap_with_parent_test.dart' as flutter_swap_with_parent;
+import 'flutter_wrap_center_test.dart' as flutter_wrap_center;
+import 'flutter_wrap_column_test.dart' as flutter_wrap_column;
+import 'flutter_wrap_container_test.dart' as flutter_wrap_container;
+import 'flutter_wrap_generic_test.dart' as flutter_wrap_generic;
+import 'flutter_wrap_padding_test.dart' as flutter_wrap_padding;
+import 'flutter_wrap_row_test.dart' as flutter_wrap_row;
+import 'flutter_wrap_stream_builder_test.dart' as flutter_wrap_stream_builder;
+import 'import_add_show_test.dart' as import_add_show;
+import 'introduce_local_cast_type_test.dart' as introduce_local_cast_type;
+import 'invert_if_statement_test.dart' as invert_if_statement;
+import 'join_if_with_inner_test.dart' as join_if_with_inner;
+import 'join_if_with_outer_test.dart' as join_if_with_outer;
+import 'join_variable_declaration_test.dart' as join_variable_declaration;
+import 'remove_type_annotation_test.dart' as remove_type_annotation;
+import 'replace_conditional_with_if_else_test.dart'
+ as replace_conditional_with_if_else;
+import 'replace_if_else_with_conditional_test.dart'
+ as replace_if_else_with_conditional;
+import 'split_and_condition_test.dart' as split_and_condition;
+import 'split_variable_declaration_test.dart' as split_variable_declaration;
+import 'surround_with_block_test.dart' as surround_with_block;
+import 'surround_with_do_while_test.dart' as surround_with_do_while;
+import 'surround_with_for_in_test.dart' as surround_with_for_in;
+import 'surround_with_for_test.dart' as surround_with_for;
+import 'surround_with_if_test.dart' as surround_with_if;
+import 'surround_with_try_catch_test.dart' as surround_with_try_catch;
+import 'surround_with_try_finally_test.dart' as surround_with_try_finally;
+import 'surround_with_while_test.dart' as surround_with_while;
+
+main() {
+ defineReflectiveSuite(() {
+ add_type_annotation.main();
+ assign_to_local_variable.main();
+ convert_class_to_mixin.main();
+ convert_documentation_into_block.main();
+ convert_documentation_into_line.main();
+ convert_into_async_body.main();
+ convert_into_block_body.main();
+ convert_into_expression_body.main();
+ convert_into_final_field.main();
+ convert_into_for_index.main();
+ convert_into_generic_function_syntax.main();
+ convert_into_getter.main();
+ convert_into_is_not.main();
+ convert_into_is_not_empty.main();
+ convert_part_of_to_uri.main();
+ convert_to_double_quoted_string.main();
+ convert_to_field_parameter.main();
+ convert_to_int_literal.main();
+ convert_to_normal_parameter.main();
+ convert_to_single_quoted_string.main();
+ encapsulate_field.main();
+ exchange_operands.main();
+ flutter_convert_to_children.main();
+ flutter_convert_to_stateful_widget.main();
+ flutter_move_down.main();
+ flutter_move_up.main();
+ flutter_remove_widget.main();
+ flutter_swap_with_child.main();
+ flutter_swap_with_parent.main();
+ flutter_wrap_center.main();
+ flutter_wrap_column.main();
+ flutter_wrap_container.main();
+ flutter_wrap_generic.main();
+ flutter_wrap_padding.main();
+ flutter_wrap_row.main();
+ flutter_wrap_stream_builder.main();
+ import_add_show.main();
+ introduce_local_cast_type.main();
+ invert_if_statement.main();
+ join_if_with_inner.main();
+ join_if_with_outer.main();
+ join_variable_declaration.main();
+ remove_type_annotation.main();
+ replace_conditional_with_if_else.main();
+ replace_if_else_with_conditional.main();
+ split_and_condition.main();
+ split_variable_declaration.main();
+ surround_with_block.main();
+ surround_with_do_while.main();
+ surround_with_for.main();
+ surround_with_for_in.main();
+ surround_with_if.main();
+ surround_with_try_catch.main();
+ surround_with_try_finally.main();
+ surround_with_while.main();
+ }, name: 'assist');
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_async_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_async_test.dart
new file mode 100644
index 0000000..49938b4
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_async_test.dart
@@ -0,0 +1,199 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AddAsyncTest);
+ });
+}
+
+@reflectiveTest
+class AddAsyncTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.ADD_ASYNC;
+
+ test_asyncFor() async {
+ await resolveTestUnit('''
+import 'dart:async';
+void main(Stream<String> names) {
+ await for (String name in names) {
+ print(name);
+ }
+}
+''');
+ await assertHasFix('''
+import 'dart:async';
+Future main(Stream<String> names) async {
+ await for (String name in names) {
+ print(name);
+ }
+}
+''');
+ }
+
+ test_blockFunctionBody_function() async {
+ await resolveTestUnit('''
+foo() {}
+main() {
+ await foo();
+}
+''');
+ await assertHasFix('''
+foo() {}
+main() async {
+ await foo();
+}
+''', errorFilter: (AnalysisError error) {
+ return error.errorCode ==
+ CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE;
+ });
+ }
+
+ test_blockFunctionBody_getter() async {
+ await resolveTestUnit('''
+int get foo => null;
+int f() {
+ await foo;
+ return 1;
+}
+''');
+ await assertHasFix('''
+int get foo => null;
+Future<int> f() async {
+ await foo;
+ return 1;
+}
+''', errorFilter: (AnalysisError error) {
+ return error.errorCode ==
+ CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE;
+ });
+ }
+
+ test_closure() async {
+ await resolveTestUnit('''
+import 'dart:async';
+
+void takeFutureCallback(Future callback()) {}
+
+void doStuff() => takeFutureCallback(() => await 1);
+''');
+ await assertHasFix('''
+import 'dart:async';
+
+void takeFutureCallback(Future callback()) {}
+
+void doStuff() => takeFutureCallback(() async => await 1);
+''', errorFilter: (AnalysisError error) {
+ return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT;
+ });
+ }
+
+ test_expressionFunctionBody() async {
+ await resolveTestUnit('''
+foo() {}
+main() => await foo();
+''');
+ await assertHasFix('''
+foo() {}
+main() async => await foo();
+''');
+ }
+
+ test_nullFunctionBody() async {
+ await resolveTestUnit('''
+var F = await;
+''');
+ await assertNoFix();
+ }
+
+ test_returnFuture_alreadyFuture() async {
+ await resolveTestUnit('''
+import 'dart:async';
+foo() {}
+Future<int> main() {
+ await foo();
+ return 42;
+}
+''');
+ await assertHasFix('''
+import 'dart:async';
+foo() {}
+Future<int> main() async {
+ await foo();
+ return 42;
+}
+''', errorFilter: (AnalysisError error) {
+ return error.errorCode ==
+ CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE;
+ });
+ }
+
+ test_returnFuture_dynamic() async {
+ await resolveTestUnit('''
+foo() {}
+dynamic main() {
+ await foo();
+ return 42;
+}
+''');
+ await assertHasFix('''
+foo() {}
+dynamic main() async {
+ await foo();
+ return 42;
+}
+''', errorFilter: (AnalysisError error) {
+ return error.errorCode ==
+ CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE;
+ });
+ }
+
+ test_returnFuture_nonFuture() async {
+ await resolveTestUnit('''
+foo() {}
+int main() {
+ await foo();
+ return 42;
+}
+''');
+ await assertHasFix('''
+foo() {}
+Future<int> main() async {
+ await foo();
+ return 42;
+}
+''', errorFilter: (AnalysisError error) {
+ return error.errorCode ==
+ CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE;
+ });
+ }
+
+ test_returnFuture_noType() async {
+ await resolveTestUnit('''
+foo() {}
+main() {
+ await foo();
+ return 42;
+}
+''');
+ await assertHasFix('''
+foo() {}
+main() async {
+ await foo();
+ return 42;
+}
+''', errorFilter: (AnalysisError error) {
+ return error.errorCode ==
+ CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE;
+ });
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_explicit_cast_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_explicit_cast_test.dart
new file mode 100644
index 0000000..e0ff288
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_explicit_cast_test.dart
@@ -0,0 +1,463 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AddExplicitCastTest);
+ });
+}
+
+@reflectiveTest
+class AddExplicitCastTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.ADD_EXPLICIT_CAST;
+
+ test_as() async {
+ await resolveTestUnit('''
+f(A a) {
+ C c = a as B;
+ print(c);
+}
+class A {}
+class B {}
+class C {}
+''');
+ await assertNoFix();
+ }
+
+ test_assignment_general() async {
+ await resolveTestUnit('''
+f(A a) {
+ B b;
+ b = a;
+ print(b);
+}
+class A {}
+class B {}
+''');
+ await assertHasFix('''
+f(A a) {
+ B b;
+ b = a as B;
+ print(b);
+}
+class A {}
+class B {}
+''');
+ }
+
+ test_assignment_general_all() async {
+ await resolveTestUnit('''
+f(A a) {
+ B b, b2;
+ b = a;
+ b2 = a;
+}
+class A {}
+class B {}
+''');
+ await assertHasFixAllFix(StaticTypeWarningCode.INVALID_ASSIGNMENT, '''
+f(A a) {
+ B b, b2;
+ b = a as B;
+ b2 = a as B;
+}
+class A {}
+class B {}
+''');
+ }
+
+ test_assignment_list() async {
+ await resolveTestUnit('''
+f(List<A> a) {
+ List<B> b;
+ b = a.where((e) => e is B).toList();
+ print(b);
+}
+class A {}
+class B {}
+''');
+ await assertHasFix('''
+f(List<A> a) {
+ List<B> b;
+ b = a.where((e) => e is B).cast<B>().toList();
+ print(b);
+}
+class A {}
+class B {}
+''');
+ }
+
+ test_assignment_list_all() async {
+ await resolveTestUnit('''
+f(List<A> a) {
+ List<B> b, b2;
+ b = a.where((e) => e is B).toList();
+ b2 = a.where((e) => e is B).toList();
+}
+class A {}
+class B {}
+''');
+ await assertHasFixAllFix(StaticTypeWarningCode.INVALID_ASSIGNMENT, '''
+f(List<A> a) {
+ List<B> b, b2;
+ b = a.where((e) => e is B).cast<B>().toList();
+ b2 = a.where((e) => e is B).cast<B>().toList();
+}
+class A {}
+class B {}
+''');
+ }
+
+ test_assignment_map() async {
+ await resolveTestUnit('''
+f(Map<A, B> a) {
+ Map<B, A> b;
+ b = a;
+ print(b);
+}
+class A {}
+class B {}
+''');
+ await assertHasFix('''
+f(Map<A, B> a) {
+ Map<B, A> b;
+ b = a.cast<B, A>();
+ print(b);
+}
+class A {}
+class B {}
+''');
+ }
+
+ test_assignment_map_all() async {
+ await resolveTestUnit('''
+f(Map<A, B> a) {
+ Map<B, A> b, b2;
+ b = a;
+ b2 = a;
+}
+class A {}
+class B {}
+''');
+ await assertHasFixAllFix(StaticTypeWarningCode.INVALID_ASSIGNMENT, '''
+f(Map<A, B> a) {
+ Map<B, A> b, b2;
+ b = a.cast<B, A>();
+ b2 = a.cast<B, A>();
+}
+class A {}
+class B {}
+''');
+ }
+
+ test_assignment_needsParens() async {
+ await resolveTestUnit('''
+f(A a) {
+ B b;
+ b = a..m();
+ print(b);
+}
+class A {
+ int m() => 0;
+}
+class B {}
+''');
+ await assertHasFix('''
+f(A a) {
+ B b;
+ b = (a..m()) as B;
+ print(b);
+}
+class A {
+ int m() => 0;
+}
+class B {}
+''');
+ }
+
+ test_assignment_needsParens_all() async {
+ await resolveTestUnit('''
+f(A a) {
+ B b, b2;
+ b = a..m();
+ b2 = a..m();
+}
+class A {
+ int m() => 0;
+}
+class B {}
+''');
+ await assertHasFixAllFix(StaticTypeWarningCode.INVALID_ASSIGNMENT, '''
+f(A a) {
+ B b, b2;
+ b = (a..m()) as B;
+ b2 = (a..m()) as B;
+}
+class A {
+ int m() => 0;
+}
+class B {}
+''');
+ }
+
+ test_assignment_set() async {
+ await resolveTestUnit('''
+f(Set<A> a) {
+ Set<B> b;
+ b = a;
+ print(b);
+}
+class A {}
+class B {}
+''');
+ await assertHasFix('''
+f(Set<A> a) {
+ Set<B> b;
+ b = a.cast<B>();
+ print(b);
+}
+class A {}
+class B {}
+''');
+ }
+
+ test_assignment_set_all() async {
+ await resolveTestUnit('''
+f(Set<A> a) {
+ Set<B> b, b2;
+ b = a;
+ b2 = a;
+}
+class A {}
+class B {}
+''');
+ await assertHasFixAllFix(StaticTypeWarningCode.INVALID_ASSIGNMENT, '''
+f(Set<A> a) {
+ Set<B> b, b2;
+ b = a.cast<B>();
+ b2 = a.cast<B>();
+}
+class A {}
+class B {}
+''');
+ }
+
+ test_cast() async {
+ await resolveTestUnit('''
+f(List<A> a) {
+ List<B> b = a.cast<A>();
+ print(b);
+}
+class A {}
+class B {}
+''');
+ await assertNoFix();
+ }
+
+ test_declaration_general() async {
+ await resolveTestUnit('''
+f(A a) {
+ B b = a;
+ print(b);
+}
+class A {}
+class B {}
+''');
+ await assertHasFix('''
+f(A a) {
+ B b = a as B;
+ print(b);
+}
+class A {}
+class B {}
+''');
+ }
+
+ test_declaration_general_all() async {
+ await resolveTestUnit('''
+f(A a) {
+ B b = a;
+ B b2 = a;
+}
+class A {}
+class B {}
+''');
+ await assertHasFixAllFix(StaticTypeWarningCode.INVALID_ASSIGNMENT, '''
+f(A a) {
+ B b = a as B;
+ B b2 = a as B;
+}
+class A {}
+class B {}
+''');
+ }
+
+ test_declaration_list() async {
+ await resolveTestUnit('''
+f(List<A> a) {
+ List<B> b = a.where((e) => e is B).toList();
+ print(b);
+}
+class A {}
+class B {}
+''');
+ await assertHasFix('''
+f(List<A> a) {
+ List<B> b = a.where((e) => e is B).cast<B>().toList();
+ print(b);
+}
+class A {}
+class B {}
+''');
+ }
+
+ test_declaration_list_all() async {
+ await resolveTestUnit('''
+f(List<A> a) {
+ List<B> b = a.where((e) => e is B).toList();
+ List<B> b2 = a.where((e) => e is B).toList();
+}
+class A {}
+class B {}
+''');
+ await assertHasFixAllFix(StaticTypeWarningCode.INVALID_ASSIGNMENT, '''
+f(List<A> a) {
+ List<B> b = a.where((e) => e is B).cast<B>().toList();
+ List<B> b2 = a.where((e) => e is B).cast<B>().toList();
+}
+class A {}
+class B {}
+''');
+ }
+
+ test_declaration_map() async {
+ await resolveTestUnit('''
+f(Map<A, B> a) {
+ Map<B, A> b = a;
+ print(b);
+}
+class A {}
+class B {}
+''');
+ await assertHasFix('''
+f(Map<A, B> a) {
+ Map<B, A> b = a.cast<B, A>();
+ print(b);
+}
+class A {}
+class B {}
+''');
+ }
+
+ test_declaration_map_all() async {
+ await resolveTestUnit('''
+f(Map<A, B> a) {
+ Map<B, A> b = a;
+ Map<B, A> b2 = a;
+}
+class A {}
+class B {}
+''');
+ await assertHasFixAllFix(StaticTypeWarningCode.INVALID_ASSIGNMENT, '''
+f(Map<A, B> a) {
+ Map<B, A> b = a.cast<B, A>();
+ Map<B, A> b2 = a.cast<B, A>();
+}
+class A {}
+class B {}
+''');
+ }
+
+ test_declaration_needsParens() async {
+ await resolveTestUnit('''
+f(A a) {
+ B b = a..m();
+ print(b);
+}
+class A {
+ int m() => 0;
+}
+class B {}
+''');
+ await assertHasFix('''
+f(A a) {
+ B b = (a..m()) as B;
+ print(b);
+}
+class A {
+ int m() => 0;
+}
+class B {}
+''');
+ }
+
+ test_declaration_needsParens_all() async {
+ await resolveTestUnit('''
+f(A a) {
+ B b = a..m();
+ B b2 = a..m();
+}
+class A {
+ int m() => 0;
+}
+class B {}
+''');
+ await assertHasFixAllFix(StaticTypeWarningCode.INVALID_ASSIGNMENT, '''
+f(A a) {
+ B b = (a..m()) as B;
+ B b2 = (a..m()) as B;
+}
+class A {
+ int m() => 0;
+}
+class B {}
+''');
+ }
+
+ test_declaration_set() async {
+ await resolveTestUnit('''
+f(Set<A> a) {
+ Set<B> b = a;
+ print(b);
+}
+class A {}
+class B {}
+''');
+ await assertHasFix('''
+f(Set<A> a) {
+ Set<B> b = a.cast<B>();
+ print(b);
+}
+class A {}
+class B {}
+''');
+ }
+
+ test_declaration_set_all() async {
+ await resolveTestUnit('''
+f(Set<A> a) {
+ Set<B> b = a;
+ Set<B> b2 = a;
+}
+class A {}
+class B {}
+''');
+ await assertHasFixAllFix(StaticTypeWarningCode.INVALID_ASSIGNMENT, '''
+f(Set<A> a) {
+ Set<B> b = a.cast<B>();
+ Set<B> b2 = a.cast<B>();
+}
+class A {}
+class B {}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_field_formal_parameters_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_field_formal_parameters_test.dart
new file mode 100644
index 0000000..172aee9
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_field_formal_parameters_test.dart
@@ -0,0 +1,123 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AddFieldFormalParametersTest);
+ });
+}
+
+@reflectiveTest
+class AddFieldFormalParametersTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.ADD_FIELD_FORMAL_PARAMETERS;
+
+ test_flutter() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+
+class MyWidget extends StatelessWidget {
+ final int a;
+ final int b;
+ final int c;
+
+ MyWidget({Key key, this.a}) : super(key: key);
+}
+''');
+ await assertHasFix('''
+import 'package:flutter/widgets.dart';
+
+class MyWidget extends StatelessWidget {
+ final int a;
+ final int b;
+ final int c;
+
+ MyWidget({Key key, this.a, this.b, this.c}) : super(key: key);
+}
+''');
+ }
+
+ test_hasRequiredParameter() async {
+ await resolveTestUnit('''
+class Test {
+ final int a;
+ final int b;
+ final int c;
+ Test(this.a);
+}
+''');
+ await assertHasFix('''
+class Test {
+ final int a;
+ final int b;
+ final int c;
+ Test(this.a, this.b, this.c);
+}
+''');
+ }
+
+ test_noParameters() async {
+ await resolveTestUnit('''
+class Test {
+ final int a;
+ final int b;
+ final int c;
+ Test();
+}
+''');
+ await assertHasFix('''
+class Test {
+ final int a;
+ final int b;
+ final int c;
+ Test(this.a, this.b, this.c);
+}
+''');
+ }
+
+ test_noRequiredParameter() async {
+ await resolveTestUnit('''
+class Test {
+ final int a;
+ final int b;
+ final int c;
+ Test([this.c]);
+}
+''');
+ await assertHasFix('''
+class Test {
+ final int a;
+ final int b;
+ final int c;
+ Test(this.a, this.b, [this.c]);
+}
+''');
+ }
+
+ test_notAllFinal() async {
+ await resolveTestUnit('''
+class Test {
+ final int a;
+ int b;
+ final int c;
+ Test();
+}
+''');
+ await assertHasFix('''
+class Test {
+ final int a;
+ int b;
+ final int c;
+ Test(this.a, this.c);
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_missing_parameter_named_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_missing_parameter_named_test.dart
new file mode 100644
index 0000000..0378f7e
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_missing_parameter_named_test.dart
@@ -0,0 +1,232 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AddMissingParameterNamedTest);
+ });
+}
+
+@reflectiveTest
+class AddMissingParameterNamedTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.ADD_MISSING_PARAMETER_NAMED;
+
+ test_constructor_hasNamed() async {
+ await resolveTestUnit('''
+class A {
+ A(int a, {int b}) {}
+}
+
+main() {
+ new A(1, b: 2, named: 3.0);
+}
+''');
+ await assertHasFix('''
+class A {
+ A(int a, {int b, double named}) {}
+}
+
+main() {
+ new A(1, b: 2, named: 3.0);
+}
+''');
+ }
+
+ test_constructor_hasRequired() async {
+ await resolveTestUnit('''
+class A {
+ A(int a) {}
+}
+
+main() {
+ new A(1, named: 2.0);
+}
+''');
+ await assertHasFix('''
+class A {
+ A(int a, {double named}) {}
+}
+
+main() {
+ new A(1, named: 2.0);
+}
+''');
+ }
+
+ test_constructor_noParameters() async {
+ await resolveTestUnit('''
+class A {
+ A() {}
+}
+
+main() {
+ new A(named: 42);
+}
+''');
+ await assertHasFix('''
+class A {
+ A({int named}) {}
+}
+
+main() {
+ new A(named: 42);
+}
+''');
+ }
+
+ test_constructor_noParameters_named() async {
+ await resolveTestUnit('''
+class A {
+ A.aaa() {}
+}
+
+main() {
+ new A.aaa(named: 42);
+}
+''');
+ await assertHasFix('''
+class A {
+ A.aaa({int named}) {}
+}
+
+main() {
+ new A.aaa(named: 42);
+}
+''');
+ }
+
+ test_function_hasNamed() async {
+ await resolveTestUnit('''
+test(int a, {int b: 0}) {}
+
+main() {
+ test(1, b: 2, named: 3.0);
+}
+''');
+ await assertHasFix('''
+test(int a, {int b: 0, double named}) {}
+
+main() {
+ test(1, b: 2, named: 3.0);
+}
+''');
+ }
+
+ test_function_hasRequired() async {
+ await resolveTestUnit('''
+test(int a) {}
+
+main() {
+ test(1, named: 2.0);
+}
+''');
+ await assertHasFix('''
+test(int a, {double named}) {}
+
+main() {
+ test(1, named: 2.0);
+}
+''');
+ }
+
+ test_function_noParameters() async {
+ await resolveTestUnit('''
+test() {}
+
+main() {
+ test(named: 42);
+}
+''');
+ await assertHasFix('''
+test({int named}) {}
+
+main() {
+ test(named: 42);
+}
+''');
+ }
+
+ test_method_hasNamed() async {
+ await resolveTestUnit('''
+class A {
+ test(int a, {int b: 0}) {}
+
+ main() {
+ test(1, b: 2, named: 3.0);
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ test(int a, {int b: 0, double named}) {}
+
+ main() {
+ test(1, b: 2, named: 3.0);
+ }
+}
+''');
+ }
+
+ test_method_hasOptionalPositional() async {
+ await resolveTestUnit('''
+class A {
+ test(int a, [int b]) {}
+
+ main() {
+ test(1, 2, named: 3.0);
+ }
+}
+''');
+ await assertNoFix();
+ }
+
+ test_method_hasRequired() async {
+ await resolveTestUnit('''
+class A {
+ test(int a) {}
+
+ main() {
+ test(1, named: 2.0);
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ test(int a, {double named}) {}
+
+ main() {
+ test(1, named: 2.0);
+ }
+}
+''');
+ }
+
+ test_method_noParameters() async {
+ await resolveTestUnit('''
+class A {
+ test() {}
+
+ main() {
+ test(named: 42);
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ test({int named}) {}
+
+ main() {
+ test(named: 42);
+ }
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_missing_parameter_positional_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_missing_parameter_positional_test.dart
new file mode 100644
index 0000000..ba8e53d
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_missing_parameter_positional_test.dart
@@ -0,0 +1,65 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AddMissingParameterPositionalTest);
+ });
+}
+
+@reflectiveTest
+class AddMissingParameterPositionalTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.ADD_MISSING_PARAMETER_POSITIONAL;
+
+ test_function_hasNamed() async {
+ await resolveTestUnit('''
+test({int a}) {}
+main() {
+ test(1);
+}
+''');
+ await assertNoFix();
+ }
+
+ test_function_hasZero() async {
+ await resolveTestUnit('''
+test() {}
+main() {
+ test(1);
+}
+''');
+ await assertHasFix('''
+test([int i]) {}
+main() {
+ test(1);
+}
+''');
+ }
+
+ test_method_hasOne() async {
+ await resolveTestUnit('''
+class A {
+ test(int a) {}
+ main() {
+ test(1, 2.0);
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ test(int a, [double d]) {}
+ main() {
+ test(1, 2.0);
+ }
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_missing_parameter_required_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_missing_parameter_required_test.dart
new file mode 100644
index 0000000..7e4dbdf
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_missing_parameter_required_test.dart
@@ -0,0 +1,142 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AddMissingParameterRequiredTest);
+ });
+}
+
+@reflectiveTest
+class AddMissingParameterRequiredTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.ADD_MISSING_PARAMETER_REQUIRED;
+
+ test_constructor_named_hasOne() async {
+ await resolveTestUnit('''
+class A {
+ A.named(int a) {}
+}
+main() {
+ new A.named(1, 2.0);
+}
+''');
+ await assertHasFix('''
+class A {
+ A.named(int a, double d) {}
+}
+main() {
+ new A.named(1, 2.0);
+}
+''');
+ }
+
+ test_constructor_unnamed_hasOne() async {
+ await resolveTestUnit('''
+class A {
+ A(int a) {}
+}
+main() {
+ new A(1, 2.0);
+}
+''');
+ await assertHasFix('''
+class A {
+ A(int a, double d) {}
+}
+main() {
+ new A(1, 2.0);
+}
+''');
+ }
+
+ test_function_hasNamed() async {
+ await resolveTestUnit('''
+test({int a}) {}
+main() {
+ test(1);
+}
+''');
+ await assertHasFix('''
+test(int i, {int a}) {}
+main() {
+ test(1);
+}
+''');
+ }
+
+ test_function_hasOne() async {
+ await resolveTestUnit('''
+test(int a) {}
+main() {
+ test(1, 2.0);
+}
+''');
+ await assertHasFix('''
+test(int a, double d) {}
+main() {
+ test(1, 2.0);
+}
+''');
+ }
+
+ test_function_hasZero() async {
+ await resolveTestUnit('''
+test() {}
+main() {
+ test(1);
+}
+''');
+ await assertHasFix('''
+test(int i) {}
+main() {
+ test(1);
+}
+''');
+ }
+
+ test_method_hasOne() async {
+ await resolveTestUnit('''
+class A {
+ test(int a) {}
+ main() {
+ test(1, 2.0);
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ test(int a, double d) {}
+ main() {
+ test(1, 2.0);
+ }
+}
+''');
+ }
+
+ test_method_hasZero() async {
+ await resolveTestUnit('''
+class A {
+ test() {}
+ main() {
+ test(1);
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ test(int i) {}
+ main() {
+ test(1);
+ }
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_missing_required_argument_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_missing_required_argument_test.dart
new file mode 100644
index 0000000..20df52c
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_missing_required_argument_test.dart
@@ -0,0 +1,369 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AddMissingRequiredArgumentTest);
+ });
+}
+
+@reflectiveTest
+class AddMissingRequiredArgumentTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.ADD_MISSING_REQUIRED_ARGUMENT;
+
+ test_cons_flutter_children() async {
+ addFlutterPackage();
+ addMetaPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+import 'package:meta/meta.dart';
+
+class MyWidget extends Widget {
+ MyWidget({@required List<Widget> children});
+}
+
+build() {
+ return new MyWidget();
+}
+''');
+ await assertHasFix('''
+import 'package:flutter/widgets.dart';
+import 'package:meta/meta.dart';
+
+class MyWidget extends Widget {
+ MyWidget({@required List<Widget> children});
+}
+
+build() {
+ return new MyWidget(children: <Widget>[],);
+}
+''');
+ }
+
+ test_cons_flutter_hasTrailingComma() async {
+ addFlutterPackage();
+ addMetaPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+import 'package:meta/meta.dart';
+
+class MyWidget extends Widget {
+ MyWidget({@required int a, @required int b});
+}
+
+build() {
+ return new MyWidget(a: 1,);
+}
+''');
+ await assertHasFix('''
+import 'package:flutter/widgets.dart';
+import 'package:meta/meta.dart';
+
+class MyWidget extends Widget {
+ MyWidget({@required int a, @required int b});
+}
+
+build() {
+ return new MyWidget(a: 1, b: null,);
+}
+''');
+ }
+
+ test_cons_single() async {
+ addMetaPackage();
+ addSource('/home/test/lib/a.dart', r'''
+import 'package:meta/meta.dart';
+
+class A {
+ A({@required int a}) {}
+}
+''');
+ await resolveTestUnit('''
+import 'package:test/a.dart';
+
+main() {
+ A a = new A();
+ print(a);
+}
+''');
+ await assertHasFix('''
+import 'package:test/a.dart';
+
+main() {
+ A a = new A(a: null);
+ print(a);
+}
+''');
+ }
+
+ test_cons_single_closure() async {
+ addMetaPackage();
+ addSource('/home/test/lib/a.dart', r'''
+import 'package:meta/meta.dart';
+
+typedef void VoidCallback();
+
+class A {
+ A({@required VoidCallback onPressed}) {}
+}
+''');
+ await resolveTestUnit('''
+import 'package:test/a.dart';
+
+main() {
+ A a = new A();
+ print(a);
+}
+''');
+ await assertHasFix('''
+import 'package:test/a.dart';
+
+main() {
+ A a = new A(onPressed: () {});
+ print(a);
+}
+''');
+ }
+
+ test_cons_single_closure_2() async {
+ addMetaPackage();
+ addSource('/home/test/lib/a.dart', r'''
+import 'package:meta/meta.dart';
+
+typedef void Callback(e);
+
+class A {
+ A({@required Callback callback}) {}
+}
+''');
+ await resolveTestUnit('''
+import 'package:test/a.dart';
+
+main() {
+ A a = new A();
+ print(a);
+}
+''');
+ await assertHasFix('''
+import 'package:test/a.dart';
+
+main() {
+ A a = new A(callback: (e) {});
+ print(a);
+}
+''');
+ }
+
+ test_cons_single_closure_3() async {
+ addMetaPackage();
+ addSource('/home/test/lib/a.dart', r'''
+import 'package:meta/meta.dart';
+
+typedef void Callback(a,b,c);
+
+class A {
+ A({@required Callback callback}) {}
+}
+''');
+ await resolveTestUnit('''
+import 'package:test/a.dart';
+
+main() {
+ A a = new A();
+ print(a);
+}
+''');
+ await assertHasFix('''
+import 'package:test/a.dart';
+
+main() {
+ A a = new A(callback: (a, b, c) {});
+ print(a);
+}
+''');
+ }
+
+ test_cons_single_closure_4() async {
+ addMetaPackage();
+ addSource('/home/test/lib/a.dart', r'''
+import 'package:meta/meta.dart';
+
+typedef int Callback(int a, String b,c);
+
+class A {
+ A({@required Callback callback}) {}
+}
+''');
+ await resolveTestUnit('''
+import 'package:test/a.dart';
+
+main() {
+ A a = new A();
+ print(a);
+}
+''');
+ await assertHasFix('''
+import 'package:test/a.dart';
+
+main() {
+ A a = new A(callback: (int a, String b, c) {});
+ print(a);
+}
+''');
+ }
+
+ test_cons_single_list() async {
+ addMetaPackage();
+ addSource('/home/test/lib/a.dart', r'''
+import 'package:meta/meta.dart';
+
+class A {
+ A({@required List<String> names}) {}
+}
+''');
+ await resolveTestUnit('''
+import 'package:test/a.dart';
+
+main() {
+ A a = new A();
+ print(a);
+}
+''');
+ await assertHasFix('''
+import 'package:test/a.dart';
+
+main() {
+ A a = new A(names: <String>[]);
+ print(a);
+}
+''');
+ }
+
+ test_multiple() async {
+ addMetaPackage();
+ await resolveTestUnit('''
+import 'package:meta/meta.dart';
+
+test({@required int a, @required int bcd}) {}
+main() {
+ test(a: 3);
+}
+''');
+ await assertHasFix('''
+import 'package:meta/meta.dart';
+
+test({@required int a, @required int bcd}) {}
+main() {
+ test(a: 3, bcd: null);
+}
+''');
+ }
+
+ test_multiple_1of2() async {
+ addMetaPackage();
+ await resolveTestUnit('''
+import 'package:meta/meta.dart';
+
+test({@required int a, @required int bcd}) {}
+main() {
+ test();
+}
+''');
+ await assertHasFix('''
+import 'package:meta/meta.dart';
+
+test({@required int a, @required int bcd}) {}
+main() {
+ test(a: null);
+}
+''', errorFilter: (error) => error.message.contains("'a'"));
+ }
+
+ test_multiple_2of2() async {
+ addMetaPackage();
+ await resolveTestUnit('''
+import 'package:meta/meta.dart';
+
+test({@required int a, @required int bcd}) {}
+main() {
+ test();
+}
+''');
+ await assertHasFix('''
+import 'package:meta/meta.dart';
+
+test({@required int a, @required int bcd}) {}
+main() {
+ test(bcd: null);
+}
+''', errorFilter: (error) => error.message.contains("'bcd'"));
+ }
+
+ test_single() async {
+ addMetaPackage();
+ await resolveTestUnit('''
+import 'package:meta/meta.dart';
+
+test({@required int abc}) {}
+main() {
+ test();
+}
+''');
+ await assertHasFix('''
+import 'package:meta/meta.dart';
+
+test({@required int abc}) {}
+main() {
+ test(abc: null);
+}
+''');
+ }
+
+ test_single_normal() async {
+ addMetaPackage();
+ await resolveTestUnit('''
+import 'package:meta/meta.dart';
+
+test(String x, {@required int abc}) {}
+main() {
+ test("foo");
+}
+''');
+ await assertHasFix('''
+import 'package:meta/meta.dart';
+
+test(String x, {@required int abc}) {}
+main() {
+ test("foo", abc: null);
+}
+''');
+ }
+
+ test_single_with_details() async {
+ addMetaPackage();
+ await resolveTestUnit('''
+import 'package:meta/meta.dart';
+
+test({@Required("Really who doesn't need an abc?") int abc}) {}
+main() {
+ test();
+}
+''');
+ await assertHasFix('''
+import 'package:meta/meta.dart';
+
+test({@Required("Really who doesn't need an abc?") int abc}) {}
+main() {
+ test(abc: null);
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_ne_null_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_ne_null_test.dart
new file mode 100644
index 0000000..c8b6d00
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_ne_null_test.dart
@@ -0,0 +1,62 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AddNeNullTest);
+ });
+}
+
+@reflectiveTest
+class AddNeNullTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.ADD_NE_NULL;
+
+ test_nonBoolCondition() async {
+ await resolveTestUnit('''
+main(String p) {
+ if (p) {
+ print(p);
+ }
+}
+''');
+ await assertHasFix('''
+main(String p) {
+ if (p != null) {
+ print(p);
+ }
+}
+''');
+ }
+
+ test_nonBoolCondition_all() async {
+ await resolveTestUnit('''
+main(String p, String q) {
+ if (p) {
+ print(p);
+ }
+ if (q) {
+ print(q);
+ }
+}
+''');
+ await assertHasFixAllFix(StaticTypeWarningCode.NON_BOOL_CONDITION, '''
+main(String p, String q) {
+ if (p != null) {
+ print(p);
+ }
+ if (q != null) {
+ print(q);
+ }
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_override_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_override_test.dart
new file mode 100644
index 0000000..8a1cf11
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_override_test.dart
@@ -0,0 +1,179 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AddOverrideTest);
+ });
+}
+
+@reflectiveTest
+class AddOverrideTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.ADD_OVERRIDE;
+
+ @override
+ String get lintCode => LintNames.annotate_overrides;
+
+ test_field() async {
+ await resolveTestUnit('''
+class abstract Test {
+ int get t;
+}
+class Sub extends Test {
+ int /*LINT*/t = 42;
+}
+''');
+ await assertHasFix('''
+class abstract Test {
+ int get t;
+}
+class Sub extends Test {
+ @override
+ int /*LINT*/t = 42;
+}
+''');
+ }
+
+ test_getter() async {
+ await resolveTestUnit('''
+class Test {
+ int get t => null;
+}
+class Sub extends Test {
+ int get /*LINT*/t => null;
+}
+''');
+ await assertHasFix('''
+class Test {
+ int get t => null;
+}
+class Sub extends Test {
+ @override
+ int get /*LINT*/t => null;
+}
+''');
+ }
+
+ test_method() async {
+ await resolveTestUnit('''
+class Test {
+ void t() { }
+}
+class Sub extends Test {
+ void /*LINT*/t() { }
+}
+''');
+ await assertHasFix('''
+class Test {
+ void t() { }
+}
+class Sub extends Test {
+ @override
+ void /*LINT*/t() { }
+}
+''');
+ }
+
+ test_method_with_doc_comment() async {
+ await resolveTestUnit('''
+class Test {
+ void t() { }
+}
+class Sub extends Test {
+ /// Doc comment.
+ void /*LINT*/t() { }
+}
+''');
+ await assertHasFix('''
+class Test {
+ void t() { }
+}
+class Sub extends Test {
+ /// Doc comment.
+ @override
+ void /*LINT*/t() { }
+}
+''');
+ }
+
+ test_method_with_doc_comment_2() async {
+ await resolveTestUnit('''
+class Test {
+ void t() { }
+}
+class Sub extends Test {
+ /**
+ * Doc comment.
+ */
+ void /*LINT*/t() { }
+}
+''');
+ await assertHasFix('''
+class Test {
+ void t() { }
+}
+class Sub extends Test {
+ /**
+ * Doc comment.
+ */
+ @override
+ void /*LINT*/t() { }
+}
+''');
+ }
+
+ test_method_with_doc_comment_and_metadata() async {
+ await resolveTestUnit('''
+class Test {
+ void t() { }
+}
+class Sub extends Test {
+ /// Doc comment.
+ @foo
+ void /*LINT*/t() { }
+}
+''');
+ await assertHasFix('''
+class Test {
+ void t() { }
+}
+class Sub extends Test {
+ /// Doc comment.
+ @override
+ @foo
+ void /*LINT*/t() { }
+}
+''');
+ }
+
+ test_method_with_non_doc_comment() async {
+ await resolveTestUnit('''
+class Test {
+ void t() { }
+}
+class Sub extends Test {
+ // Non-doc comment.
+ void /*LINT*/t() { }
+}
+''');
+ await assertHasFix('''
+class Test {
+ void t() { }
+}
+class Sub extends Test {
+ // Non-doc comment.
+ @override
+ void /*LINT*/t() { }
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_required_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_required_test.dart
new file mode 100644
index 0000000..eae5d92
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_required_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AddRequiredTest);
+ });
+}
+
+@reflectiveTest
+class AddRequiredTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.ADD_REQUIRED;
+
+ @override
+ String get lintCode => LintNames.always_require_non_null_named_parameters;
+
+ test_withAssert() async {
+ await resolveTestUnit('''
+void function({String /*LINT*/param}) {
+ assert(param != null);
+}
+''');
+ await assertHasFix('''
+void function({@required String /*LINT*/param}) {
+ assert(param != null);
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_static_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_static_test.dart
new file mode 100644
index 0000000..bf136bd
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_static_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AddStaticTest);
+ });
+}
+
+@reflectiveTest
+class AddStaticTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.ADD_STATIC;
+
+ test_multipleFields() async {
+ await resolveTestUnit('''
+class C {
+ const int x = 0, y = 0;
+}
+''');
+ await assertHasFix('''
+class C {
+ static const int x = 0, y = 0;
+}
+''');
+ }
+
+ test_oneField() async {
+ await resolveTestUnit('''
+class C {
+ const int x = 0;
+}
+''');
+ await assertHasFix('''
+class C {
+ static const int x = 0;
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_super_constructor_invocation_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_super_constructor_invocation_test.dart
new file mode 100644
index 0000000..f6282cc
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_super_constructor_invocation_test.dart
@@ -0,0 +1,111 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AddSuperConstructorInvocationTest);
+ });
+}
+
+@reflectiveTest
+class AddSuperConstructorInvocationTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION;
+
+ test_hasInitializers() async {
+ await resolveTestUnit('''
+class A {
+ A(int p);
+}
+class B extends A {
+ int field;
+ B() : field = 42 {}
+}
+''');
+ await assertHasFix('''
+class A {
+ A(int p);
+}
+class B extends A {
+ int field;
+ B() : field = 42, super(0) {}
+}
+''');
+ }
+
+ test_named() async {
+ await resolveTestUnit('''
+class A {
+ A.named(int p);
+}
+class B extends A {
+ B() {}
+}
+''');
+ await assertHasFix('''
+class A {
+ A.named(int p);
+}
+class B extends A {
+ B() : super.named(0) {}
+}
+''');
+ }
+
+ test_named_private() async {
+ await resolveTestUnit('''
+class A {
+ A._named(int p);
+}
+class B extends A {
+ B() {}
+}
+''');
+ await assertNoFix();
+ }
+
+ test_requiredAndNamed() async {
+ await resolveTestUnit('''
+class A {
+ A(bool p1, int p2, double p3, String p4, {p5});
+}
+class B extends A {
+ B() {}
+}
+''');
+ await assertHasFix('''
+class A {
+ A(bool p1, int p2, double p3, String p4, {p5});
+}
+class B extends A {
+ B() : super(false, 0, 0.0, '') {}
+}
+''');
+ }
+
+ test_typeArgument() async {
+ await resolveTestUnit('''
+class A<T> {
+ A(T p);
+}
+class B extends A<int> {
+ B();
+}
+''');
+ await assertHasFix('''
+class A<T> {
+ A(T p);
+}
+class B extends A<int> {
+ B() : super(0);
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/change_to_nearest_precise_value_test.dart b/pkg/analysis_server/test/src/services/correction/fix/change_to_nearest_precise_value_test.dart
new file mode 100644
index 0000000..01c6749
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/change_to_nearest_precise_value_test.dart
@@ -0,0 +1,66 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ChangeToNearestPreciseValueTest);
+ });
+}
+
+@reflectiveTest
+class ChangeToNearestPreciseValueTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.CHANGE_TO_NEAREST_PRECISE_VALUE;
+
+ test_impreciseIntAsDouble() async {
+ await resolveTestUnit('''
+double x = 1000000000000000000000000;
+''');
+ await assertHasFix('''
+double x = 999999999999999983222784;
+''');
+ }
+
+ test_impreciseIntAsDouble_asCapitalHex() async {
+ await resolveTestUnit('''
+double x = 0X1000000000000000000000001;
+''');
+ await assertHasFix('''
+double x = 0x1000000000000000000000000;
+''');
+ }
+
+ test_impreciseIntAsDouble_asHex() async {
+ await resolveTestUnit('''
+double x = 0x1000000000000000000000001;
+''');
+ await assertHasFix('''
+double x = 0x1000000000000000000000000;
+''');
+ }
+
+ test_impreciseIntAsDouble_maxValue() async {
+ await resolveTestUnit('''
+double x = 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;
+''');
+ await assertHasFix('''
+double x = 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368;
+''');
+ }
+
+ test_impreciseIntAsDouble_maxValue_asHex() async {
+ await resolveTestUnit('''
+double x = 0x100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;
+''');
+ await assertHasFix('''
+double x = 0xFFFFFFFFFFFFF800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/change_to_static_access_test.dart b/pkg/analysis_server/test/src/services/correction/fix/change_to_static_access_test.dart
new file mode 100644
index 0000000..507b291
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/change_to_static_access_test.dart
@@ -0,0 +1,130 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ChangeToStaticAccessTest);
+ });
+}
+
+@reflectiveTest
+class ChangeToStaticAccessTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.CHANGE_TO_STATIC_ACCESS;
+
+ test_method() async {
+ await resolveTestUnit('''
+class A {
+ static foo() {}
+}
+main(A a) {
+ a.foo();
+}
+''');
+ await assertHasFix('''
+class A {
+ static foo() {}
+}
+main(A a) {
+ A.foo();
+}
+''');
+ }
+
+ test_method_importType() async {
+ addSource('/home/test/lib/a.dart', r'''
+class A {
+ static foo() {}
+}
+''');
+ addSource('/home/test/lib/b.dart', r'''
+import 'package:test/a.dart';
+
+class B extends A {}
+''');
+ await resolveTestUnit('''
+import 'package:test/b.dart';
+
+main(B b) {
+ b.foo();
+}
+''');
+ await assertHasFix('''
+import 'package:test/a.dart';
+import 'package:test/b.dart';
+
+main(B b) {
+ A.foo();
+}
+''');
+ }
+
+ test_method_prefixLibrary() async {
+ await resolveTestUnit('''
+import 'dart:async' as pref;
+main(pref.Future f) {
+ f.wait([]);
+}
+''');
+ await assertHasFix('''
+import 'dart:async' as pref;
+main(pref.Future f) {
+ pref.Future.wait([]);
+}
+''');
+ }
+
+ test_property() async {
+ await resolveTestUnit('''
+class A {
+ static get foo => 42;
+}
+main(A a) {
+ a.foo;
+}
+''');
+ await assertHasFix('''
+class A {
+ static get foo => 42;
+}
+main(A a) {
+ A.foo;
+}
+''');
+ }
+
+ test_property_importType() async {
+ addSource('/home/test/lib/a.dart', r'''
+class A {
+ static get foo => null;
+}
+''');
+ addSource('/home/test/lib/b.dart', r'''
+import 'package:test/a.dart';
+
+class B extends A {}
+''');
+ await resolveTestUnit('''
+import 'package:test/b.dart';
+
+main(B b) {
+ b.foo;
+}
+''');
+ await assertHasFix('''
+import 'package:test/a.dart';
+import 'package:test/b.dart';
+
+main(B b) {
+ A.foo;
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/change_to_test.dart b/pkg/analysis_server/test/src/services/correction/fix/change_to_test.dart
new file mode 100644
index 0000000..553d1e5
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/change_to_test.dart
@@ -0,0 +1,332 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ChangeToTest);
+ });
+}
+
+@reflectiveTest
+class ChangeToTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.CHANGE_TO;
+
+ test_undefinedClass_fromImport() async {
+ await resolveTestUnit('''
+main() {
+ Stirng s = 'abc';
+ print(s);
+}
+''');
+ await assertHasFix('''
+main() {
+ String s = 'abc';
+ print(s);
+}
+''');
+ }
+
+ test_undefinedClass_fromThisLibrary() async {
+ await resolveTestUnit('''
+class MyClass {}
+main() {
+ MyCalss v = null;
+ print(v);
+}
+''');
+ await assertHasFix('''
+class MyClass {}
+main() {
+ MyClass v = null;
+ print(v);
+}
+''');
+ }
+
+ test_undefinedClass_prefixed() async {
+ await resolveTestUnit('''
+import 'dart:async' as c;
+main() {
+ c.Fture v = null;
+ print(v);
+}
+''');
+ await assertHasFix('''
+import 'dart:async' as c;
+main() {
+ c.Future v = null;
+ print(v);
+}
+''');
+ }
+
+ test_undefinedFunction_fromImport() async {
+ await resolveTestUnit('''
+main() {
+ pritn(0);
+}
+''');
+ await assertHasFix('''
+main() {
+ print(0);
+}
+''');
+ }
+
+ test_undefinedFunction_prefixed_fromImport() async {
+ await resolveTestUnit('''
+import 'dart:core' as c;
+main() {
+ c.prnt(42);
+}
+''');
+ await assertHasFix('''
+import 'dart:core' as c;
+main() {
+ c.print(42);
+}
+''');
+ }
+
+ test_undefinedFunction_prefixed_ignoreLocal() async {
+ await resolveTestUnit('''
+import 'dart:async' as c;
+main() {
+ c.main();
+}
+''');
+ await assertNoFix();
+ }
+
+ test_undefinedFunction_thisLibrary() async {
+ await resolveTestUnit('''
+myFunction() {}
+main() {
+ myFuntcion();
+}
+''');
+ await assertHasFix('''
+myFunction() {}
+main() {
+ myFunction();
+}
+''');
+ }
+
+ test_undefinedGetter_hint() async {
+ await resolveTestUnit('''
+class A {
+ int myField;
+}
+main(A a) {
+ var x = a;
+ print(x.myFild);
+}
+''');
+ await assertHasFix('''
+class A {
+ int myField;
+}
+main(A a) {
+ var x = a;
+ print(x.myField);
+}
+''');
+ }
+
+ test_undefinedGetter_qualified() async {
+ await resolveTestUnit('''
+class A {
+ int myField;
+}
+main(A a) {
+ print(a.myFild);
+}
+''');
+ await assertHasFix('''
+class A {
+ int myField;
+}
+main(A a) {
+ print(a.myField);
+}
+''');
+ }
+
+ test_undefinedGetter_qualified_static() async {
+ await resolveTestUnit('''
+class A {
+ static int MY_NAME = 1;
+}
+main() {
+ A.MY_NAM;
+}
+''');
+ await assertHasFix('''
+class A {
+ static int MY_NAME = 1;
+}
+main() {
+ A.MY_NAME;
+}
+''');
+ }
+
+ test_undefinedGetter_unqualified() async {
+ await resolveTestUnit('''
+class A {
+ int myField;
+ main() {
+ print(myFild);
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ int myField;
+ main() {
+ print(myField);
+ }
+}
+''');
+ }
+
+ test_undefinedMethod_ignoreOperators() async {
+ await resolveTestUnit('''
+main(Object object) {
+ object.then();
+}
+''');
+ await assertNoFix();
+ }
+
+ test_undefinedMethod_qualified() async {
+ await resolveTestUnit('''
+class A {
+ myMethod() {}
+}
+main() {
+ A a = new A();
+ a.myMehtod();
+}
+''');
+ await assertHasFix('''
+class A {
+ myMethod() {}
+}
+main() {
+ A a = new A();
+ a.myMethod();
+}
+''');
+ }
+
+ test_undefinedMethod_unqualified_superClass() async {
+ await resolveTestUnit('''
+class A {
+ myMethod() {}
+}
+class B extends A {
+ main() {
+ myMehtod();
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ myMethod() {}
+}
+class B extends A {
+ main() {
+ myMethod();
+ }
+}
+''');
+ }
+
+ test_undefinedMethod_unqualified_thisClass() async {
+ await resolveTestUnit('''
+class A {
+ myMethod() {}
+ main() {
+ myMehtod();
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ myMethod() {}
+ main() {
+ myMethod();
+ }
+}
+''');
+ }
+
+ test_undefinedSetter_hint() async {
+ await resolveTestUnit('''
+class A {
+ int myField;
+}
+main(A a) {
+ var x = a;
+ x.myFild = 42;
+}
+''');
+ await assertHasFix('''
+class A {
+ int myField;
+}
+main(A a) {
+ var x = a;
+ x.myField = 42;
+}
+''');
+ }
+
+ test_undefinedSetter_qualified() async {
+ await resolveTestUnit('''
+class A {
+ int myField;
+}
+main(A a) {
+ a.myFild = 42;
+}
+''');
+ await assertHasFix('''
+class A {
+ int myField;
+}
+main(A a) {
+ a.myField = 42;
+}
+''');
+ }
+
+ test_undefinedSetter_unqualified() async {
+ await resolveTestUnit('''
+class A {
+ int myField;
+ main() {
+ myFild = 42;
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ int myField;
+ main() {
+ myField = 42;
+ }
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/change_type_annotation_test.dart b/pkg/analysis_server/test/src/services/correction/fix/change_type_annotation_test.dart
new file mode 100644
index 0000000..8fbb66a
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/change_type_annotation_test.dart
@@ -0,0 +1,72 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ChangeTypeAnnotationTest);
+ });
+}
+
+@reflectiveTest
+class ChangeTypeAnnotationTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.CHANGE_TYPE_ANNOTATION;
+
+ test_generic() async {
+ await resolveTestUnit('''
+main() {
+ String v = <int>[];
+ print(v);
+}
+''');
+ await assertHasFix('''
+main() {
+ List<int> v = <int>[];
+ print(v);
+}
+''');
+ }
+
+ test_multipleVariables() async {
+ await resolveTestUnit('''
+main() {
+ String a, b = 42;
+ print('\$a \$b');
+}
+''');
+ await assertNoFix();
+ }
+
+ test_notVariableDeclaration() async {
+ await resolveTestUnit('''
+main() {
+ String v;
+ v = 42;
+ print(v);
+}
+''');
+ await assertNoFix();
+ }
+
+ test_simple() async {
+ await resolveTestUnit('''
+main() {
+ String v = 'abc'.length;
+ print(v);
+}
+''');
+ await assertHasFix('''
+main() {
+ int v = 'abc'.length;
+ print(v);
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_flutter_child_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_flutter_child_test.dart
new file mode 100644
index 0000000..e75321d
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_flutter_child_test.dart
@@ -0,0 +1,153 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConvertFlutterChildTest);
+ });
+}
+
+@reflectiveTest
+class ConvertFlutterChildTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.CONVERT_FLUTTER_CHILD;
+
+ test_hasList() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+build() {
+ return new Container(
+ child: new Row(
+ child: [
+ new Text('111'),
+ new Text('222'),
+ ],
+ ),
+ );
+}
+''');
+ await assertHasFix('''
+import 'package:flutter/widgets.dart';
+build() {
+ return new Container(
+ child: new Row(
+ children: <Widget>[
+ new Text('111'),
+ new Text('222'),
+ ],
+ ),
+ );
+}
+''');
+ }
+
+ test_hasTypedList() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+build() {
+ return new Container(
+ child: new Row(
+ child: <Widget>[
+ new Text('111'),
+ new Text('222'),
+ ],
+ ),
+ );
+}
+''');
+ await assertHasFix('''
+import 'package:flutter/widgets.dart';
+build() {
+ return new Container(
+ child: new Row(
+ children: <Widget>[
+ new Text('111'),
+ new Text('222'),
+ ],
+ ),
+ );
+}
+''');
+ }
+
+ test_listNotWidget() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+build() {
+ return new Container(
+ child: new Row(
+ child: <Widget>[
+ new Container(),
+ null,
+ ],
+ ),
+ );
+}
+''');
+ await assertNoFix();
+ }
+
+ test_multiLine() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/material.dart';
+build() {
+ return new Scaffold(
+ body: new Row(
+ child: new Container(
+ width: 200.0,
+ height: 300.0,
+ ),
+ ),
+ );
+}
+''');
+ await assertHasFix('''
+import 'package:flutter/material.dart';
+build() {
+ return new Scaffold(
+ body: new Row(
+ children: <Widget>[
+ new Container(
+ width: 200.0,
+ height: 300.0,
+ ),
+ ],
+ ),
+ );
+}
+''');
+ }
+
+ test_widgetVariable() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/material.dart';
+build() {
+ var text = new Text('foo');
+ new Row(
+ child: text,
+ );
+}
+''');
+ await assertHasFix('''
+import 'package:flutter/material.dart';
+build() {
+ var text = new Text('foo');
+ new Row(
+ children: <Widget>[text],
+ );
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_flutter_children_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_flutter_children_test.dart
new file mode 100644
index 0000000..f975f0a
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_flutter_children_test.dart
@@ -0,0 +1,108 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConvertFlutterChildrenTest);
+ });
+}
+
+@reflectiveTest
+class ConvertFlutterChildrenTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.CONVERT_FLUTTER_CHILDREN;
+
+ test_undefinedParameter_multiLine() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+build() {
+ return new Center(
+ children: [
+ new Container(
+ width: 200.0,
+ height: 300.0,
+ ),
+ ],
+ );
+}
+''');
+ await assertHasFix('''
+import 'package:flutter/widgets.dart';
+build() {
+ return new Center(
+ child: new Container(
+ width: 200.0,
+ height: 300.0,
+ ),
+ );
+}
+''');
+ }
+
+ test_undefinedParameter_notWidget() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+build() {
+ return new Center(
+ children: [
+ new Object(),
+ ],
+ );
+}
+''');
+ await assertNoFix();
+ }
+
+ test_undefinedParameter_singleLine() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+build() {
+ return new Center(
+ children: [
+ new Text('foo'),
+ ],
+ );
+}
+''');
+ await assertHasFix('''
+import 'package:flutter/widgets.dart';
+build() {
+ return new Center(
+ child: new Text('foo'),
+ );
+}
+''');
+ }
+
+ test_undefinedParameter_singleLine2() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+build() {
+ var text = new Text('foo');
+ new Center(
+ children: [text],
+ );
+}
+''');
+ await assertHasFix('''
+import 'package:flutter/widgets.dart';
+build() {
+ var text = new Text('foo');
+ new Center(
+ child: text,
+ );
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_named_arguments_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_named_arguments_test.dart
new file mode 100644
index 0000000..de9c388
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_named_arguments_test.dart
@@ -0,0 +1,110 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConvertToNamedArgumentsTest);
+ });
+}
+
+@reflectiveTest
+class ConvertToNamedArgumentsTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.CONVERT_TO_NAMED_ARGUMENTS;
+
+ test_ambiguous() async {
+ await resolveTestUnit('''
+class A {
+ A({int a, int b});
+}
+
+main() {
+ new A(1, 2);
+}
+''');
+ await assertNoFix();
+ }
+
+ test_instanceCreation() async {
+ await resolveTestUnit('''
+class A {
+ A({int a, double b});
+}
+
+main() {
+ new A(1.2, 3);
+}
+''');
+ await assertHasFix('''
+class A {
+ A({int a, double b});
+}
+
+main() {
+ new A(b: 1.2, a: 3);
+}
+''');
+ }
+
+ test_instanceCreation_hasPositional() async {
+ await resolveTestUnit('''
+class A {
+ A(int a, {int b});
+}
+
+main() {
+ new A(1, 2);
+}
+''');
+ await assertHasFix('''
+class A {
+ A(int a, {int b});
+}
+
+main() {
+ new A(1, b: 2);
+}
+''');
+ }
+
+ test_methodInvocation() async {
+ await resolveTestUnit('''
+class C {
+ void foo({int a}) {}
+}
+
+main(C c) {
+ c.foo(1);
+}
+''');
+ await assertHasFix('''
+class C {
+ void foo({int a}) {}
+}
+
+main(C c) {
+ c.foo(a: 1);
+}
+''');
+ }
+
+ test_noCompatibleParameter() async {
+ await resolveTestUnit('''
+class A {
+ A({String a});
+}
+
+main() {
+ new A(1);
+}
+''');
+ await assertNoFix();
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_class_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_class_test.dart
new file mode 100644
index 0000000..610c742
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_class_test.dart
@@ -0,0 +1,181 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(CreateClassTest);
+ });
+}
+
+@reflectiveTest
+class CreateClassTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.CREATE_CLASS;
+
+ test_hasUnresolvedPrefix() async {
+ await resolveTestUnit('''
+main() {
+ prefix.Test v = null;
+ print(v);
+}
+''');
+ await assertNoFix();
+ }
+
+ test_inLibraryOfPrefix() async {
+ addSource('/home/test/lib/lib.dart', r'''
+class A {}
+''');
+
+ await resolveTestUnit('''
+import 'lib.dart' as lib;
+
+main() {
+ lib.A a = null;
+ lib.Test t = null;
+ print('\$a \$t');
+}
+''');
+
+ await assertHasFix('''
+class A {}
+
+class Test {
+}
+''', target: '/home/test/lib/lib.dart');
+ expect(change.linkedEditGroups, hasLength(1));
+ }
+
+ test_innerLocalFunction() async {
+ await resolveTestUnit('''
+f() {
+ g() {
+ Test v = null;
+ print(v);
+ }
+ g();
+}
+''');
+ await assertHasFix('''
+f() {
+ g() {
+ Test v = null;
+ print(v);
+ }
+ g();
+}
+
+class Test {
+}
+''');
+ assertLinkedGroup(change.linkedEditGroups[0], ['Test v =', 'Test {']);
+ }
+
+ test_instanceCreation_withoutNew_fromFunction() async {
+ await resolveTestUnit('''
+main() {
+ Test ();
+}
+''');
+ await assertHasFix('''
+main() {
+ Test ();
+}
+
+class Test {
+}
+''');
+ assertLinkedGroup(change.linkedEditGroups[0], ['Test ()', 'Test {']);
+ }
+
+ test_instanceCreation_withoutNew_fromMethod() async {
+ await resolveTestUnit('''
+class A {
+ main() {
+ Test ();
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ main() {
+ Test ();
+ }
+}
+
+class Test {
+}
+''');
+ assertLinkedGroup(change.linkedEditGroups[0], ['Test ()', 'Test {']);
+ }
+
+ test_itemOfList() async {
+ await resolveTestUnit('''
+main() {
+ var a = [Test];
+ print(a);
+}
+''');
+ await assertHasFix('''
+main() {
+ var a = [Test];
+ print(a);
+}
+
+class Test {
+}
+''');
+ assertLinkedGroup(change.linkedEditGroups[0], ['Test];', 'Test {']);
+ }
+
+ test_itemOfList_inAnnotation() async {
+ await resolveTestUnit('''
+class MyAnnotation {
+ const MyAnnotation(a, b);
+}
+@MyAnnotation(int, const [Test])
+main() {}
+''');
+ await assertHasFix('''
+class MyAnnotation {
+ const MyAnnotation(a, b);
+}
+@MyAnnotation(int, const [Test])
+main() {}
+
+class Test {
+}
+''', errorFilter: (error) {
+ return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER;
+ });
+ assertLinkedGroup(change.linkedEditGroups[0], ['Test])', 'Test {']);
+ }
+
+ test_simple() async {
+ await resolveTestUnit('''
+main() {
+ Test v = null;
+ print(v);
+}
+''');
+ await assertHasFix('''
+main() {
+ Test v = null;
+ print(v);
+}
+
+class Test {
+}
+''');
+ assertLinkedGroup(change.linkedEditGroups[0], ['Test v =', 'Test {']);
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_constructor_for_final_fields_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_constructor_for_final_fields_test.dart
new file mode 100644
index 0000000..fa355b6
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_constructor_for_final_fields_test.dart
@@ -0,0 +1,137 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(CreateConstructorForFinalFieldsTest);
+ });
+}
+
+@reflectiveTest
+class CreateConstructorForFinalFieldsTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS;
+
+ test_flutter() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+
+class MyWidget extends StatelessWidget {
+ final int a;
+ final int b = 2;
+ final int c;
+}
+''');
+ await assertHasFix('''
+import 'package:flutter/widgets.dart';
+
+class MyWidget extends StatelessWidget {
+ final int a;
+ final int b = 2;
+ final int c;
+
+ const MyWidget({Key key, this.a, this.c}) : super(key: key);
+}
+''', errorFilter: (error) {
+ return error.message.contains("'a'");
+ });
+ }
+
+ test_flutter_childLast() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+
+class MyWidget extends StatelessWidget {
+ final int a;
+ final Widget child;
+ final int b;
+}
+''');
+ await assertHasFix('''
+import 'package:flutter/widgets.dart';
+
+class MyWidget extends StatelessWidget {
+ final int a;
+ final Widget child;
+ final int b;
+
+ const MyWidget({Key key, this.a, this.b, this.child}) : super(key: key);
+}
+''', errorFilter: (error) {
+ return error.message.contains("'a'");
+ });
+ }
+
+ test_flutter_childrenLast() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+
+class MyWidget extends StatelessWidget {
+ final int a;
+ final List<Widget> children;
+ final int b;
+}
+''');
+ await assertHasFix('''
+import 'package:flutter/widgets.dart';
+
+class MyWidget extends StatelessWidget {
+ final int a;
+ final List<Widget> children;
+ final int b;
+
+ const MyWidget({Key key, this.a, this.b, this.children}) : super(key: key);
+}
+''', errorFilter: (error) {
+ return error.message.contains("'a'");
+ });
+ }
+
+ test_inTopLevelMethod() async {
+ await resolveTestUnit('''
+main() {
+ final int v;
+ print(v);
+}
+''');
+ await assertNoFix();
+ }
+
+ test_simple() async {
+ await resolveTestUnit('''
+class Test {
+ final int a;
+ final int b = 2;
+ final int c;
+}
+''');
+ await assertHasFix('''
+class Test {
+ final int a;
+ final int b = 2;
+ final int c;
+
+ Test(this.a, this.c);
+}
+''', errorFilter: (error) {
+ return error.message.contains("'a'");
+ });
+ }
+
+ test_topLevelField() async {
+ await resolveTestUnit('''
+final int v;
+''');
+ await assertNoFix();
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_constructor_super_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_constructor_super_test.dart
new file mode 100644
index 0000000..fe59b94
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_constructor_super_test.dart
@@ -0,0 +1,156 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(CreateConstructorSuperTest);
+ });
+}
+
+@reflectiveTest
+class CreateConstructorSuperTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.CREATE_CONSTRUCTOR_SUPER;
+
+ test_fieldInitializer() async {
+ await resolveTestUnit('''
+class A {
+ int _field;
+ A(this._field);
+ int get field => _field;
+}
+class B extends A {
+ int existingField;
+
+ void existingMethod() {}
+}
+''');
+ await assertHasFix('''
+class A {
+ int _field;
+ A(this._field);
+ int get field => _field;
+}
+class B extends A {
+ int existingField;
+
+ B(int field) : super(field);
+
+ void existingMethod() {}
+}
+''');
+ }
+
+ test_importType() async {
+ addSource('/home/test/lib/a.dart', r'''
+class A {}
+''');
+ addSource('/home/test/lib/b.dart', r'''
+import 'package:test/a.dart';
+
+class B {
+ B(A a);
+}
+''');
+ await resolveTestUnit('''
+import 'package:test/b.dart';
+
+class C extends B {
+}
+''');
+ await assertHasFix('''
+import 'package:test/a.dart';
+import 'package:test/b.dart';
+
+class C extends B {
+ C(A a) : super(a);
+}
+''');
+ }
+
+ test_named() async {
+ await resolveTestUnit('''
+class A {
+ A.named(p1, int p2);
+}
+class B extends A {
+ int existingField;
+
+ void existingMethod() {}
+}
+''');
+ await assertHasFix('''
+class A {
+ A.named(p1, int p2);
+}
+class B extends A {
+ int existingField;
+
+ B.named(p1, int p2) : super.named(p1, p2);
+
+ void existingMethod() {}
+}
+''');
+ }
+
+ test_optional() async {
+ await resolveTestUnit('''
+class A {
+ A(p1, int p2, List<String> p3, [int p4]);
+}
+class B extends A {
+ int existingField;
+
+ void existingMethod() {}
+}
+''');
+ await assertHasFix('''
+class A {
+ A(p1, int p2, List<String> p3, [int p4]);
+}
+class B extends A {
+ int existingField;
+
+ B(p1, int p2, List<String> p3) : super(p1, p2, p3);
+
+ void existingMethod() {}
+}
+''');
+ }
+
+ test_private() async {
+ await resolveTestUnit('''
+class A {
+ A._named(p);
+}
+class B extends A {
+}
+''');
+ await assertNoFix();
+ }
+
+ test_typeArgument() async {
+ await resolveTestUnit('''
+class C<T> {
+ final T x;
+ C(this.x);
+}
+class D extends C<int> {
+}''');
+ await assertHasFix('''
+class C<T> {
+ final T x;
+ C(this.x);
+}
+class D extends C<int> {
+ D(int x) : super(x);
+}''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_constructor_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_constructor_test.dart
new file mode 100644
index 0000000..d5e8dd5
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_constructor_test.dart
@@ -0,0 +1,104 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(CreateConstructorTest);
+ defineReflectiveTests(CreateConstructorMixinTest);
+ });
+}
+
+@reflectiveTest
+class CreateConstructorMixinTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.CREATE_CONSTRUCTOR;
+
+ test_named() async {
+ await resolveTestUnit('''
+mixin M {}
+
+main() {
+ new M.named();
+}
+''');
+ await assertNoFix();
+ }
+}
+
+@reflectiveTest
+class CreateConstructorTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.CREATE_CONSTRUCTOR;
+
+ test_insteadOfSyntheticDefault() async {
+ await resolveTestUnit('''
+class A {
+ int field;
+
+ method() {}
+}
+main() {
+ new A(1, 2.0);
+}
+''');
+ await assertHasFix('''
+class A {
+ int field;
+
+ A(int i, double d);
+
+ method() {}
+}
+main() {
+ new A(1, 2.0);
+}
+''');
+ }
+
+ test_named() async {
+ await resolveTestUnit('''
+class A {
+ method() {}
+}
+main() {
+ new A.named(1, 2.0);
+}
+''');
+ await assertHasFix('''
+class A {
+ A.named(int i, double d);
+
+ method() {}
+}
+main() {
+ new A.named(1, 2.0);
+}
+''');
+ assertLinkedGroup(change.linkedEditGroups[0], ['named(int ', 'named(1']);
+ }
+
+ test_named_emptyClassBody() async {
+ await resolveTestUnit('''
+class A {}
+main() {
+ new A.named(1);
+}
+''');
+ await assertHasFix('''
+class A {
+ A.named(int i);
+}
+main() {
+ new A.named(1);
+}
+''');
+ assertLinkedGroup(change.linkedEditGroups[0], ['named(int ', 'named(1']);
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_field_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_field_test.dart
new file mode 100644
index 0000000..ed3eee0
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_field_test.dart
@@ -0,0 +1,555 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(CreateFieldTest);
+ defineReflectiveTests(CreateFieldMixinTest);
+ });
+}
+
+@reflectiveTest
+class CreateFieldMixinTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.CREATE_FIELD;
+
+ test_getter_qualified_instance() async {
+ await resolveTestUnit('''
+mixin M {
+}
+
+main(M m) {
+ int v = m.test;
+ print(v);
+}
+''');
+ await assertHasFix('''
+mixin M {
+ int test;
+}
+
+main(M m) {
+ int v = m.test;
+ print(v);
+}
+''');
+ }
+
+ test_setter_qualified_instance_hasField() async {
+ await resolveTestUnit('''
+mixin M {
+ int aaa;
+ int zzz;
+
+ existingMethod() {}
+}
+
+main(M m) {
+ m.test = 5;
+}
+''');
+ await assertHasFix('''
+mixin M {
+ int aaa;
+ int zzz;
+
+ int test;
+
+ existingMethod() {}
+}
+
+main(M m) {
+ m.test = 5;
+}
+''');
+ }
+}
+
+@reflectiveTest
+class CreateFieldTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.CREATE_FIELD;
+
+ test_getter_multiLevel() async {
+ await resolveTestUnit('''
+class A {
+}
+class B {
+ A a;
+}
+class C {
+ B b;
+}
+main(C c) {
+ int v = c.b.a.test;
+ print(v);
+}
+''');
+ await assertHasFix('''
+class A {
+ int test;
+}
+class B {
+ A a;
+}
+class C {
+ B b;
+}
+main(C c) {
+ int v = c.b.a.test;
+ print(v);
+}
+''');
+ }
+
+ test_getter_qualified_instance() async {
+ await resolveTestUnit('''
+class A {
+}
+main(A a) {
+ int v = a.test;
+ print(v);
+}
+''');
+ await assertHasFix('''
+class A {
+ int test;
+}
+main(A a) {
+ int v = a.test;
+ print(v);
+}
+''');
+ }
+
+ test_getter_qualified_instance_differentLibrary() async {
+ addSource('/home/test/lib/other.dart', '''
+/**
+ * A comment to push the offset of the braces for the following class
+ * declaration past the end of the content of the test file. Used to catch an
+ * index out of bounds exception that occurs when using the test source instead
+ * of the target source to compute the location at which to insert the field.
+ */
+class A {
+}
+''');
+
+ await resolveTestUnit('''
+import 'package:test/other.dart';
+
+main(A a) {
+ int v = a.test;
+ print(v);
+}
+''');
+
+ await assertHasFix('''
+/**
+ * A comment to push the offset of the braces for the following class
+ * declaration past the end of the content of the test file. Used to catch an
+ * index out of bounds exception that occurs when using the test source instead
+ * of the target source to compute the location at which to insert the field.
+ */
+class A {
+ int test;
+}
+''', target: '/home/test/lib/other.dart');
+ }
+
+ test_getter_qualified_instance_dynamicType() async {
+ await resolveTestUnit('''
+class A {
+ B b;
+ void f(Object p) {
+ p == b.test;
+ }
+}
+class B {
+}
+''');
+ await assertHasFix('''
+class A {
+ B b;
+ void f(Object p) {
+ p == b.test;
+ }
+}
+class B {
+ var test;
+}
+''');
+ }
+
+ test_getter_qualified_propagatedType() async {
+ await resolveTestUnit('''
+class A {
+ A get self => this;
+}
+main() {
+ var a = new A();
+ int v = a.self.test;
+ print(v);
+}
+''');
+ await assertHasFix('''
+class A {
+ int test;
+
+ A get self => this;
+}
+main() {
+ var a = new A();
+ int v = a.self.test;
+ print(v);
+}
+''');
+ }
+
+ test_getter_unqualified_instance_asInvocationArgument() async {
+ await resolveTestUnit('''
+class A {
+ main() {
+ f(test);
+ }
+}
+f(String s) {}
+''');
+ await assertHasFix('''
+class A {
+ String test;
+
+ main() {
+ f(test);
+ }
+}
+f(String s) {}
+''');
+ }
+
+ test_getter_unqualified_instance_assignmentRhs() async {
+ await resolveTestUnit('''
+class A {
+ main() {
+ int v = test;
+ print(v);
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ int test;
+
+ main() {
+ int v = test;
+ print(v);
+ }
+}
+''');
+ }
+
+ test_getter_unqualified_instance_asStatement() async {
+ await resolveTestUnit('''
+class A {
+ main() {
+ test;
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ var test;
+
+ main() {
+ test;
+ }
+}
+''');
+ }
+
+ test_hint() async {
+ await resolveTestUnit('''
+class A {
+}
+main(A a) {
+ var x = a;
+ int v = x.test;
+ print(v);
+}
+''');
+ await assertHasFix('''
+class A {
+ int test;
+}
+main(A a) {
+ var x = a;
+ int v = x.test;
+ print(v);
+}
+''');
+ }
+
+ test_hint_setter() async {
+ await resolveTestUnit('''
+class A {
+}
+main(A a) {
+ var x = a;
+ x.test = 0;
+}
+''');
+ await assertHasFix('''
+class A {
+ int test;
+}
+main(A a) {
+ var x = a;
+ x.test = 0;
+}
+''');
+ }
+
+ test_importType() async {
+ addSource('/home/test/lib/a.dart', r'''
+class A {}
+''');
+
+ addSource('/home/test/lib/b.dart', r'''
+import 'package:test/a.dart';
+
+A getA() => null;
+''');
+
+ await resolveTestUnit('''
+import 'package:test/b.dart';
+
+class C {
+}
+
+main(C c) {
+ c.test = getA();
+}
+''');
+
+ await assertHasFix('''
+import 'package:test/a.dart';
+import 'package:test/b.dart';
+
+class C {
+ A test;
+}
+
+main(C c) {
+ c.test = getA();
+}
+''');
+ }
+
+ test_inEnum() async {
+ await resolveTestUnit('''
+enum MyEnum {
+ AAA, BBB
+}
+main() {
+ MyEnum.foo;
+}
+''');
+ await assertNoFix();
+ }
+
+ test_inSDK() async {
+ await resolveTestUnit('''
+main(List p) {
+ p.foo = 1;
+}
+''');
+ await assertNoFix();
+ }
+
+ test_invalidInitializer_withoutType() async {
+ await resolveTestUnit('''
+class C {
+ C(this.text);
+}
+''');
+ await assertHasFix('''
+class C {
+ var text;
+
+ C(this.text);
+}
+''');
+ }
+
+ test_invalidInitializer_withType() async {
+ await resolveTestUnit('''
+class C {
+ C(String this.text);
+}
+''');
+ await assertHasFix('''
+class C {
+ String text;
+
+ C(String this.text);
+}
+''');
+ }
+
+ test_setter_generic_BAD() async {
+ await resolveTestUnit('''
+class A {
+}
+class B<T> {
+ List<T> items;
+ main(A a) {
+ a.test = items;
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ List test;
+}
+class B<T> {
+ List<T> items;
+ main(A a) {
+ a.test = items;
+ }
+}
+''');
+ }
+
+ test_setter_generic_OK_local() async {
+ await resolveTestUnit('''
+class A<T> {
+ List<T> items;
+
+ main(A a) {
+ test = items;
+ }
+}
+''');
+ await assertHasFix('''
+class A<T> {
+ List<T> items;
+
+ List<T> test;
+
+ main(A a) {
+ test = items;
+ }
+}
+''');
+ }
+
+ test_setter_qualified_instance_hasField() async {
+ await resolveTestUnit('''
+class A {
+ int aaa;
+ int zzz;
+
+ existingMethod() {}
+}
+main(A a) {
+ a.test = 5;
+}
+''');
+ await assertHasFix('''
+class A {
+ int aaa;
+ int zzz;
+
+ int test;
+
+ existingMethod() {}
+}
+main(A a) {
+ a.test = 5;
+}
+''');
+ }
+
+ test_setter_qualified_instance_hasMethod() async {
+ await resolveTestUnit('''
+class A {
+ existingMethod() {}
+}
+main(A a) {
+ a.test = 5;
+}
+''');
+ await assertHasFix('''
+class A {
+ int test;
+
+ existingMethod() {}
+}
+main(A a) {
+ a.test = 5;
+}
+''');
+ }
+
+ test_setter_qualified_static() async {
+ await resolveTestUnit('''
+class A {
+}
+main() {
+ A.test = 5;
+}
+''');
+ await assertHasFix('''
+class A {
+ static int test;
+}
+main() {
+ A.test = 5;
+}
+''');
+ }
+
+ test_setter_unqualified_instance() async {
+ await resolveTestUnit('''
+class A {
+ main() {
+ test = 5;
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ int test;
+
+ main() {
+ test = 5;
+ }
+}
+''');
+ }
+
+ test_setter_unqualified_static() async {
+ await resolveTestUnit('''
+class A {
+ static main() {
+ test = 5;
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ static int test;
+
+ static main() {
+ test = 5;
+ }
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_file_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_file_test.dart
new file mode 100644
index 0000000..3bb2fd8
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_file_test.dart
@@ -0,0 +1,101 @@
+// Copyright (c) 2018, 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/src/protocol_server.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(CreateFileTest);
+ });
+}
+
+@reflectiveTest
+class CreateFileTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.CREATE_FILE;
+
+ test_forImport() async {
+ await resolveTestUnit('''
+import 'my_file.dart';
+''');
+ await assertHasFixWithoutApplying();
+ // validate change
+ List<SourceFileEdit> fileEdits = change.edits;
+ expect(fileEdits, hasLength(1));
+ SourceFileEdit fileEdit = change.edits[0];
+ expect(fileEdit.file, convertPath('/home/test/lib/my_file.dart'));
+ expect(fileEdit.fileStamp, -1);
+ expect(fileEdit.edits, hasLength(1));
+ expect(
+ fileEdit.edits[0].replacement,
+ contains('// TODO Implement this library.'),
+ );
+ }
+
+ test_forImport_BAD_notDart() async {
+ await resolveTestUnit('''
+import 'my_file.txt';
+''');
+ await assertNoFix();
+ }
+
+ test_forImport_inPackage_lib() async {
+ await resolveTestUnit('''
+import 'a/bb/my_lib.dart';
+''');
+ await assertHasFixWithoutApplying();
+ // validate change
+ List<SourceFileEdit> fileEdits = change.edits;
+ expect(fileEdits, hasLength(1));
+ SourceFileEdit fileEdit = change.edits[0];
+ expect(fileEdit.file, convertPath('/home/test/lib/a/bb/my_lib.dart'));
+ expect(fileEdit.fileStamp, -1);
+ expect(fileEdit.edits, hasLength(1));
+ expect(
+ fileEdit.edits[0].replacement,
+ contains('// TODO Implement this library.'),
+ );
+ }
+
+ test_forImport_inPackage_test() async {
+ testFile = convertPath('/home/test/test/test.dart');
+ await resolveTestUnit('''
+import 'a/bb/my_lib.dart';
+''');
+ await assertHasFixWithoutApplying();
+ // validate change
+ List<SourceFileEdit> fileEdits = change.edits;
+ expect(fileEdits, hasLength(1));
+ SourceFileEdit fileEdit = change.edits[0];
+ expect(fileEdit.file, convertPath('/home/test/test/a/bb/my_lib.dart'));
+ expect(fileEdit.fileStamp, -1);
+ expect(fileEdit.edits, hasLength(1));
+ expect(
+ fileEdit.edits[0].replacement,
+ contains('// TODO Implement this library.'),
+ );
+ }
+
+ test_forPart() async {
+ await resolveTestUnit('''
+library my.lib;
+part 'my_part.dart';
+''');
+ await assertHasFixWithoutApplying();
+ // validate change
+ List<SourceFileEdit> fileEdits = change.edits;
+ expect(fileEdits, hasLength(1));
+ SourceFileEdit fileEdit = change.edits[0];
+ expect(fileEdit.file, convertPath('/home/test/lib/my_part.dart'));
+ expect(fileEdit.fileStamp, -1);
+ expect(fileEdit.edits, hasLength(1));
+ expect(fileEdit.edits[0].replacement, contains('part of my.lib;'));
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_function_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_function_test.dart
new file mode 100644
index 0000000..6fc4504
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_function_test.dart
@@ -0,0 +1,550 @@
+// Copyright (c) 2018, 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/src/protocol_server.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(CreateFunctionTest);
+ });
+}
+
+@reflectiveTest
+class CreateFunctionTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.CREATE_FUNCTION;
+
+ assert_returnType_bool(String lineWithTest) async {
+ await resolveTestUnit('''
+main() {
+ bool b = true;
+ $lineWithTest
+ print(b);
+}
+''');
+ await assertHasFix('''
+main() {
+ bool b = true;
+ $lineWithTest
+ print(b);
+}
+
+bool test() {
+}
+''');
+ }
+
+ test_bottomArgument() async {
+ await resolveTestUnit('''
+main() {
+ test(throw 42);
+}
+''');
+ await assertHasFix('''
+main() {
+ test(throw 42);
+}
+
+void test(param0) {
+}
+''');
+ }
+
+ test_duplicateArgumentNames() async {
+ await resolveTestUnit('''
+class C {
+ int x;
+}
+
+foo(C c1, C c2) {
+ bar(c1.x, c2.x);
+}
+''');
+ await assertHasFix('''
+class C {
+ int x;
+}
+
+foo(C c1, C c2) {
+ bar(c1.x, c2.x);
+}
+
+void bar(int x, int x2) {
+}
+''');
+ }
+
+ test_dynamicArgument() async {
+ await resolveTestUnit('''
+main() {
+ dynamic v;
+ test(v);
+}
+''');
+ await assertHasFix('''
+main() {
+ dynamic v;
+ test(v);
+}
+
+void test(v) {
+}
+''');
+ }
+
+ test_dynamicReturnType() async {
+ await resolveTestUnit('''
+main() {
+ dynamic v = test();
+ print(v);
+}
+''');
+ await assertHasFix('''
+main() {
+ dynamic v = test();
+ print(v);
+}
+
+test() {
+}
+''');
+ }
+
+ test_fromFunction() async {
+ await resolveTestUnit('''
+main() {
+ int v = myUndefinedFunction(1, 2.0, '3');
+ print(v);
+}
+''');
+ await assertHasFix('''
+main() {
+ int v = myUndefinedFunction(1, 2.0, '3');
+ print(v);
+}
+
+int myUndefinedFunction(int i, double d, String s) {
+}
+''');
+ }
+
+ test_fromMethod() async {
+ await resolveTestUnit('''
+class A {
+ main() {
+ int v = myUndefinedFunction(1, 2.0, '3');
+ print(v);
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ main() {
+ int v = myUndefinedFunction(1, 2.0, '3');
+ print(v);
+ }
+}
+
+int myUndefinedFunction(int i, double d, String s) {
+}
+''');
+ }
+
+ test_functionType_cascadeSecond() async {
+ await resolveTestUnit('''
+class A {
+ B ma() => null;
+}
+class B {
+ useFunction(int g(double a, String b)) {}
+}
+
+main() {
+ A a = new A();
+ a..ma().useFunction(test);
+}
+''');
+ await assertHasFix('''
+class A {
+ B ma() => null;
+}
+class B {
+ useFunction(int g(double a, String b)) {}
+}
+
+main() {
+ A a = new A();
+ a..ma().useFunction(test);
+}
+
+int test(double a, String b) {
+}
+''');
+ }
+
+ test_functionType_coreFunction() async {
+ await resolveTestUnit('''
+main() {
+ useFunction(g: test);
+}
+useFunction({Function g}) {}
+''');
+ await assertHasFix('''
+main() {
+ useFunction(g: test);
+}
+useFunction({Function g}) {}
+
+test() {
+}
+''');
+ }
+
+ test_functionType_dynamicArgument() async {
+ await resolveTestUnit('''
+main() {
+ useFunction(test);
+}
+useFunction(int g(a, b)) {}
+''');
+ await assertHasFix('''
+main() {
+ useFunction(test);
+}
+useFunction(int g(a, b)) {}
+
+int test(a, b) {
+}
+''');
+ }
+
+ test_functionType_function() async {
+ await resolveTestUnit('''
+main() {
+ useFunction(test);
+}
+useFunction(int g(double a, String b)) {}
+''');
+ await assertHasFix('''
+main() {
+ useFunction(test);
+}
+useFunction(int g(double a, String b)) {}
+
+int test(double a, String b) {
+}
+''');
+ }
+
+ test_functionType_function_namedArgument() async {
+ await resolveTestUnit('''
+main() {
+ useFunction(g: test);
+}
+useFunction({int g(double a, String b)}) {}
+''');
+ await assertHasFix('''
+main() {
+ useFunction(g: test);
+}
+useFunction({int g(double a, String b)}) {}
+
+int test(double a, String b) {
+}
+''');
+ }
+
+ test_functionType_importType() async {
+ addSource('/home/test/lib/a.dart', r'''
+class A {}
+''');
+ addSource('/home/test/lib/b.dart', r'''
+import 'package:test/a.dart';
+
+useFunction(int g(A a)) {}
+''');
+ await resolveTestUnit('''
+import 'package:test/b.dart';
+
+main() {
+ useFunction(test);
+}
+''');
+ await assertHasFix('''
+import 'package:test/a.dart';
+import 'package:test/b.dart';
+
+main() {
+ useFunction(test);
+}
+
+int test(A a) {
+}
+''');
+ }
+
+ test_functionType_notFunctionType() async {
+ await resolveTestUnit('''
+main(A a) {
+ useFunction(a.test);
+}
+typedef A();
+useFunction(g) {}
+''');
+ await assertNoFix();
+ }
+
+ test_generic_type() async {
+ await resolveTestUnit('''
+class A {
+ List<int> items;
+ main() {
+ process(items);
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ List<int> items;
+ main() {
+ process(items);
+ }
+}
+
+void process(List<int> items) {
+}
+''');
+ assertLinkedGroup(
+ change.linkedEditGroups[2],
+ ['List<int> items) {'],
+ expectedSuggestions(LinkedEditSuggestionKind.TYPE,
+ ['List<int>', 'Iterable<int>', 'Object']));
+ }
+
+ test_generic_typeParameter() async {
+ await resolveTestUnit('''
+class A<T> {
+ Map<int, T> items;
+ main() {
+ process(items);
+ }
+}
+''');
+ await assertHasFix('''
+class A<T> {
+ Map<int, T> items;
+ main() {
+ process(items);
+ }
+}
+
+void process(Map items) {
+}
+''');
+ }
+
+ test_importType() async {
+ addSource('/home/test/lib/lib.dart', r'''
+library lib;
+import 'dart:async';
+Future getFuture() => null;
+''');
+ await resolveTestUnit('''
+import 'lib.dart';
+main() {
+ test(getFuture());
+}
+''');
+ await assertHasFix('''
+import 'lib.dart';
+main() {
+ test(getFuture());
+}
+
+void test(Future future) {
+}
+''');
+ }
+
+ test_nullArgument() async {
+ await resolveTestUnit('''
+main() {
+ test(null);
+}
+''');
+ await assertHasFix('''
+main() {
+ test(null);
+}
+
+void test(param0) {
+}
+''');
+ }
+
+ test_returnType_bool_and_left() async {
+ await assert_returnType_bool("test() && b;");
+ }
+
+ test_returnType_bool_and_right() async {
+ await assert_returnType_bool("b && test();");
+ }
+
+ test_returnType_bool_assert() async {
+ await assert_returnType_bool("assert ( test() );");
+ }
+
+ test_returnType_bool_do() async {
+ await assert_returnType_bool("do {} while ( test() );");
+ }
+
+ test_returnType_bool_if() async {
+ await assert_returnType_bool("if ( test() ) {}");
+ }
+
+ test_returnType_bool_or_left() async {
+ await assert_returnType_bool("test() || b;");
+ }
+
+ test_returnType_bool_or_right() async {
+ await assert_returnType_bool("b || test();");
+ }
+
+ test_returnType_bool_unaryNegation() async {
+ await assert_returnType_bool("!test();");
+ }
+
+ test_returnType_bool_while() async {
+ await assert_returnType_bool("while ( test() ) {}");
+ }
+
+ test_returnType_fromAssignment_eq() async {
+ await resolveTestUnit('''
+main() {
+ int v;
+ v = myUndefinedFunction();
+ print(v);
+}
+''');
+ await assertHasFix('''
+main() {
+ int v;
+ v = myUndefinedFunction();
+ print(v);
+}
+
+int myUndefinedFunction() {
+}
+''');
+ }
+
+ test_returnType_fromAssignment_plusEq() async {
+ await resolveTestUnit('''
+main() {
+ int v;
+ v += myUndefinedFunction();
+ print(v);
+}
+''');
+ await assertHasFix('''
+main() {
+ int v;
+ v += myUndefinedFunction();
+ print(v);
+}
+
+num myUndefinedFunction() {
+}
+''');
+ }
+
+ test_returnType_fromBinary_right() async {
+ await resolveTestUnit('''
+main() {
+ 0 + myUndefinedFunction();
+}
+''');
+ await assertHasFix('''
+main() {
+ 0 + myUndefinedFunction();
+}
+
+num myUndefinedFunction() {
+}
+''');
+ }
+
+ test_returnType_fromInitializer() async {
+ await resolveTestUnit('''
+main() {
+ int v = myUndefinedFunction();
+ print(v);
+}
+''');
+ await assertHasFix('''
+main() {
+ int v = myUndefinedFunction();
+ print(v);
+}
+
+int myUndefinedFunction() {
+}
+''');
+ }
+
+ test_returnType_fromInvocationArgument() async {
+ await resolveTestUnit('''
+foo(int p) {}
+main() {
+ foo( myUndefinedFunction() );
+}
+''');
+ await assertHasFix('''
+foo(int p) {}
+main() {
+ foo( myUndefinedFunction() );
+}
+
+int myUndefinedFunction() {
+}
+''');
+ }
+
+ test_returnType_fromReturn() async {
+ await resolveTestUnit('''
+int main() {
+ return myUndefinedFunction();
+}
+''');
+ await assertHasFix('''
+int main() {
+ return myUndefinedFunction();
+}
+
+int myUndefinedFunction() {
+}
+''');
+ }
+
+ test_returnType_void() async {
+ await resolveTestUnit('''
+main() {
+ myUndefinedFunction();
+}
+''');
+ await assertHasFix('''
+main() {
+ myUndefinedFunction();
+}
+
+void myUndefinedFunction() {
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_getter_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_getter_test.dart
new file mode 100644
index 0000000..85941b0
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_getter_test.dart
@@ -0,0 +1,363 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(CreateGetterTest);
+ defineReflectiveTests(CreateGetterMixinTest);
+ });
+}
+
+@reflectiveTest
+class CreateGetterMixinTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.CREATE_GETTER;
+
+ test_qualified_instance() async {
+ await resolveTestUnit('''
+mixin M {
+}
+
+main(M m) {
+ int v = m.test;
+ print(v);
+}
+''');
+ await assertHasFix('''
+mixin M {
+ int get test => null;
+}
+
+main(M m) {
+ int v = m.test;
+ print(v);
+}
+''');
+ }
+
+ test_unqualified_instance_assignmentLhs() async {
+ await resolveTestUnit('''
+mixin M {
+ main() {
+ test = 42;
+ }
+}
+''');
+ await assertNoFix();
+ }
+
+ test_unqualified_instance_assignmentRhs() async {
+ await resolveTestUnit('''
+mixin M {
+ main() {
+ int v = test;
+ print(v);
+ }
+}
+''');
+ await assertHasFix('''
+mixin M {
+ int get test => null;
+
+ main() {
+ int v = test;
+ print(v);
+ }
+}
+''');
+ }
+}
+
+@reflectiveTest
+class CreateGetterTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.CREATE_GETTER;
+
+ test_hint_getter() async {
+ await resolveTestUnit('''
+class A {
+}
+main(A a) {
+ var x = a;
+ int v = x.test;
+ print(v);
+}
+''');
+ await assertHasFix('''
+class A {
+ int get test => null;
+}
+main(A a) {
+ var x = a;
+ int v = x.test;
+ print(v);
+}
+''');
+ }
+
+ test_inSDK() async {
+ await resolveTestUnit('''
+main(List p) {
+ int v = p.foo;
+ print(v);
+}
+''');
+ await assertNoFix();
+ }
+
+ test_location_afterLastGetter() async {
+ await resolveTestUnit('''
+class A {
+ int existingField;
+
+ int get existingGetter => null;
+
+ existingMethod() {}
+}
+main(A a) {
+ int v = a.test;
+ print(v);
+}
+''');
+ await assertHasFix('''
+class A {
+ int existingField;
+
+ int get existingGetter => null;
+
+ int get test => null;
+
+ existingMethod() {}
+}
+main(A a) {
+ int v = a.test;
+ print(v);
+}
+''');
+ }
+
+ test_multiLevel() async {
+ await resolveTestUnit('''
+class A {
+}
+class B {
+ A a;
+}
+class C {
+ B b;
+}
+main(C c) {
+ int v = c.b.a.test;
+ print(v);
+}
+''');
+ await assertHasFix('''
+class A {
+ int get test => null;
+}
+class B {
+ A a;
+}
+class C {
+ B b;
+}
+main(C c) {
+ int v = c.b.a.test;
+ print(v);
+}
+''');
+ }
+
+ test_qualified_instance() async {
+ await resolveTestUnit('''
+class A {
+}
+main(A a) {
+ int v = a.test;
+ print(v);
+}
+''');
+ await assertHasFix('''
+class A {
+ int get test => null;
+}
+main(A a) {
+ int v = a.test;
+ print(v);
+}
+''');
+ }
+
+ test_qualified_instance_differentLibrary() async {
+ addSource('/home/test/lib/other.dart', '''
+/**
+ * A comment to push the offset of the braces for the following class
+ * declaration past the end of the content of the test file. Used to catch an
+ * index out of bounds exception that occurs when using the test source instead
+ * of the target source to compute the location at which to insert the field.
+ */
+class A {
+}
+''');
+
+ await resolveTestUnit('''
+import 'package:test/other.dart';
+
+main(A a) {
+ int v = a.test;
+ print(v);
+}
+''');
+
+ await assertHasFix('''
+/**
+ * A comment to push the offset of the braces for the following class
+ * declaration past the end of the content of the test file. Used to catch an
+ * index out of bounds exception that occurs when using the test source instead
+ * of the target source to compute the location at which to insert the field.
+ */
+class A {
+ int get test => null;
+}
+''', target: '/home/test/lib/other.dart');
+ }
+
+ test_qualified_instance_dynamicType() async {
+ await resolveTestUnit('''
+class A {
+ B b;
+ void f(Object p) {
+ p == b.test;
+ }
+}
+class B {
+}
+''');
+ await assertHasFix('''
+class A {
+ B b;
+ void f(Object p) {
+ p == b.test;
+ }
+}
+class B {
+ get test => null;
+}
+''');
+ }
+
+ test_qualified_propagatedType() async {
+ await resolveTestUnit('''
+class A {
+ A get self => this;
+}
+main() {
+ var a = new A();
+ int v = a.self.test;
+ print(v);
+}
+''');
+ await assertHasFix('''
+class A {
+ A get self => this;
+
+ int get test => null;
+}
+main() {
+ var a = new A();
+ int v = a.self.test;
+ print(v);
+}
+''');
+ }
+
+ test_setterContext() async {
+ await resolveTestUnit('''
+class A {
+}
+main(A a) {
+ a.test = 42;
+}
+''');
+ await assertNoFix();
+ }
+
+ test_unqualified_instance_asInvocationArgument() async {
+ await resolveTestUnit('''
+class A {
+ main() {
+ f(test);
+ }
+}
+f(String s) {}
+''');
+ await assertHasFix('''
+class A {
+ String get test => null;
+
+ main() {
+ f(test);
+ }
+}
+f(String s) {}
+''');
+ }
+
+ test_unqualified_instance_assignmentLhs() async {
+ await resolveTestUnit('''
+class A {
+ main() {
+ test = 42;
+ }
+}
+''');
+ await assertNoFix();
+ }
+
+ test_unqualified_instance_assignmentRhs() async {
+ await resolveTestUnit('''
+class A {
+ main() {
+ int v = test;
+ print(v);
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ int get test => null;
+
+ main() {
+ int v = test;
+ print(v);
+ }
+}
+''');
+ }
+
+ test_unqualified_instance_asStatement() async {
+ await resolveTestUnit('''
+class A {
+ main() {
+ test;
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ get test => null;
+
+ main() {
+ test;
+ }
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_local_variable_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_local_variable_test.dart
new file mode 100644
index 0000000..933eec9
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_local_variable_test.dart
@@ -0,0 +1,218 @@
+// Copyright (c) 2018, 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/src/protocol_server.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(CreateLocalVariableTest);
+ });
+}
+
+@reflectiveTest
+class CreateLocalVariableTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.CREATE_LOCAL_VARIABLE;
+
+ test_functionType_named() async {
+ await resolveTestUnit('''
+typedef MY_FUNCTION(int p);
+foo(MY_FUNCTION f) {}
+main() {
+ foo(bar);
+}
+''');
+ await assertHasFix('''
+typedef MY_FUNCTION(int p);
+foo(MY_FUNCTION f) {}
+main() {
+ MY_FUNCTION bar;
+ foo(bar);
+}
+''');
+ }
+
+ test_functionType_named_generic() async {
+ await resolveTestUnit('''
+typedef MY_FUNCTION<T>(T p);
+foo(MY_FUNCTION<int> f) {}
+main() {
+ foo(bar);
+}
+''');
+ await assertHasFix('''
+typedef MY_FUNCTION<T>(T p);
+foo(MY_FUNCTION<int> f) {}
+main() {
+ MY_FUNCTION<int> bar;
+ foo(bar);
+}
+''');
+ }
+
+ test_functionType_synthetic() async {
+ await resolveTestUnit('''
+foo(f(int p)) {}
+main() {
+ foo(bar);
+}
+''');
+ await assertHasFix('''
+foo(f(int p)) {}
+main() {
+ Function(int p) bar;
+ foo(bar);
+}
+''');
+ }
+
+ test_read_typeAssignment() async {
+ await resolveTestUnit('''
+main() {
+ int a = test;
+ print(a);
+}
+''');
+ await assertHasFix('''
+main() {
+ int test;
+ int a = test;
+ print(a);
+}
+''');
+ }
+
+ test_read_typeCondition() async {
+ await resolveTestUnit('''
+main() {
+ if (!test) {
+ print(42);
+ }
+}
+''');
+ await assertHasFix('''
+main() {
+ bool test;
+ if (!test) {
+ print(42);
+ }
+}
+''');
+ }
+
+ test_read_typeInvocationArgument() async {
+ await resolveTestUnit('''
+main() {
+ f(test);
+}
+f(String p) {}
+''');
+ await assertHasFix('''
+main() {
+ String test;
+ f(test);
+}
+f(String p) {}
+''');
+ assertLinkedGroup(change.linkedEditGroups[0], ['String test;']);
+ assertLinkedGroup(change.linkedEditGroups[1], ['test;', 'test);']);
+ }
+
+ test_read_typeInvocationTarget() async {
+ await resolveTestUnit('''
+main() {
+ test.add('hello');
+}
+''');
+ await assertHasFix('''
+main() {
+ var test;
+ test.add('hello');
+}
+''');
+ assertLinkedGroup(change.linkedEditGroups[0], ['test;', 'test.add(']);
+ }
+
+ test_withImport() async {
+ addPackageFile('pkg', 'a/a.dart', '''
+class A {}
+''');
+ addPackageFile('pkg', 'b/b.dart', '''
+class B {}
+''');
+ addPackageFile('pkg', 'c/c.dart', '''
+import 'package:pkg/a/a.dart';
+import 'package:pkg/b/b.dart';
+
+class C {
+ C(A a, B b);
+}
+''');
+
+ await resolveTestUnit('''
+import 'package:pkg/a/a.dart';
+import 'package:pkg/c/c.dart';
+
+main() {
+ A a;
+ new C(a, b);
+}
+''');
+ await assertHasFix('''
+import 'package:pkg/a/a.dart';
+import 'package:pkg/b/b.dart';
+import 'package:pkg/c/c.dart';
+
+main() {
+ A a;
+ B b;
+ new C(a, b);
+}
+''');
+ List<LinkedEditGroup> groups = change.linkedEditGroups;
+ expect(groups, hasLength(2));
+ LinkedEditGroup typeGroup = groups[0];
+ List<Position> typePositions = typeGroup.positions;
+ expect(typePositions, hasLength(1));
+ expect(typePositions[0].offset, 112);
+ LinkedEditGroup nameGroup = groups[1];
+ List<Position> groupPositions = nameGroup.positions;
+ expect(groupPositions, hasLength(2));
+ expect(groupPositions[0].offset, 114);
+ expect(groupPositions[1].offset, 128);
+ }
+
+ test_write_assignment() async {
+ await resolveTestUnit('''
+main() {
+ test = 42;
+}
+''');
+ await assertHasFix('''
+main() {
+ var test = 42;
+}
+''');
+ }
+
+ test_write_assignment_compound() async {
+ await resolveTestUnit('''
+main() {
+ test += 42;
+}
+''');
+ await assertHasFix('''
+main() {
+ int test;
+ test += 42;
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_method_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_method_test.dart
new file mode 100644
index 0000000..bf502f1
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_method_test.dart
@@ -0,0 +1,705 @@
+// Copyright (c) 2018, 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/src/protocol_server.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(CreateMethodTest);
+ defineReflectiveTests(CreateMethodMixinTest);
+ });
+}
+
+@reflectiveTest
+class CreateMethodMixinTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.CREATE_METHOD;
+
+ test_createQualified_instance() async {
+ await resolveTestUnit('''
+mixin M {}
+
+main(M m) {
+ m.myUndefinedMethod();
+}
+''');
+ await assertHasFix('''
+mixin M {
+ void myUndefinedMethod() {}
+}
+
+main(M m) {
+ m.myUndefinedMethod();
+}
+''');
+ }
+
+ test_createQualified_static() async {
+ await resolveTestUnit('''
+mixin M {}
+
+main() {
+ M.myUndefinedMethod();
+}
+''');
+ await assertHasFix('''
+mixin M {
+ static void myUndefinedMethod() {}
+}
+
+main() {
+ M.myUndefinedMethod();
+}
+''');
+ }
+
+ test_createUnqualified() async {
+ await resolveTestUnit('''
+mixin M {
+ main() {
+ myUndefinedMethod();
+ }
+}
+''');
+ await assertHasFix('''
+mixin M {
+ main() {
+ myUndefinedMethod();
+ }
+
+ void myUndefinedMethod() {}
+}
+''');
+ }
+
+ test_functionType_method_enclosingMixin_static() async {
+ await resolveTestUnit('''
+mixin M {
+ static foo() {
+ useFunction(test);
+ }
+}
+
+useFunction(int g(double a, String b)) {}
+''');
+ await assertHasFix('''
+mixin M {
+ static foo() {
+ useFunction(test);
+ }
+
+ static int test(double a, String b) {
+ }
+}
+
+useFunction(int g(double a, String b)) {}
+''');
+ }
+
+ test_functionType_method_targetMixin() async {
+ await resolveTestUnit('''
+main(M m) {
+ useFunction(m.test);
+}
+
+mixin M {
+}
+
+useFunction(int g(double a, String b)) {}
+''');
+ await assertHasFix('''
+main(M m) {
+ useFunction(m.test);
+}
+
+mixin M {
+ int test(double a, String b) {
+ }
+}
+
+useFunction(int g(double a, String b)) {}
+''');
+ }
+}
+
+@reflectiveTest
+class CreateMethodTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.CREATE_METHOD;
+
+ test_createQualified_emptyClassBody() async {
+ await resolveTestUnit('''
+class A {}
+main() {
+ A.myUndefinedMethod();
+}
+''');
+ await assertHasFix('''
+class A {
+ static void myUndefinedMethod() {}
+}
+main() {
+ A.myUndefinedMethod();
+}
+''');
+ }
+
+ test_createQualified_fromClass() async {
+ await resolveTestUnit('''
+class A {
+}
+main() {
+ A.myUndefinedMethod();
+}
+''');
+ await assertHasFix('''
+class A {
+ static void myUndefinedMethod() {}
+}
+main() {
+ A.myUndefinedMethod();
+}
+''');
+ }
+
+ test_createQualified_fromClass_hasOtherMember() async {
+ await resolveTestUnit('''
+class A {
+ foo() {}
+}
+main() {
+ A.myUndefinedMethod();
+}
+''');
+ await assertHasFix('''
+class A {
+ foo() {}
+
+ static void myUndefinedMethod() {}
+}
+main() {
+ A.myUndefinedMethod();
+}
+''');
+ }
+
+ test_createQualified_fromInstance() async {
+ await resolveTestUnit('''
+class A {
+}
+main(A a) {
+ a.myUndefinedMethod();
+}
+''');
+ await assertHasFix('''
+class A {
+ void myUndefinedMethod() {}
+}
+main(A a) {
+ a.myUndefinedMethod();
+}
+''');
+ }
+
+ test_createQualified_targetIsFunctionType() async {
+ await resolveTestUnit('''
+typedef A();
+main() {
+ A.myUndefinedMethod();
+}
+''');
+ await assertNoFix();
+ }
+
+ test_createQualified_targetIsUnresolved() async {
+ await resolveTestUnit('''
+main() {
+ NoSuchClass.myUndefinedMethod();
+}
+''');
+ await assertNoFix();
+ }
+
+ test_createUnqualified_duplicateArgumentNames() async {
+ await resolveTestUnit('''
+class C {
+ int x;
+}
+
+class D {
+ foo(C c1, C c2) {
+ bar(c1.x, c2.x);
+ }
+}''');
+ await assertHasFix('''
+class C {
+ int x;
+}
+
+class D {
+ foo(C c1, C c2) {
+ bar(c1.x, c2.x);
+ }
+
+ void bar(int x, int x2) {}
+}''');
+ }
+
+ test_createUnqualified_parameters() async {
+ await resolveTestUnit('''
+class A {
+ main() {
+ myUndefinedMethod(0, 1.0, '3');
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ main() {
+ myUndefinedMethod(0, 1.0, '3');
+ }
+
+ void myUndefinedMethod(int i, double d, String s) {}
+}
+''');
+ // linked positions
+ int index = 0;
+ assertLinkedGroup(
+ change.linkedEditGroups[index++], ['void myUndefinedMethod(']);
+ assertLinkedGroup(change.linkedEditGroups[index++],
+ ['myUndefinedMethod(0', 'myUndefinedMethod(int']);
+ assertLinkedGroup(
+ change.linkedEditGroups[index++],
+ ['int i'],
+ expectedSuggestions(LinkedEditSuggestionKind.TYPE,
+ ['int', 'num', 'Object', 'Comparable<num>']));
+ assertLinkedGroup(change.linkedEditGroups[index++], ['i,']);
+ assertLinkedGroup(
+ change.linkedEditGroups[index++],
+ ['double d'],
+ expectedSuggestions(LinkedEditSuggestionKind.TYPE,
+ ['double', 'num', 'Object', 'Comparable<num>']));
+ assertLinkedGroup(change.linkedEditGroups[index++], ['d,']);
+ assertLinkedGroup(
+ change.linkedEditGroups[index++],
+ ['String s'],
+ expectedSuggestions(LinkedEditSuggestionKind.TYPE,
+ ['String', 'Object', 'Comparable<String>', 'Pattern']));
+ assertLinkedGroup(change.linkedEditGroups[index++], ['s)']);
+ }
+
+ test_createUnqualified_parameters_named() async {
+ await resolveTestUnit('''
+class A {
+ main() {
+ myUndefinedMethod(0, bbb: 1.0, ccc: '2');
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ main() {
+ myUndefinedMethod(0, bbb: 1.0, ccc: '2');
+ }
+
+ void myUndefinedMethod(int i, {double bbb, String ccc}) {}
+}
+''');
+ // linked positions
+ int index = 0;
+ assertLinkedGroup(
+ change.linkedEditGroups[index++], ['void myUndefinedMethod(']);
+ assertLinkedGroup(change.linkedEditGroups[index++],
+ ['myUndefinedMethod(0', 'myUndefinedMethod(int']);
+ assertLinkedGroup(
+ change.linkedEditGroups[index++],
+ ['int i'],
+ expectedSuggestions(LinkedEditSuggestionKind.TYPE,
+ ['int', 'num', 'Object', 'Comparable<num>']));
+ assertLinkedGroup(change.linkedEditGroups[index++], ['i,']);
+ assertLinkedGroup(
+ change.linkedEditGroups[index++],
+ ['double bbb'],
+ expectedSuggestions(LinkedEditSuggestionKind.TYPE,
+ ['double', 'num', 'Object', 'Comparable<num>']));
+ assertLinkedGroup(
+ change.linkedEditGroups[index++],
+ ['String ccc'],
+ expectedSuggestions(LinkedEditSuggestionKind.TYPE,
+ ['String', 'Object', 'Comparable<String>', 'Pattern']));
+ }
+
+ test_createUnqualified_returnType() async {
+ await resolveTestUnit('''
+class A {
+ main() {
+ int v = myUndefinedMethod();
+ print(v);
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ main() {
+ int v = myUndefinedMethod();
+ print(v);
+ }
+
+ int myUndefinedMethod() {}
+}
+''');
+ // linked positions
+ assertLinkedGroup(change.linkedEditGroups[0], ['int myUndefinedMethod(']);
+ assertLinkedGroup(change.linkedEditGroups[1],
+ ['myUndefinedMethod();', 'myUndefinedMethod() {']);
+ }
+
+ test_createUnqualified_staticFromField() async {
+ await resolveTestUnit('''
+class A {
+ static var f = myUndefinedMethod();
+}
+''');
+ await assertHasFix('''
+class A {
+ static var f = myUndefinedMethod();
+
+ static myUndefinedMethod() {}
+}
+''');
+ }
+
+ test_createUnqualified_staticFromMethod() async {
+ await resolveTestUnit('''
+class A {
+ static main() {
+ myUndefinedMethod();
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ static main() {
+ myUndefinedMethod();
+ }
+
+ static void myUndefinedMethod() {}
+}
+''');
+ }
+
+ test_functionType_method_enclosingClass_static() async {
+ await resolveTestUnit('''
+class A {
+ static foo() {
+ useFunction(test);
+ }
+}
+useFunction(int g(double a, String b)) {}
+''');
+ await assertHasFix('''
+class A {
+ static foo() {
+ useFunction(test);
+ }
+
+ static int test(double a, String b) {
+ }
+}
+useFunction(int g(double a, String b)) {}
+''');
+ }
+
+ test_functionType_method_enclosingClass_static2() async {
+ await resolveTestUnit('''
+class A {
+ var f;
+ A() : f = useFunction(test);
+}
+useFunction(int g(double a, String b)) {}
+''');
+ await assertHasFix('''
+class A {
+ var f;
+ A() : f = useFunction(test);
+
+ static int test(double a, String b) {
+ }
+}
+useFunction(int g(double a, String b)) {}
+''');
+ }
+
+ test_functionType_method_targetClass() async {
+ await resolveTestUnit('''
+main(A a) {
+ useFunction(a.test);
+}
+class A {
+}
+useFunction(int g(double a, String b)) {}
+''');
+ await assertHasFix('''
+main(A a) {
+ useFunction(a.test);
+}
+class A {
+ int test(double a, String b) {
+ }
+}
+useFunction(int g(double a, String b)) {}
+''');
+ }
+
+ test_functionType_method_targetClass_hasOtherMember() async {
+ await resolveTestUnit('''
+main(A a) {
+ useFunction(a.test);
+}
+class A {
+ m() {}
+}
+useFunction(int g(double a, String b)) {}
+''');
+ await assertHasFix('''
+main(A a) {
+ useFunction(a.test);
+}
+class A {
+ m() {}
+
+ int test(double a, String b) {
+ }
+}
+useFunction(int g(double a, String b)) {}
+''');
+ }
+
+ test_functionType_notFunctionType() async {
+ await resolveTestUnit('''
+main(A a) {
+ useFunction(a.test);
+}
+typedef A();
+useFunction(g) {}
+''');
+ await assertNoFix();
+ }
+
+ test_functionType_unknownTarget() async {
+ await resolveTestUnit('''
+main(A a) {
+ useFunction(a.test);
+}
+class A {
+}
+useFunction(g) {}
+''');
+ await assertNoFix();
+ }
+
+ test_generic_argumentType() async {
+ await resolveTestUnit('''
+class A<T> {
+ B b;
+ Map<int, T> items;
+ main() {
+ b.process(items);
+ }
+}
+
+class B {
+}
+''');
+ await assertHasFix('''
+class A<T> {
+ B b;
+ Map<int, T> items;
+ main() {
+ b.process(items);
+ }
+}
+
+class B {
+ void process(Map items) {}
+}
+''');
+ }
+
+ test_generic_literal() async {
+ await resolveTestUnit('''
+class A {
+ B b;
+ List<int> items;
+ main() {
+ b.process(items);
+ }
+}
+
+class B {}
+''');
+ await assertHasFix('''
+class A {
+ B b;
+ List<int> items;
+ main() {
+ b.process(items);
+ }
+}
+
+class B {
+ void process(List<int> items) {}
+}
+''');
+ }
+
+ test_generic_local() async {
+ await resolveTestUnit('''
+class A<T> {
+ List<T> items;
+ main() {
+ process(items);
+ }
+}
+''');
+ await assertHasFix('''
+class A<T> {
+ List<T> items;
+ main() {
+ process(items);
+ }
+
+ void process(List<T> items) {}
+}
+''');
+ }
+
+ test_generic_returnType() async {
+ await resolveTestUnit('''
+class A<T> {
+ main() {
+ T t = new B().compute();
+ print(t);
+ }
+}
+
+class B {
+}
+''');
+ await assertHasFix('''
+class A<T> {
+ main() {
+ T t = new B().compute();
+ print(t);
+ }
+}
+
+class B {
+ compute() {}
+}
+''');
+ }
+
+ test_hint_createQualified_fromInstance() async {
+ await resolveTestUnit('''
+class A {
+}
+main() {
+ var a = new A();
+ a.myUndefinedMethod();
+}
+''');
+ await assertHasFix('''
+class A {
+ void myUndefinedMethod() {}
+}
+main() {
+ var a = new A();
+ a.myUndefinedMethod();
+}
+''');
+ }
+
+ test_inSDK() async {
+ await resolveTestUnit('''
+main() {
+ List.foo();
+}
+''');
+ await assertNoFix();
+ }
+
+ test_parameterType_differentPrefixInTargetUnit() async {
+ String code2 = r'''
+import 'test3.dart' as bbb;
+export 'test3.dart';
+
+class D {
+}
+''';
+
+ addSource('/home/test/lib/test2.dart', code2);
+ addSource('/home/test/lib/test3.dart', r'''
+library test3;
+class E {}
+''');
+
+ await resolveTestUnit('''
+import 'test2.dart' as aaa;
+
+main(aaa.D d, aaa.E e) {
+ d.foo(e);
+}
+''');
+
+ await assertHasFix('''
+import 'test3.dart' as bbb;
+export 'test3.dart';
+
+class D {
+ void foo(bbb.E e) {}
+}
+''', target: '/home/test/lib/test2.dart');
+ }
+
+ test_parameterType_inTargetUnit() async {
+ addSource('/home/test/lib/test2.dart', r'''
+class D {
+}
+
+class E {}
+''');
+
+ await resolveTestUnit('''
+import 'test2.dart' as test2;
+
+main(test2.D d, test2.E e) {
+ d.foo(e);
+}
+''');
+
+ await assertHasFix('''
+class D {
+ void foo(E e) {}
+}
+
+class E {}
+''', target: '/home/test/lib/test2.dart');
+ }
+
+ test_targetIsEnum() async {
+ await resolveTestUnit('''
+enum MyEnum {A, B}
+main() {
+ MyEnum.foo();
+}
+''');
+ await assertNoFix();
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_missing_overrides_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_missing_overrides_test.dart
new file mode 100644
index 0000000..7656709
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_missing_overrides_test.dart
@@ -0,0 +1,520 @@
+// Copyright (c) 2018, 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/src/protocol_server.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(CreateMissingOverridesTest);
+ });
+}
+
+@reflectiveTest
+class CreateMissingOverridesTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.CREATE_MISSING_OVERRIDES;
+
+ test_field_untyped() async {
+ await resolveTestUnit('''
+class A {
+ var f;
+}
+
+class B implements A {
+}
+''');
+ await assertHasFix('''
+class A {
+ var f;
+}
+
+class B implements A {
+ @override
+ var f;
+}
+''');
+ }
+
+ test_functionTypeAlias() async {
+ await resolveTestUnit('''
+typedef int Binary(int left, int right);
+
+abstract class Emulator {
+ void performBinary(Binary binary);
+}
+
+class MyEmulator extends Emulator {
+}
+''');
+ await assertHasFix('''
+typedef int Binary(int left, int right);
+
+abstract class Emulator {
+ void performBinary(Binary binary);
+}
+
+class MyEmulator extends Emulator {
+ @override
+ void performBinary(Binary binary) {
+ // TODO: implement performBinary
+ }
+}
+''');
+ }
+
+ test_functionTypedParameter() async {
+ await resolveTestUnit('''
+abstract class A {
+ void forEach(int f(double p1, String p2));
+}
+
+class B extends A {
+}
+''');
+ await assertHasFix('''
+abstract class A {
+ void forEach(int f(double p1, String p2));
+}
+
+class B extends A {
+ @override
+ void forEach(int Function(double p1, String p2) f) {
+ // TODO: implement forEach
+ }
+}
+''');
+ }
+
+ test_generics_typeArguments() async {
+ await resolveTestUnit('''
+class Iterator<T> {
+}
+
+abstract class IterableMixin<T> {
+ Iterator<T> get iterator;
+}
+
+class Test extends IterableMixin<int> {
+}
+''');
+ await assertHasFix('''
+class Iterator<T> {
+}
+
+abstract class IterableMixin<T> {
+ Iterator<T> get iterator;
+}
+
+class Test extends IterableMixin<int> {
+ @override
+ // TODO: implement iterator
+ Iterator<int> get iterator => null;
+}
+''');
+ }
+
+ test_generics_typeParameters() async {
+ await resolveTestUnit('''
+abstract class ItemProvider<T> {
+ List<T> getItems();
+}
+
+class Test<V> extends ItemProvider<V> {
+}
+''');
+ await assertHasFix('''
+abstract class ItemProvider<T> {
+ List<T> getItems();
+}
+
+class Test<V> extends ItemProvider<V> {
+ @override
+ List<V> getItems() {
+ // TODO: implement getItems
+ return null;
+ }
+}
+''');
+ }
+
+ test_getter() async {
+ await resolveTestUnit('''
+abstract class A {
+ get g1;
+ int get g2;
+}
+
+class B extends A {
+}
+''');
+ await assertHasFix('''
+abstract class A {
+ get g1;
+ int get g2;
+}
+
+class B extends A {
+ @override
+ // TODO: implement g1
+ get g1 => null;
+
+ @override
+ // TODO: implement g2
+ int get g2 => null;
+}
+''');
+ }
+
+ test_importPrefix() async {
+ await resolveTestUnit('''
+import 'dart:async' as aaa;
+abstract class A {
+ Map<aaa.Future, List<aaa.Future>> g(aaa.Future p);
+}
+
+class B extends A {
+}
+''');
+ await assertHasFix('''
+import 'dart:async' as aaa;
+abstract class A {
+ Map<aaa.Future, List<aaa.Future>> g(aaa.Future p);
+}
+
+class B extends A {
+ @override
+ Map<aaa.Future, List<aaa.Future>> g(aaa.Future p) {
+ // TODO: implement g
+ return null;
+ }
+}
+''');
+ }
+
+ test_mergeToField_getterSetter() async {
+ await resolveTestUnit('''
+class A {
+ int ma;
+ void mb() {}
+ double mc;
+}
+
+class B implements A {
+}
+''');
+ await assertHasFix('''
+class A {
+ int ma;
+ void mb() {}
+ double mc;
+}
+
+class B implements A {
+ @override
+ int ma;
+
+ @override
+ double mc;
+
+ @override
+ void mb() {
+ // TODO: implement mb
+ }
+}
+''');
+ }
+
+ test_method() async {
+ await resolveTestUnit('''
+abstract class A {
+ void m1();
+ int m2();
+ String m3(int p1, double p2, Map<int, List<String>> p3);
+ String m4(p1, p2);
+ String m5(p1, [int p2 = 2, int p3, p4 = 4]);
+ String m6(p1, {int p2 = 2, int p3, p4: 4});
+}
+
+class B extends A {
+}
+''');
+ String expectedCode = '''
+abstract class A {
+ void m1();
+ int m2();
+ String m3(int p1, double p2, Map<int, List<String>> p3);
+ String m4(p1, p2);
+ String m5(p1, [int p2 = 2, int p3, p4 = 4]);
+ String m6(p1, {int p2 = 2, int p3, p4: 4});
+}
+
+class B extends A {
+ @override
+ void m1() {
+ // TODO: implement m1
+ }
+
+ @override
+ int m2() {
+ // TODO: implement m2
+ return null;
+ }
+
+ @override
+ String m3(int p1, double p2, Map<int, List<String>> p3) {
+ // TODO: implement m3
+ return null;
+ }
+
+ @override
+ String m4(p1, p2) {
+ // TODO: implement m4
+ return null;
+ }
+
+ @override
+ String m5(p1, [int p2 = 2, int p3, p4 = 4]) {
+ // TODO: implement m5
+ return null;
+ }
+
+ @override
+ String m6(p1, {int p2 = 2, int p3, p4 = 4}) {
+ // TODO: implement m6
+ return null;
+ }
+}
+''';
+ await assertHasFix(expectedCode);
+ {
+ // end position should be on "m1", not on "m2", "m3", etc.
+ Position endPosition = change.selection;
+ expect(endPosition, isNotNull);
+ expect(endPosition.file, testFile);
+ int endOffset = endPosition.offset;
+ String endString = expectedCode.substring(endOffset, endOffset + 25);
+ expect(endString, contains('m1'));
+ expect(endString, isNot(contains('m2')));
+ expect(endString, isNot(contains('m3')));
+ expect(endString, isNot(contains('m4')));
+ expect(endString, isNot(contains('m5')));
+ expect(endString, isNot(contains('m6')));
+ }
+ }
+
+ test_method_emptyClassBody() async {
+ await resolveTestUnit('''
+abstract class A {
+ void foo();
+}
+
+class B extends A {}
+''');
+ await assertHasFix('''
+abstract class A {
+ void foo();
+}
+
+class B extends A {
+ @override
+ void foo() {
+ // TODO: implement foo
+ }
+}
+''');
+ }
+
+ test_method_generic() async {
+ await resolveTestUnit('''
+class C<T> {}
+class V<E> {}
+
+abstract class A {
+ E1 foo<E1, E2 extends C<int>>(V<E2> v);
+}
+
+class B implements A {
+}
+''');
+ await assertHasFix('''
+class C<T> {}
+class V<E> {}
+
+abstract class A {
+ E1 foo<E1, E2 extends C<int>>(V<E2> v);
+}
+
+class B implements A {
+ @override
+ E1 foo<E1, E2 extends C<int>>(V<E2> v) {
+ // TODO: implement foo
+ return null;
+ }
+}
+''');
+ }
+
+ test_method_generic_withBounds() async {
+ // https://github.com/dart-lang/sdk/issues/31199
+ await resolveTestUnit('''
+abstract class A<K, V> {
+ List<T> foo<T extends V>(K key);
+}
+
+class B<K, V> implements A<K, V> {
+}
+''');
+ await assertHasFix('''
+abstract class A<K, V> {
+ List<T> foo<T extends V>(K key);
+}
+
+class B<K, V> implements A<K, V> {
+ @override
+ List<T> foo<T extends V>(K key) {
+ // TODO: implement foo
+ return null;
+ }
+}
+''');
+ }
+
+ test_method_genericClass2() async {
+ await resolveTestUnit('''
+class A<R> {
+ R foo(int a) => null;
+}
+
+class B<R> extends A<R> {
+ R bar(double b) => null;
+}
+
+class X implements B<bool> {
+}
+''');
+ await assertHasFix('''
+class A<R> {
+ R foo(int a) => null;
+}
+
+class B<R> extends A<R> {
+ R bar(double b) => null;
+}
+
+class X implements B<bool> {
+ @override
+ bool bar(double b) {
+ // TODO: implement bar
+ return null;
+ }
+
+ @override
+ bool foo(int a) {
+ // TODO: implement foo
+ return null;
+ }
+}
+''');
+ }
+
+ test_method_notEmptyClassBody() async {
+ await resolveTestUnit('''
+abstract class A {
+ void foo();
+}
+
+class B extends A {
+ void bar() {}
+}
+''');
+ await assertHasFix('''
+abstract class A {
+ void foo();
+}
+
+class B extends A {
+ void bar() {}
+
+ @override
+ void foo() {
+ // TODO: implement foo
+ }
+}
+''');
+ }
+
+ test_operator() async {
+ await resolveTestUnit('''
+abstract class A {
+ int operator [](int index);
+ void operator []=(int index, String value);
+}
+
+class B extends A {
+}
+''');
+ await assertHasFix('''
+abstract class A {
+ int operator [](int index);
+ void operator []=(int index, String value);
+}
+
+class B extends A {
+ @override
+ int operator [](int index) {
+ // TODO: implement []
+ return null;
+ }
+
+ @override
+ void operator []=(int index, String value) {
+ // TODO: implement []=
+ }
+}
+''');
+ }
+
+ test_setter() async {
+ await resolveTestUnit('''
+abstract class A {
+ set s1(x);
+ set s2(int x);
+ void set s3(String x);
+}
+
+class B extends A {
+}
+''');
+ await assertHasFix('''
+abstract class A {
+ set s1(x);
+ set s2(int x);
+ void set s3(String x);
+}
+
+class B extends A {
+ @override
+ void set s1(x) {
+ // TODO: implement s1
+ }
+
+ @override
+ void set s2(int x) {
+ // TODO: implement s2
+ }
+
+ @override
+ void set s3(String x) {
+ // TODO: implement s3
+ }
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_mixin_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_mixin_test.dart
new file mode 100644
index 0000000..463f417
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_mixin_test.dart
@@ -0,0 +1,160 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(CreateMixinTest);
+ });
+}
+
+@reflectiveTest
+class CreateMixinTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.CREATE_MIXIN;
+
+ test_hasUnresolvedPrefix() async {
+ await resolveTestUnit('''
+main() {
+ prefix.Test v = null;
+ print(v);
+}
+''');
+ await assertNoFix();
+ }
+
+ test_inLibraryOfPrefix() async {
+ String libCode = r'''
+class A {}
+''';
+ addSource('/home/test/lib/lib.dart', libCode);
+ await resolveTestUnit('''
+import 'lib.dart' as lib;
+
+main() {
+ lib.A a = null;
+ lib.Test t = null;
+ print('\$a \$t');
+}
+''');
+ await assertHasFix('''
+class A {}
+
+mixin Test {
+}
+''', target: '/home/test/lib/lib.dart');
+ expect(change.linkedEditGroups, hasLength(1));
+ }
+
+ test_innerLocalFunction() async {
+ await resolveTestUnit('''
+f() {
+ g() {
+ Test v = null;
+ print(v);
+ }
+ g();
+}
+''');
+ await assertHasFix('''
+f() {
+ g() {
+ Test v = null;
+ print(v);
+ }
+ g();
+}
+
+mixin Test {
+}
+''');
+ assertLinkedGroup(change.linkedEditGroups[0], ['Test v =', 'Test {']);
+ }
+
+ test_instanceCreation_withNew() async {
+ await resolveTestUnit('''
+main() {
+ new Test();
+}
+''');
+ await assertNoFix();
+ }
+
+ test_instanceCreation_withoutNew() async {
+ await resolveTestUnit('''
+main() {
+ Test();
+}
+''');
+ await assertNoFix();
+ }
+
+ test_itemOfList() async {
+ await resolveTestUnit('''
+main() {
+ var a = [Test];
+ print(a);
+}
+''');
+ await assertHasFix('''
+main() {
+ var a = [Test];
+ print(a);
+}
+
+mixin Test {
+}
+''');
+ assertLinkedGroup(change.linkedEditGroups[0], ['Test];', 'Test {']);
+ }
+
+ test_itemOfList_inAnnotation() async {
+ await resolveTestUnit('''
+class MyAnnotation {
+ const MyAnnotation(a, b);
+}
+@MyAnnotation(int, const [Test])
+main() {}
+''');
+ await assertHasFix('''
+class MyAnnotation {
+ const MyAnnotation(a, b);
+}
+@MyAnnotation(int, const [Test])
+main() {}
+
+mixin Test {
+}
+''', errorFilter: (error) {
+ return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER;
+ });
+ assertLinkedGroup(change.linkedEditGroups[0], ['Test])', 'Test {']);
+ }
+
+ test_simple() async {
+ await resolveTestUnit('''
+main() {
+ Test v = null;
+ print(v);
+}
+''');
+ await assertHasFix('''
+main() {
+ Test v = null;
+ print(v);
+}
+
+mixin Test {
+}
+''');
+ assertLinkedGroup(change.linkedEditGroups[0], ['Test v =', 'Test {']);
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_no_such_method_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_no_such_method_test.dart
new file mode 100644
index 0000000..5799c31
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_no_such_method_test.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(CreateNoSuchMethodTest);
+ });
+}
+
+@reflectiveTest
+class CreateNoSuchMethodTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.CREATE_NO_SUCH_METHOD;
+
+ test_class() async {
+ await resolveTestUnit('''
+abstract class A {
+ m1();
+ int m2();
+}
+
+class B extends A {
+ existing() {}
+}
+''');
+ await assertHasFix('''
+abstract class A {
+ m1();
+ int m2();
+}
+
+class B extends A {
+ existing() {}
+
+ noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+''');
+ }
+
+ test_classTypeAlias() async {
+ await resolveTestUnit('''
+abstract class A {
+ m();
+}
+
+class B = Object with A;
+''');
+ await assertNoFix();
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/extend_class_for_mixin_test.dart b/pkg/analysis_server/test/src/services/correction/fix/extend_class_for_mixin_test.dart
new file mode 100644
index 0000000..d65e90a
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/extend_class_for_mixin_test.dart
@@ -0,0 +1,79 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ExtendClassForMixinTest);
+ });
+}
+
+@reflectiveTest
+class ExtendClassForMixinTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.EXTEND_CLASS_FOR_MIXIN;
+
+ test_missingClass_withExtends() async {
+ await resolveTestUnit('''
+class A {}
+class B {}
+mixin M on B {}
+class C extends A with M {}
+''');
+ await assertNoFix();
+ }
+
+ test_missingClass_withoutExtends_withImplements() async {
+ await resolveTestUnit('''
+class A {}
+class B {}
+mixin M on B {}
+class C with M implements A {}
+''');
+ await assertHasFix('''
+class A {}
+class B {}
+mixin M on B {}
+class C extends B with M implements A {}
+''');
+ }
+
+ test_missingClass_withoutExtends_withoutImplements() async {
+ await resolveTestUnit('''
+class A {}
+mixin M on A {}
+class C with M {}
+''');
+ await assertHasFix('''
+class A {}
+mixin M on A {}
+class C extends A with M {}
+''');
+ }
+
+ test_missingMixin_withExtends() async {
+ await resolveTestUnit('''
+class A {}
+mixin M {}
+mixin N on M {}
+class C extends A with N {}
+''');
+ await assertNoFix();
+ }
+
+ @failingTest
+ test_missingMixin_withoutExtends() async {
+ await resolveTestUnit('''
+mixin M {}
+mixin N on M {}
+class C with N {}
+''');
+ await assertNoFix();
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart b/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
new file mode 100644
index 0000000..76cc4ce
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
@@ -0,0 +1,265 @@
+// Copyright (c) 2018, 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/plugin/edit/fix/fix_core.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/src/dart/error/lint_codes.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart'
+ hide AnalysisError;
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test/test.dart';
+
+import '../../../../abstract_single_unit.dart';
+
+/// A base class defining support for writing fix processor tests that are
+/// specific to fixes associated with lints that use the FixKind.
+abstract class FixProcessorLintTest extends FixProcessorTest {
+ /// Return the lint code being tested.
+ String get lintCode;
+
+ /// Find the error that is to be fixed by computing the errors in the file,
+ /// using the [errorFilter] to filter out errors that should be ignored, and
+ /// expecting that there is a single remaining error. The error filter should
+ /// return `true` if the error should not be ignored.
+ Future<AnalysisError> _findErrorToFix(
+ bool Function(AnalysisError) errorFilter,
+ {int length}) async {
+ int index = testCode.indexOf('/*LINT*/');
+ if (index < 0) {
+ fail('Missing "/*LINT*/" marker');
+ }
+ return new AnalysisError(testSource, index + '/*LINT*/'.length, length ?? 0,
+ new LintCode(lintCode, '<ignored>'));
+ }
+}
+
+/// A base class defining support for writing fix processor tests.
+abstract class FixProcessorTest extends AbstractSingleUnitTest {
+ /// The errors in the file for which fixes are being computed.
+ List<AnalysisError> _errors;
+
+ /// The source change associated with the fix that was found, or `null` if
+ /// neither [assertHasFix] nor [assertHasFixAllFix] has been invoked.
+ SourceChange change;
+
+ /// The result of applying the [change] to the file content, or `null` if
+ /// neither [assertHasFix] nor [assertHasFixAllFix] has been invoked.
+ String resultCode;
+
+ /// Return the kind of fixes being tested by this test class.
+ FixKind get kind;
+
+ Future<void> assertHasFix(String expected,
+ {bool Function(AnalysisError) errorFilter,
+ int length,
+ String target}) async {
+ AnalysisError error = await _findErrorToFix(errorFilter, length: length);
+ Fix fix = await _assertHasFix(error);
+ change = fix.change;
+
+ // apply to "file"
+ List<SourceFileEdit> fileEdits = change.edits;
+ expect(fileEdits, hasLength(1));
+
+ String fileContent = testCode;
+ if (target != null) {
+ expect(fileEdits.first.file, convertPath(target));
+ fileContent = getFile(target).readAsStringSync();
+ }
+
+ resultCode = SourceEdit.applySequence(fileContent, change.edits[0].edits);
+ expect(resultCode, expected);
+ }
+
+ assertHasFixAllFix(ErrorCode errorCode, String expected,
+ {String target}) async {
+ AnalysisError error = await _findErrorToFixOfType(errorCode);
+ Fix fix = await _assertHasFixAllFix(error);
+ change = fix.change;
+
+ // apply to "file"
+ List<SourceFileEdit> fileEdits = change.edits;
+ expect(fileEdits, hasLength(1));
+
+ String fileContent = testCode;
+ if (target != null) {
+ expect(fileEdits.first.file, convertPath(target));
+ fileContent = getFile(target).readAsStringSync();
+ }
+
+ resultCode = SourceEdit.applySequence(fileContent, change.edits[0].edits);
+ expect(resultCode, expected);
+ }
+
+ Future<void> assertHasFixWithoutApplying(
+ {bool Function(AnalysisError) errorFilter}) async {
+ AnalysisError error = await _findErrorToFix(errorFilter);
+ Fix fix = await _assertHasFix(error);
+ change = fix.change;
+ }
+
+ void assertLinkedGroup(LinkedEditGroup group, List<String> expectedStrings,
+ [List<LinkedEditSuggestion> expectedSuggestions]) {
+ List<Position> expectedPositions = _findResultPositions(expectedStrings);
+ expect(group.positions, unorderedEquals(expectedPositions));
+ if (expectedSuggestions != null) {
+ expect(group.suggestions, unorderedEquals(expectedSuggestions));
+ }
+ }
+
+ /// Compute fixes for all of the errors in the test file to effectively assert
+ /// that no exceptions will be thrown by doing so.
+ Future<void> assertNoExceptions() async {
+ List<AnalysisError> errors = await _computeErrors();
+ for (var error in errors) {
+ await _computeFixes(error);
+ }
+ }
+
+ /// Compute fixes and ensure that there is no fix of the [kind] being tested by
+ /// this class.
+ Future<void> assertNoFix({bool Function(AnalysisError) errorFilter}) async {
+ AnalysisError error = await _findErrorToFix(errorFilter);
+ await _assertNoFix(error);
+ }
+
+ List<LinkedEditSuggestion> expectedSuggestions(
+ LinkedEditSuggestionKind kind, List<String> values) {
+ return values.map((value) {
+ return new LinkedEditSuggestion(value, kind);
+ }).toList();
+ }
+
+ @override
+ void setUp() {
+ super.setUp();
+ verifyNoTestUnitErrors = false;
+ }
+
+ /// Computes fixes and verifies that there is a fix for the given [error] of
+ /// the appropriate kind.
+ Future<Fix> _assertHasFix(AnalysisError error) async {
+ // Compute the fixes for this AnalysisError
+ final List<Fix> fixes = await _computeFixes(error);
+
+ // Assert that none of the fixes are a fix-all fix.
+ Fix foundFix = null;
+ for (Fix fix in fixes) {
+ if (fix.isFixAllFix()) {
+ fail('A fix-all fix was found for the error: $error '
+ 'in the computed set of fixes:\n${fixes.join('\n')}');
+ } else if (fix.kind == kind) {
+ foundFix ??= fix;
+ }
+ }
+ if (foundFix == null) {
+ fail('Expected to find fix $kind in\n${fixes.join('\n')}');
+ }
+ return foundFix;
+ }
+
+ /// Computes fixes and verifies that there is a fix for the given [error] of
+ /// the appropriate kind.
+ Future<Fix> _assertHasFixAllFix(AnalysisError error) async {
+ if (!kind.canBeAppliedTogether()) {
+ fail('Expected to find and return fix-all FixKind for $kind, '
+ 'but kind.canBeAppliedTogether is ${kind.canBeAppliedTogether}');
+ }
+
+ // Compute the fixes for the error.
+ List<Fix> fixes = await _computeFixes(error);
+
+ // Assert that there exists such a fix in the list.
+ Fix foundFix = null;
+ for (Fix fix in fixes) {
+ if (fix.kind == kind && fix.isFixAllFix()) {
+ foundFix = fix;
+ break;
+ }
+ }
+ if (foundFix == null) {
+ fail('No fix-all fix was found for the error: $error '
+ 'in the computed set of fixes:\n${fixes.join('\n')}');
+ }
+ return foundFix;
+ }
+
+ Future<void> _assertNoFix(AnalysisError error) async {
+ List<Fix> fixes = await _computeFixes(error);
+ for (Fix fix in fixes) {
+ if (fix.kind == kind) {
+ fail('Unexpected fix $kind in\n${fixes.join('\n')}');
+ }
+ }
+ }
+
+ Future<List<AnalysisError>> _computeErrors() async {
+ if (_errors == null) {
+ if (testAnalysisResult != null) {
+ _errors = testAnalysisResult.errors;
+ }
+ if (_errors == null) {
+ var result = await session.getResolvedUnit(testFile);
+ _errors = result.errors;
+ }
+ }
+ return _errors;
+ }
+
+ /// Computes fixes for the given [error] in [testUnit].
+ Future<List<Fix>> _computeFixes(AnalysisError error) async {
+ var context = new DartFixContextImpl(testAnalysisResult, error);
+ return await new DartFixContributor().computeFixes(context);
+ }
+
+ /// Find the error that is to be fixed by computing the errors in the file,
+ /// using the [errorFilter] to filter out errors that should be ignored, and
+ /// expecting that there is a single remaining error. The error filter should
+ /// return `true` if the error should not be ignored.
+ Future<AnalysisError> _findErrorToFix(
+ bool Function(AnalysisError) errorFilter,
+ {int length}) async {
+ List<AnalysisError> errors = await _computeErrors();
+ if (errorFilter != null) {
+ if (errors.length == 1) {
+ fail('Unnecessary error filter');
+ }
+ errors = errors.where(errorFilter).toList();
+ }
+ if (errors.length == 0) {
+ fail('Expected one error, found: none');
+ } else if (errors.length > 1) {
+ StringBuffer buffer = new StringBuffer();
+ buffer.writeln('Expected one error, found:');
+ for (AnalysisError error in errors) {
+ buffer.writeln(' $error [${error.errorCode}]');
+ }
+ fail(buffer.toString());
+ }
+ return errors[0];
+ }
+
+ Future<AnalysisError> _findErrorToFixOfType(ErrorCode errorCode) async {
+ List<AnalysisError> errors = await _computeErrors();
+ for (AnalysisError error in errors) {
+ if (error.errorCode == errorCode) {
+ return error;
+ }
+ }
+ return null;
+ }
+
+ List<Position> _findResultPositions(List<String> searchStrings) {
+ List<Position> positions = <Position>[];
+ for (String search in searchStrings) {
+ int offset = resultCode.indexOf(search);
+ positions.add(new Position(testFile, offset));
+ }
+ return positions;
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/fix_test.dart b/pkg/analysis_server/test/src/services/correction/fix/fix_test.dart
new file mode 100644
index 0000000..655614c
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/fix_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2018, 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:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(FixTest);
+ });
+}
+
+@reflectiveTest
+class FixTest extends FixProcessorTest {
+ @override
+ FixKind get kind => fail('kind should not be requested');
+
+ test_malformedTypeTest() async {
+ await resolveTestUnit('''
+main(p) {
+ p i s Null;
+}''');
+ await assertNoExceptions();
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/import_async_test.dart b/pkg/analysis_server/test/src/services/correction/fix/import_async_test.dart
new file mode 100644
index 0000000..7bd9141
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/import_async_test.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ImportAsyncTest);
+ });
+}
+
+@reflectiveTest
+class ImportAsyncTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.IMPORT_ASYNC;
+
+ test_future() async {
+ updateTestPubspecFile('''
+environment:
+ sdk: ^2.0.0
+''');
+ await resolveTestUnit('''
+Future<int> zero() async => 0;
+''');
+ await assertHasFix('''
+import 'dart:async';
+
+Future<int> zero() async => 0;
+''');
+ }
+
+ test_stream() async {
+ updateTestPubspecFile('''
+environment:
+ sdk: ^2.0.0
+''');
+ await resolveTestUnit('''
+Stream<int> zero() => null;
+''');
+ await assertHasFix('''
+import 'dart:async';
+
+Stream<int> zero() => null;
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/import_library_prefix_test.dart b/pkg/analysis_server/test/src/services/correction/fix/import_library_prefix_test.dart
new file mode 100644
index 0000000..af0bbbe
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/import_library_prefix_test.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ImportLibraryPrefixTest);
+ });
+}
+
+@reflectiveTest
+class ImportLibraryPrefixTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.IMPORT_LIBRARY_PREFIX;
+
+ test_withClass() async {
+ await resolveTestUnit('''
+import 'dart:collection' as pref;
+main() {
+ pref.HashMap s = null;
+ LinkedHashMap f = null;
+ print('\$s \$f');
+}
+''');
+ await assertHasFix('''
+import 'dart:collection' as pref;
+main() {
+ pref.HashMap s = null;
+ pref.LinkedHashMap f = null;
+ print('\$s \$f');
+}
+''');
+ }
+
+ test_withTopLevelVariable() async {
+ await resolveTestUnit('''
+import 'dart:math' as pref;
+main() {
+ print(pref.E);
+ print(PI);
+}
+''');
+ await assertHasFix('''
+import 'dart:math' as pref;
+main() {
+ print(pref.E);
+ print(pref.PI);
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart b/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart
new file mode 100644
index 0000000..68d5820
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart
@@ -0,0 +1,485 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ImportLibraryProject1Test);
+ defineReflectiveTests(ImportLibraryProject2Test);
+ defineReflectiveTests(ImportLibraryProject3Test);
+ });
+}
+
+@reflectiveTest
+class ImportLibraryProject1Test extends FixProcessorTest
+ with ImportLibraryTestMixin {
+ @override
+ FixKind get kind => DartFixKind.IMPORT_LIBRARY_PROJECT1;
+
+ test_alreadyImported_package() async {
+ addSource('/home/test/lib/lib.dart', '''
+class A {}
+class B {}
+''');
+ await resolveTestUnit('''
+import 'lib.dart' show A;
+main() {
+ A a;
+ B b;
+ print('\$a \$b');
+}
+''');
+ await assertNoFix();
+ }
+
+ test_notInLib() async {
+ addSource('/home/other/test/lib.dart', 'class Test {}');
+ await resolveTestUnit('''
+main() {
+ Test t;
+ print(t);
+}
+''');
+ await assertNoFix();
+ }
+
+ test_preferDirectOverExport() async {
+ _configureMyPkg({'b.dart': 'class Test {}', 'a.dart': "export 'b.dart';"});
+ await resolveTestUnit('''
+main() {
+ Test test = null;
+ print(test);
+}
+''');
+ await assertHasFix('''
+import 'package:my_pkg/b.dart';
+
+main() {
+ Test test = null;
+ print(test);
+}
+''');
+ }
+
+ test_preferDirectOverExport_src() async {
+ _configureMyPkg({'b.dart': 'class Test {}', 'a.dart': "export 'b.dart';"});
+ await resolveTestUnit('''
+main() {
+ Test test = null;
+ print(test);
+}
+''');
+ await assertHasFix('''
+import 'package:my_pkg/b.dart';
+
+main() {
+ Test test = null;
+ print(test);
+}
+''');
+ }
+
+ test_withClass_annotation() async {
+ addSource('/home/test/lib/lib.dart', '''
+library lib;
+class Test {
+ const Test(int p);
+}
+''');
+ await resolveTestUnit('''
+@Test(0)
+main() {
+}
+''');
+ await assertHasFix('''
+import 'package:test/lib.dart';
+
+@Test(0)
+main() {
+}
+''');
+ }
+
+ test_withClass_hasOtherLibraryWithPrefix() async {
+ addSource('/home/test/lib/a.dart', '''
+library a;
+class One {}
+''');
+ addSource('/home/test/lib/b.dart', '''
+library b;
+class One {}
+class Two {}
+''');
+ await resolveTestUnit('''
+import 'package:test/b.dart' show Two;
+main () {
+ new Two();
+ new One();
+}
+''');
+ await assertHasFix('''
+import 'package:test/a.dart';
+import 'package:test/b.dart' show Two;
+main () {
+ new Two();
+ new One();
+}
+''');
+ }
+
+ test_withClass_inParentFolder() async {
+ testFile = convertPath('/home/test/bin/aaa/test.dart');
+ addSource('/home/test/bin/lib.dart', '''
+library lib;
+class Test {}
+''');
+ await resolveTestUnit('''
+main() {
+ Test t = null;
+ print(t);
+}
+''');
+ await assertHasFix('''
+import '../lib.dart';
+
+main() {
+ Test t = null;
+ print(t);
+}
+''');
+ }
+
+ test_withClass_inRelativeFolder() async {
+ testFile = convertPath('/home/test/bin/test.dart');
+ addSource('/home/test/tool/sub/folder/lib.dart', '''
+library lib;
+class Test {}
+''');
+ await resolveTestUnit('''
+main() {
+ Test t = null;
+ print(t);
+}
+''');
+ await assertHasFix('''
+import '../tool/sub/folder/lib.dart';
+
+main() {
+ Test t = null;
+ print(t);
+}
+''');
+ }
+
+ test_withClass_inSameFolder() async {
+ testFile = convertPath('/home/test/bin/test.dart');
+ addSource('/home/test/bin/lib.dart', '''
+library lib;
+class Test {}
+''');
+ await resolveTestUnit('''
+main() {
+ Test t = null;
+ print(t);
+}
+''');
+ await assertHasFix('''
+import 'lib.dart';
+
+main() {
+ Test t = null;
+ print(t);
+}
+''');
+ }
+
+ test_withClass_instanceCreation_const() async {
+ addSource('/home/test/lib/lib.dart', '''
+class Test {
+ const Test();
+}
+''');
+ await resolveTestUnit('''
+main() {
+ return const Test();
+}
+''');
+ await assertHasFix('''
+import 'package:test/lib.dart';
+
+main() {
+ return const Test();
+}
+''');
+ }
+
+ test_withClass_instanceCreation_const_namedConstructor() async {
+ addSource('/home/test/lib/lib.dart', '''
+class Test {
+ const Test.named();
+}
+''');
+ await resolveTestUnit('''
+main() {
+ const Test.named();
+}
+''');
+ await assertHasFix('''
+import 'package:test/lib.dart';
+
+main() {
+ const Test.named();
+}
+''');
+ }
+
+ test_withClass_instanceCreation_implicit() async {
+ addSource('/home/test/lib/lib.dart', '''
+class Test {
+ const Test();
+}
+''');
+ await resolveTestUnit('''
+main() {
+ return Test();
+}
+''');
+ await assertHasFix('''
+import 'package:test/lib.dart';
+
+main() {
+ return Test();
+}
+''');
+ }
+
+ test_withClass_instanceCreation_new() async {
+ addSource('/home/test/lib/lib.dart', '''
+class Test {
+ const Test();
+}
+''');
+ await resolveTestUnit('''
+main() {
+ return new Test();
+}
+''');
+ await assertHasFix('''
+import 'package:test/lib.dart';
+
+main() {
+ return new Test();
+}
+''');
+ }
+
+ test_withClass_instanceCreation_new_namedConstructor() async {
+ addSource('/home/test/lib/lib.dart', '''
+class Test {
+ Test.named();
+}
+''');
+ await resolveTestUnit('''
+main() {
+ new Test.named();
+}
+''');
+ await assertHasFix('''
+import 'package:test/lib.dart';
+
+main() {
+ new Test.named();
+}
+''');
+ }
+
+ test_withFunction() async {
+ addSource('/home/test/lib/lib.dart', '''
+library lib;
+myFunction() {}
+''');
+ await resolveTestUnit('''
+main() {
+ myFunction();
+}
+''');
+ await assertHasFix('''
+import 'package:test/lib.dart';
+
+main() {
+ myFunction();
+}
+''');
+ }
+
+ test_withFunction_unresolvedMethod() async {
+ addSource('/home/test/lib/lib.dart', '''
+library lib;
+myFunction() {}
+''');
+ await resolveTestUnit('''
+class A {
+ main() {
+ myFunction();
+ }
+}
+''');
+ await assertHasFix('''
+import 'package:test/lib.dart';
+
+class A {
+ main() {
+ myFunction();
+ }
+}
+''');
+ }
+
+ test_withFunctionTypeAlias() async {
+ addSource('/home/test/lib/lib.dart', '''
+library lib;
+typedef MyFunction();
+''');
+ await resolveTestUnit('''
+main() {
+ MyFunction t = null;
+ print(t);
+}
+''');
+ await assertHasFix('''
+import 'package:test/lib.dart';
+
+main() {
+ MyFunction t = null;
+ print(t);
+}
+''');
+ }
+
+ test_withTopLevelVariable() async {
+ addSource('/home/test/lib/lib.dart', '''
+library lib;
+int MY_VAR = 42;
+''');
+ await resolveTestUnit('''
+main() {
+ print(MY_VAR);
+}
+''');
+ await assertHasFix('''
+import 'package:test/lib.dart';
+
+main() {
+ print(MY_VAR);
+}
+''');
+ }
+}
+
+@reflectiveTest
+class ImportLibraryProject2Test extends FixProcessorTest
+ with ImportLibraryTestMixin {
+ @override
+ FixKind get kind => DartFixKind.IMPORT_LIBRARY_PROJECT2;
+
+ test_preferDirectOverExport() async {
+ _configureMyPkg({
+ 'b.dart': 'class Test {}',
+ 'a.dart': "export 'b.dart';",
+ });
+ await resolveTestUnit('''
+main() {
+ Test test = null;
+ print(test);
+}
+''');
+ await assertHasFix('''
+import 'package:my_pkg/a.dart';
+
+main() {
+ Test test = null;
+ print(test);
+}
+''');
+ }
+
+ test_preferDirectOverExport_src() async {
+ _configureMyPkg({
+ 'b.dart': 'class Test {}',
+ 'a.dart': "export 'b.dart';",
+ });
+ await resolveTestUnit('''
+main() {
+ Test test = null;
+ print(test);
+}
+''');
+ await assertHasFix('''
+import 'package:my_pkg/a.dart';
+
+main() {
+ Test test = null;
+ print(test);
+}
+''');
+ }
+}
+
+@reflectiveTest
+class ImportLibraryProject3Test extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.IMPORT_LIBRARY_PROJECT3;
+
+ test_inLibSrc_differentContextRoot() async {
+ addPackageFile('bbb', 'b1.dart', r'''
+import 'src/b2.dart';
+class A {}
+''');
+ addPackageFile('bbb', 'src/b2.dart', 'class Test {}');
+ await resolveTestUnit('''
+import 'package:bbb/b1.dart';
+main() {
+ Test t;
+ A a;
+ print('\$t \$a');
+}
+''');
+ await assertNoFix();
+ }
+
+ test_inLibSrc_thisContextRoot() async {
+ addSource('/home/test/lib/src/lib.dart', 'class Test {}');
+ await resolveTestUnit('''
+main() {
+ Test t;
+ print(t);
+}
+''');
+ await assertHasFix('''
+import 'package:test/src/lib.dart';
+
+main() {
+ Test t;
+ print(t);
+}
+''');
+ }
+}
+
+mixin ImportLibraryTestMixin on FixProcessorTest {
+ /// Configures the source factory to have a package named 'my_pkg' and for
+ /// the package to contain all of the files described by the [pathToCode] map.
+ /// The keys in the map are paths relative to the root of the package, and the
+ /// values are the contents of the files at those paths.
+ void _configureMyPkg(Map<String, String> pathToCode) {
+ pathToCode.forEach((path, code) {
+ addPackageFile('my_pkg', path, code);
+ });
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/import_library_sdk_test.dart b/pkg/analysis_server/test/src/services/correction/fix/import_library_sdk_test.dart
new file mode 100644
index 0000000..ce3dcc4
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/import_library_sdk_test.dart
@@ -0,0 +1,272 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ImportLibrarySdkTest);
+ });
+}
+
+@reflectiveTest
+class ImportLibrarySdkTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.IMPORT_LIBRARY_SDK;
+
+ test_alreadyImported_sdk() async {
+ await resolveTestUnit('''
+import 'dart:collection' show HashMap;
+main() {
+ HashMap s = null;
+ LinkedHashMap f = null;
+ print('\$s \$f');
+}
+''');
+ await assertNoFix();
+ }
+
+ test_withClass_asExpression() async {
+ await resolveTestUnit('''
+main(p) {
+ p as HashMap;
+}
+''');
+ await assertHasFix('''
+import 'dart:collection';
+
+main(p) {
+ p as HashMap;
+}
+''');
+ }
+
+ test_withClass_instanceCreation_explicitNew() async {
+ await resolveTestUnit('''
+class C {
+ foo() {
+ new HashMap();
+ }
+}
+''');
+ await assertHasFix('''
+import 'dart:collection';
+
+class C {
+ foo() {
+ new HashMap();
+ }
+}
+''');
+ }
+
+ test_withClass_instanceCreation_explicitNew_namedConstructor() async {
+ await resolveTestUnit('''
+class C {
+ foo() {
+ new Completer.sync(0);
+ }
+}
+''');
+ await assertHasFix('''
+import 'dart:async';
+
+class C {
+ foo() {
+ new Completer.sync(0);
+ }
+}
+''');
+ }
+
+ test_withClass_instanceCreation_implicitNew() async {
+ await resolveTestUnit('''
+class C {
+ foo() {
+ HashMap();
+ }
+}
+''');
+ await assertHasFix('''
+import 'dart:collection';
+
+class C {
+ foo() {
+ HashMap();
+ }
+}
+''');
+ }
+
+ test_withClass_instanceCreation_implicitNew_namedConstructor() async {
+ await resolveTestUnit('''
+class C {
+ foo() {
+ Completer.sync(0);
+ }
+}
+''');
+ await assertHasFix('''
+import 'dart:async';
+
+class C {
+ foo() {
+ Completer.sync(0);
+ }
+}
+''');
+ }
+
+ test_withClass_invocationTarget() async {
+ await resolveTestUnit('''
+main() {
+ Timer.run(null);
+}
+''');
+ await assertHasFix('''
+import 'dart:async';
+
+main() {
+ Timer.run(null);
+}
+''');
+ }
+
+ test_withClass_IsExpression() async {
+ await resolveTestUnit('''
+main(p) {
+ p is Completer;
+}
+''');
+ await assertHasFix('''
+import 'dart:async';
+
+main(p) {
+ p is Completer;
+}
+''');
+ }
+
+ test_withClass_itemOfList() async {
+ await resolveTestUnit('''
+main() {
+ var a = [Completer];
+ print(a);
+}
+''');
+ await assertHasFix('''
+import 'dart:async';
+
+main() {
+ var a = [Completer];
+ print(a);
+}
+''');
+ }
+
+ test_withClass_itemOfList_inAnnotation() async {
+ await resolveTestUnit('''
+class MyAnnotation {
+ const MyAnnotation(a, b);
+}
+@MyAnnotation(int, const [Completer])
+main() {}
+''');
+ await assertHasFix('''
+import 'dart:async';
+
+class MyAnnotation {
+ const MyAnnotation(a, b);
+}
+@MyAnnotation(int, const [Completer])
+main() {}
+''', errorFilter: (error) {
+ return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER;
+ });
+ }
+
+ test_withClass_typeAnnotation() async {
+ await resolveTestUnit('''
+main() {
+ Completer f = null;
+ print(f);
+}
+''');
+ await assertHasFix('''
+import 'dart:async';
+
+main() {
+ Completer f = null;
+ print(f);
+}
+''');
+ }
+
+ test_withClass_typeAnnotation_PrefixedIdentifier() async {
+ await resolveTestUnit('''
+main() {
+ Timer.run;
+}
+''');
+ await assertHasFix('''
+import 'dart:async';
+
+main() {
+ Timer.run;
+}
+''');
+ }
+
+ test_withClass_typeArgument() async {
+ await resolveTestUnit('''
+main() {
+ List<Completer> completers = [];
+ print(completers);
+}
+''');
+ await assertHasFix('''
+import 'dart:async';
+
+main() {
+ List<Completer> completers = [];
+ print(completers);
+}
+''');
+ }
+
+ test_withTopLevelVariable() async {
+ await resolveTestUnit('''
+main() {
+ print(PI);
+}
+''');
+ await assertHasFix('''
+import 'dart:math';
+
+main() {
+ print(PI);
+}
+''');
+ }
+
+ test_withTopLevelVariable_annotation() async {
+ await resolveTestUnit('''
+@PI
+main() {
+}
+''');
+ await assertHasFix('''
+import 'dart:math';
+
+@PI
+main() {
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/import_library_show_test.dart b/pkg/analysis_server/test/src/services/correction/fix/import_library_show_test.dart
new file mode 100644
index 0000000..4f3885f
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/import_library_show_test.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ImportLibraryShowTest);
+ });
+}
+
+@reflectiveTest
+class ImportLibraryShowTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.IMPORT_LIBRARY_SHOW;
+
+ test_package() async {
+ addSource('/home/test/lib/lib.dart', '''
+class A {}
+class B {}
+''');
+ await resolveTestUnit('''
+import 'lib.dart' show A;
+main() {
+ A a;
+ B b;
+ print('\$a \$b');
+}
+''');
+ await assertHasFix('''
+import 'lib.dart' show A, B;
+main() {
+ A a;
+ B b;
+ print('\$a \$b');
+}
+''');
+ }
+
+ test_sdk() async {
+ await resolveTestUnit('''
+import 'dart:collection' show HashMap;
+main() {
+ HashMap s = null;
+ LinkedHashMap f = null;
+ print('\$s \$f');
+}
+''');
+ await assertHasFix('''
+import 'dart:collection' show HashMap, LinkedHashMap;
+main() {
+ HashMap s = null;
+ LinkedHashMap f = null;
+ print('\$s \$f');
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/insert_semicolon_test.dart b/pkg/analysis_server/test/src/services/correction/fix/insert_semicolon_test.dart
new file mode 100644
index 0000000..77123f3
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/insert_semicolon_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(InsertSemicolonTest);
+ });
+}
+
+@reflectiveTest
+class InsertSemicolonTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.INSERT_SEMICOLON;
+
+ test_expectedToken_semicolon() async {
+ await resolveTestUnit('''
+main() {
+ print(0)
+}
+''');
+ await assertHasFix('''
+main() {
+ print(0);
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/make_class_abstract_test.dart b/pkg/analysis_server/test/src/services/correction/fix/make_class_abstract_test.dart
new file mode 100644
index 0000000..7dbf4e9
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/make_class_abstract_test.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(MakeClassAbstractTest);
+ });
+}
+
+@reflectiveTest
+class MakeClassAbstractTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.MAKE_CLASS_ABSTRACT;
+
+ test_declaresAbstractMethod() async {
+ await resolveTestUnit('''
+class A {
+ m();
+}
+''');
+ await assertHasFix('''
+abstract class A {
+ m();
+}
+''');
+ }
+
+ test_inheritsAbstractMethod() async {
+ await resolveTestUnit('''
+abstract class A {
+ m();
+}
+class B extends A {
+}
+''');
+ await assertHasFix('''
+abstract class A {
+ m();
+}
+abstract class B extends A {
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/make_field_not_final_test.dart b/pkg/analysis_server/test/src/services/correction/fix/make_field_not_final_test.dart
new file mode 100644
index 0000000..6027ac6
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/make_field_not_final_test.dart
@@ -0,0 +1,59 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(MakeFieldNotFinalTest);
+ });
+}
+
+@reflectiveTest
+class MakeFieldNotFinalTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.MAKE_FIELD_NOT_FINAL;
+
+ test_hasType() async {
+ await resolveTestUnit('''
+class A {
+ final int fff = 1;
+ main() {
+ fff = 2;
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ int fff = 1;
+ main() {
+ fff = 2;
+ }
+}
+''');
+ }
+
+ test_noType() async {
+ await resolveTestUnit('''
+class A {
+ final fff = 1;
+ main() {
+ fff = 2;
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ var fff = 1;
+ main() {
+ fff = 2;
+ }
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/make_final_test.dart b/pkg/analysis_server/test/src/services/correction/fix/make_final_test.dart
new file mode 100644
index 0000000..31bc18d
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/make_final_test.dart
@@ -0,0 +1,108 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(MakeFinalTest);
+ });
+}
+
+@reflectiveTest
+class MakeFinalTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.MAKE_FINAL;
+
+ @override
+ String get lintCode => LintNames.prefer_final_fields;
+
+ test_field_type() async {
+ await resolveTestUnit('''
+class C {
+ int /*LINT*/f = 2;
+}
+''');
+ await assertHasFix('''
+class C {
+ final int /*LINT*/f = 2;
+}
+''');
+ }
+
+ test_field_var() async {
+ await resolveTestUnit('''
+class C {
+ var /*LINT*/f = 2;
+}
+''');
+ await assertHasFix('''
+class C {
+ final /*LINT*/f = 2;
+}
+''');
+ }
+
+ test_local_type() async {
+ await resolveTestUnit('''
+bad() {
+ int /*LINT*/x = 2;
+}
+''');
+ await assertHasFix('''
+bad() {
+ final int /*LINT*/x = 2;
+}
+''');
+ }
+
+ test_local_var() async {
+ await resolveTestUnit('''
+bad() {
+ var /*LINT*/x = 2;
+}
+''');
+ await assertHasFix('''
+bad() {
+ final /*LINT*/x = 2;
+}
+''');
+ }
+
+ test_noKeyword() async {
+ await resolveTestUnit('''
+class C {
+ /*LINT*/f = 2;
+}
+''');
+ await assertHasFix('''
+class C {
+ /*LINT*/final f = 2;
+}
+''');
+ }
+
+ test_topLevel_type() async {
+ await resolveTestUnit('''
+int /*LINT*/x = 2;
+''');
+ await assertHasFix('''
+final int /*LINT*/x = 2;
+''');
+ }
+
+ test_topLevel_var() async {
+ await resolveTestUnit('''
+var /*LINT*/x = 2;
+''');
+ await assertHasFix('''
+final /*LINT*/x = 2;
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/move_type_arguments_to_class_test.dart b/pkg/analysis_server/test/src/services/correction/fix/move_type_arguments_to_class_test.dart
new file mode 100644
index 0000000..b7622e9
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/move_type_arguments_to_class_test.dart
@@ -0,0 +1,123 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(MoveTypeArgumentsToClassTest);
+ });
+}
+
+@reflectiveTest
+class MoveTypeArgumentsToClassTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.MOVE_TYPE_ARGUMENTS_TO_CLASS;
+
+ test_explicitConst() async {
+ await resolveTestUnit('''
+main() {
+ const C.named<int>();
+}
+class C<E> {
+ const C.named();
+}
+''');
+ await assertHasFix('''
+main() {
+ const C<int>.named();
+}
+class C<E> {
+ const C.named();
+}
+''');
+ }
+
+ test_explicitNew() async {
+ await resolveTestUnit('''
+main() {
+ new C.named<int>();
+}
+class C<E> {
+ C.named();
+}
+''');
+ await assertHasFix('''
+main() {
+ new C<int>.named();
+}
+class C<E> {
+ C.named();
+}
+''');
+ }
+
+ test_explicitNew_alreadyThere() async {
+ await resolveTestUnit('''
+main() {
+ new C<String>.named<int>();
+}
+class C<E> {
+ C.named();
+}
+''');
+ await assertNoFix();
+ }
+
+ test_explicitNew_wrongNumber() async {
+ await resolveTestUnit('''
+main() {
+ new C.named<int, String>();
+}
+class C<E> {
+ C.named();
+}
+''');
+ await assertNoFix();
+ }
+
+ test_implicitConst() async {
+ await resolveTestUnit('''
+main() {
+ const C c = C.named<int>();
+ print(c);
+}
+class C<E> {
+ const C.named();
+}
+''');
+ await assertHasFix('''
+main() {
+ const C c = C<int>.named();
+ print(c);
+}
+class C<E> {
+ const C.named();
+}
+''');
+ }
+
+ test_implicitNew() async {
+ await resolveTestUnit('''
+main() {
+ C.named<int>();
+}
+class C<E> {
+ C.named();
+}
+''');
+ await assertHasFix('''
+main() {
+ C<int>.named();
+}
+class C<E> {
+ C.named();
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_await_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_await_test.dart
new file mode 100644
index 0000000..6121171
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_await_test.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RemoveAwaitTest);
+ });
+}
+
+@reflectiveTest
+class RemoveAwaitTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.REMOVE_AWAIT;
+
+ @override
+ String get lintCode => LintNames.await_only_futures;
+
+ test_intLiteral() async {
+ await resolveTestUnit('''
+bad() async {
+ print(/*LINT*/await 23);
+}
+''');
+ await assertHasFix('''
+bad() async {
+ print(/*LINT*/23);
+}
+''');
+ }
+
+ test_stringLiteral() async {
+ await resolveTestUnit('''
+bad() async {
+ print(/*LINT*/await 'hola');
+}
+''');
+ await assertHasFix('''
+bad() async {
+ print(/*LINT*/'hola');
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_dead_code_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_dead_code_test.dart
new file mode 100644
index 0000000..eec8f7c
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_dead_code_test.dart
@@ -0,0 +1,71 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RemoveDeadCodeTest);
+ });
+}
+
+@reflectiveTest
+class RemoveDeadCodeTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.REMOVE_DEAD_CODE;
+
+ test_condition() async {
+ await resolveTestUnit('''
+main(int p) {
+ if (true || p > 5) {
+ print(1);
+ }
+}
+''');
+ await assertHasFix('''
+main(int p) {
+ if (true) {
+ print(1);
+ }
+}
+''');
+ }
+
+ test_statements_one() async {
+ await resolveTestUnit('''
+int main() {
+ print(0);
+ return 42;
+ print(1);
+}
+''');
+ await assertHasFix('''
+int main() {
+ print(0);
+ return 42;
+}
+''');
+ }
+
+ test_statements_two() async {
+ await resolveTestUnit('''
+int main() {
+ print(0);
+ return 42;
+ print(1);
+ print(2);
+}
+''');
+ await assertHasFix('''
+int main() {
+ print(0);
+ return 42;
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_empty_catch_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_empty_catch_test.dart
new file mode 100644
index 0000000..b5784b8
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_empty_catch_test.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RemoveEmptyCatchTest);
+ });
+}
+
+@reflectiveTest
+class RemoveEmptyCatchTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.REMOVE_EMPTY_CATCH;
+
+ @override
+ String get lintCode => LintNames.empty_catches;
+
+ test_newLine() async {
+ await resolveTestUnit('''
+void foo() {
+ try {}
+ catch (e) {/*LINT*/}
+ finally {}
+}
+''');
+ await assertHasFix('''
+void foo() {
+ try {}
+ finally {}
+}
+''');
+ }
+
+ test_sameLine() async {
+ await resolveTestUnit('''
+void foo() {
+ try {} catch (e) {/*LINT*/} finally {}
+}
+''');
+ await assertHasFix('''
+void foo() {
+ try {} finally {}
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_empty_constructor_body_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_empty_constructor_body_test.dart
new file mode 100644
index 0000000..3030ea2
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_empty_constructor_body_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RemoveEmptyConstructorBodyTest);
+ });
+}
+
+@reflectiveTest
+class RemoveEmptyConstructorBodyTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.REMOVE_EMPTY_CONSTRUCTOR_BODY;
+
+ @override
+ String get lintCode => LintNames.empty_constructor_bodies;
+
+ test_empty() async {
+ await resolveTestUnit('''
+class C {
+ C() {/*LINT*/}
+}
+''');
+ await assertHasFix('''
+class C {
+ C();
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_empty_else_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_empty_else_test.dart
new file mode 100644
index 0000000..1019af5
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_empty_else_test.dart
@@ -0,0 +1,60 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RemoveEmptyElseTest);
+ });
+}
+
+@reflectiveTest
+class RemoveEmptyElseTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.REMOVE_EMPTY_ELSE;
+
+ @override
+ String get lintCode => LintNames.avoid_empty_else;
+
+ test_newLine() async {
+ await resolveTestUnit('''
+void foo(bool cond) {
+ if (cond) {
+ //
+ }
+ else /*LINT*/;
+}
+''');
+ await assertHasFix('''
+void foo(bool cond) {
+ if (cond) {
+ //
+ }
+}
+''');
+ }
+
+ test_sameLine() async {
+ await resolveTestUnit('''
+void foo(bool cond) {
+ if (cond) {
+ //
+ } else /*LINT*/;
+}
+''');
+ await assertHasFix('''
+void foo(bool cond) {
+ if (cond) {
+ //
+ }
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_empty_statement_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_empty_statement_test.dart
new file mode 100644
index 0000000..18a278c
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_empty_statement_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RemoveEmptyStatementTest);
+ });
+}
+
+@reflectiveTest
+class RemoveEmptyStatementTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.REMOVE_EMPTY_STATEMENT;
+
+ @override
+ String get lintCode => LintNames.empty_statements;
+
+ test_insideBlock() async {
+ await resolveTestUnit('''
+void foo() {
+ while(true) {
+ /*LINT*/;
+ }
+}
+''');
+ await assertHasFix('''
+void foo() {
+ while(true) {
+ /*LINT*/
+ }
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_initializer_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_initializer_test.dart
new file mode 100644
index 0000000..b686d62
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_initializer_test.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RemoveInitializerTest);
+ });
+}
+
+@reflectiveTest
+class RemoveInitializerTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.REMOVE_INITIALIZER;
+
+ @override
+ String get lintCode => LintNames.avoid_init_to_null;
+
+ test_field() async {
+ await resolveTestUnit('''
+class Test {
+ int /*LINT*/x = null;
+}
+''');
+ await assertHasFix('''
+class Test {
+ int /*LINT*/x;
+}
+''');
+ }
+
+ test_listOfVariableDeclarations() async {
+ await resolveTestUnit('''
+String a = 'a', /*LINT*/b = null, c = 'c';
+''');
+ await assertHasFix('''
+String a = 'a', /*LINT*/b, c = 'c';
+''');
+ }
+
+ test_topLevel() async {
+ await resolveTestUnit('''
+var /*LINT*/x = null;
+''');
+ await assertHasFix('''
+var /*LINT*/x;
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_interpolation_braces_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_interpolation_braces_test.dart
new file mode 100644
index 0000000..2fdfad9a
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_interpolation_braces_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RemoveInterpolationBracesTest);
+ });
+}
+
+@reflectiveTest
+class RemoveInterpolationBracesTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.REMOVE_INTERPOLATION_BRACES;
+
+ @override
+ String get lintCode => LintNames.unnecessary_brace_in_string_interp;
+
+ test_withSpace() async {
+ await resolveTestUnit(r'''
+main() {
+ var v = 42;
+ print('v: /*LINT*/${ v}');
+}
+''');
+ await assertHasFix(r'''
+main() {
+ var v = 42;
+ print('v: /*LINT*/$v');
+}
+''', length: 4);
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_method_declaration_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_method_declaration_test.dart
new file mode 100644
index 0000000..443d382
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_method_declaration_test.dart
@@ -0,0 +1,78 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RemoveMethodDeclarationTest);
+ });
+}
+
+@reflectiveTest
+class RemoveMethodDeclarationTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.REMOVE_METHOD_DECLARATION;
+
+ @override
+ String get lintCode => LintNames.unnecessary_override;
+
+ test_getter() async {
+ await resolveTestUnit('''
+class A {
+ int x;
+}
+class B extends A {
+ @override
+ int get /*LINT*/x => super.x;
+}
+''');
+ await assertHasFix('''
+class A {
+ int x;
+}
+class B extends A {
+}
+''');
+ }
+
+ test_method() async {
+ await resolveTestUnit('''
+class A {
+ @override
+ String /*LINT*/toString() => super.toString();
+}
+''');
+ await assertHasFix('''
+class A {
+}
+''');
+ }
+
+ test_setter() async {
+ await resolveTestUnit('''
+class A {
+ int x;
+}
+class B extends A {
+ @override
+ set /*LINT*/x(int other) {
+ this.x = other;
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ int x;
+}
+class B extends A {
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_parameters_in_getter_declaration_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_parameters_in_getter_declaration_test.dart
new file mode 100644
index 0000000..20606f5
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_parameters_in_getter_declaration_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RemoveParametersInGetterDeclarationTest);
+ });
+}
+
+@reflectiveTest
+class RemoveParametersInGetterDeclarationTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.REMOVE_PARAMETERS_IN_GETTER_DECLARATION;
+
+ test_emptyList() async {
+ await resolveTestUnit('''
+class A {
+ int get foo() => 0;
+}
+''');
+ await assertHasFix('''
+class A {
+ int get foo => 0;
+}
+''');
+ }
+
+ test_nonEmptyList() async {
+ await resolveTestUnit('''
+class A {
+ int get foo(int a) => 0;
+}
+''');
+ await assertHasFix('''
+class A {
+ int get foo => 0;
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_parentheses_in_getter_invocation_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_parentheses_in_getter_invocation_test.dart
new file mode 100644
index 0000000..65e1c39
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_parentheses_in_getter_invocation_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RemoveParenthesesInGetterInvocationTest);
+ });
+}
+
+@reflectiveTest
+class RemoveParenthesesInGetterInvocationTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.REMOVE_PARENTHESIS_IN_GETTER_INVOCATION;
+
+ test_noArguments() async {
+ await resolveTestUnit('''
+class A {
+ int get foo => 0;
+}
+main(A a) {
+ a.foo();
+}
+''');
+ await assertHasFix('''
+class A {
+ int get foo => 0;
+}
+main(A a) {
+ a.foo;
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_this_expression_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_this_expression_test.dart
new file mode 100644
index 0000000..5ea13d4
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_this_expression_test.dart
@@ -0,0 +1,106 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RemoveThisExpressionTest);
+ });
+}
+
+@reflectiveTest
+class RemoveThisExpressionTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.REMOVE_THIS_EXPRESSION;
+
+ @override
+ String get lintCode => LintNames.unnecessary_this;
+
+ test_methodInvocation_oneCharacterOperator() async {
+ await resolveTestUnit('''
+class A {
+ void foo() {
+ /*LINT*/this.foo();
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ void foo() {
+ /*LINT*/foo();
+ }
+}
+''');
+ }
+
+ test_methodInvocation_twoCharactersOperator() async {
+ await resolveTestUnit('''
+class A {
+ void foo() {
+ /*LINT*/this?.foo();
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ void foo() {
+ /*LINT*/foo();
+ }
+}
+''');
+ }
+
+ test_notAThisExpression() async {
+ await resolveTestUnit('''
+void foo() {
+ final /*LINT*/this.id;
+}
+''');
+ await assertNoFix();
+ }
+
+ test_propertyAccess_oneCharacterOperator() async {
+ await resolveTestUnit('''
+class A {
+ int x;
+ void foo() {
+ /*LINT*/this.x = 2;
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ int x;
+ void foo() {
+ /*LINT*/x = 2;
+ }
+}
+''');
+ }
+
+ test_propertyAccess_twoCharactersOperator() async {
+ await resolveTestUnit('''
+class A {
+ int x;
+ void foo() {
+ /*LINT*/this?.x = 2;
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ int x;
+ void foo() {
+ /*LINT*/x = 2;
+ }
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_type_annotation_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_type_annotation_test.dart
new file mode 100644
index 0000000..54deb8b
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_type_annotation_test.dart
@@ -0,0 +1,164 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AvoidAnnotatingWithDynamicTest);
+ defineReflectiveTests(AvoidReturnTypesOnSettersTest);
+ defineReflectiveTests(AvoidTypesOnClosureParametersTest);
+ defineReflectiveTests(TypeInitFormalsTest);
+ });
+}
+
+@reflectiveTest
+class AvoidAnnotatingWithDynamicTest extends RemoveTypeAnnotationTest {
+ @override
+ String get lintCode => LintNames.avoid_annotating_with_dynamic;
+
+ test_insideFunctionTypedFormalParameter() async {
+ await resolveTestUnit('''
+bad(void foo(/*LINT*/dynamic x)) {
+ return null;
+}
+''');
+ await assertHasFix('''
+bad(void foo(/*LINT*/x)) {
+ return null;
+}
+''');
+ }
+
+ test_namedParameter() async {
+ await resolveTestUnit('''
+bad({/*LINT*/dynamic defaultValue}) {
+ return null;
+}
+''');
+ await assertHasFix('''
+bad({/*LINT*/defaultValue}) {
+ return null;
+}
+''');
+ }
+
+ test_normalParameter() async {
+ await resolveTestUnit('''
+bad(/*LINT*/dynamic defaultValue) {
+ return null;
+}
+''');
+ await assertHasFix('''
+bad(/*LINT*/defaultValue) {
+ return null;
+}
+''');
+ }
+
+ test_optionalParameter() async {
+ await resolveTestUnit('''
+bad([/*LINT*/dynamic defaultValue]) {
+ return null;
+}
+''');
+ await assertHasFix('''
+bad([/*LINT*/defaultValue]) {
+ return null;
+}
+''');
+ }
+}
+
+@reflectiveTest
+class AvoidReturnTypesOnSettersTest extends RemoveTypeAnnotationTest {
+ @override
+ String get lintCode => LintNames.avoid_return_types_on_setters;
+
+ test_void() async {
+ await resolveTestUnit('''
+/*LINT*/void set speed2(int ms) {}
+''');
+ await assertHasFix('''
+/*LINT*/set speed2(int ms) {}
+''');
+ }
+}
+
+@reflectiveTest
+class AvoidTypesOnClosureParametersTest extends RemoveTypeAnnotationTest {
+ @override
+ String get lintCode => LintNames.avoid_types_on_closure_parameters;
+
+ test_namedParameter() async {
+ await resolveTestUnit('''
+var x = ({/*LINT*/Future<int> defaultValue}) {
+ return null;
+};
+''');
+ await assertHasFix('''
+var x = ({/*LINT*/defaultValue}) {
+ return null;
+};
+''');
+ }
+
+ test_normalParameter() async {
+ await resolveTestUnit('''
+var x = (/*LINT*/Future<int> defaultValue) {
+ return null;
+};
+''');
+ await assertHasFix('''
+var x = (/*LINT*/defaultValue) {
+ return null;
+};
+''');
+ }
+
+ test_optionalParameter() async {
+ await resolveTestUnit('''
+var x = ([/*LINT*/Future<int> defaultValue]) {
+ return null;
+};
+''');
+ await assertHasFix('''
+var x = ([/*LINT*/defaultValue]) {
+ return null;
+};
+''');
+ }
+}
+
+@reflectiveTest
+class TypeInitFormalsTest extends RemoveTypeAnnotationTest {
+ @override
+ String get lintCode => LintNames.type_init_formals;
+
+ test_void() async {
+ await resolveTestUnit('''
+class C {
+ int f;
+ C(/*LINT*/int this.f);
+}
+''');
+ await assertHasFix('''
+class C {
+ int f;
+ C(/*LINT*/this.f);
+}
+''');
+ }
+}
+
+@reflectiveTest
+abstract class RemoveTypeAnnotationTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.REMOVE_TYPE_ANNOTATION;
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_type_arguments_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_type_arguments_test.dart
new file mode 100644
index 0000000..b27594f
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_type_arguments_test.dart
@@ -0,0 +1,99 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RemoveTypeArgumentsTest);
+ });
+}
+
+@reflectiveTest
+class RemoveTypeArgumentsTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.REMOVE_TYPE_ARGUMENTS;
+
+ test_explicitConst() async {
+ await resolveTestUnit('''
+main() {
+ const C.named<int>();
+}
+class C<E> {
+ const C.named();
+}
+''');
+ await assertHasFix('''
+main() {
+ const C.named();
+}
+class C<E> {
+ const C.named();
+}
+''');
+ }
+
+ test_explicitNew() async {
+ await resolveTestUnit('''
+main() {
+ new C.named<int>();
+}
+class C<E> {
+ C.named();
+}
+''');
+ await assertHasFix('''
+main() {
+ new C.named();
+}
+class C<E> {
+ C.named();
+}
+''');
+ }
+
+ test_implicitConst() async {
+ await resolveTestUnit('''
+main() {
+ const C c = C.named<int>();
+ print(c);
+}
+class C<E> {
+ const C.named();
+}
+''');
+ await assertHasFix('''
+main() {
+ const C c = C.named();
+ print(c);
+}
+class C<E> {
+ const C.named();
+}
+''');
+ }
+
+ test_implicitNew() async {
+ await resolveTestUnit('''
+main() {
+ C.named<int>();
+}
+class C<E> {
+ C.named();
+}
+''');
+ await assertHasFix('''
+main() {
+ C.named();
+}
+class C<E> {
+ C.named();
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_cast_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_cast_test.dart
new file mode 100644
index 0000000..9218c3b
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_unnecessary_cast_test.dart
@@ -0,0 +1,68 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RemoveUnnecessaryCastTest);
+ });
+}
+
+@reflectiveTest
+class RemoveUnnecessaryCastTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.REMOVE_UNNECESSARY_CAST;
+
+ test_assignment() async {
+ await resolveTestUnit('''
+main(Object p) {
+ if (p is String) {
+ String v = ((p as String));
+ print(v);
+ }
+}
+''');
+ await assertHasFix('''
+main(Object p) {
+ if (p is String) {
+ String v = p;
+ print(v);
+ }
+}
+''');
+ }
+
+ test_assignment_all() async {
+ await resolveTestUnit('''
+main(Object p, Object q) {
+ if (p is String) {
+ String v = ((p as String));
+ print(v);
+ }
+ if (q is int) {
+ int v = ((q as int));
+ print(v);
+ }
+}
+''');
+ await assertHasFixAllFix(HintCode.UNNECESSARY_CAST, '''
+main(Object p, Object q) {
+ if (p is String) {
+ String v = p;
+ print(v);
+ }
+ if (q is int) {
+ int v = q;
+ print(v);
+ }
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_catch_clause_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_catch_clause_test.dart
new file mode 100644
index 0000000..8bd4f51
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_catch_clause_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RemoveUnusedCatchClauseTest);
+ });
+}
+
+@reflectiveTest
+class RemoveUnusedCatchClauseTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.REMOVE_UNUSED_CATCH_CLAUSE;
+
+ test_removeUnusedCatchClause() async {
+ await resolveTestUnit('''
+main() {
+ try {
+ throw 42;
+ } on int catch (e) {
+ }
+}
+''');
+ await assertHasFix('''
+main() {
+ try {
+ throw 42;
+ } on int {
+ }
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_catch_stack_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_catch_stack_test.dart
new file mode 100644
index 0000000..da067cd
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_catch_stack_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RemoveUnusedCatchStackTest);
+ });
+}
+
+@reflectiveTest
+class RemoveUnusedCatchStackTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.REMOVE_UNUSED_CATCH_STACK;
+
+ test_removeUnusedCatchStack() async {
+ await resolveTestUnit('''
+main() {
+ try {
+ throw 42;
+ } catch (e, stack) {
+ }
+}
+''');
+ await assertHasFix('''
+main() {
+ try {
+ throw 42;
+ } catch (e) {
+ }
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_unused_import_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_import_test.dart
new file mode 100644
index 0000000..96ee02f
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_unused_import_test.dart
@@ -0,0 +1,127 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RemoveUnusedImportTest);
+ });
+}
+
+@reflectiveTest
+class RemoveUnusedImportTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.REMOVE_UNUSED_IMPORT;
+
+ test_all_diverseImports() async {
+ await resolveTestUnit('''
+import 'dart:math';
+import 'dart:math';
+import 'dart:async';
+main() {
+}
+''');
+ await assertHasFixAllFix(HintCode.UNUSED_IMPORT, '''
+main() {
+}
+''');
+ }
+
+ test_all_diverseImports2() async {
+ await resolveTestUnit('''
+import 'dart:async';
+import 'dart:math' as math;
+import 'dart:async';
+
+var tau = math.pi * 2;
+
+main() {
+}
+''');
+ await assertHasFixAllFix(HintCode.UNUSED_IMPORT, '''
+import 'dart:math' as math;
+
+var tau = math.pi * 2;
+
+main() {
+}
+''');
+ }
+
+ test_all_singleLine() async {
+ await resolveTestUnit('''
+import 'dart:math'; import 'dart:math'; import 'dart:math';
+main() {
+}
+''');
+ await assertHasFixAllFix(HintCode.UNUSED_IMPORT, '''
+main() {
+}
+''');
+ }
+
+ test_anotherImportOnLine() async {
+ await resolveTestUnit('''
+import 'dart:math'; import 'dart:async';
+
+main() {
+ Future f;
+ print(f);
+}
+''');
+ await assertHasFix('''
+import 'dart:async';
+
+main() {
+ Future f;
+ print(f);
+}
+''');
+ }
+
+ test_multipleOfSame_all() async {
+ await resolveTestUnit('''
+import 'dart:math';
+import 'dart:math';
+import 'dart:math';
+main() {
+}
+''');
+ await assertHasFixAllFix(HintCode.UNUSED_IMPORT, '''
+main() {
+}
+''');
+ }
+
+ test_severalLines() async {
+ await resolveTestUnit('''
+import
+ 'dart:math';
+main() {
+}
+''');
+ await assertHasFix('''
+main() {
+}
+''');
+ }
+
+ test_single() async {
+ await resolveTestUnit('''
+import 'dart:math';
+main() {
+}
+''');
+ await assertHasFix('''
+main() {
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/rename_to_camel_case_test.dart b/pkg/analysis_server/test/src/services/correction/fix/rename_to_camel_case_test.dart
new file mode 100644
index 0000000..45f6677
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/rename_to_camel_case_test.dart
@@ -0,0 +1,113 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RenameToCamelCaseTest);
+ });
+}
+
+@reflectiveTest
+class RenameToCamelCaseTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.RENAME_TO_CAMEL_CASE;
+
+ @override
+ String get lintCode => LintNames.non_constant_identifier_names;
+
+ test_localVariable() async {
+ await resolveTestUnit('''
+main() {
+ int /*LINT*/my_integer_variable = 42;
+ int foo;
+ print(my_integer_variable);
+ print(foo);
+}
+''');
+ await assertHasFix('''
+main() {
+ int /*LINT*/myIntegerVariable = 42;
+ int foo;
+ print(myIntegerVariable);
+ print(foo);
+}
+''');
+ }
+
+ test_parameter_closure() async {
+ await resolveTestUnit('''
+main() {
+ [0, 1, 2].forEach((/*LINT*/my_integer_variable) {
+ print(my_integer_variable);
+ });
+}
+''');
+ await assertHasFix('''
+main() {
+ [0, 1, 2].forEach((/*LINT*/myIntegerVariable) {
+ print(myIntegerVariable);
+ });
+}
+''');
+ }
+
+ test_parameter_function() async {
+ await resolveTestUnit('''
+main(int /*LINT*/my_integer_variable) {
+ print(my_integer_variable);
+}
+''');
+ await assertHasFix('''
+main(int /*LINT*/myIntegerVariable) {
+ print(myIntegerVariable);
+}
+''');
+ }
+
+ test_parameter_method() async {
+ await resolveTestUnit('''
+class A {
+ main(int /*LINT*/my_integer_variable) {
+ print(my_integer_variable);
+ }
+}
+''');
+ await assertHasFix('''
+class A {
+ main(int /*LINT*/myIntegerVariable) {
+ print(myIntegerVariable);
+ }
+}
+''');
+ }
+
+ test_parameter_optionalNamed() async {
+ await resolveTestUnit('''
+foo({int /*LINT*/my_integer_variable}) {
+ print(my_integer_variable);
+}
+''');
+ await assertNoFix();
+ }
+
+ test_parameter_optionalPositional() async {
+ await resolveTestUnit('''
+main([int /*LINT*/my_integer_variable]) {
+ print(my_integer_variable);
+}
+''');
+ await assertHasFix('''
+main([int /*LINT*/myIntegerVariable]) {
+ print(myIntegerVariable);
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_boolean_with_bool_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_boolean_with_bool_test.dart
new file mode 100644
index 0000000..29fe96e
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_boolean_with_bool_test.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ReplaceBooleanWithBoolTest);
+ });
+}
+
+@reflectiveTest
+class ReplaceBooleanWithBoolTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.REPLACE_BOOLEAN_WITH_BOOL;
+
+ test_all() async {
+ await resolveTestUnit('''
+main() {
+ boolean v;
+ boolean w;
+}
+''');
+ await assertHasFixAllFix(StaticWarningCode.UNDEFINED_CLASS_BOOLEAN, '''
+main() {
+ bool v;
+ bool w;
+}
+''');
+ }
+
+ test_single() async {
+ await resolveTestUnit('''
+main() {
+ boolean v;
+ print(v);
+}
+''');
+ await assertHasFix('''
+main() {
+ bool v;
+ print(v);
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_final_with_const_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_final_with_const_test.dart
new file mode 100644
index 0000000..77fa5a7
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_final_with_const_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ReplaceFinalWithConstTest);
+ });
+}
+
+@reflectiveTest
+class ReplaceFinalWithConstTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.REPLACE_FINAL_WITH_CONST;
+
+ @override
+ String get lintCode => LintNames.prefer_const_declarations;
+
+ test_method() async {
+ await resolveTestUnit('''
+/*LINT*/final int a = 1;
+''');
+ await assertHasFix('''
+/*LINT*/const int a = 1;
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_return_type_future_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_return_type_future_test.dart
new file mode 100644
index 0000000..244178e
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_return_type_future_test.dart
@@ -0,0 +1,151 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ReplaceReturnTypeFutureTest);
+ });
+}
+
+@reflectiveTest
+class ReplaceReturnTypeFutureTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.REPLACE_RETURN_TYPE_FUTURE;
+
+ test_adjacentNodes_withImport() async {
+ await resolveTestUnit('''
+import 'dart:async';
+var v;int main() async => 0;
+''');
+ await assertHasFix('''
+import 'dart:async';
+var v;Future<int> main() async => 0;
+''', errorFilter: (error) {
+ return error.errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE;
+ });
+ }
+
+ test_adjacentNodes_withoutImport() async {
+ await resolveTestUnit('''
+var v;int main() async => 0;
+''');
+ await assertHasFix('''
+var v;Future<int> main() async => 0;
+''', errorFilter: (error) {
+ return error.errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE;
+ });
+ }
+
+ test_complexTypeName_withImport() async {
+ await resolveTestUnit('''
+import 'dart:async';
+List<int> main() async {
+}
+''');
+ await assertHasFix('''
+import 'dart:async';
+Future<List<int>> main() async {
+}
+''', errorFilter: (error) {
+ return error.errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE;
+ });
+ }
+
+ @failingTest
+ test_complexTypeName_withoutImport() async {
+ await resolveTestUnit('''
+List<int> main() async {
+}
+''');
+ await assertHasFix('''
+import 'dart:async';
+
+Future<List<int>> main() async {
+}
+''', errorFilter: (error) {
+ return error.errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE;
+ });
+ }
+
+ test_importedWithPrefix() async {
+ await resolveTestUnit('''
+import 'dart:async' as al;
+int main() async {
+}
+''');
+ await assertHasFix('''
+import 'dart:async' as al;
+al.Future<int> main() async {
+}
+''', errorFilter: (error) {
+ return error.errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE;
+ });
+ }
+
+ test_simpleTypeName_withImport() async {
+ await resolveTestUnit('''
+import 'dart:async';
+int main() async => 0;
+''');
+ await assertHasFix('''
+import 'dart:async';
+Future<int> main() async => 0;
+''', errorFilter: (error) {
+ return error.errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE;
+ });
+ }
+
+ @failingTest
+ test_simpleTypeName_withoutImport() async {
+ await resolveTestUnit('''
+int main() async => 0;
+''');
+ await assertHasFix('''
+import 'dart:async';
+
+Future<int> main() async => 0;
+''', errorFilter: (error) {
+ return error.errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE;
+ });
+ }
+
+ test_withLibraryDirective_withImport() async {
+ await resolveTestUnit('''
+library main;
+import 'dart:async';
+int main() async {
+}
+''');
+ await assertHasFix('''
+library main;
+import 'dart:async';
+Future<int> main() async {
+}
+''', errorFilter: (error) {
+ return error.errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE;
+ });
+ }
+
+ test_withLibraryDirective_withoutImport() async {
+ await resolveTestUnit('''
+library main;
+int main() async {
+}
+''');
+ await assertHasFix('''
+library main;
+Future<int> main() async {
+}
+''', errorFilter: (error) {
+ return error.errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE;
+ });
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_var_with_dynamic_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_var_with_dynamic_test.dart
new file mode 100644
index 0000000..f0463c8
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_var_with_dynamic_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer/src/dart/error/syntactic_errors.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ReplaceVarWithDynamicTest);
+ });
+}
+
+@reflectiveTest
+class ReplaceVarWithDynamicTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.REPLACE_VAR_WITH_DYNAMIC;
+
+ test_simple() async {
+ await resolveTestUnit('''
+class A {
+ Map<String, var> m;
+}
+''');
+ await assertHasFix('''
+class A {
+ Map<String, dynamic> m;
+}
+''', errorFilter: (error) {
+ return error.errorCode == ParserErrorCode.VAR_AS_TYPE_NAME;
+ });
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_brackets_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_brackets_test.dart
new file mode 100644
index 0000000..93cae94
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_brackets_test.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ReplaceWithBracketsTest);
+ });
+}
+
+@reflectiveTest
+class ReplaceWithBracketsTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.REPLACE_WITH_BRACKETS;
+
+ @override
+ String get lintCode => LintNames.empty_statements;
+
+ test_outOfBlock_otherLine() async {
+ await resolveTestUnit('''
+void foo() {
+ while(true)
+ /*LINT*/;
+ print('hi');
+}
+''');
+ await assertHasFix('''
+void foo() {
+ while(true) {}
+ print('hi');
+}
+''');
+ }
+
+ test_outOfBlock_sameLine() async {
+ await resolveTestUnit('''
+void foo() {
+ while(true)/*LINT*/;
+ print('hi');
+}
+''');
+ await assertHasFix('''
+void foo() {
+ while(true) {}
+ print('hi');
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_conditional_assignment_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_conditional_assignment_test.dart
new file mode 100644
index 0000000..e5baaec
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_conditional_assignment_test.dart
@@ -0,0 +1,112 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ReplaceWithConditionalAssignmentTest);
+ });
+}
+
+@reflectiveTest
+class ReplaceWithConditionalAssignmentTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.REPLACE_WITH_CONDITIONAL_ASSIGNMENT;
+
+ @override
+ String get lintCode => LintNames.prefer_conditional_assignment;
+
+ test_withCodeBeforeAndAfter() async {
+ await resolveTestUnit('''
+class Person {
+ String _fullName;
+ void foo() {
+ print('hi');
+ /*LINT*/if (_fullName == null) {
+ _fullName = getFullUserName(this);
+ }
+ print('hi');
+ }
+}
+''');
+ await assertHasFix('''
+class Person {
+ String _fullName;
+ void foo() {
+ print('hi');
+ /*LINT*/_fullName ??= getFullUserName(this);
+ print('hi');
+ }
+}
+''');
+ }
+
+ test_withOneBlock() async {
+ await resolveTestUnit('''
+class Person {
+ String _fullName;
+ void foo() {
+ /*LINT*/if (_fullName == null) {
+ _fullName = getFullUserName(this);
+ }
+ }
+}
+''');
+ await assertHasFix('''
+class Person {
+ String _fullName;
+ void foo() {
+ /*LINT*/_fullName ??= getFullUserName(this);
+ }
+}
+''');
+ }
+
+ test_withoutBlock() async {
+ await resolveTestUnit('''
+class Person {
+ String _fullName;
+ void foo() {
+ /*LINT*/if (_fullName == null)
+ _fullName = getFullUserName(this);
+ }
+}
+''');
+ await assertHasFix('''
+class Person {
+ String _fullName;
+ void foo() {
+ /*LINT*/_fullName ??= getFullUserName(this);
+ }
+}
+''');
+ }
+
+ test_withTwoBlock() async {
+ await resolveTestUnit('''
+class Person {
+ String _fullName;
+ void foo() {
+ /*LINT*/if (_fullName == null) {{
+ _fullName = getFullUserName(this);
+ }}
+ }
+}
+''');
+ await assertHasFix('''
+class Person {
+ String _fullName;
+ void foo() {
+ /*LINT*/_fullName ??= getFullUserName(this);
+ }
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_identifier_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_identifier_test.dart
new file mode 100644
index 0000000..6dfc38c
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_identifier_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ReplaceWithIdentifierTest);
+ });
+}
+
+@reflectiveTest
+class ReplaceWithIdentifierTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.REPLACE_WITH_IDENTIFIER;
+
+ @override
+ String get lintCode => LintNames.avoid_types_on_closure_parameters;
+
+ test_functionTypedFormalParameter() async {
+ await resolveTestUnit('''
+var functionWithFunction = (/*LINT*/int f(int x)) => f(0);
+''');
+ await assertHasFix('''
+var functionWithFunction = (/*LINT*/f) => f(0);
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_literal_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_literal_test.dart
new file mode 100644
index 0000000..7ec1088
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_literal_test.dart
@@ -0,0 +1,113 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ReplaceWithLiteralTest);
+ });
+}
+
+@reflectiveTest
+class ReplaceWithLiteralTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.REPLACE_WITH_LITERAL;
+
+ @override
+ String get lintCode => LintNames.prefer_collection_literals;
+
+ test_linkedHashMap_withCommentsInGeneric() async {
+ await resolveTestUnit('''
+import 'dart:collection';
+
+final a = /*LINT*/new LinkedHashMap<int,/*comment*/int>();
+''');
+ await assertHasFix('''
+import 'dart:collection';
+
+final a = /*LINT*/<int,/*comment*/int>{};
+''');
+ }
+
+ test_linkedHashMap_withDynamicGenerics() async {
+ await resolveTestUnit('''
+import 'dart:collection';
+
+final a = /*LINT*/new LinkedHashMap<dynamic,dynamic>();
+''');
+ await assertHasFix('''
+import 'dart:collection';
+
+final a = /*LINT*/<dynamic,dynamic>{};
+''');
+ }
+
+ test_linkedHashMap_withGeneric() async {
+ await resolveTestUnit('''
+import 'dart:collection';
+
+final a = /*LINT*/new LinkedHashMap<int,int>();
+''');
+ await assertHasFix('''
+import 'dart:collection';
+
+final a = /*LINT*/<int,int>{};
+''');
+ }
+
+ test_linkedHashMap_withoutGeneric() async {
+ await resolveTestUnit('''
+import 'dart:collection';
+
+final a = /*LINT*/new LinkedHashMap();
+''');
+ await assertHasFix('''
+import 'dart:collection';
+
+final a = /*LINT*/{};
+''');
+ }
+
+ test_list_withGeneric() async {
+ await resolveTestUnit('''
+final a = /*LINT*/new List<int>();
+''');
+ await assertHasFix('''
+final a = /*LINT*/<int>[];
+''');
+ }
+
+ test_list_withoutGeneric() async {
+ await resolveTestUnit('''
+final a = /*LINT*/new List();
+''');
+ await assertHasFix('''
+final a = /*LINT*/[];
+''');
+ }
+
+ test_map_withGeneric() async {
+ await resolveTestUnit('''
+final a = /*LINT*/new Map<int,int>();
+''');
+ await assertHasFix('''
+final a = /*LINT*/<int,int>{};
+''');
+ }
+
+ test_map_withoutGeneric() async {
+ await resolveTestUnit('''
+final a = /*LINT*/new Map();
+''');
+ await assertHasFix('''
+final a = /*LINT*/{};
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_null_aware_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_null_aware_test.dart
new file mode 100644
index 0000000..f758081
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_null_aware_test.dart
@@ -0,0 +1,60 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ReplaceWithNullAwareTest);
+ });
+}
+
+@reflectiveTest
+class ReplaceWithNullAwareTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.REPLACE_WITH_NULL_AWARE;
+
+ test_chain() async {
+ await resolveTestUnit('''
+main(x) {
+ x?.a.b.c;
+}
+''');
+ await assertHasFix('''
+main(x) {
+ x?.a?.b?.c;
+}
+''');
+ }
+
+ test_methodInvocation() async {
+ await resolveTestUnit('''
+main(x) {
+ x?.a.b();
+}
+''');
+ await assertHasFix('''
+main(x) {
+ x?.a?.b();
+}
+''');
+ }
+
+ test_propertyAccess() async {
+ await resolveTestUnit('''
+main(x) {
+ x?.a().b;
+}
+''');
+ await assertHasFix('''
+main(x) {
+ x?.a()?.b;
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_tear_off_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_tear_off_test.dart
new file mode 100644
index 0000000..ccc757a
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_tear_off_test.dart
@@ -0,0 +1,97 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ReplaceWithTearOffTest);
+ });
+}
+
+@reflectiveTest
+class ReplaceWithTearOffTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.REPLACE_WITH_TEAR_OFF;
+
+ @override
+ String get lintCode => LintNames.unnecessary_lambdas;
+
+ test_function_oneParameter() async {
+ await resolveTestUnit('''
+final x = /*LINT*/(name) {
+ print(name);
+};
+''');
+ await assertHasFix('''
+final x = /*LINT*/print;
+''');
+ }
+
+ test_function_zeroParameters() async {
+ await resolveTestUnit('''
+void foo(){}
+Function finalVar() {
+ return /*LINT*/() {
+ foo();
+ };
+}
+''');
+ await assertHasFix('''
+void foo(){}
+Function finalVar() {
+ return /*LINT*/foo;
+}
+''');
+ }
+
+ test_lambda_asArgument() async {
+ await resolveTestUnit('''
+void foo() {
+ bool isPair(int a) => a % 2 == 0;
+ final finalList = <int>[];
+ finalList.where(/*LINT*/(number) =>
+ isPair(number));
+}
+''');
+ await assertHasFix('''
+void foo() {
+ bool isPair(int a) => a % 2 == 0;
+ final finalList = <int>[];
+ finalList.where(/*LINT*/isPair);
+}
+''');
+ }
+
+ test_method_oneParameter() async {
+ await resolveTestUnit('''
+var a = /*LINT*/(x) => finalList.remove(x);
+''');
+ await assertHasFix('''
+var a = /*LINT*/finalList.remove;
+''');
+ }
+
+ test_method_zeroParameter() async {
+ await resolveTestUnit('''
+final Object a;
+Function finalVar() {
+ return /*LINT*/() {
+ return a.toString();
+ };
+}
+''');
+ await assertHasFix('''
+final Object a;
+Function finalVar() {
+ return /*LINT*/a.toString;
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
new file mode 100644
index 0000000..de6f043
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
@@ -0,0 +1,180 @@
+// Copyright (c) 2018, 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:test_reflective_loader/test_reflective_loader.dart';
+
+import 'add_async_test.dart' as add_async;
+import 'add_explicit_cast_test.dart' as add_explicit_cast;
+import 'add_field_formal_parameters_test.dart' as add_field_formal_parameters;
+import 'add_missing_parameter_named_test.dart' as add_missing_parameter_named;
+import 'add_missing_parameter_positional_test.dart'
+ as add_missing_parameter_positional;
+import 'add_missing_parameter_required_test.dart'
+ as add_missing_parameter_required;
+import 'add_missing_required_argument_test.dart'
+ as add_missing_required_argument;
+import 'add_ne_null_test.dart' as add_ne_null;
+import 'add_override_test.dart' as add_override;
+import 'add_required_test.dart' as add_required;
+import 'add_static_test.dart' as add_static;
+import 'add_super_constructor_invocation_test.dart'
+ as add_super_constructor_invocation;
+import 'change_to_nearest_precise_value_test.dart'
+ as change_to_nearest_precise_value;
+import 'change_to_static_access_test.dart' as change_to_static_access;
+import 'change_to_test.dart' as change_to;
+import 'change_type_annotation_test.dart' as change_type_annotation;
+import 'convert_flutter_child_test.dart' as convert_flutter_child;
+import 'convert_flutter_children_test.dart' as convert_flutter_children;
+import 'convert_to_named_arguments_test.dart' as convert_to_named_arguments;
+import 'create_class_test.dart' as create_class;
+import 'create_constructor_for_final_fields_test.dart'
+ as create_constructor_for_final_field;
+import 'create_constructor_super_test.dart' as create_constructor_super;
+import 'create_constructor_test.dart' as create_constructor;
+import 'create_field_test.dart' as create_field;
+import 'create_file_test.dart' as create_file;
+import 'create_function_test.dart' as create_function;
+import 'create_getter_test.dart' as create_getter;
+import 'create_local_variable_test.dart' as create_local_variable;
+import 'create_method_test.dart' as create_method;
+import 'create_missing_overrides_test.dart' as create_missing_overrides;
+import 'create_mixin_test.dart' as create_mixin;
+import 'create_no_such_method_test.dart' as create_no_such_method;
+import 'extend_class_for_mixin_test.dart' as extend_class_for_mixin;
+import 'fix_test.dart' as fix;
+import 'import_async_test.dart' as import_async;
+import 'import_library_prefix_test.dart' as import_library_prefix;
+import 'import_library_project_test.dart' as import_library_project;
+import 'import_library_sdk_test.dart' as import_library_sdk;
+import 'import_library_show_test.dart' as import_library_show;
+import 'insert_semicolon_test.dart' as insert_semicolon;
+import 'make_class_abstract_test.dart' as make_class_abstract;
+import 'make_field_not_final_test.dart' as make_field_not_final;
+import 'make_final_test.dart' as make_final;
+import 'move_type_arguments_to_class_test.dart' as move_type_arguments_to_class;
+import 'remove_await_test.dart' as remove_await;
+import 'remove_dead_code_test.dart' as remove_dead_code;
+import 'remove_empty_catch_test.dart' as remove_empty_catch;
+import 'remove_empty_constructor_body_test.dart'
+ as remove_empty_constructor_body;
+import 'remove_empty_else_test.dart' as remove_empty_else;
+import 'remove_empty_statement_test.dart' as remove_empty_statement;
+import 'remove_initializer_test.dart' as remove_initializer;
+import 'remove_interpolation_braces_test.dart' as remove_interpolation_braces;
+import 'remove_method_declaration_test.dart' as remove_method_declaration;
+import 'remove_parameters_in_getter_declaration_test.dart'
+ as remove_parameters_in_getter_declaration;
+import 'remove_parentheses_in_getter_invocation_test.dart'
+ as remove_parentheses_in_getter_invocation;
+import 'remove_this_expression_test.dart' as remove_this_expression;
+import 'remove_type_annotation_test.dart' as remove_type_annotation;
+import 'remove_type_arguments_test.dart' as remove_type_arguments;
+import 'remove_unnecessary_cast_test.dart' as remove_unnecessary_cast;
+import 'remove_unused_catch_clause_test.dart' as remove_unused_catch_clause;
+import 'remove_unused_catch_stack_test.dart' as remove_unused_catch_stack;
+import 'remove_unused_import_test.dart' as remove_unused_import;
+import 'rename_to_camel_case_test.dart' as rename_to_camel_case;
+import 'replace_boolean_with_bool_test.dart' as replace_boolean_with_bool;
+import 'replace_final_with_const_test.dart' as replace_final_with_const;
+import 'replace_return_type_future_test.dart' as replace_return_type_future;
+import 'replace_var_with_dynamic_test.dart' as replace_var_with_dynamic;
+import 'replace_with_brackets_test.dart' as replace_with_brackets;
+import 'replace_with_conditional_assignment_test.dart'
+ as replace_with_conditional_assignment;
+import 'replace_with_identifier_test.dart' as replace_with_identifier;
+import 'replace_with_literal_test.dart' as replace_with_literal;
+import 'replace_with_null_aware_test.dart' as replace_with_null_aware;
+import 'replace_with_tear_off_test.dart' as replace_with_tear_off;
+import 'update_sdk_constraints_test.dart' as update_sdk_constraints;
+import 'use_const_test.dart' as use_const;
+import 'use_effective_integer_division_test.dart'
+ as use_effective_integer_division;
+import 'use_eq_eq_null_test.dart' as use_eq_eq_null;
+import 'use_is_not_empty_test.dart' as use_is_not_empty;
+import 'use_not_eq_null_test.dart' as use_not_eq_null;
+
+main() {
+ defineReflectiveSuite(() {
+ add_async.main();
+ add_explicit_cast.main();
+ add_field_formal_parameters.main();
+ add_missing_parameter_named.main();
+ add_missing_parameter_positional.main();
+ add_missing_parameter_required.main();
+ add_missing_required_argument.main();
+ add_ne_null.main();
+ add_override.main();
+ add_required.main();
+ add_static.main();
+ add_super_constructor_invocation.main();
+ change_to.main();
+ change_to_nearest_precise_value.main();
+ change_to_static_access.main();
+ change_type_annotation.main();
+ convert_flutter_child.main();
+ convert_flutter_children.main();
+ convert_to_named_arguments.main();
+ create_class.main();
+ create_constructor_for_final_field.main();
+ create_constructor_super.main();
+ create_constructor.main();
+ create_field.main();
+ create_file.main();
+ create_function.main();
+ create_getter.main();
+ create_local_variable.main();
+ create_method.main();
+ create_missing_overrides.main();
+ create_mixin.main();
+ create_no_such_method.main();
+ extend_class_for_mixin.main();
+ fix.main();
+ import_async.main();
+ import_library_prefix.main();
+ import_library_project.main();
+ import_library_sdk.main();
+ import_library_show.main();
+ insert_semicolon.main();
+ make_class_abstract.main();
+ make_field_not_final.main();
+ make_final.main();
+ move_type_arguments_to_class.main();
+ remove_await.main();
+ remove_dead_code.main();
+ remove_empty_catch.main();
+ remove_empty_constructor_body.main();
+ remove_empty_else.main();
+ remove_empty_statement.main();
+ remove_initializer.main();
+ remove_interpolation_braces.main();
+ remove_method_declaration.main();
+ remove_parameters_in_getter_declaration.main();
+ remove_parentheses_in_getter_invocation.main();
+ remove_this_expression.main();
+ remove_type_annotation.main();
+ remove_type_arguments.main();
+ remove_unnecessary_cast.main();
+ remove_unused_catch_clause.main();
+ remove_unused_catch_stack.main();
+ remove_unused_import.main();
+ rename_to_camel_case.main();
+ replace_boolean_with_bool.main();
+ replace_final_with_const.main();
+ replace_return_type_future.main();
+ replace_var_with_dynamic.main();
+ replace_with_brackets.main();
+ replace_with_conditional_assignment.main();
+ replace_with_literal.main();
+ replace_with_identifier.main();
+ replace_with_null_aware.main();
+ replace_with_tear_off.main();
+ update_sdk_constraints.main();
+ use_const.main();
+ use_effective_integer_division.main();
+ use_eq_eq_null.main();
+ use_is_not_empty.main();
+ use_not_eq_null.main();
+ }, name: 'fix');
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/update_sdk_constraints_test.dart b/pkg/analysis_server/test/src/services/correction/fix/update_sdk_constraints_test.dart
new file mode 100644
index 0000000..4b957b3
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/update_sdk_constraints_test.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(UpdateSdkConstraintsTest);
+ });
+}
+
+@reflectiveTest
+class UpdateSdkConstraintsTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.UPDATE_SDK_CONSTRAINTS;
+
+ test_any() async {
+ await testUpdate(from: 'any', to: '^2.1.0');
+ }
+
+ test_caret() async {
+ await testUpdate(from: '^2.0.0', to: '^2.1.0');
+ }
+
+ test_compound() async {
+ await testUpdate(from: "'>=2.0.0 <3.0.0'", to: "'>=2.1.0 <3.0.0'");
+ }
+
+ test_gt() async {
+ await testUpdate(from: "'>2.0.0'", to: "'>=2.1.0'");
+ }
+
+ test_gte() async {
+ await testUpdate(from: "'>=2.0.0'", to: "'>=2.1.0'");
+ }
+
+ testUpdate({String from, String to}) async {
+ updateTestPubspecFile('''
+environment:
+ sdk: $from
+''');
+ await resolveTestUnit('''
+Future<int> zero() async => 0;
+''');
+ await assertHasFix('''
+environment:
+ sdk: $to
+''', target: testPubspecPath);
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/use_const_test.dart b/pkg/analysis_server/test/src/services/correction/fix/use_const_test.dart
new file mode 100644
index 0000000..9ac1952
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/use_const_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(UseConstTest);
+ });
+}
+
+@reflectiveTest
+class UseConstTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.USE_CONST;
+
+ test_explicitNew() async {
+ await resolveTestUnit('''
+class A {
+ const A();
+}
+const a = new A();
+''');
+ await assertHasFix('''
+class A {
+ const A();
+}
+const a = const A();
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/use_effective_integer_division_test.dart b/pkg/analysis_server/test/src/services/correction/fix/use_effective_integer_division_test.dart
new file mode 100644
index 0000000..770f505
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/use_effective_integer_division_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(UseEffectiveIntegerDivisionTest);
+ });
+}
+
+@reflectiveTest
+class UseEffectiveIntegerDivisionTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.USE_EFFECTIVE_INTEGER_DIVISION;
+
+ test_normalDivision() async {
+ await resolveTestUnit('''
+main() {
+ var a = 5;
+ var b = 2;
+ print((a / b).toInt());
+}
+''');
+ await assertHasFix('''
+main() {
+ var a = 5;
+ var b = 2;
+ print(a ~/ b);
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/use_eq_eq_null_test.dart b/pkg/analysis_server/test/src/services/correction/fix/use_eq_eq_null_test.dart
new file mode 100644
index 0000000..de6b873
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/use_eq_eq_null_test.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(UseEqEqNullTest);
+ });
+}
+
+@reflectiveTest
+class UseEqEqNullTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.USE_EQ_EQ_NULL;
+
+ test_isNull() async {
+ await resolveTestUnit('''
+main(p) {
+ p is Null;
+}
+''');
+ await assertHasFix('''
+main(p) {
+ p == null;
+}
+''');
+ }
+
+ test_isNull_all() async {
+ await resolveTestUnit('''
+main(p, q) {
+ p is Null;
+ q is Null;
+}
+''');
+ await assertHasFixAllFix(HintCode.TYPE_CHECK_IS_NULL, '''
+main(p, q) {
+ p == null;
+ q == null;
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/use_is_not_empty_test.dart b/pkg/analysis_server/test/src/services/correction/fix/use_is_not_empty_test.dart
new file mode 100644
index 0000000..ab2da21
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/use_is_not_empty_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(UseIsNotEmptyTest);
+ });
+}
+
+@reflectiveTest
+class UseIsNotEmptyTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.USE_IS_NOT_EMPTY;
+
+ @override
+ String get lintCode => LintNames.prefer_is_not_empty;
+
+ test_notIsEmpty() async {
+ await resolveTestUnit('''
+f(c) {
+ if (/*LINT*/!c.isEmpty) {}
+}
+''');
+ await assertHasFix('''
+f(c) {
+ if (/*LINT*/c.isNotEmpty) {}
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/use_not_eq_null_test.dart b/pkg/analysis_server/test/src/services/correction/fix/use_not_eq_null_test.dart
new file mode 100644
index 0000000..3fdd82a
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/use_not_eq_null_test.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2018, 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/src/services/correction/fix.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(UseNotEqNullTest);
+ });
+}
+
+@reflectiveTest
+class UseNotEqNullTest extends FixProcessorTest {
+ @override
+ FixKind get kind => DartFixKind.USE_NOT_EQ_NULL;
+
+ test_isNotNull() async {
+ await resolveTestUnit('''
+main(p) {
+ p is! Null;
+}
+''');
+ await assertHasFix('''
+main(p) {
+ p != null;
+}
+''');
+ }
+
+ test_isNotNull_all() async {
+ await resolveTestUnit('''
+main(p, q) {
+ p is! Null;
+ q is! Null;
+}
+''');
+ await assertHasFixAllFix(HintCode.TYPE_CHECK_IS_NOT_NULL, '''
+main(p, q) {
+ p != null;
+ q != null;
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/test_all.dart b/pkg/analysis_server/test/src/services/correction/test_all.dart
new file mode 100644
index 0000000..7c6c49d
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/test_all.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2018, 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:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist/test_all.dart' as assist_all;
+import 'fix/test_all.dart' as fix_all;
+
+main() {
+ defineReflectiveSuite(() {
+ assist_all.main();
+ fix_all.main();
+ }, name: 'correction');
+}
diff --git a/pkg/analysis_server/test/src/services/test_all.dart b/pkg/analysis_server/test/src/services/test_all.dart
new file mode 100644
index 0000000..46f575f
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/test_all.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2018, 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:test_reflective_loader/test_reflective_loader.dart';
+
+import 'correction/test_all.dart' as correction_all;
+
+main() {
+ defineReflectiveSuite(() {
+ correction_all.main();
+ }, name: 'services');
+}
diff --git a/pkg/analysis_server/test/src/test_all.dart b/pkg/analysis_server/test/src/test_all.dart
index c25b65a..6a07ced 100644
--- a/pkg/analysis_server/test/src/test_all.dart
+++ b/pkg/analysis_server/test/src/test_all.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -6,8 +6,10 @@
import 'computer/test_all.dart' as computer_all;
import 'domain_abstract_test.dart' as domain_abstract_test;
+import 'domains/test_all.dart' as domains_all;
import 'flutter/test_all.dart' as flutter_all;
import 'plugin/test_all.dart' as plugin_all;
+import 'services/test_all.dart' as services_all;
import 'utilities/test_all.dart' as utilities_all;
import 'watch_manager_test.dart' as watch_manager_test;
@@ -18,8 +20,10 @@
defineReflectiveSuite(() {
computer_all.main();
domain_abstract_test.main();
+ domains_all.main();
flutter_all.main();
plugin_all.main();
+ services_all.main();
utilities_all.main();
watch_manager_test.main();
}, name: 'src');
diff --git a/pkg/analysis_server/test/src/utilities/flutter_util.dart b/pkg/analysis_server/test/src/utilities/flutter_util.dart
index 6e689e5..286b2c4 100644
--- a/pkg/analysis_server/test/src/utilities/flutter_util.dart
+++ b/pkg/analysis_server/test/src/utilities/flutter_util.dart
@@ -27,6 +27,7 @@
''');
newFile('$flutterPkgLibPath/widgets.dart', r'''
+export 'src/widgets/async.dart';
export 'src/widgets/basic.dart';
export 'src/widgets/container.dart';
export 'src/widgets/framework.dart';
@@ -159,6 +160,25 @@
}
void createSrcWidgets() {
+ newFile('$flutterPkgLibPath/src/widgets/async.dart', r'''
+import 'framework.dart';
+
+class AsyncSnapshot<T> {}
+
+typedef AsyncWidgetBuilder<T> = Widget Function(BuildContext context, AsyncSnapshot<T> snapshot);
+
+class StreamBuilder<T> {
+ const StreamBuilder({
+ Key key,
+ this.initialData,
+ Stream<T> stream,
+ @required this.builder
+ });
+ final T initialData;
+ final AsyncWidgetBuilder<T> builder;
+}
+''');
+
newFile('$flutterPkgLibPath/src/widgets/basic.dart', r'''
import 'package:flutter/rendering.dart';
diff --git a/pkg/analysis_server/test/src/watch_manager_test.dart b/pkg/analysis_server/test/src/watch_manager_test.dart
index 248c5b0..a5a4a93 100644
--- a/pkg/analysis_server/test/src/watch_manager_test.dart
+++ b/pkg/analysis_server/test/src/watch_manager_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2015, 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.
@@ -70,7 +70,7 @@
}
@reflectiveTest
-class WatchManagerTest extends Object with ResourceProviderMixin {
+class WatchManagerTest with ResourceProviderMixin {
WatchListener listener;
WatchManager<Token> manager;
@@ -194,7 +194,7 @@
}
@reflectiveTest
-class WatchNodeTest extends Object with ResourceProviderMixin {
+class WatchNodeTest with ResourceProviderMixin {
void test_creation_folder() {
Folder folder = getFolder('/a/b');
WatchNode node = new WatchNode(folder);
diff --git a/pkg/analysis_server/test/stress/completion/completion_runner.dart b/pkg/analysis_server/test/stress/completion/completion_runner.dart
index 3605038..41a69b8 100644
--- a/pkg/analysis_server/test/stress/completion/completion_runner.dart
+++ b/pkg/analysis_server/test/stress/completion/completion_runner.dart
@@ -103,8 +103,8 @@
}
fileCount++;
output.write('.');
- ResolveResult result =
- await context.currentSession.getResolvedAst(path);
+ ResolvedUnitResult result =
+ await context.currentSession.getResolvedUnit(path);
String content = result.content;
LineInfo lineInfo = result.lineInfo;
List<SimpleIdentifier> identifiers = _identifiersIn(result.unit);
@@ -117,7 +117,7 @@
content.substring(identifier.end);
resourceProvider.setOverlay(path,
content: modifiedContent, modificationStamp: stamp++);
- result = await context.currentSession.getResolvedAst(path);
+ result = await context.currentSession.getResolvedUnit(path);
}
timer.start();
diff --git a/pkg/analysis_server/test/tool/lsp_spec/dart_test.dart b/pkg/analysis_server/test/tool/lsp_spec/dart_test.dart
index 068063c..bcffd7a 100644
--- a/pkg/analysis_server/test/tool/lsp_spec/dart_test.dart
+++ b/pkg/analysis_server/test/tool/lsp_spec/dart_test.dart
@@ -4,45 +4,34 @@
import 'package:test/test.dart';
-import '../../../tool/lsp_spec/codegen_dart.dart';
+import '../../../tool/lsp_spec/typescript_parser.dart' as ast;
main() {
- group('mapType', () {
+ group('dartType mapping', () {
test('handles basic types', () {
- expect(mapType(['string']), equals('String'));
- expect(mapType(['boolean']), equals('bool'));
- expect(mapType(['any']), equals('dynamic'));
- expect(mapType(['object']), equals('dynamic'));
- expect(mapType(['int']), equals('int'));
- expect(mapType(['num']), equals('num'));
+ expect(_simple('string').dartType, equals('String'));
+ expect(_simple('boolean').dartType, equals('bool'));
+ expect(_simple('any').dartType, equals('dynamic'));
+ expect(_simple('object').dartType, equals('dynamic'));
+ expect(_simple('int').dartType, equals('int'));
+ expect(_simple('num').dartType, equals('num'));
});
test('handles union types', () {
- expect(mapType(['string', 'int']), equals('Either2<String, int>'));
- expect(mapType(['string | int']), equals('Either2<String, int>'));
+ expect(_union(['string', 'int']).dartTypeWithTypeArgs,
+ equals('Either2<String, int>'));
});
test('handles arrays', () {
- expect(mapType(['string[]']), equals('List<String>'));
- expect(mapType(['Array<string>']), equals('List<String>'));
- });
-
- test('handles types with args', () {
- expect(mapType(['Class<string[]>']), equals('Class<List<String>>'));
- expect(mapType(['Array<string | num>']),
- equals('List<Either2<String, num>>'));
- });
-
- test('handles complex nested types', () {
- expect(
- mapType([
- 'Array<string>',
- 'any[]',
- 'Response<A>',
- 'Request<Array<string | num>>'
- ]),
- equals(
- 'Either4<List<String>, List<dynamic>, Response<A>, Request<List<Either2<String, num>>>>'));
+ expect(_array('string').dartTypeWithTypeArgs, equals('List<String>'));
});
});
}
+
+ast.Type _simple(String name) =>
+ new ast.Type(new ast.Token(ast.TokenType.IDENTIFIER, name), []);
+
+ast.ArrayType _array(String name) => new ast.ArrayType(_simple(name));
+
+ast.UnionType _union(List<String> names) =>
+ new ast.UnionType(names.map(_simple).toList());
diff --git a/pkg/analysis_server/test/tool/lsp_spec/json_test.dart b/pkg/analysis_server/test/tool/lsp_spec/json_test.dart
index e12b850..b352d18 100644
--- a/pkg/analysis_server/test/tool/lsp_spec/json_test.dart
+++ b/pkg/analysis_server/test/tool/lsp_spec/json_test.dart
@@ -18,23 +18,21 @@
});
test('returns correct output for union types', () {
- final message =
- new RequestMessage(new Either2.t1(1), "test", null, "test");
+ final message = new RequestMessage(
+ new Either2<num, String>.t1(1), Method.shutdown, null, "test");
String output = json.encode(message.toJson());
- expect(output, equals('{"id":1,"method":"test","jsonrpc":"test"}'));
+ expect(output, equals('{"id":1,"method":"shutdown","jsonrpc":"test"}'));
});
test('returns correct output for union types containing interface types',
() {
- final params = new Either2<String, WorkspaceClientCapabilities>.t2(
- new WorkspaceClientCapabilities(
- true,
- null,
- null,
- null,
- ));
+ final params = new Either2<String, TextDocumentItem>.t2(
+ new TextDocumentItem('!uri', '!language', 1, '!text'));
String output = json.encode(params);
- expect(output, equals('{"applyEdit":true}'));
+ expect(
+ output,
+ equals(
+ '{"uri":"!uri","languageId":"!language","version":1,"text":"!text"}'));
});
test('returns correct output for types with lists', () {
@@ -45,7 +43,7 @@
final codeAction = new Diagnostic(
range,
DiagnosticSeverity.Error,
- new Either2.t2('test_err'),
+ 'test_err',
'/tmp/source.dart',
'err!!',
[new DiagnosticRelatedInformation(location, 'message')],
@@ -95,51 +93,81 @@
group('fromJson', () {
test('parses JSON for types with unions (left side)', () {
- final input = '{"id":1,"method":"test","jsonrpc":"test"}';
- final message = new RequestMessage.fromJson(jsonDecode(input));
+ final input = '{"id":1,"method":"shutdown","jsonrpc":"test"}';
+ final message = RequestMessage.fromJson(jsonDecode(input));
expect(message.id, equals(new Either2<num, String>.t1(1)));
expect(message.id.valueEquals(1), isTrue);
expect(message.jsonrpc, "test");
- expect(message.method, "test");
+ expect(message.method, Method.shutdown);
});
test('parses JSON for types with unions (right side)', () {
- final input = '{"id":"one","method":"test","jsonrpc":"test"}';
- final message = new RequestMessage.fromJson(jsonDecode(input));
+ final input = '{"id":"one","method":"shutdown","jsonrpc":"test"}';
+ final message = RequestMessage.fromJson(jsonDecode(input));
expect(message.id, equals(new Either2<num, String>.t2("one")));
expect(message.id.valueEquals("one"), isTrue);
expect(message.jsonrpc, "test");
- expect(message.method, "test");
+ expect(message.method, Method.shutdown);
+ });
+
+ test('parses JSON with nulls for unions that allow null', () {
+ final input = '{"id":null,"jsonrpc":"test"}';
+ final message = ResponseMessage.fromJson(jsonDecode(input));
+ expect(message.id, isNull);
+ });
+
+ test('parses JSON with nulls for unions that allow null', () {
+ final input = '{"method":"test","jsonrpc":"test"}';
+ final message = NotificationMessage.fromJson(jsonDecode(input));
+ expect(message.params, isNull);
});
});
- test('objects with lists and enums can round-trip through to json and back',
- () {
- final obj = new ClientCapabilities(
- new WorkspaceClientCapabilities(
- true,
- false,
- [ResourceOperationKind.Create, ResourceOperationKind.Delete],
- FailureHandlingKind.Undo),
- new TextDocumentClientCapabilities(true, false, true, false),
- null);
+ test('objects with lists can round-trip through to json and back', () {
+ final obj = new InitializeParams(1, '!root', null, null,
+ new ClientCapabilities(null, null, null), '!trace', [
+ new WorkspaceFolder('!uri1', '!name1'),
+ new WorkspaceFolder('!uri2', '!name2'),
+ ]);
final String json = jsonEncode(obj);
- final restoredObj = new ClientCapabilities.fromJson(jsonDecode(json));
+ final restoredObj = InitializeParams.fromJson(jsonDecode(json));
- expect(restoredObj.workspace.applyEdit, equals(obj.workspace.applyEdit));
- expect(restoredObj.workspace.documentChanges,
- equals(obj.workspace.documentChanges));
- expect(restoredObj.workspace.resourceOperations,
- equals(obj.workspace.resourceOperations));
- expect(restoredObj.workspace.failureHandling,
- equals(obj.workspace.failureHandling));
- expect(restoredObj.textDocument.didSave, equals(obj.textDocument.didSave));
- expect(restoredObj.textDocument.dynamicRegistration,
- equals(obj.textDocument.dynamicRegistration));
expect(
- restoredObj.textDocument.willSave, equals(obj.textDocument.willSave));
- expect(restoredObj.textDocument.willSaveWaitUntil,
- equals(obj.textDocument.willSaveWaitUntil));
- expect(restoredObj.experimental, equals(obj.experimental));
+ restoredObj.workspaceFolders, hasLength(obj.workspaceFolders.length));
+ for (var i = 0; i < obj.workspaceFolders.length; i++) {
+ expect(restoredObj.workspaceFolders[i].name,
+ equals(obj.workspaceFolders[i].name));
+ expect(restoredObj.workspaceFolders[i].uri,
+ equals(obj.workspaceFolders[i].uri));
+ }
+ });
+
+ test('objects with enums can round-trip through to json and back', () {
+ final obj = new FoldingRange(1, 2, 3, 4, FoldingRangeKind.Comment);
+ final String json = jsonEncode(obj);
+ final restoredObj = FoldingRange.fromJson(jsonDecode(json));
+
+ expect(restoredObj.startLine, equals(obj.startLine));
+ expect(restoredObj.startCharacter, equals(obj.startCharacter));
+ expect(restoredObj.endLine, equals(obj.endLine));
+ expect(restoredObj.endCharacter, equals(obj.endCharacter));
+ expect(restoredObj.kind, equals(obj.kind));
+ });
+
+ test('objects with maps can round-trip through to json and back', () {
+ final start = new Position(1, 1);
+ final end = new Position(2, 2);
+ final range = new Range(start, end);
+ final obj = new WorkspaceEdit(<String, List<TextEdit>>{
+ 'fileA': [new TextEdit(range, 'text A')],
+ 'fileB': [new TextEdit(range, 'text B')]
+ }, null);
+ final String json = jsonEncode(obj);
+ final restoredObj = WorkspaceEdit.fromJson(jsonDecode(json));
+
+ expect(restoredObj.documentChanges, equals(obj.documentChanges));
+ expect(restoredObj.changes, equals(obj.changes));
+ expect(restoredObj.changes.keys, equals(obj.changes.keys));
+ expect(restoredObj.changes.values, equals(obj.changes.values));
});
}
diff --git a/pkg/analysis_server/test/tool/lsp_spec/matchers.dart b/pkg/analysis_server/test/tool/lsp_spec/matchers.dart
new file mode 100644
index 0000000..72ee321
--- /dev/null
+++ b/pkg/analysis_server/test/tool/lsp_spec/matchers.dart
@@ -0,0 +1,82 @@
+// Copyright (c) 2018, 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/lsp_protocol/protocol_generated.dart';
+import 'package:matcher/matcher.dart';
+
+import '../../../tool/lsp_spec/typescript_parser.dart';
+
+Matcher isSimpleType(String name) => new SimpleTypeMatcher(name);
+
+class SimpleTypeMatcher extends Matcher {
+ final String _expectedName;
+ const SimpleTypeMatcher(this._expectedName);
+
+ bool matches(item, Map matchState) {
+ return item is Type && item.name == _expectedName;
+ }
+
+ Description describe(Description description) =>
+ description.add('a type with the name $_expectedName');
+
+ Description describeMismatch(
+ item, Description mismatchDescription, Map matchState, bool verbose) {
+ if (item is Type) {
+ return mismatchDescription
+ .add('has the name ')
+ .addDescriptionOf(item.name);
+ } else {
+ return mismatchDescription.add('is not a Type');
+ }
+ }
+}
+
+Matcher isArrayOf(Matcher matcher) =>
+ new ArrayTypeMatcher(wrapMatcher(matcher));
+
+class ArrayTypeMatcher extends Matcher {
+ final Matcher _elementTypeMatcher;
+ const ArrayTypeMatcher(this._elementTypeMatcher);
+
+ bool matches(item, Map matchState) {
+ return item is ArrayType &&
+ _elementTypeMatcher.matches(item.elementType, matchState);
+ }
+
+ Description describe(Description description) =>
+ description.add('an array of ').addDescriptionOf(_elementTypeMatcher);
+
+ Description describeMismatch(
+ item, Description mismatchDescription, Map matchState, bool verbose) {
+ if (item is ArrayType) {
+ return _elementTypeMatcher.describeMismatch(
+ item, mismatchDescription, matchState, verbose);
+ } else {
+ return mismatchDescription.add('is not an ArrayType');
+ }
+ }
+}
+
+Matcher isMapOf(Matcher indexMatcher, Matcher valueMatcher) =>
+ new MapTypeMatcher(wrapMatcher(indexMatcher), wrapMatcher(valueMatcher));
+
+class MapTypeMatcher extends Matcher {
+ final Matcher _indexMatcher, _valueMatcher;
+ const MapTypeMatcher(this._indexMatcher, this._valueMatcher);
+
+ bool matches(item, Map matchState) {
+ return item is MapType &&
+ _indexMatcher.matches(item.indexType, matchState) &&
+ _valueMatcher.matches(item.valueType, matchState);
+ }
+
+ Description describe(Description description) => description
+ .add('a MapType where index is ')
+ .addDescriptionOf(_indexMatcher)
+ .add(' and value is ')
+ .addDescriptionOf(_valueMatcher);
+}
+
+Matcher isResponseError(ErrorCodes code) => const TypeMatcher<ResponseError>()
+ .having((e) => e.code, 'code', equals(code));
diff --git a/pkg/analysis_server/test/tool/lsp_spec/test_all.dart b/pkg/analysis_server/test/tool/lsp_spec/test_all.dart
new file mode 100644
index 0000000..1edfb80
--- /dev/null
+++ b/pkg/analysis_server/test/tool/lsp_spec/test_all.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2018, 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:test_reflective_loader/test_reflective_loader.dart';
+
+import 'dart_test.dart' as dart_test;
+import 'json_test.dart' as json_test;
+import 'markdown_test.dart' as markdown_test;
+import 'typescript_test.dart' as typescript_test;
+
+main() {
+ defineReflectiveSuite(() {
+ dart_test.main();
+ json_test.main();
+ markdown_test.main();
+ typescript_test.main();
+ }, name: 'lsp-tool');
+}
diff --git a/pkg/analysis_server/test/tool/lsp_spec/typescript_test.dart b/pkg/analysis_server/test/tool/lsp_spec/typescript_test.dart
index 1fad598..d03b5fb 100644
--- a/pkg/analysis_server/test/tool/lsp_spec/typescript_test.dart
+++ b/pkg/analysis_server/test/tool/lsp_spec/typescript_test.dart
@@ -4,7 +4,8 @@
import 'package:test/test.dart';
-import '../../../tool/lsp_spec/typescript.dart';
+import '../../../tool/lsp_spec/typescript_parser.dart';
+import 'matchers.dart';
main() {
group('typescript parser', () {
@@ -20,22 +21,57 @@
options?: OptionKind[];
}
''';
- final List<ApiItem> output = extractTypes(input);
+ final List<AstNode> output = parseFile(input);
expect(output, hasLength(1));
expect(output[0], const TypeMatcher<Interface>());
final Interface interface = output[0];
expect(interface.name, equals('SomeOptions'));
- expect(interface.comment, equals('Some options.'));
+ expect(interface.commentText, equals('Some options.'));
expect(interface.baseTypes, hasLength(0));
expect(interface.members, hasLength(1));
expect(interface.members[0], const TypeMatcher<Field>());
final Field field = interface.members[0];
expect(field.name, equals('options'));
- expect(field.comment, equals('''Options used by something.'''));
+ expect(field.commentText, equals('''Options used by something.'''));
expect(field.allowsNull, isFalse);
expect(field.allowsUndefined, isTrue);
- expect(field.types, hasLength(1));
- expect(field.types[0], equals('OptionKind[]'));
+ expect(field.type, isArrayOf(isSimpleType('OptionKind')));
+ });
+
+ test('parses an interface with a field with an inline/unnamed type', () {
+ final String input = '''
+export interface Capabilities {
+ textDoc?: {
+ deprecated?: bool;
+ };
+}
+ ''';
+ final List<AstNode> output = parseFile(input);
+ // Length is two because we'll fabricate the type of textDoc.
+ expect(output, hasLength(2));
+
+ // Check there was a full fabricarted interface for this type.
+ expect(output[0], const TypeMatcher<Interface>());
+ Interface interface = output[0];
+ expect(interface.name, equals('CapabilitiesTextDoc'));
+ expect(interface.members, hasLength(1));
+ expect(interface.members[0], const TypeMatcher<Field>());
+ Field field = interface.members[0];
+ expect(field.name, equals('deprecated'));
+ expect(field.allowsNull, isFalse);
+ expect(field.allowsUndefined, isTrue);
+ expect(field.type, isSimpleType('bool'));
+ expect(field.allowsUndefined, isTrue);
+
+ expect(output[1], const TypeMatcher<Interface>());
+ interface = output[1];
+ expect(interface.name, equals('Capabilities'));
+ expect(interface.members, hasLength(1));
+ expect(interface.members[0], const TypeMatcher<Field>());
+ field = interface.members[0];
+ expect(field.name, equals('textDoc'));
+ expect(field.allowsNull, isFalse);
+ expect(field.type, isSimpleType('CapabilitiesTextDoc'));
});
test('parses an interface with multiple fields', () {
@@ -51,7 +87,7 @@
options1: any;
}
''';
- final List<ApiItem> output = extractTypes(input);
+ final List<AstNode> output = parseFile(input);
expect(output, hasLength(1));
expect(output[0], const TypeMatcher<Interface>());
final Interface interface = output[0];
@@ -60,7 +96,7 @@
expect(interface.members[i], const TypeMatcher<Field>());
final Field field = interface.members[i];
expect(field.name, equals('options$i'));
- expect(field.comment, equals('''Options$i used by something.'''));
+ expect(field.commentText, equals('''Options$i used by something.'''));
});
});
@@ -70,7 +106,7 @@
data?: D;
}
''';
- final List<ApiItem> output = extractTypes(input);
+ final List<AstNode> output = parseFile(input);
expect(output, hasLength(1));
expect(output[0], const TypeMatcher<Interface>());
final Interface interface = output[0];
@@ -78,21 +114,21 @@
final Field field = interface.members.first;
expect(field, const TypeMatcher<Field>());
expect(field.name, equals('data'));
- expect(field.allowsUndefined, true);
- expect(field.allowsNull, false);
- expect(field.types, equals(['D']));
+ expect(field.allowsUndefined, isTrue);
+ expect(field.allowsNull, isFalse);
+ expect(field.type, isSimpleType('D'));
});
test('parses an interface with Arrays in Array<T> format', () {
final String input = '''
-export interface RequestMessage {
+export interface MyMessage {
/**
* The method's params.
*/
params?: Array<any> | object;
}
''';
- final List<ApiItem> output = extractTypes(input);
+ final List<AstNode> output = parseFile(input);
expect(output, hasLength(1));
expect(output[0], const TypeMatcher<Interface>());
final Interface interface = output[0];
@@ -100,10 +136,32 @@
final Field field = interface.members.first;
expect(field, const TypeMatcher<Field>());
expect(field.name, equals('params'));
- expect(field.comment, equals('''The method's params.'''));
- expect(field.allowsUndefined, true);
- expect(field.allowsNull, false);
- expect(field.types, equals(['Array<any>', 'object']));
+ expect(field.commentText, equals('''The method's params.'''));
+ expect(field.allowsUndefined, isTrue);
+ expect(field.allowsNull, isFalse);
+ expect(field.type, const TypeMatcher<UnionType>());
+ UnionType union = field.type;
+ expect(union.types, hasLength(2));
+ expect(union.types[0], isArrayOf(isSimpleType('any')));
+ expect(union.types[1], isSimpleType('object'));
+ });
+
+ test('parses an interface with a map into a MapType', () {
+ final String input = '''
+export interface WorkspaceEdit {
+ changes: { [uri: string]: TextEdit[]; };
+}
+ ''';
+ final List<AstNode> output = parseFile(input);
+ expect(output, hasLength(1));
+ expect(output[0], const TypeMatcher<Interface>());
+ final Interface interface = output[0];
+ expect(interface.members, hasLength(1));
+ final Field field = interface.members.first;
+ expect(field, const TypeMatcher<Field>());
+ expect(field.name, equals('changes'));
+ expect(field.type,
+ isMapOf(isSimpleType('string'), isArrayOf(isSimpleType('TextEdit'))));
});
test('flags nullable undefined values', () {
@@ -115,7 +173,7 @@
canBeUndefined?: string;
}
''';
- final List<ApiItem> output = extractTypes(input);
+ final List<AstNode> output = parseFile(input);
final Interface interface = output[0];
expect(interface.members, hasLength(4));
interface.members.forEach((m) => expect(m, const TypeMatcher<Field>()));
@@ -155,9 +213,9 @@
a: a;
}
''';
- final List<ApiItem> output = extractTypes(input);
+ final List<AstNode> output = parseFile(input);
final Interface interface = output[0];
- expect(interface.comment, equals('''
+ expect(interface.commentText, equals('''
Describes the what this class in lots of words that wrap onto multiple lines that will need re-wrapping to format nicely when converted into Dart.
Blank lines should remain in-tact, as should:
@@ -176,12 +234,12 @@
final String input = '''
export type DocumentSelector = DocumentFilter[];
''';
- final List<ApiItem> output = extractTypes(input);
+ final List<AstNode> output = parseFile(input);
expect(output, hasLength(1));
expect(output[0], const TypeMatcher<TypeAlias>());
final TypeAlias typeAlias = output[0];
expect(typeAlias.name, equals('DocumentSelector'));
- expect(typeAlias.baseType, equals('DocumentFilter[]'));
+ expect(typeAlias.baseType, isArrayOf(isSimpleType('DocumentFilter')));
});
test('parses a namespace of constants', () {
@@ -203,7 +261,7 @@
export const Rename: ResourceOperationKind = 'rename';
}
''';
- final List<ApiItem> output = extractTypes(input);
+ final List<AstNode> output = parseFile(input);
expect(output, hasLength(1));
expect(output[0], const TypeMatcher<Namespace>());
final Namespace namespace = output[0];
@@ -213,16 +271,16 @@
delete = namespace.members[1],
rename = namespace.members[2];
expect(create.name, equals('Create'));
- expect(create.type, equals('ResourceOperationKind'));
- expect(
- create.comment, equals('Supports creating new files and folders.'));
+ expect(create.type, isSimpleType('ResourceOperationKind'));
+ expect(create.commentText,
+ equals('Supports creating new files and folders.'));
expect(rename.name, equals('Rename'));
- expect(rename.type, equals('ResourceOperationKind'));
- expect(rename.comment,
+ expect(rename.type, isSimpleType('ResourceOperationKind'));
+ expect(rename.commentText,
equals('Supports renaming existing files and folders.'));
expect(delete.name, equals('Delete'));
- expect(delete.type, equals('ResourceOperationKind'));
- expect(delete.comment,
+ expect(delete.type, isSimpleType('ResourceOperationKind'));
+ expect(delete.commentText,
equals('Supports deleting existing files and folders.'));
});
});
diff --git a/pkg/analysis_server/tool/instrumentation/log/log.dart b/pkg/analysis_server/tool/instrumentation/log/log.dart
index 011581a..10dfd90 100644
--- a/pkg/analysis_server/tool/instrumentation/log/log.dart
+++ b/pkg/analysis_server/tool/instrumentation/log/log.dart
@@ -870,7 +870,7 @@
/**
* A log entry representing a communication between the server and a plugin.
*/
-abstract class PluginEntryMixin {
+mixin PluginEntryMixin {
/**
* The components describing the plugin associated with this entry.
*/
diff --git a/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart b/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
index 79b2b63..c95ca9c 100644
--- a/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
+++ b/pkg/analysis_server/tool/lsp_spec/codegen_dart.dart
@@ -3,16 +3,30 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:dart_style/dart_style.dart';
-import 'package:meta/meta.dart';
import 'typescript.dart';
+import 'typescript_parser.dart';
final formatter = new DartFormatter();
Map<String, Interface> _interfaces = {};
+// TODO(dantup): Rename namespaces -> enums since they're always that now.
Map<String, Namespace> _namespaces = {};
Map<String, TypeAlias> _typeAliases = {};
-String generateDartForTypes(List<ApiItem> types) {
+/// Whether our enum class allows any value (eg. should always return true
+/// from canParse() for the correct type). This is to allow us to have some
+/// type safety for these values but without restricting which values are allowed.
+/// This is to support things like custom error codes and also future changes
+/// in the spec (it's important the server doesn't crash on deserialising
+/// newer values).
+bool enumClassAllowsAnyValue(String name) {
+ // TODO(dantup): This should return true by default, and allow opt-out for
+ // those things we know are not supported. This behaviour matches the old
+ // code in order to simplify diffs while migrating.
+ return name == 'ErrorCodes' || name == 'CodeActionKind';
+}
+
+String generateDartForTypes(List<AstNode> types) {
// Keep maps of items we may need to look up quickly later.
types
.whereType<TypeAlias>()
@@ -29,8 +43,15 @@
return formattedCode.trim() + '\n'; // Ensure a single trailing newline.
}
-List<String> _extractTypesFromUnion(String type) {
- return type.split('|').map((t) => t.trim()).toList();
+TypeBase resolveTypeAlias(TypeBase type, {resolveEnumClasses: false}) {
+ if (type is Type && _typeAliases.containsKey(type.name)) {
+ final alias = _typeAliases[type.name];
+ // Only follow the type if we're not an enum, or we wanted to follow enums.
+ if (!_namespaces.containsKey(alias.name) || resolveEnumClasses) {
+ return alias.baseType;
+ }
+ }
+ return type;
}
String _formatCode(String code) {
@@ -52,45 +73,28 @@
return interface.members
.whereType<Field>()
.followedBy(interface.baseTypes
- .map((name) => _getAllFields(_interfaces[name]))
+ // This cast is safe because base types are always real types.
+ .map((type) => _getAllFields(_interfaces[(type as Type).name]))
.expand((ts) => ts))
.toList();
}
-String _getListType(String type) {
- return type.substring('List<'.length, type.length - 1);
-}
-
/// Returns a copy of the list sorted by name.
-List<ApiItem> _getSorted(List<ApiItem> items) {
+List<AstNode> _getSorted(List<AstNode> items) {
final sortedList = items.toList();
sortedList.sort((item1, item2) => item1.name.compareTo(item2.name));
return sortedList;
}
-List<String> _getUnionTypes(String type) {
- return type
- .substring('EitherX<'.length, type.length - 1)
- .split(',')
- .map((s) => s.trim())
- .toList();
-}
-
-bool _isList(String type) {
- return type.startsWith('List<') && type.endsWith('>');
-}
-
-bool _isLiteral(String type) {
+bool _isSimpleType(TypeBase type) {
const literals = ['num', 'String', 'bool'];
- return literals.contains(type);
+ return type is Type && literals.contains(type.dartType);
}
-bool _isSpecType(String type) {
- return _interfaces.containsKey(type) || _namespaces.containsKey(type);
-}
-
-bool _isUnion(String type) {
- return type.startsWith('Either') && type.endsWith('>');
+bool _isSpecType(TypeBase type) {
+ return type is Type &&
+ (_interfaces.containsKey(type.name) ||
+ (_namespaces.containsKey(type.name)));
}
/// Maps reserved words and identifiers that cause issues in field names.
@@ -104,57 +108,6 @@
return map[identifier] ?? identifier;
}
-/// Maps a TypeScript type on to a Dart type, including following TypeAliases.
-@visibleForTesting
-String mapType(List<String> types) {
- const mapping = <String, String>{
- 'boolean': 'bool',
- 'string': 'String',
- 'number': 'num',
- 'any': 'dynamic',
- 'object': 'dynamic',
- // Special cases that are hard to parse or anonymous types.
- '{ [uri: string]: TextEdit[]; }': 'Map<String, List<TextEdit>>',
- '{ language: string; value: string }': 'MarkedStringWithLanguage'
- };
- if (types.length > 4) {
- throw 'Unions of more than 4 types are not supported.';
- }
- if (types.length >= 2) {
- final typeArgs = types.map((t) => mapType([t])).join(', ');
- return 'Either${types.length}<$typeArgs>';
- }
-
- final type = types.first;
- if (type.endsWith('[]')) {
- return 'List<${mapType([type.substring(0, type.length - 2)])}>';
- } else if (type.startsWith('Array<') && type.endsWith('>')) {
- return 'List<${mapType([type.substring(6, type.length - 1)])}>';
- } else if (type.contains('<')) {
- // For types with type args, we need to map the type and each type arg.
- final declaredType = _stripTypeArgs(type);
- final typeArgs = type
- .substring(declaredType.length + 1, type.length - 1)
- .split(',')
- .map((t) => t.trim());
- return '${mapType([
- declaredType
- ])}<${typeArgs.map((t) => mapType([t])).join(', ')}>';
- } else if (type.contains('|')) {
- // It's possible we ended up with nested unions that the parsing.
- // TODO(dantup): This is now partly done during parsing and partly done
- // here. Maybe consider removing from typescript.dart and just carrying a
- // String through so the logic is all in one place in this function?
- return mapType(_extractTypesFromUnion(type));
- } else if (_typeAliases.containsKey(type)) {
- return mapType([_typeAliases[type].baseType]);
- } else if (mapping.containsKey(type)) {
- return mapType([mapping[type]]);
- } else {
- return type;
- }
-}
-
String _rewriteCommentReference(String comment) {
final commentReferencePattern = new RegExp(r'\[([\w ]+)\]\(#(\w+)\)');
return comment.replaceAllMapped(commentReferencePattern, (m) {
@@ -168,10 +121,6 @@
});
}
-String _stripTypeArgs(String typeName) => typeName.contains('<')
- ? typeName.substring(0, typeName.indexOf('<'))
- : typeName;
-
Iterable<String> _wrapLines(List<String> lines, int maxLength) sync* {
lines = lines.map((l) => l.trimRight()).toList();
for (var line in lines) {
@@ -205,8 +154,7 @@
_getAllFields(interface).where((f) => !f.allowsUndefined);
for (var field in requiredFields) {
buffer.write(" && obj.containsKey('${field.name}') && ");
- _writeTypeCheckCondition(
- buffer, "obj['${field.name}']", mapType(field.types));
+ _writeTypeCheckCondition(buffer, "obj['${field.name}']", field.type);
}
buffer
..writeln(';')
@@ -216,7 +164,7 @@
void _writeConst(IndentableStringBuffer buffer, Const cons) {
_writeDocCommentsAndAnnotations(buffer, cons);
- buffer.writeIndentedln('static const ${cons.name} = ${cons.value};');
+ buffer.writeIndentedln('static const ${cons.name} = ${cons.valueAsLiteral};');
}
void _writeConstructor(IndentableStringBuffer buffer, Interface interface) {
@@ -225,7 +173,7 @@
return;
}
buffer
- ..writeIndented('${_stripTypeArgs(interface.name)}(')
+ ..writeIndented('${interface.name}(')
..write(allFields.map((field) => 'this.${field.name}').join(', '))
..write(')');
final fieldsWithValidation =
@@ -252,51 +200,65 @@
}
void _writeDocCommentsAndAnnotations(
- IndentableStringBuffer buffer, ApiItem item) {
- var comment = item.comment?.trim();
- if (comment == null || comment.length == 0) {
- return;
+ IndentableStringBuffer buffer, AstNode node) {
+ var comment = node.commentText?.trim();
+ if (comment != null && comment.isNotEmpty) {
+ comment = _rewriteCommentReference(comment);
+ Iterable<String> lines = comment.split('\n');
+ // Wrap at 80 - 4 ('/// ') - indent characters.
+ lines = _wrapLines(lines, (80 - 4 - buffer.totalIndent).clamp(0, 80));
+ lines.forEach((l) => buffer.writeIndentedln('/// $l'.trim()));
}
- comment = _rewriteCommentReference(comment);
- Iterable<String> lines = comment.split('\n');
- // Wrap at 80 - 4 ('/// ') - indent characters.
- lines = _wrapLines(lines, (80 - 4 - buffer.totalIndent).clamp(0, 80));
- lines.forEach((l) => buffer.writeIndentedln('/// $l'.trim()));
- if (item.isDeprecated) {
+ if (node.isDeprecated) {
buffer.writeIndentedln('@core.deprecated');
}
}
void _writeEnumClass(IndentableStringBuffer buffer, Namespace namespace) {
_writeDocCommentsAndAnnotations(buffer, namespace);
+ final consts = namespace.members.cast<Const>().toList();
+ final allowsAnyValue = enumClassAllowsAnyValue(namespace.name);
+ final constructorName = allowsAnyValue ? '' : '._';
+ final typeOfValues =
+ resolveTypeAlias(consts.first.type, resolveEnumClasses: true);
+
buffer
..writeln('class ${namespace.name} {')
..indent()
- ..writeIndentedln('const ${namespace.name}._(this._value);')
+ ..writeIndentedln('const ${namespace.name}$constructorName(this._value);')
..writeIndentedln('const ${namespace.name}.fromJson(this._value);')
..writeln()
- ..writeIndentedln('final Object _value;')
+ ..writeIndentedln('final ${typeOfValues.dartTypeWithTypeArgs} _value;')
..writeln()
..writeIndentedln('static bool canParse(Object obj) {')
- ..indent()
- ..writeIndentedln('switch (obj) {')
..indent();
- namespace.members.whereType<Const>().forEach((cons) {
- buffer..writeIndentedln('case ${cons.value}:');
- });
+ if (allowsAnyValue) {
+ buffer.writeIndentedln('return ');
+ _writeTypeCheckCondition(buffer, 'obj', consts.first.type);
+ buffer.writeln(';');
+ } else {
+ buffer
+ ..writeIndentedln('switch (obj) {')
+ ..indent();
+ consts.forEach((cons) {
+ buffer..writeIndentedln('case ${cons.valueAsLiteral}:');
+ });
+ buffer
+ ..indent()
+ ..writeIndentedln('return true;')
+ ..outdent()
+ ..outdent()
+ ..writeIndentedln('}')
+ ..writeIndentedln('return false;');
+ }
buffer
- ..indent()
- ..writeIndentedln('return true;')
- ..outdent()
- ..writeIndentedln('}')
- ..writeIndentedln('return false;')
..outdent()
..writeIndentedln('}');
namespace.members.whereType<Const>().forEach((cons) {
_writeDocCommentsAndAnnotations(buffer, cons);
buffer
..writeIndentedln(
- 'static const ${_makeValidIdentifier(cons.name)} = const ${namespace.name}._(${cons.value});');
+ 'static const ${_makeValidIdentifier(cons.name)} = const ${namespace.name}$constructorName(${cons.valueAsLiteral});');
});
buffer
..writeln()
@@ -313,58 +275,107 @@
..writeln();
}
+void _writeEquals(IndentableStringBuffer buffer, Interface interface) {
+ buffer
+ ..writeIndentedln('@override')
+ ..writeIndentedln('bool operator ==(other) {')
+ ..indent()
+ ..writeIndentedln('if (other is ${interface.name}) {')
+ ..indent()
+ ..writeIndented('return ');
+ for (var field in _getAllFields(interface)) {
+ final type = field.type;
+ if (type is ArrayType) {
+ final elementType = type.elementType;
+ final elementDartType = elementType.dartTypeWithTypeArgs;
+ buffer.write(
+ 'listEqual(${field.name}, other.${field.name}, ($elementDartType a, $elementDartType b) => a == b) && ');
+ } else if (type is MapType) {
+ final valueType = type.valueType;
+ final valueDartType = valueType.dartTypeWithTypeArgs;
+ buffer.write(
+ 'mapEqual(${field.name}, other.${field.name}, ($valueDartType a, $valueDartType b) => a == b) && ');
+ } else {
+ buffer.write('${field.name} == other.${field.name} && ');
+ }
+ }
+ buffer
+ ..writeln('true;')
+ ..outdent()
+ ..writeIndentedln('}')
+ ..writeIndentedln('return false;')
+ ..outdent()
+ ..writeIndentedln('}');
+}
+
void _writeField(IndentableStringBuffer buffer, Field field) {
_writeDocCommentsAndAnnotations(buffer, field);
buffer
..writeIndented('final ')
- ..write(mapType(field.types))
+ ..write(field.type.dartTypeWithTypeArgs)
..writeln(' ${field.name};');
}
void _writeFromJsonCode(
- IndentableStringBuffer buffer, List<String> types, String valueCode) {
- final type = mapType(types);
- if (_isLiteral(type)) {
+ IndentableStringBuffer buffer, TypeBase type, String valueCode,
+ {bool allowsNull}) {
+ type = resolveTypeAlias(type);
+
+ if (_isSimpleType(type)) {
buffer.write("$valueCode");
} else if (_isSpecType(type)) {
// Our own types have fromJson() constructors we can call.
- buffer.write("$valueCode != null ? new $type.fromJson($valueCode) : null");
- } else if (_isList(type)) {
- // Lists need to be mapped so we can recursively call (they may need fromJson).
+ buffer.write(
+ "$valueCode != null ? ${type.dartType}.fromJson${type.typeArgsString}($valueCode) : null");
+ } else if (type is ArrayType) {
+ // Lists need to be map()'d so we can recursively call writeFromJsonCode
+ // as they may need fromJson on each element.
buffer.write("$valueCode?.map((item) => ");
- final listType = _getListType(type);
- _writeFromJsonCode(buffer, [listType], 'item');
- buffer.write(')?.cast<$listType>()?.toList()');
- } else if (_isUnion(type)) {
- _writeFromJsonCodeForUnion(buffer, types, valueCode);
+ _writeFromJsonCode(buffer, type.elementType, 'item',
+ allowsNull: allowsNull);
+ buffer
+ .write(')?.cast<${type.elementType.dartTypeWithTypeArgs}>()?.toList()');
+ } else if (type is MapType) {
+ // Maps need to be map()'d so we can recursively call writeFromJsonCode as
+ // they may need fromJson on each key or value.
+ buffer.write('$valueCode?.map((key, value) => new MapEntry(');
+ _writeFromJsonCode(buffer, type.indexType, 'key', allowsNull: allowsNull);
+ buffer.write(', ');
+ _writeFromJsonCode(buffer, type.valueType, 'value', allowsNull: allowsNull);
+ buffer.write(
+ '))?.cast<${type.indexType.dartTypeWithTypeArgs}, ${type.valueType.dartTypeWithTypeArgs}>()');
+ } else if (type is UnionType) {
+ _writeFromJsonCodeForUnion(buffer, type, valueCode, allowsNull: allowsNull);
} else {
buffer.write("$valueCode");
}
}
void _writeFromJsonCodeForUnion(
- IndentableStringBuffer buffer, List<String> types, String valueCode) {
- final unionTypeName = mapType(types);
+ IndentableStringBuffer buffer, UnionType union, String valueCode,
+ {bool allowsNull}) {
// Write a check against each type, eg.:
// x is y ? new Either.tx(x) : (...)
var hasIncompleteCondition = false;
var unclosedParens = 0;
- for (var i = 0; i < types.length; i++) {
- final dartType = mapType([types[i]]);
+ for (var i = 0; i < union.types.length; i++) {
+ final type = union.types[i];
+ final isDynamic = type.dartType == 'dynamic';
// Dynamic matches all type checks, so only emit it if required.
- if (dartType != 'dynamic') {
- _writeTypeCheckCondition(buffer, valueCode, dartType);
+ if (!isDynamic) {
+ _writeTypeCheckCondition(buffer, valueCode, type);
buffer.write(' ? ');
}
// The code to construct a value with this "side" of the union.
- buffer.write('new $unionTypeName.t${i + 1}(');
- _writeFromJsonCode(buffer, [dartType], valueCode); // Call recursively!
+ buffer.write('new ${union.dartTypeWithTypeArgs}.t${i + 1}(');
+ _writeFromJsonCode(buffer, type, valueCode,
+ allowsNull: allowsNull); // Call recursively!
buffer.write(')');
// If we output the type condition at the top, prepare for the next condition.
- if (dartType != 'dynamic') {
+ if (!isDynamic) {
buffer.write(' : (');
hasIncompleteCondition = true;
unclosedParens++;
@@ -375,8 +386,12 @@
// Fill the final parens with a throw because if we fell through all of the
// cases then the value we had didn't match any of the types in the union.
if (hasIncompleteCondition) {
+ if (allowsNull) {
+ buffer.write('$valueCode == null ? null : (');
+ unclosedParens++;
+ }
buffer.write(
- "throw '''\${$valueCode} was not one of (${types.join(', ')})'''");
+ "throw '''\${$valueCode} was not one of (${union.types.map((t) => t.dartTypeWithTypeArgs).join(', ')})'''");
}
buffer.write(')' * unclosedParens);
}
@@ -384,31 +399,48 @@
void _writeFromJsonConstructor(
IndentableStringBuffer buffer, Interface interface) {
final allFields = _getAllFields(interface);
- if (allFields.isEmpty) {
- return;
- }
buffer
- ..writeIndentedln(
- 'factory ${_stripTypeArgs(interface.name)}.fromJson(Map<String, dynamic> json) {')
+ ..writeIndentedln('static ${interface.nameWithTypeArgs} '
+ 'fromJson${interface.typeArgsString}(Map<String, dynamic> json) {')
..indent();
for (final field in allFields) {
buffer.writeIndented('final ${field.name} = ');
- _writeFromJsonCode(buffer, field.types, "json['${field.name}']");
+ _writeFromJsonCode(buffer, field.type, "json['${field.name}']",
+ allowsNull: field.allowsNull || field.allowsUndefined);
buffer.writeln(';');
}
buffer
- ..writeIndented('return new ${interface.name}(')
+ ..writeIndented('return new ${interface.nameWithTypeArgs}(')
..write(allFields.map((field) => '${field.name}').join(', '))
..writeln(');')
..outdent()
..writeIndented('}');
}
+void _writeHashCode(IndentableStringBuffer buffer, Interface interface) {
+ buffer
+ ..writeIndentedln('@override')
+ ..writeIndentedln('int get hashCode {')
+ ..indent()
+ ..writeIndented('int hash = 0;');
+ for (var field in _getAllFields(interface)) {
+ buffer
+ .write('hash = JenkinsSmiHash.combine(hash, ${field.name}.hashCode);');
+ }
+ buffer
+ ..writeln('return JenkinsSmiHash.finish(hash);')
+ ..outdent()
+ ..writeIndentedln('}');
+}
+
void _writeInterface(IndentableStringBuffer buffer, Interface interface) {
_writeDocCommentsAndAnnotations(buffer, interface);
- buffer.writeIndented('class ${interface.name} ');
- var allBaseTypes = interface.baseTypes.followedBy(['ToJsonable']);
+ buffer.writeIndented('class ${interface.nameWithTypeArgs} ');
+ final allBaseTypes =
+ interface.baseTypes.map((t) => t.dartTypeWithTypeArgs).toList();
+ allBaseTypes.addAll(getSpecialBaseTypes(interface));
+ allBaseTypes.add('ToJsonable');
if (allBaseTypes.isNotEmpty) {
buffer.writeIndented('implements ${allBaseTypes.join(', ')} ');
}
@@ -428,6 +460,9 @@
buffer.writeln();
_writeToJsonMethod(buffer, interface);
_writeCanParseMethod(buffer, interface);
+ _writeEquals(buffer, interface);
+ _writeHashCode(buffer, interface);
+ _writeToString(buffer, interface);
buffer
..outdent()
..writeIndentedln('}')
@@ -440,14 +475,10 @@
// undefined and never explicitly null), we'll only add the value if set.
if (field.allowsUndefined) {
buffer
- ..writeIndentedlnIf(
- field.isDeprecated, '// ignore: deprecated_member_use')
..writeIndentedln('if (${field.name} != null) {')
..indent();
}
- buffer
- ..writeIndentedlnIf(field.isDeprecated, '// ignore: deprecated_member_use')
- ..writeIndented('''$mapName['${field.name}'] = ${field.name}''');
+ buffer..writeIndented('''$mapName['${field.name}'] = ${field.name}''');
if (!field.allowsUndefined && !field.allowsNull) {
buffer.write(''' ?? (throw '${field.name} is required but was not set')''');
}
@@ -473,29 +504,6 @@
_getSorted(members).forEach((m) => _writeMember(buffer, m));
}
-void _writeNamespace(IndentableStringBuffer buffer, Namespace namespace) {
- // Namespaces are just groups of constants. For some uses we can write these
- // as enum classes for extra type safety, but not for all - for example
- // CodeActionKind can be an arbitrary String even though it also defines
- // constants for common values. We can tell which can have their own values
- // because they're marked with type aliases, with the exception of ErrorCodes!
- if (!_typeAliases.containsKey(namespace.name) &&
- namespace.name != 'ErrorCodes') {
- _writeEnumClass(buffer, namespace);
- return;
- }
-
- _writeDocCommentsAndAnnotations(buffer, namespace);
- buffer
- ..writeln('abstract class ${namespace.name} {')
- ..indent();
- _writeMembers(buffer, namespace.members);
- buffer
- ..outdent()
- ..writeln('}')
- ..writeln();
-}
-
void _writeToJsonMethod(IndentableStringBuffer buffer, Interface interface) {
// It's important the name we use for the map here isn't in use in the object
// already. 'result' was, so we prefix it with some underscores.
@@ -512,11 +520,17 @@
..writeIndentedln('}');
}
-void _writeType(IndentableStringBuffer buffer, ApiItem type) {
+void _writeToString(IndentableStringBuffer buffer, Interface interface) {
+ buffer
+ ..writeIndentedln('@override')
+ ..writeIndentedln('String toString() => jsonEncoder.convert(toJson());');
+}
+
+void _writeType(IndentableStringBuffer buffer, AstNode type) {
if (type is Interface) {
_writeInterface(buffer, type);
} else if (type is Namespace) {
- _writeNamespace(buffer, type);
+ _writeEnumClass(buffer, type);
} else if (type is TypeAlias) {
// For now type aliases are not supported, so are collected at the start
// of the process in a map, and just replaced with the aliased type during
@@ -528,38 +542,51 @@
}
void _writeTypeCheckCondition(
- IndentableStringBuffer buffer, String valueCode, String dartType) {
- if (dartType == 'dynamic') {
+ IndentableStringBuffer buffer, String valueCode, TypeBase type) {
+ type = resolveTypeAlias(type, resolveEnumClasses: true);
+
+ final resolvedDartType = type.dartTypeWithTypeArgs;
+ if (resolvedDartType == 'dynamic') {
buffer.write('true');
- } else if (_isLiteral(dartType)) {
- buffer.write('$valueCode is $dartType');
- } else if (_isSpecType(dartType)) {
- buffer.write('$dartType.canParse($valueCode)');
- } else if (_isList(dartType)) {
- final listType = _getListType(dartType);
+ } else if (_isSimpleType(type)) {
+ buffer.write('$valueCode is $resolvedDartType');
+ } else if (_isSpecType(type)) {
+ buffer.write('$resolvedDartType.canParse($valueCode)');
+ } else if (type is ArrayType) {
buffer.write('($valueCode is List');
- if (dartType != 'dynamic') {
+ if (resolvedDartType != 'dynamic') {
// TODO(dantup): If we're happy to assume we never have two lists in a union
// we could skip this bit.
buffer
.write(' && ($valueCode.length == 0 || $valueCode.every((item) => ');
- _writeTypeCheckCondition(buffer, 'item', listType);
+ _writeTypeCheckCondition(buffer, 'item', type.elementType);
buffer.write('))');
}
buffer.write(')');
- } else if (_isUnion(dartType)) {
+ } else if (type is MapType) {
+ buffer.write('($valueCode is Map');
+ if (resolvedDartType != 'dynamic') {
+ buffer
+ ..write(' && ($valueCode.length == 0 || (')
+ ..write('$valueCode.keys.every((item) => ');
+ _writeTypeCheckCondition(buffer, 'item', type.indexType);
+ buffer..write('&& $valueCode.values.every((item) => ');
+ _writeTypeCheckCondition(buffer, 'item', type.valueType);
+ buffer.write(')))');
+ }
+ buffer.write(')');
+ } else if (type is UnionType) {
// To type check a union, we just recursively check against each of its types.
- final unionTypes = _getUnionTypes(dartType);
buffer.write('(');
- for (var i = 0; i < unionTypes.length; i++) {
+ for (var i = 0; i < type.types.length; i++) {
if (i != 0) {
buffer.write(' || ');
}
- _writeTypeCheckCondition(buffer, valueCode, mapType([unionTypes[i]]));
+ _writeTypeCheckCondition(buffer, valueCode, type.types[i]);
}
buffer.write(')');
} else {
- throw 'Unable to type check $valueCode against $dartType';
+ throw 'Unable to type check $valueCode against $resolvedDartType';
}
}
@@ -582,10 +609,4 @@
write(_indentString);
writeln(obj);
}
-
- void writeIndentedlnIf(bool condition, Object obj) {
- if (condition) {
- writeIndentedln(obj);
- }
- }
}
diff --git a/pkg/analysis_server/tool/lsp_spec/generate_all.dart b/pkg/analysis_server/tool/lsp_spec/generate_all.dart
index caa6aea..8e93a31 100644
--- a/pkg/analysis_server/tool/lsp_spec/generate_all.dart
+++ b/pkg/analysis_server/tool/lsp_spec/generate_all.dart
@@ -11,6 +11,7 @@
import 'codegen_dart.dart';
import 'markdown.dart';
import 'typescript.dart';
+import 'typescript_parser.dart';
main() async {
final String script = Platform.script.toFilePath();
@@ -20,14 +21,48 @@
new Directory(outFolder).createSync();
final String spec = await fetchSpec();
- final List<ApiItem> types = extractAllTypes(extractTypeScriptBlocks(spec));
- types.addAll(_getSpecialCaseTypes());
+ final List<AstNode> types = extractTypeScriptBlocks(spec)
+ .where(shouldIncludeScriptBlock)
+ .map(parseFile)
+ .expand((f) => f)
+ .where(includeTypeDefinitionInOutput)
+ .toList();
+
+ // Generate an enum for all of the request methods to avoid strings.
+ types.add(extractMethodsEnum(spec));
+
final String output = generateDartForTypes(types);
new File(path.join(outFolder, 'protocol_generated.dart'))
.writeAsStringSync(_generatedFileHeader + output);
}
+Namespace extractMethodsEnum(String spec) {
+ Const toConstant(String value) {
+ final comment = new Comment(
+ new Token(TokenType.COMMENT, '''Constant for the '$value' method.'''));
+
+ // Generate a safe name for the member from the string. Those that start with
+ // $/ will have the prefix removed and all slashes should be replaced with
+ // underscores.
+ final safeMemberName = value.replaceAll(r'$/', '').replaceAll('/', '_');
+
+ return new Const(
+ comment,
+ new Token.identifier(safeMemberName),
+ new Type.identifier('string'),
+ new Token(TokenType.STRING, "'$value'"),
+ );
+ }
+
+ final comment = new Comment(new Token(TokenType.COMMENT,
+ 'Valid LSP methods known at the time of code generation from the spec.'));
+ final methodConstants = extractMethodNames(spec).map(toConstant).toList();
+
+ return new Namespace(
+ comment, new Token.identifier('Method'), methodConstants);
+}
+
const _generatedFileHeader = '''
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
@@ -37,9 +72,17 @@
// To regenerate the file, use the script
// "pkg/analysis_server/tool/lsp_spec/generate_all.dart".
+// ignore_for_file: deprecated_member_use
+// ignore_for_file: unnecessary_brace_in_string_interps
+
import 'dart:core' hide deprecated;
import 'dart:core' as core show deprecated;
+import 'dart:convert' show JsonEncoder;
import 'package:analysis_server/lsp_protocol/protocol_special.dart';
+import 'package:analysis_server/src/protocol/protocol_internal.dart' show listEqual, mapEqual;
+import 'package:analyzer/src/generated/utilities_general.dart';
+
+const jsonEncoder = const JsonEncoder.withIndent(' ');
''';
@@ -51,16 +94,18 @@
return resp.body;
}
-/// Fabricates types for things that don't parse well from the TS spec,
-/// such as anonymous types:
-/// type MarkedString = string | { language: string; value: string };
-List<ApiItem> _getSpecialCaseTypes() {
- return [
- // For MarkedString, we drop the string-only version since we can always
- // supply a language and it makes the type a little simpler.
- new Interface('MarkedString', null, [], [
- new Field('language', null, ['string'], false, false),
- new Field('value', null, ['string'], false, false)
- ])
- ];
+/// Returns whether a script block should be parsed or not.
+bool shouldIncludeScriptBlock(String input) {
+ // We can't parse literal arrays, but this script block is just an example
+ // and not actually referenced anywhere.
+ if (input.trim() == r"export const EOL: string[] = ['\n', '\r\n', '\r'];") {
+ return false;
+ }
+
+ // There are some code blocks that just have example JSON in them.
+ if (input.startsWith('{') && input.endsWith('}')) {
+ return false;
+ }
+
+ return true;
}
diff --git a/pkg/analysis_server/tool/lsp_spec/markdown.dart b/pkg/analysis_server/tool/lsp_spec/markdown.dart
index ae99df1..bf93adc 100644
--- a/pkg/analysis_server/tool/lsp_spec/markdown.dart
+++ b/pkg/analysis_server/tool/lsp_spec/markdown.dart
@@ -4,6 +4,9 @@
final _typeScriptBlockPattern =
new RegExp(r'\B```typescript([\S\s]*?)\n```', multiLine: true);
+final _methodNamesPattern = new RegExp(
+ r'''_(?:Notification|Request):?_:?\r?\n\* method: '(.*?)'\r?\n''',
+ multiLine: true);
/// Extracts fenced code blocks that are explicitly marked as TypeScript from a
/// markdown document.
@@ -13,3 +16,10 @@
.map((m) => m.group(1).trim())
.toList();
}
+
+List<String> extractMethodNames(String spec) {
+ return _methodNamesPattern
+ .allMatches(spec)
+ .map((m) => m.group(1).trim())
+ .toList();
+}
diff --git a/pkg/analysis_server/tool/lsp_spec/typescript.dart b/pkg/analysis_server/tool/lsp_spec/typescript.dart
index 017c666..dd6e854 100644
--- a/pkg/analysis_server/tool/lsp_spec/typescript.dart
+++ b/pkg/analysis_server/tool/lsp_spec/typescript.dart
@@ -2,26 +2,20 @@
// 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.
-// TODO(dantup): Regex seemed like a good choice when parsing the first few...
-// maybe it's not so great now. We should parse this properly if it turns out
-// there are issues with what we have here.
-const String _blockBody = r'\{([\s\S]*?)\s*\n\s*\}';
-const String _comment = r'(?:\/\*\*((?:[\S\s](?!\*\/))+?)\s\*\/)?\s*';
+import 'typescript_parser.dart';
-List<ApiItem> extractAllTypes(List<String> code) {
- return extractTypes(code.join('\n'));
-}
-
-List<ApiItem> extractTypes(String code) {
- final types = ApiItem.extractFrom(code);
- _removeUnwantedTypes(types);
- return types;
-}
-
-String _cleanComment(String comment) {
+String cleanComment(String comment) {
if (comment == null) {
return null;
}
+
+ // Remove the start/end comment markers.
+ if (comment.startsWith('/**') && comment.endsWith('*/')) {
+ comment = comment.substring(3, comment.length - 2);
+ } else if (comment.startsWith('//')) {
+ comment = comment.substring(2);
+ }
+
final _commentLinePrefixes = new RegExp(r'\n\s*\* ?');
final _nonConcurrentNewlines = new RegExp(r'\n(?![\n\s\-*])');
final _newLinesThatRequireReinserting = new RegExp(r'\n (\w)');
@@ -41,10 +35,11 @@
/// Fixes up some enum types that are not as specific as they could be in the
/// spec. For example, Diagnostic.severity is typed "number" but can be mapped
/// to the DiagnosticSeverity enum class.
-String _getImprovedType(String interfaceName, String fieldName) {
+String getImprovedType(String interfaceName, String fieldName) {
const Map<String, Map<String, String>> _improvedTypeMappings = {
"Diagnostic": {
"severity": "DiagnosticSeverity",
+ "code": "String",
},
"TextDocumentSyncOptions": {
"change": "TextDocumentSyncKind",
@@ -61,6 +56,20 @@
"FoldingRange": {
"kind": "FoldingRangeKind",
},
+ "ResponseError": {
+ "code": "ErrorCodes",
+ },
+ "NotificationMessage": {
+ "method": "Method",
+ "params": "object",
+ },
+ "RequestMessage": {
+ "method": "Method",
+ "params": "object",
+ },
+ "SymbolInformation": {
+ "kind": "SymbolKind",
+ },
};
final interface = _improvedTypeMappings[interfaceName];
@@ -68,246 +77,38 @@
return interface != null ? interface[fieldName] : null;
}
-List<String> _getSpecialBaseClasses(String name) {
- const fileOperationTypes = [
- 'TextDocumentEdit',
- 'CreateFile',
- 'RenameFile',
- 'DeleteFile'
- ];
- if (fileOperationTypes.contains(name)) {
- return ['FileOperation'];
+List<String> getSpecialBaseTypes(Interface interface) {
+ if (interface.name == 'RequestMessage' ||
+ interface.name == 'NotificationMessage') {
+ return ['IncomingMessage'];
} else {
return [];
}
}
-List<String> _parseTypes(String baseTypes, String sep) {
- // Special case for a single complicated type we can't parse easily...
- if (baseTypes ==
- '(TextDocumentEdit[] | (TextDocumentEdit | CreateFile | RenameFile | DeleteFile)[])') {
- return ['FileOperation[]'];
- }
- return baseTypes?.split(sep)?.map((t) => t.trim())?.toList() ?? [];
-}
-
-/// Removes types that are in the spec that we don't want.
-void _removeUnwantedTypes(List<ApiItem> types) {
+/// Removes types that are in the spec that we don't want to emit.
+bool includeTypeDefinitionInOutput(AstNode node) {
// These types are not used for v3.0 (Feb 2017) and by dropping them we don't
// have to handle any cases where both a namespace and interfaces are declared
// with the same name.
- types.removeWhere((item) => item.name == 'InitializeError');
+ return node.name != 'InitializeError' &&
+ // We don't emit MarkedString because it gets mapped to a simple String
+ // when getting the .dartType for it.
+ // .startsWith() because there are inline types that will be generated.
+ !node.name.startsWith('MarkedString');
}
-/// Base class for Interface, Field, Constant, etc. parsed from the LSP spec.
-abstract class ApiItem {
- String name, comment;
- bool isDeprecated;
- ApiItem(this.name, String comment)
- : comment = _cleanComment(comment),
- isDeprecated = comment?.contains('@deprecated') ?? false;
-
- static List<ApiItem> extractFrom(String code) {
- List<ApiItem> types = [];
- types.addAll(Interface.extractFrom(code));
- types.addAll(Namespace.extractFrom(code));
- types.addAll(TypeAlias.extractFrom(code));
- return types;
+/// Removes types that are in the spec that we don't want in other signatures.
+bool allowTypeInSignatures(TypeBase type) {
+ // Don't allow arrays of MarkedStrings, but do allow simple MarkedStrings.
+ // The only place that uses these are Hovers and we only send one value
+ // (to match the MarkupString equiv) so the array just makes the types
+ // unnecessarily complicated.
+ if (type is ArrayType) {
+ final elementType = type.elementType;
+ if (elementType is Type && elementType.name == 'MarkedString') {
+ return false;
+ }
}
-}
-
-/// A Constant parsed from the LSP spec.
-class Const extends Member {
- final String type, value;
- Const(String name, String comment, this.type, this.value)
- : super(name, comment);
-
- static List<Const> extractFrom(String code) {
- final RegExp _constPattern = new RegExp(_comment +
- r'''(?:export\s+)?const\s+(\w+)(?::\s+([\w\[\]'".-]+?))?\s*=\s*([\w\[\]'".-]+)\s*(?:;|$)''');
-
- final consts = _constPattern.allMatches(code).map((m) {
- final String comment = m.group(1);
- final String name = m.group(2);
- final String type = m.group(3);
- final String value = m.group(4);
- return new Const(name, comment, type, value);
- }).toList();
- return consts;
- }
-
- static List<Const> extractFromEnumValue(String code) {
- final RegExp _constPattern =
- new RegExp(_comment + r'''(\w+)\s*=\s*([\w\[\]'".-]+)\s*(?:,|$)''');
-
- final consts = _constPattern.allMatches(code).map((m) {
- final String comment = m.group(1);
- final String name = m.group(2);
- final String value = m.group(3);
- return new Const(name, comment, null, value);
- }).toList();
- return consts;
- }
-}
-
-/// A Field for an Interface parsed from the LSP spec.
-class Field extends Member {
- final List<String> types;
- final bool allowsNull, allowsUndefined;
- Field(String name, String comment, this.types, this.allowsNull,
- this.allowsUndefined)
- : super(name, comment);
-
- static List<Field> extractFrom(String interfaceName, String code) {
- final RegExp _fieldPattern = new RegExp(_comment +
- r'([\w\[\]]+\??)\s*:\s*([\w\[\] \|\{\}\(\)<>:;]+)\s*(?:;|$)');
-
- final fields = _fieldPattern.allMatches(code).where((m) {
- // Skip over the indexer in FormattingOptions since we don't need this
- // (for now) and it's complicated to represent.
- if (m.group(0).contains('[key: string]: boolean | number | string;')) {
- return false;
- }
- return true;
- }).map((m) {
- String comment = m.group(1);
- String name = m.group(2);
- String typesString = m.group(3).trim();
- // Our regex may result in semicolons on the end...
- // TODO(dantup): Fix this, or make a simple parser.
- if (typesString.endsWith(';')) {
- typesString = typesString.substring(0, typesString.length - 1);
- }
- // Some fields have weird comments like this in the spec:
- // {@link MessageType}
- // These seem to be the correct type of the field, while the field is
- // marked with number.
- if (comment != null) {
- final RegExp _linkTypePattern = new RegExp(r'See \{@link (\w+)\}\.?');
- final linkTypeMatch = _linkTypePattern.firstMatch(comment);
- if (linkTypeMatch != null) {
- typesString = linkTypeMatch.group(1);
- comment = comment.replaceAll(_linkTypePattern, '');
- }
- }
- List<String> types = _parseTypes(typesString, '|');
- final bool allowsNull = types.contains('null');
- if (allowsNull) {
- types.remove('null');
- }
- final bool allowsUndefined = name.endsWith('?');
- if (allowsUndefined) {
- name = name.substring(0, name.length - 1);
- }
- // Perform simple type improvements for enums values that are typed as
- // num/string in the spec but are enums.
- // the spec.
- if (types.length == 1) {
- types[0] = _getImprovedType(interfaceName, name) ?? types[0];
- }
- return new Field(name, comment, types, allowsNull, allowsUndefined);
- }).toList();
- return fields;
- }
-}
-
-/// An Interface parsed from the LSP spec.
-class Interface extends ApiItem {
- final List<String> baseTypes;
- final List<Member> members;
- Interface(String name, String comment, this.baseTypes, this.members)
- : super(name, comment);
-
- static List<Interface> extractFrom(String code) {
- final RegExp _interfacePattern = new RegExp(_comment +
- r'(?:export\s+)?(?:interface|class)\s+([\w<>]+)(?:\s+extends\s+([\w, ]+?))?\s*' +
- _blockBody);
-
- final interfaces = _interfacePattern.allMatches(code).map((match) {
- final String comment = match.group(1);
- final String name = match.group(2);
- final List<String> baseTypes = _parseTypes(match.group(3), ',');
- final String body = match.group(4);
- final List<Member> members = Member.extractFrom(name, body);
-
- // Add any special base classes we've added to simplify types.
- baseTypes.addAll(_getSpecialBaseClasses(name));
-
- return new Interface(name, comment, baseTypes, members);
- }).toList();
- return interfaces;
- }
-}
-
-/// A Field or Constant parsed from the LSP type.
-abstract class Member extends ApiItem {
- Member(String name, String comment) : super(name, comment);
-
- static List<Member> extractFrom(String interfaceName, String code) {
- List<Member> members = [];
- members.addAll(Field.extractFrom(interfaceName, code));
- members.addAll(Const.extractFrom(code));
- return members;
- }
-}
-
-/// An Enum or Namsepace containing constants parsed from the LSP spec.
-class Namespace extends ApiItem {
- final List<Member> members;
- Namespace(String name, String comment, this.members) : super(name, comment);
-
- static List<Namespace> extractFrom(String code) {
- final enums = <Namespace>[];
- enums.addAll(_extractNamespacesFrom(code));
- enums.addAll(_extractEnumsFrom(code));
- return enums;
- }
-
- static List<Namespace> _extractEnumsFrom(String code) {
- final RegExp _namespacePattern =
- new RegExp(_comment + r'(?:export\s+)?enum\s+(\w+)\s*' + _blockBody);
-
- final namespaces = _namespacePattern.allMatches(code).map((match) {
- final String comment = match.group(1);
- final String name = match.group(2);
- final String body = match.group(3);
-
- final List<Member> members = Const.extractFromEnumValue(body);
- return new Namespace(name, comment, members);
- }).toList();
- return namespaces;
- }
-
- static List<Namespace> _extractNamespacesFrom(String code) {
- final RegExp _namespacePattern = new RegExp(
- _comment + r'(?:export\s+)?namespace\s+(\w+)\s*' + _blockBody);
-
- final namespaces = _namespacePattern.allMatches(code).map((match) {
- final String comment = match.group(1);
- final String name = match.group(2);
- final String body = match.group(3);
- final List<Member> members = Member.extractFrom(name, body);
- return new Namespace(name, comment, members);
- }).toList();
- return namespaces;
- }
-}
-
-/// A type alias parsed from the LSP spec.
-class TypeAlias extends ApiItem {
- final String baseType;
- TypeAlias(name, comment, this.baseType) : super(name, comment);
-
- static List<TypeAlias> extractFrom(String code) {
- final RegExp _typeAliasPattern =
- new RegExp(_comment + r'type\s+([\w]+)\s+=\s+([\w\[\]]+)\s*;');
-
- final typeAliases = _typeAliasPattern.allMatches(code).map((match) {
- final String comment = match.group(1);
- final String name = match.group(2);
- final String baseType = match.group(3);
- return new TypeAlias(name, comment, baseType);
- }).toList();
- return typeAliases;
- }
+ return true;
}
diff --git a/pkg/analysis_server/tool/lsp_spec/typescript_parser.dart b/pkg/analysis_server/tool/lsp_spec/typescript_parser.dart
new file mode 100644
index 0000000..5a6a844
--- /dev/null
+++ b/pkg/analysis_server/tool/lsp_spec/typescript_parser.dart
@@ -0,0 +1,910 @@
+// Copyright (c) 2018, 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:math';
+
+import 'package:analysis_server/src/services/correction/strings.dart'
+ show capitalize;
+
+import 'codegen_dart.dart';
+import 'typescript.dart';
+
+final _validIdentifierCharacters = RegExp('[a-zA-Z0-9_]');
+
+bool isNullType(TypeBase t) => t is Type && t.name == 'null';
+
+bool isUndefinedType(TypeBase t) => t is Type && t.name == 'undefined';
+
+/// A fabricated field name for indexers in case they result in generation
+/// of type names for inline types.
+const fieldNameForIndexer = 'indexer';
+
+List<AstNode> parseFile(String input) {
+ final scanner = new Scanner(input);
+ final tokens = scanner.scan();
+ final parser = new Parser(tokens);
+ return parser.parse();
+}
+
+TypeBase typeOfLiteral(TokenType tokenType) {
+ final typeName = tokenType == TokenType.STRING
+ ? 'string'
+ : tokenType == TokenType.NUMBER
+ ? 'number'
+ : throw 'Unknown literal type $tokenType';
+ return new Type.identifier(typeName);
+}
+
+class ArrayType extends TypeBase {
+ final TypeBase elementType;
+
+ ArrayType(this.elementType);
+
+ @override
+ String get dartType => 'List';
+ @override
+ String get typeArgsString => '<${elementType.dartTypeWithTypeArgs}>';
+}
+
+class MapType extends TypeBase {
+ final TypeBase indexType;
+ final TypeBase valueType;
+
+ MapType(this.indexType, this.valueType);
+
+ @override
+ String get dartType => 'Map';
+ @override
+ String get typeArgsString =>
+ '<${indexType.dartTypeWithTypeArgs}, ${valueType.dartTypeWithTypeArgs}>';
+}
+
+class AstNode {
+ final Comment commentNode;
+ final bool isDeprecated;
+ AstNode(this.commentNode)
+ : isDeprecated = commentNode?.text?.contains('@deprecated') ?? false;
+ String get commentText => commentNode?.text;
+
+ String get name => null;
+}
+
+class Comment extends AstNode {
+ final Token token;
+ final String text;
+
+ Comment(this.token)
+ : text = cleanComment(token.lexeme),
+ super(null);
+}
+
+class Const extends Member {
+ Token nameToken;
+ TypeBase type;
+ Token valueToken;
+ Const(Comment comment, this.nameToken, this.type, this.valueToken)
+ : super(comment);
+ String get name => nameToken.lexeme;
+
+ String get valueAsLiteral {
+ if (type.dartType == 'String') {
+ // Write strings as raw strings, since some have dollars in them (eg. for
+ // LSP method names). valueToken.lexeme already includes the quotes as
+ // read from the spec.
+ return 'r${valueToken.lexeme}';
+ } else {
+ return valueToken.lexeme;
+ }
+ }
+}
+
+class Field extends Member {
+ final Token nameToken;
+ final TypeBase type;
+ final bool allowsNull;
+ final bool allowsUndefined;
+ Field(
+ Comment comment,
+ this.nameToken,
+ this.type,
+ this.allowsNull,
+ this.allowsUndefined,
+ ) : super(comment);
+
+ String get name => nameToken.lexeme;
+}
+
+class FixedValueField extends Field {
+ final Token valueToken;
+ FixedValueField(
+ Comment comment,
+ Token nameToken,
+ this.valueToken,
+ TypeBase type,
+ bool allowsNull,
+ bool allowsUndefined,
+ ) : super(comment, nameToken, type, allowsNull, allowsUndefined);
+}
+
+class InlineInterface extends Interface {
+ InlineInterface(
+ String name,
+ List<Member> members,
+ ) : super(null, new Token.identifier(name), [], [], members);
+}
+
+class Indexer extends Member {
+ final TypeBase indexType;
+ final TypeBase valueType;
+ Indexer(
+ Comment comment,
+ this.indexType,
+ this.valueType,
+ ) : super(comment);
+
+ String get name => fieldNameForIndexer;
+}
+
+class Interface extends AstNode {
+ final Token nameToken;
+ final List<Token> typeArgs;
+ final List<TypeBase> baseTypes;
+ final List<Member> members;
+
+ Interface(
+ Comment comment,
+ this.nameToken,
+ this.typeArgs,
+ this.baseTypes,
+ this.members,
+ ) : super(comment);
+ String get name => nameToken.lexeme;
+ String get nameWithTypeArgs => '$name$typeArgsString';
+
+ String get typeArgsString => typeArgs.isNotEmpty
+ ? '<${typeArgs.map((t) => t.lexeme).join(', ')}>'
+ : '';
+}
+
+class Member extends AstNode {
+ Member(Comment comment) : super(comment);
+}
+
+class Namespace extends AstNode {
+ final Token nameToken;
+ final List<Member> members;
+ Namespace(
+ Comment comment,
+ this.nameToken,
+ this.members,
+ ) : super(comment);
+
+ String get name => nameToken.lexeme;
+}
+
+class Parser {
+ final List<Token> _tokens;
+ int _current = 0;
+ List<AstNode> _nodes;
+ Parser(this._tokens);
+
+ bool get _isAtEnd => _peek().type == TokenType.EOF;
+
+ List<AstNode> parse() {
+ if (_nodes == null) {
+ _nodes = <AstNode>[];
+ while (!_isAtEnd) {
+ _nodes.add(_topLevel());
+ }
+ }
+ return _nodes;
+ }
+
+ /// Returns the current token and moves to the next.
+ Token _advance() => _tokenAt(_current++);
+
+ /// Checks if the next token is [type] without advancing.
+ bool _check(TokenType type) => !_isAtEnd && _peek().type == type;
+
+ Comment _comment() {
+ if (_peek().type != TokenType.COMMENT) {
+ return null;
+ }
+ return Comment(_advance());
+ }
+
+ Const _const(String containerName, Comment leadingComment) {
+ _eatUnwantedKeywords();
+ final name = _consume(TokenType.IDENTIFIER, 'Expected identifier');
+ TypeBase type;
+ if (_match([TokenType.COLON])) {
+ type = _type(containerName, name.lexeme);
+ }
+ final value = _match([TokenType.EQUAL]) ? _advance() : null;
+
+ if (type == null && value != null) {
+ type = typeOfLiteral(value.type);
+ }
+
+ _consume(TokenType.SEMI_COLON, 'Expected ;');
+ return Const(leadingComment, name, type, value);
+ }
+
+ Indexer _indexer(String containerName, Comment leadingComment) {
+ final indexer = _field(containerName, leadingComment);
+ _consume(TokenType.RIGHT_BRACKET, 'Expected ]');
+ _consume(TokenType.COLON, 'Expected :');
+
+ TypeBase type;
+ type = _type(containerName, fieldNameForIndexer, improveTypes: true);
+
+ //_consume(TokenType.RIGHT_BRACE, 'Expected }');
+ _match([TokenType.SEMI_COLON]);
+
+ return new Indexer(leadingComment, indexer.type, type);
+ }
+
+ /// Ensures the next token is [type] and moves to the next, throwing [message]
+ /// if not.
+ Token _consume(TokenType type, String message) {
+ if (_check(type)) {
+ return _advance();
+ }
+
+ throw '$message\n\n${_peek()}';
+ }
+
+ void _eatUnwantedKeywords() {
+ _match([TokenType.EXPORT_KEYWORD]);
+ _match([TokenType.READONLY_KEYWORD]);
+ }
+
+ Namespace _enum(Comment leadingComment) {
+ final name = _consume(TokenType.IDENTIFIER, 'Expected identifier');
+ _consume(TokenType.LEFT_BRACE, 'Expected {');
+ final consts = <Const>[];
+ while (!_check(TokenType.RIGHT_BRACE)) {
+ consts.add(_enumValue(name.lexeme));
+ // Commas might not be present (eg. for last one).
+ _match([TokenType.COMMA]);
+ }
+ _consume(TokenType.RIGHT_BRACE, 'Expected }');
+
+ return new Namespace(leadingComment, name, consts);
+ }
+
+ Const _enumValue(String enumName) {
+ final leadingComment = _comment();
+ _eatUnwantedKeywords();
+ final name = _consume(TokenType.IDENTIFIER, 'Expected identifier');
+ TypeBase type;
+ if (_match([TokenType.COLON])) {
+ type = _type(enumName, name.lexeme);
+ }
+ final value = _match([TokenType.EQUAL]) ? _advance() : null;
+
+ if (type == null && value != null) {
+ type = typeOfLiteral(value.type);
+ }
+ return Const(leadingComment, name, type, value);
+ }
+
+ String _joinNames(String parent, String child) {
+ return '$parent${capitalize(child)}';
+ }
+
+ Field _field(String containerName, Comment leadingComment) {
+ _eatUnwantedKeywords();
+ final name = _consume(TokenType.IDENTIFIER, 'Expected identifier');
+ var canBeUndefined = _match([TokenType.QUESTION]);
+ var canBeNull = false;
+ _consume(TokenType.COLON, 'Expected :');
+ TypeBase type;
+ Token value;
+ type = _type(containerName, name.lexeme,
+ includeUndefined: canBeUndefined, improveTypes: true);
+
+ // Some fields have weird comments like this in the spec:
+ // {@link MessageType}
+ // These seem to be the correct type of the field, while the field is
+ // marked with number.
+ final commentText = leadingComment?.text;
+ if (commentText != null) {
+ final RegExp _linkTypePattern = new RegExp(r'See \{@link (\w+)\}\.?');
+ final linkTypeMatch = _linkTypePattern.firstMatch(commentText);
+ if (linkTypeMatch != null) {
+ type = new Type.identifier(linkTypeMatch.group(1));
+ leadingComment = new Comment(new Token(TokenType.COMMENT,
+ '// ' + commentText.replaceAll(_linkTypePattern, '')));
+ }
+ }
+
+ // Ideally this would be _consume(), but there are no semi-colons after the
+ // "inline types" since they're blocks.
+ _match([TokenType.SEMI_COLON]);
+
+ // Special handling for fields that have fixed values.
+ if (value != null) {
+ return new FixedValueField(
+ leadingComment, name, value, type, canBeNull, canBeUndefined);
+ }
+
+ if (type is UnionType) {
+ UnionType union = type;
+ // Since undefined and null can appear in the union type list but we want to
+ // handle it specially in the code generation, we promote them to fields on
+ // the Field.
+ canBeUndefined |= union.types.any(isUndefinedType);
+ canBeNull = union.types.any(isNullType);
+ // Finally, we need to remove them from the union.
+ final remainingTypes = union.types
+ .where((t) => !isNullType(t) && !isUndefinedType(t))
+ .toList();
+
+ // We also remove any types that are deprecated and/or we won't use to
+ // simplify the unions.
+ remainingTypes.removeWhere((t) => !allowTypeInSignatures(t));
+
+ type = remainingTypes.length > 1
+ ? new UnionType(remainingTypes)
+ : remainingTypes.single;
+ }
+ return Field(leadingComment, name, type, canBeNull, canBeUndefined);
+ }
+
+ Interface _interface(Comment leadingComment) {
+ final name = _consume(TokenType.IDENTIFIER, 'Expected identifier');
+ final typeArgs = <Token>[];
+ if (_match([TokenType.LESS])) {
+ while (true) {
+ typeArgs.add(_consume(TokenType.IDENTIFIER, 'Expected identifier'));
+ if (_check(TokenType.GREATER)) {
+ break;
+ }
+ _consume(TokenType.COMMA, 'Expected , or >');
+ }
+ _consume(TokenType.GREATER, 'Expected >');
+ }
+ final baseTypes = <TypeBase>[];
+ if (_match([TokenType.EXTENDS_KEYWORD])) {
+ while (true) {
+ baseTypes.add(_type(name.lexeme, null));
+ if (_check(TokenType.LEFT_BRACE)) {
+ break;
+ }
+ _consume(TokenType.COMMA, 'Expected , or {');
+ }
+ }
+ _consume(TokenType.LEFT_BRACE, 'Expected {');
+ final members = <Member>[];
+ while (!_check(TokenType.RIGHT_BRACE)) {
+ members.add(_member(name.lexeme));
+ }
+
+ // TODO(dantup): Temporary hack until we handle indexers. Remove nulls, which
+ // are (currently) returned by _field() for indexers.
+ members.removeWhere((m) => m == null);
+
+ _consume(TokenType.RIGHT_BRACE, 'Expected }');
+
+ return new Interface(leadingComment, name, typeArgs, baseTypes, members);
+ }
+
+ /// Returns [true] an advances if the next token is one of [types], otherwise
+ /// returns [false].
+ bool _match(List<TokenType> types) {
+ for (final type in types) {
+ if (_check(type)) {
+ _advance();
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ Member _member(String containerName) {
+ final leadingComment = _comment();
+ _eatUnwantedKeywords();
+
+ if (_match([TokenType.CONST_KEYWORD])) {
+ return _const(containerName, leadingComment);
+ } else if (_match([TokenType.LEFT_BRACKET])) {
+ return _indexer(containerName, leadingComment);
+ } else {
+ return _field(containerName, leadingComment);
+ }
+ }
+
+ Namespace _namespace(Comment leadingComment) {
+ final name = _consume(TokenType.IDENTIFIER, 'Expected identifier');
+ _consume(TokenType.LEFT_BRACE, 'Expected {');
+ final members = <Member>[];
+ while (!_check(TokenType.RIGHT_BRACE)) {
+ members.add(_member(name.lexeme));
+ }
+ _consume(TokenType.RIGHT_BRACE, 'Expected }');
+
+ return new Namespace(leadingComment, name, members);
+ }
+
+ /// Returns the next token without advancing.
+ Token _peek() => _tokenAt(_current);
+
+ Token _tokenAt(int index) =>
+ index < _tokens.length ? _tokens[index] : Token.EOF;
+
+ AstNode _topLevel() {
+ final leadingComment = _comment();
+ _match([TokenType.EXPORT_KEYWORD]);
+
+ final token = _peek();
+ if (_match([TokenType.NAMESPACE_KEYWORD])) {
+ return _namespace(leadingComment);
+ } else if (_match([TokenType.INTERFACE_KEYWORD])) {
+ return _interface(leadingComment);
+ } else if (_match([TokenType.CLASS_KEYWORD])) {
+ // Classes are the same as interfaces in this spec.
+ return _interface(leadingComment);
+ } else if (_match([TokenType.ENUM_KEYWORD])) {
+ return _enum(leadingComment);
+ } else if (token.type == TokenType.IDENTIFIER && token.lexeme == 'type') {
+ // TODO(dantup): This is a hack... We don't have a TYPE_KEYWORD because
+ // the spec has `type` as an identifier.
+ _advance(); // Eat the 'type' keyword.
+ return _typeAlias(leadingComment);
+ } else {
+ throw 'Unexpected token ${_peek()}';
+ }
+ }
+
+ TypeBase _type(
+ String containerName,
+ String fieldName, {
+ bool includeUndefined = false,
+ bool improveTypes = false,
+ }) {
+ var types = <TypeBase>[];
+ if (includeUndefined) {
+ types.add(Type.Undefined);
+ }
+ while (true) {
+ TypeBase type;
+ if (_match([TokenType.LEFT_BRACE])) {
+ // Inline interfaces.
+ final members = <Member>[];
+ while (!_check(TokenType.RIGHT_BRACE)) {
+ members.add(_member(containerName));
+ }
+
+ // TODO(dantup): Temporary hack until we handle indexers. Remove nulls, which
+ // are (currently) returned by _field() for indexers.
+ members.removeWhere((m) => m == null);
+
+ _consume(TokenType.RIGHT_BRACE, 'Expected }');
+ // Some of the inline interfaces have trailing commas (and some do not!)
+ _match([TokenType.COMMA]);
+
+ // If we have a single member that is an indexer type, we can use a Map.
+ if (members.length == 1 && members.single is Indexer) {
+ Indexer indexer = members.single;
+ type = new MapType(indexer.indexType, indexer.valueType);
+ } else {
+ // Add a synthetic interface to the parsers list of nodes to represent this type.
+ final generatedName = _joinNames(containerName, fieldName);
+ _nodes.add(new InlineInterface(generatedName, members));
+ // Record the type as a simple type that references this interface.
+ type = new Type.identifier(generatedName);
+ }
+ } else if (_match([TokenType.LEFT_PAREN])) {
+ // Some types are in (parens), so we just parse the contents as a nested type.
+ type = _type(containerName, fieldName);
+ _consume(TokenType.RIGHT_PAREN, 'Expected )');
+ } else if (_match([TokenType.STRING])) {
+ // In TS and the spec, literal strings can be types:
+ // export const PlainText: 'plaintext' = 'plaintext';
+ // trace?: 'off' | 'messages' | 'verbose';
+ // the best we can do is use their base type (string).
+ type = Type.identifier('string');
+ } else if (_match([TokenType.NUMBER])) {
+ // In TS and the spec, literal numbers can be types:
+ // export const Invoked: 1 = 1;
+ // the best we can do is use their base type (number).
+ type = Type.identifier('number');
+ } else {
+ var typeName = _consume(TokenType.IDENTIFIER, 'Expected identifier');
+ final typeArgs = <Type>[];
+ if (_match([TokenType.LESS])) {
+ while (true) {
+ typeArgs.add(_type(containerName, fieldName));
+ if (_peek() != TokenType.COMMA) {
+ _consume(TokenType.GREATER, 'Expected >');
+ break;
+ }
+ }
+ }
+
+ type = typeName.lexeme == 'Array'
+ ? new ArrayType(typeArgs.single)
+ : new Type(typeName, typeArgs);
+ }
+ if (_match([TokenType.LEFT_BRACKET])) {
+ _consume(TokenType.RIGHT_BRACKET, 'Expected ]');
+ type = new ArrayType(type);
+ }
+ // TODO(dantup): Handle types like This & That.
+ // For now, map to any.
+ if (_match([TokenType.AMPERSAND])) {
+ while (true) {
+ // Eat as many types/ampersands as we have.
+ _type(containerName, fieldName);
+ if (!_check(TokenType.AMPERSAND)) {
+ break;
+ }
+ }
+ type = Type.Any;
+ }
+
+ types.add(type);
+
+ if (!_match([TokenType.PIPE])) {
+ break;
+ }
+ }
+
+ // Remove any duplicate types (for ex. if we map multiple types into dynamic)
+ // we don't want to end up with `dynamic | dynamic`. Key on dartType to
+ // ensure we different types that will map down to the same type.
+ final uniqueTypes = new Map.fromEntries(
+ types.map((t) => new MapEntry(t.dartTypeWithTypeArgs, t)),
+ ).values.toList();
+
+ var type = uniqueTypes.length == 1
+ ? uniqueTypes.single
+ : new UnionType(uniqueTypes);
+
+ // Handle improved type mappings for things that aren't very tight in the spec.
+ if (improveTypes) {
+ final improvedTypeName = getImprovedType(containerName, fieldName);
+ if (improvedTypeName != null) {
+ type = new Type.identifier(improvedTypeName);
+ }
+ }
+ return type;
+ }
+
+ TypeAlias _typeAlias(Comment leadingComment) {
+ final name = _consume(TokenType.IDENTIFIER, 'Expected identifier');
+ _consume(TokenType.EQUAL, 'Expected =');
+ final type = _type(name.lexeme, null);
+ _consume(TokenType.SEMI_COLON, 'Expected ;');
+
+ return new TypeAlias(leadingComment, name, type);
+ }
+}
+
+class Scanner {
+ final String _source;
+ int _startOfToken = 0;
+ int _currentPos = 0;
+ final _tokens = <Token>[];
+ Scanner(this._source);
+
+ bool get _isAtEnd => _currentPos >= _source.length;
+ bool get _isNextAtEnd => _currentPos + 1 >= _source.length;
+
+ List<Token> scan() {
+ while (!_isAtEnd) {
+ _startOfToken = _currentPos;
+ _scanToken();
+ }
+ return _tokens;
+ }
+
+ void _addToken(TokenType type) {
+ final text = _source.substring(_startOfToken, _currentPos);
+ _tokens.add(Token(type, text));
+ }
+
+ String _advance() => _currentPos < _source.length
+ ? _source[_currentPos++]
+ : throw 'Cannot advance past end of source';
+
+ void _identifier() {
+ const keywords = <String, TokenType>{
+ 'class': TokenType.CLASS_KEYWORD,
+ 'const': TokenType.CONST_KEYWORD,
+ 'enum': TokenType.ENUM_KEYWORD,
+ 'export': TokenType.EXPORT_KEYWORD,
+ 'extends': TokenType.EXTENDS_KEYWORD,
+ 'interface': TokenType.INTERFACE_KEYWORD,
+ 'namespace': TokenType.NAMESPACE_KEYWORD,
+ 'readonly': TokenType.READONLY_KEYWORD,
+ };
+ while (_isAlpha(_peek())) {
+ _advance();
+ }
+
+ final string = _source.substring(_startOfToken, _currentPos);
+ if (keywords.containsKey(string)) {
+ _addToken(keywords[string]);
+ } else {
+ _addToken(TokenType.IDENTIFIER);
+ }
+ }
+
+ bool _isAlpha(String s) => _validIdentifierCharacters.hasMatch(s);
+
+ bool _isDigit(String s) => s != null && (s.codeUnitAt(0) ^ 0x30) <= 9;
+
+ bool _match(String expected) {
+ if (_isAtEnd || _source[_currentPos] != expected) {
+ return false;
+ }
+ _currentPos++;
+ return true;
+ }
+
+ void _number() {
+ // Optionally process a negative.
+ _match('-');
+ while (_isDigit(_peek())) {
+ _advance();
+ }
+
+ // Handle fractional parts.
+ if (_peek() == '.' && _isDigit(_peekNext())) {
+ // Consume the decimal point.
+ _advance();
+
+ while (_isDigit(_peek())) {
+ _advance();
+ }
+ }
+
+ _addToken(TokenType.NUMBER);
+ }
+
+ String _peek() => _isAtEnd ? null : _source[_currentPos];
+
+ String _peekNext() => _isNextAtEnd ? null : _source[_currentPos + 1];
+
+ void _scanToken() {
+ const singleCharTokens = <String, TokenType>{
+ ',': TokenType.COMMA,
+ ';': TokenType.SEMI_COLON,
+ ':': TokenType.COLON,
+ '?': TokenType.QUESTION,
+ '.': TokenType.DOT,
+ '(': TokenType.LEFT_PAREN,
+ ')': TokenType.RIGHT_PAREN,
+ '[': TokenType.LEFT_BRACKET,
+ ']': TokenType.RIGHT_BRACKET,
+ '{': TokenType.LEFT_BRACE,
+ '}': TokenType.RIGHT_BRACE,
+ '*': TokenType.STAR,
+ '&': TokenType.AMPERSAND,
+ '=': TokenType.EQUAL,
+ '|': TokenType.PIPE,
+ };
+
+ final c = _advance();
+ if (singleCharTokens.containsKey(c)) {
+ _addToken(singleCharTokens[c]);
+ return;
+ }
+ switch (c) {
+ case '/':
+ if (_match('*')) {
+ // Block comment.
+ while (!_isAtEnd && (_peek() != '*' || _peekNext() != '/')) {
+ _advance();
+ }
+ // Eat the closing comment markers detected above.
+ if (!_isAtEnd) {
+ _advance();
+ _advance();
+ }
+ _addToken(TokenType.COMMENT);
+ } else if (_match('/')) {
+ // Single line comment.
+ while (_peek() != '\n' && !_isAtEnd) {
+ _advance();
+ }
+ _addToken(TokenType.COMMENT);
+ } else {
+ _addToken(TokenType.SLASH);
+ }
+ break;
+ case '<':
+ _addToken(_match('=') ? TokenType.LESS_EQUAL : TokenType.LESS);
+ break;
+ case '>':
+ _addToken(_match('=') ? TokenType.GREATER_EQUAL : TokenType.GREATER);
+ break;
+ case ' ':
+ case '\r':
+ case '\n':
+ case '\t':
+ // Whitespace.
+ break;
+ case '"':
+ case "'":
+ _string(c);
+ break;
+ default:
+ if (_isDigit(c) || c == '-' && _isDigit(_peek())) {
+ _number();
+ } else if (_isAlpha(c)) {
+ _identifier();
+ } else {
+ final start = max(0, _currentPos - 20);
+ final end = min(_currentPos + 20, _source.length);
+ final snippet = _source.substring(start, end);
+ throw "Unexpected character '$c'.\n\n$snippet";
+ }
+ break;
+ }
+ }
+
+ void _string(String terminator) {
+ // TODO(dantup): Handle escape sequences, inc. quotes.
+ while (!_isAtEnd && _peek() != terminator) {
+ _advance();
+
+ if (_isAtEnd) {
+ throw 'Unterminated string.';
+ }
+ }
+
+ // Skip over the closing terminator.
+ _advance();
+
+ _addToken(TokenType.STRING);
+ }
+}
+
+class Token {
+ static final Token EOF = new Token(TokenType.EOF, '');
+
+ final TokenType type;
+ final String lexeme;
+
+ Token(this.type, this.lexeme);
+
+ Token.identifier(String identifier) : this(TokenType.IDENTIFIER, identifier);
+
+ @override
+ String toString() => '${type.toString().padRight(25)} '
+ '${lexeme.padRight(10)}\n';
+}
+
+enum TokenType {
+ AMPERSAND,
+ CLASS_KEYWORD,
+ COLON,
+ COMMA,
+ COMMENT,
+ CONST_KEYWORD,
+ DOT,
+ ENUM_KEYWORD,
+ EOF,
+ EQUAL,
+ EXPORT_KEYWORD,
+ EXTENDS_KEYWORD,
+ GREATER_EQUAL,
+ GREATER,
+ IDENTIFIER,
+ INTERFACE_KEYWORD,
+ LEFT_BRACE,
+ LEFT_BRACKET,
+ LEFT_PAREN,
+ LESS_EQUAL,
+ LESS,
+ NAMESPACE_KEYWORD,
+ NUMBER,
+ PIPE,
+ QUESTION,
+ READONLY_KEYWORD,
+ RIGHT_BRACE,
+ RIGHT_BRACKET,
+ RIGHT_PAREN,
+ SEMI_COLON,
+ SLASH,
+ STAR,
+ STRING,
+}
+
+class Type extends TypeBase {
+ static final TypeBase Undefined = new Type.identifier('undefined');
+ static final TypeBase Any = new Type.identifier('any');
+ final Token nameToken;
+ final List<TypeBase> typeArgs;
+
+ Type(this.nameToken, this.typeArgs) {
+ if (this.name == 'Array' || this.name.endsWith('[]')) {
+ throw 'Type should not be used for arrays, use ArrayType instead';
+ }
+ }
+
+ Type.identifier(String identifier)
+ : this(new Token.identifier(identifier), []);
+
+ @override
+ String get dartType {
+ // Always resolve type aliases when asked for our Dart type.
+ final resolvedType = resolveTypeAlias(this);
+ if (resolvedType != this) {
+ return resolvedType.dartType;
+ }
+
+ const mapping = <String, String>{
+ 'boolean': 'bool',
+ 'string': 'String',
+ 'number': 'num',
+ 'any': 'dynamic',
+ 'object': 'dynamic',
+ // Simplify MarkedString from
+ // string | { language: string; value: string }
+ // to just String
+ 'MarkedString': 'String'
+ };
+
+ final typeName = mapping[name] ?? name;
+ return typeName;
+ }
+
+ String get name => nameToken.lexeme;
+
+ @override
+ String get typeArgsString {
+ // Always resolve type aliases when asked for our Dart type.
+ final resolvedType = resolveTypeAlias(this);
+ if (resolvedType != this) {
+ return resolvedType.typeArgsString;
+ }
+
+ return typeArgs.isNotEmpty
+ ? '<${typeArgs.map((t) => t.dartTypeWithTypeArgs).join(', ')}>'
+ : '';
+ }
+}
+
+class TypeAlias extends AstNode {
+ final Token nameToken;
+ final TypeBase baseType;
+ TypeAlias(
+ Comment comment,
+ this.nameToken,
+ this.baseType,
+ ) : super(comment);
+
+ String get name => nameToken.lexeme;
+}
+
+abstract class TypeBase {
+ String get dartType;
+ String get dartTypeWithTypeArgs => '$dartType$typeArgsString';
+ String get typeArgsString;
+}
+
+class UnionType extends TypeBase {
+ final List<TypeBase> types;
+
+ UnionType(this.types);
+
+ @override
+ String get dartType {
+ if (types.length > 4) {
+ throw 'Unions of more than 4 types are not supported.';
+ }
+ return 'Either${types.length}';
+ }
+
+ @override
+ String get typeArgsString {
+ final typeArgs = types.map((t) => t.dartTypeWithTypeArgs).join(', ');
+ return '<$typeArgs>';
+ }
+}
diff --git a/pkg/analysis_server/tool/spec/to_html.dart b/pkg/analysis_server/tool/spec/to_html.dart
index a6b897b..a2c1b37 100644
--- a/pkg/analysis_server/tool/spec/to_html.dart
+++ b/pkg/analysis_server/tool/spec/to_html.dart
@@ -161,7 +161,7 @@
/**
* Helper methods for creating HTML elements.
*/
-abstract class HtmlMixin {
+mixin HtmlMixin {
void anchor(String id, void callback()) {
element('a', {'name': id}, callback);
}
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 1d0af63..83181c8 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,3 +1,17 @@
+## 0.34.0
+* Support for `declarations-casts` has been removed and the `implicit-casts`
+ option now has the combined semantics of both options. This means that users
+ that disable `implicit-casts` might now see errors that were not previously
+ being reported.
+* Minor changes to the AnalysisSession and AnalysisDriver APIs to make it easier
+ for clients to transition away from using the task model.
+* Minor changes to the linter API to make it easier for lint rules to define
+ their own lint codes.
+* Add a version of getAncestor that matches by type without a closure.
+* Add an AST structure for set literals.
+* Bug fixes: #35162, #35230, #34733, #34741, #33553, #35090, #32815, #34387,
+ #34495, #35043, #33553, #34906, #34489.
+
## 0.33.6+1-dev
* Added a note to the `UriResolver` documentation alerting clients of an
upcoming breaking change.
diff --git a/pkg/analyzer/benchmark/errors_in_all_libraries.dart b/pkg/analyzer/benchmark/errors_in_all_libraries.dart
deleted file mode 100644
index e2540fb..0000000
--- a/pkg/analyzer/benchmark/errors_in_all_libraries.dart
+++ /dev/null
@@ -1,99 +0,0 @@
-#!/usr/bin/env dart
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// Resolves this library and everything it transitively imports and generates
-/// errors in all of those libraries. Does this in an infinite loop, starting
-/// from scratch each time, to show how VM warm-up affects things and to make
-/// it easier to connect to this with observatory.
-import 'dart:io';
-
-import 'package:analyzer/dart/ast/standard_resolution_map.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/src/context/builder.dart';
-import 'package:analyzer/src/dart/sdk/sdk.dart';
-import 'package:analyzer/src/file_system/file_system.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/source/package_map_resolver.dart';
-import 'package:analyzer/src/source/source_resource.dart';
-import 'package:path/path.dart' as p;
-
-void main(List<String> args) {
- // Assumes you have run "pub get" in the analyzer directory itself and uses
- // that "packages" directory as its package root.
- var packageRoot =
- p.normalize(p.join(p.dirname(p.fromUri(Platform.script)), "packages"));
-
- var best = new Duration(days: 1);
- while (true) {
- var start = new DateTime.now();
- AnalysisEngine.instance.clearCaches();
-
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- options.strongModeHints = true;
-
- PhysicalResourceProvider resourceProvider =
- PhysicalResourceProvider.INSTANCE;
- FolderBasedDartSdk sdk = new FolderBasedDartSdk(
- resourceProvider, resourceProvider.getFolder(args[0]));
- sdk.analysisOptions = options;
-
- ContextBuilder builder = new ContextBuilder(resourceProvider, null, null);
- AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
- context.sourceFactory = new SourceFactory([
- new DartUriResolver(sdk),
- new ResourceUriResolver(resourceProvider),
- new PackageMapUriResolver(resourceProvider,
- builder.convertPackagesToMap(builder.createPackageMap(packageRoot)))
- ]);
- context.analysisOptions = options;
-
- var mainSource =
- new FileSource(resourceProvider.getFile(p.fromUri(Platform.script)));
- context.applyChanges(new ChangeSet()..addedSource(mainSource));
-
- var initialLibrary =
- context.resolveCompilationUnit2(mainSource, mainSource);
-
- // Walk all of the transitively referenced libraries and compute errors.
- var errorCount = 0;
- var allLibraries = _reachableLibraries(
- resolutionMap.elementDeclaredByCompilationUnit(initialLibrary).library);
- for (var lib in allLibraries) {
- for (var unit in lib.units) {
- var source = unit.source;
-
- // Skip core libraries.
- if (source.uri.scheme == 'dart') continue;
-
- var librarySource = context.getLibrariesContaining(source).single;
- context.resolveCompilationUnit2(source, librarySource);
- errorCount += context.computeErrors(source).length;
- }
- }
-
- var elapsed = new DateTime.now().difference(start);
- print("$elapsed : $errorCount errors ${elapsed < best ? "(best)" : ""}");
- if (elapsed < best) best = elapsed;
- }
-}
-
-/// Returns all libraries transitively imported or exported from [start].
-List<LibraryElement> _reachableLibraries(LibraryElement start) {
- var results = <LibraryElement>[];
- var seen = new Set();
- void find(LibraryElement lib) {
- if (seen.contains(lib)) return;
- seen.add(lib);
- results.add(lib);
- lib.importedLibraries.forEach(find);
- lib.exportedLibraries.forEach(find);
- }
-
- find(start);
- return results;
-}
diff --git a/pkg/analyzer/example/parser_driver.dart b/pkg/analyzer/example/parser_driver.dart
deleted file mode 100644
index 6515b34..0000000
--- a/pkg/analyzer/example/parser_driver.dart
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/usr/bin/env dart
-// Copyright (c) 2013, 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:io';
-
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/visitor.dart';
-import 'package:analyzer/error/error.dart';
-import 'package:analyzer/error/listener.dart';
-import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/src/dart/scanner/reader.dart';
-import 'package:analyzer/src/dart/scanner/scanner.dart';
-import 'package:analyzer/src/generated/parser.dart';
-
-main(List<String> args) {
- print('working dir ${new File('.').resolveSymbolicLinksSync()}');
-
- if (args.length == 0) {
- print('Usage: parser_driver [files_to_parse]');
- exit(0);
- }
-
- for (var arg in args) {
- _parse(new File(arg));
- }
-}
-
-_parse(File file) {
- var src = file.readAsStringSync();
- PhysicalResourceProvider resourceProvider = PhysicalResourceProvider.INSTANCE;
- var source = resourceProvider.getFile(file.path).createSource();
- var errorListener = new _ErrorCollector();
- var reader = new CharSequenceReader(src);
- var scanner = new Scanner(source, reader, errorListener);
- var token = scanner.tokenize();
- var parser = new Parser(source, errorListener);
- var unit = parser.parseCompilationUnit(token);
-
- var visitor = new _ASTVisitor();
- unit.accept(visitor);
-
- for (var error in errorListener.errors) {
- print(error);
- }
-}
-
-class _ASTVisitor extends GeneralizingAstVisitor {
- @override
- visitNode(AstNode node) {
- print('${node.runtimeType} : <"$node">');
- return super.visitNode(node);
- }
-}
-
-class _ErrorCollector extends AnalysisErrorListener {
- List<AnalysisError> errors;
- _ErrorCollector() : errors = new List<AnalysisError>();
- @override
- onError(error) => errors.add(error);
-}
diff --git a/pkg/analyzer/example/resolver_driver.dart b/pkg/analyzer/example/resolver_driver.dart
deleted file mode 100755
index 6c972a8..0000000
--- a/pkg/analyzer/example/resolver_driver.dart
+++ /dev/null
@@ -1,87 +0,0 @@
-#!/usr/bin/env dart
-// Copyright (c) 2013, 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:io';
-
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/visitor.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/src/context/builder.dart';
-import 'package:analyzer/src/dart/sdk/sdk.dart';
-import 'package:analyzer/src/file_system/file_system.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/source/package_map_resolver.dart';
-import 'package:analyzer/src/source/source_resource.dart';
-
-void main(List<String> args) {
- print('working dir ${new File('.').resolveSymbolicLinksSync()}');
-
- if (args.length < 2 || args.length > 3) {
- print(_usage);
- exit(0);
- }
-
- String packageRoot;
- if (args.length == 3) {
- packageRoot = args[2];
- }
-
- PhysicalResourceProvider resourceProvider = PhysicalResourceProvider.INSTANCE;
- DartSdk sdk = new FolderBasedDartSdk(
- resourceProvider, resourceProvider.getFolder(args[0]));
-
- var resolvers = [
- new DartUriResolver(sdk),
- new ResourceUriResolver(resourceProvider)
- ];
-
- if (packageRoot != null) {
- ContextBuilder builder = new ContextBuilder(resourceProvider, null, null);
- resolvers.add(new PackageMapUriResolver(resourceProvider,
- builder.convertPackagesToMap(builder.createPackageMap(packageRoot))));
- }
-
- AnalysisContext context = AnalysisEngine.instance.createAnalysisContext()
- ..sourceFactory = new SourceFactory(resolvers);
-
- Source source = new FileSource(resourceProvider.getFile(args[1]));
- ChangeSet changeSet = new ChangeSet()..addedSource(source);
- context.applyChanges(changeSet);
- LibraryElement libElement = context.computeLibraryElement(source);
- print("libElement: $libElement");
-
- CompilationUnit resolvedUnit =
- context.resolveCompilationUnit(source, libElement);
- var visitor = new _ASTVisitor();
- resolvedUnit.accept(visitor);
-}
-
-const _usage =
- 'Usage: resolve_driver <path_to_sdk> <file_to_resolve> [<packages_root>]';
-
-class _ASTVisitor extends GeneralizingAstVisitor {
- @override
- visitNode(AstNode node) {
- var lines = <String>['${node.runtimeType} : <"$node">'];
- if (node is SimpleIdentifier) {
- Element element = node.staticElement;
- if (element != null) {
- lines.add(' element: ${element.runtimeType}');
- LibraryElement library = element.library;
- if (library != null) {
- var fullName =
- element.library.definingCompilationUnit.source.fullName;
- lines.add(" from $fullName");
- }
- }
- }
- print(lines.join('\n'));
- return super.visitNode(node);
- }
-}
diff --git a/pkg/analyzer/example/scanner_driver.dart b/pkg/analyzer/example/scanner_driver.dart
deleted file mode 100644
index 22a4e0f..0000000
--- a/pkg/analyzer/example/scanner_driver.dart
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/env dart
-// Copyright (c) 2013, 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:io';
-
-import 'package:analyzer/dart/ast/token.dart';
-import 'package:analyzer/error/listener.dart';
-import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/src/dart/scanner/reader.dart';
-import 'package:analyzer/src/dart/scanner/scanner.dart';
-
-main(List<String> args) {
- print('working dir ${new File('.').resolveSymbolicLinksSync()}');
-
- if (args.length == 0) {
- print('Usage: scanner_driver [files_to_scan]');
- exit(0);
- }
-
- for (var arg in args) {
- _scan(new File(arg));
- }
-}
-
-_scan(File file) {
- var src = file.readAsStringSync();
- PhysicalResourceProvider resourceProvider = PhysicalResourceProvider.INSTANCE;
- var source = resourceProvider.getFile(file.path).createSource();
- var reader = new CharSequenceReader(src);
- var listener = new BooleanErrorListener();
- var scanner = new Scanner(source, reader, listener);
- var token = scanner.tokenize();
- while (token.type != TokenType.EOF) {
- print(token);
- token = token.next;
- }
- if (listener.errorReported) {
- print('Errors found.');
- exit(1);
- }
-}
diff --git a/pkg/analyzer/lib/analyzer.dart b/pkg/analyzer/lib/analyzer.dart
index ab46a8d..3516414 100644
--- a/pkg/analyzer/lib/analyzer.dart
+++ b/pkg/analyzer/lib/analyzer.dart
@@ -2,6 +2,9 @@
// 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.
+@deprecated
+library analyzer;
+
import 'dart:io';
import 'package:analyzer/dart/ast/ast.dart';
diff --git a/pkg/analyzer/lib/dart/analysis/context_builder.dart b/pkg/analyzer/lib/dart/analysis/context_builder.dart
index 69ef376..f99dce5 100644
--- a/pkg/analyzer/lib/dart/analysis/context_builder.dart
+++ b/pkg/analyzer/lib/dart/analysis/context_builder.dart
@@ -30,13 +30,22 @@
* the the variable names found in `fromEnvironment` invocations to the
* constant value that will be returned. If none is given, then no variables
* will be defined.
+ *
+ * If a list of [librarySummaryPaths] is provided, then the summary files at
+ * those paths will be used, when possible, when analyzing the libraries
+ * contained in the summary files.
*
* If an [sdkPath] is provided, and if it is a valid path to a directory
* containing a valid SDK, then the SDK in the referenced directory will be
* used when analyzing the code in the context.
+ *
+ * If an [sdkSummaryPath] is provided, then that file will be used as the
+ * summary file for the SDK.
*/
AnalysisContext createContext(
{@required ContextRoot contextRoot,
DeclaredVariables declaredVariables,
- String sdkPath});
+ List<String> librarySummaryPaths,
+ String sdkPath,
+ String sdkSummaryPath});
}
diff --git a/pkg/analyzer/lib/dart/analysis/results.dart b/pkg/analyzer/lib/dart/analysis/results.dart
index 2c33745..55defb7 100644
--- a/pkg/analyzer/lib/dart/analysis/results.dart
+++ b/pkg/analyzer/lib/dart/analysis/results.dart
@@ -9,43 +9,29 @@
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source.dart';
-/**
- * The result of performing some kind of analysis on a single file. Every result
- * that implements this interface will also implement a sub-interface.
- *
- * Clients may not extend, implement or mix-in this class.
- */
+/// The result of performing some kind of analysis on a single file. Every
+/// result that implements this interface will also implement a sub-interface.
+///
+/// Clients may not extend, implement or mix-in this class.
abstract class AnalysisResult {
- /**
- * The absolute and normalized path of the file that was analyzed.
- */
+ /// The absolute and normalized path of the file that was analyzed.
String get path;
- /**
- * Return the session used to compute this result.
- */
+ /// Return the session used to compute this result.
AnalysisSession get session;
- /**
- * The state of the results.
- */
+ /// The state of the results.
ResultState get state;
- /**
- * The absolute URI of the file that was analyzed.
- */
+ /// The absolute URI of the file that was analyzed.
Uri get uri;
}
-/**
- * An analysis result that includes the errors computed during analysis.
- *
- * Clients may not extend, implement or mix-in this class.
- */
+/// An analysis result that includes the errors computed during analysis.
+///
+/// Clients may not extend, implement or mix-in this class.
abstract class AnalysisResultWithErrors implements FileResult {
- /**
- * The analysis errors that were computed during analysis.
- */
+ /// The analysis errors that were computed during analysis.
List<AnalysisError> get errors;
}
@@ -68,29 +54,21 @@
ResolvedUnitResult get resolvedUnit;
}
-/**
- * The result of computing all of the errors contained in a single file, both
- * syntactic and semantic.
- *
- * Clients may not extend, implement or mix-in this class.
- */
+/// The result of computing all of the errors contained in a single file, both
+/// syntactic and semantic.
+///
+/// Clients may not extend, implement or mix-in this class.
abstract class ErrorsResult implements AnalysisResultWithErrors {}
-/**
- * The result of computing some cheap information for a single file, when full
- * parsed file is not required, so [ParseResult] is not necessary.
- *
- * Clients may not extend, implement or mix-in this class.
- */
+/// The result of computing some cheap information for a single file, when full
+/// parsed file is not required, so [ParsedUnitResult] is not necessary.
+///
+/// Clients may not extend, implement or mix-in this class.
abstract class FileResult implements AnalysisResult {
- /**
- * Whether the file is a part.
- */
+ /// Whether the file is a part.
bool get isPart;
- /**
- * Information about lines in the content.
- */
+ /// Information about lines in the content.
LineInfo get lineInfo;
}
@@ -111,23 +89,19 @@
/// those discovered during scanning and parsing.
///
/// Clients may not extend, implement or mix-in this class.
+// ignore: deprecated_member_use
abstract class ParsedUnitResult implements ParseResult {}
-/**
- * The result of parsing of a single file. The errors returned include only
- * those discovered during scanning and parsing.
- *
- * Clients may not extend, implement or mix-in this class.
- */
+/// The result of parsing of a single file. The errors returned include only
+/// those discovered during scanning and parsing.
+///
+/// Clients may not extend, implement or mix-in this class.
+@deprecated
abstract class ParseResult implements AnalysisResultWithErrors {
- /**
- * The content of the file that was scanned and parsed.
- */
+ /// The content of the file that was scanned and parsed.
String get content;
- /**
- * The parsed, unresolved compilation unit for the [content].
- */
+ /// The parsed, unresolved compilation unit for the [content].
CompilationUnit get unit;
}
@@ -154,85 +128,61 @@
/// include both syntactic and semantic errors.
///
/// Clients may not extend, implement or mix-in this class.
+// ignore: deprecated_member_use
abstract class ResolvedUnitResult implements ResolveResult {}
-/**
- * The result of building a resolved AST for a single file. The errors returned
- * include both syntactic and semantic errors.
- *
- * Clients may not extend, implement or mix-in this class.
- */
+/// The result of building a resolved AST for a single file. The errors returned
+/// include both syntactic and semantic errors.
+///
+/// Clients may not extend, implement or mix-in this class.
+@deprecated
abstract class ResolveResult implements AnalysisResultWithErrors {
- /**
- * The content of the file that was scanned, parsed and resolved.
- */
+ /// The content of the file that was scanned, parsed and resolved.
String get content;
- /**
- * The element representing the library containing the compilation [unit].
- */
+ /// The element representing the library containing the compilation [unit].
LibraryElement get libraryElement;
- /**
- * The type provider used when resolving the compilation [unit].
- */
+ /// The type provider used when resolving the compilation [unit].
TypeProvider get typeProvider;
- /**
- * The type system used when resolving the compilation [unit].
- */
+ /// The type system used when resolving the compilation [unit].
TypeSystem get typeSystem;
- /**
- * The fully resolved compilation unit for the [content].
- */
+ /// The fully resolved compilation unit for the [content].
CompilationUnit get unit;
}
-/**
- * An indication of whether an analysis result is valid, and if not why.
- */
+/// An indication of whether an analysis result is valid, and if not why.
enum ResultState {
- /**
- * An indication that analysis could not be performed because the path
- * represents a file of a type that cannot be analyzed.
- */
+ /// An indication that analysis could not be performed because the path
+ /// represents a file of a type that cannot be analyzed.
INVALID_FILE_TYPE,
- /**
- * An indication that analysis could not be performed because the path does
- * not represent a file. It might represent something else, such as a
- * directory, or it might not represent anything.
- */
+ /// An indication that analysis could not be performed because the path does
+ /// not represent a file. It might represent something else, such as a
+ /// directory, or it might not represent anything.
NOT_A_FILE,
- /**
- * An indication that analysis completed normally and the results are valid.
- */
+ /// An indication that analysis completed normally and the results are valid.
VALID
}
-/**
- * The result of building the element model for a single file.
- *
- * Clients may not extend, implement or mix-in this class.
- */
+/// The result of building the element model for a single file.
+///
+/// Clients may not extend, implement or mix-in this class.
abstract class UnitElementResult implements AnalysisResult {
- /**
- * The element of the file.
- */
+ /// The element of the file.
CompilationUnitElement get element;
- /**
- * The signature of the library containing the [element]. This is the same
- * signature returned by the method [AnalysisSession.getUnitElementSignature]
- * when given the path to the compilation unit represented by the [element].
- *
- * The signature is based on the APIs of the files of the library (including
- * the file itself), and the transitive closure of files imported and exported
- * by the library. If the signature of a file has not changed, then there have
- * been no changes that would cause any files that depend on it to need to be
- * re-analyzed.
- */
+ /// The signature of the library containing the [element]. This is the same
+ /// signature returned by the method [AnalysisSession.getUnitElementSignature]
+ /// when given the path to the compilation unit represented by the [element].
+ ///
+ /// The signature is based on the APIs of the files of the library (including
+ /// the file itself), and the transitive closure of files imported and
+ /// exported by the library. If the signature of a file has not changed, then
+ /// there have been no changes that would cause any files that depend on it
+ /// to need to be re-analyzed.
String get signature;
}
diff --git a/pkg/analyzer/lib/dart/analysis/session.dart b/pkg/analyzer/lib/dart/analysis/session.dart
index b945ed6..6f31a7b 100644
--- a/pkg/analyzer/lib/dart/analysis/session.dart
+++ b/pkg/analyzer/lib/dart/analysis/session.dart
@@ -4,6 +4,7 @@
import 'dart:async';
+import 'package:analyzer/dart/analysis/analysis_context.dart';
import 'package:analyzer/dart/analysis/declared_variables.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/uri_converter.dart';
@@ -14,81 +15,86 @@
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source.dart';
-/**
- * A consistent view of the results of analyzing one or more files.
- *
- * The methods in this class that return analysis results will throw an
- * [InconsistentAnalysisException] if the result to be returned might be
- * inconsistent with any previously returned results.
- *
- * Clients may not extend, implement or mix-in this class.
- */
+/// A consistent view of the results of analyzing one or more files.
+///
+/// The methods in this class that return analysis results will throw an
+/// [InconsistentAnalysisException] if the result to be returned might be
+/// inconsistent with any previously returned results.
+///
+/// Clients may not extend, implement or mix-in this class.
abstract class AnalysisSession {
- /**
- * The declared environment variables.
- */
+ /// The analysis context that created this session.
+ AnalysisContext get analysisContext;
+
+ /// The declared environment variables.
DeclaredVariables get declaredVariables;
- /**
- * Return the [ResourceProvider] that is used to access the file system.
- */
+ /// Return the [ResourceProvider] that is used to access the file system.
ResourceProvider get resourceProvider;
- /**
- * Return the source factory used to resolve URIs.
- *
- * Deprecated: Use the methods on [uriConverter] instead.
- */
+ /// Return the source factory used to resolve URIs.
+ ///
+ /// Deprecated: Use the methods on [uriConverter] instead.
@deprecated
SourceFactory get sourceFactory;
- /**
- * Return a type provider that is consistent with the results returned by this
- * session.
- */
+ /// Return a type provider that is consistent with the results returned by
+ /// this session.
Future<TypeProvider> get typeProvider;
- /**
- * Return the type system being used by this session.
- */
+ /// Return the type system being used by this session.
Future<TypeSystem> get typeSystem;
- /**
- * Return the URI converter used to convert between URI's and file paths.
- */
+ /// Return the URI converter used to convert between URI's and file paths.
UriConverter get uriConverter;
- /**
- * Return a future that will complete with information about the errors
- * contained in the file with the given absolute, normalized [path].
- *
- * If the file cannot be analyzed by this session, then the result will have
- * a result state indicating the nature of the problem.
- */
+ /// Return a future that will complete with information about the errors
+ /// contained in the file with the given absolute, normalized [path].
+ ///
+ /// If the file cannot be analyzed by this session, then the result will have
+ /// a result state indicating the nature of the problem.
Future<ErrorsResult> getErrors(String path);
- /**
- * Return a future that will complete with the library element representing
- * the library with the given [uri].
- */
+ /// Return a future that will complete with the library element representing
+ /// the library with the given [uri].
Future<LibraryElement> getLibraryByUri(String uri);
- /**
- * Return a future that will complete with information about the results of
- * parsing the file with the given absolute, normalized [path].
- */
+ /// Return a future that will complete with information about the results of
+ /// parsing the file with the given absolute, normalized [path].
+ ///
+ /// Deprecated: Use [getParsedUnit] instead.
+ @deprecated
Future<ParseResult> getParsedAst(String path);
- /**
- * Return information about the results of parsing the file with the given
- * absolute, normalized [path].
- */
+ /// Return information about the results of parsing the file with the given
+ /// absolute, normalized [path].
+ ///
+ /// Deprecated: Use [getParsedUnit] instead.
+ @deprecated
ParseResult getParsedAstSync(String path);
- /**
- * Return a future that will complete with information about the results of
- * resolving the file with the given absolute, normalized [path].
- */
+ /// Return information about the results of parsing units of the library file
+ /// with the given absolute, normalized [path].
+ ///
+ /// Throw [ArgumentError] if the given [path] is not the defining compilation
+ /// unit for a library (that is, is a part of a library).
+ ParsedLibraryResult getParsedLibrary(String path);
+
+ /// Return information about the results of parsing units of the library file
+ /// with the given library [element].
+ ///
+ /// Throw [ArgumentError] if the [element] was not produced by this session.
+ ParsedLibraryResult getParsedLibraryByElement(LibraryElement element);
+
+ /// Return information about the results of parsing the file with the given
+ /// absolute, normalized [path].
+ ParsedUnitResult getParsedUnit(String path);
+
+ /// Return a future that will complete with information about the results of
+ /// resolving the file with the given absolute, normalized [path].
+ ///
+ /// Deprecated: Use [getResolvedUnit] instead.
+ @deprecated
Future<ResolveResult> getResolvedAst(String path);
/// Return a future that will complete with information about the results of
@@ -106,46 +112,41 @@
Future<ResolvedLibraryResult> getResolvedLibraryByElement(
LibraryElement element);
- /**
- * Return a future that will complete with the source kind of the file with
- * the given absolute, normalized [path]. If the path does not represent a
- * file or if the kind of the file cannot be determined, then the future will
- * complete with [SourceKind.UNKNOWN].
- */
+ /// Return a future that will complete with information about the results of
+ /// resolving the file with the given absolute, normalized [path].
+ Future<ResolvedUnitResult> getResolvedUnit(String path);
+
+ /// Return a future that will complete with the source kind of the file with
+ /// the given absolute, normalized [path]. If the path does not represent a
+ /// file or if the kind of the file cannot be determined, then the future will
+ /// complete with [SourceKind.UNKNOWN].
Future<SourceKind> getSourceKind(String path);
- /**
- * Return a future that will complete with a list of the top-level
- * declarations with the given [name] in all known libraries.
- */
+ /// Return a future that will complete with a list of the top-level
+ /// declarations with the given [name] in all known libraries.
Future<List<TopLevelDeclarationInSource>> getTopLevelDeclarations(
String name);
- /**
- * Return a future that will complete with information about the results of
- * building the element model for the file with the given absolute, normalized
- * [path].
- */
+ /// Return a future that will complete with information about the results of
+ /// building the element model for the file with the given absolute,
+ /// normalized[path].
Future<UnitElementResult> getUnitElement(String path);
- /**
- * Return a future that will complete with the signature for the file with the
- * given absolute, normalized [path], or `null` if the file cannot be analyzed.
- * This is the same signature returned in the result from [getUnitElement].
- *
- * The signature is based on the APIs of the files of the library (including
- * the file itself), and the transitive closure of files imported and exported
- * by the library. If the signature of a file has not changed, then there have
- * been no changes that would cause any files that depend on it to need to be
- * re-analyzed.
- */
+ /// Return a future that will complete with the signature for the file with
+ /// the given absolute, normalized [path], or `null` if the file cannot be
+ /// analyzed. This is the same signature returned in the result from
+ /// [getUnitElement].
+ ///
+ /// The signature is based on the APIs of the files of the library (including
+ /// the file itself), and the transitive closure of files imported and
+ /// exported by the library. If the signature of a file has not changed, then
+ /// there have been no changes that would cause any files that depend on it to
+ /// need to be re-analyzed.
Future<String> getUnitElementSignature(String path);
}
-/**
- * The exception thrown by an [AnalysisSession] if a result is requested that
- * might be inconsistent with any previously returned results.
- */
+/// The exception thrown by an [AnalysisSession] if a result is requested that
+/// might be inconsistent with any previously returned results.
class InconsistentAnalysisException extends AnalysisException {
InconsistentAnalysisException()
: super('Requested result might be inconsistent with previously '
diff --git a/pkg/analyzer/lib/dart/analysis/utilities.dart b/pkg/analyzer/lib/dart/analysis/utilities.dart
new file mode 100644
index 0000000..75ef87b
--- /dev/null
+++ b/pkg/analyzer/lib/dart/analysis/utilities.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2018, 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:analyzer/dart/analysis/analysis_context.dart';
+import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:meta/meta.dart';
+
+/// Return the result of parsing the file at the given [path].
+///
+/// If a [resourceProvider] is given, it will be used to access the file system.
+///
+/// Note that if more than one file is going to be parsed then this function is
+/// inefficient. Clients should instead use [AnalysisContextCollection] to
+/// create one or more contexts and use those contexts to parse the files.
+ParsedUnitResult parseFile(
+ {@required String path, ResourceProvider resourceProvider}) {
+ AnalysisContext context =
+ _createAnalysisContext(path: path, resourceProvider: resourceProvider);
+ return context.currentSession.getParsedUnit(path);
+}
+
+/// Return the result of resolving the file at the given [path].
+///
+/// If a [resourceProvider] is given, it will be used to access the file system.
+///
+/// Note that if more than one file is going to be resolved then this function
+/// is inefficient. Clients should instead use [AnalysisContextCollection] to
+/// create one or more contexts and use those contexts to resolve the files.
+Future<ResolvedUnitResult> resolveFile(
+ {@required String path, ResourceProvider resourceProvider}) async {
+ AnalysisContext context =
+ _createAnalysisContext(path: path, resourceProvider: resourceProvider);
+ return await context.currentSession.getResolvedUnit(path);
+}
+
+/// Return a newly create analysis context in which the file at the given [path]
+/// can be analyzed.
+///
+/// If a [resourceProvider] is given, it will be used to access the file system.
+AnalysisContext _createAnalysisContext(
+ {@required String path, ResourceProvider resourceProvider}) {
+ AnalysisContextCollection collection = new AnalysisContextCollection(
+ includedPaths: <String>[path],
+ resourceProvider: resourceProvider ?? PhysicalResourceProvider.INSTANCE,
+ );
+ List<AnalysisContext> contexts = collection.contexts;
+ if (contexts.length != 1) {
+ throw new ArgumentError('path must be an absolute path to a single file');
+ }
+ return contexts[0];
+}
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index 661d15b..d0c6320 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -554,6 +554,12 @@
E thisOrAncestorMatching<E extends AstNode>(Predicate<AstNode> predicate);
/**
+ * Return either this node or the most immediate ancestor of this node that
+ * has the given type, or `null` if there is no such node.
+ */
+ T thisOrAncestorOfType<T extends AstNode>();
+
+ /**
* Return a textual description of this node in a form approximating valid
* source. The returned string will not be valid source primarily in the case
* where the node itself is not well-formed.
@@ -757,6 +763,8 @@
R visitScriptTag(ScriptTag node);
+ R visitSetLiteral(SetLiteral node);
+
R visitShowCombinator(ShowCombinator node);
R visitSimpleFormalParameter(SimpleFormalParameter node);
@@ -4347,8 +4355,6 @@
* ('new' | 'const')? [TypeName] ('.' [SimpleIdentifier])? [ArgumentList]
*
* Clients may not extend, implement or mix-in this class.
- *
- * 'new' | 'const' are only optional if the previewDart2 option is enabled.
*/
abstract class InstanceCreationExpression extends Expression
implements ConstructorReferenceNode {
@@ -6029,6 +6035,43 @@
}
/**
+ * A literal set.
+ *
+ * setLiteral ::=
+ * 'const'? ('<' [TypeAnnotation] '>')?
+ * '{' [Expression] (',' [Expression])* ','? '}'
+ * | 'const'? ('<' [TypeAnnotation] '>')? '{' '}'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class SetLiteral extends TypedLiteral {
+ /**
+ * Return the expressions used to compute the elements of the set.
+ */
+ NodeList<Expression> get elements;
+
+ /**
+ * Return the left curly bracket.
+ */
+ Token get leftBracket;
+
+ /**
+ * Set the left curly bracket to the given [token].
+ */
+ void set leftBracket(Token token);
+
+ /**
+ * Return the right curly bracket.
+ */
+ Token get rightBracket;
+
+ /**
+ * Set the right curly bracket to the given [token].
+ */
+ void set rightBracket(Token token);
+}
+
+/**
* A combinator that restricts the names being imported to those in a given list.
*
* showCombinator ::=
diff --git a/pkg/analyzer/lib/dart/ast/ast_factory.dart b/pkg/analyzer/lib/dart/ast/ast_factory.dart
index 5d46028..4d402b0 100644
--- a/pkg/analyzer/lib/dart/ast/ast_factory.dart
+++ b/pkg/analyzer/lib/dart/ast/ast_factory.dart
@@ -939,6 +939,15 @@
ScriptTag scriptTag(Token scriptTag);
/**
+ * Returns a newly created set literal. The [constKeyword] can be `null`
+ * if the literal is not a constant. The [typeArguments] can be `null` if no
+ * type arguments were declared. The list of [elements] can be `null` if the
+ * set is empty.
+ */
+ SetLiteral setLiteral(Token constKeyword, TypeArgumentList typeArguments,
+ Token leftBracket, List<Expression> elements, Token rightBracket);
+
+ /**
* Returns a newly created import show combinator.
*/
ShowCombinator showCombinator(
diff --git a/pkg/analyzer/lib/dart/ast/visitor.dart b/pkg/analyzer/lib/dart/ast/visitor.dart
index 6394b8b..53ff333 100644
--- a/pkg/analyzer/lib/dart/ast/visitor.dart
+++ b/pkg/analyzer/lib/dart/ast/visitor.dart
@@ -480,6 +480,9 @@
R visitScriptTag(ScriptTag scriptTag) => visitNode(scriptTag);
@override
+ R visitSetLiteral(SetLiteral node) => visitTypedLiteral(node);
+
+ @override
R visitShowCombinator(ShowCombinator node) => visitCombinator(node);
@override
@@ -1123,6 +1126,12 @@
}
@override
+ R visitSetLiteral(SetLiteral node) {
+ node.visitChildren(this);
+ return null;
+ }
+
+ @override
R visitShowCombinator(ShowCombinator node) {
node.visitChildren(this);
return null;
@@ -1552,6 +1561,9 @@
R visitScriptTag(ScriptTag node) => null;
@override
+ R visitSetLiteral(SetLiteral node) => null;
+
+ @override
R visitShowCombinator(ShowCombinator node) => null;
@override
@@ -1910,6 +1922,9 @@
R visitScriptTag(ScriptTag node) => _throw(node);
@override
+ R visitSetLiteral(SetLiteral node) => _throw(node);
+
+ @override
R visitShowCombinator(ShowCombinator node) => _throw(node);
@override
@@ -2720,6 +2735,14 @@
}
@override
+ T visitSetLiteral(SetLiteral node) {
+ stopwatch.start();
+ T result = _baseVisitor.visitSetLiteral(node);
+ stopwatch.stop();
+ return result;
+ }
+
+ @override
T visitShowCombinator(ShowCombinator node) {
stopwatch.start();
T result = _baseVisitor.visitShowCombinator(node);
@@ -3213,6 +3236,9 @@
R visitScriptTag(ScriptTag scriptTag) => visitNode(scriptTag);
@override
+ R visitSetLiteral(SetLiteral node) => visitNode(node);
+
+ @override
R visitShowCombinator(ShowCombinator node) => visitNode(node);
@override
@@ -3296,7 +3322,7 @@
* A helper class used to implement the correct order of visits for a
* [BreadthFirstVisitor].
*/
-class _BreadthFirstChildVisitor extends UnifyingAstVisitor<Object> {
+class _BreadthFirstChildVisitor extends UnifyingAstVisitor<void> {
/**
* The [BreadthFirstVisitor] being helped by this visitor.
*/
@@ -3308,8 +3334,7 @@
_BreadthFirstChildVisitor(this.outerVisitor);
@override
- Object visitNode(AstNode node) {
+ void visitNode(AstNode node) {
outerVisitor._queue.add(node);
- return null;
}
}
diff --git a/pkg/analyzer/lib/dart/constant/value.dart b/pkg/analyzer/lib/dart/constant/value.dart
index 2d7ddda..64a29c6 100644
--- a/pkg/analyzer/lib/dart/constant/value.dart
+++ b/pkg/analyzer/lib/dart/constant/value.dart
@@ -130,6 +130,14 @@
Map<DartObject, DartObject> toMapValue();
/**
+ * Return a set corresponding to the value of the object being represented,
+ * or `null` if
+ * * this object is not of type 'Set', or
+ * * the value of the object being represented is `null`.
+ */
+ Set<DartObject> toSetValue();
+
+ /**
* Return a string corresponding to the value of the object being represented,
* or `null` if
* * this object is not of type 'String',
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index a282eb8..87e6f0f 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -34,9 +34,11 @@
/// representation of the statements in a method body, but if one of those
/// statements declares a local variable then the local variable will be
/// represented by an element.
+import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/constant/value.dart';
import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/error/error.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
@@ -182,6 +184,7 @@
/// the class.
ConstructorElement get unnamedConstructor;
+ @deprecated
@override
NamedCompilationUnitMember computeNode();
@@ -405,6 +408,7 @@
/// unit.
List<ClassElement> get types;
+ @deprecated
@override
CompilationUnit computeNode();
@@ -453,6 +457,7 @@
/// library containing this constructor has not yet been resolved.
ConstructorElement get redirectedConstructor;
+ @deprecated
@override
ConstructorDeclaration computeNode();
}
@@ -632,6 +637,9 @@
/// does not have a name, or otherwise does not have an offset.
int get nameOffset;
+ /// Return the analysis session in which this element is defined.
+ AnalysisSession get session;
+
@override
Source get source;
@@ -640,6 +648,7 @@
///
/// This method is expensive, because resolved AST might have been already
/// evicted from cache, so parsing and resolving will be performed.
+ @deprecated
CompilationUnit get unit;
/// Use the given [visitor] to visit this element. Return the value returned
@@ -667,6 +676,7 @@
/// cache, so parsing and resolving will be performed.
///
/// <b>Note:</b> This method cannot be used in an async environment.
+ @deprecated
AstNode computeNode();
/// Return the most immediate ancestor of this element for which the
@@ -703,10 +713,14 @@
@deprecated
static const List<ElementAnnotation> EMPTY_LIST = const <ElementAnnotation>[];
- /// Return a representation of the value of this annotation.
- ///
- /// Return `null` if the value of this annotation could not be computed
- /// because of errors.
+ /// Return the errors that were produced while computing a value for this
+ /// annotation, or `null` if no value has been computed. If a value has been
+ /// produced but no errors were generated, then the list will be empty.
+ List<AnalysisError> get constantEvaluationErrors;
+
+ /// Return a representation of the value of this annotation, or `null` if the
+ /// value of this annotation has not been computed or if the value could not
+ /// be computed because of errors.
DartObject get constantValue;
/// Return the element representing the field, variable, or const constructor
@@ -1055,6 +1069,7 @@
@deprecated
bool get isVirtual;
+ @deprecated
@override
AstNode computeNode();
}
@@ -1097,6 +1112,7 @@
/// and has the name `main`.
bool get isEntryPoint;
+ @deprecated
@override
FunctionDeclaration computeNode();
}
@@ -1118,6 +1134,7 @@
/// type on the right side of the equals.
GenericFunctionTypeElement get function;
+ @deprecated
@override
TypeAlias computeNode();
@@ -1301,6 +1318,11 @@
/// computed yet.
Namespace get publicNamespace;
+ /// Return the top-level elements defined in each of the compilation units
+ /// that are included in this library. This includes both public and private
+ /// elements, but does not include imports, exports, or synthetic elements.
+ Iterable<Element> get topLevelElements;
+
/// Return a list containing all of the compilation units this library
/// consists of. This includes the defining compilation unit and units
/// included using the `part` directive.
@@ -1353,6 +1375,7 @@
@deprecated
static const List<MethodElement> EMPTY_LIST = const <MethodElement>[];
+ @deprecated
@override
MethodDeclaration computeNode();
@@ -1463,6 +1486,7 @@
/// the given [buffer].
void appendToWithoutDelimiters(StringBuffer buffer);
+ @deprecated
@override
FormalParameter computeNode();
}
@@ -1597,6 +1621,7 @@
static const List<TopLevelVariableElement> EMPTY_LIST =
const <TopLevelVariableElement>[];
+ @deprecated
@override
VariableDeclaration computeNode();
}
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index b6545a4..4ecccad 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -57,11 +57,11 @@
AnalysisOptionsHintCode.SUPER_MIXINS_SETTING_DEPRECATED,
CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
- CheckedModeCompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
CheckedModeCompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE,
CheckedModeCompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,
CheckedModeCompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE,
CheckedModeCompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE,
+ CheckedModeCompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE,
CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH,
CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE,
CompileTimeErrorCode.ACCESS_PRIVATE_ENUM_FIELD,
@@ -96,9 +96,11 @@
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE,
CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL,
+ CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_INT,
CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING,
CompileTimeErrorCode.CONST_EVAL_TYPE_INT,
CompileTimeErrorCode.CONST_EVAL_TYPE_NUM,
+ CompileTimeErrorCode.CONST_EVAL_TYPE_TYPE,
CompileTimeErrorCode.CONST_FORMAL_PARAMETER,
CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE,
CompileTimeErrorCode
@@ -106,6 +108,7 @@
CompileTimeErrorCode.CONST_INSTANCE_FIELD,
CompileTimeErrorCode.CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS,
CompileTimeErrorCode.CONST_NOT_INITIALIZED,
+ CompileTimeErrorCode.CONST_SET_ELEMENT_TYPE_IMPLEMENTS_EQUALS,
CompileTimeErrorCode.CONST_WITH_INVALID_TYPE_PARAMETERS,
CompileTimeErrorCode.CONST_WITH_NON_CONST,
CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT,
@@ -137,7 +140,7 @@
CompileTimeErrorCode.FOR_IN_WITH_CONST_VARIABLE,
CompileTimeErrorCode.GENERIC_FUNCTION_TYPED_PARAM_UNSUPPORTED,
CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND,
- CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT,
+ CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS,
CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS,
CompileTimeErrorCode.IMPLEMENTS_NON_CLASS,
@@ -172,6 +175,7 @@
CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS,
CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST,
CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP,
+ CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_SET,
CompileTimeErrorCode.INVALID_URI,
CompileTimeErrorCode.INVALID_USE_OF_COVARIANT,
CompileTimeErrorCode.LABEL_IN_OUTER_SCOPE,
@@ -179,6 +183,7 @@
CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME,
CompileTimeErrorCode.MISSING_CONST_IN_LIST_LITERAL,
CompileTimeErrorCode.MISSING_CONST_IN_MAP_LITERAL,
+ CompileTimeErrorCode.MISSING_CONST_IN_SET_LITERAL,
CompileTimeErrorCode.MISSING_DART_LIBRARY,
CompileTimeErrorCode.MIXIN_APPLICATION_CONCRETE_SUPER_INVOKED_MEMBER_TYPE,
CompileTimeErrorCode.MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE,
@@ -211,6 +216,8 @@
CompileTimeErrorCode.NON_CONSTANT_MAP_KEY_FROM_DEFERRED_LIBRARY,
CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE,
CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY,
+ CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT,
+ CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT_FROM_DEFERRED_LIBRARY,
CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER,
CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY,
CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT,
@@ -318,7 +325,6 @@
HintCode.TYPE_CHECK_IS_NULL,
HintCode.UNDEFINED_GETTER,
HintCode.UNDEFINED_HIDDEN_NAME,
- HintCode.UNDEFINED_METHOD,
HintCode.UNDEFINED_OPERATOR,
HintCode.UNDEFINED_SETTER,
HintCode.UNDEFINED_SHOWN_NAME,
@@ -533,6 +539,7 @@
ScannerErrorCode.UNTERMINATED_MULTI_LINE_COMMENT,
ScannerErrorCode.UNTERMINATED_STRING_LITERAL,
StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS,
+ StaticTypeWarningCode.EXPECTED_ONE_SET_TYPE_ARGUMENTS,
StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS,
StaticTypeWarningCode.FOR_IN_OF_INVALID_ELEMENT_TYPE,
StaticTypeWarningCode.FOR_IN_OF_INVALID_TYPE,
@@ -556,7 +563,6 @@
StaticTypeWarningCode.UNDEFINED_FUNCTION,
StaticTypeWarningCode.UNDEFINED_GETTER,
StaticTypeWarningCode.UNDEFINED_METHOD,
- StaticTypeWarningCode.UNDEFINED_METHOD_WITH_CONSTRUCTOR,
StaticTypeWarningCode.UNDEFINED_OPERATOR,
StaticTypeWarningCode.UNDEFINED_SETTER,
StaticTypeWarningCode.UNDEFINED_SUPER_GETTER,
@@ -629,6 +635,7 @@
StaticWarningCode.REDIRECT_TO_MISSING_CONSTRUCTOR,
StaticWarningCode.REDIRECT_TO_NON_CLASS,
StaticWarningCode.RETURN_WITHOUT_VALUE,
+ StaticWarningCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE,
StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER,
StaticWarningCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE,
StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS,
@@ -665,6 +672,7 @@
StrongModeCode.INVALID_CAST_LITERAL,
StrongModeCode.INVALID_CAST_LITERAL_LIST,
StrongModeCode.INVALID_CAST_LITERAL_MAP,
+ StrongModeCode.INVALID_CAST_LITERAL_SET,
StrongModeCode.INVALID_CAST_FUNCTION_EXPR,
StrongModeCode.INVALID_CAST_NEW_EXPR,
StrongModeCode.INVALID_CAST_METHOD,
diff --git a/pkg/analyzer/lib/error/listener.dart b/pkg/analyzer/lib/error/listener.dart
index eeef617..a835bc3 100644
--- a/pkg/analyzer/lib/error/listener.dart
+++ b/pkg/analyzer/lib/error/listener.dart
@@ -256,58 +256,32 @@
* way that is appropriate for caching those errors within an analysis context.
*/
class RecordingErrorListener implements AnalysisErrorListener {
- /**
- * A map of sets containing the errors that were collected, keyed by each
- * source.
- */
- Map<Source, HashSet<AnalysisError>> _errors =
- new HashMap<Source, HashSet<AnalysisError>>();
+ Set<AnalysisError> _errors;
/**
* Return the errors collected by the listener.
*/
List<AnalysisError> get errors {
- int numEntries = _errors.length;
- if (numEntries == 0) {
- return AnalysisError.NO_ERRORS;
+ if (_errors == null) {
+ return const <AnalysisError>[];
}
- List<AnalysisError> resultList = new List<AnalysisError>();
- for (HashSet<AnalysisError> errors in _errors.values) {
- resultList.addAll(errors);
- }
- return resultList;
- }
-
- /**
- * Add all of the errors recorded by the given [listener] to this listener.
- */
- void addAll(RecordingErrorListener listener) {
- for (AnalysisError error in listener.errors) {
- onError(error);
- }
+ return _errors.toList();
}
/**
* Return the errors collected by the listener for the given [source].
*/
List<AnalysisError> getErrorsForSource(Source source) {
- HashSet<AnalysisError> errorsForSource = _errors[source];
- if (errorsForSource == null) {
- return AnalysisError.NO_ERRORS;
- } else {
- return new List.from(errorsForSource);
+ if (_errors == null) {
+ return const <AnalysisError>[];
}
+ return _errors.where((error) => error.source == source).toList();
}
@override
void onError(AnalysisError error) {
- Source source = error.source;
- HashSet<AnalysisError> errorsForSource = _errors[source];
- if (_errors[source] == null) {
- errorsForSource = new HashSet<AnalysisError>();
- _errors[source] = errorsForSource;
- }
- errorsForSource.add(error);
+ _errors ??= new HashSet<AnalysisError>();
+ _errors.add(error);
}
}
diff --git a/pkg/analyzer/lib/src/codegen/html.dart b/pkg/analyzer/lib/src/codegen/html.dart
index f6405af..1cbce5f 100644
--- a/pkg/analyzer/lib/src/codegen/html.dart
+++ b/pkg/analyzer/lib/src/codegen/html.dart
@@ -75,7 +75,7 @@
/**
* Mixin class for generating HTML.
*/
-class HtmlGenerator {
+mixin HtmlGenerator {
List<dom.Node> _html;
/**
diff --git a/pkg/analyzer/lib/src/command_line/arguments.dart b/pkg/analyzer/lib/src/command_line/arguments.dart
index 904684c..c39ec25 100644
--- a/pkg/analyzer/lib/src/command_line/arguments.dart
+++ b/pkg/analyzer/lib/src/command_line/arguments.dart
@@ -15,7 +15,6 @@
const String analysisOptionsFileOption = 'options';
const String bazelAnalysisOptionsPath =
'package:dart.analysis_options/default.yaml';
-const String declarationCastsFlag = 'declaration-casts';
const String defineVariableOption = 'D';
const String enableInitializingFormalAccessFlag = 'initializing-formal-access';
@deprecated
@@ -47,13 +46,6 @@
options.implicitCasts = args[implicitCastsFlag];
verbose('$implicitCastsFlag = ${options.implicitCasts}');
}
- if (args.wasParsed(declarationCastsFlag)) {
- options.declarationCasts = args[declarationCastsFlag];
- verbose('$declarationCastsFlag = ${options.declarationCasts}');
- } else if (args.wasParsed(implicitCastsFlag)) {
- options.declarationCasts = args[implicitCastsFlag];
- verbose('$declarationCastsFlag = ${options.declarationCasts}');
- }
if (args.wasParsed(noImplicitDynamicFlag)) {
options.implicitDynamic = !args[noImplicitDynamicFlag];
verbose('$noImplicitDynamicFlag = ${options.implicitDynamic}');
@@ -162,10 +154,10 @@
defaultsTo: true,
hide: true,
negatable: true);
- parser.addFlag(declarationCastsFlag,
+ parser.addFlag('declaration-casts',
negatable: true,
help: 'Disable declaration casts in strong mode (https://goo.gl/cTLz40)\n'
- 'This option is deprecated and will be removed in a future release.',
+ 'This option is now ignored and will be removed in a future release.',
hide: ddc && hide);
parser.addFlag(implicitCastsFlag,
negatable: true,
diff --git a/pkg/analyzer/lib/src/context/builder.dart b/pkg/analyzer/lib/src/context/builder.dart
index 8c7104e..3e50d4a 100644
--- a/pkg/analyzer/lib/src/context/builder.dart
+++ b/pkg/analyzer/lib/src/context/builder.dart
@@ -1,10 +1,12 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:collection';
import 'dart:core';
+import 'package:analyzer/dart/analysis/analysis_context.dart' as api;
+import 'package:analyzer/dart/analysis/context_locator.dart' as api;
import 'package:analyzer/dart/analysis/declared_variables.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
@@ -15,27 +17,31 @@
flutterAnalysisOptionsPath;
import 'package:analyzer/src/context/context.dart';
import 'package:analyzer/src/context/context_root.dart';
+import 'package:analyzer/src/dart/analysis/byte_store.dart';
+import 'package:analyzer/src/dart/analysis/context_root.dart' as api;
import 'package:analyzer/src/dart/analysis/driver.dart'
show AnalysisDriver, AnalysisDriverScheduler;
+import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart'
+ as api;
import 'package:analyzer/src/dart/analysis/file_state.dart';
+import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
-import 'package:analyzer/src/file_system/file_system.dart';
-import 'package:analyzer/src/generated/bazel.dart';
import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/gn.dart';
-import 'package:analyzer/src/generated/package_build.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/workspace.dart';
+import 'package:analyzer/src/hint/sdk_constraint_extractor.dart';
import 'package:analyzer/src/lint/registry.dart';
import 'package:analyzer/src/plugin/resolver_provider.dart';
-import 'package:analyzer/src/source/package_map_resolver.dart';
+import 'package:analyzer/src/summary/package_bundle_reader.dart';
import 'package:analyzer/src/summary/summary_sdk.dart';
import 'package:analyzer/src/task/options.dart';
import 'package:analyzer/src/util/uri.dart';
+import 'package:analyzer/src/workspace/basic.dart';
+import 'package:analyzer/src/workspace/bazel.dart';
+import 'package:analyzer/src/workspace/gn.dart';
+import 'package:analyzer/src/workspace/package_build.dart';
+import 'package:analyzer/src/workspace/workspace.dart';
import 'package:args/args.dart';
-import 'package:analyzer/src/dart/analysis/byte_store.dart';
-import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:package_config/packages.dart';
import 'package:package_config/packages_file.dart';
import 'package:package_config/src/packages_impl.dart';
@@ -131,9 +137,10 @@
FileContentOverlay fileContentOverlay;
/**
- * Whether to enable the Dart 2.0 preview.
+ * Whether any analysis driver created through this interface should support
+ * indexing and search.
*/
- bool get previewDart2 => true;
+ bool enableIndex = false;
/**
* Initialize a newly created builder to be ready to build a context rooted in
@@ -155,7 +162,6 @@
AnalysisOptionsImpl options = getAnalysisOptions(path);
context.contentCache = contentCache;
context.sourceFactory = createSourceFactory(path, options);
- options.previewDart2 = previewDart2;
context.analysisOptions = options;
context.name = path;
//_processAnalysisOptions(context, optionMap);
@@ -172,7 +178,11 @@
AnalysisOptions options =
getAnalysisOptions(path, contextRoot: contextRoot);
//_processAnalysisOptions(context, optionMap);
- final sf = createSourceFactory(path, options);
+ SummaryDataStore summaryData;
+ if (builderOptions.librarySummaryPaths != null) {
+ summaryData = SummaryDataStore(builderOptions.librarySummaryPaths);
+ }
+ final sf = createSourceFactory(path, options, summaryData: summaryData);
AnalysisDriver driver = new AnalysisDriver(
analysisDriverScheduler,
@@ -182,7 +192,23 @@
fileContentOverlay,
contextRoot,
sf,
- options);
+ options,
+ enableIndex: enableIndex,
+ externalSummaries: summaryData);
+
+ // Set API AnalysisContext for the driver.
+ var apiContextRoots = api.ContextLocator(
+ resourceProvider: resourceProvider,
+ ).locateRoots(
+ includedPaths: [contextRoot.root],
+ excludedPaths: contextRoot.exclude,
+ );
+ driver.analysisContext = api.DriverBasedAnalysisContext(
+ resourceProvider,
+ apiContextRoots.first,
+ driver,
+ );
+
// temporary plugin support:
if (onCreateAnalysisDriver != null) {
onCreateAnalysisDriver(driver, analysisDriverScheduler, performanceLog,
@@ -255,10 +281,14 @@
return findPackagesFromFile(rootDirectoryPath);
}
- SourceFactory createSourceFactory(String rootPath, AnalysisOptions options) {
+ SourceFactory createSourceFactory(String rootPath, AnalysisOptions options,
+ {SummaryDataStore summaryData}) {
Workspace workspace = createWorkspace(rootPath);
DartSdk sdk = findSdk(workspace.packageMap, options);
- return workspace.createSourceFactory(sdk);
+ if (summaryData != null && sdk is SummaryBasedDartSdk) {
+ summaryData.addBundle(null, sdk.bundle);
+ }
+ return workspace.createSourceFactory(sdk, summaryData);
}
Workspace createWorkspace(String rootPath) {
@@ -266,12 +296,12 @@
// Bazel workspaces that include package files are treated like normal
// (non-Bazel) directories. But may still use package:build.
return PackageBuildWorkspace.find(resourceProvider, rootPath, this) ??
- _BasicWorkspace.find(resourceProvider, rootPath, this);
+ BasicWorkspace.find(resourceProvider, rootPath, this);
}
Workspace workspace = BazelWorkspace.find(resourceProvider, rootPath);
workspace ??= GnWorkspace.find(resourceProvider, rootPath);
workspace ??= PackageBuildWorkspace.find(resourceProvider, rootPath, this);
- return workspace ?? _BasicWorkspace.find(resourceProvider, rootPath, this);
+ return workspace ?? BasicWorkspace.find(resourceProvider, rootPath, this);
}
/**
@@ -414,7 +444,7 @@
// TODO(danrubel) restructure so that we don't create a workspace
// both here and in createSourceFactory
Workspace workspace = createWorkspace(path);
- SourceFactory sourceFactory = workspace.createSourceFactory(null);
+ SourceFactory sourceFactory = workspace.createSourceFactory(null, null);
AnalysisOptionsProvider optionsProvider =
new AnalysisOptionsProvider(sourceFactory);
@@ -472,6 +502,16 @@
} else {
verbose('Using default analysis options');
}
+
+ var pubspecFile = _findPubspecFile(path);
+ if (pubspecFile != null) {
+ var extractor = new SdkConstraintExtractor(pubspecFile);
+ var sdkVersionConstraint = extractor.constraint();
+ if (sdkVersionConstraint != null) {
+ options.sdkVersionConstraint = sdkVersionConstraint;
+ }
+ }
+
return options;
}
@@ -606,6 +646,24 @@
}
/**
+ * Return the `pubspec.yaml` file that should be used when analyzing code in
+ * the directory with the given [path], possibly `null`.
+ */
+ File _findPubspecFile(String path) {
+ var resource = resourceProvider.getResource(path);
+ while (resource != null) {
+ if (resource is Folder) {
+ File pubspecFile = resource.getChildAssumingFile('pubspec.yaml');
+ if (pubspecFile.exists) {
+ return pubspecFile;
+ }
+ }
+ resource = resource.parent;
+ }
+ return null;
+ }
+
+ /**
* Return `true` if either the directory at [rootPath] or a parent of that
* directory contains a `.packages` file.
*/
@@ -674,6 +732,12 @@
String defaultPackagesDirectoryPath;
/**
+ * A list of the paths of summary files that are to be used, or `null` if no
+ * summary information is available.
+ */
+ List<String> librarySummaryPaths;
+
+ /**
* Initialize a newly created set of options
*/
ContextBuilderOptions();
@@ -773,71 +837,3 @@
}
}
}
-
-/**
- * Information about a default Dart workspace.
- */
-class _BasicWorkspace extends Workspace {
- /**
- * The [ResourceProvider] by which paths are converted into [Resource]s.
- */
- final ResourceProvider provider;
-
- /**
- * The absolute workspace root path.
- */
- final String root;
-
- final ContextBuilder _builder;
-
- Map<String, List<Folder>> _packageMap;
-
- Packages _packages;
-
- _BasicWorkspace._(this.provider, this.root, this._builder);
-
- @override
- Map<String, List<Folder>> get packageMap {
- _packageMap ??= _builder.convertPackagesToMap(packages);
- return _packageMap;
- }
-
- Packages get packages {
- _packages ??= _builder.createPackageMap(root);
- return _packages;
- }
-
- @override
- UriResolver get packageUriResolver =>
- new PackageMapUriResolver(provider, packageMap);
-
- @override
- SourceFactory createSourceFactory(DartSdk sdk) {
- List<UriResolver> resolvers = <UriResolver>[];
- if (sdk != null) {
- resolvers.add(new DartUriResolver(sdk));
- }
- resolvers.add(packageUriResolver);
- resolvers.add(new ResourceUriResolver(provider));
- return new SourceFactory(resolvers, packages, provider);
- }
-
- /**
- * Find the basic workspace that contains the given [path].
- */
- static _BasicWorkspace find(
- ResourceProvider provider, String path, ContextBuilder builder) {
- Context context = provider.pathContext;
-
- // Ensure that the path is absolute and normalized.
- if (!context.isAbsolute(path)) {
- throw new ArgumentError('not absolute: $path');
- }
- path = context.normalize(path);
- Resource resource = provider.getResource(path);
- if (resource is File) {
- path = resource.parent.path;
- }
- return new _BasicWorkspace._(provider, path, builder);
- }
-}
diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart
index 2dc5cfd..f26ad7d 100644
--- a/pkg/analyzer/lib/src/context/context.dart
+++ b/pkg/analyzer/lib/src/context/context.dart
@@ -283,9 +283,6 @@
? this._options.strongModeHints != options.strongModeHints
: false) ||
((options is AnalysisOptionsImpl)
- ? this._options.declarationCasts != options.declarationCasts
- : false) ||
- ((options is AnalysisOptionsImpl)
? this._options.implicitCasts != options.implicitCasts
: false) ||
((options is AnalysisOptionsImpl)
@@ -313,10 +310,8 @@
this._options.patchPaths = options.patchPaths;
if (options is AnalysisOptionsImpl) {
this._options.strongModeHints = options.strongModeHints;
- this._options.declarationCasts = options.declarationCasts;
this._options.implicitCasts = options.implicitCasts;
this._options.implicitDynamic = options.implicitDynamic;
- this._options.isMixinSupportEnabled = options.isMixinSupportEnabled;
}
if (needsRecompute) {
for (WorkManager workManager in workManagers) {
diff --git a/pkg/analyzer/lib/src/dart/analysis/analysis_context_collection.dart b/pkg/analyzer/lib/src/dart/analysis/analysis_context_collection.dart
index a474878..f844029 100644
--- a/pkg/analyzer/lib/src/dart/analysis/analysis_context_collection.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/analysis_context_collection.dart
@@ -4,10 +4,11 @@
import 'package:analyzer/dart/analysis/analysis_context.dart';
import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
-import 'package:analyzer/dart/analysis/context_builder.dart';
import 'package:analyzer/dart/analysis/context_locator.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/dart/analysis/context_builder.dart';
+import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:meta/meta.dart';
/// An implementation of [AnalysisContextCollection].
@@ -20,7 +21,9 @@
/// Initialize a newly created analysis context manager.
AnalysisContextCollectionImpl(
- {@required List<String> includedPaths,
+ {bool enableIndex: false,
+ @deprecated FileContentOverlay fileContentOverlay,
+ @required List<String> includedPaths,
ResourceProvider resourceProvider,
String sdkPath})
: resourceProvider =
@@ -35,11 +38,15 @@
);
var roots = contextLocator.locateRoots(includedPaths: includedPaths);
for (var root in roots) {
- var contextBuilder = new ContextBuilder(
+ var contextBuilder = new ContextBuilderImpl(
resourceProvider: this.resourceProvider,
);
- var context =
- contextBuilder.createContext(contextRoot: root, sdkPath: sdkPath);
+ var context = contextBuilder.createContext(
+ contextRoot: root,
+ enableIndex: enableIndex,
+ fileContentOverlay: fileContentOverlay,
+ sdkPath: sdkPath,
+ );
contexts.add(context);
}
}
diff --git a/pkg/analyzer/lib/src/dart/analysis/ast_provider_driver.dart b/pkg/analyzer/lib/src/dart/analysis/ast_provider_driver.dart
deleted file mode 100644
index 21c2297..0000000
--- a/pkg/analyzer/lib/src/dart/analysis/ast_provider_driver.dart
+++ /dev/null
@@ -1,66 +0,0 @@
-// 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:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
-import 'package:analyzer/src/dart/ast/utilities.dart';
-import 'package:analyzer/src/dart/element/ast_provider.dart';
-
-/**
- * [AstProvider] implementation for [AnalysisDriver].
- */
-class AstProviderForDriver implements AstProvider {
- final AnalysisDriver driver;
-
- AstProviderForDriver(this.driver);
-
- @override
- Future<SimpleIdentifier> getParsedNameForElement(Element element) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
- CompilationUnit unit = await getParsedUnitForElement(element);
- return _getNameNode(unit, element);
- }
-
- @override
- Future<CompilationUnit> getParsedUnitForElement(Element element) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
- String path = element.source.fullName;
- ParseResult parseResult = await driver.parseFile(path);
- return parseResult.unit;
- }
-
- @override
- Future<SimpleIdentifier> getResolvedNameForElement(Element element) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
- CompilationUnit unit = await getResolvedUnitForElement(element);
- return _getNameNode(unit, element);
- }
-
- @override
- Future<CompilationUnit> getResolvedUnitForElement(Element element) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
- String path = element.source.fullName;
- AnalysisResult analysisResult = await driver.getResult(path);
- return analysisResult?.unit;
- }
-
- SimpleIdentifier _getNameNode(CompilationUnit unit, Element element) {
- int nameOffset = element.nameOffset;
- if (nameOffset == -1) {
- return null;
- }
- AstNode nameNode = new NodeLocator(nameOffset).searchWithin(unit);
- if (nameNode is SimpleIdentifier) {
- return nameNode;
- }
- return null;
- }
-}
diff --git a/pkg/analyzer/lib/src/dart/analysis/context_builder.dart b/pkg/analyzer/lib/src/dart/analysis/context_builder.dart
index f835eb6..074d46d 100644
--- a/pkg/analyzer/lib/src/dart/analysis/context_builder.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/context_builder.dart
@@ -11,18 +11,18 @@
import 'package:analyzer/src/context/builder.dart' as old
show ContextBuilder, ContextBuilderOptions;
import 'package:analyzer/src/context/context_root.dart' as old;
+import 'package:analyzer/src/dart/analysis/byte_store.dart'
+ show ByteStore, MemoryByteStore;
import 'package:analyzer/src/dart/analysis/driver.dart'
show AnalysisDriver, AnalysisDriverScheduler;
import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart'
show FileContentOverlay;
+import 'package:analyzer/src/dart/analysis/performance_logger.dart'
+ show PerformanceLog;
import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/sdk.dart' show DartSdkManager;
import 'package:analyzer/src/generated/source.dart' show ContentCache;
-import 'package:analyzer/src/dart/analysis/performance_logger.dart'
- show PerformanceLog;
-import 'package:analyzer/src/dart/analysis/byte_store.dart'
- show ByteStore, MemoryByteStore;
import 'package:meta/meta.dart';
/**
@@ -55,10 +55,15 @@
{@deprecated ByteStore byteStore,
@required ContextRoot contextRoot,
DeclaredVariables declaredVariables,
+ bool enableIndex: false,
+ @deprecated FileContentOverlay fileContentOverlay,
+ List<String> librarySummaryPaths,
@deprecated PerformanceLog performanceLog,
@deprecated AnalysisDriverScheduler scheduler,
- String sdkPath}) {
+ String sdkPath,
+ String sdkSummaryPath}) {
byteStore ??= new MemoryByteStore();
+ fileContentOverlay ??= new FileContentOverlay();
performanceLog ??= new PerformanceLog(new StringBuffer());
sdkPath ??= _defaultSdkPath;
@@ -78,6 +83,12 @@
if (declaredVariables != null) {
options.declaredVariables = _toMap(declaredVariables);
}
+ if (sdkSummaryPath != null) {
+ options.dartSdkSummaryPath = sdkSummaryPath;
+ }
+ if (librarySummaryPaths != null) {
+ options.librarySummaryPaths = librarySummaryPaths;
+ }
options.defaultPackageFilePath = contextRoot.packagesFile?.path;
old.ContextBuilder builder = new old.ContextBuilder(
@@ -85,7 +96,8 @@
options: options);
builder.analysisDriverScheduler = scheduler;
builder.byteStore = byteStore;
- builder.fileContentOverlay = new FileContentOverlay();
+ builder.fileContentOverlay = fileContentOverlay;
+ builder.enableIndex = enableIndex;
builder.performanceLog = performanceLog;
old.ContextRoot oldContextRoot = new old.ContextRoot(
diff --git a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
index 4422823..e3fff7c 100644
--- a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
@@ -13,19 +13,18 @@
import 'package:analyzer/src/context/builder.dart'
show ContextBuilder, ContextBuilderOptions;
import 'package:analyzer/src/context/context_root.dart' as old;
+import 'package:analyzer/src/dart/analysis/byte_store.dart'
+ show MemoryByteStore;
import 'package:analyzer/src/dart/analysis/context_root.dart';
import 'package:analyzer/src/dart/analysis/driver.dart'
show AnalysisDriver, AnalysisDriverScheduler;
import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart'
show FileContentOverlay;
-import 'package:analyzer/src/dart/sdk/sdk.dart' show FolderBasedDartSdk;
-import 'package:analyzer/src/generated/sdk.dart' show DartSdkManager;
-import 'package:analyzer/src/generated/source.dart' show ContentCache;
import 'package:analyzer/src/dart/analysis/performance_logger.dart'
show PerformanceLog;
-import 'package:analyzer/src/dart/analysis/byte_store.dart'
- show MemoryByteStore;
+import 'package:analyzer/src/dart/sdk/sdk.dart' show FolderBasedDartSdk;
+import 'package:analyzer/src/generated/sdk.dart' show DartSdkManager;
import 'package:meta/meta.dart';
/**
@@ -91,7 +90,7 @@
scheduler.start();
ContextBuilderOptions options = new ContextBuilderOptions();
ContextBuilder builder = new ContextBuilder(
- resourceProvider, sdkManager, new ContentCache(),
+ resourceProvider, sdkManager, null,
options: options);
if (packagesFile != null) {
options.defaultPackageFilePath = packagesFile;
diff --git a/pkg/analyzer/lib/src/dart/analysis/dependency/library_builder.dart b/pkg/analyzer/lib/src/dart/analysis/dependency/library_builder.dart
new file mode 100644
index 0000000..5acbdc4
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/analysis/dependency/library_builder.dart
@@ -0,0 +1,667 @@
+// Copyright (c) 2018, 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:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/src/dart/analysis/dependency/node.dart';
+import 'package:analyzer/src/dart/ast/token.dart';
+import 'package:analyzer/src/summary/api_signature.dart';
+
+/// Build [Library] that describes nodes and dependencies of the library
+/// with the given [uri] and [units].
+///
+/// If the [units] are just parsed, then only token signatures and referenced
+/// names of nodes can be computed. If the [units] are fully resolved, then
+/// also class member references can be recorded.
+Library buildLibrary(
+ Uri uri,
+ List<CompilationUnit> units,
+ ReferenceCollector referenceCollector,
+) {
+ return _LibraryBuilder(uri, units, referenceCollector).build();
+}
+
+/// The `show` or `hide` namespace combinator.
+class Combinator {
+ final bool isShow;
+ final List<String> names;
+
+ Combinator(this.isShow, this.names);
+
+ @override
+ String toString() {
+ if (isShow) {
+ return 'show ' + names.join(', ');
+ } else {
+ return 'hide ' + names.join(', ');
+ }
+ }
+}
+
+/// The `export` directive.
+class Export {
+ /// The absolute URI of the exported library.
+ final Uri uri;
+
+ /// The list of namespace combinators to apply, not `null`.
+ final List<Combinator> combinators;
+
+ Export(this.uri, this.combinators);
+
+ @override
+ String toString() {
+ return 'Export(uri: $uri, combinators: $combinators)';
+ }
+}
+
+/// The `import` directive.
+class Import {
+ /// The absolute URI of the imported library.
+ final Uri uri;
+
+ /// The import prefix, or `null` if not specified.
+ final String prefix;
+
+ /// The list of namespace combinators to apply, not `null`.
+ final List<Combinator> combinators;
+
+ Import(this.uri, this.prefix, this.combinators);
+
+ @override
+ String toString() {
+ return 'Import(uri: $uri, prefix: $prefix, combinators: $combinators)';
+ }
+}
+
+/// The collection of imports, exports, and top-level nodes.
+class Library {
+ /// The absolute URI of the library.
+ final Uri uri;
+
+ /// The list of imports in this library.
+ final List<Import> imports;
+
+ /// The list of exports in this library.
+ final List<Export> exports;
+
+ /// The list of libraries that correspond to the [imports].
+ List<Library> importedLibraries;
+
+ /// The list of top-level nodes defined in the library.
+ ///
+ /// This list is sorted.
+ final List<DependencyNode> declaredNodes;
+
+ /// The map of [declaredNodes], used for fast search.
+ /// TODO(scheglov) consider using binary search instead.
+ final Map<DependencyName, DependencyNode> declaredNodeMap = {};
+
+ /// The list of nodes exported from this library, either using `export`
+ /// directives, or declared in this library.
+ ///
+ /// This list is sorted.
+ List<DependencyNode> exportedNodes;
+
+ /// The map of nodes that are visible in the library, either imported,
+ /// or declared in this library.
+ ///
+ /// TODO(scheglov) support for imports with prefixes
+ Map<String, DependencyNode> libraryScope;
+
+ Library(this.uri, this.imports, this.exports, this.declaredNodes) {
+ for (var node in declaredNodes) {
+ declaredNodeMap[node.name] = node;
+ }
+ }
+
+ @override
+ String toString() => '$uri';
+}
+
+/// The interface for a class that collects information about external nodes
+/// referenced by a node.
+///
+/// The workflow for using it is that the library builder creates a new
+/// instance, fills it with names of import prefixes using [addImportPrefix].
+/// Then for each node defined in the library, methods `appendXyz` called
+/// zero or more times to record references to external names to record API or
+/// implementation dependencies. When all dependencies of a node are appended,
+/// [finish] is invoked to construct the full [DependencyNodeDependencies].
+/// TODO(scheglov) In following CLs we will provide single implementation.
+abstract class ReferenceCollector {
+ final Uri libraryUri;
+
+ ReferenceCollector(this.libraryUri);
+
+ /// Record that the [name] is a name of an import prefix.
+ ///
+ /// So, when we see code like `prefix.foo` we know that `foo` should be
+ /// resolved in the import scope that corresponds to `prefix` (unless the
+ /// name `prefix` is shadowed by a local declaration).
+ void addImportPrefix(String name);
+
+ /// Collect external nodes referenced from the given [node].
+ void appendExpression(Expression node);
+
+ /// Collect external nodes referenced from the given [node].
+ void appendFormalParameters(FormalParameterList node);
+
+ /// Collect external nodes referenced from the given [node].
+ void appendFunctionBody(FunctionBody node);
+
+ /// Collect external nodes referenced from the given [node].
+ void appendTypeAnnotation(TypeAnnotation node);
+
+ /// Construct and return a new [DependencyNodeDependencies] with the given
+ /// [tokenSignature] and all recorded references to external nodes. Clear
+ /// data structures with recorded references and be ready to start recording
+ /// references for a new node.
+ DependencyNodeDependencies finish(List<int> tokenSignature);
+}
+
+class _LibraryBuilder {
+ /// The URI of the library.
+ final Uri uri;
+
+ /// The units of the library, parsed or fully resolved.
+ final List<CompilationUnit> units;
+
+ /// The instance of the referenced names, class members collector.
+ final ReferenceCollector referenceCollector;
+
+ /// The list of imports in the library.
+ final List<Import> imports = [];
+
+ /// The list of exports in the library.
+ final List<Export> exports = [];
+
+ /// The top-level nodes declared in the library.
+ final List<DependencyNode> declaredNodes = [];
+
+ _LibraryBuilder(this.uri, this.units, this.referenceCollector);
+
+ Library build() {
+ _addImports();
+ _addExports();
+
+ // TODO(scheglov) import prefixes are shadowed by class members
+
+ for (var unit in units) {
+ _addUnit(unit);
+ }
+ declaredNodes.sort(DependencyNode.compare);
+
+ return Library(uri, imports, exports, declaredNodes);
+ }
+
+ void _addClassOrMixin(ClassOrMixinDeclaration node) {
+ var hasConstConstructor = node.members.any(
+ (m) => m is ConstructorDeclaration && m.constKeyword != null,
+ );
+
+ List<DependencyNode> classTypeParameters;
+ if (node.typeParameters != null) {
+ classTypeParameters = <DependencyNode>[];
+ for (var typeParameter in node.typeParameters.typeParameters) {
+ classTypeParameters.add(DependencyNode(
+ DependencyName(uri, typeParameter.name.name),
+ DependencyNodeKind.TYPE_PARAMETER,
+ _computeApiDependencies(
+ _computeNodeTokenSignature(typeParameter),
+ typeParameter,
+ ),
+ DependencyNodeDependencies.none,
+ ));
+ }
+ classTypeParameters.sort(DependencyNode.compare);
+ }
+
+ var classMembers = <DependencyNode>[];
+ var hasConstructor = false;
+ for (var member in node.members) {
+ if (member is ConstructorDeclaration) {
+ hasConstructor = true;
+ _addConstructor(classMembers, member);
+ } else if (member is FieldDeclaration) {
+ _addVariables(
+ classMembers,
+ member.metadata,
+ member.fields,
+ hasConstConstructor,
+ );
+ } else if (member is MethodDeclaration) {
+ _addMethod(classMembers, member);
+ } else {
+ throw UnimplementedError('(${member.runtimeType}) $member');
+ }
+ }
+
+ if (!hasConstructor && node is ClassDeclaration) {
+ classMembers.add(DependencyNode(
+ DependencyName(uri, ''),
+ DependencyNodeKind.CONSTRUCTOR,
+ DependencyNodeDependencies.none,
+ DependencyNodeDependencies.none,
+ ));
+ }
+
+ var classTokenSignature = _computeTokenSignature(
+ node.beginToken,
+ node.leftBracket,
+ );
+ // TODO(scheglov) add library URI
+
+ var classNode = DependencyNode(
+ DependencyName(uri, node.name.name),
+ node is MixinDeclaration
+ ? DependencyNodeKind.MIXIN
+ : DependencyNodeKind.CLASS,
+ _computeApiDependencies(classTokenSignature, node),
+ DependencyNodeDependencies.none,
+ classTypeParameters: classTypeParameters,
+ );
+
+ classMembers.sort(DependencyNode.compare);
+ classNode.setClassMembers(classMembers);
+
+ declaredNodes.add(classNode);
+ }
+
+ void _addClassTypeAlias(ClassTypeAlias node) {
+ var tokenSignature = _computeNodeTokenSignature(node);
+ declaredNodes.add(DependencyNode(
+ DependencyName(uri, node.name.name),
+ DependencyNodeKind.CLASS_TYPE_ALIAS,
+ _computeApiDependencies(tokenSignature, node),
+ DependencyNodeDependencies.none,
+ ));
+ }
+
+ void _addConstructor(
+ List<DependencyNode> classMembers, ConstructorDeclaration node) {
+ var signature = ApiSignature();
+ _appendMetadataTokens(signature, node.metadata);
+ _appendFormalParametersTokens(signature, node.parameters);
+ var tokenSignature = signature.toByteList();
+
+ classMembers.add(DependencyNode(
+ DependencyName(uri, node.name?.name ?? ''),
+ DependencyNodeKind.CONSTRUCTOR,
+ _computeApiDependencies(tokenSignature, node),
+ DependencyNodeDependencies.none,
+ ));
+ }
+
+ void _addEnum(EnumDeclaration node) {
+ var classMembers = <DependencyNode>[];
+ for (var constant in node.constants) {
+ classMembers.add(DependencyNode(
+ DependencyName(uri, constant.name.name),
+ DependencyNodeKind.GETTER,
+ DependencyNodeDependencies.none,
+ DependencyNodeDependencies.none,
+ ));
+ }
+ classMembers.add(DependencyNode(
+ DependencyName(uri, 'index'),
+ DependencyNodeKind.GETTER,
+ DependencyNodeDependencies.none,
+ DependencyNodeDependencies.none,
+ ));
+ classMembers.add(DependencyNode(
+ DependencyName(uri, 'values'),
+ DependencyNodeKind.GETTER,
+ DependencyNodeDependencies.none,
+ DependencyNodeDependencies.none,
+ ));
+ classMembers.sort(DependencyNode.compare);
+
+ var enumNode = DependencyNode(
+ DependencyName(uri, node.name.name),
+ DependencyNodeKind.ENUM,
+ DependencyNodeDependencies.none,
+ DependencyNodeDependencies.none,
+ );
+ enumNode.setClassMembers(classMembers);
+
+ declaredNodes.add(enumNode);
+ }
+
+ /// Fill [exports] with information about exports.
+ void _addExports() {
+ for (var directive in units.first.directives) {
+ if (directive is ExportDirective) {
+ var refUri = directive.uri.stringValue;
+ var importUri = uri.resolve(refUri);
+ var combinators = _getCombinators(directive);
+ exports.add(Export(importUri, combinators));
+ }
+ }
+ }
+
+ void _addFunction(FunctionDeclaration node) {
+ var functionExpression = node.functionExpression;
+
+ var signature = ApiSignature();
+ _appendMetadataTokens(signature, node.metadata);
+ _appendNodeTokens(signature, node.returnType);
+ _appendNodeTokens(signature, functionExpression.typeParameters);
+ _appendFormalParametersTokens(signature, functionExpression.parameters);
+ var tokenSignature = signature.toByteList();
+
+ var rawName = node.name.name;
+ var name = DependencyName(uri, node.isSetter ? '$rawName=' : rawName);
+
+ DependencyNodeKind kind;
+ if (node.isGetter) {
+ kind = DependencyNodeKind.GETTER;
+ } else if (node.isSetter) {
+ kind = DependencyNodeKind.SETTER;
+ } else {
+ kind = DependencyNodeKind.FUNCTION;
+ }
+
+ referenceCollector.appendTypeAnnotation(node.returnType);
+ referenceCollector.appendFormalParameters(
+ node.functionExpression.parameters,
+ );
+ var api = referenceCollector.finish(tokenSignature);
+
+ var bodyNode = node.functionExpression.body;
+ var implTokenSignature = _computeNodeTokenSignature(bodyNode);
+ referenceCollector.appendFunctionBody(bodyNode);
+ var impl = referenceCollector.finish(implTokenSignature);
+
+ declaredNodes.add(DependencyNode(name, kind, api, impl));
+ }
+
+ void _addFunctionTypeAlias(FunctionTypeAlias node) {
+ var signature = ApiSignature();
+ _appendMetadataTokens(signature, node.metadata);
+ _appendNodeTokens(signature, node.typeParameters);
+ _appendNodeTokens(signature, node.returnType);
+ _appendFormalParametersTokens(signature, node.parameters);
+ var tokenSignature = signature.toByteList();
+
+ declaredNodes.add(DependencyNode(
+ DependencyName(uri, node.name.name),
+ DependencyNodeKind.FUNCTION_TYPE_ALIAS,
+ _computeApiDependencies(tokenSignature, node),
+ DependencyNodeDependencies.none,
+ ));
+ }
+
+ void _addGenericTypeAlias(GenericTypeAlias node) {
+ var functionType = node.functionType;
+
+ var signature = ApiSignature();
+ _appendMetadataTokens(signature, node.metadata);
+ _appendNodeTokens(signature, node.typeParameters);
+ _appendNodeTokens(signature, functionType.returnType);
+ _appendNodeTokens(signature, functionType.typeParameters);
+ _appendFormalParametersTokens(signature, functionType.parameters);
+ var tokenSignature = signature.toByteList();
+
+ declaredNodes.add(DependencyNode(
+ DependencyName(uri, node.name.name),
+ DependencyNodeKind.GENERIC_TYPE_ALIAS,
+ _computeApiDependencies(tokenSignature, node),
+ DependencyNodeDependencies.none,
+ ));
+ }
+
+ /// Fill [imports] with information about imports.
+ void _addImports() {
+ var hasDartCoreImport = false;
+ for (var directive in units.first.directives) {
+ if (directive is ImportDirective) {
+ var refUri = directive.uri.stringValue;
+ var importUri = uri.resolve(refUri);
+
+ if (importUri.toString() == 'dart:core') {
+ hasDartCoreImport = true;
+ }
+
+ var combinators = _getCombinators(directive);
+
+ imports.add(Import(importUri, directive.prefix?.name, combinators));
+
+ if (directive.prefix != null) {
+ referenceCollector.addImportPrefix(directive.prefix.name);
+ }
+ }
+ }
+
+ if (!hasDartCoreImport) {
+ imports.add(Import(Uri.parse('dart:core'), null, []));
+ }
+ }
+
+ void _addMethod(List<DependencyNode> classMembers, MethodDeclaration node) {
+ var signature = ApiSignature();
+ _appendMetadataTokens(signature, node.metadata);
+ _appendNodeTokens(signature, node.returnType);
+ _appendNodeTokens(signature, node.typeParameters);
+ _appendFormalParametersTokens(signature, node.parameters);
+ var tokenSignature = signature.toByteList();
+
+ DependencyNodeKind kind;
+ if (node.isGetter) {
+ kind = DependencyNodeKind.GETTER;
+ } else if (node.isSetter) {
+ kind = DependencyNodeKind.SETTER;
+ } else {
+ kind = DependencyNodeKind.METHOD;
+ }
+
+ referenceCollector.appendTypeAnnotation(node.returnType);
+ referenceCollector.appendFormalParameters(node.parameters);
+ var api = referenceCollector.finish(tokenSignature);
+
+ var implTokenSignature = _computeNodeTokenSignature(node.body);
+ referenceCollector.appendFunctionBody(node.body);
+ var impl = referenceCollector.finish(implTokenSignature);
+
+ classMembers.add(
+ DependencyNode(DependencyName(uri, node.name.name), kind, api, impl));
+ }
+
+ void _addUnit(CompilationUnit unit) {
+ for (var declaration in unit.declarations) {
+ if (declaration is ClassOrMixinDeclaration) {
+ _addClassOrMixin(declaration);
+ } else if (declaration is ClassTypeAlias) {
+ _addClassTypeAlias(declaration);
+ } else if (declaration is EnumDeclaration) {
+ _addEnum(declaration);
+ } else if (declaration is FunctionDeclaration) {
+ _addFunction(declaration);
+ } else if (declaration is FunctionTypeAlias) {
+ _addFunctionTypeAlias(declaration);
+ } else if (declaration is GenericTypeAlias) {
+ _addGenericTypeAlias(declaration);
+ } else if (declaration is TopLevelVariableDeclaration) {
+ _addVariables(
+ declaredNodes,
+ declaration.metadata,
+ declaration.variables,
+ false,
+ );
+ } else {
+ throw UnimplementedError('(${declaration.runtimeType}) $declaration');
+ }
+ }
+ }
+
+ void _addVariables(
+ List<DependencyNode> variableNodes,
+ List<Annotation> metadata,
+ VariableDeclarationList variables,
+ bool appendInitializerToApi) {
+ if (variables.isConst || variables.type == null) {
+ appendInitializerToApi = true;
+ }
+
+ for (var variable in variables.variables) {
+ var signature = ApiSignature();
+ signature.addInt(variables.isConst ? 1 : 0); // const flag
+ _appendMetadataTokens(signature, metadata);
+
+ _appendNodeTokens(signature, variables.type);
+ referenceCollector.appendTypeAnnotation(variables.type);
+
+ if (appendInitializerToApi) {
+ _appendNodeTokens(signature, variable.initializer);
+ referenceCollector.appendExpression(variable.initializer);
+ }
+
+ var tokenSignature = signature.toByteList();
+ var api = referenceCollector.finish(tokenSignature);
+
+ var rawName = variable.name.name;
+ variableNodes.add(
+ DependencyNode(
+ DependencyName(uri, rawName),
+ DependencyNodeKind.GETTER,
+ api,
+ DependencyNodeDependencies.none,
+ ),
+ );
+ if (!variables.isConst && !variables.isFinal) {
+ variableNodes.add(
+ DependencyNode(
+ DependencyName(uri, '$rawName='),
+ DependencyNodeKind.SETTER,
+ api,
+ DependencyNodeDependencies.none,
+ ),
+ );
+ }
+ }
+ }
+
+ /// Append tokens of the given [parameters] to the [signature].
+ static void _appendFormalParametersTokens(
+ ApiSignature signature, FormalParameterList parameters) {
+ if (parameters == null) return;
+
+ for (var parameter in parameters.parameters) {
+ if (parameter.isRequired) {
+ signature.addInt(1);
+ } else if (parameter.isOptionalPositional) {
+ signature.addInt(2);
+ } else {
+ signature.addInt(3);
+ }
+
+ // If a simple not named parameter, we don't need its name.
+ // We should be careful to include also annotations.
+ if (parameter is SimpleFormalParameter && parameter.type != null) {
+ _appendTokens(
+ signature,
+ parameter.beginToken,
+ parameter.type.endToken,
+ );
+ continue;
+ }
+
+ // We don't know anything better than adding the whole parameter.
+ _appendNodeTokens(signature, parameter);
+ }
+ }
+
+ static void _appendMetadataTokens(
+ ApiSignature signature, List<Annotation> metadata) {
+ if (metadata != null) {
+ for (var annotation in metadata) {
+ _appendNodeTokens(signature, annotation);
+ }
+ }
+ }
+
+ /// Append tokens of the given [node] to the [signature].
+ static void _appendNodeTokens(ApiSignature signature, AstNode node) {
+ if (node != null) {
+ _appendTokens(signature, node.beginToken, node.endToken);
+ }
+ }
+
+ /// Append tokens from [begin] to [end] (both including) to the [signature].
+ static void _appendTokens(ApiSignature signature, Token begin, Token end) {
+ if (begin is CommentToken) {
+ begin = (begin as CommentToken).parent;
+ }
+
+ Token token = begin;
+ while (token != null) {
+ signature.addString(token.lexeme);
+
+ if (token == end) {
+ break;
+ }
+
+ var nextToken = token.next;
+ if (nextToken == token) {
+ break;
+ }
+
+ token = nextToken;
+ }
+ }
+
+ /// TODO(scheglov) Replace all uses with [referenceCollector].
+ static DependencyNodeDependencies _computeApiDependencies(
+ List<int> tokenSignature, AstNode node,
+ [AstNode node2]) {
+ List<String> importPrefixes = [];
+ List<String> unprefixedReferencedNames = [];
+ List<List<String>> importPrefixedReferencedNames = [];
+ return DependencyNodeDependencies(
+ tokenSignature,
+ unprefixedReferencedNames,
+ importPrefixes,
+ importPrefixedReferencedNames,
+ const [],
+ );
+ }
+
+ /// Return the signature for all tokens of the [node].
+ static List<int> _computeNodeTokenSignature(AstNode node) {
+ if (node == null) {
+ return const <int>[];
+ }
+ return _computeTokenSignature(node.beginToken, node.endToken);
+ }
+
+ /// Return the signature for tokens from [begin] to [end] (both including).
+ static List<int> _computeTokenSignature(Token begin, Token end) {
+ var signature = ApiSignature();
+ _appendTokens(signature, begin, end);
+ return signature.toByteList();
+ }
+
+ /// Return [Combinator]s for the given import or export [directive].
+ static List<Combinator> _getCombinators(NamespaceDirective directive) {
+ var combinators = <Combinator>[];
+ for (var combinator in directive.combinators) {
+ if (combinator is ShowCombinator) {
+ combinators.add(
+ Combinator(
+ true,
+ combinator.shownNames.map((id) => id.name).toList(),
+ ),
+ );
+ }
+ if (combinator is HideCombinator) {
+ combinators.add(
+ Combinator(
+ false,
+ combinator.hiddenNames.map((id) => id.name).toList(),
+ ),
+ );
+ }
+ }
+ return combinators;
+ }
+}
diff --git a/pkg/analyzer/lib/src/dart/analysis/dependency/node.dart b/pkg/analyzer/lib/src/dart/analysis/dependency/node.dart
new file mode 100644
index 0000000..e3de954
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/analysis/dependency/node.dart
@@ -0,0 +1,248 @@
+// Copyright (c) 2018, 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:typed_data';
+
+import 'package:analyzer/src/generated/utilities_general.dart';
+import 'package:convert/convert.dart';
+
+/// The reference to a class member.
+class ClassMemberReference {
+ /// The target class name.
+ ///
+ /// This is different from the class that actually turned out to define
+ /// the referenced member at the time of recording this reference. So, we
+ /// will notice added overrides in the target class, or anywhere in between.
+ final DependencyName target;
+
+ /// Whether the explicit `super` was used as the target.
+ /// The [target] is the enclosing class.
+ final bool targetSuper;
+
+ /// The name referenced in the [target].
+ final String name;
+
+ @override
+ final int hashCode;
+
+ ClassMemberReference(this.target, this.targetSuper, this.name)
+ : hashCode = JenkinsSmiHash.hash2(target.hashCode, name.hashCode);
+
+ @override
+ bool operator ==(other) {
+ return other is ClassMemberReference &&
+ other.target == target &&
+ other.targetSuper == targetSuper &&
+ other.name == name;
+ }
+
+ @override
+ String toString() {
+ return '($target, $name, super: $targetSuper)';
+ }
+
+ static int compare(ClassMemberReference first, ClassMemberReference second) {
+ var result = DependencyName.compare(first.target, second.target);
+ if (result != 0) return result;
+
+ if (first.targetSuper && !second.targetSuper) return -1;
+ if (!first.targetSuper && second.targetSuper) return 1;
+
+ return first.name.compareTo(second.name);
+ }
+}
+
+/// A name qualified by a library URI.
+class DependencyName {
+ /// The URI of the defining library.
+ /// Not `null`.
+ final Uri libraryUri;
+
+ /// The name of this name object.
+ /// If the name starts with `_`, then the name is private.
+ /// Names of setters end with `=`.
+ final String name;
+
+ /// Whether this name is private, and its [name] starts with `_`.
+ final bool isPrivate;
+
+ /// The cached, pre-computed hash code.
+ @override
+ final int hashCode;
+
+ factory DependencyName(Uri libraryUri, String name) {
+ var isPrivate = name.startsWith('_');
+ var hashCode = JenkinsSmiHash.hash2(libraryUri.hashCode, name.hashCode);
+ return DependencyName._internal(libraryUri, name, isPrivate, hashCode);
+ }
+
+ DependencyName._internal(
+ this.libraryUri, this.name, this.isPrivate, this.hashCode);
+
+ @override
+ bool operator ==(Object other) {
+ return other is DependencyName &&
+ other.hashCode == hashCode &&
+ name == other.name &&
+ libraryUri == other.libraryUri;
+ }
+
+ /// Whether this name us accessible for the library with the given
+ /// [libraryUri], i.e. when the name is public, or is defined in a library
+ /// with the same URI.
+ bool isAccessibleFor(Uri libraryUri) {
+ return !isPrivate || this.libraryUri == libraryUri;
+ }
+
+ @override
+ String toString() => '$libraryUri::$name';
+
+ /// Compare given names by their raw names.
+ ///
+ /// This method should be used only for sorting, it does not follow the
+ /// complete semantics of [==] and [hashCode].
+ static int compare(DependencyName first, DependencyName second) {
+ return first.name.compareTo(second.name);
+ }
+}
+
+/// A dependency node - anything that has a name, and can be referenced.
+class DependencyNode {
+ /// The API or implementation signature used in [DependencyNodeDependencies]
+ /// as a marker that this node is changed, explicitly because its token
+ /// signature changed, or implicitly - because it references a changed node.
+ static final changedSignature = Uint8List.fromList([0xDE, 0xAD, 0xBE, 0xEF]);
+
+ final DependencyName name;
+ final DependencyNodeKind kind;
+
+ /// Dependencies that affect the API of the node, so affect API or
+ /// implementation dependencies of the nodes that use this node.
+ final DependencyNodeDependencies api;
+
+ /// Additional (to the [api]) dependencies that affect only the
+ /// "implementation" of the node, e.g. the body of a method, but are not
+ /// visible outside of the node, and so don't affect any other nodes.
+ final DependencyNodeDependencies impl;
+
+ /// If the node is a class member, the node of the enclosing class.
+ /// Otherwise `null`.
+ final DependencyNode enclosingClass;
+
+ /// If the node is a class, the nodes of its type parameters.
+ /// Otherwise `null`.
+ final List<DependencyNode> classTypeParameters;
+
+ /// If the node is a class, the sorted list of members in this class.
+ /// Otherwise `null`.
+ List<DependencyNode> classMembers;
+
+ DependencyNode(
+ this.name,
+ this.kind,
+ this.api,
+ this.impl, {
+ this.enclosingClass,
+ this.classTypeParameters,
+ });
+
+ /// Return the node that can be referenced by the given [name] from the
+ /// library with the given [libraryUri].
+ DependencyNode getClassMember(Uri libraryUri, String name) {
+ // TODO(scheglov) The list is sorted, use this fact to search faster.
+ // TODO(scheglov) Collect superclass members here or outside.
+ for (var i = 0; i < classMembers.length; ++i) {
+ var member = classMembers[i];
+ var memberName = member.name;
+ if (memberName.name == name && memberName.isAccessibleFor(libraryUri)) {
+ return member;
+ }
+ }
+ return null;
+ }
+
+ /// Set new class members for this class.
+ void setClassMembers(List<DependencyNode> newClassMembers) {
+ classMembers = newClassMembers;
+ }
+
+ @override
+ String toString() {
+ if (enclosingClass != null) {
+ return '$enclosingClass::${name.name}';
+ }
+ return name.toString();
+ }
+
+ /// Compare given nodes by their names.
+ static int compare(DependencyNode first, DependencyNode second) {
+ return DependencyName.compare(first.name, second.name);
+ }
+}
+
+/// The dependencies of the API or implementation portion of a node.
+class DependencyNodeDependencies {
+ static final none = DependencyNodeDependencies([], [], [], [], []);
+
+ /// The token signature of this portion of the node. It depends on all
+ /// tokens that might affect the node API or implementation resolution.
+ final List<int> tokenSignature;
+
+ /// The names that appear unprefixed in this portion of the node, and are
+ /// not defined locally in the node. Locally defined names themselves
+ /// depend on some non-local nodes, which will also recorded here.
+ ///
+ /// This list is sorted.
+ final List<String> unprefixedReferencedNames;
+
+ /// The names of import prefixes used to reference names in this node.
+ ///
+ /// This list is sorted.
+ final List<String> importPrefixes;
+
+ /// The names referenced by this node with the import prefix at the
+ /// corresponding index in [importPrefixes].
+ ///
+ /// This list is sorted.
+ final List<List<String>> importPrefixedReferencedNames;
+
+ /// The class members referenced in this portion of the node.
+ ///
+ /// This list is sorted.
+ final List<ClassMemberReference> classMemberReferences;
+
+ /// All referenced nodes, computed from [unprefixedReferencedNames],
+ /// [importPrefixedReferencedNames], and [classMemberReferences].
+ List<DependencyNode> referencedNodes;
+
+ /// The transitive signature of this portion of the node, computed using
+ /// the [tokenSignature] of this node, and API signatures of the
+ /// [referencedNodes].
+ List<int> transitiveSignature;
+
+ DependencyNodeDependencies(
+ this.tokenSignature,
+ this.unprefixedReferencedNames,
+ this.importPrefixes,
+ this.importPrefixedReferencedNames,
+ this.classMemberReferences);
+
+ String get tokenSignatureHex => hex.encode(tokenSignature);
+}
+
+/// Kinds of nodes.
+enum DependencyNodeKind {
+ CLASS,
+ CLASS_TYPE_ALIAS,
+ CONSTRUCTOR,
+ ENUM,
+ FUNCTION,
+ FUNCTION_TYPE_ALIAS,
+ GENERIC_TYPE_ALIAS,
+ GETTER,
+ METHOD,
+ MIXIN,
+ SETTER,
+ TYPE_PARAMETER,
+}
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 6f2d3ec..a1cc939 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -6,13 +6,12 @@
import 'dart:collection';
import 'dart:typed_data';
+import 'package:analyzer/dart/analysis/analysis_context.dart' as api;
import 'package:analyzer/dart/analysis/declared_variables.dart';
-import 'package:analyzer/dart/analysis/results.dart' as results;
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/element/element.dart'
- show CompilationUnitElement, LibraryElement;
+import 'package:analyzer/dart/element/element.dart' show LibraryElement;
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/exception/exception.dart';
@@ -145,11 +144,6 @@
AnalysisOptionsImpl _analysisOptions;
/**
- * The optional SDK bundle, used when the client cannot read SDK files.
- */
- final PackageBundle _sdkBundle;
-
- /**
* The [SourceFactory] is used to resolve URIs to paths and restore URIs
* from file paths.
*/
@@ -166,16 +160,21 @@
final ContextRoot contextRoot;
/**
+ * The analysis context that created this driver / session.
+ */
+ api.AnalysisContext analysisContext;
+
+ /**
* The salt to mix into all hashes used as keys for unlinked data.
*/
final Uint32List _unlinkedSalt =
- new Uint32List(1 + AnalysisOptionsImpl.unlinkedSignatureLength);
+ new Uint32List(2 + AnalysisOptionsImpl.unlinkedSignatureLength);
/**
* The salt to mix into all hashes used as keys for linked data.
*/
final Uint32List _linkedSalt =
- new Uint32List(1 + AnalysisOptions.signatureLength);
+ new Uint32List(2 + AnalysisOptions.signatureLength);
/**
* The set of priority files, that should be analyzed sooner.
@@ -186,7 +185,7 @@
* The mapping from the files for which analysis was requested using
* [getResult] to the [Completer]s to report the result.
*/
- final _requestedFiles = <String, List<Completer<AnalysisResult>>>{};
+ final _requestedFiles = <String, List<Completer<ResolvedUnitResult>>>{};
/**
* The mapping from the files for which analysis was requested using
@@ -257,7 +256,7 @@
* [getResult], and which were found to be parts without known libraries,
* to the [Completer]s to report the result.
*/
- final _requestedParts = <String, List<Completer<AnalysisResult>>>{};
+ final _requestedParts = <String, List<Completer<ResolvedUnitResult>>>{};
/**
* The set of part files that are currently scheduled for analysis.
@@ -267,12 +266,12 @@
/**
* The controller for the [results] stream.
*/
- final _resultController = new StreamController<AnalysisResult>();
+ final _resultController = new StreamController<ResolvedUnitResult>();
/**
* The stream that will be written to when analysis results are produced.
*/
- Stream<AnalysisResult> _onResults;
+ Stream<ResolvedUnitResult> _onResults;
/**
* Resolution signatures of the most recently produced results for files.
@@ -282,7 +281,7 @@
/**
* Cached results for [_priorityFiles].
*/
- final Map<String, AnalysisResult> _priorityResults = {};
+ final Map<String, ResolvedUnitResult> _priorityResults = {};
/**
* The controller for the [exceptions] stream.
@@ -323,6 +322,11 @@
final bool disableChangesAndCacheAllResults;
/**
+ * Whether resolved units should be indexed.
+ */
+ final bool enableIndex;
+
+ /**
* The cache to use with [disableChangesAndCacheAllResults].
*/
final Map<String, AnalysisResult> _allCachedResults = {};
@@ -333,6 +337,13 @@
AnalysisSessionImpl _currentSession;
/**
+ * The current library context, consistent with the [_currentSession].
+ *
+ * TODO(scheglov) We probably should tie it into the session.
+ */
+ LibraryContext _libraryContext;
+
+ /**
* Create a new instance of [AnalysisDriver].
*
* The given [SourceFactory] is cloned to ensure that it does not contain a
@@ -347,12 +358,11 @@
this.contextRoot,
SourceFactory sourceFactory,
this._analysisOptions,
- {PackageBundle sdkBundle,
- this.disableChangesAndCacheAllResults: false,
+ {this.disableChangesAndCacheAllResults: false,
+ this.enableIndex: false,
SummaryDataStore externalSummaries})
: _logger = logger,
_sourceFactory = sourceFactory.clone(),
- _sdkBundle = sdkBundle,
_externalSummaries = externalSummaries {
_createNewSession();
_onResults = _resultController.stream.asBroadcastStream();
@@ -456,7 +466,7 @@
* Results might be produced even for files that have never been added
* using [addFile], for example when [getResult] was called for a file.
*/
- Stream<AnalysisResult> get results => _onResults;
+ Stream<ResolvedUnitResult> get results => _onResults;
/**
* Return the search support for the driver.
@@ -528,6 +538,7 @@
_unitElementRequestedParts.isNotEmpty) {
return AnalysisDriverPriority.general;
}
+ _libraryContext = null;
return AnalysisDriverPriority.nothing;
}
@@ -539,13 +550,7 @@
}
if (AnalysisEngine.isDartFileName(path)) {
_fileTracker.addFile(path);
- // If the file is known, it has already been read, even if it did not
- // exist. Now we are notified that the file exists, so we need to
- // re-read it and make sure that we invalidate signature of the files
- // that reference it.
- if (_fsState.knownFilePaths.contains(path)) {
- _changeFile(path);
- }
+ _changeFile(path);
}
}
@@ -613,17 +618,17 @@
}
/**
- * Return the cached [AnalysisResult] for the Dart file with the given [path].
- * If there is no cached result, return `null`. Usually only results of
- * priority files are cached.
+ * Return the cached [ResolvedUnitResult] for the Dart file with the given
+ * [path]. If there is no cached result, return `null`. Usually only results
+ * of priority files are cached.
*
* The [path] must be absolute and normalized.
*
* The [path] can be any file - explicitly or implicitly analyzed, or neither.
*/
- AnalysisResult getCachedResult(String path) {
+ ResolvedUnitResult getCachedResult(String path) {
_throwIfNotAbsolutePath(path);
- AnalysisResult result = _priorityResults[path];
+ ResolvedUnitResult result = _priorityResults[path];
if (disableChangesAndCacheAllResults) {
result ??= _allCachedResults[path];
}
@@ -647,13 +652,7 @@
// Ask the analysis result without unit, so return cached errors.
// If no cached analysis result, it will be computed.
- AnalysisResult analysisResult = await _computeAnalysisResult(path);
-
- // Check for asynchronous changes during computing the result.
- await _runTestAsyncWorkDuringAnalysis(path);
- if (_fileTracker.hasChangedFiles) {
- analysisResult = null;
- }
+ ResolvedUnitResult analysisResult = _computeAnalysisResult(path);
// If not computed yet, because a part file without a known library,
// we have to compute the full analysis result, with the unit.
@@ -662,7 +661,7 @@
return null;
}
- return new ErrorsResult(currentSession, path, analysisResult.uri,
+ return new ErrorsResultImpl(currentSession, path, analysisResult.uri,
analysisResult.lineInfo, analysisResult.isPart, analysisResult.errors);
}
@@ -698,7 +697,7 @@
FileResult getFileSync(String path) {
_throwIfNotAbsolutePath(path);
FileState file = _fileTracker.verifyApiSignature(path);
- return new FileResult(
+ return new FileResultImpl(
_currentSession, path, file.uri, file.lineInfo, file.isPart);
}
@@ -709,6 +708,9 @@
*/
Future<AnalysisDriverUnitIndex> getIndex(String path) {
_throwIfNotAbsolutePath(path);
+ if (!enableIndex) {
+ throw new ArgumentError('Indexing is not enabled.');
+ }
if (!_fsState.hasUri(path)) {
return new Future.value();
}
@@ -724,20 +726,78 @@
* Return a [Future] that completes with the [LibraryElement] for the given
* [uri], which is either resynthesized from the provided external summary
* store, or built for a file to which the given [uri] is resolved.
+ *
+ * Throw [ArgumentError] if the [uri] corresponds to a part.
*/
Future<LibraryElement> getLibraryByUri(String uri) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
- if (_externalSummaries != null && _externalSummaries.hasUnlinkedUnit(uri)) {
- return LibraryContext.resynthesizeLibraryElement(analysisOptions,
- declaredVariables, sourceFactory, _externalSummaries, uri);
+ var uriObj = Uri.parse(uri);
+ var file = _fsState.getFileForUri(uriObj);
+
+ if (file.isExternalLibrary) {
+ return _createLibraryContext(file).getLibraryElement(file);
}
- Source source = sourceFactory.resolveUri(null, uri);
- UnitElementResult unitResult = await getUnitElement(source.fullName);
+
+ if (file.isPart) {
+ throw ArgumentError('$uri is not a library.');
+ }
+
+ UnitElementResult unitResult = await getUnitElement(file.path);
return unitResult.element.library;
}
/**
+ * Return a [ParsedLibraryResult] for the library with the given [path].
+ *
+ * Throw [ArgumentError] if the given [path] is not the defining compilation
+ * unit for a library (that is, is a part of a library).
+ *
+ * The [path] must be absolute and normalized.
+ */
+ ParsedLibraryResult getParsedLibrary(String path) {
+ FileState file = _fsState.getFileForPath(path);
+
+ if (file.isExternalLibrary) {
+ return ParsedLibraryResultImpl.external(currentSession, file.uri);
+ }
+
+ if (file.isPart) {
+ throw ArgumentError('Is a part: $path');
+ }
+
+ var units = <ParsedUnitResult>[];
+ for (var unitFile in file.libraryFiles) {
+ var unitPath = unitFile.path;
+ if (unitPath != null) {
+ var unitResult = parseFileSync(unitPath);
+ units.add(unitResult);
+ }
+ }
+
+ return ParsedLibraryResultImpl(currentSession, path, file.uri, units);
+ }
+
+ /**
+ * Return a [ParsedLibraryResult] for the library with the given [uri].
+ *
+ * Throw [ArgumentError] if the given [uri] is not the defining compilation
+ * unit for a library (that is, is a part of a library).
+ */
+ ParsedLibraryResult getParsedLibraryByUri(Uri uri) {
+ FileState file = _fsState.getFileForUri(uri);
+
+ if (file.isExternalLibrary) {
+ return ParsedLibraryResultImpl.external(currentSession, file.uri);
+ }
+
+ if (file.isPart) {
+ throw ArgumentError('Is a part: $uri');
+ }
+
+ // The file is a local file, we can get the result.
+ return getParsedLibrary(file.path);
+ }
+
+ /**
* Return a [Future] that completes with a [ResolvedLibraryResult] for the
* Dart library file with the given [path]. If the file is not a Dart file
* or cannot be analyzed, the [Future] completes with `null`.
@@ -823,7 +883,7 @@
}
/**
- * Return a [Future] that completes with a [AnalysisResult] for the Dart
+ * Return a [Future] that completes with a [ResolvedUnitResult] for the Dart
* file with the given [path]. If the file is not a Dart file or cannot
* be analyzed, the [Future] completes with `null`.
*
@@ -841,7 +901,7 @@
* of the files previously reported using [changeFile]), prior to the next
* time the analysis state transitions to "idle".
*/
- Future<AnalysisResult> getResult(String path,
+ Future<ResolvedUnitResult> getResult(String path,
{bool sendCachedToStream: false}) {
_throwIfNotAbsolutePath(path);
if (!_fsState.hasUri(path)) {
@@ -850,7 +910,7 @@
// Return the cached result.
{
- AnalysisResult result = getCachedResult(path);
+ ResolvedUnitResult result = getCachedResult(path);
if (result != null) {
if (sendCachedToStream) {
_resultController.add(result);
@@ -860,9 +920,9 @@
}
// Schedule analysis.
- var completer = new Completer<AnalysisResult>();
+ var completer = new Completer<ResolvedUnitResult>();
_requestedFiles
- .putIfAbsent(path, () => <Completer<AnalysisResult>>[])
+ .putIfAbsent(path, () => <Completer<ResolvedUnitResult>>[])
.add(completer);
_scheduler.notify(this);
return completer.future;
@@ -959,17 +1019,11 @@
* not a part, so it must be a library.
*/
bool isLibraryByUri(Uri uri) {
- if (_externalSummaries != null) {
- var uriStr = uri.toString();
- if (_externalSummaries.unlinkedMap[uriStr] != null) {
- return _externalSummaries.linkedMap.containsKey(uriStr);
- }
- }
return !_fsState.getFileForUri(uri).isPart;
}
/**
- * Return a [Future] that completes with a [ParseResult] for the file
+ * Return a [Future] that completes with a [ParsedUnitResult] for the file
* with the given [path].
*
* The [path] must be absolute and normalized.
@@ -980,14 +1034,14 @@
* produced through the [results] stream (just because it is not a fully
* resolved unit).
*/
- Future<ParseResult> parseFile(String path) async {
+ Future<ParsedUnitResult> parseFile(String path) async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
return parseFileSync(path);
}
/**
- * Return a [ParseResult] for the file with the given [path].
+ * Return a [ParsedUnitResult] for the file with the given [path].
*
* The [path] must be absolute and normalized.
*
@@ -997,13 +1051,13 @@
* produced through the [results] stream (just because it is not a fully
* resolved unit).
*/
- ParseResult parseFileSync(String path) {
+ ParsedUnitResult parseFileSync(String path) {
_throwIfNotAbsolutePath(path);
FileState file = _fileTracker.verifyApiSignature(path);
RecordingErrorListener listener = new RecordingErrorListener();
CompilationUnit unit = file.parse(listener);
- return new ParseResult(currentSession, file.path, file.uri, file.content,
- file.lineInfo, file.isPart, unit, listener.errors);
+ return new ParsedUnitResultImpl(currentSession, file.path, file.uri,
+ file.content, file.lineInfo, file.isPart, unit, listener.errors);
}
@override
@@ -1018,13 +1072,7 @@
if (_requestedFiles.isNotEmpty) {
String path = _requestedFiles.keys.first;
try {
- AnalysisResult result =
- await _computeAnalysisResult(path, withUnit: true);
- // Check for asynchronous changes during computing the result.
- await _runTestAsyncWorkDuringAnalysis(path);
- if (_fileTracker.hasChangedFiles) {
- return;
- }
+ AnalysisResult result = _computeAnalysisResult(path, withUnit: true);
// If a part without a library, delay its analysis.
if (result == null) {
_requestedParts
@@ -1067,7 +1115,7 @@
// Process an index request.
if (_indexRequestedFiles.isNotEmpty) {
String path = _indexRequestedFiles.keys.first;
- AnalysisDriverUnitIndex index = await _computeIndex(path);
+ AnalysisDriverUnitIndex index = _computeIndex(path);
_indexRequestedFiles.remove(path).forEach((completer) {
completer.complete(index);
});
@@ -1094,7 +1142,7 @@
// Process a unit element request.
if (_unitElementRequestedFiles.isNotEmpty) {
String path = _unitElementRequestedFiles.keys.first;
- UnitElementResult result = await _computeUnitElement(path);
+ UnitElementResult result = _computeUnitElement(path);
var completers = _unitElementRequestedFiles.remove(path);
if (result != null) {
completers.forEach((completer) {
@@ -1152,8 +1200,7 @@
if (_fileTracker.isFilePending(path)) {
try {
AnalysisResult result =
- await _computeAnalysisResult(path, withUnit: true);
- await _runTestAsyncWorkDuringAnalysis(path);
+ _computeAnalysisResult(path, withUnit: true);
if (result == null) {
_partsToAnalyze.add(path);
} else {
@@ -1173,9 +1220,8 @@
if (_fileTracker.hasPendingFiles) {
String path = _fileTracker.anyPendingFile;
try {
- AnalysisResult result = await _computeAnalysisResult(path,
+ AnalysisResult result = _computeAnalysisResult(path,
withUnit: false, skipIfSameSignature: true);
- await _runTestAsyncWorkDuringAnalysis(path);
if (result == null) {
_partsToAnalyze.add(path);
} else if (result == AnalysisResult._UNCHANGED) {
@@ -1197,12 +1243,8 @@
if (_requestedParts.isNotEmpty) {
String path = _requestedParts.keys.first;
try {
- AnalysisResult result = await _computeAnalysisResult(path,
+ AnalysisResult result = _computeAnalysisResult(path,
withUnit: true, asIsIfPartWithoutLibrary: true);
- // Check for asynchronous changes during computing the result.
- if (_fileTracker.hasChangedFiles) {
- return;
- }
// Notify the completers.
_requestedParts.remove(path).forEach((completer) {
completer.complete(result);
@@ -1224,7 +1266,7 @@
String path = _partsToAnalyze.first;
_partsToAnalyze.remove(path);
try {
- AnalysisResult result = await _computeAnalysisResult(path,
+ AnalysisResult result = _computeAnalysisResult(path,
withUnit: _priorityFiles.contains(path),
asIsIfPartWithoutLibrary: true);
_resultController.add(result);
@@ -1237,7 +1279,7 @@
// Process a unit element signature request for a part.
if (_unitElementSignatureParts.isNotEmpty) {
String path = _unitElementSignatureParts.keys.first;
- var signature =
+ String signature =
_computeUnitElementSignature(path, asIsIfPartWithoutLibrary: true);
_unitElementSignatureParts.remove(path).forEach((completer) {
completer.complete(signature);
@@ -1249,7 +1291,7 @@
if (_unitElementRequestedParts.isNotEmpty) {
String path = _unitElementRequestedParts.keys.first;
UnitElementResult result =
- await _computeUnitElement(path, asIsIfPartWithoutLibrary: true);
+ _computeUnitElement(path, asIsIfPartWithoutLibrary: true);
_unitElementRequestedParts.remove(path).forEach((completer) {
completer.complete(result);
});
@@ -1270,6 +1312,7 @@
_throwIfNotAbsolutePath(path);
_throwIfChangesAreNotAllowed();
_fileTracker.removeFile(path);
+ _libraryContext = null;
_priorityResults.clear();
}
@@ -1277,8 +1320,15 @@
* Implementation for [changeFile].
*/
void _changeFile(String path) {
- _fileTracker.changeFile(path);
- _priorityResults.clear();
+ // If the file is known, it has already been read, even if it din't exist.
+ // Now we are notified that the file changed (just changed or added), so we
+ // need to re-read it and make sure that we invalidate signature of the
+ // files that reference it.
+ if (_fsState.knownFilePaths.contains(path)) {
+ _fileTracker.changeFile(path);
+ _libraryContext = null;
+ _priorityResults.clear();
+ }
}
/**
@@ -1287,6 +1337,7 @@
*/
void _changeHook() {
_createNewSession();
+ _libraryContext = null;
_priorityResults.clear();
_scheduler.notify(this);
}
@@ -1306,12 +1357,10 @@
* the resolved signature of the file in its library is the same as the one
* that was the most recently produced to the client.
*/
- Future<AnalysisResult> _computeAnalysisResult(String path,
+ AnalysisResult _computeAnalysisResult(String path,
{bool withUnit: false,
bool asIsIfPartWithoutLibrary: false,
- bool skipIfSameSignature: false}) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
+ bool skipIfSameSignature: false}) {
FileState file = _fsState.getFileForPath(path);
// Prepare the library - the file itself, or the known library.
@@ -1347,67 +1396,60 @@
}
// We need the fully resolved unit, or the result is not cached.
- return _logger.runAsync('Compute analysis result for $path', () async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
+ return _logger.run('Compute analysis result for $path', () {
try {
- LibraryContext libraryContext;
- try {
- _testView.numOfAnalyzedLibraries++;
+ _testView.numOfAnalyzedLibraries++;
- if (!_fsState.getFileForUri(Uri.parse('dart:core')).exists) {
- return _newMissingDartLibraryResult(file, 'dart:core');
- }
- if (!_fsState.getFileForUri(Uri.parse('dart:async')).exists) {
- return _newMissingDartLibraryResult(file, 'dart:async');
- }
- libraryContext = _createLibraryContext(library);
-
- LibraryAnalyzer analyzer = new LibraryAnalyzer(
- analysisOptions,
- declaredVariables,
- sourceFactory,
- libraryContext.isLibraryUri,
- libraryContext.analysisContext,
- libraryContext.resynthesizer,
- library,
- _resourceProvider);
- Map<FileState, UnitAnalysisResult> results = analyzer.analyze();
-
- List<int> bytes;
- CompilationUnit resolvedUnit;
- for (FileState unitFile in results.keys) {
- UnitAnalysisResult unitResult = results[unitFile];
- List<int> unitBytes =
- _serializeResolvedUnit(unitResult.unit, unitResult.errors);
- String unitSignature = _getResolvedUnitSignature(library, unitFile);
- String unitKey = _getResolvedUnitKey(unitSignature);
- _byteStore.put(unitKey, unitBytes);
- if (unitFile == file) {
- bytes = unitBytes;
- resolvedUnit = unitResult.unit;
- }
- if (disableChangesAndCacheAllResults) {
- AnalysisResult result = _getAnalysisResultFromBytes(
- unitFile, unitSignature, unitBytes,
- content: unitFile.content, resolvedUnit: unitResult.unit);
- _allCachedResults[unitFile.path] = result;
- }
- }
-
- // Return the result, full or partial.
- _logger.writeln('Computed new analysis result.');
- AnalysisResult result = _getAnalysisResultFromBytes(
- file, signature, bytes,
- content: withUnit ? file.content : null,
- resolvedUnit: withUnit ? resolvedUnit : null);
- if (withUnit && _priorityFiles.contains(path)) {
- _priorityResults[path] = result;
- }
- return result;
- } finally {
- libraryContext?.dispose();
+ if (!_fsState.getFileForUri(Uri.parse('dart:core')).exists) {
+ return _newMissingDartLibraryResult(file, 'dart:core');
}
+ if (!_fsState.getFileForUri(Uri.parse('dart:async')).exists) {
+ return _newMissingDartLibraryResult(file, 'dart:async');
+ }
+ var libraryContext = _createLibraryContext(library);
+
+ LibraryAnalyzer analyzer = new LibraryAnalyzer(
+ analysisOptions,
+ declaredVariables,
+ sourceFactory,
+ libraryContext.isLibraryUri,
+ libraryContext.analysisContext,
+ libraryContext.resynthesizer,
+ libraryContext.inheritanceManager,
+ library);
+ Map<FileState, UnitAnalysisResult> results = analyzer.analyze();
+
+ List<int> bytes;
+ CompilationUnit resolvedUnit;
+ for (FileState unitFile in results.keys) {
+ UnitAnalysisResult unitResult = results[unitFile];
+ List<int> unitBytes =
+ _serializeResolvedUnit(unitResult.unit, unitResult.errors);
+ String unitSignature = _getResolvedUnitSignature(library, unitFile);
+ String unitKey = _getResolvedUnitKey(unitSignature);
+ _byteStore.put(unitKey, unitBytes);
+ if (unitFile == file) {
+ bytes = unitBytes;
+ resolvedUnit = unitResult.unit;
+ }
+ if (disableChangesAndCacheAllResults) {
+ AnalysisResult result = _getAnalysisResultFromBytes(
+ unitFile, unitSignature, unitBytes,
+ content: unitFile.content, resolvedUnit: unitResult.unit);
+ _allCachedResults[unitFile.path] = result;
+ }
+ }
+
+ // Return the result, full or partial.
+ _logger.writeln('Computed new analysis result.');
+ AnalysisResult result = _getAnalysisResultFromBytes(
+ file, signature, bytes,
+ content: withUnit ? file.content : null,
+ resolvedUnit: withUnit ? resolvedUnit : null);
+ if (withUnit && _priorityFiles.contains(path)) {
+ _priorityResults[path] = result;
+ }
+ return result;
} catch (exception, stackTrace) {
String contextKey =
_storeExceptionContext(path, library, exception, stackTrace);
@@ -1416,10 +1458,8 @@
});
}
- Future<AnalysisDriverUnitIndex> _computeIndex(String path) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
- AnalysisResult analysisResult = await _computeAnalysisResult(path,
+ AnalysisDriverUnitIndex _computeIndex(String path) {
+ AnalysisResult analysisResult = _computeAnalysisResult(path,
withUnit: false, asIsIfPartWithoutLibrary: true);
return analysisResult._index;
}
@@ -1442,8 +1482,8 @@
libraryContext.isLibraryUri,
libraryContext.analysisContext,
libraryContext.resynthesizer,
- library,
- _resourceProvider);
+ libraryContext.inheritanceManager,
+ library);
Map<FileState, UnitAnalysisResult> unitResults = analyzer.analyze();
var resolvedUnits = <ResolvedUnitResult>[];
@@ -1452,7 +1492,7 @@
var unitResult = unitResults[unitFile];
resolvedUnits.add(
new AnalysisResult(
- this,
+ currentSession,
_sourceFactory,
unitFile.path,
unitFile.uri,
@@ -1474,16 +1514,14 @@
library.path,
library.uri,
resolvedUnits.first.libraryElement,
- libraryContext.analysisContext.typeProvider,
+ libraryContext.typeProvider,
resolvedUnits,
);
});
}
- Future<UnitElementResult> _computeUnitElement(String path,
- {bool asIsIfPartWithoutLibrary: false}) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
+ UnitElementResult _computeUnitElement(String path,
+ {bool asIsIfPartWithoutLibrary: false}) {
FileState file = _fsState.getFileForPath(path);
// Prepare the library - the file itself, or the known library.
@@ -1496,16 +1534,10 @@
}
}
- LibraryContext libraryContext = _createLibraryContext(library);
- try {
- CompilationUnitElement element =
- libraryContext.computeUnitElement(library.source, file.source);
- String signature = library.transitiveSignature;
- return new UnitElementResult(
- currentSession, path, file.uri, signature, element);
- } finally {
- libraryContext.dispose();
- }
+ var libraryContext = _createLibraryContext(library);
+ var element = libraryContext.computeUnitElement(library, file);
+ return new UnitElementResultImpl(
+ currentSession, path, file.uri, library.transitiveSignature, element);
}
String _computeUnitElementSignature(String path,
@@ -1551,17 +1583,28 @@
* Return the context in which the [library] should be analyzed.
*/
LibraryContext _createLibraryContext(FileState library) {
- _testView.numOfCreatedLibraryContexts++;
- return new LibraryContext.forSingleLibrary(
- library,
- _logger,
- _sdkBundle,
- _byteStore,
- _analysisOptions,
- declaredVariables,
- _sourceFactory,
- _externalSummaries,
- fsState);
+ if (_libraryContext != null) {
+ if (_libraryContext.pack()) {
+ _libraryContext = null;
+ }
+ }
+
+ if (_libraryContext == null) {
+ _libraryContext = new LibraryContext(
+ session: currentSession,
+ logger: _logger,
+ fsState: fsState,
+ byteStore: _byteStore,
+ analysisOptions: _analysisOptions,
+ declaredVariables: declaredVariables,
+ sourceFactory: _sourceFactory,
+ externalSummaries: _externalSummaries,
+ targetLibrary: library,
+ );
+ } else {
+ _libraryContext.load(library);
+ }
+ return _libraryContext;
}
/**
@@ -1584,10 +1627,12 @@
*/
void _fillSalt() {
_unlinkedSalt[0] = DATA_VERSION;
- _unlinkedSalt.setAll(1, _analysisOptions.unlinkedSignature);
+ _unlinkedSalt[1] = enableIndex ? 1 : 0;
+ _unlinkedSalt.setAll(2, _analysisOptions.unlinkedSignature);
_linkedSalt[0] = DATA_VERSION;
- _linkedSalt.setAll(1, _analysisOptions.signature);
+ _linkedSalt[1] = enableIndex ? 1 : 0;
+ _linkedSalt.setAll(2, _analysisOptions.signature);
}
/**
@@ -1601,7 +1646,7 @@
List<AnalysisError> errors = _getErrorsFromSerialized(file, unit.errors);
_updateHasErrorOrWarningFlag(file, errors);
return new AnalysisResult(
- this,
+ currentSession,
_sourceFactory,
file.path,
file.uri,
@@ -1691,7 +1736,7 @@
FileState file, String missingUri) {
// TODO(scheglov) Find a better way to report this.
return new AnalysisResult(
- this,
+ currentSession,
_sourceFactory,
file.path,
file.uri,
@@ -1721,26 +1766,13 @@
}
/**
- * Runs any asynchronous work that was injected as part of a test using
- * [AnalysisDriverTestView.workToWaitAfterComputingResult].
- *
- * If the test view indicates that there is work to do, performs the work
- * and returns a [Future] that will be signaled when the work completes.
- *
- * This gives tests a reliable way to simulate file changes during analysis.
- */
- Future _runTestAsyncWorkDuringAnalysis(String path) {
- var work = _testView.workToWaitAfterComputingResult;
- _testView.workToWaitAfterComputingResult = null;
- return work != null ? work(path) : new Future.value();
- }
-
- /**
* Serialize the given [resolvedUnit] errors and index into bytes.
*/
List<int> _serializeResolvedUnit(
CompilationUnit resolvedUnit, List<AnalysisError> errors) {
- AnalysisDriverUnitIndexBuilder index = indexUnit(resolvedUnit);
+ AnalysisDriverUnitIndexBuilder index = enableIndex
+ ? indexUnit(resolvedUnit)
+ : new AnalysisDriverUnitIndexBuilder();
return new AnalysisDriverResolvedUnitBuilder(
errors: errors
.map((error) => new AnalysisDriverUnitErrorBuilder(
@@ -1763,7 +1795,7 @@
}
try {
List<AnalysisDriverExceptionFileBuilder> contextFiles = libraryFile
- .transitiveFiles
+ .libraryFiles
.map((file) => new AnalysisDriverExceptionFileBuilder(
path: file.path, content: file.content))
.toList();
@@ -2092,34 +2124,20 @@
class AnalysisDriverTestView {
final AnalysisDriver driver;
- int numOfCreatedLibraryContexts = 0;
-
int numOfAnalyzedLibraries = 0;
- /**
- * If non-null, a function that should be executed asynchronously after
- * the next result is computed.
- *
- * This can be used by a test to simulate file changes during analysis.
- */
- WorkToWaitAfterComputingResult workToWaitAfterComputingResult;
-
AnalysisDriverTestView(this.driver);
FileTracker get fileTracker => driver._fileTracker;
- Map<String, AnalysisResult> get priorityResults => driver._priorityResults;
+ Map<String, ResolvedUnitResult> get priorityResults {
+ return driver._priorityResults;
+ }
- Future<SummaryDataStore> getSummaryStore(String libraryPath) async {
+ SummaryDataStore getSummaryStore(String libraryPath) {
FileState library = driver.fsState.getFileForPath(libraryPath);
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
LibraryContext libraryContext = driver._createLibraryContext(library);
- try {
- return libraryContext.store;
- } finally {
- libraryContext.dispose();
- }
+ return libraryContext.store;
}
}
@@ -2134,88 +2152,52 @@
* Every result is independent, and is not guaranteed to be consistent with
* any previously returned result, even inside of the same library.
*/
-class AnalysisResult extends FileResult implements results.ResolvedUnitResult {
+class AnalysisResult extends ResolvedUnitResultImpl {
static final _UNCHANGED = new AnalysisResult(
null, null, null, null, null, null, null, null, null, null, null, null);
-
- /**
- * The [AnalysisDriver] that produced this result.
- */
- final AnalysisDriver driver;
-
/**
* The [SourceFactory] with which the file was analyzed.
*/
final SourceFactory sourceFactory;
/**
- * Return `true` if the file exists.
- */
- final bool exists;
-
- @override
- final String content;
-
- /**
* The signature of the result based on the content of the file, and the
* transitive closure of files imported and exported by the library of
* the requested file.
*/
final String _signature;
- @override
- final CompilationUnit unit;
-
- @override
- final List<AnalysisError> errors;
-
/**
* The index of the unit.
*/
final AnalysisDriverUnitIndex _index;
AnalysisResult(
- this.driver,
+ AnalysisSession session,
this.sourceFactory,
String path,
Uri uri,
- this.exists,
- this.content,
+ bool exists,
+ String content,
LineInfo lineInfo,
bool isPart,
this._signature,
- this.unit,
- this.errors,
+ CompilationUnit unit,
+ List<AnalysisError> errors,
this._index)
- : super(driver?.currentSession, path, uri, lineInfo, isPart);
+ : super(session, path, uri, exists, content, lineInfo, isPart, unit,
+ errors);
@override
LibraryElement get libraryElement => unit.declaredElement.library;
@override
- results.ResultState get state =>
- exists ? results.ResultState.VALID : results.ResultState.NOT_A_FILE;
-
- @override
TypeProvider get typeProvider => unit.declaredElement.context.typeProvider;
@override
TypeSystem get typeSystem => unit.declaredElement.context.typeSystem;
}
-abstract class BaseAnalysisResult implements results.AnalysisResult {
- @override
- final AnalysisSession session;
-
- @override
- final String path;
-
- @override
- final Uri uri;
-
- BaseAnalysisResult(this.session, this.path, this.uri);
-}
-
class DriverPerformance {
static final PerformanceTag driver =
PerformanceStatistics.analyzer.createChild('driver');
@@ -2242,25 +2224,6 @@
}
/**
- * The errors in a single file.
- *
- * These results are self-consistent, i.e. [errors] and [lineInfo] correspond
- * to each other. But none of the results is guaranteed to be consistent with
- * the state of the files.
- */
-class ErrorsResult extends FileResult implements results.ErrorsResult {
- @override
- final List<AnalysisError> errors;
-
- ErrorsResult(AnalysisSession session, String path, Uri uri, LineInfo lineInfo,
- bool isPart, this.errors)
- : super(session, path, uri, lineInfo, isPart);
-
- @override
- results.ResultState get state => results.ResultState.VALID;
-}
-
-/**
* Exception that happened during analysis.
*/
class ExceptionResult {
@@ -2288,83 +2251,6 @@
}
/**
- * The result of computing some cheap information for a single file, when full
- * parsed file is not required, so [ParseResult] is not necessary.
- */
-class FileResult extends BaseAnalysisResult implements results.FileResult {
- @override
- final LineInfo lineInfo;
-
- @override
- final bool isPart;
-
- FileResult(
- AnalysisSession session, String path, Uri uri, this.lineInfo, this.isPart)
- : super(session, path, uri);
-
- @override
- results.ResultState get state => results.ResultState.VALID;
-}
-
-/**
- * The result of parsing of a single file.
- *
- * These results are self-consistent, i.e. [content], [lineInfo], the
- * parsed [unit] correspond to each other. But none of the results is
- * guaranteed to be consistent with the state of the files.
- */
-class ParseResult extends FileResult implements results.ParseResult {
- @override
- final String content;
-
- @override
- final CompilationUnit unit;
-
- @override
- final List<AnalysisError> errors;
-
- ParseResult(AnalysisSession session, String path, Uri uri, this.content,
- LineInfo lineInfo, bool isPart, this.unit, this.errors)
- : super(session, path, uri, lineInfo, isPart);
-
- @override
- results.ResultState get state => results.ResultState.VALID;
-}
-
-/**
- * The result with the [CompilationUnitElement] of a single file.
- *
- * These results are self-consistent, i.e. all elements and types accessible
- * through [element], including defined in other files, correspond to each
- * other. But none of the results is guaranteed to be consistent with the state
- * of the files.
- *
- * Every result is independent, and is not guaranteed to be consistent with
- * any previously returned result, even inside of the same library.
- */
-class UnitElementResult extends BaseAnalysisResult
- implements results.UnitElementResult {
- /**
- * The signature of the [element] is based the APIs of the files of the
- * library (including the file itself) of the requested file and the
- * transitive closure of files imported and exported by the library.
- */
- final String signature;
-
- /**
- * The element of the file.
- */
- final CompilationUnitElement element;
-
- UnitElementResult(AnalysisSession session, String path, Uri uri,
- this.signature, this.element)
- : super(session, path, uri);
-
- @override
- results.ResultState get state => results.ResultState.VALID;
-}
-
-/**
* Task that discovers all files that are available to the driver, and makes
* them known.
*/
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart b/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart
index f96d909..6d35e0e 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart
@@ -6,7 +6,7 @@
import 'package:analyzer/dart/analysis/context_root.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart' hide AnalysisResult;
+import 'package:analyzer/src/dart/analysis/driver.dart' show AnalysisDriver;
import 'package:analyzer/src/generated/engine.dart' show AnalysisOptions;
/**
@@ -31,7 +31,9 @@
* to access the file system and that is based on the given analysis [driver].
*/
DriverBasedAnalysisContext(
- this.resourceProvider, this.contextRoot, this.driver);
+ this.resourceProvider, this.contextRoot, this.driver) {
+ driver.analysisContext = this;
+ }
@override
AnalysisOptions get analysisOptions => driver.analysisOptions;
diff --git a/pkg/analyzer/lib/src/dart/analysis/experiments.dart b/pkg/analyzer/lib/src/dart/analysis/experiments.dart
new file mode 100644
index 0000000..d0993c6
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/analysis/experiments.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2018, 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:analyzer/src/generated/engine.dart';
+
+/// A representation of the set of experiments that are active and whether they
+/// are enabled.
+class Experiments {
+ /// The name of the experiment to extend which expressions are constant
+ /// expressions.
+ static const String constantUpdate2018Name = 'constant-update-2018';
+
+ /// The name of the experiment to support set literals.
+ static const String setLiteralName = 'set-literal';
+
+ /// A list containing the names of active experiments.
+ static const List<String> activeExperimentNames = <String>[
+ constantUpdate2018Name,
+ setLiteralName,
+ ];
+
+ /// A list containing the names of the experiments that have been enabled.
+ final List<String> _enabled;
+
+ /// Initialize a newly created set of experiments from the given set of
+ /// analysis [options].
+ Experiments(AnalysisOptions options) : _enabled = options.enabledExperiments;
+
+ /// Return `true` if the experiment named 'constant-update-2018' has been
+ /// enabled.
+ bool get constantUpdate2018 => _enabled.contains(constantUpdate2018Name);
+
+ /// Return `true` if the experiment named 'set-literal' has been enabled.
+ bool get setLiteral => _enabled.contains(setLiteralName);
+}
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index e627abb..2ea7c4c 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -12,6 +12,8 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/defined_names.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer/src/dart/analysis/library_graph.dart';
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/dart/analysis/referenced_names.dart';
import 'package:analyzer/src/dart/analysis/top_level_declaration.dart';
@@ -125,8 +127,11 @@
List<NameFilter> _exportFilters;
Set<FileState> _directReferencedFiles;
- Set<FileState> _transitiveFiles;
+ Set<FileState> _directReferencedLibraries;
+
+ LibraryCycle _libraryCycle;
String _transitiveSignature;
+ String _transitiveSignatureLinked;
Map<String, TopLevelDeclaration> _topLevelDeclarations;
Map<String, TopLevelDeclaration> _exportedTopLevelDeclarations;
@@ -147,6 +152,7 @@
source = null,
_exists = true {
_apiSignature = new Uint8List(16);
+ _libraryCycle = new LibraryCycle.external();
}
/**
@@ -187,6 +193,11 @@
Set<FileState> get directReferencedFiles => _directReferencedFiles;
/**
+ * Return the set of all directly referenced libraries - imported or exported.
+ */
+ Set<FileState> get directReferencedLibraries => _directReferencedLibraries;
+
+ /**
* Return `true` if the file exists.
*/
bool get exists => _exists;
@@ -213,6 +224,8 @@
*/
List<FileState> get importedFiles => _importedFiles;
+ LibraryCycle get internal_libraryCycle => _libraryCycle;
+
/**
* Return `true` if the file is a stub created for a library in the provided
* external summary store.
@@ -254,6 +267,23 @@
}
}
+ /// Return the [LibraryCycle] this file belongs to, even if it consists of
+ /// just this file. If the library cycle is not known yet, compute it.
+ LibraryCycle get libraryCycle {
+ if (isPart) {
+ var library = this.library;
+ if (library != null) {
+ return library.libraryCycle;
+ }
+ }
+
+ if (_libraryCycle == null) {
+ computeLibraryCycle(_fsState._linkedSalt, this);
+ }
+
+ return _libraryCycle;
+ }
+
/**
* The list of files files that this library consists of, i.e. this library
* file itself and its [partedFiles].
@@ -331,39 +361,26 @@
}
/**
- * Return the set of transitive files - the file itself and all of the
- * directly or indirectly referenced files.
+ * Return the signature of the file, based on API signatures of the
+ * transitive closure of imported / exported files.
*/
- Set<FileState> get transitiveFiles {
- if (_transitiveFiles == null) {
- _transitiveFiles = new Set<FileState>();
-
- void appendReferenced(FileState file) {
- if (_transitiveFiles.add(file)) {
- file._directReferencedFiles?.forEach(appendReferenced);
- }
+ String get transitiveSignature {
+ if (isPart) {
+ var library = this.library;
+ if (library != null) {
+ return library.transitiveSignature;
}
-
- appendReferenced(this);
}
- return _transitiveFiles;
+
+ this.libraryCycle; // sets _transitiveSignature
+ return _transitiveSignature;
}
/**
- * Return the signature of the file, based on the [transitiveFiles].
+ * The value `transitiveSignature.linked` is used often, so we cache it.
*/
- String get transitiveSignature {
- if (_transitiveSignature == null) {
- ApiSignature signature = new ApiSignature();
- signature.addUint32List(_fsState._linkedSalt);
- signature.addInt(transitiveFiles.length);
- transitiveFiles
- .map((file) => file.apiSignature)
- .forEach(signature.addBytes);
- signature.addString(uri.toString());
- _transitiveSignature = signature.toHex();
- }
- return _transitiveSignature;
+ String get transitiveSignatureLinked {
+ return _transitiveSignatureLinked ??= '$transitiveSignature.linked';
}
/**
@@ -381,6 +398,17 @@
return other is FileState && other.uri == uri;
}
+ void internal_setLibraryCycle(LibraryCycle cycle, String signature) {
+ if (cycle == null) {
+ _libraryCycle = null;
+ _transitiveSignature = null;
+ _transitiveSignatureLinked = null;
+ } else {
+ _libraryCycle = cycle;
+ _transitiveSignature = signature;
+ }
+ }
+
/**
* Return a new parsed unresolved [CompilationUnit].
*
@@ -461,14 +489,11 @@
_apiSignature = newApiSignature;
// The API signature changed.
- // Flush transitive signatures of affected files.
+ // Flush affected library cycles.
// Flush exported top-level declarations of all files.
if (apiSignatureChanged) {
+ _libraryCycle?.invalidate();
for (FileState file in _fsState._uriToFile.values) {
- if (file._transitiveFiles != null &&
- file._transitiveFiles.contains(this)) {
- file._transitiveSignature = null;
- }
file._exportedTopLevelDeclarations = null;
}
}
@@ -508,26 +533,13 @@
_libraryFiles = [this]..addAll(_partedFiles);
// Compute referenced files.
- Set<FileState> oldDirectReferencedFiles = _directReferencedFiles;
_directReferencedFiles = new Set<FileState>()
..addAll(_importedFiles)
..addAll(_exportedFiles)
..addAll(_partedFiles);
-
- // If the set of directly referenced files of this file is changed,
- // then the transitive sets of files that include this file are also
- // changed. Reset these transitive sets.
- if (oldDirectReferencedFiles != null) {
- if (_directReferencedFiles.length != oldDirectReferencedFiles.length ||
- !_directReferencedFiles.containsAll(oldDirectReferencedFiles)) {
- for (FileState file in _fsState._uriToFile.values) {
- if (file._transitiveFiles != null &&
- file._transitiveFiles.contains(this)) {
- file._transitiveFiles = null;
- }
- }
- }
- }
+ _directReferencedLibraries = Set<FileState>()
+ ..addAll(_importedFiles)
+ ..addAll(_exportedFiles);
// Update mapping from subtyped names to files.
for (var name in _driverUnlinkedUnit.subtypedNames) {
@@ -659,8 +671,10 @@
}
AnalysisOptions analysisOptions = _fsState._analysisOptions;
+ Experiments experiments = new Experiments(analysisOptions);
CharSequenceReader reader = new CharSequenceReader(content);
Scanner scanner = new Scanner(source, reader, errorListener);
+ scanner.enableGtGtGt = experiments.constantUpdate2018;
Token token = PerformanceStatistics.scan.makeCurrentWhile(() {
return scanner.tokenize();
});
@@ -669,6 +683,7 @@
bool useFasta = analysisOptions.useFastaParser;
Parser parser = new Parser(source, errorListener, useFasta: useFasta);
parser.enableOptionalNewAndConst = true;
+ parser.enableSetLiterals = experiments.setLiteral;
CompilationUnit unit = parser.parseCompilationUnit(token);
unit.lineInfo = lineInfo;
@@ -714,7 +729,7 @@
*/
class FileSystemState {
final PerformanceLog _logger;
- final ResourceProvider resourceProvider;
+ final ResourceProvider _resourceProvider;
final ByteStore _byteStore;
final FileContentOverlay _contentOverlay;
final SourceFactory _sourceFactory;
@@ -795,7 +810,7 @@
this._logger,
this._byteStore,
this._contentOverlay,
- this.resourceProvider,
+ this._resourceProvider,
this._sourceFactory,
this._analysisOptions,
this._unlinkedSalt,
@@ -803,7 +818,7 @@
this.externalSummaries,
}) {
_fileContentCache = _FileContentCache.getInstance(
- resourceProvider,
+ _resourceProvider,
_contentOverlay,
);
_testView = new FileSystemStateTestView(this);
@@ -833,7 +848,7 @@
FileState getFileForPath(String path) {
FileState file = _pathToCanonicalFile[path];
if (file == null) {
- File resource = resourceProvider.getFile(path);
+ File resource = _resourceProvider.getFile(path);
Source fileSource = resource.createSource();
Uri uri = _sourceFactory.restoreUri(fileSource);
// Try to get the existing instance.
@@ -884,7 +899,7 @@
}
String path = uriSource.fullName;
- File resource = resourceProvider.getFile(path);
+ File resource = _resourceProvider.getFile(path);
FileSource source = new FileSource(resource, uri);
file = new FileState._(this, path, uri, source);
_uriToFile[uri] = file;
@@ -927,7 +942,7 @@
bool hasUri(String path) {
bool flag = _hasUriForPath[path];
if (flag == null) {
- File resource = resourceProvider.getFile(path);
+ File resource = _resourceProvider.getFile(path);
Source fileSource = resource.createSource();
Uri uri = _sourceFactory.restoreUri(fileSource);
Source uriSource = _sourceFactory.forUri2(uri);
@@ -978,15 +993,9 @@
FileSystemStateTestView(this.state);
- Set<FileState> get filesWithoutTransitiveFiles {
+ Set<FileState> get filesWithoutLibraryCycle {
return state._uriToFile.values
- .where((f) => f._transitiveFiles == null)
- .toSet();
- }
-
- Set<FileState> get filesWithoutTransitiveSignature {
- return state._uriToFile.values
- .where((f) => f._transitiveSignature == null)
+ .where((f) => f._libraryCycle == null)
.toSet();
}
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index ed45474..c11275c 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -8,8 +8,6 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/context/context.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
@@ -27,7 +25,6 @@
import 'package:analyzer/src/generated/error_verifier.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/hint/sdk_constraint_extractor.dart';
import 'package:analyzer/src/hint/sdk_constraint_verifier.dart';
import 'package:analyzer/src/lint/linter.dart';
import 'package:analyzer/src/lint/linter_visitor.dart';
@@ -44,37 +41,31 @@
/// [_versionConstraintFromPubspec] when the previous initialization attempt
/// failed.
static final VersionRange noSpecifiedRange = new VersionRange();
-
final AnalysisOptionsImpl _analysisOptions;
final DeclaredVariables _declaredVariables;
final SourceFactory _sourceFactory;
final FileState _library;
- final ResourceProvider resourceProvider;
- final InheritanceManager2 _inheritance;
+ final InheritanceManager2 _inheritance;
final bool Function(Uri) _isLibraryUri;
- final AnalysisContextImpl _context;
+ final AnalysisContext _context;
final ElementResynthesizer _resynthesizer;
final TypeProvider _typeProvider;
+
final TypeSystem _typeSystem;
-
LibraryElement _libraryElement;
+
LibraryScope _libraryScope;
-
final Map<FileState, LineInfo> _fileToLineInfo = {};
- final Map<FileState, IgnoreInfo> _fileToIgnoreInfo = {};
+ final Map<FileState, IgnoreInfo> _fileToIgnoreInfo = {};
final Map<FileState, RecordingErrorListener> _errorListeners = {};
final Map<FileState, ErrorReporter> _errorReporters = {};
final List<UsedImportedElements> _usedImportedElementsList = [];
final List<UsedLocalElements> _usedLocalElementsList = [];
final Map<FileState, List<PendingError>> _fileToPendingErrors = {};
- final Set<ConstantEvaluationTarget> _constants = new Set();
- /// The cached version range for the SDK specified in `pubspec.yaml`, or
- /// [noSpecifiedRange] if there is no `pubspec.yaml` or if it does not contain
- /// an SDK range. Use [versionConstraintFromPubspec] to access this field.
- VersionConstraint _versionConstraintFromPubspec;
+ final Set<ConstantEvaluationTarget> _constants = new Set();
LibraryAnalyzer(
this._analysisOptions,
@@ -83,10 +74,9 @@
this._isLibraryUri,
this._context,
this._resynthesizer,
- this._library,
- this.resourceProvider)
- : _inheritance = new InheritanceManager2(_context.typeSystem),
- _typeProvider = _context.typeProvider,
+ this._inheritance,
+ this._library)
+ : _typeProvider = _context.typeProvider,
_typeSystem = _context.typeSystem;
/**
@@ -114,60 +104,56 @@
_resolveUriBasedDirectives(file, unit);
});
- try {
- _libraryElement = _resynthesizer
- .getElement(new ElementLocationImpl.con3([_library.uriStr]));
- _libraryScope = new LibraryScope(_libraryElement);
+ _libraryElement = _resynthesizer
+ .getElement(new ElementLocationImpl.con3([_library.uriStr]));
+ _libraryScope = new LibraryScope(_libraryElement);
- _resolveDirectives(units);
+ _resolveDirectives(units);
+ units.forEach((file, unit) {
+ _resolveFile(file, unit);
+ _computePendingMissingRequiredParameters(file, unit);
+ });
+
+ units.values.forEach(_findConstants);
+ _computeConstants();
+
+ PerformanceStatistics.errors.makeCurrentWhile(() {
units.forEach((file, unit) {
- _resolveFile(file, unit);
- _computePendingMissingRequiredParameters(file, unit);
+ _computeVerifyErrors(file, unit);
});
+ });
- units.values.forEach(_findConstants);
- _computeConstants();
-
- PerformanceStatistics.errors.makeCurrentWhile(() {
+ if (_analysisOptions.hint) {
+ PerformanceStatistics.hints.makeCurrentWhile(() {
units.forEach((file, unit) {
- _computeVerifyErrors(file, unit);
- });
- });
-
- if (_analysisOptions.hint) {
- PerformanceStatistics.hints.makeCurrentWhile(() {
- units.forEach((file, unit) {
- {
- var visitor = new GatherUsedLocalElementsVisitor(_libraryElement);
- unit.accept(visitor);
- _usedLocalElementsList.add(visitor.usedElements);
- }
- {
- var visitor =
- new GatherUsedImportedElementsVisitor(_libraryElement);
- unit.accept(visitor);
- _usedImportedElementsList.add(visitor.usedElements);
- }
- });
- units.forEach((file, unit) {
- _computeHints(file, unit);
- });
- });
- }
-
- if (_analysisOptions.lint) {
- PerformanceStatistics.lints.makeCurrentWhile(() {
- var allUnits = _library.libraryFiles
- .map((file) => LinterContextUnit(file.content, units[file]))
- .toList();
- for (int i = 0; i < allUnits.length; i++) {
- _computeLints(_library.libraryFiles[i], allUnits[i], allUnits);
+ {
+ var visitor = new GatherUsedLocalElementsVisitor(_libraryElement);
+ unit.accept(visitor);
+ _usedLocalElementsList.add(visitor.usedElements);
+ }
+ {
+ var visitor =
+ new GatherUsedImportedElementsVisitor(_libraryElement);
+ unit.accept(visitor);
+ _usedImportedElementsList.add(visitor.usedElements);
}
});
- }
- } finally {
- _context.dispose();
+ units.forEach((file, unit) {
+ _computeHints(file, unit);
+ });
+ });
+ }
+
+ if (_analysisOptions.lint) {
+ PerformanceStatistics.lints.makeCurrentWhile(() {
+ var allUnits = _library.libraryFiles
+ .map((file) => LinterContextUnit(file.content, units[file]))
+ .toList();
+ for (int i = 0; i < allUnits.length; i++) {
+ _computeLints(_library.libraryFiles[i], allUnits[i], allUnits);
+ }
+ });
}
// Return full results.
@@ -180,20 +166,6 @@
return results;
}
- VersionConstraint versionConstraintFromPubspec() {
- if (_versionConstraintFromPubspec == null) {
- _versionConstraintFromPubspec = noSpecifiedRange;
- File pubspecFile = _findPubspecFile(_library);
- if (pubspecFile != null) {
- SdkConstraintExtractor extractor =
- new SdkConstraintExtractor(pubspecFile);
- _versionConstraintFromPubspec =
- extractor.constraint() ?? noSpecifiedRange;
- }
- }
- return _versionConstraintFromPubspec;
- }
-
void _computeConstantErrors(
ErrorReporter errorReporter, CompilationUnit unit) {
ConstantVerifier constantVerifier = new ConstantVerifier(
@@ -268,14 +240,15 @@
new UnusedLocalElementsVerifier(errorListener, usedElements);
unit.accept(visitor);
}
+
//
- // Find code that uses features from an SDK that is newer than the minimum
- // version allowed in the pubspec.yaml file.
+ // Find code that uses features from an SDK version that does not satisfy
+ // the SDK constraints specified in analysis options.
//
- VersionRange versionRange = versionConstraintFromPubspec();
- if (versionRange != noSpecifiedRange) {
+ var sdkVersionConstraint = _analysisOptions.sdkVersionConstraint;
+ if (sdkVersionConstraint != null) {
SdkConstraintVerifier verifier = new SdkConstraintVerifier(
- errorReporter, _libraryElement, _typeProvider, versionRange);
+ errorReporter, _libraryElement, _typeProvider, sdkVersionConstraint);
unit.accept(verifier);
}
}
@@ -295,11 +268,8 @@
allUnits, currentUnit, _declaredVariables, _typeProvider, _typeSystem);
for (Linter linter in _analysisOptions.lintRules) {
linter.reporter = errorReporter;
- if (linter is NodeLintRuleWithContext) {
- (linter as NodeLintRuleWithContext)
- .registerNodeProcessors(nodeRegistry, context);
- } else if (linter is NodeLintRule) {
- (linter as NodeLintRule).registerNodeProcessors(nodeRegistry);
+ if (linter is NodeLintRule) {
+ (linter as NodeLintRule).registerNodeProcessors(nodeRegistry, context);
} else {
AstVisitor visitor = linter.getVisitor();
if (visitor != null) {
@@ -412,18 +382,6 @@
_constants.addAll(dependenciesFinder.dependencies);
}
- File _findPubspecFile(FileState file) {
- Folder folder = resourceProvider?.getFile(file.path)?.parent;
- while (folder != null) {
- File pubspecFile = folder.getChildAssumingFile('pubspec.yaml');
- if (pubspecFile.exists) {
- return pubspecFile;
- }
- folder = folder.parent;
- }
- return null;
- }
-
RecordingErrorListener _getErrorListener(FileState file) =>
_errorListeners.putIfAbsent(file, () => new RecordingErrorListener());
@@ -459,6 +417,15 @@
return null;
}
+ bool _isExistingSource(Source source) {
+ for (var file in _library.directReferencedFiles) {
+ if (file.uri == source.uri) {
+ return file.exists;
+ }
+ }
+ return false;
+ }
+
/**
* Return `true` if the given [source] is a library.
*/
@@ -554,7 +521,7 @@
// Validate that the part contains a part-of directive with the same
// name or uri as the library.
//
- if (_context.exists(partSource)) {
+ if (_isExistingSource(partSource)) {
_NameOrSource nameOrSource = _getPartLibraryNameOrUri(
partSource, partUnit, directivesToResolve);
if (nameOrSource == null) {
@@ -702,7 +669,7 @@
FileState file, UriBasedDirectiveImpl directive) {
Source source = directive.uriSource;
if (source != null) {
- if (_context.exists(source)) {
+ if (_isExistingSource(source)) {
return;
}
} else {
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_context.dart b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
index 3a36e2b..44f61a4 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/analysis/declared_variables.dart';
+import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/element/element.dart'
show CompilationUnitElement, LibraryElement;
import 'package:analyzer/src/context/context.dart';
@@ -10,161 +11,94 @@
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
+import 'package:analyzer/src/dart/analysis/restricted_analysis_context.dart';
import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/dart/element/handle.dart';
+import 'package:analyzer/src/dart/element/inheritance_manager2.dart';
import 'package:analyzer/src/generated/engine.dart'
- show AnalysisContext, AnalysisEngine, AnalysisOptions;
+ show AnalysisContext, AnalysisOptions;
+import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/link.dart';
import 'package:analyzer/src/summary/package_bundle_reader.dart';
+import 'package:analyzer/src/summary/resynthesize.dart';
+import 'package:meta/meta.dart';
/**
* Context information necessary to analyze one or more libraries within an
* [AnalysisDriver].
*
* Currently this is implemented as a wrapper around [AnalysisContext].
- * TODO(paulberry): make a front end API that this can make use of instead.
*/
class LibraryContext {
- final SummaryDataStore store;
+ static const _maxLinkedDataInBytes = 64 * 1024 * 1024;
- /**
- * The [AnalysisContext] which is used to do the analysis.
- */
- final AnalysisContext analysisContext;
+ final PerformanceLog logger;
+ final ByteStore byteStore;
+ final SummaryDataStore store = new SummaryDataStore([]);
- /**
- * The resynthesizer that resynthesizes elements in [analysisContext].
- */
- final ElementResynthesizer resynthesizer;
+ /// The size of the linked data that is loaded by this context.
+ /// When it reaches [_maxLinkedDataInBytes] the whole context is thrown away.
+ /// We use it as an approximation for the heap size of elements.
+ int _linkedDataInBytes = 0;
- /**
- * Create a [LibraryContext] which is prepared to analyze [targetLibrary].
- */
- factory LibraryContext.forSingleLibrary(
- FileState targetLibrary,
- PerformanceLog logger,
- PackageBundle sdkBundle,
- ByteStore byteStore,
- AnalysisOptions options,
- DeclaredVariables declaredVariables,
- SourceFactory sourceFactory,
- SummaryDataStore externalSummaries,
- FileSystemState fsState) {
- return logger.run('Create library context', () {
- Map<String, FileState> libraries = <String, FileState>{};
- SummaryDataStore store = new SummaryDataStore(const <String>[]);
+ AnalysisContextImpl analysisContext;
+ SummaryResynthesizer resynthesizer;
+ InheritanceManager2 inheritanceManager;
- if (externalSummaries != null) {
- store.addStore(externalSummaries);
- }
+ LibraryContext({
+ @required AnalysisSession session,
+ @required PerformanceLog logger,
+ @required ByteStore byteStore,
+ @required FileSystemState fsState,
+ @required AnalysisOptions analysisOptions,
+ @required DeclaredVariables declaredVariables,
+ @required SourceFactory sourceFactory,
+ @required SummaryDataStore externalSummaries,
+ @required FileState targetLibrary,
+ }) : this.logger = logger,
+ this.byteStore = byteStore {
+ if (externalSummaries != null) {
+ store.addStore(externalSummaries);
+ }
- if (sdkBundle != null) {
- store.addBundle(null, sdkBundle);
- }
+ // Fill the store with summaries required for the initial library.
+ load(targetLibrary);
- void appendLibraryFiles(FileState library) {
- if (!libraries.containsKey(library.uriStr)) {
- // Serve 'dart:' URIs from the SDK bundle.
- if (sdkBundle != null && library.uri.scheme == 'dart') {
- return;
- }
+ analysisContext = new RestrictedAnalysisContext(
+ analysisOptions,
+ declaredVariables,
+ sourceFactory,
+ );
- if (library.isInExternalSummaries) {
- return;
- }
+ var provider = new InputPackagesResultProvider(analysisContext, store,
+ session: session);
+ resynthesizer = provider.resynthesizer;
- libraries[library.uriStr] = library;
-
- // Append library units.
- for (FileState part in library.libraryFiles) {
- store.addUnlinkedUnit(part.uriStr, part.unlinked);
- }
-
- // Append referenced libraries.
- library.importedFiles.forEach(appendLibraryFiles);
- library.exportedFiles.forEach(appendLibraryFiles);
- }
- }
-
- logger.run('Append library files', () {
- appendLibraryFiles(targetLibrary);
- });
-
- var libraryUrisToLink = new Set<String>();
- var libraryFilesToLink = new Set<FileState>();
- logger.run('Load linked bundles', () {
- for (FileState library in libraries.values) {
- if (library.exists || library == targetLibrary) {
- String key = '${library.transitiveSignature}.linked';
- List<int> bytes = byteStore.get(key);
- if (bytes != null) {
- LinkedLibrary linked = new LinkedLibrary.fromBuffer(bytes);
- store.addLinkedLibrary(library.uriStr, linked);
- } else {
- libraryUrisToLink.add(library.uriStr);
- libraryFilesToLink.add(library);
- }
- }
- }
- int numOfLoaded = libraries.length - libraryUrisToLink.length;
- logger.writeln('Loaded $numOfLoaded linked bundles.');
- });
-
- Map<String, LinkedLibraryBuilder> linkedLibraries = {};
- logger.run('Link libraries', () {
- linkedLibraries = link(libraryUrisToLink, (String uri) {
- LinkedLibrary linkedLibrary = store.linkedMap[uri];
- return linkedLibrary;
- }, (String uri) {
- UnlinkedUnit unlinkedUnit = store.unlinkedMap[uri];
- return unlinkedUnit;
- }, (_) => null);
- logger.writeln('Linked ${linkedLibraries.length} libraries.');
- });
-
- for (String uri in linkedLibraries.keys) {
- LinkedLibraryBuilder linkedBuilder = linkedLibraries[uri];
- FileState library = libraries[uri];
- String key = '${library.transitiveSignature}.linked';
- List<int> bytes = linkedBuilder.toBuffer();
- LinkedLibrary linked = new LinkedLibrary.fromBuffer(bytes);
- store.addLinkedLibrary(uri, linked);
- byteStore.put(key, bytes);
- }
-
- var resynthesizingContext = _createResynthesizingContext(
- options, declaredVariables, sourceFactory, store);
- resynthesizingContext.context.contentCache =
- new _ContentCacheWrapper(fsState);
-
- return new LibraryContext._(store, resynthesizingContext.context,
- resynthesizingContext.resynthesizer);
- });
+ inheritanceManager = new InheritanceManager2(analysisContext.typeSystem);
}
- LibraryContext._(this.store, this.analysisContext, this.resynthesizer);
+ /**
+ * The type provider used in this context.
+ */
+ TypeProvider get typeProvider => analysisContext.typeProvider;
/**
* Computes a [CompilationUnitElement] for the given library/unit pair.
*/
- CompilationUnitElement computeUnitElement(
- Source librarySource, Source unitSource) {
- String libraryUri = librarySource.uri.toString();
- String unitUri = unitSource.uri.toString();
- return resynthesizer.getElement(
- new ElementLocationImpl.con3(<String>[libraryUri, unitUri]));
+ CompilationUnitElement computeUnitElement(FileState library, FileState unit) {
+ return resynthesizer.getElement(new ElementLocationImpl.con3(<String>[
+ library.uriStr,
+ unit.uriStr,
+ ]));
}
/**
- * Cleans up any persistent resources used by this [LibraryContext].
- *
- * Should be called once the [LibraryContext] is no longer needed.
+ * Get the [LibraryElement] for the given library.
*/
- void dispose() {
- analysisContext.dispose();
+ LibraryElement getLibraryElement(FileState library) {
+ return resynthesizer.getLibraryElement(library.uriStr);
}
/**
@@ -175,99 +109,96 @@
return store.unlinkedMap[uriStr]?.isPartOf == false;
}
- /**
- * Resynthesize the [LibraryElement] from the given [store].
- */
- static LibraryElement resynthesizeLibraryElement(
- AnalysisOptions analysisOptions,
- DeclaredVariables declaredVariables,
- SourceFactory sourceFactory,
- SummaryDataStore store,
- String uri) {
- var resynthesizingContext = _createResynthesizingContext(
- analysisOptions, declaredVariables, sourceFactory, store);
- try {
- return resynthesizingContext.resynthesizer
- .getElement(new ElementLocationImpl.con3([uri]));
- } finally {
- resynthesizingContext.context.dispose();
+ /// Load data required to access elements of the given [targetLibrary].
+ void load(FileState targetLibrary) {
+ // The library is already a part of the context, nothing to do.
+ if (store.linkedMap.containsKey(targetLibrary.uriStr)) {
+ return;
+ }
+
+ var libraries = <String, FileState>{};
+ void appendLibraryFiles(FileState library) {
+ // Stop if this library is already a part of the context.
+ // Libraries from external summaries are also covered by this.
+ if (store.linkedMap.containsKey(library.uriStr)) {
+ return;
+ }
+
+ // Stop if we have already scheduled loading of this library.
+ if (libraries.containsKey(library.uriStr)) {
+ return;
+ }
+
+ // Schedule the library for loading or linking.
+ libraries[library.uriStr] = library;
+
+ // Append library units.
+ for (FileState part in library.libraryFiles) {
+ store.addUnlinkedUnit(part.uriStr, part.unlinked);
+ }
+
+ // Append referenced libraries.
+ library.importedFiles.forEach(appendLibraryFiles);
+ library.exportedFiles.forEach(appendLibraryFiles);
+ }
+
+ logger.run('Append library files', () {
+ appendLibraryFiles(targetLibrary);
+ });
+
+ var libraryUrisToLink = new Set<String>();
+ logger.run('Load linked bundles', () {
+ for (FileState library in libraries.values) {
+ if (library.exists || library == targetLibrary) {
+ String key = library.transitiveSignatureLinked;
+ List<int> bytes = byteStore.get(key);
+ if (bytes != null) {
+ LinkedLibrary linked = new LinkedLibrary.fromBuffer(bytes);
+ store.addLinkedLibrary(library.uriStr, linked);
+ _linkedDataInBytes += bytes.length;
+ } else {
+ libraryUrisToLink.add(library.uriStr);
+ }
+ }
+ }
+ int numOfLoaded = libraries.length - libraryUrisToLink.length;
+ logger.writeln('Loaded $numOfLoaded linked bundles.');
+ });
+
+ var linkedLibraries = <String, LinkedLibraryBuilder>{};
+ logger.run('Link libraries', () {
+ linkedLibraries = link(libraryUrisToLink, (String uri) {
+ LinkedLibrary linkedLibrary = store.linkedMap[uri];
+ return linkedLibrary;
+ }, (String uri) {
+ UnlinkedUnit unlinkedUnit = store.unlinkedMap[uri];
+ return unlinkedUnit;
+ }, (_) => null);
+ logger.writeln('Linked ${linkedLibraries.length} libraries.');
+ });
+
+ // Store freshly linked libraries into the byte store.
+ // Append them to the context.
+ for (String uri in linkedLibraries.keys) {
+ FileState library = libraries[uri];
+ String key = library.transitiveSignatureLinked;
+
+ LinkedLibraryBuilder linkedBuilder = linkedLibraries[uri];
+ List<int> bytes = linkedBuilder.toBuffer();
+ byteStore.put(key, bytes);
+
+ LinkedLibrary linked = new LinkedLibrary.fromBuffer(bytes);
+ store.addLinkedLibrary(uri, linked);
+ _linkedDataInBytes += bytes.length;
}
}
- static _ResynthesizingAnalysisContext _createResynthesizingContext(
- AnalysisOptions analysisOptions,
- DeclaredVariables declaredVariables,
- SourceFactory sourceFactory,
- SummaryDataStore store) {
- AnalysisContextImpl analysisContext =
- AnalysisEngine.instance.createAnalysisContext();
- analysisContext.useSdkCachePartition = false;
- analysisContext.analysisOptions = analysisOptions;
- analysisContext.declaredVariables = declaredVariables;
- analysisContext.sourceFactory = sourceFactory.clone();
- var provider = new InputPackagesResultProvider(analysisContext, store);
- analysisContext.resultProvider = provider;
- return new _ResynthesizingAnalysisContext(
- analysisContext, provider.resynthesizer);
+ /// Return `true` if this context grew too large, and should be recreated.
+ ///
+ /// It might have been used to analyze libraries that we don't need anymore,
+ /// and because loading libraries is not very expensive (but not free), the
+ /// simplest way to get rid of the garbage is to throw away everything.
+ bool pack() {
+ return _linkedDataInBytes > _maxLinkedDataInBytes;
}
}
-
-/**
- * [ContentCache] wrapper around [FileContentOverlay].
- */
-class _ContentCacheWrapper implements ContentCache {
- final FileSystemState fsState;
-
- _ContentCacheWrapper(this.fsState);
-
- @override
- void accept(ContentCacheVisitor visitor) {
- throw new UnimplementedError();
- }
-
- @override
- String getContents(Source source) {
- return _getFileForSource(source).content;
- }
-
- @override
- bool getExists(Source source) {
- if (source.isInSystemLibrary) {
- return true;
- }
- String uriStr = source.uri.toString();
- if (fsState.externalSummaries != null &&
- fsState.externalSummaries.hasUnlinkedUnit(uriStr)) {
- return true;
- }
- return _getFileForSource(source).exists;
- }
-
- @override
- int getModificationStamp(Source source) {
- if (source.isInSystemLibrary) {
- return 0;
- }
- return _getFileForSource(source).exists ? 0 : -1;
- }
-
- @override
- String setContents(Source source, String contents) {
- throw new UnimplementedError();
- }
-
- FileState _getFileForSource(Source source) {
- String path = source.fullName;
- return fsState.getFileForPath(path);
- }
-}
-
-/**
- * Container with analysis context and the corresponding resynthesizer.
- */
-class _ResynthesizingAnalysisContext {
- final AnalysisContextImpl context;
- final ElementResynthesizer resynthesizer;
-
- _ResynthesizingAnalysisContext(this.context, this.resynthesizer);
-}
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_graph.dart b/pkg/analyzer/lib/src/dart/analysis/library_graph.dart
new file mode 100644
index 0000000..74cb08c
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/analysis/library_graph.dart
@@ -0,0 +1,173 @@
+// Copyright (c) 2018, 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:typed_data';
+
+import 'package:analyzer/src/dart/analysis/file_state.dart';
+import 'package:analyzer/src/summary/api_signature.dart';
+import 'package:analyzer/src/summary/link.dart' as graph
+ show DependencyWalker, Node;
+import 'package:meta/meta.dart';
+
+/// Ensure that the [FileState.libraryCycle] for the [file] and anything it
+/// depends on is computed.
+void computeLibraryCycle(Uint32List linkedSalt, FileState file) {
+ var libraryWalker = new _LibraryWalker(linkedSalt);
+ libraryWalker.walk(libraryWalker.getNode(file));
+}
+
+/// Information about libraries that reference each other, so form a cycle.
+class LibraryCycle {
+ /// The libraries that belong to this cycle.
+ final List<FileState> libraries = [];
+
+ /// The library cycles that this cycle references directly.
+ @visibleForTesting
+ final Set<LibraryCycle> directDependencies = new Set<LibraryCycle>();
+
+ /// The cycles that use this cycle, used to [invalidate] transitively.
+ final List<LibraryCycle> _directUsers = [];
+
+ /// The transitive signature of this cycle.
+ ///
+ /// It is based on the API signatures of all files of the [libraries], and
+ /// transitive signatures of the cycles that the [libraries] reference
+ /// directly. So, indirectly it is based on the transitive closure of all
+ /// files that [libraries] reference (but we don't compute these files).
+ String _transitiveSignature;
+
+ /// The map from a library in [libraries] to its transitive signature.
+ ///
+ /// It is almost the same as [_transitiveSignature], but is also based on
+ /// the URI of this specific library. Currently we store each linked library
+ /// with its own key, so we need unique keys. However practically we never
+ /// can use just *one* library of a cycle, we always use the whole cycle.
+ ///
+ /// TODO(scheglov) Switch to loading the whole cycle maybe?
+ final Map<FileState, String> transitiveSignatures = {};
+
+ LibraryCycle();
+
+ LibraryCycle.external() : _transitiveSignature = '<external>';
+
+ /// Invalidate this cycle and any cycles that directly or indirectly use it.
+ ///
+ /// Practically invalidation means that we clear the library cycle in all the
+ /// [libraries] that share this [LibraryCycle] instance.
+ void invalidate() {
+ for (var library in libraries) {
+ library.internal_setLibraryCycle(null, null);
+ }
+ for (var user in _directUsers) {
+ user.invalidate();
+ }
+ _directUsers.clear();
+ }
+
+ @override
+ String toString() {
+ return '[' + libraries.join(', ') + ']';
+ }
+}
+
+/// Node in [_LibraryWalker].
+class _LibraryNode extends graph.Node<_LibraryNode> {
+ final _LibraryWalker walker;
+ final FileState file;
+
+ _LibraryNode(this.walker, this.file);
+
+ @override
+ bool get isEvaluated => file.internal_libraryCycle != null;
+
+ @override
+ List<_LibraryNode> computeDependencies() {
+ return file.directReferencedLibraries.map(walker.getNode).toList();
+ }
+}
+
+/// Helper that organizes dependencies of a library into topologically
+/// sorted [LibraryCycle]s.
+class _LibraryWalker extends graph.DependencyWalker<_LibraryNode> {
+ final Uint32List _linkedSalt;
+ final Map<FileState, _LibraryNode> nodesOfFiles = {};
+
+ _LibraryWalker(this._linkedSalt);
+
+ @override
+ void evaluate(_LibraryNode v) {
+ evaluateScc([v]);
+ }
+
+ @override
+ void evaluateScc(List<_LibraryNode> scc) {
+ var cycle = new LibraryCycle();
+
+ var signature = new ApiSignature();
+ signature.addUint32List(_linkedSalt);
+
+ // Sort libraries to produce stable signatures.
+ scc.sort((first, second) {
+ var firstPath = first.file.path;
+ var secondPath = second.file.path;
+ return firstPath.compareTo(secondPath);
+ });
+
+ // Append direct referenced cycles.
+ for (var node in scc) {
+ var file = node.file;
+ _appendDirectlyReferenced(cycle, signature, file.importedFiles);
+ _appendDirectlyReferenced(cycle, signature, file.exportedFiles);
+ }
+
+ // Fill the cycle with libraries.
+ for (var node in scc) {
+ cycle.libraries.add(node.file);
+
+ signature.addInt(node.file.libraryFiles.length);
+ for (var file in node.file.libraryFiles) {
+ signature.addBytes(file.apiSignature);
+ }
+ }
+
+ // Compute the general library cycle signature.
+ cycle._transitiveSignature = signature.toHex();
+
+ // Compute library specific signatures.
+ for (var node in scc) {
+ var librarySignatureBuilder = new ApiSignature()
+ ..addString(node.file.uriStr)
+ ..addString(cycle._transitiveSignature);
+ var librarySignature = librarySignatureBuilder.toHex();
+
+ node.file.internal_setLibraryCycle(
+ cycle,
+ librarySignature,
+ );
+ }
+ }
+
+ _LibraryNode getNode(FileState file) {
+ return nodesOfFiles.putIfAbsent(file, () => new _LibraryNode(this, file));
+ }
+
+ void _appendDirectlyReferenced(
+ LibraryCycle cycle,
+ ApiSignature signature,
+ List<FileState> directlyReferenced,
+ ) {
+ signature.addInt(directlyReferenced.length);
+ for (var referencedLibrary in directlyReferenced) {
+ var referencedCycle = referencedLibrary.internal_libraryCycle;
+
+ // We get null when the library is a part of the cycle being build.
+ if (referencedCycle == null) continue;
+
+ if (cycle.directDependencies.add(referencedCycle)) {
+ referencedCycle._directUsers.add(cycle);
+ signature.addString(referencedCycle._transitiveSignature);
+ }
+ }
+ }
+}
diff --git a/pkg/analyzer/lib/src/dart/analysis/restricted_analysis_context.dart b/pkg/analyzer/lib/src/dart/analysis/restricted_analysis_context.dart
new file mode 100644
index 0000000..179ac05
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/analysis/restricted_analysis_context.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2018, 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:analyzer/dart/analysis/declared_variables.dart';
+import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/type_system.dart';
+
+/// This class is a temporary step toward migrating Analyzer clients to the
+/// new API. It guards against attempts to use any [AnalysisContext]
+/// functionality (which is task based), except what we intend to expose
+/// through the new API.
+class RestrictedAnalysisContext implements AnalysisContextImpl {
+ @override
+ final AnalysisOptionsImpl analysisOptions;
+
+ @override
+ final DeclaredVariables declaredVariables;
+
+ @override
+ final SourceFactory sourceFactory;
+
+ TypeProvider _typeProvider;
+
+ TypeSystem _typeSystem;
+
+ RestrictedAnalysisContext(
+ this.analysisOptions, this.declaredVariables, this.sourceFactory);
+
+ @override
+ TypeProvider get typeProvider => _typeProvider;
+
+ @override
+ set typeProvider(TypeProvider typeProvider) {
+ if (_typeProvider != null) {
+ throw StateError('TypeProvider can be set only once.');
+ }
+ _typeProvider = typeProvider;
+ }
+
+ @override
+ TypeSystem get typeSystem {
+ return _typeSystem ??= StrongTypeSystemImpl(
+ typeProvider,
+ implicitCasts: analysisOptions.implicitCasts,
+ );
+ }
+
+ noSuchMethod(Invocation invocation) {
+ return super.noSuchMethod(invocation);
+ }
+}
diff --git a/pkg/analyzer/lib/src/dart/analysis/results.dart b/pkg/analyzer/lib/src/dart/analysis/results.dart
index 2b9ac07..fd50c1c 100644
--- a/pkg/analyzer/lib/src/dart/analysis/results.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/results.dart
@@ -68,39 +68,62 @@
class ParsedLibraryResultImpl extends AnalysisResultImpl
implements ParsedLibraryResult {
@override
- final ResultState state = ResultState.VALID;
-
- @override
final List<ParsedUnitResult> units;
ParsedLibraryResultImpl(
AnalysisSession session, String path, Uri uri, this.units)
: super(session, path, uri);
+ ParsedLibraryResultImpl.external(AnalysisSession session, Uri uri)
+ : this(session, null, uri, null);
+
@Deprecated('This factory exists temporary until AnalysisSession migration.')
factory ParsedLibraryResultImpl.tmp(LibraryElement library) {
- var libraryPath = library.source.fullName;
- var analysisContext = library.context;
- var units = <ParsedUnitResult>[];
- for (var unitElement in library.units) {
- var unitSource = unitElement.source;
+ var session = library.session;
+ if (session != null) {
+ return session.getParsedLibraryByElement(library);
+ } else {
+ var analysisContext = library.context;
+ var units = <ParsedUnitResult>[];
+ for (var unitElement in library.units) {
+ var unitSource = unitElement.source;
- if (!analysisContext.exists(unitSource)) {
- continue;
+ if (!analysisContext.exists(unitSource)) {
+ continue;
+ }
+
+ var content = analysisContext.getContents(unitSource).data;
+ var lineInfo = analysisContext.getLineInfo(unitSource);
+ var unit = analysisContext.parseCompilationUnit(unitSource);
+ units.add(ParsedUnitResultImpl(
+ null,
+ unitSource.fullName,
+ unitSource.uri,
+ content,
+ lineInfo,
+ unitSource != library.source,
+ unit, const []));
}
-
- var content = analysisContext.getContents(unitSource).data;
- var lineInfo = analysisContext.getLineInfo(unitSource);
- var unit = analysisContext.parseCompilationUnit(unitSource);
- units.add(ParsedUnitResultImpl(null, unitSource.fullName, unitSource.uri,
- content, lineInfo, unitSource != library.source, unit, const []));
+ var libraryPath = library.source.fullName;
+ return ParsedLibraryResultImpl(
+ null, libraryPath, library.source.uri, units);
}
- return ParsedLibraryResultImpl(
- null, libraryPath, library.source.uri, units);
+ }
+
+ @override
+ ResultState get state {
+ if (path == null) {
+ return ResultState.NOT_A_FILE;
+ }
+ return ResultState.VALID;
}
@override
ElementDeclarationResult getElementDeclaration(Element element) {
+ if (state != ResultState.VALID) {
+ throw StateError('The result is not valid: $state');
+ }
+
var elementPath = element.source.fullName;
var unitResult = units.firstWhere(
(r) => r.path == elementPath,
@@ -190,25 +213,30 @@
@Deprecated('This method exists temporary until AnalysisSession migration.')
static Future<ResolvedLibraryResult> tmp(LibraryElement library) async {
- var libraryPath = library.source.fullName;
- var units = <ResolvedUnitResult>[];
- var analysisContext = library.context;
- for (var unitElement in library.units) {
- var unitSource = unitElement.source;
+ var session = library.session;
+ if (session != null) {
+ return session.getResolvedLibraryByElement(library);
+ } else {
+ var units = <ResolvedUnitResult>[];
+ var analysisContext = library.context;
+ for (var unitElement in library.units) {
+ var unitSource = unitElement.source;
- if (!analysisContext.exists(unitSource)) {
- continue;
+ if (!analysisContext.exists(unitSource)) {
+ continue;
+ }
+
+ var path = unitSource.fullName;
+ var content = analysisContext.getContents(unitSource).data;
+ var lineInfo = analysisContext.getLineInfo(unitSource);
+ var unit = analysisContext.resolveCompilationUnit(unitSource, library);
+ units.add(ResolvedUnitResultImpl(null, path, unitSource.uri, true,
+ content, lineInfo, unitSource != library.source, unit, const []));
}
-
- var path = unitSource.fullName;
- var content = analysisContext.getContents(unitSource).data;
- var lineInfo = analysisContext.getLineInfo(unitSource);
- var unit = analysisContext.resolveCompilationUnit(unitSource, library);
- units.add(ResolvedUnitResultImpl(null, path, unitSource.uri, true,
- content, lineInfo, unitSource != library.source, unit, const []));
+ var libraryPath = library.source.fullName;
+ return ResolvedLibraryResultImpl(null, libraryPath, library.source.uri,
+ library, library.context.typeProvider, units);
}
- return ResolvedLibraryResultImpl(null, libraryPath, library.source.uri,
- library, library.context.typeProvider, units);
}
}
diff --git a/pkg/analyzer/lib/src/dart/analysis/search.dart b/pkg/analyzer/lib/src/dart/analysis/search.dart
index 9d1ff41..38f006e 100644
--- a/pkg/analyzer/lib/src/dart/analysis/search.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/search.dart
@@ -1,10 +1,11 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
import 'dart:collection';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
@@ -654,10 +655,10 @@
LibraryElement libraryElement = element.library;
for (CompilationUnitElement unitElement in libraryElement.units) {
String unitPath = unitElement.source.fullName;
- AnalysisResult unitAnalysisResult = await _driver.getResult(unitPath);
+ ResolvedUnitResult unitResult = await _driver.getResult(unitPath);
_ImportElementReferencesVisitor visitor =
new _ImportElementReferencesVisitor(element, unitElement);
- unitAnalysisResult.unit.accept(visitor);
+ unitResult.unit.accept(visitor);
results.addAll(visitor.results);
}
return results;
@@ -675,8 +676,8 @@
List<SearchResult> results = <SearchResult>[];
for (CompilationUnitElement unitElement in element.units) {
String unitPath = unitElement.source.fullName;
- AnalysisResult unitAnalysisResult = await _driver.getResult(unitPath);
- CompilationUnit unit = unitAnalysisResult.unit;
+ ResolvedUnitResult unitResult = await _driver.getResult(unitPath);
+ CompilationUnit unit = unitResult.unit;
for (Directive directive in unit.directives) {
if (directive is PartOfDirective && directive.element == element) {
results.add(new SearchResult._(
@@ -702,8 +703,8 @@
}
// Prepare the unit.
- AnalysisResult analysisResult = await _driver.getResult(path);
- CompilationUnit unit = analysisResult.unit;
+ ResolvedUnitResult unitResult = await _driver.getResult(path);
+ CompilationUnit unit = unitResult.unit;
if (unit == null) {
return const <SearchResult>[];
}
@@ -715,7 +716,7 @@
}
// Prepare the enclosing node.
- AstNode enclosingNode = node.getAncestor(isRootNode);
+ AstNode enclosingNode = node.thisOrAncestorMatching(isRootNode);
if (enclosingNode == null) {
return const <SearchResult>[];
}
@@ -759,10 +760,10 @@
LibraryElement libraryElement = element.library;
for (CompilationUnitElement unitElement in libraryElement.units) {
String unitPath = unitElement.source.fullName;
- AnalysisResult unitAnalysisResult = await _driver.getResult(unitPath);
+ ResolvedUnitResult unitResult = await _driver.getResult(unitPath);
_LocalReferencesVisitor visitor =
new _LocalReferencesVisitor(element, unitElement);
- unitAnalysisResult.unit.accept(visitor);
+ unitResult.unit.accept(visitor);
results.addAll(visitor.results);
}
return results;
diff --git a/pkg/analyzer/lib/src/dart/analysis/session.dart b/pkg/analyzer/lib/src/dart/analysis/session.dart
index b44d556..7f1a46e 100644
--- a/pkg/analyzer/lib/src/dart/analysis/session.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/session.dart
@@ -4,6 +4,7 @@
import 'dart:async';
+import 'package:analyzer/dart/analysis/analysis_context.dart';
import 'package:analyzer/dart/analysis/declared_variables.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
@@ -51,6 +52,9 @@
AnalysisSessionImpl(this._driver);
@override
+ AnalysisContext get analysisContext => _driver.analysisContext;
+
+ @override
DeclaredVariables get declaredVariables => _driver.declaredVariables;
@override
@@ -110,24 +114,36 @@
return libraryElement;
}
+ @deprecated
@override
- Future<ParseResult> getParsedAst(String path) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
- return getParsedAstSync(path);
+ Future<ParseResult> getParsedAst(String path) async => getParsedUnit(path);
+
+ @deprecated
+ @override
+ ParseResult getParsedAstSync(String path) => getParsedUnit(path);
+
+ @override
+ ParsedLibraryResult getParsedLibrary(String path) {
+ _checkConsistency();
+ return _driver.getParsedLibrary(path);
}
@override
- ParseResult getParsedAstSync(String path) {
+ ParsedLibraryResult getParsedLibraryByElement(LibraryElement element) {
+ _checkConsistency();
+ _checkElementOfThisSession(element);
+ return _driver.getParsedLibraryByUri(element.source.uri);
+ }
+
+ @override
+ ParsedUnitResult getParsedUnit(String path) {
_checkConsistency();
return _driver.parseFileSync(path);
}
+ @deprecated
@override
- Future<ResolveResult> getResolvedAst(String path) {
- _checkConsistency();
- return _driver.getResult(path);
- }
+ Future<ResolveResult> getResolvedAst(String path) => getResolvedUnit(path);
@override
Future<ResolvedLibraryResult> getResolvedLibrary(String path) {
@@ -144,6 +160,12 @@
}
@override
+ Future<ResolvedUnitResult> getResolvedUnit(String path) {
+ _checkConsistency();
+ return _driver.getResult(path);
+ }
+
+ @override
Future<SourceKind> getSourceKind(String path) {
_checkConsistency();
return _driver.getSourceKind(path);
@@ -179,11 +201,10 @@
}
void _checkElementOfThisSession(Element element) {
- // TODO(scheglov) Requires 2.2 implementation
-// if (element.session != this) {
-// throw new ArgumentError(
-// '(${element.runtimeType}) $element was not produced by '
-// 'this session.');
-// }
+ if (element.session != this) {
+ throw new ArgumentError(
+ '(${element.runtimeType}) $element was not produced by '
+ 'this session.');
+ }
}
}
diff --git a/pkg/analyzer/lib/src/dart/analysis/session_helper.dart b/pkg/analyzer/lib/src/dart/analysis/session_helper.dart
index e35ec6a..9692a26 100644
--- a/pkg/analyzer/lib/src/dart/analysis/session_helper.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/session_helper.dart
@@ -4,6 +4,7 @@
import 'dart:async';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/element/element.dart';
@@ -15,14 +16,14 @@
class AnalysisSessionHelper {
final AnalysisSession session;
+ final Map<String, ResolvedLibraryResult> _resolvedLibraries = {};
+
AnalysisSessionHelper(this.session);
/// Return the [ClassElement] with the given [className] that is exported
/// from the library with the given [libraryUri], or `null` if the library
/// does not export a class with such name.
Future<ClassElement> getClass(String libraryUri, String className) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var libraryElement = await session.getLibraryByUri(libraryUri);
var element = libraryElement.exportNamespace.get(className);
if (element is ClassElement) {
@@ -32,13 +33,31 @@
}
}
+ /// Return the declaration of the [element], or `null` is the [element]
+ /// is synthetic.
+ Future<ElementDeclarationResult> getElementDeclaration(
+ Element element) async {
+ var libraryPath = element.library.source.fullName;
+ var resolvedLibrary = await _getResolvedLibrary(libraryPath);
+ return resolvedLibrary.getElementDeclaration(element);
+ }
+
+ /// Return the resolved unit that declares the given [element].
+ Future<ResolvedUnitResult> getResolvedUnitByElement(Element element) async {
+ var libraryPath = element.library.source.fullName;
+ var resolvedLibrary = await _getResolvedLibrary(libraryPath);
+
+ var unitPath = element.source.fullName;
+ return resolvedLibrary.units.singleWhere((resolvedUnit) {
+ return resolvedUnit.path == unitPath;
+ });
+ }
+
/// Return the [PropertyAccessorElement] with the given [name] that is
/// exported from the library with the given [uri], or `null` if the
/// library does not export a top-level accessor with such name.
Future<PropertyAccessorElement> getTopLevelPropertyAccessor(
String uri, String name) async {
- // TODO(brianwilkerson) Determine whether this await is necessary.
- await null;
var libraryElement = await session.getLibraryByUri(uri);
var element = libraryElement.exportNamespace.get(name);
if (element is PropertyAccessorElement) {
@@ -47,4 +66,14 @@
return null;
}
}
+
+ /// Return a newly resolved, or cached library with the given [path].
+ Future<ResolvedLibraryResult> _getResolvedLibrary(String path) async {
+ var result = _resolvedLibraries[path];
+ if (result == null) {
+ result = await session.getResolvedLibrary(path);
+ _resolvedLibraries[path] = result;
+ }
+ return result;
+ }
}
diff --git a/pkg/analyzer/lib/src/dart/analysis/uri_converter.dart b/pkg/analyzer/lib/src/dart/analysis/uri_converter.dart
index df11c02..da33b5a 100644
--- a/pkg/analyzer/lib/src/dart/analysis/uri_converter.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/uri_converter.dart
@@ -18,8 +18,8 @@
final AnalysisDriver driver;
/**
- * Initialize a newly created URI converter to use the given [context] and
- * [driver] to perform the conversions.
+ * Initialize a newly created URI converter to use the given [driver] to =
+ * perform the conversions.
*/
DriverBasedUriConverter(this.driver);
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 3db5ed9..b328a9a 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -939,6 +939,15 @@
}
@override
+ T thisOrAncestorOfType<T extends AstNode>() {
+ AstNode node = this;
+ while (node != null && node is! T) {
+ node = node.parent;
+ }
+ return node as T;
+ }
+
+ @override
String toSource() {
StringBuffer buffer = new StringBuffer();
accept(new ToSourceVisitor2(buffer));
@@ -1596,7 +1605,7 @@
/**
* Helper class to allow iteration of child entities of an AST node.
*/
-class ChildEntities extends Object
+class ChildEntities
with IterableMixin<SyntacticEntity>
implements Iterable<SyntacticEntity> {
/**
@@ -2687,17 +2696,21 @@
if (errorCode is CompileTimeErrorCode) {
switch (errorCode) {
case CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL:
+ case CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_INT:
case CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING:
case CompileTimeErrorCode.CONST_EVAL_TYPE_INT:
case CompileTimeErrorCode.CONST_EVAL_TYPE_NUM:
case CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION:
case CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE:
+ case CompileTimeErrorCode.CONST_WITH_NON_CONST:
case CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT:
case CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER:
case CompileTimeErrorCode
.CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST:
case CompileTimeErrorCode.INVALID_CONSTANT:
case CompileTimeErrorCode.MISSING_CONST_IN_LIST_LITERAL:
+ case CompileTimeErrorCode.MISSING_CONST_IN_MAP_LITERAL:
+ case CompileTimeErrorCode.MISSING_CONST_IN_SET_LITERAL:
hasConstError = true;
}
}
@@ -6394,8 +6407,6 @@
*
* newExpression ::=
* ('new' | 'const')? [TypeName] ('.' [SimpleIdentifier])? [ArgumentList]
- *
- * 'new' | 'const' are only optional if the previewDart2 option is enabled.
*/
class InstanceCreationExpressionImpl extends ExpressionImpl
implements InstanceCreationExpression {
@@ -6487,8 +6498,6 @@
/**
* Return `true` if this is an implicit constructor invocations.
- *
- * This can only be `true` when the previewDart2 option is enabled.
*/
bool get isImplicit => keyword == null;
@@ -6531,7 +6540,10 @@
*
* Also note that this method can cause constant evaluation to occur, which
* can be computationally expensive.
+ *
+ * Deprecated: Use `LinterContext.canBeConst` instead.
*/
+ @deprecated
bool canBeConst() {
//
// Verify that the invoked constructor is a const constructor.
@@ -8252,9 +8264,7 @@
/**
* A list of AST nodes that have a common parent.
*/
-class NodeListImpl<E extends AstNode> extends Object
- with ListMixin<E>
- implements NodeList<E> {
+class NodeListImpl<E extends AstNode> with ListMixin<E> implements NodeList<E> {
/**
* The node that is the parent of each of the elements in the list.
*/
@@ -9460,6 +9470,78 @@
}
/**
+ * A literal set.
+ *
+ * setLiteral ::=
+ * 'const'? ('<' [TypeAnnotation] '>')?
+ * '{' [Expression] (',' [Expression])* ','? '}'
+ * | 'const'? ('<' [TypeAnnotation] '>')? '{' '}'
+ */
+class SetLiteralImpl extends TypedLiteralImpl implements SetLiteral {
+ /**
+ * The left curly bracket.
+ */
+ @override
+ Token leftBracket;
+
+ /**
+ * The elements in the set.
+ */
+ NodeList<Expression> _elements;
+
+ /**
+ * The right curly bracket.
+ */
+ @override
+ Token rightBracket;
+
+ /**
+ * Initialize a newly created set literal. The [constKeyword] can be `null` if
+ * the literal is not a constant. The [typeArguments] can be `null` if no type
+ * arguments were declared. The [elements] can be `null` if the set is empty.
+ */
+ SetLiteralImpl(Token constKeyword, TypeArgumentListImpl typeArguments,
+ this.leftBracket, List<Expression> elements, this.rightBracket)
+ : super(constKeyword, typeArguments) {
+ _elements = new NodeListImpl<Expression>(this, elements);
+ }
+
+ @override
+ Token get beginToken {
+ if (constKeyword != null) {
+ return constKeyword;
+ }
+ TypeArgumentList typeArguments = this.typeArguments;
+ if (typeArguments != null) {
+ return typeArguments.beginToken;
+ }
+ return leftBracket;
+ }
+
+ @override
+ // TODO(paulberry): add commas.
+ Iterable<SyntacticEntity> get childEntities => super._childEntities
+ ..add(leftBracket)
+ ..addAll(elements)
+ ..add(rightBracket);
+
+ @override
+ NodeList<Expression> get elements => _elements;
+
+ @override
+ Token get endToken => rightBracket;
+
+ @override
+ E accept<E>(AstVisitor<E> visitor) => visitor.visitSetLiteral(this);
+
+ @override
+ void visitChildren(AstVisitor visitor) {
+ super.visitChildren(visitor);
+ _elements.accept(visitor);
+ }
+}
+
+/**
* A combinator that restricts the names being imported to those in a given list.
*
* showCombinator ::=
diff --git a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
index 6a3c3b5..d12b7a6 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
@@ -832,6 +832,12 @@
ScriptTag scriptTag(Token scriptTag) => new ScriptTagImpl(scriptTag);
@override
+ SetLiteral setLiteral(Token constKeyword, TypeArgumentList typeArguments,
+ Token leftBracket, List<Expression> elements, Token rightBracket) =>
+ new SetLiteralImpl(
+ constKeyword, typeArguments, leftBracket, elements, rightBracket);
+
+ @override
ShowCombinator showCombinator(
Token keyword, List<SimpleIdentifier> shownNames) =>
new ShowCombinatorImpl(keyword, shownNames);
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index f7e6832..2370ed0 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -845,6 +845,14 @@
astFactory.scriptTag(cloneToken(node.scriptTag));
@override
+ SetLiteral visitSetLiteral(SetLiteral node) => astFactory.setLiteral(
+ cloneToken(node.constKeyword),
+ cloneNode(node.typeArguments),
+ cloneToken(node.leftBracket),
+ cloneNodeList(node.elements),
+ cloneToken(node.rightBracket));
+
+ @override
ShowCombinator visitShowCombinator(ShowCombinator node) => astFactory
.showCombinator(cloneToken(node.keyword), cloneNodeList(node.shownNames));
@@ -1988,6 +1996,16 @@
}
@override
+ bool visitSetLiteral(SetLiteral node) {
+ SetLiteral other = _other as SetLiteral;
+ return isEqualTokens(node.constKeyword, other.constKeyword) &&
+ isEqualNodes(node.typeArguments, other.typeArguments) &&
+ isEqualTokens(node.leftBracket, other.leftBracket) &&
+ _isEqualNodeLists(node.elements, other.elements) &&
+ isEqualTokens(node.rightBracket, other.rightBracket);
+ }
+
+ @override
bool visitShowCombinator(ShowCombinator node) {
ShowCombinator other = _other as ShowCombinator;
return isEqualTokens(node.keyword, other.keyword) &&
@@ -2633,7 +2651,7 @@
*
* See [PrefixedIdentifier.isDeferred].
*/
-class DeferredLibraryReferenceDetector extends RecursiveAstVisitor<Object> {
+class DeferredLibraryReferenceDetector extends RecursiveAstVisitor<void> {
/**
* A flag indicating whether an identifier from a deferred library has been
* found.
@@ -2647,13 +2665,12 @@
bool get result => _result;
@override
- Object visitPrefixedIdentifier(PrefixedIdentifier node) {
+ void visitPrefixedIdentifier(PrefixedIdentifier node) {
if (!_result) {
if (node.isDeferred) {
_result = true;
}
}
- return null;
}
}
@@ -3713,6 +3730,18 @@
astFactory.scriptTag(_mapToken(node.scriptTag));
@override
+ SetLiteral visitSetLiteral(SetLiteral node) {
+ SetLiteral copy = astFactory.setLiteral(
+ _mapToken(node.constKeyword),
+ _cloneNode(node.typeArguments),
+ _mapToken(node.leftBracket),
+ _cloneNodeList(node.elements),
+ _mapToken(node.rightBracket));
+ copy.staticType = node.staticType;
+ return copy;
+ }
+
+ @override
ShowCombinator visitShowCombinator(ShowCombinator node) => astFactory
.showCombinator(_mapToken(node.keyword), _cloneNodeList(node.shownNames));
@@ -3959,7 +3988,7 @@
* the [AstNode] with the shortest length whose source range completely
* encompasses the specified range.
*/
-class NodeLocator extends UnifyingAstVisitor<Object> {
+class NodeLocator extends UnifyingAstVisitor<void> {
/**
* The start offset of the range used to identify the node.
*/
@@ -4012,10 +4041,10 @@
}
@override
- Object visitNode(AstNode node) {
+ void visitNode(AstNode node) {
// Don't visit a new tree if the result has been already found.
if (_foundNode != null) {
- return null;
+ return;
}
// Check whether the current node covers the selection.
Token beginToken = node.beginToken;
@@ -4032,11 +4061,8 @@
}
int end = endToken.end;
int start = node.offset;
- if (end < _startOffset) {
- return null;
- }
- if (start > _endOffset) {
- return null;
+ if (end < _startOffset || start > _endOffset) {
+ return;
}
// Check children.
try {
@@ -4050,13 +4076,12 @@
}
// Found a child.
if (_foundNode != null) {
- return null;
+ return;
}
// Check this node.
if (start <= _startOffset && _endOffset <= end) {
_foundNode = node;
}
- return null;
}
}
@@ -4065,7 +4090,7 @@
* More specifically, they will return the deepest [AstNode] which completely
* encompasses the specified range.
*/
-class NodeLocator2 extends UnifyingAstVisitor<Object> {
+class NodeLocator2 extends UnifyingAstVisitor<void> {
/**
* The inclusive start offset of the range used to identify the node.
*/
@@ -4112,10 +4137,10 @@
}
@override
- Object visitNode(AstNode node) {
+ void visitNode(AstNode node) {
// Don't visit a new tree if the result has been already found.
if (_foundNode != null) {
- return null;
+ return;
}
// Check whether the current node covers the selection.
Token beginToken = node.beginToken;
@@ -4132,11 +4157,8 @@
}
int end = endToken.end;
int start = node.offset;
- if (end <= _startOffset) {
- return null;
- }
- if (start > _endOffset) {
- return null;
+ if (end <= _startOffset || start > _endOffset) {
+ return;
}
// Check children.
try {
@@ -4150,13 +4172,12 @@
}
// Found a child.
if (_foundNode != null) {
- return null;
+ return;
}
// Check this node.
if (start <= _startOffset && _endOffset < end) {
_foundNode = node;
}
- return null;
}
}
@@ -5164,6 +5185,14 @@
bool visitScriptTag(ScriptTag scriptTag) => visitNode(scriptTag);
@override
+ bool visitSetLiteral(SetLiteral node) {
+ if (_replaceInList(node.elements)) {
+ return true;
+ }
+ return visitTypedLiteral(node);
+ }
+
+ @override
bool visitShowCombinator(ShowCombinator node) {
if (_replaceInList(node.shownNames)) {
return true;
@@ -6494,6 +6523,21 @@
}
@override
+ bool visitSetLiteral(SetLiteral node) {
+ SetLiteral toNode = this._toNode as SetLiteral;
+ if (_and(
+ _isEqualTokens(node.constKeyword, toNode.constKeyword),
+ _isEqualNodes(node.typeArguments, toNode.typeArguments),
+ _isEqualTokens(node.leftBracket, toNode.leftBracket),
+ _isEqualNodeLists(node.elements, toNode.elements),
+ _isEqualTokens(node.rightBracket, toNode.rightBracket))) {
+ toNode.staticType = node.staticType;
+ return true;
+ }
+ return false;
+ }
+
+ @override
bool visitShowCombinator(ShowCombinator node) {
ShowCombinator toNode = this._toNode as ShowCombinator;
return _and(_isEqualTokens(node.keyword, toNode.keyword),
@@ -6893,7 +6937,7 @@
* Completion test code coverage is 95%. The two basic blocks that are not
* executed cannot be executed. They are included for future reference.
*/
-class ScopedNameFinder extends GeneralizingAstVisitor<Object> {
+class ScopedNameFinder extends GeneralizingAstVisitor<void> {
Declaration _declarationNode;
AstNode _immediateChild;
@@ -6912,112 +6956,104 @@
Map<String, SimpleIdentifier> get locals => _locals;
@override
- Object visitBlock(Block node) {
+ void visitBlock(Block node) {
_checkStatements(node.statements);
- return super.visitBlock(node);
+ super.visitBlock(node);
}
@override
- Object visitCatchClause(CatchClause node) {
+ void visitCatchClause(CatchClause node) {
_addToScope(node.exceptionParameter);
_addToScope(node.stackTraceParameter);
- return super.visitCatchClause(node);
+ super.visitCatchClause(node);
}
@override
- Object visitConstructorDeclaration(ConstructorDeclaration node) {
+ void visitConstructorDeclaration(ConstructorDeclaration node) {
if (!identical(_immediateChild, node.parameters)) {
_addParameters(node.parameters.parameters);
}
_declarationNode = node;
- return null;
}
@override
- Object visitFieldDeclaration(FieldDeclaration node) {
+ void visitFieldDeclaration(FieldDeclaration node) {
_declarationNode = node;
- return null;
}
@override
- Object visitForEachStatement(ForEachStatement node) {
+ void visitForEachStatement(ForEachStatement node) {
DeclaredIdentifier loopVariable = node.loopVariable;
if (loopVariable != null) {
_addToScope(loopVariable.identifier);
}
- return super.visitForEachStatement(node);
+ super.visitForEachStatement(node);
}
@override
- Object visitForStatement(ForStatement node) {
+ void visitForStatement(ForStatement node) {
if (!identical(_immediateChild, node.variables) && node.variables != null) {
_addVariables(node.variables.variables);
}
- return super.visitForStatement(node);
+ super.visitForStatement(node);
}
@override
- Object visitFunctionDeclaration(FunctionDeclaration node) {
+ void visitFunctionDeclaration(FunctionDeclaration node) {
if (node.parent is! FunctionDeclarationStatement) {
_declarationNode = node;
- return null;
+ } else {
+ super.visitFunctionDeclaration(node);
}
- return super.visitFunctionDeclaration(node);
}
@override
- Object visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
+ void visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
_referenceIsWithinLocalFunction = true;
- return super.visitFunctionDeclarationStatement(node);
+ super.visitFunctionDeclarationStatement(node);
}
@override
- Object visitFunctionExpression(FunctionExpression node) {
+ void visitFunctionExpression(FunctionExpression node) {
if (node.parameters != null &&
!identical(_immediateChild, node.parameters)) {
_addParameters(node.parameters.parameters);
}
- return super.visitFunctionExpression(node);
+ super.visitFunctionExpression(node);
}
@override
- Object visitMethodDeclaration(MethodDeclaration node) {
+ void visitMethodDeclaration(MethodDeclaration node) {
_declarationNode = node;
- if (node.parameters == null) {
- return null;
- }
- if (!identical(_immediateChild, node.parameters)) {
+ if (node.parameters != null &&
+ !identical(_immediateChild, node.parameters)) {
_addParameters(node.parameters.parameters);
}
- return null;
}
@override
- Object visitNode(AstNode node) {
+ void visitNode(AstNode node) {
_immediateChild = node;
AstNode parent = node.parent;
if (parent != null) {
parent.accept(this);
}
- return null;
}
@override
- Object visitSwitchMember(SwitchMember node) {
+ void visitSwitchMember(SwitchMember node) {
_checkStatements(node.statements);
- return super.visitSwitchMember(node);
+ super.visitSwitchMember(node);
}
@override
- Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+ void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
_declarationNode = node;
- return null;
}
@override
- Object visitTypeAlias(TypeAlias node) {
+ void visitTypeAlias(TypeAlias node) {
_declarationNode = node;
- return null;
}
void _addParameters(NodeList<FormalParameter> vars) {
@@ -7076,7 +7112,7 @@
* This class has been deprecated. Use the class ToSourceVisitor2 instead.
*/
@deprecated
-class ToSourceVisitor implements AstVisitor<Object> {
+class ToSourceVisitor implements AstVisitor<void> {
/**
* The writer to which the source is to be written.
*/
@@ -7089,38 +7125,34 @@
ToSourceVisitor(this._writer);
@override
- Object visitAdjacentStrings(AdjacentStrings node) {
+ void visitAdjacentStrings(AdjacentStrings node) {
_visitNodeListWithSeparator(node.strings, " ");
- return null;
}
@override
- Object visitAnnotation(Annotation node) {
+ void visitAnnotation(Annotation node) {
_writer.print('@');
_visitNode(node.name);
_visitNodeWithPrefix(".", node.constructorName);
_visitNode(node.arguments);
- return null;
}
@override
- Object visitArgumentList(ArgumentList node) {
+ void visitArgumentList(ArgumentList node) {
_writer.print('(');
_visitNodeListWithSeparator(node.arguments, ", ");
_writer.print(')');
- return null;
}
@override
- Object visitAsExpression(AsExpression node) {
+ void visitAsExpression(AsExpression node) {
_visitNode(node.expression);
_writer.print(" as ");
_visitNode(node.type);
- return null;
}
@override
- bool visitAssertInitializer(AssertInitializer node) {
+ void visitAssertInitializer(AssertInitializer node) {
_writer.print("assert (");
_visitNode(node.condition);
if (node.message != null) {
@@ -7128,11 +7160,10 @@
_visitNode(node.message);
}
_writer.print(")");
- return null;
}
@override
- Object visitAssertStatement(AssertStatement node) {
+ void visitAssertStatement(AssertStatement node) {
_writer.print("assert (");
_visitNode(node.condition);
if (node.message != null) {
@@ -7140,46 +7171,41 @@
_visitNode(node.message);
}
_writer.print(");");
- return null;
}
@override
- Object visitAssignmentExpression(AssignmentExpression node) {
+ void visitAssignmentExpression(AssignmentExpression node) {
_visitNode(node.leftHandSide);
_writer.print(' ');
_writer.print(node.operator.lexeme);
_writer.print(' ');
_visitNode(node.rightHandSide);
- return null;
}
@override
- Object visitAwaitExpression(AwaitExpression node) {
+ void visitAwaitExpression(AwaitExpression node) {
_writer.print("await ");
_visitNode(node.expression);
- return null;
}
@override
- Object visitBinaryExpression(BinaryExpression node) {
+ void visitBinaryExpression(BinaryExpression node) {
_visitNode(node.leftOperand);
_writer.print(' ');
_writer.print(node.operator.lexeme);
_writer.print(' ');
_visitNode(node.rightOperand);
- return null;
}
@override
- Object visitBlock(Block node) {
+ void visitBlock(Block node) {
_writer.print('{');
_visitNodeListWithSeparator(node.statements, " ");
_writer.print('}');
- return null;
}
@override
- Object visitBlockFunctionBody(BlockFunctionBody node) {
+ void visitBlockFunctionBody(BlockFunctionBody node) {
Token keyword = node.keyword;
if (keyword != null) {
_writer.print(keyword.lexeme);
@@ -7189,32 +7215,28 @@
_writer.print(' ');
}
_visitNode(node.block);
- return null;
}
@override
- Object visitBooleanLiteral(BooleanLiteral node) {
+ void visitBooleanLiteral(BooleanLiteral node) {
_writer.print(node.literal.lexeme);
- return null;
}
@override
- Object visitBreakStatement(BreakStatement node) {
+ void visitBreakStatement(BreakStatement node) {
_writer.print("break");
_visitNodeWithPrefix(" ", node.label);
_writer.print(";");
- return null;
}
@override
- Object visitCascadeExpression(CascadeExpression node) {
+ void visitCascadeExpression(CascadeExpression node) {
_visitNode(node.target);
_visitNodeList(node.cascadeSections);
- return null;
}
@override
- Object visitCatchClause(CatchClause node) {
+ void visitCatchClause(CatchClause node) {
_visitNodeWithPrefix("on ", node.exceptionType);
if (node.catchKeyword != null) {
if (node.exceptionType != null) {
@@ -7228,11 +7250,10 @@
_writer.print(" ");
}
_visitNode(node.body);
- return null;
}
@override
- Object visitClassDeclaration(ClassDeclaration node) {
+ void visitClassDeclaration(ClassDeclaration node) {
_visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
_visitTokenWithSuffix(node.abstractKeyword, " ");
_writer.print("class ");
@@ -7244,11 +7265,10 @@
_writer.print(" {");
_visitNodeListWithSeparator(node.members, " ");
_writer.print("}");
- return null;
}
@override
- Object visitClassTypeAlias(ClassTypeAlias node) {
+ void visitClassTypeAlias(ClassTypeAlias node) {
_visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
if (node.abstractKeyword != null) {
_writer.print("abstract ");
@@ -7261,17 +7281,16 @@
_visitNodeWithPrefix(" ", node.withClause);
_visitNodeWithPrefix(" ", node.implementsClause);
_writer.print(";");
- return null;
}
@override
- Object visitComment(Comment node) => null;
+ void visitComment(Comment node) {}
@override
- Object visitCommentReference(CommentReference node) => null;
+ void visitCommentReference(CommentReference node) {}
@override
- Object visitCompilationUnit(CompilationUnit node) {
+ void visitCompilationUnit(CompilationUnit node) {
ScriptTag scriptTag = node.scriptTag;
NodeList<Directive> directives = node.directives;
_visitNode(scriptTag);
@@ -7279,31 +7298,28 @@
_visitNodeListWithSeparatorAndPrefix(prefix, directives, " ");
prefix = scriptTag == null && directives.isEmpty ? "" : " ";
_visitNodeListWithSeparatorAndPrefix(prefix, node.declarations, " ");
- return null;
}
@override
- Object visitConditionalExpression(ConditionalExpression node) {
+ void visitConditionalExpression(ConditionalExpression node) {
_visitNode(node.condition);
_writer.print(" ? ");
_visitNode(node.thenExpression);
_writer.print(" : ");
_visitNode(node.elseExpression);
- return null;
}
@override
- Object visitConfiguration(Configuration node) {
+ void visitConfiguration(Configuration node) {
_writer.print('if (');
_visitNode(node.name);
_visitNodeWithPrefix(" == ", node.value);
_writer.print(') ');
_visitNode(node.uri);
- return null;
}
@override
- Object visitConstructorDeclaration(ConstructorDeclaration node) {
+ void visitConstructorDeclaration(ConstructorDeclaration node) {
_visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
_visitTokenWithSuffix(node.externalKeyword, " ");
_visitTokenWithSuffix(node.constKeyword, " ");
@@ -7314,44 +7330,39 @@
_visitNodeListWithSeparatorAndPrefix(" : ", node.initializers, ", ");
_visitNodeWithPrefix(" = ", node.redirectedConstructor);
_visitFunctionWithPrefix(" ", node.body);
- return null;
}
@override
- Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
+ void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
_visitTokenWithSuffix(node.thisKeyword, ".");
_visitNode(node.fieldName);
_writer.print(" = ");
_visitNode(node.expression);
- return null;
}
@override
- Object visitConstructorName(ConstructorName node) {
+ void visitConstructorName(ConstructorName node) {
_visitNode(node.type);
_visitNodeWithPrefix(".", node.name);
- return null;
}
@override
- Object visitContinueStatement(ContinueStatement node) {
+ void visitContinueStatement(ContinueStatement node) {
_writer.print("continue");
_visitNodeWithPrefix(" ", node.label);
_writer.print(";");
- return null;
}
@override
- Object visitDeclaredIdentifier(DeclaredIdentifier node) {
+ void visitDeclaredIdentifier(DeclaredIdentifier node) {
_visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
_visitTokenWithSuffix(node.keyword, " ");
_visitNodeWithSuffix(node.type, " ");
_visitNode(node.identifier);
- return null;
}
@override
- Object visitDefaultFormalParameter(DefaultFormalParameter node) {
+ void visitDefaultFormalParameter(DefaultFormalParameter node) {
_visitNode(node.parameter);
if (node.separator != null) {
if (node.separator.lexeme != ":") {
@@ -7360,73 +7371,64 @@
_writer.print(node.separator.lexeme);
_visitNodeWithPrefix(" ", node.defaultValue);
}
- return null;
}
@override
- Object visitDoStatement(DoStatement node) {
+ void visitDoStatement(DoStatement node) {
_writer.print("do ");
_visitNode(node.body);
_writer.print(" while (");
_visitNode(node.condition);
_writer.print(");");
- return null;
}
@override
- Object visitDottedName(DottedName node) {
+ void visitDottedName(DottedName node) {
_visitNodeListWithSeparator(node.components, ".");
- return null;
}
@override
- Object visitDoubleLiteral(DoubleLiteral node) {
+ void visitDoubleLiteral(DoubleLiteral node) {
_writer.print(node.literal.lexeme);
- return null;
}
@override
- Object visitEmptyFunctionBody(EmptyFunctionBody node) {
+ void visitEmptyFunctionBody(EmptyFunctionBody node) {
_writer.print(';');
- return null;
}
@override
- Object visitEmptyStatement(EmptyStatement node) {
+ void visitEmptyStatement(EmptyStatement node) {
_writer.print(';');
- return null;
}
@override
- Object visitEnumConstantDeclaration(EnumConstantDeclaration node) {
+ void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
_visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
_visitNode(node.name);
- return null;
}
@override
- Object visitEnumDeclaration(EnumDeclaration node) {
+ void visitEnumDeclaration(EnumDeclaration node) {
_visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
_writer.print("enum ");
_visitNode(node.name);
_writer.print(" {");
_visitNodeListWithSeparator(node.constants, ", ");
_writer.print("}");
- return null;
}
@override
- Object visitExportDirective(ExportDirective node) {
+ void visitExportDirective(ExportDirective node) {
_visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
_writer.print("export ");
_visitNode(node.uri);
_visitNodeListWithSeparatorAndPrefix(" ", node.combinators, " ");
_writer.print(';');
- return null;
}
@override
- Object visitExpressionFunctionBody(ExpressionFunctionBody node) {
+ void visitExpressionFunctionBody(ExpressionFunctionBody node) {
Token keyword = node.keyword;
if (keyword != null) {
_writer.print(keyword.lexeme);
@@ -7437,34 +7439,30 @@
if (node.semicolon != null) {
_writer.print(';');
}
- return null;
}
@override
- Object visitExpressionStatement(ExpressionStatement node) {
+ void visitExpressionStatement(ExpressionStatement node) {
_visitNode(node.expression);
_writer.print(';');
- return null;
}
@override
- Object visitExtendsClause(ExtendsClause node) {
+ void visitExtendsClause(ExtendsClause node) {
_writer.print("extends ");
_visitNode(node.superclass);
- return null;
}
@override
- Object visitFieldDeclaration(FieldDeclaration node) {
+ void visitFieldDeclaration(FieldDeclaration node) {
_visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
_visitTokenWithSuffix(node.staticKeyword, " ");
_visitNode(node.fields);
_writer.print(";");
- return null;
}
@override
- Object visitFieldFormalParameter(FieldFormalParameter node) {
+ void visitFieldFormalParameter(FieldFormalParameter node) {
_visitNodeListWithSeparatorAndSuffix(node.metadata, ' ', ' ');
_visitTokenWithSuffix(node.covariantKeyword, ' ');
_visitTokenWithSuffix(node.keyword, " ");
@@ -7473,11 +7471,10 @@
_visitNode(node.identifier);
_visitNode(node.typeParameters);
_visitNode(node.parameters);
- return null;
}
@override
- Object visitForEachStatement(ForEachStatement node) {
+ void visitForEachStatement(ForEachStatement node) {
DeclaredIdentifier loopVariable = node.loopVariable;
if (node.awaitKeyword != null) {
_writer.print("await ");
@@ -7492,11 +7489,10 @@
_visitNode(node.iterable);
_writer.print(") ");
_visitNode(node.body);
- return null;
}
@override
- Object visitFormalParameterList(FormalParameterList node) {
+ void visitFormalParameterList(FormalParameterList node) {
String groupEnd = null;
_writer.print('(');
NodeList<FormalParameter> parameters = node.parameters;
@@ -7521,11 +7517,10 @@
_writer.print(groupEnd);
}
_writer.print(')');
- return null;
}
@override
- Object visitForStatement(ForStatement node) {
+ void visitForStatement(ForStatement node) {
Expression initialization = node.initialization;
_writer.print("for (");
if (initialization != null) {
@@ -7539,47 +7534,42 @@
_visitNodeListWithSeparatorAndPrefix(" ", node.updaters, ", ");
_writer.print(") ");
_visitNode(node.body);
- return null;
}
@override
- Object visitFunctionDeclaration(FunctionDeclaration node) {
+ void visitFunctionDeclaration(FunctionDeclaration node) {
_visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
_visitTokenWithSuffix(node.externalKeyword, " ");
_visitNodeWithSuffix(node.returnType, " ");
_visitTokenWithSuffix(node.propertyKeyword, " ");
_visitNode(node.name);
_visitNode(node.functionExpression);
- return null;
}
@override
- Object visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
+ void visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
_visitNode(node.functionDeclaration);
- return null;
}
@override
- Object visitFunctionExpression(FunctionExpression node) {
+ void visitFunctionExpression(FunctionExpression node) {
_visitNode(node.typeParameters);
_visitNode(node.parameters);
if (node.body is! EmptyFunctionBody) {
_writer.print(' ');
}
_visitNode(node.body);
- return null;
}
@override
- Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+ void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
_visitNode(node.function);
_visitNode(node.typeArguments);
_visitNode(node.argumentList);
- return null;
}
@override
- Object visitFunctionTypeAlias(FunctionTypeAlias node) {
+ void visitFunctionTypeAlias(FunctionTypeAlias node) {
_visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
_writer.print("typedef ");
_visitNodeWithSuffix(node.returnType, " ");
@@ -7587,66 +7577,59 @@
_visitNode(node.typeParameters);
_visitNode(node.parameters);
_writer.print(";");
- return null;
}
@override
- Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+ void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
_visitNodeListWithSeparatorAndSuffix(node.metadata, ' ', ' ');
_visitTokenWithSuffix(node.covariantKeyword, ' ');
_visitNodeWithSuffix(node.returnType, " ");
_visitNode(node.identifier);
_visitNode(node.typeParameters);
_visitNode(node.parameters);
- return null;
}
@override
- Object visitGenericFunctionType(GenericFunctionType node) {
+ void visitGenericFunctionType(GenericFunctionType node) {
_visitNode(node.returnType);
_writer.print(' Function');
_visitNode(node.typeParameters);
_visitNode(node.parameters);
- return null;
}
@override
- Object visitGenericTypeAlias(GenericTypeAlias node) {
+ void visitGenericTypeAlias(GenericTypeAlias node) {
_visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
_writer.print("typedef ");
_visitNode(node.name);
_visitNode(node.typeParameters);
_writer.print(" = ");
_visitNode(node.functionType);
- return null;
}
@override
- Object visitHideCombinator(HideCombinator node) {
+ void visitHideCombinator(HideCombinator node) {
_writer.print("hide ");
_visitNodeListWithSeparator(node.hiddenNames, ", ");
- return null;
}
@override
- Object visitIfStatement(IfStatement node) {
+ void visitIfStatement(IfStatement node) {
_writer.print("if (");
_visitNode(node.condition);
_writer.print(") ");
_visitNode(node.thenStatement);
_visitNodeWithPrefix(" else ", node.elseStatement);
- return null;
}
@override
- Object visitImplementsClause(ImplementsClause node) {
+ void visitImplementsClause(ImplementsClause node) {
_writer.print("implements ");
_visitNodeListWithSeparator(node.interfaces, ", ");
- return null;
}
@override
- Object visitImportDirective(ImportDirective node) {
+ void visitImportDirective(ImportDirective node) {
_visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
_writer.print("import ");
_visitNode(node.uri);
@@ -7656,11 +7639,10 @@
_visitNodeWithPrefix(" as ", node.prefix);
_visitNodeListWithSeparatorAndPrefix(" ", node.combinators, " ");
_writer.print(';');
- return null;
}
@override
- Object visitIndexExpression(IndexExpression node) {
+ void visitIndexExpression(IndexExpression node) {
if (node.isCascaded) {
_writer.print("..");
} else {
@@ -7669,25 +7651,22 @@
_writer.print('[');
_visitNode(node.index);
_writer.print(']');
- return null;
}
@override
- Object visitInstanceCreationExpression(InstanceCreationExpression node) {
+ void visitInstanceCreationExpression(InstanceCreationExpression node) {
_visitTokenWithSuffix(node.keyword, " ");
_visitNode(node.constructorName);
_visitNode(node.argumentList);
- return null;
}
@override
- Object visitIntegerLiteral(IntegerLiteral node) {
+ void visitIntegerLiteral(IntegerLiteral node) {
_writer.print(node.literal.lexeme);
- return null;
}
@override
- Object visitInterpolationExpression(InterpolationExpression node) {
+ void visitInterpolationExpression(InterpolationExpression node) {
if (node.rightBracket != null) {
_writer.print("\${");
_visitNode(node.expression);
@@ -7696,17 +7675,15 @@
_writer.print("\$");
_visitNode(node.expression);
}
- return null;
}
@override
- Object visitInterpolationString(InterpolationString node) {
+ void visitInterpolationString(InterpolationString node) {
_writer.print(node.contents.lexeme);
- return null;
}
@override
- Object visitIsExpression(IsExpression node) {
+ void visitIsExpression(IsExpression node) {
_visitNode(node.expression);
if (node.notOperator == null) {
_writer.print(" is ");
@@ -7714,40 +7691,35 @@
_writer.print(" is! ");
}
_visitNode(node.type);
- return null;
}
@override
- Object visitLabel(Label node) {
+ void visitLabel(Label node) {
_visitNode(node.label);
_writer.print(":");
- return null;
}
@override
- Object visitLabeledStatement(LabeledStatement node) {
+ void visitLabeledStatement(LabeledStatement node) {
_visitNodeListWithSeparatorAndSuffix(node.labels, " ", " ");
_visitNode(node.statement);
- return null;
}
@override
- Object visitLibraryDirective(LibraryDirective node) {
+ void visitLibraryDirective(LibraryDirective node) {
_visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
_writer.print("library ");
_visitNode(node.name);
_writer.print(';');
- return null;
}
@override
- Object visitLibraryIdentifier(LibraryIdentifier node) {
+ void visitLibraryIdentifier(LibraryIdentifier node) {
_writer.print(node.name);
- return null;
}
@override
- Object visitListLiteral(ListLiteral node) {
+ void visitListLiteral(ListLiteral node) {
if (node.constKeyword != null) {
_writer.print(node.constKeyword.lexeme);
_writer.print(' ');
@@ -7756,11 +7728,10 @@
_writer.print("[");
_visitNodeListWithSeparator(node.elements, ", ");
_writer.print("]");
- return null;
}
@override
- Object visitMapLiteral(MapLiteral node) {
+ void visitMapLiteral(MapLiteral node) {
if (node.constKeyword != null) {
_writer.print(node.constKeyword.lexeme);
_writer.print(' ');
@@ -7769,19 +7740,17 @@
_writer.print("{");
_visitNodeListWithSeparator(node.entries, ", ");
_writer.print("}");
- return null;
}
@override
- Object visitMapLiteralEntry(MapLiteralEntry node) {
+ void visitMapLiteralEntry(MapLiteralEntry node) {
_visitNode(node.key);
_writer.print(" : ");
_visitNode(node.value);
- return null;
}
@override
- Object visitMethodDeclaration(MethodDeclaration node) {
+ void visitMethodDeclaration(MethodDeclaration node) {
_visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
_visitTokenWithSuffix(node.externalKeyword, " ");
_visitTokenWithSuffix(node.modifierKeyword, " ");
@@ -7794,11 +7763,10 @@
_visitNode(node.parameters);
}
_visitFunctionWithPrefix(" ", node.body);
- return null;
}
@override
- Object visitMethodInvocation(MethodInvocation node) {
+ void visitMethodInvocation(MethodInvocation node) {
if (node.isCascaded) {
_writer.print("..");
} else {
@@ -7810,11 +7778,10 @@
_visitNode(node.methodName);
_visitNode(node.typeArguments);
_visitNode(node.argumentList);
- return null;
}
@override
- bool visitMixinDeclaration(MixinDeclaration node) {
+ void visitMixinDeclaration(MixinDeclaration node) {
_visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
_writer.print("mixin ");
_visitNode(node.name);
@@ -7824,94 +7791,82 @@
_writer.print(" {");
_visitNodeListWithSeparator(node.members, " ");
_writer.print("}");
- return null;
}
@override
- Object visitNamedExpression(NamedExpression node) {
+ void visitNamedExpression(NamedExpression node) {
_visitNode(node.name);
_visitNodeWithPrefix(" ", node.expression);
- return null;
}
@override
- Object visitNativeClause(NativeClause node) {
+ void visitNativeClause(NativeClause node) {
_writer.print("native ");
_visitNode(node.name);
- return null;
}
@override
- Object visitNativeFunctionBody(NativeFunctionBody node) {
+ void visitNativeFunctionBody(NativeFunctionBody node) {
_writer.print("native ");
_visitNode(node.stringLiteral);
_writer.print(';');
- return null;
}
@override
- Object visitNullLiteral(NullLiteral node) {
+ void visitNullLiteral(NullLiteral node) {
_writer.print("null");
- return null;
}
@override
- bool visitOnClause(OnClause node) {
+ void visitOnClause(OnClause node) {
_writer.print('on ');
_visitNodeListWithSeparator(node.superclassConstraints, ", ");
- return null;
}
@override
- Object visitParenthesizedExpression(ParenthesizedExpression node) {
+ void visitParenthesizedExpression(ParenthesizedExpression node) {
_writer.print('(');
_visitNode(node.expression);
_writer.print(')');
- return null;
}
@override
- Object visitPartDirective(PartDirective node) {
+ void visitPartDirective(PartDirective node) {
_visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
_writer.print("part ");
_visitNode(node.uri);
_writer.print(';');
- return null;
}
@override
- Object visitPartOfDirective(PartOfDirective node) {
+ void visitPartOfDirective(PartOfDirective node) {
_visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
_writer.print("part of ");
_visitNode(node.libraryName);
_writer.print(';');
- return null;
}
@override
- Object visitPostfixExpression(PostfixExpression node) {
+ void visitPostfixExpression(PostfixExpression node) {
_visitNode(node.operand);
_writer.print(node.operator.lexeme);
- return null;
}
@override
- Object visitPrefixedIdentifier(PrefixedIdentifier node) {
+ void visitPrefixedIdentifier(PrefixedIdentifier node) {
_visitNode(node.prefix);
_writer.print('.');
_visitNode(node.identifier);
- return null;
}
@override
- Object visitPrefixExpression(PrefixExpression node) {
+ void visitPrefixExpression(PrefixExpression node) {
_writer.print(node.operator.lexeme);
_visitNode(node.operand);
- return null;
}
@override
- Object visitPropertyAccess(PropertyAccess node) {
+ void visitPropertyAccess(PropertyAccess node) {
if (node.isCascaded) {
_writer.print("..");
} else {
@@ -7919,26 +7874,23 @@
_writer.print(node.operator.lexeme);
}
_visitNode(node.propertyName);
- return null;
}
@override
- Object visitRedirectingConstructorInvocation(
+ void visitRedirectingConstructorInvocation(
RedirectingConstructorInvocation node) {
_writer.print("this");
_visitNodeWithPrefix(".", node.constructorName);
_visitNode(node.argumentList);
- return null;
}
@override
- Object visitRethrowExpression(RethrowExpression node) {
+ void visitRethrowExpression(RethrowExpression node) {
_writer.print("rethrow");
- return null;
}
@override
- Object visitReturnStatement(ReturnStatement node) {
+ void visitReturnStatement(ReturnStatement node) {
Expression expression = node.expression;
if (expression == null) {
_writer.print("return;");
@@ -7947,24 +7899,33 @@
expression.accept(this);
_writer.print(";");
}
- return null;
}
@override
- Object visitScriptTag(ScriptTag node) {
+ void visitScriptTag(ScriptTag node) {
_writer.print(node.scriptTag.lexeme);
- return null;
}
@override
- Object visitShowCombinator(ShowCombinator node) {
+ void visitSetLiteral(SetLiteral node) {
+ if (node.constKeyword != null) {
+ _writer.print(node.constKeyword.lexeme);
+ _writer.print(' ');
+ }
+ _visitNodeWithSuffix(node.typeArguments, " ");
+ _writer.print("{");
+ _visitNodeListWithSeparator(node.elements, ", ");
+ _writer.print("}");
+ }
+
+ @override
+ void visitShowCombinator(ShowCombinator node) {
_writer.print("show ");
_visitNodeListWithSeparator(node.shownNames, ", ");
- return null;
}
@override
- Object visitSimpleFormalParameter(SimpleFormalParameter node) {
+ void visitSimpleFormalParameter(SimpleFormalParameter node) {
_visitNodeListWithSeparatorAndSuffix(node.metadata, ' ', ' ');
_visitTokenWithSuffix(node.covariantKeyword, ' ');
_visitTokenWithSuffix(node.keyword, " ");
@@ -7973,71 +7934,62 @@
_writer.print(' ');
}
_visitNode(node.identifier);
- return null;
}
@override
- Object visitSimpleIdentifier(SimpleIdentifier node) {
+ void visitSimpleIdentifier(SimpleIdentifier node) {
_writer.print(node.token.lexeme);
- return null;
}
@override
- Object visitSimpleStringLiteral(SimpleStringLiteral node) {
+ void visitSimpleStringLiteral(SimpleStringLiteral node) {
_writer.print(node.literal.lexeme);
- return null;
}
@override
- Object visitStringInterpolation(StringInterpolation node) {
+ void visitStringInterpolation(StringInterpolation node) {
_visitNodeList(node.elements);
- return null;
}
@override
- Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+ void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
_writer.print("super");
_visitNodeWithPrefix(".", node.constructorName);
_visitNode(node.argumentList);
- return null;
}
@override
- Object visitSuperExpression(SuperExpression node) {
+ void visitSuperExpression(SuperExpression node) {
_writer.print("super");
- return null;
}
@override
- Object visitSwitchCase(SwitchCase node) {
+ void visitSwitchCase(SwitchCase node) {
_visitNodeListWithSeparatorAndSuffix(node.labels, " ", " ");
_writer.print("case ");
_visitNode(node.expression);
_writer.print(": ");
_visitNodeListWithSeparator(node.statements, " ");
- return null;
}
@override
- Object visitSwitchDefault(SwitchDefault node) {
+ void visitSwitchDefault(SwitchDefault node) {
_visitNodeListWithSeparatorAndSuffix(node.labels, " ", " ");
_writer.print("default: ");
_visitNodeListWithSeparator(node.statements, " ");
- return null;
}
@override
- Object visitSwitchStatement(SwitchStatement node) {
+ void visitSwitchStatement(SwitchStatement node) {
_writer.print("switch (");
_visitNode(node.expression);
_writer.print(") {");
_visitNodeListWithSeparator(node.members, " ");
_writer.print("}");
- return null;
}
@override
- Object visitSymbolLiteral(SymbolLiteral node) {
+ void visitSymbolLiteral(SymbolLiteral node) {
_writer.print("#");
List<Token> components = node.components;
for (int i = 0; i < components.length; i++) {
@@ -8046,110 +7998,96 @@
}
_writer.print(components[i].lexeme);
}
- return null;
}
@override
- Object visitThisExpression(ThisExpression node) {
+ void visitThisExpression(ThisExpression node) {
_writer.print("this");
- return null;
}
@override
- Object visitThrowExpression(ThrowExpression node) {
+ void visitThrowExpression(ThrowExpression node) {
_writer.print("throw ");
_visitNode(node.expression);
- return null;
}
@override
- Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+ void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
_visitNodeWithSuffix(node.variables, ";");
- return null;
}
@override
- Object visitTryStatement(TryStatement node) {
+ void visitTryStatement(TryStatement node) {
_writer.print("try ");
_visitNode(node.body);
_visitNodeListWithSeparatorAndPrefix(" ", node.catchClauses, " ");
_visitNodeWithPrefix(" finally ", node.finallyBlock);
- return null;
}
@override
- Object visitTypeArgumentList(TypeArgumentList node) {
+ void visitTypeArgumentList(TypeArgumentList node) {
_writer.print('<');
_visitNodeListWithSeparator(node.arguments, ", ");
_writer.print('>');
- return null;
}
@override
- Object visitTypeName(TypeName node) {
+ void visitTypeName(TypeName node) {
_visitNode(node.name);
_visitNode(node.typeArguments);
- return null;
}
@override
- Object visitTypeParameter(TypeParameter node) {
+ void visitTypeParameter(TypeParameter node) {
_visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
_visitNode(node.name);
_visitNodeWithPrefix(" extends ", node.bound);
- return null;
}
@override
- Object visitTypeParameterList(TypeParameterList node) {
+ void visitTypeParameterList(TypeParameterList node) {
_writer.print('<');
_visitNodeListWithSeparator(node.typeParameters, ", ");
_writer.print('>');
- return null;
}
@override
- Object visitVariableDeclaration(VariableDeclaration node) {
+ void visitVariableDeclaration(VariableDeclaration node) {
_visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
_visitNode(node.name);
_visitNodeWithPrefix(" = ", node.initializer);
- return null;
}
@override
- Object visitVariableDeclarationList(VariableDeclarationList node) {
+ void visitVariableDeclarationList(VariableDeclarationList node) {
_visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
_visitTokenWithSuffix(node.keyword, " ");
_visitNodeWithSuffix(node.type, " ");
_visitNodeListWithSeparator(node.variables, ", ");
- return null;
}
@override
- Object visitVariableDeclarationStatement(VariableDeclarationStatement node) {
+ void visitVariableDeclarationStatement(VariableDeclarationStatement node) {
_visitNode(node.variables);
_writer.print(";");
- return null;
}
@override
- Object visitWhileStatement(WhileStatement node) {
+ void visitWhileStatement(WhileStatement node) {
_writer.print("while (");
_visitNode(node.condition);
_writer.print(") ");
_visitNode(node.body);
- return null;
}
@override
- Object visitWithClause(WithClause node) {
+ void visitWithClause(WithClause node) {
_writer.print("with ");
_visitNodeListWithSeparator(node.mixinTypes, ", ");
- return null;
}
@override
- Object visitYieldStatement(YieldStatement node) {
+ void visitYieldStatement(YieldStatement node) {
if (node.star != null) {
_writer.print("yield* ");
} else {
@@ -8157,7 +8095,6 @@
}
_visitNode(node.expression);
_writer.print(";");
- return null;
}
/**
@@ -8280,7 +8217,7 @@
* A visitor used to write a source representation of a visited AST node (and
* all of it's children) to a sink.
*/
-class ToSourceVisitor2 implements AstVisitor<Object> {
+class ToSourceVisitor2 implements AstVisitor<void> {
/**
* The sink to which the source is to be written.
*/
@@ -8419,38 +8356,34 @@
}
@override
- Object visitAdjacentStrings(AdjacentStrings node) {
+ void visitAdjacentStrings(AdjacentStrings node) {
safelyVisitNodeListWithSeparator(node.strings, " ");
- return null;
}
@override
- Object visitAnnotation(Annotation node) {
+ void visitAnnotation(Annotation node) {
sink.write('@');
safelyVisitNode(node.name);
safelyVisitNodeWithPrefix(".", node.constructorName);
safelyVisitNode(node.arguments);
- return null;
}
@override
- Object visitArgumentList(ArgumentList node) {
+ void visitArgumentList(ArgumentList node) {
sink.write('(');
safelyVisitNodeListWithSeparator(node.arguments, ", ");
sink.write(')');
- return null;
}
@override
- Object visitAsExpression(AsExpression node) {
+ void visitAsExpression(AsExpression node) {
safelyVisitNode(node.expression);
sink.write(" as ");
safelyVisitNode(node.type);
- return null;
}
@override
- bool visitAssertInitializer(AssertInitializer node) {
+ void visitAssertInitializer(AssertInitializer node) {
sink.write("assert (");
safelyVisitNode(node.condition);
if (node.message != null) {
@@ -8458,11 +8391,10 @@
safelyVisitNode(node.message);
}
sink.write(");");
- return null;
}
@override
- Object visitAssertStatement(AssertStatement node) {
+ void visitAssertStatement(AssertStatement node) {
sink.write("assert (");
safelyVisitNode(node.condition);
if (node.message != null) {
@@ -8470,46 +8402,41 @@
safelyVisitNode(node.message);
}
sink.write(");");
- return null;
}
@override
- Object visitAssignmentExpression(AssignmentExpression node) {
+ void visitAssignmentExpression(AssignmentExpression node) {
safelyVisitNode(node.leftHandSide);
sink.write(' ');
sink.write(node.operator.lexeme);
sink.write(' ');
safelyVisitNode(node.rightHandSide);
- return null;
}
@override
- Object visitAwaitExpression(AwaitExpression node) {
+ void visitAwaitExpression(AwaitExpression node) {
sink.write("await ");
safelyVisitNode(node.expression);
- return null;
}
@override
- Object visitBinaryExpression(BinaryExpression node) {
+ void visitBinaryExpression(BinaryExpression node) {
_writeOperand(node, node.leftOperand);
sink.write(' ');
sink.write(node.operator.lexeme);
sink.write(' ');
_writeOperand(node, node.rightOperand);
- return null;
}
@override
- Object visitBlock(Block node) {
+ void visitBlock(Block node) {
sink.write('{');
safelyVisitNodeListWithSeparator(node.statements, " ");
sink.write('}');
- return null;
}
@override
- Object visitBlockFunctionBody(BlockFunctionBody node) {
+ void visitBlockFunctionBody(BlockFunctionBody node) {
Token keyword = node.keyword;
if (keyword != null) {
sink.write(keyword.lexeme);
@@ -8519,32 +8446,28 @@
sink.write(' ');
}
safelyVisitNode(node.block);
- return null;
}
@override
- Object visitBooleanLiteral(BooleanLiteral node) {
+ void visitBooleanLiteral(BooleanLiteral node) {
sink.write(node.literal.lexeme);
- return null;
}
@override
- Object visitBreakStatement(BreakStatement node) {
+ void visitBreakStatement(BreakStatement node) {
sink.write("break");
safelyVisitNodeWithPrefix(" ", node.label);
sink.write(";");
- return null;
}
@override
- Object visitCascadeExpression(CascadeExpression node) {
+ void visitCascadeExpression(CascadeExpression node) {
safelyVisitNode(node.target);
safelyVisitNodeList(node.cascadeSections);
- return null;
}
@override
- Object visitCatchClause(CatchClause node) {
+ void visitCatchClause(CatchClause node) {
safelyVisitNodeWithPrefix("on ", node.exceptionType);
if (node.catchKeyword != null) {
if (node.exceptionType != null) {
@@ -8558,11 +8481,10 @@
sink.write(" ");
}
safelyVisitNode(node.body);
- return null;
}
@override
- Object visitClassDeclaration(ClassDeclaration node) {
+ void visitClassDeclaration(ClassDeclaration node) {
safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
safelyVisitTokenWithSuffix(node.abstractKeyword, " ");
sink.write("class ");
@@ -8574,11 +8496,10 @@
sink.write(" {");
safelyVisitNodeListWithSeparator(node.members, " ");
sink.write("}");
- return null;
}
@override
- Object visitClassTypeAlias(ClassTypeAlias node) {
+ void visitClassTypeAlias(ClassTypeAlias node) {
safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
if (node.abstractKeyword != null) {
sink.write("abstract ");
@@ -8591,17 +8512,16 @@
safelyVisitNodeWithPrefix(" ", node.withClause);
safelyVisitNodeWithPrefix(" ", node.implementsClause);
sink.write(";");
- return null;
}
@override
- Object visitComment(Comment node) => null;
+ void visitComment(Comment node) {}
@override
- Object visitCommentReference(CommentReference node) => null;
+ void visitCommentReference(CommentReference node) {}
@override
- Object visitCompilationUnit(CompilationUnit node) {
+ void visitCompilationUnit(CompilationUnit node) {
ScriptTag scriptTag = node.scriptTag;
NodeList<Directive> directives = node.directives;
safelyVisitNode(scriptTag);
@@ -8609,31 +8529,28 @@
safelyVisitNodeListWithSeparatorAndPrefix(prefix, directives, " ");
prefix = scriptTag == null && directives.isEmpty ? "" : " ";
safelyVisitNodeListWithSeparatorAndPrefix(prefix, node.declarations, " ");
- return null;
}
@override
- Object visitConditionalExpression(ConditionalExpression node) {
+ void visitConditionalExpression(ConditionalExpression node) {
safelyVisitNode(node.condition);
sink.write(" ? ");
safelyVisitNode(node.thenExpression);
sink.write(" : ");
safelyVisitNode(node.elseExpression);
- return null;
}
@override
- Object visitConfiguration(Configuration node) {
+ void visitConfiguration(Configuration node) {
sink.write('if (');
safelyVisitNode(node.name);
safelyVisitNodeWithPrefix(" == ", node.value);
sink.write(') ');
safelyVisitNode(node.uri);
- return null;
}
@override
- Object visitConstructorDeclaration(ConstructorDeclaration node) {
+ void visitConstructorDeclaration(ConstructorDeclaration node) {
safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
safelyVisitTokenWithSuffix(node.externalKeyword, " ");
safelyVisitTokenWithSuffix(node.constKeyword, " ");
@@ -8644,44 +8561,39 @@
safelyVisitNodeListWithSeparatorAndPrefix(" : ", node.initializers, ", ");
safelyVisitNodeWithPrefix(" = ", node.redirectedConstructor);
safelyVisitFunctionWithPrefix(" ", node.body);
- return null;
}
@override
- Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
+ void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
safelyVisitTokenWithSuffix(node.thisKeyword, ".");
safelyVisitNode(node.fieldName);
sink.write(" = ");
safelyVisitNode(node.expression);
- return null;
}
@override
- Object visitConstructorName(ConstructorName node) {
+ void visitConstructorName(ConstructorName node) {
safelyVisitNode(node.type);
safelyVisitNodeWithPrefix(".", node.name);
- return null;
}
@override
- Object visitContinueStatement(ContinueStatement node) {
+ void visitContinueStatement(ContinueStatement node) {
sink.write("continue");
safelyVisitNodeWithPrefix(" ", node.label);
sink.write(";");
- return null;
}
@override
- Object visitDeclaredIdentifier(DeclaredIdentifier node) {
+ void visitDeclaredIdentifier(DeclaredIdentifier node) {
safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
safelyVisitTokenWithSuffix(node.keyword, " ");
safelyVisitNodeWithSuffix(node.type, " ");
safelyVisitNode(node.identifier);
- return null;
}
@override
- Object visitDefaultFormalParameter(DefaultFormalParameter node) {
+ void visitDefaultFormalParameter(DefaultFormalParameter node) {
safelyVisitNode(node.parameter);
if (node.separator != null) {
if (node.separator.lexeme != ":") {
@@ -8690,73 +8602,64 @@
sink.write(node.separator.lexeme);
safelyVisitNodeWithPrefix(" ", node.defaultValue);
}
- return null;
}
@override
- Object visitDoStatement(DoStatement node) {
+ void visitDoStatement(DoStatement node) {
sink.write("do ");
safelyVisitNode(node.body);
sink.write(" while (");
safelyVisitNode(node.condition);
sink.write(");");
- return null;
}
@override
- Object visitDottedName(DottedName node) {
+ void visitDottedName(DottedName node) {
safelyVisitNodeListWithSeparator(node.components, ".");
- return null;
}
@override
- Object visitDoubleLiteral(DoubleLiteral node) {
+ void visitDoubleLiteral(DoubleLiteral node) {
sink.write(node.literal.lexeme);
- return null;
}
@override
- Object visitEmptyFunctionBody(EmptyFunctionBody node) {
+ void visitEmptyFunctionBody(EmptyFunctionBody node) {
sink.write(';');
- return null;
}
@override
- Object visitEmptyStatement(EmptyStatement node) {
+ void visitEmptyStatement(EmptyStatement node) {
sink.write(';');
- return null;
}
@override
- Object visitEnumConstantDeclaration(EnumConstantDeclaration node) {
+ void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
safelyVisitNode(node.name);
- return null;
}
@override
- Object visitEnumDeclaration(EnumDeclaration node) {
+ void visitEnumDeclaration(EnumDeclaration node) {
safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
sink.write("enum ");
safelyVisitNode(node.name);
sink.write(" {");
safelyVisitNodeListWithSeparator(node.constants, ", ");
sink.write("}");
- return null;
}
@override
- Object visitExportDirective(ExportDirective node) {
+ void visitExportDirective(ExportDirective node) {
safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
sink.write("export ");
safelyVisitNode(node.uri);
safelyVisitNodeListWithSeparatorAndPrefix(" ", node.combinators, " ");
sink.write(';');
- return null;
}
@override
- Object visitExpressionFunctionBody(ExpressionFunctionBody node) {
+ void visitExpressionFunctionBody(ExpressionFunctionBody node) {
Token keyword = node.keyword;
if (keyword != null) {
sink.write(keyword.lexeme);
@@ -8767,34 +8670,30 @@
if (node.semicolon != null) {
sink.write(';');
}
- return null;
}
@override
- Object visitExpressionStatement(ExpressionStatement node) {
+ void visitExpressionStatement(ExpressionStatement node) {
safelyVisitNode(node.expression);
sink.write(';');
- return null;
}
@override
- Object visitExtendsClause(ExtendsClause node) {
+ void visitExtendsClause(ExtendsClause node) {
sink.write("extends ");
safelyVisitNode(node.superclass);
- return null;
}
@override
- Object visitFieldDeclaration(FieldDeclaration node) {
+ void visitFieldDeclaration(FieldDeclaration node) {
safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
safelyVisitTokenWithSuffix(node.staticKeyword, " ");
safelyVisitNode(node.fields);
sink.write(";");
- return null;
}
@override
- Object visitFieldFormalParameter(FieldFormalParameter node) {
+ void visitFieldFormalParameter(FieldFormalParameter node) {
safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, ' ', ' ');
safelyVisitTokenWithSuffix(node.covariantKeyword, ' ');
safelyVisitTokenWithSuffix(node.keyword, " ");
@@ -8803,11 +8702,10 @@
safelyVisitNode(node.identifier);
safelyVisitNode(node.typeParameters);
safelyVisitNode(node.parameters);
- return null;
}
@override
- Object visitForEachStatement(ForEachStatement node) {
+ void visitForEachStatement(ForEachStatement node) {
DeclaredIdentifier loopVariable = node.loopVariable;
if (node.awaitKeyword != null) {
sink.write("await ");
@@ -8822,11 +8720,10 @@
safelyVisitNode(node.iterable);
sink.write(") ");
safelyVisitNode(node.body);
- return null;
}
@override
- Object visitFormalParameterList(FormalParameterList node) {
+ void visitFormalParameterList(FormalParameterList node) {
String groupEnd = null;
sink.write('(');
NodeList<FormalParameter> parameters = node.parameters;
@@ -8851,11 +8748,10 @@
sink.write(groupEnd);
}
sink.write(')');
- return null;
}
@override
- Object visitForStatement(ForStatement node) {
+ void visitForStatement(ForStatement node) {
Expression initialization = node.initialization;
sink.write("for (");
if (initialization != null) {
@@ -8869,47 +8765,42 @@
safelyVisitNodeListWithSeparatorAndPrefix(" ", node.updaters, ", ");
sink.write(") ");
safelyVisitNode(node.body);
- return null;
}
@override
- Object visitFunctionDeclaration(FunctionDeclaration node) {
+ void visitFunctionDeclaration(FunctionDeclaration node) {
safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
safelyVisitTokenWithSuffix(node.externalKeyword, " ");
safelyVisitNodeWithSuffix(node.returnType, " ");
safelyVisitTokenWithSuffix(node.propertyKeyword, " ");
safelyVisitNode(node.name);
safelyVisitNode(node.functionExpression);
- return null;
}
@override
- Object visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
+ void visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
safelyVisitNode(node.functionDeclaration);
- return null;
}
@override
- Object visitFunctionExpression(FunctionExpression node) {
+ void visitFunctionExpression(FunctionExpression node) {
safelyVisitNode(node.typeParameters);
safelyVisitNode(node.parameters);
if (node.body is! EmptyFunctionBody) {
sink.write(' ');
}
safelyVisitNode(node.body);
- return null;
}
@override
- Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+ void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
safelyVisitNode(node.function);
safelyVisitNode(node.typeArguments);
safelyVisitNode(node.argumentList);
- return null;
}
@override
- Object visitFunctionTypeAlias(FunctionTypeAlias node) {
+ void visitFunctionTypeAlias(FunctionTypeAlias node) {
safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
sink.write("typedef ");
safelyVisitNodeWithSuffix(node.returnType, " ");
@@ -8917,66 +8808,59 @@
safelyVisitNode(node.typeParameters);
safelyVisitNode(node.parameters);
sink.write(";");
- return null;
}
@override
- Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+ void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, ' ', ' ');
safelyVisitTokenWithSuffix(node.covariantKeyword, ' ');
safelyVisitNodeWithSuffix(node.returnType, " ");
safelyVisitNode(node.identifier);
safelyVisitNode(node.typeParameters);
safelyVisitNode(node.parameters);
- return null;
}
@override
- Object visitGenericFunctionType(GenericFunctionType node) {
+ void visitGenericFunctionType(GenericFunctionType node) {
safelyVisitNode(node.returnType);
sink.write(' Function');
safelyVisitNode(node.typeParameters);
safelyVisitNode(node.parameters);
- return null;
}
@override
- Object visitGenericTypeAlias(GenericTypeAlias node) {
+ void visitGenericTypeAlias(GenericTypeAlias node) {
safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
sink.write("typedef ");
safelyVisitNode(node.name);
safelyVisitNode(node.typeParameters);
sink.write(" = ");
safelyVisitNode(node.functionType);
- return null;
}
@override
- Object visitHideCombinator(HideCombinator node) {
+ void visitHideCombinator(HideCombinator node) {
sink.write("hide ");
safelyVisitNodeListWithSeparator(node.hiddenNames, ", ");
- return null;
}
@override
- Object visitIfStatement(IfStatement node) {
+ void visitIfStatement(IfStatement node) {
sink.write("if (");
safelyVisitNode(node.condition);
sink.write(") ");
safelyVisitNode(node.thenStatement);
safelyVisitNodeWithPrefix(" else ", node.elseStatement);
- return null;
}
@override
- Object visitImplementsClause(ImplementsClause node) {
+ void visitImplementsClause(ImplementsClause node) {
sink.write("implements ");
safelyVisitNodeListWithSeparator(node.interfaces, ", ");
- return null;
}
@override
- Object visitImportDirective(ImportDirective node) {
+ void visitImportDirective(ImportDirective node) {
safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
sink.write("import ");
safelyVisitNode(node.uri);
@@ -8986,11 +8870,10 @@
safelyVisitNodeWithPrefix(" as ", node.prefix);
safelyVisitNodeListWithSeparatorAndPrefix(" ", node.combinators, " ");
sink.write(';');
- return null;
}
@override
- Object visitIndexExpression(IndexExpression node) {
+ void visitIndexExpression(IndexExpression node) {
if (node.isCascaded) {
sink.write("..");
} else {
@@ -8999,25 +8882,22 @@
sink.write('[');
safelyVisitNode(node.index);
sink.write(']');
- return null;
}
@override
- Object visitInstanceCreationExpression(InstanceCreationExpression node) {
+ void visitInstanceCreationExpression(InstanceCreationExpression node) {
safelyVisitTokenWithSuffix(node.keyword, " ");
safelyVisitNode(node.constructorName);
safelyVisitNode(node.argumentList);
- return null;
}
@override
- Object visitIntegerLiteral(IntegerLiteral node) {
+ void visitIntegerLiteral(IntegerLiteral node) {
sink.write(node.literal.lexeme);
- return null;
}
@override
- Object visitInterpolationExpression(InterpolationExpression node) {
+ void visitInterpolationExpression(InterpolationExpression node) {
if (node.rightBracket != null) {
sink.write("\${");
safelyVisitNode(node.expression);
@@ -9026,17 +8906,15 @@
sink.write("\$");
safelyVisitNode(node.expression);
}
- return null;
}
@override
- Object visitInterpolationString(InterpolationString node) {
+ void visitInterpolationString(InterpolationString node) {
sink.write(node.contents.lexeme);
- return null;
}
@override
- Object visitIsExpression(IsExpression node) {
+ void visitIsExpression(IsExpression node) {
safelyVisitNode(node.expression);
if (node.notOperator == null) {
sink.write(" is ");
@@ -9044,40 +8922,35 @@
sink.write(" is! ");
}
safelyVisitNode(node.type);
- return null;
}
@override
- Object visitLabel(Label node) {
+ void visitLabel(Label node) {
safelyVisitNode(node.label);
sink.write(":");
- return null;
}
@override
- Object visitLabeledStatement(LabeledStatement node) {
+ void visitLabeledStatement(LabeledStatement node) {
safelyVisitNodeListWithSeparatorAndSuffix(node.labels, " ", " ");
safelyVisitNode(node.statement);
- return null;
}
@override
- Object visitLibraryDirective(LibraryDirective node) {
+ void visitLibraryDirective(LibraryDirective node) {
safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
sink.write("library ");
safelyVisitNode(node.name);
sink.write(';');
- return null;
}
@override
- Object visitLibraryIdentifier(LibraryIdentifier node) {
+ void visitLibraryIdentifier(LibraryIdentifier node) {
sink.write(node.name);
- return null;
}
@override
- Object visitListLiteral(ListLiteral node) {
+ void visitListLiteral(ListLiteral node) {
if (node.constKeyword != null) {
sink.write(node.constKeyword.lexeme);
sink.write(' ');
@@ -9086,11 +8959,10 @@
sink.write("[");
safelyVisitNodeListWithSeparator(node.elements, ", ");
sink.write("]");
- return null;
}
@override
- Object visitMapLiteral(MapLiteral node) {
+ void visitMapLiteral(MapLiteral node) {
if (node.constKeyword != null) {
sink.write(node.constKeyword.lexeme);
sink.write(' ');
@@ -9099,19 +8971,17 @@
sink.write("{");
safelyVisitNodeListWithSeparator(node.entries, ", ");
sink.write("}");
- return null;
}
@override
- Object visitMapLiteralEntry(MapLiteralEntry node) {
+ void visitMapLiteralEntry(MapLiteralEntry node) {
safelyVisitNode(node.key);
sink.write(" : ");
safelyVisitNode(node.value);
- return null;
}
@override
- Object visitMethodDeclaration(MethodDeclaration node) {
+ void visitMethodDeclaration(MethodDeclaration node) {
safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
safelyVisitTokenWithSuffix(node.externalKeyword, " ");
safelyVisitTokenWithSuffix(node.modifierKeyword, " ");
@@ -9124,11 +8994,10 @@
safelyVisitNode(node.parameters);
}
safelyVisitFunctionWithPrefix(" ", node.body);
- return null;
}
@override
- Object visitMethodInvocation(MethodInvocation node) {
+ void visitMethodInvocation(MethodInvocation node) {
if (node.isCascaded) {
sink.write("..");
} else {
@@ -9140,11 +9009,10 @@
safelyVisitNode(node.methodName);
safelyVisitNode(node.typeArguments);
safelyVisitNode(node.argumentList);
- return null;
}
@override
- bool visitMixinDeclaration(MixinDeclaration node) {
+ void visitMixinDeclaration(MixinDeclaration node) {
safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
sink.write("mixin ");
safelyVisitNode(node.name);
@@ -9154,94 +9022,82 @@
sink.write(" {");
safelyVisitNodeListWithSeparator(node.members, " ");
sink.write("}");
- return null;
}
@override
- Object visitNamedExpression(NamedExpression node) {
+ void visitNamedExpression(NamedExpression node) {
safelyVisitNode(node.name);
safelyVisitNodeWithPrefix(" ", node.expression);
- return null;
}
@override
- Object visitNativeClause(NativeClause node) {
+ void visitNativeClause(NativeClause node) {
sink.write("native ");
safelyVisitNode(node.name);
- return null;
}
@override
- Object visitNativeFunctionBody(NativeFunctionBody node) {
+ void visitNativeFunctionBody(NativeFunctionBody node) {
sink.write("native ");
safelyVisitNode(node.stringLiteral);
sink.write(';');
- return null;
}
@override
- Object visitNullLiteral(NullLiteral node) {
+ void visitNullLiteral(NullLiteral node) {
sink.write("null");
- return null;
}
@override
- bool visitOnClause(OnClause node) {
+ void visitOnClause(OnClause node) {
sink.write('on ');
safelyVisitNodeListWithSeparator(node.superclassConstraints, ", ");
- return null;
}
@override
- Object visitParenthesizedExpression(ParenthesizedExpression node) {
+ void visitParenthesizedExpression(ParenthesizedExpression node) {
sink.write('(');
safelyVisitNode(node.expression);
sink.write(')');
- return null;
}
@override
- Object visitPartDirective(PartDirective node) {
+ void visitPartDirective(PartDirective node) {
safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
sink.write("part ");
safelyVisitNode(node.uri);
sink.write(';');
- return null;
}
@override
- Object visitPartOfDirective(PartOfDirective node) {
+ void visitPartOfDirective(PartOfDirective node) {
safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
sink.write("part of ");
safelyVisitNode(node.libraryName);
sink.write(';');
- return null;
}
@override
- Object visitPostfixExpression(PostfixExpression node) {
+ void visitPostfixExpression(PostfixExpression node) {
_writeOperand(node, node.operand);
sink.write(node.operator.lexeme);
- return null;
}
@override
- Object visitPrefixedIdentifier(PrefixedIdentifier node) {
+ void visitPrefixedIdentifier(PrefixedIdentifier node) {
safelyVisitNode(node.prefix);
sink.write('.');
safelyVisitNode(node.identifier);
- return null;
}
@override
- Object visitPrefixExpression(PrefixExpression node) {
+ void visitPrefixExpression(PrefixExpression node) {
sink.write(node.operator.lexeme);
_writeOperand(node, node.operand);
- return null;
}
@override
- Object visitPropertyAccess(PropertyAccess node) {
+ void visitPropertyAccess(PropertyAccess node) {
if (node.isCascaded) {
sink.write("..");
} else {
@@ -9249,26 +9105,23 @@
sink.write(node.operator.lexeme);
}
safelyVisitNode(node.propertyName);
- return null;
}
@override
- Object visitRedirectingConstructorInvocation(
+ void visitRedirectingConstructorInvocation(
RedirectingConstructorInvocation node) {
sink.write("this");
safelyVisitNodeWithPrefix(".", node.constructorName);
safelyVisitNode(node.argumentList);
- return null;
}
@override
- Object visitRethrowExpression(RethrowExpression node) {
+ void visitRethrowExpression(RethrowExpression node) {
sink.write("rethrow");
- return null;
}
@override
- Object visitReturnStatement(ReturnStatement node) {
+ void visitReturnStatement(ReturnStatement node) {
Expression expression = node.expression;
if (expression == null) {
sink.write("return;");
@@ -9277,24 +9130,33 @@
expression.accept(this);
sink.write(";");
}
- return null;
}
@override
- Object visitScriptTag(ScriptTag node) {
+ void visitScriptTag(ScriptTag node) {
sink.write(node.scriptTag.lexeme);
- return null;
}
@override
- Object visitShowCombinator(ShowCombinator node) {
+ void visitSetLiteral(SetLiteral node) {
+ if (node.constKeyword != null) {
+ sink.write(node.constKeyword.lexeme);
+ sink.write(' ');
+ }
+ safelyVisitNodeWithSuffix(node.typeArguments, " ");
+ sink.write("{");
+ safelyVisitNodeListWithSeparator(node.elements, ", ");
+ sink.write("}");
+ }
+
+ @override
+ void visitShowCombinator(ShowCombinator node) {
sink.write("show ");
safelyVisitNodeListWithSeparator(node.shownNames, ", ");
- return null;
}
@override
- Object visitSimpleFormalParameter(SimpleFormalParameter node) {
+ void visitSimpleFormalParameter(SimpleFormalParameter node) {
safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, ' ', ' ');
safelyVisitTokenWithSuffix(node.covariantKeyword, ' ');
safelyVisitTokenWithSuffix(node.keyword, " ");
@@ -9303,71 +9165,62 @@
sink.write(' ');
}
safelyVisitNode(node.identifier);
- return null;
}
@override
- Object visitSimpleIdentifier(SimpleIdentifier node) {
+ void visitSimpleIdentifier(SimpleIdentifier node) {
sink.write(node.token.lexeme);
- return null;
}
@override
- Object visitSimpleStringLiteral(SimpleStringLiteral node) {
+ void visitSimpleStringLiteral(SimpleStringLiteral node) {
sink.write(node.literal.lexeme);
- return null;
}
@override
- Object visitStringInterpolation(StringInterpolation node) {
+ void visitStringInterpolation(StringInterpolation node) {
safelyVisitNodeList(node.elements);
- return null;
}
@override
- Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+ void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
sink.write("super");
safelyVisitNodeWithPrefix(".", node.constructorName);
safelyVisitNode(node.argumentList);
- return null;
}
@override
- Object visitSuperExpression(SuperExpression node) {
+ void visitSuperExpression(SuperExpression node) {
sink.write("super");
- return null;
}
@override
- Object visitSwitchCase(SwitchCase node) {
+ void visitSwitchCase(SwitchCase node) {
safelyVisitNodeListWithSeparatorAndSuffix(node.labels, " ", " ");
sink.write("case ");
safelyVisitNode(node.expression);
sink.write(": ");
safelyVisitNodeListWithSeparator(node.statements, " ");
- return null;
}
@override
- Object visitSwitchDefault(SwitchDefault node) {
+ void visitSwitchDefault(SwitchDefault node) {
safelyVisitNodeListWithSeparatorAndSuffix(node.labels, " ", " ");
sink.write("default: ");
safelyVisitNodeListWithSeparator(node.statements, " ");
- return null;
}
@override
- Object visitSwitchStatement(SwitchStatement node) {
+ void visitSwitchStatement(SwitchStatement node) {
sink.write("switch (");
safelyVisitNode(node.expression);
sink.write(") {");
safelyVisitNodeListWithSeparator(node.members, " ");
sink.write("}");
- return null;
}
@override
- Object visitSymbolLiteral(SymbolLiteral node) {
+ void visitSymbolLiteral(SymbolLiteral node) {
sink.write("#");
List<Token> components = node.components;
for (int i = 0; i < components.length; i++) {
@@ -9376,110 +9229,96 @@
}
sink.write(components[i].lexeme);
}
- return null;
}
@override
- Object visitThisExpression(ThisExpression node) {
+ void visitThisExpression(ThisExpression node) {
sink.write("this");
- return null;
}
@override
- Object visitThrowExpression(ThrowExpression node) {
+ void visitThrowExpression(ThrowExpression node) {
sink.write("throw ");
safelyVisitNode(node.expression);
- return null;
}
@override
- Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+ void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
safelyVisitNodeWithSuffix(node.variables, ";");
- return null;
}
@override
- Object visitTryStatement(TryStatement node) {
+ void visitTryStatement(TryStatement node) {
sink.write("try ");
safelyVisitNode(node.body);
safelyVisitNodeListWithSeparatorAndPrefix(" ", node.catchClauses, " ");
safelyVisitNodeWithPrefix(" finally ", node.finallyBlock);
- return null;
}
@override
- Object visitTypeArgumentList(TypeArgumentList node) {
+ void visitTypeArgumentList(TypeArgumentList node) {
sink.write('<');
safelyVisitNodeListWithSeparator(node.arguments, ", ");
sink.write('>');
- return null;
}
@override
- Object visitTypeName(TypeName node) {
+ void visitTypeName(TypeName node) {
safelyVisitNode(node.name);
safelyVisitNode(node.typeArguments);
- return null;
}
@override
- Object visitTypeParameter(TypeParameter node) {
+ void visitTypeParameter(TypeParameter node) {
safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
safelyVisitNode(node.name);
safelyVisitNodeWithPrefix(" extends ", node.bound);
- return null;
}
@override
- Object visitTypeParameterList(TypeParameterList node) {
+ void visitTypeParameterList(TypeParameterList node) {
sink.write('<');
safelyVisitNodeListWithSeparator(node.typeParameters, ", ");
sink.write('>');
- return null;
}
@override
- Object visitVariableDeclaration(VariableDeclaration node) {
+ void visitVariableDeclaration(VariableDeclaration node) {
safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
safelyVisitNode(node.name);
safelyVisitNodeWithPrefix(" = ", node.initializer);
- return null;
}
@override
- Object visitVariableDeclarationList(VariableDeclarationList node) {
+ void visitVariableDeclarationList(VariableDeclarationList node) {
safelyVisitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
safelyVisitTokenWithSuffix(node.keyword, " ");
safelyVisitNodeWithSuffix(node.type, " ");
safelyVisitNodeListWithSeparator(node.variables, ", ");
- return null;
}
@override
- Object visitVariableDeclarationStatement(VariableDeclarationStatement node) {
+ void visitVariableDeclarationStatement(VariableDeclarationStatement node) {
safelyVisitNode(node.variables);
sink.write(";");
- return null;
}
@override
- Object visitWhileStatement(WhileStatement node) {
+ void visitWhileStatement(WhileStatement node) {
sink.write("while (");
safelyVisitNode(node.condition);
sink.write(") ");
safelyVisitNode(node.body);
- return null;
}
@override
- Object visitWithClause(WithClause node) {
+ void visitWithClause(WithClause node) {
sink.write("with ");
safelyVisitNodeListWithSeparator(node.mixinTypes, ", ");
- return null;
}
@override
- Object visitYieldStatement(YieldStatement node) {
+ void visitYieldStatement(YieldStatement node) {
if (node.star != null) {
sink.write("yield* ");
} else {
@@ -9487,7 +9326,6 @@
}
safelyVisitNode(node.expression);
sink.write(";");
- return null;
}
void _writeOperand(Expression node, Expression operand) {
diff --git a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
index d333f97..b271890 100644
--- a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
+++ b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2018, 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.
@@ -23,7 +23,7 @@
/// for additional errors and warnings not covered by the parser and resolver.
/// In particular, it looks for errors and warnings related to constant
/// expressions.
-class ConstantVerifier extends RecursiveAstVisitor<Object> {
+class ConstantVerifier extends RecursiveAstVisitor<void> {
/// The error reporter by which errors will be reported.
final ErrorReporter _errorReporter;
@@ -71,7 +71,7 @@
}
@override
- Object visitAnnotation(Annotation node) {
+ void visitAnnotation(Annotation node) {
super.visitAnnotation(node);
// check annotation creation
Element element = node.element;
@@ -80,14 +80,14 @@
if (!element.isConst) {
_errorReporter.reportErrorForNode(
CompileTimeErrorCode.NON_CONSTANT_ANNOTATION_CONSTRUCTOR, node);
- return null;
+ return;
}
// should have arguments
ArgumentList argumentList = node.arguments;
if (argumentList == null) {
_errorReporter.reportErrorForNode(
CompileTimeErrorCode.NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS, node);
- return null;
+ return;
}
// arguments should be constants
_validateConstantArguments(argumentList);
@@ -99,28 +99,26 @@
_errorReporter.reportErrorForNode(
HintCode.INVALID_SEALED_ANNOTATION, node.parent, [node.element.name]);
}
- return null;
}
@override
- Object visitConstructorDeclaration(ConstructorDeclaration node) {
+ void visitConstructorDeclaration(ConstructorDeclaration node) {
if (node.constKeyword != null) {
_validateConstructorInitializers(node);
_validateFieldInitializers(node.parent as ClassDeclaration, node);
}
_validateDefaultValues(node.parameters);
- return super.visitConstructorDeclaration(node);
+ super.visitConstructorDeclaration(node);
}
@override
- Object visitFunctionExpression(FunctionExpression node) {
+ void visitFunctionExpression(FunctionExpression node) {
super.visitFunctionExpression(node);
_validateDefaultValues(node.parameters);
- return null;
}
@override
- Object visitInstanceCreationExpression(InstanceCreationExpression node) {
+ void visitInstanceCreationExpression(InstanceCreationExpression node) {
if (node.isConst) {
TypeName typeName = node.constructorName.type;
_checkForConstWithTypeParameters(typeName);
@@ -138,14 +136,13 @@
constantVisitor,
_errorReporter);
}
- return null;
} else {
- return super.visitInstanceCreationExpression(node);
+ super.visitInstanceCreationExpression(node);
}
}
@override
- Object visitListLiteral(ListLiteral node) {
+ void visitListLiteral(ListLiteral node) {
super.visitListLiteral(node);
if (node.isConst) {
DartObjectImpl result;
@@ -160,11 +157,10 @@
}
}
}
- return null;
}
@override
- Object visitMapLiteral(MapLiteral node) {
+ void visitMapLiteral(MapLiteral node) {
super.visitMapLiteral(node);
bool isConst = node.isConst;
bool reportEqualKeys = true;
@@ -227,18 +223,41 @@
StaticWarningCode.EQUAL_KEYS_IN_MAP, invalidKeys[i]);
}
}
- return null;
}
@override
- Object visitMethodDeclaration(MethodDeclaration node) {
+ void visitMethodDeclaration(MethodDeclaration node) {
super.visitMethodDeclaration(node);
_validateDefaultValues(node.parameters);
- return null;
}
@override
- Object visitSwitchStatement(SwitchStatement node) {
+ void visitSetLiteral(SetLiteral node) {
+ super.visitSetLiteral(node);
+ if (node.isConst) {
+ DartObjectImpl result;
+ for (Expression element in node.elements) {
+ result =
+ _validate(element, CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT);
+ if (result != null) {
+ _reportErrorIfFromDeferredLibrary(
+ element,
+ CompileTimeErrorCode
+ .NON_CONSTANT_SET_ELEMENT_FROM_DEFERRED_LIBRARY);
+ DartType type = result.type;
+ if (_implementsEqualsWhenNotAllowed(type)) {
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.CONST_SET_ELEMENT_TYPE_IMPLEMENTS_EQUALS,
+ element,
+ [type.displayName]);
+ }
+ }
+ }
+ }
+ }
+
+ @override
+ void visitSwitchStatement(SwitchStatement node) {
// TODO(paulberry): to minimize error messages, it would be nice to
// compare all types with the most popular type rather than the first
// type.
@@ -274,11 +293,11 @@
if (!foundError) {
_checkForCaseExpressionTypeImplementsEquals(node, firstType);
}
- return super.visitSwitchStatement(node);
+ super.visitSwitchStatement(node);
}
@override
- Object visitVariableDeclaration(VariableDeclaration node) {
+ void visitVariableDeclaration(VariableDeclaration node) {
super.visitVariableDeclaration(node);
Expression initializer = node.initializer;
if (initializer != null && (node.isConst || node.isFinal)) {
@@ -290,7 +309,7 @@
// values computed if the value was needed (e.g. final variables in a
// class containing const constructors).
assert(!node.isConst);
- return null;
+ return;
}
_reportErrors(result.errors,
CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE);
@@ -299,7 +318,6 @@
CompileTimeErrorCode
.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE_FROM_DEFERRED_LIBRARY);
}
- return null;
}
/// This verifies that the passed switch statement does not have a case
@@ -409,12 +427,12 @@
identical(dataErrorCode,
CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING) ||
identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL) ||
+ identical(
+ dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_INT) ||
identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_INT) ||
identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM) ||
identical(dataErrorCode,
CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT) ||
- identical(dataErrorCode,
- CheckedModeCompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION) ||
identical(
dataErrorCode,
CheckedModeCompileTimeErrorCode
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
index 3cab468..922caa0 100644
--- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart
+++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -14,6 +14,7 @@
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/dart/constant/utilities.dart';
import 'package:analyzer/src/dart/constant/value.dart';
import 'package:analyzer/src/dart/element/element.dart';
@@ -36,6 +37,7 @@
* Parameter to "fromEnvironment" methods that denotes the default value.
*/
static String _DEFAULT_VALUE_PARAM = "defaultValue";
+
/**
* Source of RegExp matching declarable operator names.
* From sdk/lib/internal/symbol.dart.
@@ -84,6 +86,11 @@
final DeclaredVariables _declaredVariables;
/**
+ * Return the object representing the state of active experiments.
+ */
+ final Experiments experiments;
+
+ /**
* Validator used to verify correct dependency analysis when running unit
* tests.
*/
@@ -103,12 +110,14 @@
*/
ConstantEvaluationEngine(TypeProvider typeProvider, this._declaredVariables,
{ConstantEvaluationValidator validator,
+ Experiments experiments,
TypeSystem typeSystem,
this.forAnalysisDriver: false})
: typeProvider = typeProvider,
validator =
validator ?? new ConstantEvaluationValidator_ForProduction(),
- typeSystem = typeSystem ?? new StrongTypeSystemImpl(typeProvider);
+ typeSystem = typeSystem ?? new StrongTypeSystemImpl(typeProvider),
+ experiments = experiments ?? new Experiments(new AnalysisOptionsImpl());
/**
* Check that the arguments to a call to fromEnvironment() are correct. The
@@ -246,7 +255,7 @@
// ignore it here.
constant.evaluationResult = new EvaluationResultImpl(null);
}
- } else if (element is ConstructorElementImpl &&
+ } else if (element is ConstructorElement &&
element.isConst &&
constNode.arguments != null) {
RecordingErrorListener errorListener = new RecordingErrorListener();
@@ -445,6 +454,7 @@
CompileTimeErrorCode.CONST_WITH_NON_CONST, node);
return null;
}
+
if (!getConstructorImpl(constructor).isCycleFree) {
// It's not safe to evaluate this constructor, so bail out.
// TODO(paulberry): ensure that a reasonable error message is produced
@@ -453,34 +463,35 @@
// itself")
return new DartObjectImpl.validWithUnknownValue(constructor.returnType);
}
+
int argumentCount = arguments.length;
- List<DartObjectImpl> argumentValues =
- new List<DartObjectImpl>(argumentCount);
- List<DartObjectImpl> positionalArguments = <DartObjectImpl>[];
- List<Expression> argumentNodes = new List<Expression>(argumentCount);
- Map<String, DartObjectImpl> namedArgumentValues =
- new HashMap<String, DartObjectImpl>();
- Map<String, NamedExpression> namedArgumentNodes =
- new HashMap<String, NamedExpression>();
+ var argumentValues = new List<DartObjectImpl>(argumentCount);
+ Map<String, NamedExpression> namedNodes;
+ Map<String, DartObjectImpl> namedValues;
for (int i = 0; i < argumentCount; i++) {
Expression argument = arguments[i];
if (argument is NamedExpression) {
+ namedNodes ??= new HashMap<String, NamedExpression>();
+ namedValues ??= new HashMap<String, DartObjectImpl>();
String name = argument.name.label.name;
- namedArgumentValues[name] =
- constantVisitor._valueOf(argument.expression);
- namedArgumentNodes[name] = argument;
- argumentValues[i] = typeProvider.nullObject;
+ namedNodes[name] = argument;
+ namedValues[name] = constantVisitor._valueOf(argument.expression);
} else {
var argumentValue = constantVisitor._valueOf(argument);
argumentValues[i] = argumentValue;
- positionalArguments.add(argumentValue);
- argumentNodes[i] = argument;
}
}
+ namedNodes ??= const {};
+ namedValues ??= const {};
+
if (invocation == null) {
invocation = new ConstructorInvocation(
- constructor, positionalArguments, namedArgumentValues);
+ constructor,
+ argumentValues,
+ namedValues,
+ );
}
+
constructor = followConstantRedirectionChain(constructor);
InterfaceType definingClass = constructor.returnType as InterfaceType;
if (constructor.isFactory) {
@@ -489,7 +500,7 @@
// that we can emulate.
if (constructor.name == "fromEnvironment") {
if (!checkFromEnvironmentArguments(
- arguments, argumentValues, namedArgumentValues, definingClass)) {
+ arguments, argumentValues, namedValues, definingClass)) {
errorReporter.reportErrorForNode(
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, node);
return null;
@@ -503,7 +514,7 @@
return computeValueFromEnvironment(
valueFromEnvironment,
new DartObjectImpl(typeProvider.boolType, BoolState.FALSE_STATE),
- namedArgumentValues);
+ namedValues);
} else if (definingClass == typeProvider.intType) {
DartObject valueFromEnvironment;
valueFromEnvironment =
@@ -511,7 +522,7 @@
return computeValueFromEnvironment(
valueFromEnvironment,
new DartObjectImpl(typeProvider.nullType, NullState.NULL_STATE),
- namedArgumentValues);
+ namedValues);
} else if (definingClass == typeProvider.stringType) {
DartObject valueFromEnvironment;
valueFromEnvironment =
@@ -519,13 +530,12 @@
return computeValueFromEnvironment(
valueFromEnvironment,
new DartObjectImpl(typeProvider.nullType, NullState.NULL_STATE),
- namedArgumentValues);
+ namedValues);
}
} else if (constructor.name == "" &&
definingClass == typeProvider.symbolType &&
argumentCount == 1) {
- if (!checkSymbolArguments(
- arguments, argumentValues, namedArgumentValues)) {
+ if (!checkSymbolArguments(arguments, argumentValues, namedValues)) {
errorReporter.reportErrorForNode(
CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, node);
return null;
@@ -562,28 +572,10 @@
// into the current ErrorReporter, because they usually happen in a
// different source. But they still should cause a constant evaluation
// error for the current node.
- var externalErrorListener = new RecordingErrorListener();
+ var externalErrorListener = new BooleanErrorListener();
var externalErrorReporter =
new ErrorReporter(externalErrorListener, constructor.source);
- void reportLocalErrorForRecordedExternalErrors() {
- ErrorCode errorCode;
- for (AnalysisError error in externalErrorListener.errors) {
- if (error.errorCode is CompileTimeErrorCode) {
- errorCode = CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION;
- break;
- }
- if (error.errorCode is CheckedModeCompileTimeErrorCode) {
- errorCode =
- CheckedModeCompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION;
- break;
- }
- }
- if (errorCode != null) {
- errorReporter.reportErrorForNode(errorCode, node);
- }
- }
-
// Start with final fields that are initialized at their declaration site.
List<FieldElement> fields = constructor.enclosingElement.fields;
for (int i = 0; i < fields.length; i++) {
@@ -629,11 +621,11 @@
DartObjectImpl argumentValue = null;
AstNode errorTarget = null;
if (baseParameter.isNamed) {
- argumentValue = namedArgumentValues[baseParameter.name];
- errorTarget = namedArgumentNodes[baseParameter.name];
+ argumentValue = namedValues[baseParameter.name];
+ errorTarget = namedNodes[baseParameter.name];
} else if (i < argumentCount) {
argumentValue = argumentValues[i];
- errorTarget = argumentNodes[i];
+ errorTarget = arguments[i];
}
if (errorTarget == null) {
// No argument node that we can direct error messages to, because we
@@ -695,7 +687,8 @@
lexicalEnvironment: parameterMap);
String superName = null;
NodeList<Expression> superArguments = null;
- for (ConstructorInitializer initializer in initializers) {
+ for (var i = 0; i < initializers.length; i++) {
+ var initializer = initializers[i];
if (initializer is ConstructorFieldInitializer) {
Expression initializerExpression = initializer.expression;
DartObjectImpl evaluationResult =
@@ -743,23 +736,24 @@
initializerVisitor,
externalErrorReporter,
invocation: invocation);
- reportLocalErrorForRecordedExternalErrors();
+ if (externalErrorListener.errorReported) {
+ errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, node);
+ }
return result;
}
} else if (initializer is AssertInitializer) {
Expression condition = initializer.condition;
if (condition == null) {
errorReporter.reportErrorForNode(
- CheckedModeCompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
- node);
+ CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, node);
}
DartObjectImpl evaluationResult = condition.accept(initializerVisitor);
if (evaluationResult == null ||
!evaluationResult.isBool ||
evaluationResult.toBoolValue() != true) {
errorReporter.reportErrorForNode(
- CheckedModeCompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
- node);
+ CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, node);
return null;
}
}
@@ -778,7 +772,10 @@
superArguments, initializerVisitor, externalErrorReporter);
}
}
- reportLocalErrorForRecordedExternalErrors();
+ if (externalErrorListener.errorReported) {
+ errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, node);
+ }
return new DartObjectImpl(
definingClass, new GenericState(fieldMap, invocation: invocation));
}
@@ -1075,10 +1072,9 @@
}
/**
- * Convenience getter to gain access to the [evalationEngine]'s type
- * provider.
+ * Return the object representing the state of active experiments.
*/
- TypeProvider get _typeProvider => evaluationEngine.typeProvider;
+ Experiments get experiments => evaluationEngine.experiments;
/**
* Convenience getter to gain access to the [evaluationEngine]'s type system.
@@ -1086,6 +1082,12 @@
TypeSystem get typeSystem => evaluationEngine.typeSystem;
/**
+ * Convenience getter to gain access to the [evaluationEngine]'s type
+ * provider.
+ */
+ TypeProvider get _typeProvider => evaluationEngine.typeProvider;
+
+ /**
* Given a [type] that may contain free type variables, evaluate them against
* the current lexical environment and return the substituted type.
*/
@@ -1133,27 +1135,50 @@
}
@override
+ DartObjectImpl visitAsExpression(AsExpression node) {
+ if (experiments.constantUpdate2018) {
+ DartObjectImpl expressionResult = node.expression.accept(this);
+ DartObjectImpl typeResult = node.type.accept(this);
+ return _dartObjectComputer.castToType(node, expressionResult, typeResult);
+ }
+ // TODO(brianwilkerson) Figure out which error to report.
+ _error(node, null);
+ return null;
+ }
+
+ @override
DartObjectImpl visitBinaryExpression(BinaryExpression node) {
TokenType operatorType = node.operator.type;
DartObjectImpl leftResult = node.leftOperand.accept(this);
// evaluate lazy operators
if (operatorType == TokenType.AMPERSAND_AMPERSAND) {
- return _dartObjectComputer.logicalAnd(
+ return _dartObjectComputer.lazyAnd(
node, leftResult, () => node.rightOperand.accept(this));
} else if (operatorType == TokenType.BAR_BAR) {
- return _dartObjectComputer.logicalOr(
+ return _dartObjectComputer.lazyOr(
node, leftResult, () => node.rightOperand.accept(this));
+ } else if (operatorType == TokenType.QUESTION_QUESTION) {
+ if (experiments.constantUpdate2018) {
+ return _dartObjectComputer.lazyQuestionQuestion(
+ node, leftResult, () => node.rightOperand.accept(this));
+ } else {
+ return _dartObjectComputer.eagerQuestionQuestion(
+ node, leftResult, node.rightOperand.accept(this));
+ }
}
// evaluate eager operators
DartObjectImpl rightResult = node.rightOperand.accept(this);
if (operatorType == TokenType.AMPERSAND) {
- return _dartObjectComputer.bitAnd(node, leftResult, rightResult);
+ return _dartObjectComputer.eagerAnd(
+ node, leftResult, rightResult, experiments.constantUpdate2018);
} else if (operatorType == TokenType.BANG_EQ) {
return _dartObjectComputer.notEqual(node, leftResult, rightResult);
} else if (operatorType == TokenType.BAR) {
- return _dartObjectComputer.bitOr(node, leftResult, rightResult);
+ return _dartObjectComputer.eagerOr(
+ node, leftResult, rightResult, experiments.constantUpdate2018);
} else if (operatorType == TokenType.CARET) {
- return _dartObjectComputer.bitXor(node, leftResult, rightResult);
+ return _dartObjectComputer.eagerXor(
+ node, leftResult, rightResult, experiments.constantUpdate2018);
} else if (operatorType == TokenType.EQ_EQ) {
return _dartObjectComputer.equalEqual(node, leftResult, rightResult);
} else if (operatorType == TokenType.GT) {
@@ -1181,9 +1206,6 @@
return _dartObjectComputer.divide(node, leftResult, rightResult);
} else if (operatorType == TokenType.TILDE_SLASH) {
return _dartObjectComputer.integerDivide(node, leftResult, rightResult);
- } else if (operatorType == TokenType.QUESTION_QUESTION) {
- return _dartObjectComputer.questionQuestion(
- node, leftResult, rightResult);
} else {
// TODO(brianwilkerson) Figure out which error to report.
_error(node, null);
@@ -1199,6 +1221,30 @@
DartObjectImpl visitConditionalExpression(ConditionalExpression node) {
Expression condition = node.condition;
DartObjectImpl conditionResult = condition.accept(this);
+ if (experiments.constantUpdate2018) {
+ if (conditionResult == null) {
+ return conditionResult;
+ } else if (!conditionResult.isBool) {
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL, condition);
+ return null;
+ }
+ conditionResult = _dartObjectComputer.applyBooleanConversion(
+ condition, conditionResult);
+ if (conditionResult == null) {
+ return conditionResult;
+ }
+ if (conditionResult.toBoolValue() == true) {
+ return node.thenExpression.accept(this);
+ } else if (conditionResult.toBoolValue() == false) {
+ return node.elseExpression.accept(this);
+ }
+ // We used to return an object with a known type and an unknown value, but
+ // we can't do that without evaluating both the 'then' and 'else'
+ // expressions, and we're not suppose to do that under lazy semantics. I'm
+ // not sure which failure mode is worse.
+ return null;
+ }
DartObjectImpl thenResult = node.thenExpression.accept(this);
DartObjectImpl elseResult = node.elseExpression.accept(this);
if (conditionResult == null) {
@@ -1270,6 +1316,18 @@
new DartObjectImpl(_typeProvider.stringType, new StringState(node.value));
@override
+ DartObjectImpl visitIsExpression(IsExpression node) {
+ if (experiments.constantUpdate2018) {
+ DartObjectImpl expressionResult = node.expression.accept(this);
+ DartObjectImpl typeResult = node.type.accept(this);
+ return _dartObjectComputer.typeTest(node, expressionResult, typeResult);
+ }
+ // TODO(brianwilkerson) Figure out which error to report.
+ _error(node, null);
+ return null;
+ }
+
+ @override
DartObjectImpl visitListLiteral(ListLiteral node) {
if (!node.isConst) {
_errorReporter.reportErrorForNode(
@@ -1433,6 +1491,35 @@
}
@override
+ DartObjectImpl visitSetLiteral(SetLiteral node) {
+ if (!node.isConst) {
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.MISSING_CONST_IN_SET_LITERAL, node);
+ return null;
+ }
+ bool errorOccurred = false;
+ Set<DartObjectImpl> elements = new Set<DartObjectImpl>();
+ for (Expression element in node.elements) {
+ DartObjectImpl elementResult = element.accept(this);
+ if (elementResult == null) {
+ errorOccurred = true;
+ } else {
+ elements.add(elementResult);
+ }
+ }
+ if (errorOccurred) {
+ return null;
+ }
+ DartType nodeType = node.staticType;
+ DartType elementType =
+ nodeType is InterfaceType && nodeType.typeArguments.isNotEmpty
+ ? nodeType.typeArguments[0]
+ : _typeProvider.dynamicType;
+ InterfaceType setType = _typeProvider.setType.instantiate([elementType]);
+ return new DartObjectImpl(setType, new SetState(elements));
+ }
+
+ @override
DartObjectImpl visitSimpleIdentifier(SimpleIdentifier node) {
if (_lexicalEnvironment != null &&
_lexicalEnvironment.containsKey(node.name)) {
@@ -1521,8 +1608,9 @@
// Driver, we compute values of all dependencies first (or detect cycle).
// So, the value has already been computed. Just return it.
if (evaluationEngine.forAnalysisDriver) {
- if (variableElement.isConst) {
- return variableElement.evaluationResult.value;
+ EvaluationResultImpl value = variableElement.evaluationResult;
+ if (variableElement.isConst && value != null) {
+ return value.value;
}
} else {
// TODO(scheglov) Once we remove task model, we can remove this code.
@@ -1626,18 +1714,6 @@
return null;
}
- DartObjectImpl bitAnd(BinaryExpression node, DartObjectImpl leftOperand,
- DartObjectImpl rightOperand) {
- if (leftOperand != null && rightOperand != null) {
- try {
- return leftOperand.bitAnd(_typeProvider, rightOperand);
- } on EvaluationException catch (exception) {
- _errorReporter.reportErrorForNode(exception.errorCode, node);
- }
- }
- return null;
- }
-
DartObjectImpl bitNot(Expression node, DartObjectImpl evaluationResult) {
if (evaluationResult != null) {
try {
@@ -1649,23 +1725,11 @@
return null;
}
- DartObjectImpl bitOr(BinaryExpression node, DartObjectImpl leftOperand,
- DartObjectImpl rightOperand) {
- if (leftOperand != null && rightOperand != null) {
+ DartObjectImpl castToType(
+ AsExpression node, DartObjectImpl expression, DartObjectImpl type) {
+ if (expression != null && type != null) {
try {
- return leftOperand.bitOr(_typeProvider, rightOperand);
- } on EvaluationException catch (exception) {
- _errorReporter.reportErrorForNode(exception.errorCode, node);
- }
- }
- return null;
- }
-
- DartObjectImpl bitXor(BinaryExpression node, DartObjectImpl leftOperand,
- DartObjectImpl rightOperand) {
- if (leftOperand != null && rightOperand != null) {
- try {
- return leftOperand.bitXor(_typeProvider, rightOperand);
+ return expression.castToType(_typeProvider, type);
} on EvaluationException catch (exception) {
_errorReporter.reportErrorForNode(exception.errorCode, node);
}
@@ -1697,6 +1761,53 @@
return null;
}
+ DartObjectImpl eagerAnd(BinaryExpression node, DartObjectImpl leftOperand,
+ DartObjectImpl rightOperand, bool allowBool) {
+ if (leftOperand != null && rightOperand != null) {
+ try {
+ return leftOperand.eagerAnd(_typeProvider, rightOperand, allowBool);
+ } on EvaluationException catch (exception) {
+ _errorReporter.reportErrorForNode(exception.errorCode, node);
+ }
+ }
+ return null;
+ }
+
+ DartObjectImpl eagerOr(BinaryExpression node, DartObjectImpl leftOperand,
+ DartObjectImpl rightOperand, bool allowBool) {
+ if (leftOperand != null && rightOperand != null) {
+ try {
+ return leftOperand.eagerOr(_typeProvider, rightOperand, allowBool);
+ } on EvaluationException catch (exception) {
+ _errorReporter.reportErrorForNode(exception.errorCode, node);
+ }
+ }
+ return null;
+ }
+
+ DartObjectImpl eagerQuestionQuestion(Expression node,
+ DartObjectImpl leftOperand, DartObjectImpl rightOperand) {
+ if (leftOperand != null && rightOperand != null) {
+ if (leftOperand.isNull) {
+ return rightOperand;
+ }
+ return leftOperand;
+ }
+ return null;
+ }
+
+ DartObjectImpl eagerXor(BinaryExpression node, DartObjectImpl leftOperand,
+ DartObjectImpl rightOperand, bool allowBool) {
+ if (leftOperand != null && rightOperand != null) {
+ try {
+ return leftOperand.eagerXor(_typeProvider, rightOperand, allowBool);
+ } on EvaluationException catch (exception) {
+ _errorReporter.reportErrorForNode(exception.errorCode, node);
+ }
+ }
+ return null;
+ }
+
DartObjectImpl equalEqual(Expression node, DartObjectImpl leftOperand,
DartObjectImpl rightOperand) {
if (leftOperand != null && rightOperand != null) {
@@ -1757,6 +1868,41 @@
return null;
}
+ DartObjectImpl lazyAnd(BinaryExpression node, DartObjectImpl leftOperand,
+ DartObjectImpl rightOperandComputer()) {
+ if (leftOperand != null) {
+ try {
+ return leftOperand.lazyAnd(_typeProvider, rightOperandComputer);
+ } on EvaluationException catch (exception) {
+ _errorReporter.reportErrorForNode(exception.errorCode, node);
+ }
+ }
+ return null;
+ }
+
+ DartObjectImpl lazyOr(BinaryExpression node, DartObjectImpl leftOperand,
+ DartObjectImpl rightOperandComputer()) {
+ if (leftOperand != null) {
+ try {
+ return leftOperand.lazyOr(_typeProvider, rightOperandComputer);
+ } on EvaluationException catch (exception) {
+ _errorReporter.reportErrorForNode(exception.errorCode, node);
+ }
+ }
+ return null;
+ }
+
+ DartObjectImpl lazyQuestionQuestion(Expression node,
+ DartObjectImpl leftOperand, DartObjectImpl rightOperandComputer()) {
+ if (leftOperand != null) {
+ if (leftOperand.isNull) {
+ return rightOperandComputer();
+ }
+ return leftOperand;
+ }
+ return null;
+ }
+
DartObjectImpl lessThan(BinaryExpression node, DartObjectImpl leftOperand,
DartObjectImpl rightOperand) {
if (leftOperand != null && rightOperand != null) {
@@ -1781,18 +1927,6 @@
return null;
}
- DartObjectImpl logicalAnd(BinaryExpression node, DartObjectImpl leftOperand,
- DartObjectImpl rightOperandComputer()) {
- if (leftOperand != null) {
- try {
- return leftOperand.logicalAnd(_typeProvider, rightOperandComputer);
- } on EvaluationException catch (exception) {
- _errorReporter.reportErrorForNode(exception.errorCode, node);
- }
- }
- return null;
- }
-
DartObjectImpl logicalNot(Expression node, DartObjectImpl evaluationResult) {
if (evaluationResult != null) {
try {
@@ -1804,18 +1938,6 @@
return null;
}
- DartObjectImpl logicalOr(BinaryExpression node, DartObjectImpl leftOperand,
- DartObjectImpl rightOperandComputer()) {
- if (leftOperand != null) {
- try {
- return leftOperand.logicalOr(_typeProvider, rightOperandComputer);
- } on EvaluationException catch (exception) {
- _errorReporter.reportErrorForNode(exception.errorCode, node);
- }
- }
- return null;
- }
-
DartObjectImpl minus(BinaryExpression node, DartObjectImpl leftOperand,
DartObjectImpl rightOperand) {
if (leftOperand != null && rightOperand != null) {
@@ -1863,17 +1985,6 @@
return null;
}
- DartObjectImpl questionQuestion(Expression node, DartObjectImpl leftOperand,
- DartObjectImpl rightOperand) {
- if (leftOperand != null && rightOperand != null) {
- if (leftOperand.isNull) {
- return rightOperand;
- }
- return leftOperand;
- }
- return null;
- }
-
DartObjectImpl remainder(BinaryExpression node, DartObjectImpl leftOperand,
DartObjectImpl rightOperand) {
if (leftOperand != null && rightOperand != null) {
@@ -1939,6 +2050,22 @@
}
return null;
}
+
+ DartObjectImpl typeTest(
+ IsExpression node, DartObjectImpl expression, DartObjectImpl type) {
+ if (expression != null && type != null) {
+ try {
+ DartObjectImpl result = expression.hasType(_typeProvider, type);
+ if (node.notOperator != null) {
+ return result.logicalNot(_typeProvider);
+ }
+ return result;
+ } on EvaluationException catch (exception) {
+ _errorReporter.reportErrorForNode(exception.errorCode, node);
+ }
+ }
+ return null;
+ }
}
/**
diff --git a/pkg/analyzer/lib/src/dart/constant/utilities.dart b/pkg/analyzer/lib/src/dart/constant/utilities.dart
index 50480ad..b0aa23a 100644
--- a/pkg/analyzer/lib/src/dart/constant/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/constant/utilities.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -106,6 +106,16 @@
}
@override
+ SetLiteral visitSetLiteral(SetLiteral node) {
+ SetLiteral literal = super.visitSetLiteral(node);
+ literal.staticType = node.staticType;
+ if (node.constKeyword == null && node.isConst) {
+ literal.constKeyword = new KeywordToken(Keyword.CONST, node.offset);
+ }
+ return literal;
+ }
+
+ @override
SimpleIdentifier visitSimpleIdentifier(SimpleIdentifier node) {
SimpleIdentifier identifier = super.visitSimpleIdentifier(node);
identifier.staticElement = node.staticElement;
@@ -173,6 +183,15 @@
}
@override
+ void visitSetLiteral(SetLiteral node) {
+ if (node.isConst) {
+ _find(node);
+ } else {
+ super.visitSetLiteral(node);
+ }
+ }
+
+ @override
void visitSwitchCase(SwitchCase node) {
_find(node.expression);
node.statements.accept(this);
@@ -192,7 +211,7 @@
* constructors, constant constructor invocations, and annotations found in
* those compilation units.
*/
-class ConstantFinder extends RecursiveAstVisitor<Object> {
+class ConstantFinder extends RecursiveAstVisitor<void> {
/**
* The elements and AST nodes whose constant values need to be computed.
*/
@@ -206,7 +225,7 @@
bool treatFinalInstanceVarAsConst = false;
@override
- Object visitAnnotation(Annotation node) {
+ void visitAnnotation(Annotation node) {
super.visitAnnotation(node);
ElementAnnotation elementAnnotation = node.elementAnnotation;
if (elementAnnotation == null) {
@@ -217,11 +236,10 @@
} else {
constantsToCompute.add(elementAnnotation);
}
- return null;
}
@override
- Object visitClassDeclaration(ClassDeclaration node) {
+ void visitClassDeclaration(ClassDeclaration node) {
bool prevTreatFinalInstanceVarAsConst = treatFinalInstanceVarAsConst;
if (resolutionMap
.elementDeclaredByClassDeclaration(node)
@@ -233,14 +251,14 @@
treatFinalInstanceVarAsConst = true;
}
try {
- return super.visitClassDeclaration(node);
+ super.visitClassDeclaration(node);
} finally {
treatFinalInstanceVarAsConst = prevTreatFinalInstanceVarAsConst;
}
}
@override
- Object visitConstructorDeclaration(ConstructorDeclaration node) {
+ void visitConstructorDeclaration(ConstructorDeclaration node) {
super.visitConstructorDeclaration(node);
if (node.constKeyword != null) {
ConstructorElement element = node.declaredElement;
@@ -249,22 +267,20 @@
constantsToCompute.addAll(element.parameters);
}
}
- return null;
}
@override
- Object visitDefaultFormalParameter(DefaultFormalParameter node) {
+ void visitDefaultFormalParameter(DefaultFormalParameter node) {
super.visitDefaultFormalParameter(node);
Expression defaultValue = node.defaultValue;
if (defaultValue != null && node.declaredElement != null) {
constantsToCompute
.add(resolutionMap.elementDeclaredByFormalParameter(node));
}
- return null;
}
@override
- Object visitVariableDeclaration(VariableDeclaration node) {
+ void visitVariableDeclaration(VariableDeclaration node) {
super.visitVariableDeclaration(node);
Expression initializer = node.initializer;
VariableElement element = node.declaredElement;
@@ -278,7 +294,6 @@
constantsToCompute.add(element);
}
}
- return null;
}
}
@@ -286,7 +301,7 @@
* An object used to add reference information for a given variable to the
* bi-directional mapping used to order the evaluation of constants.
*/
-class ReferenceFinder extends RecursiveAstVisitor<Object> {
+class ReferenceFinder extends RecursiveAstVisitor<void> {
/**
* The callback which should be used to report any dependencies that were
* found.
@@ -301,39 +316,37 @@
ReferenceFinder(this._callback);
@override
- Object visitInstanceCreationExpression(InstanceCreationExpression node) {
+ void visitInstanceCreationExpression(InstanceCreationExpression node) {
if (node.isConst) {
ConstructorElement constructor = getConstructorImpl(node.staticElement);
if (constructor != null) {
_callback(constructor);
}
}
- return super.visitInstanceCreationExpression(node);
+ super.visitInstanceCreationExpression(node);
}
@override
- Object visitLabel(Label node) {
+ void visitLabel(Label node) {
// We are visiting the "label" part of a named expression in a function
// call (presumably a constructor call), e.g. "const C(label: ...)". We
// don't want to visit the SimpleIdentifier for the label because that's a
// reference to a function parameter that needs to be filled in; it's not a
// constant whose value we depend on.
- return null;
}
@override
- Object visitRedirectingConstructorInvocation(
+ void visitRedirectingConstructorInvocation(
RedirectingConstructorInvocation node) {
super.visitRedirectingConstructorInvocation(node);
ConstructorElement target = getConstructorImpl(node.staticElement);
if (target != null) {
_callback(target);
}
- return null;
}
@override
- Object visitSimpleIdentifier(SimpleIdentifier node) {
+ void visitSimpleIdentifier(SimpleIdentifier node) {
Element staticElement = node.staticElement;
Element element = staticElement is PropertyAccessorElement
? staticElement.variable
@@ -341,16 +354,14 @@
if (element is VariableElement && element.isConst) {
_callback(element);
}
- return null;
}
@override
- Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+ void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
super.visitSuperConstructorInvocation(node);
ConstructorElement constructor = getConstructorImpl(node.staticElement);
if (constructor != null) {
_callback(constructor);
}
- return null;
}
}
diff --git a/pkg/analyzer/lib/src/dart/constant/value.dart b/pkg/analyzer/lib/src/dart/constant/value.dart
index cca4d22..e15ba2e 100644
--- a/pkg/analyzer/lib/src/dart/constant/value.dart
+++ b/pkg/analyzer/lib/src/dart/constant/value.dart
@@ -98,7 +98,7 @@
}
@override
- BoolState logicalAnd(InstanceState rightOperandComputer()) {
+ BoolState lazyAnd(InstanceState rightOperandComputer()) {
if (value == false) {
return FALSE_STATE;
}
@@ -108,6 +108,16 @@
}
@override
+ BoolState lazyOr(InstanceState rightOperandComputer()) {
+ if (value == true) {
+ return TRUE_STATE;
+ }
+ InstanceState rightOperand = rightOperandComputer();
+ assertBool(rightOperand);
+ return value == null ? UNKNOWN_VALUE : rightOperand.convertToBool();
+ }
+
+ @override
BoolState logicalNot() {
if (value == null) {
return UNKNOWN_VALUE;
@@ -116,16 +126,6 @@
}
@override
- BoolState logicalOr(InstanceState rightOperandComputer()) {
- if (value == true) {
- return TRUE_STATE;
- }
- InstanceState rightOperand = rightOperandComputer();
- assertBool(rightOperand);
- return value == null ? UNKNOWN_VALUE : rightOperand.convertToBool();
- }
-
- @override
String toString() => value == null ? "-unknown-" : (value ? "true" : "false");
/**
@@ -145,9 +145,10 @@
final ConstructorElement constructor;
/**
- * The positional arguments passed to the constructor.
+ * Values of specified arguments, actual values for positional, and `null`
+ * for named (which are provided as [namedArguments]).
*/
- final List<DartObjectImpl> positionalArguments;
+ final List<DartObjectImpl> _argumentValues;
/**
* The named arguments passed to the constructor.
@@ -155,7 +156,14 @@
final Map<String, DartObjectImpl> namedArguments;
ConstructorInvocation(
- this.constructor, this.positionalArguments, this.namedArguments);
+ this.constructor, this._argumentValues, this.namedArguments);
+
+ /**
+ * The positional arguments passed to the constructor.
+ */
+ List<DartObjectImpl> get positionalArguments {
+ return _argumentValues.takeWhile((v) => v != null).toList();
+ }
}
/**
@@ -219,6 +227,11 @@
*/
bool get isBoolNumStringOrNull => _state.isBoolNumStringOrNull;
+ /**
+ * Return `true` if this object represents an object whose type is 'int'.
+ */
+ bool get isInt => _state.isInt;
+
@override
bool get isNull => _state is NullState;
@@ -265,19 +278,6 @@
}
/**
- * Return the result of invoking the '&' operator on this object with the
- * [rightOperand]. The [typeProvider] is the type provider used to find known
- * types.
- *
- * Throws an [EvaluationException] if the operator is not appropriate for an
- * object of this kind.
- */
- DartObjectImpl bitAnd(
- TypeProvider typeProvider, DartObjectImpl rightOperand) =>
- new DartObjectImpl(
- typeProvider.intType, _state.bitAnd(rightOperand._state));
-
- /**
* Return the result of invoking the '~' operator on this object. The
* [typeProvider] is the type provider used to find known types.
*
@@ -288,30 +288,20 @@
new DartObjectImpl(typeProvider.intType, _state.bitNot());
/**
- * Return the result of invoking the '|' operator on this object with the
- * [rightOperand]. The [typeProvider] is the type provider used to find known
- * types.
- *
- * Throws an [EvaluationException] if the operator is not appropriate for an
- * object of this kind.
+ * Return the result of casting this object to the given [castType].
*/
- DartObjectImpl bitOr(
- TypeProvider typeProvider, DartObjectImpl rightOperand) =>
- new DartObjectImpl(
- typeProvider.intType, _state.bitOr(rightOperand._state));
-
- /**
- * Return the result of invoking the '^' operator on this object with the
- * [rightOperand]. The [typeProvider] is the type provider used to find known
- * types.
- *
- * Throws an [EvaluationException] if the operator is not appropriate for an
- * object of this kind.
- */
- DartObjectImpl bitXor(
- TypeProvider typeProvider, DartObjectImpl rightOperand) =>
- new DartObjectImpl(
- typeProvider.intType, _state.bitXor(rightOperand._state));
+ DartObjectImpl castToType(
+ TypeProvider typeProvider, DartObjectImpl castType) {
+ _assertType(castType);
+ if (isNull) {
+ return this;
+ }
+ if (!type.isSubtypeOf((castType._state as TypeState)._type)) {
+ throw new EvaluationException(
+ CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+ }
+ return this;
+ }
/**
* Return the result of invoking the ' ' operator on this object with the
@@ -364,6 +354,69 @@
}
/**
+ * Return the result of invoking the '&' operator on this object with the
+ * [rightOperand]. The [typeProvider] is the type provider used to find known
+ * types.
+ *
+ * Throws an [EvaluationException] if the operator is not appropriate for an
+ * object of this kind.
+ */
+ DartObjectImpl eagerAnd(
+ TypeProvider typeProvider, DartObjectImpl rightOperand, bool allowBool) {
+ if (allowBool && isBool && rightOperand.isBool) {
+ return new DartObjectImpl(
+ typeProvider.boolType, _state.logicalAnd(rightOperand._state));
+ } else if (isInt && rightOperand.isInt) {
+ return new DartObjectImpl(
+ typeProvider.intType, _state.bitAnd(rightOperand._state));
+ }
+ throw new EvaluationException(
+ CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_INT);
+ }
+
+ /**
+ * Return the result of invoking the '|' operator on this object with the
+ * [rightOperand]. The [typeProvider] is the type provider used to find known
+ * types.
+ *
+ * Throws an [EvaluationException] if the operator is not appropriate for an
+ * object of this kind.
+ */
+ DartObjectImpl eagerOr(
+ TypeProvider typeProvider, DartObjectImpl rightOperand, bool allowBool) {
+ if (allowBool && isBool && rightOperand.isBool) {
+ return new DartObjectImpl(
+ typeProvider.boolType, _state.logicalOr(rightOperand._state));
+ } else if (isInt && rightOperand.isInt) {
+ return new DartObjectImpl(
+ typeProvider.intType, _state.bitOr(rightOperand._state));
+ }
+ throw new EvaluationException(
+ CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_INT);
+ }
+
+ /**
+ * Return the result of invoking the '^' operator on this object with the
+ * [rightOperand]. The [typeProvider] is the type provider used to find known
+ * types.
+ *
+ * Throws an [EvaluationException] if the operator is not appropriate for an
+ * object of this kind.
+ */
+ DartObjectImpl eagerXor(
+ TypeProvider typeProvider, DartObjectImpl rightOperand, bool allowBool) {
+ if (allowBool && isBool && rightOperand.isBool) {
+ return new DartObjectImpl(
+ typeProvider.boolType, _state.logicalXor(rightOperand._state));
+ } else if (isInt && rightOperand.isInt) {
+ return new DartObjectImpl(
+ typeProvider.intType, _state.bitXor(rightOperand._state));
+ }
+ throw new EvaluationException(
+ CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_INT);
+ }
+
+ /**
* Return the result of invoking the '==' operator on this object with the
* [rightOperand]. The [typeProvider] is the type provider used to find known
* types.
@@ -434,6 +487,27 @@
_state.greaterThanOrEqual(rightOperand._state));
/**
+ * Return the result of testing whether this object has the given [testedType].
+ */
+ DartObjectImpl hasType(TypeProvider typeProvider, DartObjectImpl testedType) {
+ _assertType(testedType);
+ DartType typeType = (testedType._state as TypeState)._type;
+ BoolState state;
+ if (isNull) {
+ if (typeType == typeProvider.objectType ||
+ typeType == typeProvider.dynamicType ||
+ typeType == typeProvider.nullType) {
+ state = BoolState.TRUE_STATE;
+ } else {
+ state = BoolState.FALSE_STATE;
+ }
+ } else {
+ state = BoolState.from(type.isSubtypeOf(typeType));
+ }
+ return new DartObjectImpl(typeProvider.boolType, state);
+ }
+
+ /**
* Return the result of invoking the '~/' operator on this object with the
* [rightOperand]. The [typeProvider] is the type provider used to find known
* types.
@@ -458,6 +532,32 @@
}
/**
+ * Return the result of invoking the '&&' operator on this object with the
+ * [rightOperand]. The [typeProvider] is the type provider used to find known
+ * types.
+ *
+ * Throws an [EvaluationException] if the operator is not appropriate for an
+ * object of this kind.
+ */
+ DartObjectImpl lazyAnd(
+ TypeProvider typeProvider, DartObjectImpl rightOperandComputer()) =>
+ new DartObjectImpl(typeProvider.boolType,
+ _state.lazyAnd(() => rightOperandComputer()?._state));
+
+ /**
+ * Return the result of invoking the '||' operator on this object with the
+ * [rightOperand]. The [typeProvider] is the type provider used to find known
+ * types.
+ *
+ * Throws an [EvaluationException] if the operator is not appropriate for an
+ * object of this kind.
+ */
+ DartObjectImpl lazyOr(
+ TypeProvider typeProvider, DartObjectImpl rightOperandComputer()) =>
+ new DartObjectImpl(typeProvider.boolType,
+ _state.lazyOr(() => rightOperandComputer()?._state));
+
+ /**
* Return the result of invoking the '<' operator on this object with the
* [rightOperand]. The [typeProvider] is the type provider used to find known
* types.
@@ -484,19 +584,6 @@
typeProvider.boolType, _state.lessThanOrEqual(rightOperand._state));
/**
- * Return the result of invoking the '&&' operator on this object with the
- * [rightOperand]. The [typeProvider] is the type provider used to find known
- * types.
- *
- * Throws an [EvaluationException] if the operator is not appropriate for an
- * object of this kind.
- */
- DartObjectImpl logicalAnd(
- TypeProvider typeProvider, DartObjectImpl rightOperandComputer()) =>
- new DartObjectImpl(typeProvider.boolType,
- _state.logicalAnd(() => rightOperandComputer()?._state));
-
- /**
* Return the result of invoking the '!' operator on this object. The
* [typeProvider] is the type provider used to find known types.
*
@@ -507,19 +594,6 @@
new DartObjectImpl(typeProvider.boolType, _state.logicalNot());
/**
- * Return the result of invoking the '||' operator on this object with the
- * [rightOperand]. The [typeProvider] is the type provider used to find known
- * types.
- *
- * Throws an [EvaluationException] if the operator is not appropriate for an
- * object of this kind.
- */
- DartObjectImpl logicalOr(
- TypeProvider typeProvider, DartObjectImpl rightOperandComputer()) =>
- new DartObjectImpl(typeProvider.boolType,
- _state.logicalOr(() => rightOperandComputer()?._state));
-
- /**
* Return the result of invoking the '-' operator on this object with the
* [rightOperand]. The [typeProvider] is the type provider used to find known
* types.
@@ -722,6 +796,15 @@
}
@override
+ Set<DartObject> toSetValue() {
+ InstanceState state = _state;
+ if (state is SetState) {
+ return state._elements;
+ }
+ return null;
+ }
+
+ @override
String toString() => "${type.displayName} ($_state)";
@override
@@ -750,6 +833,16 @@
}
return null;
}
+
+ /**
+ * Throw an exception if the given [object]'s state does not represent a Type
+ * value.
+ */
+ void _assertType(DartObjectImpl object) {
+ if (object._state is! TypeState) {
+ throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_TYPE);
+ }
+ }
}
/**
@@ -1183,6 +1276,19 @@
}
@override
+ BoolState lazyAnd(InstanceState rightOperandComputer()) {
+ assertBool(rightOperandComputer());
+ return BoolState.UNKNOWN_VALUE;
+ }
+
+ @override
+ BoolState lazyOr(InstanceState rightOperandComputer()) {
+ InstanceState rightOperand = rightOperandComputer();
+ assertBool(rightOperand);
+ return rightOperand.convertToBool();
+ }
+
+ @override
BoolState lessThan(InstanceState rightOperand) {
assertNumOrNull(rightOperand);
return BoolState.UNKNOWN_VALUE;
@@ -1195,22 +1301,9 @@
}
@override
- BoolState logicalAnd(InstanceState rightOperandComputer()) {
- assertBool(rightOperandComputer());
- return BoolState.UNKNOWN_VALUE;
- }
-
- @override
BoolState logicalNot() => BoolState.UNKNOWN_VALUE;
@override
- BoolState logicalOr(InstanceState rightOperandComputer()) {
- InstanceState rightOperand = rightOperandComputer();
- assertBool(rightOperand);
- return rightOperand.convertToBool();
- }
-
- @override
NumState minus(InstanceState rightOperand) {
assertNumOrNull(rightOperand);
return _unknownNum(rightOperand);
@@ -1461,6 +1554,16 @@
bool get isBoolNumStringOrNull => false;
/**
+ * Return `true` if this object represents an object whose type is 'int'.
+ */
+ bool get isInt => false;
+
+ /**
+ * Return `true` if this object represents the value 'null'.
+ */
+ bool get isNull => false;
+
+ /**
* Return `true` if this object represents an unknown value.
*/
bool get isUnknown => false;
@@ -1704,6 +1807,40 @@
BoolState isIdentical(InstanceState rightOperand);
/**
+ * Return the result of invoking the '&&' operator on this object with the
+ * [rightOperand].
+ *
+ * Throws an [EvaluationException] if the operator is not appropriate for an
+ * object of this kind.
+ */
+ BoolState lazyAnd(InstanceState rightOperandComputer()) {
+ assertBool(this);
+ if (convertToBool() == BoolState.FALSE_STATE) {
+ return this;
+ }
+ InstanceState rightOperand = rightOperandComputer();
+ assertBool(rightOperand);
+ return rightOperand.convertToBool();
+ }
+
+ /**
+ * Return the result of invoking the '||' operator on this object with the
+ * [rightOperand].
+ *
+ * Throws an [EvaluationException] if the operator is not appropriate for an
+ * object of this kind.
+ */
+ BoolState lazyOr(InstanceState rightOperandComputer()) {
+ assertBool(this);
+ if (convertToBool() == BoolState.TRUE_STATE) {
+ return this;
+ }
+ InstanceState rightOperand = rightOperandComputer();
+ assertBool(rightOperand);
+ return rightOperand.convertToBool();
+ }
+
+ /**
* Return the result of invoking the '<' operator on this object with the
* [rightOperand].
*
@@ -1732,20 +1869,17 @@
}
/**
- * Return the result of invoking the '&&' operator on this object with the
+ * Return the result of invoking the '&' operator on this object with the
* [rightOperand].
*
* Throws an [EvaluationException] if the operator is not appropriate for an
* object of this kind.
*/
- BoolState logicalAnd(InstanceState rightOperandComputer()) {
+ BoolState logicalAnd(InstanceState rightOperand) {
assertBool(this);
- if (convertToBool() == BoolState.FALSE_STATE) {
- return this;
- }
- InstanceState rightOperand = rightOperandComputer();
assertBool(rightOperand);
- return rightOperand.convertToBool();
+ return BoolState.from(
+ convertToBool().value & rightOperand.convertToBool().value);
}
/**
@@ -1760,20 +1894,31 @@
}
/**
- * Return the result of invoking the '||' operator on this object with the
+ * Return the result of invoking the '|' operator on this object with the
* [rightOperand].
*
* Throws an [EvaluationException] if the operator is not appropriate for an
* object of this kind.
*/
- BoolState logicalOr(InstanceState rightOperandComputer()) {
+ BoolState logicalOr(InstanceState rightOperand) {
assertBool(this);
- if (convertToBool() == BoolState.TRUE_STATE) {
- return this;
- }
- InstanceState rightOperand = rightOperandComputer();
assertBool(rightOperand);
- return rightOperand.convertToBool();
+ return BoolState.from(
+ convertToBool().value | rightOperand.convertToBool().value);
+ }
+
+ /**
+ * Return the result of invoking the '^' operator on this object with the
+ * [rightOperand].
+ *
+ * Throws an [EvaluationException] if the operator is not appropriate for an
+ * object of this kind.
+ */
+ BoolState logicalXor(InstanceState rightOperand) {
+ assertBool(this);
+ assertBool(rightOperand);
+ return BoolState.from(
+ convertToBool().value ^ rightOperand.convertToBool().value);
}
/**
@@ -1898,6 +2043,9 @@
bool get isBoolNumStringOrNull => true;
@override
+ bool get isInt => true;
+
+ @override
bool get isUnknown => value == null;
@override
@@ -2521,6 +2669,9 @@
bool get isBoolNumStringOrNull => true;
@override
+ bool get isNull => true;
+
+ @override
String get typeName => "Null";
@override
@@ -2676,6 +2827,89 @@
}
/**
+ * The state of an object representing a set.
+ */
+class SetState extends InstanceState {
+ /**
+ * The elements of the set.
+ */
+ final Set<DartObjectImpl> _elements;
+
+ /**
+ * Initialize a newly created state to represent a set with the given
+ * [elements].
+ */
+ SetState(this._elements);
+
+ @override
+ int get hashCode {
+ int value = 0;
+ for (DartObjectImpl element in _elements) {
+ value = (value << 3) ^ element.hashCode;
+ }
+ return value;
+ }
+
+ @override
+ String get typeName => "Set";
+
+ @override
+ bool operator ==(Object object) {
+ if (object is SetState) {
+ List<DartObjectImpl> elements = _elements.toList();
+ List<DartObjectImpl> otherElements = object._elements.toList();
+ int count = elements.length;
+ if (otherElements.length != count) {
+ return false;
+ } else if (count == 0) {
+ return true;
+ }
+ for (int i = 0; i < count; i++) {
+ if (elements[i] != otherElements[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ @override
+ StringState convertToString() => StringState.UNKNOWN_VALUE;
+
+ @override
+ BoolState equalEqual(InstanceState rightOperand) {
+ assertBoolNumStringOrNull(rightOperand);
+ return isIdentical(rightOperand);
+ }
+
+ @override
+ BoolState isIdentical(InstanceState rightOperand) {
+ if (rightOperand is DynamicState) {
+ return BoolState.UNKNOWN_VALUE;
+ }
+ return BoolState.from(this == rightOperand);
+ }
+
+ @override
+ String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.write('{');
+ bool first = true;
+ _elements.forEach((DartObjectImpl element) {
+ if (first) {
+ first = false;
+ } else {
+ buffer.write(', ');
+ }
+ buffer.write(element);
+ });
+ buffer.write('}');
+ return buffer.toString();
+ }
+}
+
+/**
* The state of an object representing a string.
*/
class StringState extends InstanceState {
diff --git a/pkg/analyzer/lib/src/dart/element/ast_provider.dart b/pkg/analyzer/lib/src/dart/element/ast_provider.dart
deleted file mode 100644
index ba94d53..0000000
--- a/pkg/analyzer/lib/src/dart/element/ast_provider.dart
+++ /dev/null
@@ -1,46 +0,0 @@
-// 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:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
-
-/**
- * Provider for resolved and unresolved [CompilationUnit]s that contain, or
- * [AstNode]s that declare [Element]s.
- */
-abstract class AstProvider {
- /**
- * Return the driver that is used to provide ASTs.
- */
- AnalysisDriver get driver;
-
- /**
- * Completes with the [SimpleIdentifier] that declares the [element]. The
- * enclosing unit is only parsed, but not resolved. Completes with `null` if
- * the [element] is synthetic, or the file where it is declared cannot be
- * parsed, etc.
- */
- Future<SimpleIdentifier> getParsedNameForElement(Element element);
-
- /**
- * Completes with the parsed [CompilationUnit] that contains the [element].
- */
- Future<CompilationUnit> getParsedUnitForElement(Element element);
-
- /**
- * Completes with the [SimpleIdentifier] that declares the [element]. The
- * enclosing unit is fully resolved. Completes with `null` if the [element]
- * is synthetic, or the file where it is declared cannot be parsed and
- * resolved, etc.
- */
- Future<SimpleIdentifier> getResolvedNameForElement(Element element);
-
- /**
- * Completes with the resolved [CompilationUnit] that contains the [element].
- */
- Future<CompilationUnit> getResolvedUnitForElement(Element element);
-}
diff --git a/pkg/analyzer/lib/src/dart/element/builder.dart b/pkg/analyzer/lib/src/dart/element/builder.dart
index 2e518e3..cefb1d8 100644
--- a/pkg/analyzer/lib/src/dart/element/builder.dart
+++ b/pkg/analyzer/lib/src/dart/element/builder.dart
@@ -48,7 +48,7 @@
: super(initialHolder, compilationUnitElement);
@override
- Object visitAnnotation(Annotation node) {
+ void visitAnnotation(Annotation node) {
// Although it isn't valid to do so because closures are not constant
// expressions, it's possible for one of the arguments to the constructor to
// contain a closure. Wrapping the processing of the annotation this way
@@ -62,16 +62,13 @@
} finally {
_currentHolder = previousHolder;
}
- return null;
}
@override
- Object visitBlockFunctionBody(BlockFunctionBody node) {
- return null;
- }
+ void visitBlockFunctionBody(BlockFunctionBody node) {}
@override
- Object visitClassDeclaration(ClassDeclaration node) {
+ void visitClassDeclaration(ClassDeclaration node) {
_enclosingClassHasConstConstructor = false;
for (var constructor in node.members) {
if (constructor is ConstructorDeclaration &&
@@ -90,12 +87,10 @@
_fillClassElement(node, element, holder);
_currentHolder.addType(element);
-
- return null;
}
@override
- Object visitClassTypeAlias(ClassTypeAlias node) {
+ void visitClassTypeAlias(ClassTypeAlias node) {
ElementHolder holder = new ElementHolder();
_visitChildren(holder, node);
SimpleIdentifier className = node.name;
@@ -109,19 +104,18 @@
_currentHolder.addType(element);
className.staticElement = element;
holder.validate();
- return null;
}
@override
- Object visitCompilationUnit(CompilationUnit node) {
+ void visitCompilationUnit(CompilationUnit node) {
if (_unitElement is ElementImpl) {
_setCodeRange(_unitElement, node);
}
- return super.visitCompilationUnit(node);
+ super.visitCompilationUnit(node);
}
@override
- Object visitConstructorDeclaration(ConstructorDeclaration node) {
+ void visitConstructorDeclaration(ConstructorDeclaration node) {
ElementHolder holder = new ElementHolder();
_visitChildren(holder, node);
FunctionBody body = node.body;
@@ -163,11 +157,10 @@
element.nameEnd = constructorName.end;
}
holder.validate();
- return null;
}
@override
- Object visitEnumDeclaration(EnumDeclaration node) {
+ void visitEnumDeclaration(EnumDeclaration node) {
SimpleIdentifier enumName = node.name;
EnumElementImpl enumElement = new EnumElementImpl.forNode(enumName);
_setCodeRange(enumElement, node);
@@ -199,24 +192,22 @@
_currentHolder.addEnum(enumElement);
enumName.staticElement = enumElement;
- return super.visitEnumDeclaration(node);
+ super.visitEnumDeclaration(node);
}
@override
- Object visitExportDirective(ExportDirective node) {
+ void visitExportDirective(ExportDirective node) {
List<ElementAnnotation> annotations =
_createElementAnnotations(node.metadata);
_unitElement.setAnnotations(node.offset, annotations);
- return super.visitExportDirective(node);
+ super.visitExportDirective(node);
}
@override
- Object visitExpressionFunctionBody(ExpressionFunctionBody node) {
- return null;
- }
+ void visitExpressionFunctionBody(ExpressionFunctionBody node) {}
@override
- Object visitFunctionDeclaration(FunctionDeclaration node) {
+ void visitFunctionDeclaration(FunctionDeclaration node) {
FunctionExpression expression = node.functionExpression;
if (expression != null) {
ElementHolder holder = new ElementHolder();
@@ -254,7 +245,7 @@
SimpleIdentifier propertyNameNode = node.name;
if (propertyNameNode == null) {
// TODO(brianwilkerson) Report this internal error.
- return null;
+ return;
}
String propertyName = propertyNameNode.name;
TopLevelVariableElementImpl variable = _currentHolder
@@ -327,15 +318,15 @@
}
holder.validate();
}
- return null;
}
@override
- Object visitFunctionExpression(FunctionExpression node) {
+ void visitFunctionExpression(FunctionExpression node) {
if (node.parent is FunctionDeclaration) {
// visitFunctionDeclaration has already created the element for the
// declaration. We just need to visit children.
- return super.visitFunctionExpression(node);
+ super.visitFunctionExpression(node);
+ return;
}
ElementHolder holder = new ElementHolder();
_visitChildren(holder, node);
@@ -359,11 +350,10 @@
_currentHolder.addFunction(element);
node.element = element;
holder.validate();
- return null;
}
@override
- Object visitFunctionTypeAlias(FunctionTypeAlias node) {
+ void visitFunctionTypeAlias(FunctionTypeAlias node) {
ElementHolder holder = new ElementHolder();
_visitChildren(holder, node);
SimpleIdentifier aliasName = node.name;
@@ -382,11 +372,10 @@
_currentHolder.addTypeAlias(element);
aliasName.staticElement = element;
holder.validate();
- return null;
}
@override
- Object visitGenericTypeAlias(GenericTypeAlias node) {
+ void visitGenericTypeAlias(GenericTypeAlias node) {
ElementHolder holder = new ElementHolder();
_visitChildren(holder, node);
SimpleIdentifier aliasName = node.name;
@@ -403,27 +392,26 @@
_currentHolder.addTypeAlias(element);
aliasName.staticElement = element;
holder.validate();
- return null;
}
@override
- Object visitImportDirective(ImportDirective node) {
+ void visitImportDirective(ImportDirective node) {
List<ElementAnnotation> annotations =
_createElementAnnotations(node.metadata);
_unitElement.setAnnotations(node.offset, annotations);
- return super.visitImportDirective(node);
+ super.visitImportDirective(node);
}
@override
- Object visitLibraryDirective(LibraryDirective node) {
+ void visitLibraryDirective(LibraryDirective node) {
List<ElementAnnotation> annotations =
_createElementAnnotations(node.metadata);
_unitElement.setAnnotations(node.offset, annotations);
- return super.visitLibraryDirective(node);
+ super.visitLibraryDirective(node);
}
@override
- Object visitMethodDeclaration(MethodDeclaration node) {
+ void visitMethodDeclaration(MethodDeclaration node) {
try {
ElementHolder holder = new ElementHolder();
_visitChildren(holder, node);
@@ -539,7 +527,7 @@
} catch (exception, stackTrace) {
if (node.name.staticElement == null) {
ClassDeclaration classNode =
- node.getAncestor((node) => node is ClassDeclaration);
+ node.thisOrAncestorOfType<ClassDeclaration>();
StringBuffer buffer = new StringBuffer();
buffer.write("The element for the method ");
buffer.write(node.name);
@@ -557,7 +545,7 @@
} finally {
if (node.name.staticElement == null) {
ClassDeclaration classNode =
- node.getAncestor((node) => node is ClassDeclaration);
+ node.thisOrAncestorOfType<ClassDeclaration>();
StringBuffer buffer = new StringBuffer();
buffer.write("The element for the method ");
buffer.write(node.name);
@@ -570,11 +558,10 @@
new AnalysisException(buffer.toString()), null));
}
}
- return null;
}
@override
- Object visitMixinDeclaration(MixinDeclaration node) {
+ void visitMixinDeclaration(MixinDeclaration node) {
ElementHolder holder = _buildClassMembers(node);
SimpleIdentifier nameNode = node.name;
@@ -583,20 +570,18 @@
_fillClassElement(node, element, holder);
_currentHolder.addMixin(element);
-
- return null;
}
@override
- Object visitPartDirective(PartDirective node) {
+ void visitPartDirective(PartDirective node) {
List<ElementAnnotation> annotations =
_createElementAnnotations(node.metadata);
_unitElement.setAnnotations(node.offset, annotations);
- return super.visitPartDirective(node);
+ super.visitPartDirective(node);
}
@override
- Object visitVariableDeclaration(VariableDeclaration node) {
+ void visitVariableDeclaration(VariableDeclaration node) {
bool isConst = node.isConst;
bool isFinal = node.isFinal;
Expression initializerNode = node.initializer;
@@ -658,11 +643,10 @@
_currentHolder.addAccessor(setter);
}
}
- return null;
}
@override
- Object visitVariableDeclarationList(VariableDeclarationList node) {
+ void visitVariableDeclarationList(VariableDeclarationList node) {
super.visitVariableDeclarationList(node);
AstNode parent = node.parent;
List<ElementAnnotation> elementAnnotations;
@@ -676,7 +660,6 @@
}
_setVariableDeclarationListAnnotations(node, elementAnnotations);
_setVariableDeclarationListCodeRanges(node);
- return null;
}
ElementHolder _buildClassMembers(AstNode classNode) {
@@ -827,7 +810,7 @@
* Instances of the class `DirectiveElementBuilder` build elements for top
* level library directives.
*/
-class DirectiveElementBuilder extends SimpleAstVisitor<Object> {
+class DirectiveElementBuilder extends SimpleAstVisitor<void> {
/**
* The analysis context within which directive elements are being built.
*/
@@ -903,7 +886,7 @@
this.exportSourceKindMap);
@override
- Object visitCompilationUnit(CompilationUnit node) {
+ void visitCompilationUnit(CompilationUnit node) {
//
// Resolve directives.
//
@@ -926,11 +909,10 @@
//
libraryElement.imports = imports;
libraryElement.exports = exports;
- return null;
}
@override
- Object visitExportDirective(ExportDirective node) {
+ void visitExportDirective(ExportDirective node) {
// Remove previous element. (It will remain null if the target is missing.)
node.element = null;
Source exportedSource = node.selectedSource;
@@ -962,11 +944,10 @@
errors.add(new AnalysisError(libraryElement.source, offset, length,
CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY, [uriLiteral.toSource()]));
}
- return null;
}
@override
- Object visitImportDirective(ImportDirective node) {
+ void visitImportDirective(ImportDirective node) {
// Remove previous element. (It will remain null if the target is missing.)
node.element = null;
Source importedSource = node.selectedSource;
@@ -1017,21 +998,18 @@
errors.add(new AnalysisError(libraryElement.source, offset, length,
errorCode, [uriLiteral.toSource()]));
}
- return null;
}
@override
- Object visitLibraryDirective(LibraryDirective node) {
+ void visitLibraryDirective(LibraryDirective node) {
(node.element as LibraryElementImpl)?.metadata =
_getElementAnnotations(node.metadata);
- return null;
}
@override
- Object visitPartDirective(PartDirective node) {
+ void visitPartDirective(PartDirective node) {
(node.element as CompilationUnitElementImpl)?.metadata =
_getElementAnnotations(node.metadata);
- return null;
}
/**
@@ -1080,30 +1058,27 @@
: super(initialHolder, compilationUnitElement);
@override
- Object visitBlockFunctionBody(BlockFunctionBody node) {
+ void visitBlockFunctionBody(BlockFunctionBody node) {
_buildLocal(node);
- return null;
}
@override
- Object visitDefaultFormalParameter(DefaultFormalParameter node) {
+ void visitDefaultFormalParameter(DefaultFormalParameter node) {
super.visitDefaultFormalParameter(node);
buildParameterInitializer(
node.declaredElement as ParameterElementImpl, node.defaultValue);
- return null;
}
@override
- Object visitExpressionFunctionBody(ExpressionFunctionBody node) {
+ void visitExpressionFunctionBody(ExpressionFunctionBody node) {
_buildLocal(node);
- return null;
}
@override
- Object visitMixinDeclaration(MixinDeclaration node) {
+ void visitMixinDeclaration(MixinDeclaration node) {
_mixinSuperInvokedNames = new Set<String>();
try {
- return super.visitMixinDeclaration(node);
+ super.visitMixinDeclaration(node);
} finally {
MixinElementImpl element = node.declaredElement;
element.superInvokedNames = _mixinSuperInvokedNames.toList();
@@ -1112,11 +1087,10 @@
}
@override
- Object visitVariableDeclaration(VariableDeclaration node) {
+ void visitVariableDeclaration(VariableDeclaration node) {
super.visitVariableDeclaration(node);
VariableElementImpl element = node.declaredElement as VariableElementImpl;
buildVariableInitializer(element, node.initializer);
- return null;
}
void _buildLocal(FunctionBody body) {
@@ -1142,6 +1116,13 @@
: super(initialHolder, compilationUnitElement);
/**
+ * Initialize a newly created element builder as a first step to analyzing a
+ * dangling dart expression.
+ */
+ LocalElementBuilder.forDanglingExpression()
+ : super(new ElementHolder(), null);
+
+ /**
* Builds the variable elements associated with [node] and stores them in
* the element holder.
*/
@@ -1186,13 +1167,13 @@
}
@override
- Object visitCatchClause(CatchClause node) {
+ void visitCatchClause(CatchClause node) {
buildCatchVariableElements(node);
- return super.visitCatchClause(node);
+ super.visitCatchClause(node);
}
@override
- Object visitDeclaredIdentifier(DeclaredIdentifier node) {
+ void visitDeclaredIdentifier(DeclaredIdentifier node) {
SimpleIdentifier variableName = node.identifier;
LocalVariableElementImpl element =
new LocalVariableElementImpl.forNode(variableName);
@@ -1211,22 +1192,20 @@
}
_currentHolder.addLocalVariable(element);
variableName.staticElement = element;
- return null;
}
@override
- Object visitDefaultFormalParameter(DefaultFormalParameter node) {
+ void visitDefaultFormalParameter(DefaultFormalParameter node) {
super.visitDefaultFormalParameter(node);
buildParameterInitializer(
node.declaredElement as ParameterElementImpl, node.defaultValue);
- return null;
}
@override
- Object visitFunctionDeclaration(FunctionDeclaration node) {
+ void visitFunctionDeclaration(FunctionDeclaration node) {
FunctionExpression expression = node.functionExpression;
if (expression == null) {
- return null;
+ return;
}
ElementHolder holder = new ElementHolder();
@@ -1255,7 +1234,7 @@
}
{
- Block enclosingBlock = node.getAncestor((node) => node is Block);
+ Block enclosingBlock = node.thisOrAncestorOfType<Block>();
if (enclosingBlock != null) {
element.setVisibleRange(enclosingBlock.offset, enclosingBlock.length);
}
@@ -1269,15 +1248,15 @@
expression.element = element;
node.name.staticElement = element;
holder.validate();
- return null;
}
@override
- Object visitFunctionExpression(FunctionExpression node) {
+ void visitFunctionExpression(FunctionExpression node) {
if (node.parent is FunctionDeclaration) {
// visitFunctionDeclaration has already created the element for the
// declaration. We just need to visit children.
- return super.visitFunctionExpression(node);
+ super.visitFunctionExpression(node);
+ return;
}
ElementHolder holder = new ElementHolder();
@@ -1298,43 +1277,38 @@
if (body.isGenerator) {
element.generator = true;
}
-
- {
- Block enclosingBlock = node.getAncestor((node) => node is Block);
- if (enclosingBlock != null) {
- element.setVisibleRange(enclosingBlock.offset, enclosingBlock.length);
- }
+ Block enclosingBlock = node.thisOrAncestorOfType<Block>();
+ if (enclosingBlock != null) {
+ element.setVisibleRange(enclosingBlock.offset, enclosingBlock.length);
}
-
element.type = new FunctionTypeImpl(element);
element.hasImplicitReturnType = true;
_currentHolder.addFunction(element);
node.element = element;
holder.validate();
- return null;
}
@override
- Object visitLabeledStatement(LabeledStatement node) {
+ void visitLabeledStatement(LabeledStatement node) {
bool onSwitchStatement = node.statement is SwitchStatement;
buildLabelElements(node.labels, onSwitchStatement, false);
- return super.visitLabeledStatement(node);
+ super.visitLabeledStatement(node);
}
@override
- Object visitSwitchCase(SwitchCase node) {
+ void visitSwitchCase(SwitchCase node) {
buildLabelElements(node.labels, false, true);
- return super.visitSwitchCase(node);
+ super.visitSwitchCase(node);
}
@override
- Object visitSwitchDefault(SwitchDefault node) {
+ void visitSwitchDefault(SwitchDefault node) {
buildLabelElements(node.labels, false, true);
- return super.visitSwitchDefault(node);
+ super.visitSwitchDefault(node);
}
@override
- Object visitVariableDeclaration(VariableDeclaration node) {
+ void visitVariableDeclaration(VariableDeclaration node) {
bool isConst = node.isConst;
bool isFinal = node.isFinal;
Expression initializerNode = node.initializer;
@@ -1354,17 +1328,15 @@
element.isConst = isConst;
element.isFinal = isFinal;
buildVariableInitializer(element, initializerNode);
- return null;
}
@override
- Object visitVariableDeclarationList(VariableDeclarationList node) {
+ void visitVariableDeclarationList(VariableDeclarationList node) {
super.visitVariableDeclarationList(node);
List<ElementAnnotation> elementAnnotations =
_createElementAnnotations(node.metadata);
_setVariableDeclarationListAnnotations(node, elementAnnotations);
_setVariableDeclarationListCodeRanges(node);
- return null;
}
void _setVariableVisibleRange(
@@ -1374,7 +1346,7 @@
if (parent2 is ForStatement) {
scopeNode = parent2;
} else {
- scopeNode = node.getAncestor((node) => node is Block);
+ scopeNode = node.thisOrAncestorOfType<Block>();
}
element.setVisibleRange(scopeNode.offset, scopeNode.length);
}
@@ -1383,7 +1355,7 @@
/**
* Base class for API and local element builders.
*/
-abstract class _BaseElementBuilder extends RecursiveAstVisitor<Object> {
+abstract class _BaseElementBuilder extends RecursiveAstVisitor<void> {
/**
* The compilation unit element into which the elements being built will be
* stored.
@@ -1444,7 +1416,7 @@
}
@override
- Object visitDefaultFormalParameter(DefaultFormalParameter node) {
+ void visitDefaultFormalParameter(DefaultFormalParameter node) {
NormalFormalParameter normalParameter = node.parameter;
SimpleIdentifier parameterName = normalParameter.identifier;
ParameterElementImpl parameter;
@@ -1474,11 +1446,10 @@
}
parameterName?.staticElement = parameter;
normalParameter.accept(this);
- return null;
}
@override
- Object visitFieldFormalParameter(FieldFormalParameter node) {
+ void visitFieldFormalParameter(FieldFormalParameter node) {
if (node.parent is! DefaultFormalParameter) {
SimpleIdentifier parameterName = node.identifier;
FieldFormalParameterElementImpl parameter =
@@ -1505,11 +1476,10 @@
_createGenericFunctionType(element, holder);
}
holder.validate();
- return null;
}
@override
- Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+ void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
if (node.parent is! DefaultFormalParameter) {
SimpleIdentifier parameterName = node.identifier;
ParameterElementImpl parameter =
@@ -1534,11 +1504,10 @@
element.metadata = _createElementAnnotations(node.metadata);
_createGenericFunctionType(element, holder);
holder.validate();
- return null;
}
@override
- Object visitGenericFunctionType(GenericFunctionType node) {
+ void visitGenericFunctionType(GenericFunctionType node) {
ElementHolder holder = new ElementHolder();
_visitChildren(holder, node);
GenericFunctionTypeElementImpl element =
@@ -1550,11 +1519,10 @@
element.type = type;
(node as GenericFunctionTypeImpl).type = type;
holder.validate();
- return null;
}
@override
- Object visitSimpleFormalParameter(SimpleFormalParameter node) {
+ void visitSimpleFormalParameter(SimpleFormalParameter node) {
ParameterElementImpl parameter;
if (node.parent is! DefaultFormalParameter) {
SimpleIdentifier parameterName = node.identifier;
@@ -1576,11 +1544,10 @@
super.visitSimpleFormalParameter(node);
parameter ??= node.declaredElement;
parameter?.metadata = _createElementAnnotations(node.metadata);
- return null;
}
@override
- Object visitTypeParameter(TypeParameter node) {
+ void visitTypeParameter(TypeParameter node) {
SimpleIdentifier parameterName = node.name;
TypeParameterElementImpl typeParameter =
new TypeParameterElementImpl.forNode(parameterName);
@@ -1591,7 +1558,7 @@
typeParameter.type = typeParameterType;
_currentHolder.addTypeParameter(typeParameter);
parameterName.staticElement = typeParameter;
- return super.visitTypeParameter(node);
+ super.visitTypeParameter(node);
}
/**
@@ -1720,54 +1687,50 @@
/**
* Builds elements for all node that are not constructors or methods.
*/
-class _ClassNotExecutableElementsBuilder extends UnifyingAstVisitor<Object> {
+class _ClassNotExecutableElementsBuilder extends UnifyingAstVisitor<void> {
final ApiElementBuilder builder;
final List<ClassMember> nonFields;
_ClassNotExecutableElementsBuilder(this.builder, this.nonFields);
@override
- Object visitConstructorDeclaration(ConstructorDeclaration node) {
+ void visitConstructorDeclaration(ConstructorDeclaration node) {
nonFields.add(node);
- return null;
}
@override
- Object visitMethodDeclaration(MethodDeclaration node) {
+ void visitMethodDeclaration(MethodDeclaration node) {
nonFields.add(node);
- return null;
}
@override
- Object visitNode(AstNode node) => node.accept(builder);
+ void visitNode(AstNode node) => node.accept(builder);
}
/**
* Instances of the class [_NamespaceCombinatorBuilder] can be used to visit
* [Combinator] AST nodes and generate [NamespaceCombinator] elements.
*/
-class _NamespaceCombinatorBuilder extends SimpleAstVisitor<Object> {
+class _NamespaceCombinatorBuilder extends SimpleAstVisitor<void> {
/**
* Elements generated so far.
*/
final List<NamespaceCombinator> combinators = <NamespaceCombinator>[];
@override
- Object visitHideCombinator(HideCombinator node) {
+ void visitHideCombinator(HideCombinator node) {
HideElementCombinatorImpl hide = new HideElementCombinatorImpl();
hide.hiddenNames = _getIdentifiers(node.hiddenNames);
combinators.add(hide);
- return null;
}
@override
- Object visitShowCombinator(ShowCombinator node) {
+ void visitShowCombinator(ShowCombinator node) {
ShowElementCombinatorImpl show = new ShowElementCombinatorImpl();
show.offset = node.offset;
show.end = node.end;
show.shownNames = _getIdentifiers(node.shownNames);
combinators.add(show);
- return null;
}
/**
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 513799f..27fc635 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -1,15 +1,17 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:collection';
import 'dart:math' show min;
+import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/constant/value.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/error/error.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/dart/constant/compute.dart';
import 'package:analyzer/src/dart/constant/value.dart';
@@ -106,6 +108,7 @@
@override
T accept<T>(ElementVisitor<T> visitor) => visitor.visitClassElement(this);
+ @deprecated
@override
NamedCompilationUnitMember computeNode() {
if (isEnum) {
@@ -507,22 +510,49 @@
@override
List<ConstructorElement> get constructors {
+ if (_constructors != null) {
+ return _constructors;
+ }
+
if (isMixinApplication) {
- return _computeMixinAppConstructors();
+ return _constructors = _computeMixinAppConstructors();
}
- if (_unlinkedClass != null && _constructors == null) {
- _constructors = _unlinkedClass.executables
- .where((e) => e.kind == UnlinkedExecutableKind.constructor)
- .map((e) => new ConstructorElementImpl.forSerialized(e, this))
- .toList(growable: false);
- // Ensure at least implicit default constructor.
- if (_constructors.isEmpty) {
- ConstructorElementImpl constructor = new ConstructorElementImpl('', -1);
- constructor.isSynthetic = true;
- constructor.enclosingElement = this;
- _constructors = <ConstructorElement>[constructor];
+
+ if (_unlinkedClass != null) {
+ var unlinkedExecutables = _unlinkedClass.executables;
+
+ var length = unlinkedExecutables.length;
+ if (length != 0) {
+ var count = 0;
+ for (var i = 0; i < length; i++) {
+ var e = unlinkedExecutables[i];
+ if (e.kind == UnlinkedExecutableKind.constructor) {
+ count++;
+ }
+ }
+
+ if (count != 0) {
+ var constructors = new List<ConstructorElement>(count);
+ var index = 0;
+ for (var i = 0; i < length; i++) {
+ var e = unlinkedExecutables[i];
+ if (e.kind == UnlinkedExecutableKind.constructor) {
+ constructors[index++] =
+ new ConstructorElementImpl.forSerialized(e, this);
+ }
+ }
+ return _constructors = constructors;
+ }
}
+
+ // There are no explicit constructors.
+ // Create the implicit default constructor.
+ var constructor = new ConstructorElementImpl('', -1);
+ constructor.isSynthetic = true;
+ constructor.enclosingElement = this;
+ _constructors = <ConstructorElement>[constructor];
}
+
assert(_constructors != null);
return _constructors ?? const <ConstructorElement>[];
}
@@ -646,17 +676,39 @@
@override
List<InterfaceType> get interfaces {
- if (_interfaces == null) {
- if (_unlinkedClass != null) {
- ResynthesizerContext context = enclosingUnit.resynthesizerContext;
- _interfaces = _unlinkedClass.interfaces
- .map((EntityRef t) => context.resolveTypeRef(this, t))
- .where(_isInterfaceTypeInterface)
- .cast<InterfaceType>()
- .toList(growable: false);
- }
+ if (_interfaces != null) {
+ return _interfaces;
}
- return _interfaces ?? const <InterfaceType>[];
+
+ if (_unlinkedClass != null) {
+ var unlinkedInterfaces = _unlinkedClass.interfaces;
+ var length = unlinkedInterfaces.length;
+ if (length == 0) {
+ return _interfaces = const <InterfaceType>[];
+ }
+
+ ResynthesizerContext context = enclosingUnit.resynthesizerContext;
+ var interfaces = new List<InterfaceType>(length);
+ var index = 0;
+ var hasNonInterfaceType = false;
+ for (var i = 0; i < length; i++) {
+ var t = unlinkedInterfaces[i];
+ var type = context.resolveTypeRef(this, t);
+ if (_isInterfaceTypeInterface(type)) {
+ interfaces[index++] = type;
+ } else {
+ hasNonInterfaceType = true;
+ }
+ }
+
+ if (hasNonInterfaceType) {
+ interfaces = interfaces.sublist(0, index);
+ }
+
+ return _interfaces = interfaces;
+ }
+
+ return _interfaces = const <InterfaceType>[];
}
void set interfaces(List<InterfaceType> interfaces) {
@@ -721,13 +773,40 @@
@override
List<MethodElement> get methods {
- if (_unlinkedClass != null) {
- _methods ??= _unlinkedClass.executables
- .where((e) => e.kind == UnlinkedExecutableKind.functionOrMethod)
- .map((e) => new MethodElementImpl.forSerialized(e, this))
- .toList(growable: false);
+ if (_methods != null) {
+ return _methods;
}
- return _methods ?? const <MethodElement>[];
+
+ if (_unlinkedClass != null) {
+ var unlinkedExecutables = _unlinkedClass.executables;
+
+ var length = unlinkedExecutables.length;
+ if (length == 0) {
+ return _methods = const <MethodElement>[];
+ }
+
+ var count = 0;
+ for (var i = 0; i < length; i++) {
+ var e = unlinkedExecutables[i];
+ if (e.kind == UnlinkedExecutableKind.functionOrMethod) {
+ count++;
+ }
+ }
+ if (count == 0) {
+ return _methods = const <MethodElement>[];
+ }
+
+ var methods = new List<MethodElement>(count);
+ var index = 0;
+ for (var i = 0; i < length; i++) {
+ var e = unlinkedExecutables[i];
+ if (e.kind == UnlinkedExecutableKind.functionOrMethod) {
+ methods[index++] = new MethodElementImpl.forSerialized(e, this);
+ }
+ }
+ return _methods = methods;
+ }
+ return _methods = const <MethodElement>[];
}
/// Set the methods contained in this class to the given [methods].
@@ -747,17 +826,39 @@
@override
List<InterfaceType> get mixins {
- if (_mixins == null) {
- if (_unlinkedClass != null) {
- ResynthesizerContext context = enclosingUnit.resynthesizerContext;
- _mixins = _unlinkedClass.mixins
- .map((EntityRef t) => context.resolveTypeRef(this, t))
- .where(_isInterfaceTypeInterface)
- .cast<InterfaceType>()
- .toList(growable: false);
- }
+ if (_mixins != null) {
+ return _mixins;
}
- return _mixins ?? const <InterfaceType>[];
+
+ if (_unlinkedClass != null) {
+ var unlinkedMixins = _unlinkedClass.mixins;
+ var length = unlinkedMixins.length;
+ if (length == 0) {
+ return _mixins = const <InterfaceType>[];
+ }
+
+ ResynthesizerContext context = enclosingUnit.resynthesizerContext;
+ var mixins = new List<InterfaceType>(length);
+ var index = 0;
+ var hasNonInterfaceType = false;
+ for (var i = 0; i < length; i++) {
+ var t = unlinkedMixins[i];
+ var type = context.resolveTypeRef(this, t);
+ if (_isInterfaceTypeInterface(type)) {
+ mixins[index++] = type;
+ } else {
+ hasNonInterfaceType = true;
+ }
+ }
+
+ if (hasNonInterfaceType) {
+ mixins = mixins.sublist(0, index);
+ }
+
+ return _mixins = mixins;
+ }
+
+ return _mixins = const <InterfaceType>[];
}
void set mixins(List<InterfaceType> mixins) {
@@ -1067,60 +1168,105 @@
void _resynthesizeFieldsAndPropertyAccessors() {
assert(_fields == null);
assert(_accessors == null);
- var explicitFields = <FieldElement>[];
- var implicitAccessors = <PropertyAccessorElement>[];
- var explicitAccessors = <PropertyAccessorElement>[];
- var implicitFields = <String, FieldElementImpl>{};
+
+ var unlinkedFields = _unlinkedClass.fields;
+ var unlinkedExecutables = _unlinkedClass.executables;
// Build explicit fields and implicit property accessors.
- for (UnlinkedVariable v in _unlinkedClass.fields) {
- FieldElementImpl field =
- new FieldElementImpl.forSerializedFactory(v, this);
- explicitFields.add(field);
- implicitAccessors.add(
- new PropertyAccessorElementImpl_ImplicitGetter(field)
- ..enclosingElement = this);
- if (!field.isConst && !field.isFinal) {
+ List<FieldElement> explicitFields;
+ List<PropertyAccessorElement> implicitAccessors;
+ var unlinkedFieldsLength = unlinkedFields.length;
+ if (unlinkedFieldsLength != 0) {
+ explicitFields = new List<FieldElement>(unlinkedFieldsLength);
+ implicitAccessors = <PropertyAccessorElement>[];
+ for (var i = 0; i < unlinkedFieldsLength; i++) {
+ var v = unlinkedFields[i];
+ FieldElementImpl field =
+ new FieldElementImpl.forSerializedFactory(v, this);
+ explicitFields[i] = field;
implicitAccessors.add(
- new PropertyAccessorElementImpl_ImplicitSetter(field)
+ new PropertyAccessorElementImpl_ImplicitGetter(field)
..enclosingElement = this);
+ if (!field.isConst && !field.isFinal) {
+ implicitAccessors.add(
+ new PropertyAccessorElementImpl_ImplicitSetter(field)
+ ..enclosingElement = this);
+ }
}
+ } else {
+ explicitFields = const <FieldElement>[];
+ implicitAccessors = const <PropertyAccessorElement>[];
}
- // Build explicit property accessors and implicit fields.
- for (UnlinkedExecutable e in _unlinkedClass.executables) {
+
+ var unlinkedExecutablesLength = unlinkedExecutables.length;
+ var getterSetterCount = 0;
+ for (var i = 0; i < unlinkedExecutablesLength; i++) {
+ var e = unlinkedExecutables[i];
if (e.kind == UnlinkedExecutableKind.getter ||
e.kind == UnlinkedExecutableKind.setter) {
- PropertyAccessorElementImpl accessor =
- new PropertyAccessorElementImpl.forSerialized(e, this);
- explicitAccessors.add(accessor);
- // Create or update the implicit field.
- String fieldName = accessor.displayName;
- FieldElementImpl field = implicitFields[fieldName];
- if (field == null) {
- field = new FieldElementImpl(fieldName, -1);
- implicitFields[fieldName] = field;
- field.enclosingElement = this;
- field.isSynthetic = true;
- field.isFinal = e.kind == UnlinkedExecutableKind.getter;
- field.isStatic = e.isStatic;
- } else {
- field.isFinal = false;
- }
- accessor.variable = field;
- if (e.kind == UnlinkedExecutableKind.getter) {
- field.getter = accessor;
- } else {
- field.setter = accessor;
- }
+ getterSetterCount++;
}
}
+
+ // Build explicit property accessors and implicit fields.
+ List<PropertyAccessorElement> explicitAccessors;
+ Map<String, FieldElementImpl> implicitFields;
+ if (getterSetterCount != 0) {
+ explicitAccessors = new List<PropertyAccessorElement>(getterSetterCount);
+ implicitFields = <String, FieldElementImpl>{};
+ var index = 0;
+ for (var i = 0; i < unlinkedExecutablesLength; i++) {
+ var e = unlinkedExecutables[i];
+ if (e.kind == UnlinkedExecutableKind.getter ||
+ e.kind == UnlinkedExecutableKind.setter) {
+ PropertyAccessorElementImpl accessor =
+ new PropertyAccessorElementImpl.forSerialized(e, this);
+ explicitAccessors[index++] = accessor;
+ // Create or update the implicit field.
+ String fieldName = accessor.displayName;
+ FieldElementImpl field = implicitFields[fieldName];
+ if (field == null) {
+ field = new FieldElementImpl(fieldName, -1);
+ implicitFields[fieldName] = field;
+ field.enclosingElement = this;
+ field.isSynthetic = true;
+ field.isFinal = e.kind == UnlinkedExecutableKind.getter;
+ field.isStatic = e.isStatic;
+ } else {
+ field.isFinal = false;
+ }
+ accessor.variable = field;
+ if (e.kind == UnlinkedExecutableKind.getter) {
+ field.getter = accessor;
+ } else {
+ field.setter = accessor;
+ }
+ }
+ }
+ } else {
+ explicitAccessors = const <PropertyAccessorElement>[];
+ implicitFields = const <String, FieldElementImpl>{};
+ }
+
// Combine explicit and implicit fields and property accessors.
- _fields = <FieldElement>[]
- ..addAll(explicitFields)
- ..addAll(implicitFields.values);
- _accessors = <PropertyAccessorElement>[]
- ..addAll(explicitAccessors)
- ..addAll(implicitAccessors);
+ if (implicitFields.isEmpty) {
+ _fields = explicitFields;
+ } else if (explicitFields.isEmpty) {
+ _fields = implicitFields.values.toList(growable: false);
+ } else {
+ _fields = <FieldElement>[]
+ ..addAll(explicitFields)
+ ..addAll(implicitFields.values);
+ }
+ if (explicitAccessors.isEmpty) {
+ _accessors = implicitAccessors;
+ } else if (implicitAccessors.isEmpty) {
+ _accessors = explicitAccessors;
+ } else {
+ _accessors = <PropertyAccessorElement>[]
+ ..addAll(explicitAccessors)
+ ..addAll(implicitAccessors);
+ }
}
bool _safeIsOrInheritsProxy(
@@ -1524,6 +1670,7 @@
}
}
+ @deprecated
@override
CompilationUnit computeNode() => unit;
@@ -2049,6 +2196,7 @@
super.appendTo(buffer);
}
+ @deprecated
@override
ConstructorDeclaration computeNode() =>
getNodeMatching((node) => node is ConstructorDeclaration);
@@ -2141,8 +2289,7 @@
/// This interface is only used for constant variables that have initializers.
///
/// This class is not intended to be part of the public API for analyzer.
-abstract class ConstVariableElement
- implements ElementImpl, ConstantEvaluationTarget {
+mixin ConstVariableElement implements ElementImpl, ConstantEvaluationTarget {
/// If this element represents a constant variable, and it has an initializer,
/// a copy of the initializer for the constant. Otherwise `null`.
///
@@ -2233,6 +2380,7 @@
UnlinkedParam unlinkedParam, ElementImpl enclosingElement)
: super.forSerialized(unlinkedParam, enclosingElement);
+ @deprecated
@override
DefaultFormalParameter computeNode() =>
getNodeMatching((node) => node is DefaultFormalParameter);
@@ -2363,6 +2511,10 @@
ElementAnnotationImpl(this.compilationUnit);
@override
+ List<AnalysisError> get constantEvaluationErrors =>
+ evaluationResult?.errors ?? const <AnalysisError>[];
+
+ @override
DartObject get constantValue => evaluationResult?.value;
@override
@@ -2852,6 +3004,11 @@
}
@override
+ AnalysisSession get session {
+ return _enclosingElement?.session;
+ }
+
+ @override
Source get source {
if (_enclosingElement == null) {
return null;
@@ -2866,6 +3023,7 @@
return _enclosingElement?.typeParameterContext;
}
+ @deprecated
@override
CompilationUnit get unit => context.resolveCompilationUnit(source, library);
@@ -2912,6 +3070,7 @@
@override
String computeDocumentationComment() => documentationComment;
+ @deprecated
@override
AstNode computeNode() => getNodeMatching((node) => node is AstNode);
@@ -2949,6 +3108,7 @@
}
/// Return the resolved [AstNode] of the given type enclosing [getNameOffset].
+ @deprecated
AstNode getNodeMatching(Predicate<AstNode> predicate) {
CompilationUnit unit = this.unit;
if (unit == null) {
@@ -2959,7 +3119,7 @@
if (node == null) {
return null;
}
- return node.getAncestor(predicate);
+ return node.thisOrAncestorMatching(predicate);
}
/// Return `true` if this element has the given [modifier] associated with it.
@@ -3768,7 +3928,7 @@
/// order in which they were specified.
List<NamespaceCombinator> _combinators;
- /// The URI that was selected based on the [context] declared variables.
+ /// The URI that was selected based on the declared variables.
String _selectedUri;
/// Initialize a newly created export element at the given [offset].
@@ -3975,6 +4135,7 @@
@override
T accept<T>(ElementVisitor<T> visitor) => visitor.visitFieldElement(this);
+ @deprecated
@override
AstNode computeNode() {
if (isEnumConstant) {
@@ -4147,6 +4308,7 @@
super.appendTo(buffer);
}
+ @deprecated
@override
FunctionDeclaration computeNode() =>
getNodeMatching((node) => node is FunctionDeclaration);
@@ -4619,6 +4781,7 @@
}
}
+ @deprecated
@override
GenericTypeAlias computeNode() =>
getNodeMatching((node) => node is GenericTypeAlias);
@@ -4746,7 +4909,7 @@
///` if there was no prefix specified.
PrefixElement _prefix;
- /// The URI that was selected based on the [context] declared variables.
+ /// The URI that was selected based on the declared variables.
String _selectedUri;
/// The cached value of [namespace].
@@ -5030,6 +5193,9 @@
/// The analysis context in which this library is defined.
final AnalysisContext context;
+ @override
+ final AnalysisSession session;
+
final LibraryResynthesizerContext resynthesizerContext;
final UnlinkedUnit unlinkedDefiningUnit;
@@ -5084,22 +5250,29 @@
/// Initialize a newly created library element in the given [context] to have
/// the given [name] and [offset].
- LibraryElementImpl(this.context, String name, int offset, this.nameLength)
+ LibraryElementImpl(
+ this.context, this.session, String name, int offset, this.nameLength)
: resynthesizerContext = null,
unlinkedDefiningUnit = null,
super(name, offset);
/// Initialize a newly created library element in the given [context] to have
/// the given [name].
- LibraryElementImpl.forNode(this.context, LibraryIdentifier name)
+ LibraryElementImpl.forNode(this.context, this.session, LibraryIdentifier name)
: nameLength = name != null ? name.length : 0,
resynthesizerContext = null,
unlinkedDefiningUnit = null,
super.forNode(name);
/// Initialize using the given serialized information.
- LibraryElementImpl.forSerialized(this.context, String name, int offset,
- this.nameLength, this.resynthesizerContext, this.unlinkedDefiningUnit)
+ LibraryElementImpl.forSerialized(
+ this.context,
+ this.session,
+ String name,
+ int offset,
+ this.nameLength,
+ this.resynthesizerContext,
+ this.unlinkedDefiningUnit)
: super.forSerialized(null) {
_name = name;
_nameOffset = offset;
@@ -5491,6 +5664,19 @@
}
@override
+ Iterable<Element> get topLevelElements sync* {
+ for (var unit in units) {
+ yield* unit.accessors;
+ yield* unit.enums;
+ yield* unit.functionTypeAliases;
+ yield* unit.functions;
+ yield* unit.mixins;
+ yield* unit.topLevelVariables;
+ yield* unit.types;
+ }
+ }
+
+ @override
List<CompilationUnitElement> get units {
List<CompilationUnitElement> units = new List<CompilationUnitElement>();
units.add(_definingCompilationUnit);
@@ -5793,6 +5979,7 @@
buffer.write(displayName);
}
+ @deprecated
@override
Declaration computeNode() => getNodeMatching(
(node) => node is DeclaredIdentifier || node is VariableDeclaration);
@@ -5889,6 +6076,7 @@
super.appendTo(buffer);
}
+ @deprecated
@override
MethodDeclaration computeNode() =>
getNodeMatching((node) => node is MethodDeclaration);
@@ -6166,6 +6354,9 @@
@override
final AnalysisContext context;
+ @override
+ final AnalysisSession session;
+
/// The name of the conflicting elements.
@override
final String name;
@@ -6175,7 +6366,8 @@
/// Initialize a newly created element in the given [context] to represent
/// the given non-empty [conflictingElements].
- MultiplyDefinedElementImpl(this.context, this.name, this.conflictingElements);
+ MultiplyDefinedElementImpl(
+ this.context, this.session, this.name, this.conflictingElements);
@override
String get displayName => name;
@@ -6300,6 +6492,7 @@
@override
String computeDocumentationComment() => null;
+ @deprecated
@override
AstNode computeNode() => null;
@@ -6924,6 +7117,7 @@
buffer.write(right);
}
+ @deprecated
@override
FormalParameter computeNode() =>
getNodeMatching((node) => node is FormalParameter);
@@ -7047,7 +7241,7 @@
/// A mixin that provides a common implementation for methods defined in
/// [ParameterElement].
-abstract class ParameterElementMixin implements ParameterElement {
+mixin ParameterElementMixin implements ParameterElement {
@override
bool get isNamed => parameterKind == ParameterKind.NAMED;
@@ -7301,6 +7495,7 @@
super.appendTo(buffer);
}
+ @deprecated
@override
AstNode computeNode() {
if (isSynthetic) {
@@ -7569,7 +7764,7 @@
/// Mixin providing the implementation of
/// [TypeParameterizedElement.isSimplyBounded] for elements that define a type.
-abstract class SimplyBoundableMixin implements TypeParameterizedElement {
+mixin SimplyBoundableMixin implements TypeParameterizedElement {
CompilationUnitElementImpl get enclosingUnit;
@override
@@ -7618,6 +7813,7 @@
T accept<T>(ElementVisitor<T> visitor) =>
visitor.visitTopLevelVariableElement(this);
+ @deprecated
@override
VariableDeclaration computeNode() =>
getNodeMatching((node) => node is VariableDeclaration);
@@ -7754,7 +7950,7 @@
}
/// Mixin representing an element which can have type parameters.
-abstract class TypeParameterizedElementMixin
+mixin TypeParameterizedElementMixin
implements
TypeParameterizedElement,
ElementImpl,
diff --git a/pkg/analyzer/lib/src/dart/element/handle.dart b/pkg/analyzer/lib/src/dart/element/handle.dart
index 728ff86..97f978f 100644
--- a/pkg/analyzer/lib/src/dart/element/handle.dart
+++ b/pkg/analyzer/lib/src/dart/element/handle.dart
@@ -2,6 +2,7 @@
// 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:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/constant/value.dart';
import 'package:analyzer/dart/element/element.dart';
@@ -117,6 +118,7 @@
@override
ConstructorElement get unnamedConstructor => actualElement.unnamedConstructor;
+ @deprecated
@override
NamedCompilationUnitMember computeNode() => super.computeNode();
@@ -246,6 +248,7 @@
@override
int get uriOffset => actualElement.uriOffset;
+ @deprecated
@override
CompilationUnit computeNode() => actualElement.computeNode();
@@ -302,6 +305,7 @@
ConstructorElement get redirectedConstructor =>
actualElement.redirectedConstructor;
+ @deprecated
@override
ConstructorDeclaration computeNode() => actualElement.computeNode();
}
@@ -458,8 +462,12 @@
int get nameOffset => actualElement.nameOffset;
@override
+ AnalysisSession get session => _resynthesizer.session;
+
+ @override
Source get source => actualElement.source;
+ @deprecated
@override
CompilationUnit get unit => actualElement.unit;
@@ -473,6 +481,7 @@
@override
String computeDocumentationComment() => documentationComment;
+ @deprecated
@override
AstNode computeNode() => actualElement.computeNode();
@@ -509,10 +518,17 @@
final AnalysisContext context;
/**
+ * The session that owns the element to be resynthesized.
+ *
+ * Note that this will be `null` if the task model is being used.
+ */
+ final AnalysisSession session;
+
+ /**
* Initialize a newly created resynthesizer to resynthesize elements in the
* given [context].
*/
- ElementResynthesizer(this.context);
+ ElementResynthesizer(this.context, this.session);
/**
* Return the element referenced by the given [location].
@@ -646,6 +662,7 @@
@override
ElementKind get kind => ElementKind.FIELD;
+ @deprecated
@override
VariableDeclaration computeNode() => actualElement.computeNode();
}
@@ -676,6 +693,7 @@
@override
SourceRange get visibleRange => actualElement.visibleRange;
+ @deprecated
@override
FunctionDeclaration computeNode() => actualElement.computeNode();
}
@@ -723,6 +741,7 @@
@override
List<TypeParameterElement> get typeParameters => actualElement.typeParameters;
+ @deprecated
@override
FunctionTypeAlias computeNode() => actualElement.computeNode();
@@ -769,6 +788,7 @@
@override
List<TypeParameterElement> get typeParameters => actualElement.typeParameters;
+ @deprecated
@override
FunctionTypeAlias computeNode() => actualElement.computeNode();
@@ -923,6 +943,9 @@
Namespace get publicNamespace => actualElement.publicNamespace;
@override
+ Iterable<Element> get topLevelElements => actualElement.topLevelElements;
+
+ @override
List<CompilationUnitElement> get units => actualElement.units;
@override
@@ -957,6 +980,7 @@
@override
SourceRange get visibleRange => actualElement.visibleRange;
+ @deprecated
@override
VariableDeclaration computeNode() => actualElement.computeNode();
}
@@ -987,6 +1011,7 @@
@override
ElementKind get kind => ElementKind.METHOD;
+ @deprecated
@override
MethodDeclaration computeNode() => actualElement.computeNode();
@@ -1039,6 +1064,7 @@
@override
SourceRange get visibleRange => actualElement.visibleRange;
+ @deprecated
@override
FormalParameter computeNode() => super.computeNode();
}
@@ -1164,6 +1190,7 @@
@override
ElementKind get kind => ElementKind.TOP_LEVEL_VARIABLE;
+ @deprecated
@override
VariableDeclaration computeNode() => super.computeNode();
}
diff --git a/pkg/analyzer/lib/src/dart/element/inheritance_manager2.dart b/pkg/analyzer/lib/src/dart/element/inheritance_manager2.dart
index 8d18330..d523d07 100644
--- a/pkg/analyzer/lib/src/dart/element/inheritance_manager2.dart
+++ b/pkg/analyzer/lib/src/dart/element/inheritance_manager2.dart
@@ -71,13 +71,13 @@
return Interface._empty;
}
- Map<Name, FunctionType> map = {};
Map<Name, List<FunctionType>> namedCandidates = {};
List<Map<Name, FunctionType>> superImplemented = [];
+ Map<Name, FunctionType> declared;
try {
// If a class declaration has a member declaration, the signature of that
// member declaration becomes the signature in the interface.
- _addTypeMembers(map, type);
+ declared = _getTypeMembers(type);
for (var interface in type.interfaces) {
_addCandidates(namedCandidates, interface);
@@ -123,6 +123,7 @@
// super-interfaces that is a valid override of all the other
// super-interface signatures with the same name. That "most specific"
// signature becomes the signature of the class's interface.
+ Map<Name, FunctionType> map = new Map.of(declared);
List<Conflict> conflicts = _findMostSpecificFromNamedCandidates(
map,
namedCandidates,
@@ -130,6 +131,7 @@
var interface = new Interface._(
map,
+ declared,
namedCandidates,
superImplemented,
conflicts ?? const [],
@@ -197,20 +199,6 @@
}
}
- void _addTypeMembers(Map<Name, FunctionType> map, InterfaceType type) {
- var libraryUri = type.element.librarySource.uri;
-
- void addTypeMember(ExecutableElement member) {
- if (!member.isStatic) {
- var name = new Name(libraryUri, member.name);
- map[name] = member.type;
- }
- }
-
- type.methods.forEach(addTypeMember);
- type.accessors.forEach(addTypeMember);
- }
-
/// Check that all [candidates] for the given [name] have the same kind, all
/// getters, all methods, or all setter. If a conflict found, return the
/// new [Conflict] instance that describes it.
@@ -389,6 +377,31 @@
_mixinMembers[type] = implemented;
return implemented;
}
+
+ Map<Name, FunctionType> _getTypeMembers(InterfaceType type) {
+ var declared = <Name, FunctionType>{};
+ var libraryUri = type.element.librarySource.uri;
+
+ var methods = type.methods;
+ for (var i = 0; i < methods.length; i++) {
+ var method = methods[i];
+ if (!method.isStatic) {
+ var name = new Name(libraryUri, method.name);
+ declared[name] = method.type;
+ }
+ }
+
+ var accessors = type.accessors;
+ for (var i = 0; i < accessors.length; i++) {
+ var accessor = accessors[i];
+ if (!accessor.isStatic) {
+ var name = new Name(libraryUri, accessor.name);
+ declared[name] = accessor.type;
+ }
+ }
+
+ return declared;
+ }
}
/// The instance interface of an [InterfaceType].
@@ -396,6 +409,7 @@
static const _empty = const Interface._(
const {},
const {},
+ const {},
const [{}],
const [],
);
@@ -403,6 +417,9 @@
/// The map of names to their signature in the interface.
final Map<Name, FunctionType> map;
+ /// The map of declared names to their signatures.
+ final Map<Name, FunctionType> declared;
+
/// The map of names to their signatures from the mixins, superclasses,
/// or interfaces.
final Map<Name, List<FunctionType>> _overridden;
@@ -420,6 +437,7 @@
const Interface._(
this.map,
+ this.declared,
this._overridden,
this._superImplemented,
this.conflicts,
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index c5f7657..bc18d7b7 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -2,6 +2,7 @@
// 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:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/constant/value.dart';
import 'package:analyzer/dart/element/element.dart';
@@ -63,6 +64,7 @@
T accept<T>(ElementVisitor<T> visitor) =>
visitor.visitConstructorElement(this);
+ @deprecated
@override
ConstructorDeclaration computeNode() => baseElement.computeNode();
@@ -268,6 +270,7 @@
@override
T accept<T>(ElementVisitor<T> visitor) => visitor.visitFieldElement(this);
+ @deprecated
@override
VariableDeclaration computeNode() => baseElement.computeNode();
@@ -326,6 +329,7 @@
@override
T accept<T>(ElementVisitor<T> visitor) => visitor.visitFunctionElement(this);
+ @deprecated
@override
FunctionDeclaration computeNode() => baseElement.computeNode();
@@ -496,14 +500,19 @@
int get nameOffset => _baseElement.nameOffset;
@override
+ AnalysisSession get session => _baseElement.session;
+
+ @override
Source get source => _baseElement.source;
+ @deprecated
@override
CompilationUnit get unit => _baseElement.unit;
@override
String computeDocumentationComment() => documentationComment;
+ @deprecated
@override
AstNode computeNode() => _baseElement.computeNode();
@@ -586,6 +595,7 @@
@override
T accept<T>(ElementVisitor<T> visitor) => visitor.visitMethodElement(this);
+ @deprecated
@override
MethodDeclaration computeNode() => baseElement.computeNode();
@@ -729,6 +739,7 @@
@override
T accept<T>(ElementVisitor<T> visitor) => visitor.visitParameterElement(this);
+ @deprecated
@override
FormalParameter computeNode() => baseElement.computeNode();
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index b566cbb..86b41bc 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -2053,6 +2053,16 @@
@override
DartType replaceTopAndBottom(TypeProvider typeProvider,
{bool isCovariant: true}) {
+ // First check if this is actually an instance of Bottom
+ if (this.isDartCoreNull) {
+ if (isCovariant) {
+ return this;
+ } else {
+ return typeProvider.objectType;
+ }
+ }
+
+ // Otherwise, recurse over type arguments.
var typeArguments = _transformOrShare(
this.typeArguments,
(t) => (t as TypeImpl)
diff --git a/pkg/analyzer/lib/src/dart/element/wrapped.dart b/pkg/analyzer/lib/src/dart/element/wrapped.dart
index aaad9cd..3dfc8d6 100644
--- a/pkg/analyzer/lib/src/dart/element/wrapped.dart
+++ b/pkg/analyzer/lib/src/dart/element/wrapped.dart
@@ -2,6 +2,7 @@
// 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:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart' hide Directive;
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/resolver/scope.dart';
@@ -151,6 +152,9 @@
int get nameOffset => wrappedUnit.nameOffset;
@override
+ AnalysisSession get session => wrappedUnit.session;
+
+ @override
Source get source => wrappedUnit.source;
@override
@@ -160,6 +164,7 @@
@override
List<ClassElement> get types => wrappedUnit.types;
+ @deprecated
@override
CompilationUnit get unit => wrappedUnit.unit;
@@ -179,6 +184,7 @@
String computeDocumentationComment() => wrappedUnit
.computeDocumentationComment(); // ignore: deprecated_member_use
+ @deprecated
@override
CompilationUnit computeNode() => wrappedUnit.computeNode();
@@ -342,8 +348,12 @@
int get prefixOffset => wrappedImport.prefixOffset;
@override
+ AnalysisSession get session => wrappedImport.session;
+
+ @override
Source get source => wrappedImport.source;
+ @deprecated
@override
CompilationUnit get unit => wrappedImport.unit;
@@ -363,6 +373,7 @@
String computeDocumentationComment() => wrappedImport
.computeDocumentationComment(); // ignore: deprecated_member_use
+ @deprecated
@override
AstNode computeNode() => wrappedImport.computeNode();
@@ -560,9 +571,16 @@
Namespace get publicNamespace => wrappedLib.publicNamespace;
@override
+ AnalysisSession get session => wrappedLib.session;
+
+ @override
Source get source => wrappedLib.source;
@override
+ Iterable<Element> get topLevelElements => wrappedLib.topLevelElements;
+
+ @deprecated
+ @override
CompilationUnit get unit => wrappedLib.unit;
@override
@@ -575,6 +593,7 @@
String computeDocumentationComment() =>
wrappedLib.computeDocumentationComment(); // ignore: deprecated_member_use
+ @deprecated
@override
AstNode computeNode() => wrappedLib.computeNode();
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
index 12f0423..b6364f8 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
@@ -571,21 +571,6 @@
/**
* This hint is generated anywhere where the
- * [StaticTypeWarningCode.UNDEFINED_METHOD] would have been generated, if we
- * used propagated information for the warnings.
- *
- * Parameters:
- * 0: the name of the method that is undefined
- * 1: the resolved type name that the method lookup is happening on
- */
- static const HintCode UNDEFINED_METHOD = const HintCode(
- 'UNDEFINED_METHOD', "The method '{0}' isn't defined for the class '{1}'.",
- correction:
- "Try correcting the name to the name of an existing method, or "
- "defining a method named '{0}'.");
-
- /**
- * This hint is generated anywhere where the
* [StaticTypeWarningCode.UNDEFINED_OPERATOR] would have been generated, if we
* used propagated information for the warnings.
*
diff --git a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
new file mode 100644
index 0000000..46f8334
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
@@ -0,0 +1,625 @@
+// Copyright (c) 2018, 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: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';
+import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/inheritance_manager2.dart';
+import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/resolver/scope.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+
+class MethodInvocationResolver {
+ static final _nameCall = new Name(null, 'call');
+
+ /// The resolver driving this participant.
+ final ResolverVisitor _resolver;
+
+ /// The type representing the type 'dynamic'.
+ final DynamicTypeImpl _dynamicType = DynamicTypeImpl.instance;
+
+ /// The type representing the type 'type'.
+ final InterfaceType _typeType;
+
+ /// The manager for the inheritance mappings.
+ final InheritanceManager2 _inheritance;
+
+ /// The element for the library containing the compilation unit being visited.
+ final LibraryElement _definingLibrary;
+
+ /// The URI of [_definingLibrary].
+ final Uri _definingLibraryUri;
+
+ /// The object keeping track of which elements have had their types promoted.
+ final TypePromotionManager _promoteManager;
+
+ /// The [Name] object of the invocation being resolved by [resolve].
+ Name _currentName;
+
+ MethodInvocationResolver(this._resolver)
+ : _typeType = _resolver.typeProvider.typeType,
+ _inheritance = _resolver.inheritance,
+ _definingLibrary = _resolver.definingLibrary,
+ _definingLibraryUri = _resolver.definingLibrary.source.uri,
+ _promoteManager = _resolver.promoteManager;
+
+ /// The scope used to resolve identifiers.
+ Scope get nameScope => _resolver.nameScope;
+
+ void resolve(MethodInvocation node) {
+ SimpleIdentifier nameNode = node.methodName;
+ String name = nameNode.name;
+ _currentName = Name(_definingLibraryUri, name);
+
+ //
+ // Synthetic identifiers have been already reported during parsing.
+ //
+ if (nameNode.isSynthetic) {
+ return;
+ }
+
+ Expression receiver = node.realTarget;
+
+ if (receiver == null) {
+ _resolveReceiverNull(node, nameNode, name);
+ return;
+ }
+
+ if (receiver is NullLiteral) {
+ _setDynamicResolution(node);
+ return;
+ }
+
+ if (receiver is SimpleIdentifier) {
+ var receiverElement = receiver.staticElement;
+ if (receiverElement is PrefixElement) {
+ _resolveReceiverPrefix(node, receiver, receiverElement, nameNode, name);
+ return;
+ }
+ }
+
+ if (receiver is SuperExpression) {
+ _resolveReceiverSuper(node, receiver, nameNode, name);
+ return;
+ }
+
+ ClassElement typeReference = getTypeReference(receiver);
+ if (typeReference != null) {
+ _resolveReceiverTypeLiteral(node, typeReference, nameNode, name);
+ return;
+ }
+
+ DartType receiverType = receiver.staticType;
+ receiverType = _resolveTypeParameter(receiverType);
+
+ if (receiverType is InterfaceType) {
+ _resolveReceiverInterfaceType(node, receiverType, nameNode, name);
+ return;
+ }
+
+ if (receiverType is DynamicTypeImpl) {
+ _resolveReceiverDynamic(node, name);
+ return;
+ }
+
+ if (receiverType is FunctionType) {
+ _resolveReceiverFunctionType(
+ node, receiver, receiverType, nameNode, name);
+ return;
+ }
+
+ if (receiverType is VoidType) {
+ _reportUseOfVoidType(node, receiver);
+ return;
+ }
+ }
+
+ /// Given an [argumentList] and the executable [element] that will be invoked
+ /// using those arguments, compute the list of parameters that correspond to
+ /// the list of arguments. Return the parameters that correspond to the
+ /// arguments, or `null` if no correspondence could be computed.
+ List<ParameterElement> _computeCorrespondingParameters(
+ ArgumentList argumentList, DartType type) {
+ if (type is InterfaceType) {
+ MethodElement callMethod =
+ type.lookUpMethod(FunctionElement.CALL_METHOD_NAME, _definingLibrary);
+ if (callMethod != null) {
+ return _resolveArgumentsToFunction(false, argumentList, callMethod);
+ }
+ } else if (type is FunctionType) {
+ return _resolveArgumentsToParameters(
+ false, argumentList, type.parameters);
+ }
+ return null;
+ }
+
+ DartType _getCalleeType(FunctionType targetType) {
+ if (targetType.element.kind == ElementKind.GETTER) {
+ var calleeType = (targetType as FunctionTypeImpl).returnType;
+ calleeType = _resolveTypeParameter(calleeType);
+ return calleeType;
+ }
+ return targetType;
+ }
+
+ /// Check for a generic type, and apply type arguments.
+ FunctionType _instantiateFunctionType(
+ FunctionType invokeType, TypeArgumentList typeArguments, AstNode node) {
+ var typeFormals = invokeType.typeFormals;
+ var arguments = typeArguments?.arguments;
+ if (arguments != null && arguments.length != typeFormals.length) {
+ _resolver.errorReporter.reportErrorForNode(
+ StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD,
+ node,
+ [invokeType, typeFormals.length, arguments?.length ?? 0]);
+ arguments = null;
+ }
+
+ if (typeFormals.isNotEmpty) {
+ if (arguments == null) {
+ return _resolver.typeSystem.instantiateToBounds(invokeType);
+ } else {
+ return invokeType.instantiate(arguments.map((n) => n.type).toList());
+ }
+ }
+
+ return invokeType;
+ }
+
+ bool _isCoreFunction(DartType type) {
+ // TODO(scheglov) Can we optimize this?
+ return type is InterfaceType && type.isDartCoreFunction;
+ }
+
+ ExecutableElement _lookUpClassMember(ClassElement element, String name) {
+ // TODO(scheglov) Use class hierarchy.
+ return element.lookUpMethod(name, _definingLibrary);
+ }
+
+ void _reportInvocationOfNonFunction(MethodInvocation node) {
+ _setDynamicResolution(node, setNameTypeToDynamic: false);
+ _resolver.errorReporter.reportErrorForNode(
+ StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION,
+ node.methodName,
+ [node.methodName.name],
+ );
+ }
+
+ void _reportPrefixIdentifierNotFollowedByDot(SimpleIdentifier target) {
+ _resolver.errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
+ target,
+ [target.name],
+ );
+ }
+
+ void _reportUndefinedFunction(
+ MethodInvocation node, Identifier ignorableIdentifier) {
+ _setDynamicResolution(node);
+
+ // TODO(scheglov) This is duplication.
+ if (nameScope.shouldIgnoreUndefined(ignorableIdentifier)) {
+ return;
+ }
+
+ _resolver.errorReporter.reportErrorForNode(
+ StaticTypeWarningCode.UNDEFINED_FUNCTION,
+ node.methodName,
+ [node.methodName.name],
+ );
+ }
+
+ void _reportUndefinedMethod(
+ MethodInvocation node, String name, ClassElement typeReference) {
+ _setDynamicResolution(node);
+ _resolver.errorReporter.reportErrorForNode(
+ StaticTypeWarningCode.UNDEFINED_METHOD,
+ node.methodName,
+ [name, typeReference.displayName],
+ );
+ }
+
+ void _reportUseOfVoidType(MethodInvocation node, AstNode errorNode) {
+ _setDynamicResolution(node);
+ _resolver.errorReporter.reportErrorForNode(
+ StaticWarningCode.USE_OF_VOID_RESULT,
+ errorNode,
+ );
+ }
+
+ /// Given an [argumentList] and the [executableElement] that will be invoked
+ /// using those argument, compute the list of parameters that correspond to the
+ /// list of arguments. An error will be reported if any of the arguments cannot
+ /// be matched to a parameter. The flag [reportAsError] should be `true` if a
+ /// compile-time error should be reported; or `false` if a compile-time warning
+ /// should be reported. Return the parameters that correspond to the arguments,
+ /// or `null` if no correspondence could be computed.
+ List<ParameterElement> _resolveArgumentsToFunction(bool reportAsError,
+ ArgumentList argumentList, ExecutableElement executableElement) {
+ if (executableElement == null) {
+ return null;
+ }
+ List<ParameterElement> parameters = executableElement.parameters;
+ return _resolveArgumentsToParameters(
+ reportAsError, argumentList, parameters);
+ }
+
+ /// Given an [argumentList] and the [parameters] related to the element that
+ /// will be invoked using those arguments, compute the list of parameters that
+ /// correspond to the list of arguments. An error will be reported if any of
+ /// the arguments cannot be matched to a parameter. The flag [reportAsError]
+ /// should be `true` if a compile-time error should be reported; or `false` if
+ /// a compile-time warning should be reported. Return the parameters that
+ /// correspond to the arguments.
+ List<ParameterElement> _resolveArgumentsToParameters(bool reportAsError,
+ ArgumentList argumentList, List<ParameterElement> parameters) {
+ return ResolverVisitor.resolveArgumentsToParameters(
+ argumentList, parameters, _resolver.errorReporter.reportErrorForNode,
+ reportAsError: reportAsError);
+ }
+
+ /// Given that we are accessing a property of the given [classElement] with the
+ /// given [propertyName], return the element that represents the property.
+ Element _resolveElement(
+ ClassElement classElement, SimpleIdentifier propertyName) {
+ // TODO(scheglov) Replace with class hierarchy.
+ String name = propertyName.name;
+ Element element = null;
+ if (propertyName.inSetterContext()) {
+ element = classElement.getSetter(name);
+ }
+ if (element == null) {
+ element = classElement.getGetter(name);
+ }
+ if (element == null) {
+ element = classElement.getMethod(name);
+ }
+ if (element != null && element.isAccessibleIn(_definingLibrary)) {
+ return element;
+ }
+ return null;
+ }
+
+ void _resolveReceiverDynamic(MethodInvocation node, String name) {
+ _setDynamicResolution(node);
+ }
+
+ void _resolveReceiverFunctionType(MethodInvocation node, Expression receiver,
+ FunctionType receiverType, SimpleIdentifier nameNode, String name) {
+ if (name == FunctionElement.CALL_METHOD_NAME) {
+ _setResolution(node, receiverType);
+ // TODO(scheglov) Replace this with using FunctionType directly.
+ // Here was erase resolution that _setResolution() sets.
+ nameNode.staticElement = null;
+ nameNode.staticType = _dynamicType;
+ return;
+ }
+
+ // We can invoke Object methods on Function.
+ var type = _inheritance.getMember(
+ _resolver.typeProvider.objectType,
+ new Name(null, name),
+ );
+ if (type != null) {
+ nameNode.staticElement = type.element;
+ return _setResolution(node, type);
+ }
+
+ _reportUndefinedMethod(
+ node,
+ name,
+ _resolver.typeProvider.functionType.element,
+ );
+ }
+
+ void _resolveReceiverInterfaceType(MethodInvocation node,
+ InterfaceType receiverType, SimpleIdentifier nameNode, String name) {
+ if (_isCoreFunction(receiverType) &&
+ name == FunctionElement.CALL_METHOD_NAME) {
+ _setDynamicResolution(node);
+ return;
+ }
+
+ var targetType = _inheritance.getMember(receiverType, _currentName);
+ if (targetType != null) {
+ var calleeType = _getCalleeType(targetType);
+
+ // TODO(scheglov) This is bad, we have to create members here.
+ // Find a way to avoid this.
+ Element element;
+ var baseElement = targetType.element;
+ if (baseElement is MethodElement) {
+ element = MethodMember.from(baseElement, receiverType);
+ } else if (baseElement is PropertyAccessorElement) {
+ element = PropertyAccessorMember.from(baseElement, receiverType);
+ }
+ nameNode.staticElement = element;
+
+ return _setResolution(node, calleeType);
+ }
+
+ // The interface of the receiver does not have an instance member.
+ // Try to recover and find a member in the class.
+ var targetElement = _lookUpClassMember(receiverType.element, name);
+ if (targetElement != null && targetElement.isStatic) {
+ nameNode.staticElement = targetElement;
+ _setDynamicResolution(node);
+ _resolver.errorReporter.reportErrorForNode(
+ StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER,
+ nameNode,
+ [
+ name,
+ targetElement.kind.displayName,
+ targetElement.enclosingElement.displayName,
+ ],
+ );
+ return;
+ }
+
+ _setDynamicResolution(node);
+ _resolver.errorReporter.reportErrorForNode(
+ StaticTypeWarningCode.UNDEFINED_METHOD,
+ nameNode,
+ [name, receiverType.element.displayName],
+ );
+ }
+
+ void _resolveReceiverNull(
+ MethodInvocation node, SimpleIdentifier nameNode, String name) {
+ var element = nameScope.lookup(nameNode, _definingLibrary);
+ if (element != null) {
+ nameNode.staticElement = element;
+ if (element is MultiplyDefinedElement) {
+ MultiplyDefinedElement multiply = element;
+ element = multiply.conflictingElements[0];
+ }
+ if (element is ExecutableElement) {
+ var calleeType = _getCalleeType(element.type);
+ return _setResolution(node, calleeType);
+ }
+ if (element is VariableElement) {
+ var targetType = _promoteManager.getStaticType(element);
+ return _setResolution(node, targetType);
+ }
+ // TODO(scheglov) This is a questionable distinction.
+ if (element is PrefixElement) {
+ _setDynamicResolution(node);
+ return _reportPrefixIdentifierNotFollowedByDot(nameNode);
+ }
+ return _reportInvocationOfNonFunction(node);
+ }
+
+ ClassElement enclosingClass = _resolver.enclosingClass;
+ if (enclosingClass == null) {
+ return _reportUndefinedFunction(node, node.methodName);
+ }
+
+ var receiverType = enclosingClass.type;
+ var targetType = _inheritance.getMember(receiverType, _currentName);
+
+ if (targetType != null) {
+ nameNode.staticElement = targetType.element;
+ var calleeType = _getCalleeType(targetType);
+ return _setResolution(node, calleeType);
+ }
+
+ var targetElement = _lookUpClassMember(enclosingClass, name);
+ if (targetElement != null && targetElement.isStatic) {
+ nameNode.staticElement = targetElement;
+ _setDynamicResolution(node);
+ _resolver.errorReporter.reportErrorForNode(
+ StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER,
+ nameNode,
+ [receiverType.displayName],
+ );
+ return;
+ }
+
+ return _reportUndefinedMethod(node, name, enclosingClass);
+ }
+
+ void _resolveReceiverPrefix(MethodInvocation node, SimpleIdentifier receiver,
+ PrefixElement prefix, SimpleIdentifier nameNode, String name) {
+ if (node.operator.type == TokenType.QUESTION_PERIOD) {
+ _reportPrefixIdentifierNotFollowedByDot(receiver);
+ }
+
+ if (name == FunctionElement.LOAD_LIBRARY_NAME) {
+ var imports = _definingLibrary.getImportsWithPrefix(prefix);
+ if (imports.length == 1 && imports[0].isDeferred) {
+ var importedLibrary = imports[0].importedLibrary;
+ var loadLibraryFunction = importedLibrary?.loadLibraryFunction;
+ nameNode.staticElement = loadLibraryFunction;
+ node.staticInvokeType = loadLibraryFunction?.type;
+ node.staticType = loadLibraryFunction?.returnType;
+ return;
+ }
+ }
+
+ // TODO(scheglov) I don't like how we resolve prefixed names.
+ // But maybe this is the only one solution.
+ var prefixedName = new PrefixedIdentifierImpl.temp(receiver, nameNode);
+ var element = nameScope.lookup(prefixedName, _definingLibrary);
+ nameNode.staticElement = element;
+
+ if (element is MultiplyDefinedElement) {
+ MultiplyDefinedElement multiply = element;
+ element = multiply.conflictingElements[0];
+ }
+
+ if (element is ExecutableElement) {
+ var calleeType = _getCalleeType(element.type);
+ return _setResolution(node, calleeType);
+ }
+
+ _reportUndefinedFunction(node, prefixedName);
+ }
+
+ void _resolveReceiverSuper(MethodInvocation node, SuperExpression receiver,
+ SimpleIdentifier nameNode, String name) {
+ if (!_isSuperInValidContext(receiver)) {
+ return;
+ }
+
+ var receiverType = _resolver.enclosingClass.type;
+ var targetType = _inheritance.getMember(
+ receiverType,
+ _currentName,
+ forSuper: true,
+ );
+
+ // If there is that concrete dispatch target, then we are done.
+ if (targetType != null) {
+ nameNode.staticElement = targetType.element;
+ var calleeType = _getCalleeType(targetType);
+ _setResolution(node, calleeType);
+ return;
+ }
+
+ // Otherwise, this is an error.
+ // But we would like to give the user at least some resolution.
+ // So, we try to find the interface target.
+ targetType = _inheritance.getInherited(receiverType, _currentName);
+ if (targetType != null) {
+ nameNode.staticElement = targetType.element;
+ var calleeType = _getCalleeType(targetType);
+ _setResolution(node, calleeType);
+
+ ClassElementImpl receiverSuperClass = AbstractClassElementImpl.getImpl(
+ receiverType.element.supertype.element,
+ );
+ if (receiverSuperClass.hasNoSuchMethod) {
+ return;
+ }
+
+ _resolver.errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE,
+ nameNode,
+ [targetType.element.kind.displayName, name]);
+ return;
+ }
+
+ // Nothing help, there is no target at all.
+ _setDynamicResolution(node);
+ _resolver.errorReporter.reportErrorForNode(
+ StaticTypeWarningCode.UNDEFINED_SUPER_METHOD,
+ nameNode,
+ [name, _resolver.enclosingClass.displayName]);
+ }
+
+ void _resolveReceiverTypeLiteral(MethodInvocation node, ClassElement receiver,
+ SimpleIdentifier nameNode, String name) {
+ if (node.isCascaded) {
+ receiver = _typeType.element;
+ }
+
+ var element = _resolveElement(receiver, nameNode);
+ if (element != null) {
+ if (element is ExecutableElement) {
+ nameNode.staticElement = element;
+ var calleeType = _getCalleeType(element.type);
+ _setResolution(node, calleeType);
+ } else {
+ _reportInvocationOfNonFunction(node);
+ }
+ return;
+ }
+
+ _reportUndefinedMethod(node, name, receiver);
+ }
+
+ /// If the given [type] is a type parameter, replace with its bound.
+ /// Otherwise, return the original type.
+ DartType _resolveTypeParameter(DartType type) {
+ if (type is TypeParameterType) {
+ return type.resolveToBound(_resolver.typeProvider.objectType);
+ }
+ return type;
+ }
+
+ void _setDynamicResolution(MethodInvocation node,
+ {bool setNameTypeToDynamic: true}) {
+ if (setNameTypeToDynamic) {
+ node.methodName.staticType = _dynamicType;
+ }
+ node.staticInvokeType = _dynamicType;
+ node.staticType = _dynamicType;
+ }
+
+ void _setResolution(MethodInvocation node, DartType type) {
+ if (type == _dynamicType || _isCoreFunction(type)) {
+ _setDynamicResolution(node);
+ return;
+ }
+
+ // TODO(scheglov) We need this for StaticTypeAnalyzer to run inference.
+ // But it seems weird. Do we need to know the raw type of a function?!
+ node.methodName.staticType = type;
+
+ if (type is InterfaceType) {
+ var call = _inheritance.getMember(type, _nameCall);
+ if (call != null && call.element.kind == ElementKind.METHOD) {
+ type = call;
+ }
+ }
+
+ if (type is FunctionType) {
+ // TODO(scheglov) Extract this when receiver is already FunctionType?
+ var instantiatedType = _instantiateFunctionType(
+ type,
+ node.typeArguments,
+ node.methodName,
+ );
+ node.staticInvokeType = instantiatedType;
+ node.staticType = instantiatedType.returnType;
+ // TODO(scheglov) too much magic
+ node.argumentList.correspondingStaticParameters =
+ _computeCorrespondingParameters(
+ node.argumentList,
+ instantiatedType,
+ );
+ return;
+ }
+
+ if (type is VoidType) {
+ return _reportUseOfVoidType(node, node.methodName);
+ }
+
+ _reportInvocationOfNonFunction(node);
+ }
+
+ /// Checks whether the given [expression] is a reference to a class. If it is
+ /// then the element representing the class is returned, otherwise `null` is
+ /// returned.
+ static ClassElement getTypeReference(Expression expression) {
+ if (expression is Identifier) {
+ Element staticElement = expression.staticElement;
+ if (staticElement is ClassElement) {
+ return staticElement;
+ }
+ }
+ return null;
+ }
+
+ /// Return `true` if the given 'super' [expression] is used in a valid context.
+ static bool _isSuperInValidContext(SuperExpression expression) {
+ for (AstNode node = expression; node != null; node = node.parent) {
+ if (node is CompilationUnit) {
+ return false;
+ } else if (node is ConstructorDeclaration) {
+ return node.factoryKeyword == null;
+ } else if (node is ConstructorFieldInitializer) {
+ return false;
+ } else if (node is MethodDeclaration) {
+ return !node.isStatic;
+ }
+ }
+ return false;
+ }
+}
diff --git a/pkg/analyzer/lib/src/dart/resolver/scope.dart b/pkg/analyzer/lib/src/dart/resolver/scope.dart
index 4d71222..f1fb360 100644
--- a/pkg/analyzer/lib/src/dart/resolver/scope.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/scope.dart
@@ -537,8 +537,11 @@
var conflictingElements = <Element>[]
..addAll(sdkElements)
..addAll(nonSdkElements);
- return new MultiplyDefinedElementImpl(_definingLibrary.context,
- conflictingElements.first.name, conflictingElements);
+ return new MultiplyDefinedElementImpl(
+ _definingLibrary.context,
+ _definingLibrary.session,
+ conflictingElements.first.name,
+ conflictingElements);
}
if (nonSdkElements.isNotEmpty) {
result = nonSdkElements.first;
@@ -1011,8 +1014,7 @@
* not be determined.
*/
Source getSource(AstNode identifier) {
- CompilationUnit unit =
- identifier.getAncestor((node) => node is CompilationUnit);
+ CompilationUnit unit = identifier.thisOrAncestorOfType<CompilationUnit>();
if (unit != null) {
CompilationUnitElement unitElement = unit.declaredElement;
if (unitElement != null) {
diff --git a/pkg/analyzer/lib/src/dart/scanner/scanner.dart b/pkg/analyzer/lib/src/dart/scanner/scanner.dart
index 25af788e..ab852cf 100644
--- a/pkg/analyzer/lib/src/dart/scanner/scanner.dart
+++ b/pkg/analyzer/lib/src/dart/scanner/scanner.dart
@@ -54,6 +54,11 @@
bool scanLazyAssignmentOperators = false;
/**
+ * A flag indicating whether the scanner should recognize the `>>>` operator.
+ */
+ bool enableGtGtGt = false;
+
+ /**
* Initialize a newly created scanner to scan characters from the given
* [source]. The given character [reader] will be used to read the characters
* in the source. The given [_errorListener] will be informed of any errors
@@ -99,6 +104,7 @@
Token tokenize() {
fasta.ScannerResult result = fasta.scanString(_contents,
+ enableGtGtGt: enableGtGtGt,
includeComments: _preserveComments,
scanLazyAssignmentOperators: scanLazyAssignmentOperators);
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index d966ee8..a3cff21 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -49,14 +49,6 @@
"'{1}'.");
/**
- * 16.12.2 Const: It is a compile-time error if evaluation of a constant
- * object results in an uncaught exception being thrown.
- */
- static const CheckedModeCompileTimeErrorCode CONST_EVAL_THROWS_EXCEPTION =
- const CheckedModeCompileTimeErrorCode('CONST_EVAL_THROWS_EXCEPTION',
- "Evaluation of this constant expression throws an exception.");
-
- /**
* 7.6.1 Generative Constructors: In checked mode, it is a dynamic type error
* if o is not <b>null</b> and the interface of the class of <i>o</i> is not a
* subtype of the static type of the field <i>v</i>.
@@ -87,6 +79,10 @@
* the type of the named parameter <i>q</i> of <i>f</i>. It is a static
* warning if <i>T<sub>j</sub></i> may not be assigned to <i>S<sub>j</sub>,
* 1 <= j <= m</i>.
+ *
+ * Parameters:
+ * 0: the actual type of the list element
+ * 1: the expected type of the list element
*/
static const CheckedModeCompileTimeErrorCode
LIST_ELEMENT_TYPE_NOT_ASSIGNABLE = const CheckedModeCompileTimeErrorCode(
@@ -134,6 +130,15 @@
"'{1}'.");
/**
+ * Parameters:
+ * 0: the actual type of the set element
+ * 1: the expected type of the set element
+ */
+ static const CheckedModeCompileTimeErrorCode SET_ELEMENT_TYPE_NOT_ASSIGNABLE =
+ const CheckedModeCompileTimeErrorCode('SET_ELEMENT_TYPE_NOT_ASSIGNABLE',
+ "The element type '{0}' can't be assigned to the set type '{1}'.");
+
+ /**
* 16.12.2 Const: It is a compile-time error if evaluation of a constant
* object results in an uncaught exception being thrown.
*/
@@ -659,6 +664,18 @@
correction: "Try adding an initialization to the declaration.");
/**
+ * Parameters:
+ * 0: the type of the element
+ */
+ static const CompileTimeErrorCode CONST_SET_ELEMENT_TYPE_IMPLEMENTS_EQUALS =
+ const CompileTimeErrorCode(
+ 'CONST_SET_ELEMENT_TYPE_IMPLEMENTS_EQUALS',
+ "The constant set element type '{0}' can't override "
+ "the == operator.",
+ correction: "Try using a different value for the element, or "
+ "removing the keyword 'const' from the set.");
+
+ /**
* 16.12.2 Const: An expression of one of the forms !e, e1 && e2 or e1 || e2,
* where e, e1 and e2 are constant expressions that evaluate to a boolean
* value.
@@ -670,6 +687,17 @@
"'bool'.");
/**
+ * 16.12.2 Const: An expression of one of the forms !e, e1 && e2 or e1 || e2,
+ * where e, e1 and e2 are constant expressions that evaluate to a boolean
+ * value.
+ */
+ static const CompileTimeErrorCode CONST_EVAL_TYPE_BOOL_INT =
+ const CompileTimeErrorCode(
+ 'CONST_EVAL_TYPE_BOOL_INT',
+ "In constant expressions, operands of this operator must be of type "
+ "'bool' or 'int'.");
+
+ /**
* 16.12.2 Const: An expression of one of the forms e1 == e2 or e1 != e2 where
* e1 and e2 are constant expressions that evaluate to a numeric, string or
* boolean value or to null.
@@ -703,6 +731,12 @@
"In constant expressions, operands of this operator must be of type "
"'num'.");
+ static const CompileTimeErrorCode CONST_EVAL_TYPE_TYPE =
+ const CompileTimeErrorCode(
+ 'CONST_EVAL_TYPE_TYPE',
+ "In constant expressions, operands of this operator must be of type "
+ "'Type'.");
+
/**
* 16.12.2 Const: It is a compile-time error if evaluation of a constant
* object results in an uncaught exception being thrown.
@@ -1587,6 +1621,14 @@
correction:
"Try replacing the type parameter with a different type.");
+ static const CompileTimeErrorCode INVALID_TYPE_ARGUMENT_IN_CONST_SET =
+ const CompileTimeErrorCode(
+ 'INVALID_TYPE_ARGUMENT_IN_CONST_SET',
+ "Constant set literals can't include a type parameter as a type "
+ "argument, such as '{0}'.",
+ correction:
+ "Try replacing the type parameter with a different type.");
+
/**
* The 'covariant' keyword was found in an inappropriate location.
*/
@@ -1677,6 +1719,16 @@
"expression.",
correction: "Try adding the keyword 'const' before the literal.");
+ /**
+ * 12.1 Constants: A constant expression is ... a constant set literal.
+ */
+ static const CompileTimeErrorCode MISSING_CONST_IN_SET_LITERAL =
+ const CompileTimeErrorCode(
+ 'MISSING_CONST_IN_SET_LITERAL',
+ "Set literals must be prefixed with 'const' when used as a constant "
+ "expression.",
+ correction: "Try adding the keyword 'const' before the literal.");
+
static const CompileTimeErrorCode MISSING_DART_LIBRARY =
const CompileTimeErrorCode(
'MISSING_DART_LIBRARY', "Required library '{0}' is missing.",
@@ -1714,7 +1766,8 @@
static const CompileTimeErrorCode
MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE = const CompileTimeErrorCode(
'MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE',
- "The class doesn't implement the required class '{0}'.");
+ "The class doesn't implement the required class '{0}'.",
+ correction: "Try extending the class '{0}'.");
/**
* It's a compile-time error to apply a mixin containing super-invocations to
@@ -1967,8 +2020,8 @@
static const CompileTimeErrorCode NON_CONST_MAP_AS_EXPRESSION_STATEMENT =
const CompileTimeErrorCode(
'NON_CONST_MAP_AS_EXPRESSION_STATEMENT',
- "A non-constant map literal without type arguments can't be used as "
- "an expression statement.");
+ "A non-constant map or set literal without type arguments can't be "
+ "used as an expression statement.");
/**
* 13.9 Switch: Given a switch statement of the form <i>switch (e) {
@@ -2041,7 +2094,8 @@
static const CompileTimeErrorCode NON_CONSTANT_LIST_ELEMENT =
const CompileTimeErrorCode('NON_CONSTANT_LIST_ELEMENT',
"The values in a const list literal must be constants.",
- correction: "Try removing the keyword 'const' from the map literal.");
+ correction:
+ "Try removing the keyword 'const' from the list literal.");
/**
* 12.6 Lists: It is a compile time error if an element of a constant list
@@ -2118,6 +2172,19 @@
const CompileTimeErrorCode('NON_CONSTANT_ANNOTATION_CONSTRUCTOR',
"Annotation creation can only call a const constructor.");
+ static const CompileTimeErrorCode NON_CONSTANT_SET_ELEMENT =
+ const CompileTimeErrorCode('NON_CONSTANT_SET_ELEMENT',
+ "The values in a const set literal must be constants.",
+ correction: "Try removing the keyword 'const' from the set literal.");
+
+ static const CompileTimeErrorCode
+ NON_CONSTANT_SET_ELEMENT_FROM_DEFERRED_LIBRARY =
+ const CompileTimeErrorCode(
+ 'NON_CONSTANT_SET_ELEMENT_FROM_DEFERRED_LIBRARY',
+ "Constant values from a deferred library can't be used as values in "
+ "a 'const' set.",
+ correction: "Try removing the keyword 'const' from the set literal.");
+
/**
* 7.6.3 Constant Constructors: Any expression that appears within the
* initializer list of a constant constructor must be a potentially constant
@@ -2251,9 +2318,9 @@
static const CompileTimeErrorCode PRIVATE_COLLISION_IN_MIXIN_APPLICATION =
const CompileTimeErrorCode(
'PRIVATE_COLLISION_IN_MIXIN_APPLICATION',
- "The private name {0}, defined by {1}, conflicts with the same name "
- "defined by {2}.",
- correction: "Try removing {1} from the 'with' clause.");
+ "The private name '{0}', defined by '{1}', "
+ "conflicts with the same name defined by '{2}'.",
+ correction: "Try removing '{1}' from the 'with' clause.");
/**
* 6.2.2 Optional Formals: It is a compile-time error if the name of a named
@@ -2555,13 +2622,13 @@
* It is a compile-time error if a generic function type is used as an actual
* type argument.
*/
- static const CompileTimeErrorCode GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT =
+ static const CompileTimeErrorCode
+ GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT =
const CompileTimeErrorCode(
- 'GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT',
- "Generic function has type parameters '<{0}>', so it may not be used"
- ' as a type argument',
- correction: "Try removing the type parameters '<{0}>', or using"
- " 'dynamic' as the type argument here instead of a function.");
+ 'GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT',
+ "A generic function type cannot be a type argument.",
+ correction: "Try removing type parameters from the generic function "
+ "type, or using 'dynamic' as the type argument here.");
/**
* 15.3.1 Typedef: Any self reference, either directly, or recursively via
@@ -2808,6 +2875,17 @@
correction: "Try adjusting the number of type arguments.");
/**
+ * Parameters:
+ * 0: the number of provided type arguments
+ */
+ static const StaticTypeWarningCode EXPECTED_ONE_SET_TYPE_ARGUMENTS =
+ const StaticTypeWarningCode(
+ 'EXPECTED_ONE_SET_TYPE_ARGUMENTS',
+ "Set literals require exactly one type argument or none, "
+ "but {0} found.",
+ correction: "Try adjusting the number of type arguments.");
+
+ /**
* 12.8 Maps: A fresh instance (7.6.1) <i>m</i>, of size <i>n</i>, whose class
* implements the built-in class <i>Map<K, V></i> is allocated.
*
@@ -3145,22 +3223,6 @@
"defining a method named '{0}'.");
/**
- * 12.15.1 Ordinary Invocation: Let <i>T</i> be the static type of <i>o</i>.
- * It is a static type warning if <i>T</i> does not have an accessible
- * instance member named <i>m</i>.
- *
- * Parameters:
- * 0: the name of the method that is undefined
- * 1: the resolved type name that the method lookup is happening on
- */
- static const StaticTypeWarningCode UNDEFINED_METHOD_WITH_CONSTRUCTOR =
- const StaticTypeWarningCode('UNDEFINED_METHOD_WITH_CONSTRUCTOR',
- "The method '{0}' isn't defined for the class '{1}', but a constructor with that name is defined.",
- correction:
- "Try adding 'new' or 'const' to invoke the constructor, or "
- "correcting the name to the name of an existing method.");
-
- /**
* 12.18 Assignment: Evaluation of an assignment of the form
* <i>e<sub>1</sub></i>[<i>e<sub>2</sub></i>] = <i>e<sub>3</sub></i> is
* equivalent to the evaluation of the expression (a, i, e){a.[]=(i, e);
@@ -3931,6 +3993,10 @@
* the type of the named parameter <i>q</i> of <i>f</i>. It is a static
* warning if <i>T<sub>j</sub></i> may not be assigned to <i>S<sub>j</sub>, 1
* <= j <= m</i>.
+ *
+ * Parameters:
+ * 0: the actual type of the list element
+ * 1: the expected type of the list element
*/
static const StaticWarningCode LIST_ELEMENT_TYPE_NOT_ASSIGNABLE =
const StaticWarningCode('LIST_ELEMENT_TYPE_NOT_ASSIGNABLE',
@@ -4380,6 +4446,15 @@
correction: null);
/**
+ * Parameters:
+ * 0: the actual type of the set element
+ * 1: the expected type of the set element
+ */
+ static const StaticWarningCode SET_ELEMENT_TYPE_NOT_ASSIGNABLE =
+ const StaticWarningCode('SET_ELEMENT_TYPE_NOT_ASSIGNABLE',
+ "The element type '{0}' can't be assigned to the set type '{1}'.");
+
+ /**
* 12.16.3 Static Invocation: It is a static warning if <i>C</i> does not
* declare a static method or getter <i>m</i>.
*
@@ -4639,6 +4714,13 @@
"type can be changed with an explicit generic type arguments or by "
"changing the key and value types.");
+ static const StrongModeCode INVALID_CAST_LITERAL_SET = const StrongModeCode(
+ ErrorType.COMPILE_TIME_ERROR,
+ 'INVALID_CAST_LITERAL_SET',
+ "The set literal type '{0}' isn't of expected type '{1}'. The set's "
+ "type can be changed with an explicit generic type argument or by "
+ "changing the element types.");
+
static const StrongModeCode INVALID_CAST_FUNCTION_EXPR = const StrongModeCode(
ErrorType.COMPILE_TIME_ERROR,
'INVALID_CAST_FUNCTION_EXPR',
diff --git a/pkg/analyzer/lib/src/error/inheritance_override.dart b/pkg/analyzer/lib/src/error/inheritance_override.dart
index b74f141..d545ddc 100644
--- a/pkg/analyzer/lib/src/error/inheritance_override.dart
+++ b/pkg/analyzer/lib/src/error/inheritance_override.dart
@@ -1,11 +1,11 @@
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2018, 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:analyzer/analyzer.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/inheritance_manager2.dart';
@@ -94,8 +94,12 @@
final TypeName superclass;
final WithClause withClause;
+ /// The set of unique supertypes of the current class.
+ /// It is used to decide when to add a new element to [allSuperinterfaces].
+ final Set<InterfaceType> allSupertypes = new Set<InterfaceType>();
+
/// The list of all superinterfaces, collected so far.
- final List<InterfaceType> allSuperinterfaces = [];
+ final List<Interface> allSuperinterfaces = [];
_ClassVerifier({
this.typeSystem,
@@ -122,8 +126,7 @@
// Add all superinterfaces of the direct supertype.
if (type.superclass != null) {
- ClassElementImpl.collectAllSupertypes(
- allSuperinterfaces, type.superclass, null);
+ _addSuperinterfaces(type.superclass);
}
// Each mixin in `class C extends S with M0, M1, M2 {}` is equivalent to:
@@ -136,15 +139,14 @@
var mixinNodes = withClause?.mixinTypes;
var mixinTypes = type.mixins;
for (var i = 0; i < mixinTypes.length; i++) {
- _checkDeclaredMembers(mixinNodes[i], mixinTypes[i]);
- ClassElementImpl.collectAllSupertypes(
- allSuperinterfaces, mixinTypes[i], null);
+ var mixinType = mixinTypes[i];
+ _checkDeclaredMembers(mixinNodes[i], mixinType);
+ _addSuperinterfaces(mixinType);
}
// Add all superinterfaces of the direct class interfaces.
for (var interface in type.interfaces) {
- ClassElementImpl.collectAllSupertypes(
- allSuperinterfaces, interface, null);
+ _addSuperinterfaces(interface);
}
// Check the members if the class itself, against all the previously
@@ -163,24 +165,24 @@
}
// Compute the interface of the class.
- var interfaceMembers = inheritance.getInterface(type);
+ var interface = inheritance.getInterface(type);
// Report conflicts between direct superinterfaces of the class.
- for (var conflict in interfaceMembers.conflicts) {
+ for (var conflict in interface.conflicts) {
_reportInconsistentInheritance(classNameNode, conflict);
}
- _checkForMismatchedAccessorTypes(interfaceMembers);
+ _checkForMismatchedAccessorTypes(interface);
if (!classElement.isAbstract) {
List<FunctionType> inheritedAbstract = null;
- for (var name in interfaceMembers.map.keys) {
+ for (var name in interface.map.keys) {
if (!name.isAccessibleFor(libraryUri)) {
continue;
}
- var interfaceType = interfaceMembers.map[name];
+ var interfaceType = interface.map[name];
var concreteType = inheritance.getMember(type, name, concrete: true);
// No concrete implementation of the name.
@@ -226,6 +228,18 @@
}
}
+ void _addSuperinterfaces(InterfaceType startingType) {
+ var supertypes = <InterfaceType>[];
+ ClassElementImpl.collectAllSupertypes(supertypes, startingType, null);
+ for (int i = 0; i < supertypes.length; i++) {
+ var supertype = supertypes[i];
+ if (allSupertypes.add(supertype)) {
+ var interface = inheritance.getInterface(supertype);
+ allSuperinterfaces.add(interface);
+ }
+ }
+ }
+
/// Check that the given [member] is a valid override of the corresponding
/// instance members in each of [allSuperinterfaces]. The [libraryUri] is
/// the URI of the library containing the [member].
@@ -238,8 +252,8 @@
if (member.isStatic) return;
var name = new Name(libraryUri, member.name);
- for (var superType in allSuperinterfaces) {
- var superMemberType = inheritance.getInterface(superType).map[name];
+ for (var superInterface in allSuperinterfaces) {
+ var superMemberType = superInterface.declared[name];
if (superMemberType != null) {
// The case when members have different kinds is reported in verifier.
// TODO(scheglov) Do it here?
@@ -352,7 +366,7 @@
if (getter.element.kind == ElementKind.GETTER) {
// TODO(scheglov) We should separate getters and setters.
var setter = interface.map[new Name(libraryUri, '${name.name}=')];
- if (setter != null) {
+ if (setter != null && setter.parameters.length == 1) {
var getterType = getter.returnType;
var setterType = setter.parameters[0].type;
if (!typeSystem.isAssignableTo(getterType, setterType)) {
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index e816bf5..bb0a129 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -890,6 +890,29 @@
push(ast.nullLiteral(token));
}
+ @override
+ void handleEmptyLiteralSetOrMap(
+ Token leftBrace, Token constKeyword, Token rightBrace) {
+ // TODO(danrubel): From a type resolution standpoint, this could be either
+ // a set literal or a map literal depending upon the context
+ // in which this expression occurs.
+ // For now, generate a map literal.
+ handleLiteralMap(0, leftBrace, constKeyword, rightBrace);
+ }
+
+ void handleLiteralSet(
+ int count, Token leftBracket, Token constKeyword, Token rightBracket) {
+ assert(optional('{', leftBracket));
+ assert(optionalOrNull('const', constKeyword));
+ assert(optional('}', rightBracket));
+ debugEvent("LiteralSet");
+
+ List<Expression> entries = popTypedList(count) ?? <Expression>[];
+ TypeArgumentList typeArguments = pop();
+ push(ast.setLiteral(
+ constKeyword, typeArguments, leftBracket, entries, rightBracket));
+ }
+
void handleLiteralMap(
int count, Token leftBracket, Token constKeyword, Token rightBracket) {
assert(optional('{', leftBracket));
diff --git a/pkg/analyzer/lib/src/fasta/error_converter.dart b/pkg/analyzer/lib/src/fasta/error_converter.dart
index 8464578..b99d26f 100644
--- a/pkg/analyzer/lib/src/fasta/error_converter.dart
+++ b/pkg/analyzer/lib/src/fasta/error_converter.dart
@@ -1,10 +1,12 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import 'package:analyzer/analyzer.dart';
import 'package:analyzer/dart/ast/token.dart' show Token;
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/dart/error/syntactic_errors.dart';
+import 'package:analyzer/src/error/codes.dart';
import 'package:front_end/src/fasta/messages.dart' show Code, Message;
/// An error reporter that knows how to convert a Fasta error into an analyzer
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index b759dd0..53f150f 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -19,6 +19,7 @@
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/inheritance_manager2.dart';
import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/resolver/method_invocation_resolver.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
@@ -82,7 +83,7 @@
* combinators that are not defined in the imported library (which is not an
* error).
*/
-class ElementResolver extends SimpleAstVisitor<Object> {
+class ElementResolver extends SimpleAstVisitor<void> {
/**
* The manager for the inheritance mappings.
*/
@@ -104,28 +105,25 @@
DartType _dynamicType;
/**
- * The type representing the type 'type'.
+ * The type representing the type 'Type'.
*/
InterfaceType _typeType;
- /**
- * The object keeping track of which elements have had their types promoted.
- */
- TypePromotionManager _promoteManager;
-
/// Whether constant evaluation errors should be reported during resolution.
final bool reportConstEvaluationErrors;
+ final MethodInvocationResolver _methodInvocationResolver;
+
/**
* Initialize a newly created visitor to work for the given [_resolver] to
* resolve the nodes in a compilation unit.
*/
ElementResolver(this._resolver, {this.reportConstEvaluationErrors: true})
: _inheritance = _resolver.inheritance,
- _definingLibrary = _resolver.definingLibrary {
+ _definingLibrary = _resolver.definingLibrary,
+ _methodInvocationResolver = new MethodInvocationResolver(_resolver) {
_dynamicType = _resolver.typeProvider.dynamicType;
_typeType = _resolver.typeProvider.typeType;
- _promoteManager = _resolver.promoteManager;
}
/**
@@ -141,7 +139,7 @@
}
@override
- Object visitAssignmentExpression(AssignmentExpression node) {
+ void visitAssignmentExpression(AssignmentExpression node) {
Token operator = node.operator;
TokenType operatorType = operator.type;
Expression leftHandSide = node.leftHandSide;
@@ -154,7 +152,7 @@
staticType.isVoid) {
_recordUndefinedToken(
null, StaticWarningCode.USE_OF_VOID_RESULT, operator, []);
- return null;
+ return;
}
if (operatorType != TokenType.AMPERSAND_AMPERSAND_EQ &&
@@ -176,40 +174,35 @@
}
}
}
- return null;
}
@override
- Object visitBinaryExpression(BinaryExpression node) {
+ void visitBinaryExpression(BinaryExpression node) {
Token operator = node.operator;
if (operator.isUserDefinableOperator) {
_resolveBinaryExpression(node, operator.lexeme);
} else if (operator.type == TokenType.BANG_EQ) {
_resolveBinaryExpression(node, TokenType.EQ_EQ.lexeme);
}
- return null;
}
@override
- Object visitBreakStatement(BreakStatement node) {
+ void visitBreakStatement(BreakStatement node) {
node.target = _lookupBreakOrContinueTarget(node, node.label, false);
- return null;
}
@override
- Object visitClassDeclaration(ClassDeclaration node) {
+ void visitClassDeclaration(ClassDeclaration node) {
resolveMetadata(node);
- return null;
}
@override
- Object visitClassTypeAlias(ClassTypeAlias node) {
+ void visitClassTypeAlias(ClassTypeAlias node) {
resolveMetadata(node);
- return null;
}
@override
- Object visitCommentReference(CommentReference node) {
+ void visitCommentReference(CommentReference node) {
Identifier identifier = node.identifier;
if (identifier is SimpleIdentifier) {
Element element = _resolveSimpleIdentifier(identifier);
@@ -249,7 +242,7 @@
// TODO(brianwilkerson) Report this error?
element = _resolver.nameScope.lookup(identifier, _definingLibrary);
name.staticElement = element;
- return null;
+ return;
}
LibraryElement library = element.library;
if (library == null) {
@@ -293,11 +286,10 @@
}
}
}
- return null;
}
@override
- Object visitConstructorDeclaration(ConstructorDeclaration node) {
+ void visitConstructorDeclaration(ConstructorDeclaration node) {
super.visitConstructorDeclaration(node);
ConstructorElement element = node.declaredElement;
if (element is ConstructorElementImpl) {
@@ -317,20 +309,18 @@
}
resolveMetadata(node);
}
- return null;
}
@override
- Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
+ void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
SimpleIdentifier fieldName = node.fieldName;
ClassElement enclosingClass = _resolver.enclosingClass;
FieldElement fieldElement = enclosingClass.getField(fieldName.name);
fieldName.staticElement = fieldElement;
- return null;
}
@override
- Object visitConstructorName(ConstructorName node) {
+ void visitConstructorName(ConstructorName node) {
DartType type = node.type.type;
if (type != null && type.isDynamic) {
// Nothing to do.
@@ -358,29 +348,25 @@
// // This is part of a redirecting factory constructor; not sure which error code to use
// }
}
- return null;
}
@override
- Object visitContinueStatement(ContinueStatement node) {
+ void visitContinueStatement(ContinueStatement node) {
node.target = _lookupBreakOrContinueTarget(node, node.label, true);
- return null;
}
@override
- Object visitDeclaredIdentifier(DeclaredIdentifier node) {
+ void visitDeclaredIdentifier(DeclaredIdentifier node) {
resolveMetadata(node);
- return null;
}
@override
- Object visitEnumDeclaration(EnumDeclaration node) {
+ void visitEnumDeclaration(EnumDeclaration node) {
resolveMetadata(node);
- return null;
}
@override
- Object visitExportDirective(ExportDirective node) {
+ void visitExportDirective(ExportDirective node) {
ExportElement exportElement = node.element;
if (exportElement != null) {
// The element is null when the URI is invalid
@@ -389,23 +375,21 @@
_resolveCombinators(exportElement.exportedLibrary, node.combinators);
resolveMetadata(node);
}
- return null;
}
@override
- Object visitFieldFormalParameter(FieldFormalParameter node) {
+ void visitFieldFormalParameter(FieldFormalParameter node) {
_resolveMetadataForParameter(node);
- return super.visitFieldFormalParameter(node);
+ super.visitFieldFormalParameter(node);
}
@override
- Object visitFunctionDeclaration(FunctionDeclaration node) {
+ void visitFunctionDeclaration(FunctionDeclaration node) {
resolveMetadata(node);
- return null;
}
@override
- Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+ void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
Expression function = node.function;
DartType staticInvokeType = _instantiateGenericMethod(
function.staticType, node.typeArguments, node);
@@ -417,23 +401,20 @@
if (parameters != null) {
node.argumentList.correspondingStaticParameters = parameters;
}
- return null;
}
@override
- Object visitFunctionTypeAlias(FunctionTypeAlias node) {
+ void visitFunctionTypeAlias(FunctionTypeAlias node) {
resolveMetadata(node);
- return null;
}
@override
- Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+ void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
_resolveMetadataForParameter(node);
- return null;
}
@override
- Object visitImportDirective(ImportDirective node) {
+ void visitImportDirective(ImportDirective node) {
SimpleIdentifier prefixNode = node.prefix;
if (prefixNode != null) {
String prefixName = prefixNode.name;
@@ -456,11 +437,10 @@
}
resolveMetadata(node);
}
- return null;
}
@override
- Object visitIndexExpression(IndexExpression node) {
+ void visitIndexExpression(IndexExpression node) {
Expression target = node.realTarget;
DartType staticType = _getStaticType(target);
String getterMethodName = TokenType.INDEX.lexeme;
@@ -475,7 +455,7 @@
node.staticElement = setterStaticMethod;
// generate undefined method warning
_checkForUndefinedIndexOperator(
- node, target, getterMethodName, setterStaticMethod, staticType);
+ node, target, setterMethodName, setterStaticMethod, staticType);
// lookup getter method
MethodElement getterStaticMethod =
_lookUpMethod(target, staticType, getterMethodName);
@@ -505,11 +485,10 @@
_checkForUndefinedIndexOperator(
node, target, setterMethodName, staticMethod, staticType);
}
- return null;
}
@override
- Object visitInstanceCreationExpression(InstanceCreationExpression node) {
+ void visitInstanceCreationExpression(InstanceCreationExpression node) {
ConstructorElement invokedConstructor = node.constructorName.staticElement;
node.staticElement = invokedConstructor;
ArgumentList argumentList = node.argumentList;
@@ -520,246 +499,35 @@
if (parameters != null) {
argumentList.correspondingStaticParameters = parameters;
}
- return null;
}
@override
- Object visitLibraryDirective(LibraryDirective node) {
+ void visitLibraryDirective(LibraryDirective node) {
resolveMetadata(node);
- return null;
}
@override
- Object visitMethodDeclaration(MethodDeclaration node) {
+ void visitMethodDeclaration(MethodDeclaration node) {
resolveMetadata(node);
- return null;
}
@override
- Object visitMethodInvocation(MethodInvocation node) {
- SimpleIdentifier methodName = node.methodName;
- //
- // Synthetic identifiers have been already reported during parsing.
- //
- if (methodName.isSynthetic) {
- return null;
- }
- //
- // We have a method invocation of one of two forms: 'e.m(a1, ..., an)' or
- // 'm(a1, ..., an)'. The first step is to figure out which executable is
- // being invoked, using both the static and the propagated type information.
- //
- Expression target = node.realTarget;
- if (target is SuperExpression && !_isSuperInValidContext(target)) {
- return null;
- }
- Element staticElement;
- if (target == null) {
- staticElement = _resolveInvokedElement(methodName);
- } else if (methodName.name == FunctionElement.LOAD_LIBRARY_NAME &&
- _isDeferredPrefix(target)) {
- if (node.operator.type == TokenType.QUESTION_PERIOD) {
- _resolver.errorReporter.reportErrorForNode(
- CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
- target,
- [(target as SimpleIdentifier).name]);
- }
- LibraryElement importedLibrary = _getImportedLibrary(target);
- FunctionElement loadLibraryFunction =
- importedLibrary?.loadLibraryFunction;
- methodName.staticElement = loadLibraryFunction;
- node.staticInvokeType = loadLibraryFunction?.type;
- return null;
- } else {
- //
- // If this method invocation is of the form 'C.m' where 'C' is a class,
- // then we don't call resolveInvokedElement(...) which walks up the class
- // hierarchy, instead we just look for the member in the type only. This
- // does not apply to conditional method invocation (i.e. 'C?.m(...)').
- //
- bool isConditional = node.operator.type == TokenType.QUESTION_PERIOD;
- ClassElement typeReference = getTypeReference(target);
-
- if (typeReference != null) {
- if (node.isCascaded) {
- typeReference = _typeType.element;
- }
- staticElement = _resolveElement(typeReference, methodName);
- } else {
- DartType staticType = _getStaticTypeOrFunctionType(target);
-
- if (staticType is FunctionType &&
- methodName.name == FunctionElement.CALL_METHOD_NAME) {
- if (target is SimpleIdentifier) {
- methodName.staticElement = target.staticElement;
- }
- methodName.staticType = target.staticType;
- node.staticType = staticType;
- node.staticInvokeType = staticType;
- node.argumentList.correspondingStaticParameters =
- _computeCorrespondingParameters(node.argumentList, staticType);
- return null;
- }
-
- if (target is SuperExpression) {
- if (staticType is InterfaceTypeImpl) {
- staticElement = staticType.lookUpInheritedMember(
- methodName.name, _definingLibrary,
- concrete: true, forSuperInvocation: true);
- // We were not able to find the concrete dispatch target.
- // But we would like to give the user at least some resolution.
- // So, we retry without the "concrete" requirement.
- if (staticElement == null) {
- staticElement = staticType.lookUpInheritedMember(
- methodName.name, _definingLibrary,
- concrete: false);
- if (staticElement != null) {
- _resolver.errorReporter.reportErrorForNode(
- CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE,
- methodName,
- [staticElement.kind.displayName, methodName.name]);
- }
- }
- }
- } else {
- staticElement = _resolveInvokedElementWithTarget(
- target, staticType, methodName, isConditional);
- }
- }
- }
-
- staticElement = _convertSetterToGetter(staticElement);
-
- //
- // Given the elements, determine the type of the function we are invoking
- //
- DartType staticType = _getInvokeType(staticElement);
- methodName.staticType = staticType;
-
- //
- // Instantiate generic function or method if needed.
- //
- DartType staticInvokeType = _instantiateGenericMethod(
- staticType, node.typeArguments, node.methodName);
-
- //
- // Record the results.
- //
- methodName.staticElement = staticElement;
- node.staticInvokeType = staticInvokeType;
- ArgumentList argumentList = node.argumentList;
- if (staticInvokeType != null) {
- List<ParameterElement> parameters =
- _computeCorrespondingParameters(argumentList, staticInvokeType);
- argumentList.correspondingStaticParameters = parameters;
- }
- //
- // Then check for error conditions.
- //
- ErrorCode errorCode = _checkForInvocationError(
- target, true, staticElement, staticType, methodName.name);
- if (errorCode != null &&
- target is SimpleIdentifier &&
- target.staticElement is PrefixElement) {
- Identifier functionName =
- new PrefixedIdentifierImpl.temp(target, methodName);
- if (_resolver.nameScope.shouldIgnoreUndefined(functionName)) {
- return null;
- }
- }
- if (errorCode == null) {
- return null;
- }
-
- if (identical(
- errorCode, StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION) ||
- identical(errorCode,
- CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT) ||
- identical(errorCode, StaticTypeWarningCode.UNDEFINED_FUNCTION)) {
- if (!_resolver.nameScope.shouldIgnoreUndefined(methodName)) {
- _resolver.errorReporter
- .reportErrorForNode(errorCode, methodName, [methodName.name]);
- }
- } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) {
- String targetTypeName;
- if (target == null) {
- ClassElement enclosingClass = _resolver.enclosingClass;
- targetTypeName = enclosingClass.displayName;
- ErrorCode proxyErrorCode = StaticTypeWarningCode.UNDEFINED_METHOD;
- _recordUndefinedNode(_resolver.enclosingClass, proxyErrorCode,
- methodName, [methodName.name, targetTypeName]);
- } else {
- // ignore Function "call"
- // (if we are about to create a hint using type propagation,
- // then we can use type propagation here as well)
- DartType targetType = null;
- targetType = _getStaticType(target);
- if (targetType != null &&
- targetType.isDartCoreFunction &&
- methodName.name == FunctionElement.CALL_METHOD_NAME) {
- return null;
- }
- if (!node.isCascaded) {
- ClassElement typeReference = getTypeReference(target);
- if (typeReference != null) {
- ConstructorElement constructor =
- typeReference.getNamedConstructor(methodName.name);
- if (constructor != null) {
- _recordUndefinedNode(
- typeReference,
- StaticTypeWarningCode.UNDEFINED_METHOD_WITH_CONSTRUCTOR,
- methodName,
- [methodName.name, typeReference.name]);
- return null;
- }
- }
- }
-
- targetTypeName = targetType?.displayName;
- ErrorCode proxyErrorCode = StaticTypeWarningCode.UNDEFINED_METHOD;
-
- _recordUndefinedNode(targetType.element, proxyErrorCode, methodName,
- [methodName.name, targetTypeName]);
- }
- } else if (identical(
- errorCode, StaticTypeWarningCode.UNDEFINED_SUPER_METHOD)) {
- // Generate the type name.
- // The error code will never be generated via type propagation
- DartType getSuperType(DartType type) {
- if (type is InterfaceType) {
- InterfaceType superclass = type.superclass;
- if (superclass != null) return superclass;
- }
- return type;
- }
-
- DartType targetType = getSuperType(_getStaticType(target));
- String targetTypeName = targetType?.name;
- _resolver.errorReporter.reportErrorForNode(
- StaticTypeWarningCode.UNDEFINED_SUPER_METHOD,
- methodName,
- [methodName.name, targetTypeName]);
- } else if (identical(errorCode, StaticWarningCode.USE_OF_VOID_RESULT)) {
- _resolver.errorReporter.reportErrorForNode(
- StaticWarningCode.USE_OF_VOID_RESULT, target ?? methodName, []);
- }
- return null;
+ void visitMethodInvocation(MethodInvocation node) {
+ _methodInvocationResolver.resolve(node);
}
@override
- Object visitMixinDeclaration(MixinDeclaration node) {
+ void visitMixinDeclaration(MixinDeclaration node) {
resolveMetadata(node);
- return null;
}
@override
- Object visitPartDirective(PartDirective node) {
+ void visitPartDirective(PartDirective node) {
resolveMetadata(node);
- return null;
}
@override
- Object visitPostfixExpression(PostfixExpression node) {
+ void visitPostfixExpression(PostfixExpression node) {
Expression operand = node.operand;
String methodName = _getPostfixOperator(node);
DartType staticType = _getStaticType(operand);
@@ -780,11 +548,10 @@
[methodName, staticType.displayName]);
}
}
- return null;
}
@override
- Object visitPrefixedIdentifier(PrefixedIdentifier node) {
+ void visitPrefixedIdentifier(PrefixedIdentifier node) {
SimpleIdentifier prefix = node.prefix;
SimpleIdentifier identifier = node.identifier;
//
@@ -794,7 +561,7 @@
_isDeferredPrefix(prefix)) {
LibraryElement importedLibrary = _getImportedLibrary(prefix);
identifier.staticElement = importedLibrary?.loadLibraryFunction;
- return null;
+ return;
}
//
// Check to see whether the prefix is really a prefix.
@@ -810,7 +577,7 @@
element = _resolver.nameScope.lookup(setterName, _definingLibrary);
}
if (element == null && _resolver.nameScope.shouldIgnoreUndefined(node)) {
- return null;
+ return;
}
if (element == null) {
if (identifier.inSetterContext()) {
@@ -818,7 +585,7 @@
StaticTypeWarningCode.UNDEFINED_SETTER,
identifier,
[identifier.name, prefixElement.name]);
- return null;
+ return;
}
AstNode parent = node.parent;
if (parent is Annotation) {
@@ -832,7 +599,7 @@
identifier,
[identifier.name, prefixElement.name]);
}
- return null;
+ return;
}
Element accessor = element;
if (accessor is PropertyAccessorElement && identifier.inSetterContext()) {
@@ -852,7 +619,7 @@
if (parent is Annotation) {
_resolveAnnotationElement(parent);
}
- return null;
+ return;
}
// May be annotation, resolve invocation of "const" constructor.
AstNode parent = node.parent;
@@ -864,11 +631,10 @@
// identifier and this is really equivalent to a property access node.
//
_resolvePropertyAccess(prefix, identifier, false);
- return null;
}
@override
- Object visitPrefixExpression(PrefixExpression node) {
+ void visitPrefixExpression(PrefixExpression node) {
Token operator = node.operator;
TokenType operatorType = operator.type;
if (operatorType.isUserDefinableOperator ||
@@ -896,27 +662,25 @@
}
}
}
- return null;
}
@override
- Object visitPropertyAccess(PropertyAccess node) {
+ void visitPropertyAccess(PropertyAccess node) {
Expression target = node.realTarget;
if (target is SuperExpression && !_isSuperInValidContext(target)) {
- return null;
+ return;
}
SimpleIdentifier propertyName = node.propertyName;
_resolvePropertyAccess(target, propertyName, node.isCascaded);
- return null;
}
@override
- Object visitRedirectingConstructorInvocation(
+ void visitRedirectingConstructorInvocation(
RedirectingConstructorInvocation node) {
ClassElement enclosingClass = _resolver.enclosingClass;
if (enclosingClass == null) {
// TODO(brianwilkerson) Report this error.
- return null;
+ return;
}
SimpleIdentifier name = node.constructorName;
ConstructorElement element;
@@ -928,7 +692,7 @@
if (element == null) {
// TODO(brianwilkerson) Report this error and decide what element to
// associate with the node.
- return null;
+ return;
}
if (name != null) {
name.staticElement = element;
@@ -940,41 +704,39 @@
if (parameters != null) {
argumentList.correspondingStaticParameters = parameters;
}
- return null;
}
@override
- Object visitSimpleFormalParameter(SimpleFormalParameter node) {
+ void visitSimpleFormalParameter(SimpleFormalParameter node) {
_resolveMetadataForParameter(node);
- return null;
}
@override
- Object visitSimpleIdentifier(SimpleIdentifier node) {
+ void visitSimpleIdentifier(SimpleIdentifier node) {
//
// Synthetic identifiers have been already reported during parsing.
//
if (node.isSynthetic) {
- return null;
+ return;
}
//
// Ignore nodes that should have been resolved before getting here.
//
if (node.inDeclarationContext()) {
- return null;
+ return;
}
if (node.staticElement is LocalVariableElement ||
node.staticElement is ParameterElement) {
- return null;
+ return;
}
AstNode parent = node.parent;
if (parent is FieldFormalParameter) {
- return null;
+ return;
} else if (parent is ConstructorFieldInitializer &&
parent.fieldName == node) {
- return null;
+ return;
} else if (parent is Annotation && parent.constructorName == node) {
- return null;
+ return;
}
//
// The name dynamic denotes a Type object even though dynamic is not a
@@ -983,7 +745,7 @@
if (node.name == _dynamicType.name) {
node.staticElement = _dynamicType.element;
node.staticType = _typeType;
- return null;
+ return;
}
//
// Otherwise, the node should be resolved.
@@ -1039,21 +801,20 @@
if (parent is Annotation) {
_resolveAnnotationElement(parent);
}
- return null;
}
@override
- Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+ void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
ClassElementImpl enclosingClass =
AbstractClassElementImpl.getImpl(_resolver.enclosingClass);
if (enclosingClass == null) {
// TODO(brianwilkerson) Report this error.
- return null;
+ return;
}
InterfaceType superType = enclosingClass.supertype;
if (superType == null) {
// TODO(brianwilkerson) Report this error.
- return null;
+ return;
}
SimpleIdentifier name = node.constructorName;
String superName = name?.name;
@@ -1071,7 +832,7 @@
node,
[superType.displayName]);
}
- return null;
+ return;
} else {
if (element.isFactory) {
_resolver.errorReporter.reportErrorForNode(
@@ -1085,11 +846,11 @@
// TODO(brianwilkerson) Defer this check until we know there's an error (by
// in-lining _resolveArgumentsToFunction below).
ClassDeclaration declaration =
- node.getAncestor((AstNode node) => node is ClassDeclaration);
+ node.thisOrAncestorOfType<ClassDeclaration>();
Identifier superclassName = declaration.extendsClause?.superclass?.name;
if (superclassName != null &&
_resolver.nameScope.shouldIgnoreUndefined(superclassName)) {
- return null;
+ return;
}
ArgumentList argumentList = node.argumentList;
List<ParameterElement> parameters = _resolveArgumentsToFunction(
@@ -1097,121 +858,25 @@
if (parameters != null) {
argumentList.correspondingStaticParameters = parameters;
}
- return null;
}
@override
- Object visitSuperExpression(SuperExpression node) {
+ void visitSuperExpression(SuperExpression node) {
if (!_isSuperInValidContext(node)) {
_resolver.errorReporter.reportErrorForNode(
CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT, node);
}
- return super.visitSuperExpression(node);
+ super.visitSuperExpression(node);
}
@override
- Object visitTypeParameter(TypeParameter node) {
+ void visitTypeParameter(TypeParameter node) {
resolveMetadata(node);
- return null;
}
@override
- Object visitVariableDeclaration(VariableDeclaration node) {
+ void visitVariableDeclaration(VariableDeclaration node) {
resolveMetadata(node);
- return null;
- }
-
- /**
- * Given that we have found code to invoke the given [element], return the
- * error code that should be reported, or `null` if no error should be
- * reported. The [target] is the target of the invocation, or `null` if there
- * was no target. The flag [useStaticContext] should be `true` if the
- * invocation is in a static constant (does not have access to instance state).
- */
- ErrorCode _checkForInvocationError(Expression target, bool useStaticContext,
- Element element, DartType type, String name) {
- // Prefix is not declared, instead "prefix.id" are declared.
- if (element is PrefixElement) {
- return CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT;
- } else if (element is PropertyAccessorElement) {
- //
- // This is really a function expression invocation.
- //
- // TODO(brianwilkerson) Consider the possibility of re-writing the AST.
- FunctionType getterType = element.type;
- if (getterType != null) {
- DartType returnType = getterType.returnType;
- return _getErrorCodeForExecuting(returnType);
- }
- } else if (element is ExecutableElement) {
- return null;
- } else if (element is MultiplyDefinedElement) {
- // The error has already been reported
- return null;
- } else if (element == null && target is SuperExpression) {
- // TODO(jwren) We should split the UNDEFINED_METHOD into two error codes,
- // this one, and a code that describes the situation where the method was
- // found, but it was not accessible from the current library.
- return StaticTypeWarningCode.UNDEFINED_SUPER_METHOD;
- } else {
- //
- // This is really a function expression invocation.
- //
- // TODO(brianwilkerson) Consider the possibility of re-writing the AST.
- if (element is PropertyInducingElement) {
- PropertyAccessorElement getter = element.getter;
- FunctionType getterType = getter.type;
- if (getterType != null) {
- DartType returnType = getterType.returnType;
- return _getErrorCodeForExecuting(returnType);
- }
- } else if (element is VariableElement) {
- return _getErrorCodeForExecuting(type);
- } else {
- if (target == null) {
- ClassElement enclosingClass = _resolver.enclosingClass;
- if (enclosingClass == null) {
- return StaticTypeWarningCode.UNDEFINED_FUNCTION;
- } else if (element == null) {
- // Proxy-conditional warning, based on state of
- // resolver.getEnclosingClass()
- return StaticTypeWarningCode.UNDEFINED_METHOD;
- } else {
- return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION;
- }
- } else {
- DartType targetType;
- if (useStaticContext) {
- targetType = _getStaticType(target);
- } else {
- // Compute and use the propagated type, if it is null, then it may
- // be the case that static type is some type, in which the static
- // type should be used.
- targetType = _getBestType(target);
- }
- if (targetType == null) {
- if (target is Identifier &&
- _resolver.nameScope.shouldIgnoreUndefined(target)) {
- return null;
- }
- return StaticTypeWarningCode.UNDEFINED_FUNCTION;
- } else if (targetType.isVoid) {
- return StaticWarningCode.USE_OF_VOID_RESULT;
- } else if (!targetType.isDynamic && target is! NullLiteral) {
- // Proxy-conditional warning, based on state of
- // targetType.getElement()
- return StaticTypeWarningCode.UNDEFINED_METHOD;
- } else if (targetType.isDynamic) {
- PropertyAccessorElement getter =
- _resolver.typeProvider.objectType.getGetter(name);
- if (getter != null && getter.returnType is! FunctionType) {
- return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION;
- }
- }
- }
- }
- }
- return null;
}
/**
@@ -1275,50 +940,6 @@
}
/**
- * If the given [element] is a setter, return the getter associated with it.
- * Otherwise, return the element unchanged.
- */
- Element _convertSetterToGetter(Element element) {
- // TODO(brianwilkerson) Determine whether and why the element could ever be
- // a setter.
- if (element is PropertyAccessorElement) {
- return element.variable.getter;
- }
- return element;
- }
-
- /**
- * Return the best type of the given [expression] that is to be used for
- * type analysis.
- */
- DartType _getBestType(Expression expression) {
- DartType bestType = _resolveTypeParameter(expression.staticType);
- if (bestType is FunctionType) {
- //
- // All function types are subtypes of 'Function', which is itself a
- // subclass of 'Object'.
- //
- bestType = _resolver.typeProvider.functionType;
- }
- return bestType;
- }
-
- /**
- * Return an error if the [type], which is presumably being invoked, is not a
- * function. The errors for non functions may be broken up by type; currently,
- * it returns a special value for when the type is `void`.
- */
- ErrorCode _getErrorCodeForExecuting(DartType type) {
- if (_isExecutableType(type)) {
- return null;
- }
-
- return type.isVoid
- ? StaticWarningCode.USE_OF_VOID_RESULT
- : StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION;
- }
-
- /**
* Assuming that the given [identifier] is a prefix for a deferred import,
* return the library that is being imported.
*/
@@ -1330,28 +951,6 @@
}
/**
- * Given an element, computes the type of the invocation.
- *
- * For executable elements (like methods, functions) this is just their type.
- *
- * For variables it is their type taking into account any type promotion.
- *
- * For calls to getters in Dart, we invoke the function that is returned by
- * the getter, so the invoke type is the getter's returnType.
- */
- DartType _getInvokeType(Element element) {
- DartType invokeType;
- if (element is PropertyAccessorElement) {
- invokeType = element.returnType;
- } else if (element is ExecutableElement) {
- invokeType = element.type;
- } else if (element is VariableElement) {
- invokeType = _promoteManager.getStaticType(element);
- }
- return invokeType ?? DynamicTypeImpl.instance;
- }
-
- /**
* Return the name of the method invoked by the given postfix [expression].
*/
String _getPostfixOperator(PostfixExpression expression) =>
@@ -1461,25 +1060,6 @@
}
/**
- * Return `true` if the given [type] represents an object that could be
- * invoked using the call operator '()'.
- */
- bool _isExecutableType(DartType type) {
- type = type?.resolveToBound(_resolver.typeProvider.objectType);
- if (type.isDynamic || type is FunctionType) {
- return true;
- } else if (type.isDartCoreFunction) {
- return true;
- } else if (type is InterfaceType) {
- ClassElement classElement = type.element;
- MethodElement methodElement = classElement.lookUpMethod(
- FunctionElement.CALL_METHOD_NAME, _definingLibrary);
- return methodElement != null;
- }
- return false;
- }
-
- /**
* Return `true` if the given [element] is a static element.
*/
bool _isStatic(Element element) {
@@ -1582,18 +1162,18 @@
/**
* Look up the [FunctionType] of a getter or a method with the given [name]
- * in the given [targetType]. The [target] is the target of the invocation,
- * or `null` if there is no target.
+ * in the given [targetType].
*/
- FunctionType _lookUpGetterType(
- Expression target, DartType targetType, String name) {
+ FunctionType _lookUpGetterType(DartType targetType, String name,
+ {bool concrete: false, bool forSuper: false}) {
targetType = _resolveTypeParameter(targetType);
if (targetType is InterfaceType) {
var nameObject = new Name(_definingLibrary.source.uri, name);
return _inheritance.getMember(
targetType,
nameObject,
- forSuper: target is SuperExpression,
+ concrete: concrete,
+ forSuper: forSuper,
);
}
return null;
@@ -1752,8 +1332,7 @@
}
// Class(args)
if (element1 is ClassElement) {
- constructor = new InterfaceTypeImpl(element1)
- .lookUpConstructor(null, _definingLibrary);
+ constructor = element1.type.lookUpConstructor(null, _definingLibrary);
} else if (element1 == null) {
undefined = true;
}
@@ -1781,8 +1360,8 @@
}
// Class.constructor(args)
if (element1 is ClassElement) {
- constructor = new InterfaceTypeImpl(element1)
- .lookUpConstructor(nameNode2.name, _definingLibrary);
+ constructor =
+ element1.type.lookUpConstructor(nameNode2.name, _definingLibrary);
nameNode2.staticElement = constructor;
}
if (element1 == null && element2 == null) {
@@ -1807,8 +1386,7 @@
return;
}
// prefix.Class.constructor(args)
- constructor = new InterfaceTypeImpl(element2)
- .lookUpConstructor(name3, _definingLibrary);
+ constructor = element2.type.lookUpConstructor(name3, _definingLibrary);
nameNode3.staticElement = constructor;
} else if (element2 == null) {
undefined = true;
@@ -1894,12 +1472,14 @@
Expression leftOperand = node.leftOperand;
if (leftOperand != null) {
DartType leftType = _getStaticType(leftOperand);
- var invokeType = _lookUpGetterType(leftOperand, leftType, methodName);
+ var isSuper = leftOperand is SuperExpression;
+ var invokeType = _lookUpGetterType(leftType, methodName,
+ concrete: isSuper, forSuper: isSuper);
var invokeElement = invokeType?.element;
node.staticElement = invokeElement;
node.staticInvokeType = invokeType;
if (_shouldReportMissingMember(leftType, invokeElement)) {
- if (leftOperand is SuperExpression) {
+ if (isSuper) {
_recordUndefinedToken(
leftType.element,
StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR,
@@ -1978,103 +1558,6 @@
}
/**
- * Given an invocation of the form 'm(a1, ..., an)', resolve 'm' to the
- * element being invoked. If the returned element is a method, then the method
- * will be invoked. If the returned element is a getter, the getter will be
- * invoked without arguments and the result of that invocation will then be
- * invoked with the arguments. The [methodName] is the name of the method
- * being invoked ('m').
- */
- Element _resolveInvokedElement(SimpleIdentifier methodName) {
- //
- // Look first in the lexical scope.
- //
- Element element = _resolver.nameScope.lookup(methodName, _definingLibrary);
- if (element == null) {
- //
- // If it isn't defined in the lexical scope, and the invocation is within
- // a class, then look in the inheritance scope.
- //
- ClassElement enclosingClass = _resolver.enclosingClass;
- if (enclosingClass != null) {
- InterfaceType enclosingType = enclosingClass.type;
- element = _lookUpMethod(null, enclosingType, methodName.name);
- if (element == null) {
- //
- // If there's no method, then it's possible that 'm' is a getter that
- // returns a function.
- //
- element = _lookUpGetter(null, enclosingType, methodName.name);
- }
- }
- }
- // TODO(brianwilkerson) Report this error.
- return element;
- }
-
- /**
- * Given an invocation of the form 'e.m(a1, ..., an)', resolve 'e.m' to the
- * element being invoked. If the returned element is a method, then the method
- * will be invoked. If the returned element is a getter, the getter will be
- * invoked without arguments and the result of that invocation will then be
- * invoked with the arguments. The [target] is the target of the invocation
- * ('e'). The [targetType] is the type of the target. The [methodName] is th
- * name of the method being invoked ('m'). [isConditional] indicates
- * whether the invocation uses a '?.' operator.
- */
- Element _resolveInvokedElementWithTarget(Expression target,
- DartType targetType, SimpleIdentifier methodName, bool isConditional) {
- String name = methodName.name;
- if (targetType is InterfaceType) {
- Element element = _lookUpMethod(target, targetType, name);
- if (element == null) {
- //
- // If there's no method, then it's possible that 'm' is a getter that
- // returns a function.
- //
- // TODO (collinsn): need to add union type support here too, in the
- // style of [lookUpMethod].
- element = _lookUpGetter(target, targetType, name);
- }
- return element;
- } else if (targetType is FunctionType &&
- _resolver.typeProvider.isObjectMethod(name)) {
- return _resolver.typeProvider.objectType.element.getMethod(name);
- } else if (target is SimpleIdentifier) {
- Element targetElement = target.staticElement;
- if (targetType is FunctionType &&
- name == FunctionElement.CALL_METHOD_NAME) {
- return targetElement;
- }
- if (targetElement is PrefixElement) {
- if (isConditional) {
- _resolver.errorReporter.reportErrorForNode(
- CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
- target,
- [target.name]);
- }
- //
- // Look to see whether the name of the method is really part of a
- // prefixed identifier for an imported top-level function or top-level
- // getter that returns a function.
- //
- Identifier functionName =
- new PrefixedIdentifierImpl.temp(target, methodName);
- Element element =
- _resolver.nameScope.lookup(functionName, _definingLibrary);
- if (element != null) {
- // TODO(brianwilkerson) This isn't a method invocation, it's a
- // function invocation where the function name is a prefixed
- // identifier. Consider re-writing the AST.
- return element;
- }
- }
- }
- // TODO(brianwilkerson) Report this error.
- return null;
- }
-
- /**
* Given a [node] that can have annotations associated with it, resolve the
* annotations in the element model representing annotations to the node.
*/
@@ -2134,10 +1617,16 @@
propertyName.name, _definingLibrary,
setter: propertyName.inSetterContext(), concrete: false);
if (staticElement != null) {
- _resolver.errorReporter.reportErrorForNode(
- CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE,
- propertyName,
- [staticElement.kind.displayName, propertyName.name]);
+ ClassElementImpl receiverSuperClass =
+ AbstractClassElementImpl.getImpl(
+ staticType.element.supertype.element,
+ );
+ if (!receiverSuperClass.hasNoSuchMethod) {
+ _resolver.errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE,
+ propertyName,
+ [staticElement.kind.displayName, propertyName.name]);
+ }
}
}
}
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 91e3739..f4d63dc 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -40,6 +40,7 @@
import 'package:path/path.dart' as pathos;
import 'package:plugin/manager.dart';
import 'package:plugin/plugin.dart';
+import 'package:pub_semver/pub_semver.dart';
export 'package:analyzer/error/listener.dart' show RecordingErrorListener;
export 'package:analyzer/src/generated/timestamped_data.dart'
@@ -1147,10 +1148,10 @@
AnalyzeFunctionBodiesPredicate get analyzeFunctionBodiesPredicate;
/**
- * DEPRECATED: Return the maximum number of sources for which AST structures should be
+ * Return the maximum number of sources for which AST structures should be
* kept in the cache.
*
- * This setting no longer has any effect.
+ * DEPRECATED: This setting no longer has any effect.
*/
@deprecated
int get cacheSize;
@@ -1197,6 +1198,15 @@
bool get enableConditionalDirectives;
/**
+ * Return a list containing the names of the experiments that are enabled in
+ * the context associated with these options.
+ *
+ * The process around these experiments is described in this
+ * [doc](https://github.com/dart-lang/sdk/blob/master/docs/process/experimental-flags.md).
+ */
+ List<String> get enabledExperiments;
+
+ /**
* Return a list of the names of the packages for which, if they define a
* plugin, the plugin should be enabled.
*/
@@ -1301,6 +1311,12 @@
bool get previewDart2;
/**
+ * The version range for the SDK specified in `pubspec.yaml`, or `null` if
+ * there is no `pubspec.yaml` or if it does not contain an SDK range.
+ */
+ VersionConstraint get sdkVersionConstraint;
+
+ /**
* Return the opaque signature of the options.
*
* The length of the list is guaranteed to equal [signatureLength].
@@ -1338,6 +1354,7 @@
* Set the values of the cross-context options to match those in the given set
* of [options].
*/
+ @deprecated
void setCrossContextOptionsFrom(AnalysisOptions options);
/**
@@ -1394,13 +1411,8 @@
*/
Uint32List _signature;
- /**
- * A flag indicating whether declaration casts are allowed in [strongMode]
- * (they are always allowed in Dart 1.0 mode).
- *
- * This option is deprecated and will be removed in a future release.
- */
- bool declarationCasts = true;
+ @override
+ VersionConstraint sdkVersionConstraint;
@override
@deprecated
@@ -1410,6 +1422,9 @@
bool dart2jsHint = false;
@override
+ List<String> enabledExperiments = const <String>[];
+
+ @override
List<String> enabledPluginNames = const <String>[];
@override
@@ -1489,13 +1504,6 @@
*/
bool implicitDynamic = true;
- // A no-op setter.
- /**
- * Return `true` to enable mixin declarations.
- * https://github.com/dart-lang/language/issues/12
- */
- bool isMixinSupportEnabled = false;
-
/**
* Initialize a newly created set of analysis options to have their default
* values.
@@ -1509,6 +1517,7 @@
AnalysisOptionsImpl.from(AnalysisOptions options) {
analyzeFunctionBodiesPredicate = options.analyzeFunctionBodiesPredicate;
dart2jsHint = options.dart2jsHint;
+ enabledExperiments = options.enabledExperiments;
enabledPluginNames = options.enabledPluginNames;
enableLazyAssignmentOperators = options.enableLazyAssignmentOperators;
enableTiming = options.enableTiming;
@@ -1522,15 +1531,14 @@
preserveComments = options.preserveComments;
useFastaParser = options.useFastaParser;
if (options is AnalysisOptionsImpl) {
- declarationCasts = options.declarationCasts;
strongModeHints = options.strongModeHints;
implicitCasts = options.implicitCasts;
implicitDynamic = options.implicitDynamic;
- isMixinSupportEnabled = options.isMixinSupportEnabled;
}
trackCacheDependencies = options.trackCacheDependencies;
disableCacheFlushing = options.disableCacheFlushing;
patchPaths = options.patchPaths;
+ sdkVersionConstraint = options.sdkVersionConstraint;
}
bool get analyzeFunctionBodies {
@@ -1645,6 +1653,16 @@
_excludePatterns = patterns;
}
+ /**
+ * Return `true` to enable mixin declarations.
+ * https://github.com/dart-lang/language/issues/12
+ */
+ @deprecated
+ bool get isMixinSupportEnabled => true;
+
+ @deprecated
+ set isMixinSupportEnabled(bool value) {}
+
@override
List<Linter> get lintRules => _lintRules ??= const <Linter>[];
@@ -1656,9 +1674,11 @@
_lintRules = rules;
}
+ @deprecated
@override
bool get previewDart2 => true;
+ @deprecated
set previewDart2(bool value) {}
@override
@@ -1666,15 +1686,23 @@
if (_signature == null) {
ApiSignature buffer = new ApiSignature();
+ // Append environment.
+ if (sdkVersionConstraint != null) {
+ buffer.addString(sdkVersionConstraint.toString());
+ }
+
// Append boolean flags.
- buffer.addBool(declarationCasts);
buffer.addBool(enableLazyAssignmentOperators);
buffer.addBool(implicitCasts);
buffer.addBool(implicitDynamic);
buffer.addBool(strongModeHints);
buffer.addBool(useFastaParser);
- buffer.addBool(previewDart2);
- buffer.addBool(isMixinSupportEnabled);
+
+ // Append enabled experiments.
+ buffer.addInt(enabledExperiments.length);
+ for (String experimentName in enabledExperiments) {
+ buffer.addString(experimentName);
+ }
// Append error processors.
buffer.addInt(errorProcessors.length);
@@ -1730,9 +1758,9 @@
@override
void resetToDefaults() {
- declarationCasts = true;
dart2jsHint = false;
disableCacheFlushing = false;
+ enabledExperiments = const <String>[];
enabledPluginNames = const <String>[];
enableLazyAssignmentOperators = false;
enableTiming = false;
@@ -1749,9 +1777,10 @@
preserveComments = true;
strongModeHints = false;
trackCacheDependencies = true;
- useFastaParser = false;
+ useFastaParser = true;
}
+ @deprecated
@override
void setCrossContextOptionsFrom(AnalysisOptions options) {
enableLazyAssignmentOperators = options.enableLazyAssignmentOperators;
@@ -2686,7 +2715,7 @@
* An visitor that removes any resolution information from an AST structure when
* used to visit that structure.
*/
-class ResolutionEraser extends GeneralizingAstVisitor<Object> {
+class ResolutionEraser extends GeneralizingAstVisitor<void> {
/**
* A flag indicating whether the elements associated with declarations should
* be erased.
@@ -2694,122 +2723,122 @@
bool eraseDeclarations = true;
@override
- Object visitAssignmentExpression(AssignmentExpression node) {
+ void visitAssignmentExpression(AssignmentExpression node) {
node.staticElement = null;
- return super.visitAssignmentExpression(node);
+ super.visitAssignmentExpression(node);
}
@override
- Object visitBinaryExpression(BinaryExpression node) {
+ void visitBinaryExpression(BinaryExpression node) {
node.staticElement = null;
- return super.visitBinaryExpression(node);
+ super.visitBinaryExpression(node);
}
@override
- Object visitBreakStatement(BreakStatement node) {
+ void visitBreakStatement(BreakStatement node) {
node.target = null;
- return super.visitBreakStatement(node);
+ super.visitBreakStatement(node);
}
@override
- Object visitCompilationUnit(CompilationUnit node) {
+ void visitCompilationUnit(CompilationUnit node) {
if (eraseDeclarations) {
node.element = null;
}
- return super.visitCompilationUnit(node);
+ super.visitCompilationUnit(node);
}
@override
- Object visitConstructorDeclaration(ConstructorDeclaration node) {
+ void visitConstructorDeclaration(ConstructorDeclaration node) {
if (eraseDeclarations) {
node.element = null;
}
- return super.visitConstructorDeclaration(node);
+ super.visitConstructorDeclaration(node);
}
@override
- Object visitConstructorName(ConstructorName node) {
+ void visitConstructorName(ConstructorName node) {
node.staticElement = null;
- return super.visitConstructorName(node);
+ super.visitConstructorName(node);
}
@override
- Object visitContinueStatement(ContinueStatement node) {
+ void visitContinueStatement(ContinueStatement node) {
node.target = null;
- return super.visitContinueStatement(node);
+ super.visitContinueStatement(node);
}
@override
- Object visitDirective(Directive node) {
+ void visitDirective(Directive node) {
if (eraseDeclarations) {
node.element = null;
}
- return super.visitDirective(node);
+ super.visitDirective(node);
}
@override
- Object visitExpression(Expression node) {
+ void visitExpression(Expression node) {
node.staticType = null;
- return super.visitExpression(node);
+ super.visitExpression(node);
}
@override
- Object visitFunctionExpression(FunctionExpression node) {
+ void visitFunctionExpression(FunctionExpression node) {
if (eraseDeclarations) {
node.element = null;
}
- return super.visitFunctionExpression(node);
+ super.visitFunctionExpression(node);
}
@override
- Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+ void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
node.staticElement = null;
- return super.visitFunctionExpressionInvocation(node);
+ super.visitFunctionExpressionInvocation(node);
}
@override
- Object visitIndexExpression(IndexExpression node) {
+ void visitIndexExpression(IndexExpression node) {
node.staticElement = null;
- return super.visitIndexExpression(node);
+ super.visitIndexExpression(node);
}
@override
- Object visitInstanceCreationExpression(InstanceCreationExpression node) {
+ void visitInstanceCreationExpression(InstanceCreationExpression node) {
node.staticElement = null;
- return super.visitInstanceCreationExpression(node);
+ super.visitInstanceCreationExpression(node);
}
@override
- Object visitPostfixExpression(PostfixExpression node) {
+ void visitPostfixExpression(PostfixExpression node) {
node.staticElement = null;
- return super.visitPostfixExpression(node);
+ super.visitPostfixExpression(node);
}
@override
- Object visitPrefixExpression(PrefixExpression node) {
+ void visitPrefixExpression(PrefixExpression node) {
node.staticElement = null;
- return super.visitPrefixExpression(node);
+ super.visitPrefixExpression(node);
}
@override
- Object visitRedirectingConstructorInvocation(
+ void visitRedirectingConstructorInvocation(
RedirectingConstructorInvocation node) {
node.staticElement = null;
- return super.visitRedirectingConstructorInvocation(node);
+ super.visitRedirectingConstructorInvocation(node);
}
@override
- Object visitSimpleIdentifier(SimpleIdentifier node) {
+ void visitSimpleIdentifier(SimpleIdentifier node) {
if (eraseDeclarations || !node.inDeclarationContext()) {
node.staticElement = null;
}
- return super.visitSimpleIdentifier(node);
+ super.visitSimpleIdentifier(node);
}
@override
- Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+ void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
node.staticElement = null;
- return super.visitSuperConstructorInvocation(node);
+ super.visitSuperConstructorInvocation(node);
}
/**
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 207515d..5ca19f8 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -34,7 +34,7 @@
* A visitor used to traverse an AST structure looking for additional errors and
* warnings not covered by the parser and resolver.
*/
-class ErrorVerifier extends RecursiveAstVisitor<Object> {
+class ErrorVerifier extends RecursiveAstVisitor<void> {
/**
* The error reporter by which errors will be reported.
*/
@@ -328,38 +328,38 @@
}
@override
- Object visitAnnotation(Annotation node) {
+ void visitAnnotation(Annotation node) {
_checkForInvalidAnnotationFromDeferredLibrary(node);
_checkForMissingJSLibAnnotation(node);
- return super.visitAnnotation(node);
+ super.visitAnnotation(node);
}
@override
- Object visitArgumentList(ArgumentList node) {
+ void visitArgumentList(ArgumentList node) {
_checkForArgumentTypesNotAssignableInList(node);
- return super.visitArgumentList(node);
+ super.visitArgumentList(node);
}
@override
- Object visitAsExpression(AsExpression node) {
+ void visitAsExpression(AsExpression node) {
_checkForTypeAnnotationDeferredClass(node.type);
- return super.visitAsExpression(node);
+ super.visitAsExpression(node);
}
@override
- Object visitAssertInitializer(AssertInitializer node) {
+ void visitAssertInitializer(AssertInitializer node) {
_checkForNonBoolExpression(node);
- return super.visitAssertInitializer(node);
+ super.visitAssertInitializer(node);
}
@override
- Object visitAssertStatement(AssertStatement node) {
+ void visitAssertStatement(AssertStatement node) {
_checkForNonBoolExpression(node);
- return super.visitAssertStatement(node);
+ super.visitAssertStatement(node);
}
@override
- Object visitAssignmentExpression(AssignmentExpression node) {
+ void visitAssignmentExpression(AssignmentExpression node) {
TokenType operatorType = node.operator.type;
Expression lhs = node.leftHandSide;
Expression rhs = node.rightHandSide;
@@ -371,20 +371,20 @@
_checkForArgumentTypeNotAssignableForArgument(rhs);
}
_checkForAssignmentToFinal(lhs);
- return super.visitAssignmentExpression(node);
+ super.visitAssignmentExpression(node);
}
@override
- Object visitAwaitExpression(AwaitExpression node) {
+ void visitAwaitExpression(AwaitExpression node) {
if (!_inAsync) {
_errorReporter.reportErrorForToken(
CompileTimeErrorCode.AWAIT_IN_WRONG_CONTEXT, node.awaitKeyword);
}
- return super.visitAwaitExpression(node);
+ super.visitAwaitExpression(node);
}
@override
- Object visitBinaryExpression(BinaryExpression node) {
+ void visitBinaryExpression(BinaryExpression node) {
Token operator = node.operator;
TokenType type = operator.type;
if (type == TokenType.AMPERSAND_AMPERSAND || type == TokenType.BAR_BAR) {
@@ -398,22 +398,22 @@
_checkForArgumentTypeNotAssignableForArgument(node.rightOperand);
}
_checkForUseOfVoidResult(node.leftOperand);
- return super.visitBinaryExpression(node);
+ super.visitBinaryExpression(node);
}
@override
- Object visitBlock(Block node) {
+ void visitBlock(Block node) {
_hiddenElements = new HiddenElements(_hiddenElements, node);
try {
_checkDuplicateDeclarationInStatements(node.statements);
- return super.visitBlock(node);
+ super.visitBlock(node);
} finally {
_hiddenElements = _hiddenElements.outerElements;
}
}
@override
- Object visitBlockFunctionBody(BlockFunctionBody node) {
+ void visitBlockFunctionBody(BlockFunctionBody node) {
bool wasInAsync = _inAsync;
bool wasInGenerator = _inGenerator;
bool previousHasReturnWithoutValue = _hasReturnWithoutValue;
@@ -434,11 +434,10 @@
_returnsWithout = previousReturnsWithout;
_hasReturnWithoutValue = previousHasReturnWithoutValue;
}
- return null;
}
@override
- Object visitBreakStatement(BreakStatement node) {
+ void visitBreakStatement(BreakStatement node) {
SimpleIdentifier labelNode = node.label;
if (labelNode != null) {
Element labelElement = labelNode.staticElement;
@@ -447,24 +446,23 @@
ResolverErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER, labelNode);
}
}
- return null;
}
@override
- Object visitCatchClause(CatchClause node) {
+ void visitCatchClause(CatchClause node) {
_checkDuplicateDefinitionInCatchClause(node);
bool previousIsInCatchClause = _isInCatchClause;
try {
_isInCatchClause = true;
_checkForTypeAnnotationDeferredClass(node.exceptionType);
- return super.visitCatchClause(node);
+ super.visitCatchClause(node);
} finally {
_isInCatchClause = previousIsInCatchClause;
}
}
@override
- Object visitClassDeclaration(ClassDeclaration node) {
+ void visitClassDeclaration(ClassDeclaration node) {
ClassElementImpl outerClass = _enclosingClass;
try {
_isInNativeClass = node.nativeClause != null;
@@ -491,7 +489,7 @@
_initializeInitialFieldElementsMap(_enclosingClass.fields);
_checkForFinalNotInitializedInClass(members);
_checkForBadFunctionUse(node);
- return super.visitClassDeclaration(node);
+ super.visitClassDeclaration(node);
} finally {
_isInNativeClass = false;
_initialFieldElementsMap = null;
@@ -500,7 +498,7 @@
}
@override
- Object visitClassTypeAlias(ClassTypeAlias node) {
+ void visitClassTypeAlias(ClassTypeAlias node) {
_checkForBuiltInIdentifierAsName(
node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
ClassElementImpl outerClassElement = _enclosingClass;
@@ -511,37 +509,37 @@
} finally {
_enclosingClass = outerClassElement;
}
- return super.visitClassTypeAlias(node);
+ super.visitClassTypeAlias(node);
}
@override
- Object visitComment(Comment node) {
+ void visitComment(Comment node) {
_isInComment = true;
try {
- return super.visitComment(node);
+ super.visitComment(node);
} finally {
_isInComment = false;
}
}
@override
- Object visitCompilationUnit(CompilationUnit node) {
+ void visitCompilationUnit(CompilationUnit node) {
_checkDuplicateUnitMembers(node);
_checkForDeferredPrefixCollisions(node);
- return super.visitCompilationUnit(node);
+ super.visitCompilationUnit(node);
}
@override
- Object visitConditionalExpression(ConditionalExpression node) {
+ void visitConditionalExpression(ConditionalExpression node) {
_checkForNonBoolCondition(node.condition);
// TODO(mfairhurst) Enable this and get code compliant.
//_checkForUseOfVoidResult(node.thenExpression);
//_checkForUseOfVoidResult(node.elseExpression);
- return super.visitConditionalExpression(node);
+ super.visitConditionalExpression(node);
}
@override
- Object visitConstructorDeclaration(ConstructorDeclaration node) {
+ void visitConstructorDeclaration(ConstructorDeclaration node) {
ExecutableElement outerFunction = _enclosingFunction;
try {
ConstructorElement constructorElement = node.declaredElement;
@@ -563,7 +561,7 @@
_checkForUndefinedConstructorInInitializerImplicit(node);
_checkForRedirectToNonConstConstructor(node, constructorElement);
_checkForReturnInGenerativeConstructor(node);
- return super.visitConstructorDeclaration(node);
+ super.visitConstructorDeclaration(node);
} finally {
_isEnclosingConstructorConst = false;
_isInFactory = false;
@@ -572,7 +570,7 @@
}
@override
- Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
+ void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
_isInConstructorInitializer = true;
try {
SimpleIdentifier fieldName = node.fieldName;
@@ -581,14 +579,14 @@
if (staticElement is FieldElement) {
_checkForFieldInitializerNotAssignable(node, staticElement);
}
- return super.visitConstructorFieldInitializer(node);
+ super.visitConstructorFieldInitializer(node);
} finally {
_isInConstructorInitializer = false;
}
}
@override
- Object visitContinueStatement(ContinueStatement node) {
+ void visitContinueStatement(ContinueStatement node) {
SimpleIdentifier labelNode = node.label;
if (labelNode != null) {
Element labelElement = labelNode.staticElement;
@@ -598,36 +596,35 @@
ResolverErrorCode.CONTINUE_LABEL_ON_SWITCH, labelNode);
}
}
- return null;
}
@override
- Object visitDefaultFormalParameter(DefaultFormalParameter node) {
+ void visitDefaultFormalParameter(DefaultFormalParameter node) {
_checkForInvalidAssignment(node.identifier, node.defaultValue);
_checkForDefaultValueInFunctionTypedParameter(node);
- return super.visitDefaultFormalParameter(node);
+ super.visitDefaultFormalParameter(node);
}
@override
- Object visitDoStatement(DoStatement node) {
+ void visitDoStatement(DoStatement node) {
_checkForNonBoolCondition(node.condition);
- return super.visitDoStatement(node);
+ super.visitDoStatement(node);
}
@override
- Object visitEnumDeclaration(EnumDeclaration node) {
+ void visitEnumDeclaration(EnumDeclaration node) {
ClassElement outerEnum = _enclosingEnum;
try {
_enclosingEnum = node.declaredElement;
_checkDuplicateEnumMembers(node);
- return super.visitEnumDeclaration(node);
+ super.visitEnumDeclaration(node);
} finally {
_enclosingEnum = outerEnum;
}
}
@override
- Object visitExportDirective(ExportDirective node) {
+ void visitExportDirective(ExportDirective node) {
ExportElement exportElement = node.element;
if (exportElement != null) {
LibraryElement exportedLibrary = exportElement.exportedLibrary;
@@ -635,11 +632,11 @@
_checkForExportDuplicateLibraryName(node, exportElement, exportedLibrary);
_checkForExportInternalLibrary(node, exportElement);
}
- return super.visitExportDirective(node);
+ super.visitExportDirective(node);
}
@override
- Object visitExpressionFunctionBody(ExpressionFunctionBody node) {
+ void visitExpressionFunctionBody(ExpressionFunctionBody node) {
bool wasInAsync = _inAsync;
bool wasInGenerator = _inGenerator;
try {
@@ -657,7 +654,7 @@
_checkForReturnOfInvalidType(node.expression, expectedReturnType,
isArrowFunction: true);
}
- return super.visitExpressionFunctionBody(node);
+ super.visitExpressionFunctionBody(node);
} finally {
_inAsync = wasInAsync;
_inGenerator = wasInGenerator;
@@ -665,7 +662,7 @@
}
@override
- Object visitFieldDeclaration(FieldDeclaration node) {
+ void visitFieldDeclaration(FieldDeclaration node) {
_isInStaticVariableDeclaration = node.isStatic;
_isInInstanceVariableDeclaration = !_isInStaticVariableDeclaration;
if (_isInInstanceVariableDeclaration) {
@@ -676,7 +673,7 @@
}
}
try {
- return super.visitFieldDeclaration(node);
+ super.visitFieldDeclaration(node);
} finally {
_isInStaticVariableDeclaration = false;
_isInInstanceVariableDeclaration = false;
@@ -684,41 +681,41 @@
}
@override
- Object visitFieldFormalParameter(FieldFormalParameter node) {
+ void visitFieldFormalParameter(FieldFormalParameter node) {
_checkForValidField(node);
_checkForConstFormalParameter(node);
_checkForPrivateOptionalParameter(node);
_checkForFieldInitializingFormalRedirectingConstructor(node);
_checkForTypeAnnotationDeferredClass(node.type);
- return super.visitFieldFormalParameter(node);
+ super.visitFieldFormalParameter(node);
}
@override
- Object visitForEachStatement(ForEachStatement node) {
+ void visitForEachStatement(ForEachStatement node) {
_checkForInIterable(node);
- return super.visitForEachStatement(node);
+ super.visitForEachStatement(node);
}
@override
- Object visitFormalParameterList(FormalParameterList node) {
+ void visitFormalParameterList(FormalParameterList node) {
_checkDuplicateDefinitionInParameterList(node);
_checkUseOfCovariantInParameters(node);
- return super.visitFormalParameterList(node);
+ super.visitFormalParameterList(node);
}
@override
- Object visitForStatement(ForStatement node) {
+ void visitForStatement(ForStatement node) {
if (node.condition != null) {
_checkForNonBoolCondition(node.condition);
}
if (node.variables != null) {
_checkDuplicateVariables(node.variables);
}
- return super.visitForStatement(node);
+ super.visitForStatement(node);
}
@override
- Object visitFunctionDeclaration(FunctionDeclaration node) {
+ void visitFunctionDeclaration(FunctionDeclaration node) {
ExecutableElement functionElement = node.declaredElement;
if (functionElement != null &&
functionElement.enclosingElement is! CompilationUnitElement) {
@@ -751,31 +748,31 @@
_checkForTypeAnnotationDeferredClass(returnType);
_checkForIllegalReturnType(returnType);
_checkForImplicitDynamicReturn(node.name, node.declaredElement);
- return super.visitFunctionDeclaration(node);
+ super.visitFunctionDeclaration(node);
} finally {
_enclosingFunction = outerFunction;
}
}
@override
- Object visitFunctionExpression(FunctionExpression node) {
+ void visitFunctionExpression(FunctionExpression node) {
// If this function expression is wrapped in a function declaration, don't
// change the enclosingFunction field.
if (node.parent is! FunctionDeclaration) {
ExecutableElement outerFunction = _enclosingFunction;
try {
_enclosingFunction = node.declaredElement;
- return super.visitFunctionExpression(node);
+ super.visitFunctionExpression(node);
} finally {
_enclosingFunction = outerFunction;
}
} else {
- return super.visitFunctionExpression(node);
+ super.visitFunctionExpression(node);
}
}
@override
- Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+ void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
Expression functionExpression = node.function;
DartType expressionType = functionExpression.staticType;
if (!_checkForUseOfVoidResult(functionExpression) &&
@@ -787,20 +784,20 @@
_checkTypeArguments(node);
}
_checkForImplicitDynamicInvoke(node);
- return super.visitFunctionExpressionInvocation(node);
+ super.visitFunctionExpressionInvocation(node);
}
@override
- Object visitFunctionTypeAlias(FunctionTypeAlias node) {
+ void visitFunctionTypeAlias(FunctionTypeAlias node) {
_checkForBuiltInIdentifierAsName(
node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
_checkForDefaultValueInFunctionTypeAlias(node);
_checkForTypeAliasCannotReferenceItself_function(node);
- return super.visitFunctionTypeAlias(node);
+ super.visitFunctionTypeAlias(node);
}
@override
- Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+ void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
bool old = _isInFunctionTypedFormalParameter;
_isInFunctionTypedFormalParameter = true;
try {
@@ -828,35 +825,35 @@
node);
}
- return super.visitFunctionTypedFormalParameter(node);
+ super.visitFunctionTypedFormalParameter(node);
} finally {
_isInFunctionTypedFormalParameter = old;
}
}
@override
- Object visitGenericTypeAlias(GenericTypeAlias node) {
+ void visitGenericTypeAlias(GenericTypeAlias node) {
if (_hasTypedefSelfReference(node.declaredElement)) {
_errorReporter.reportErrorForNode(
CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, node);
}
- return super.visitGenericTypeAlias(node);
+ super.visitGenericTypeAlias(node);
}
@override
- Object visitIfStatement(IfStatement node) {
+ void visitIfStatement(IfStatement node) {
_checkForNonBoolCondition(node.condition);
- return super.visitIfStatement(node);
+ super.visitIfStatement(node);
}
@override
- Object visitImplementsClause(ImplementsClause node) {
+ void visitImplementsClause(ImplementsClause node) {
node.interfaces.forEach(_checkForImplicitDynamicType);
- return super.visitImplementsClause(node);
+ super.visitImplementsClause(node);
}
@override
- Object visitImportDirective(ImportDirective node) {
+ void visitImportDirective(ImportDirective node) {
ImportElement importElement = node.element;
if (node.prefix != null) {
_checkForBuiltInIdentifierAsName(
@@ -866,17 +863,17 @@
_checkForImportDuplicateLibraryName(node, importElement);
_checkForImportInternalLibrary(node, importElement);
}
- return super.visitImportDirective(node);
+ super.visitImportDirective(node);
}
@override
- Object visitIndexExpression(IndexExpression node) {
+ void visitIndexExpression(IndexExpression node) {
_checkForArgumentTypeNotAssignableForArgument(node.index);
- return super.visitIndexExpression(node);
+ super.visitIndexExpression(node);
}
@override
- Object visitInstanceCreationExpression(InstanceCreationExpression node) {
+ void visitInstanceCreationExpression(InstanceCreationExpression node) {
bool wasInConstInstanceCreation = _isInConstInstanceCreation;
_isInConstInstanceCreation = node.isConst;
try {
@@ -897,33 +894,33 @@
}
}
_checkForImplicitDynamicType(typeName);
- return super.visitInstanceCreationExpression(node);
+ super.visitInstanceCreationExpression(node);
} finally {
_isInConstInstanceCreation = wasInConstInstanceCreation;
}
}
@override
- Object visitIntegerLiteral(IntegerLiteral node) {
+ void visitIntegerLiteral(IntegerLiteral node) {
_checkForOutOfRange(node);
- return super.visitIntegerLiteral(node);
+ super.visitIntegerLiteral(node);
}
@override
- Object visitInterpolationExpression(InterpolationExpression node) {
+ void visitInterpolationExpression(InterpolationExpression node) {
_checkForUseOfVoidResult(node.expression);
- return super.visitInterpolationExpression(node);
+ super.visitInterpolationExpression(node);
}
@override
- Object visitIsExpression(IsExpression node) {
+ void visitIsExpression(IsExpression node) {
_checkForTypeAnnotationDeferredClass(node.type);
_checkForUseOfVoidResult(node.expression);
- return super.visitIsExpression(node);
+ super.visitIsExpression(node);
}
@override
- Object visitListLiteral(ListLiteral node) {
+ void visitListLiteral(ListLiteral node) {
TypeArgumentList typeArguments = node.typeArguments;
if (typeArguments != null) {
if (node.isConst) {
@@ -938,11 +935,11 @@
_checkForImplicitDynamicTypedLiteral(node);
_checkForListElementTypeNotAssignable(node);
- return super.visitListLiteral(node);
+ super.visitListLiteral(node);
}
@override
- Object visitMapLiteral(MapLiteral node) {
+ void visitMapLiteral(MapLiteral node) {
TypeArgumentList typeArguments = node.typeArguments;
if (typeArguments != null) {
NodeList<TypeAnnotation> arguments = typeArguments.arguments;
@@ -957,11 +954,11 @@
_checkForImplicitDynamicTypedLiteral(node);
_checkForMapTypeNotAssignable(node);
_checkForNonConstMapAsExpressionStatement(node);
- return super.visitMapLiteral(node);
+ super.visitMapLiteral(node);
}
@override
- Object visitMethodDeclaration(MethodDeclaration node) {
+ void visitMethodDeclaration(MethodDeclaration node) {
ExecutableElement previousFunction = _enclosingFunction;
try {
_isInStaticMethod = node.isStatic;
@@ -981,7 +978,7 @@
_checkForIllegalReturnType(returnType);
_checkForImplicitDynamicReturn(node, node.declaredElement);
_checkForMustCallSuper(node);
- return super.visitMethodDeclaration(node);
+ super.visitMethodDeclaration(node);
} finally {
_enclosingFunction = previousFunction;
_isInStaticMethod = false;
@@ -989,7 +986,7 @@
}
@override
- Object visitMethodInvocation(MethodInvocation node) {
+ void visitMethodInvocation(MethodInvocation node) {
Expression target = node.realTarget;
SimpleIdentifier methodName = node.methodName;
if (target != null) {
@@ -1001,11 +998,11 @@
}
_checkTypeArguments(node);
_checkForImplicitDynamicInvoke(node);
- return super.visitMethodInvocation(node);
+ super.visitMethodInvocation(node);
}
@override
- Object visitMixinDeclaration(MixinDeclaration node) {
+ void visitMixinDeclaration(MixinDeclaration node) {
// TODO(scheglov) Verify for all mixin errors.
ClassElementImpl outerClass = _enclosingClass;
try {
@@ -1029,7 +1026,7 @@
_initializeInitialFieldElementsMap(_enclosingClass.fields);
_checkForFinalNotInitializedInClass(members);
// _checkForBadFunctionUse(node);
- return super.visitMixinDeclaration(node);
+ super.visitMixinDeclaration(node);
} finally {
_initialFieldElementsMap = null;
_enclosingClass = outerClass;
@@ -1037,31 +1034,31 @@
}
@override
- Object visitNativeClause(NativeClause node) {
+ void visitNativeClause(NativeClause node) {
// TODO(brianwilkerson) Figure out the right rule for when 'native' is
// allowed.
if (!_isInSystemLibrary) {
_errorReporter.reportErrorForNode(
ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE, node);
}
- return super.visitNativeClause(node);
+ super.visitNativeClause(node);
}
@override
- Object visitNativeFunctionBody(NativeFunctionBody node) {
+ void visitNativeFunctionBody(NativeFunctionBody node) {
_checkForNativeFunctionBodyInNonSdkCode(node);
- return super.visitNativeFunctionBody(node);
+ super.visitNativeFunctionBody(node);
}
@override
- Object visitPostfixExpression(PostfixExpression node) {
+ void visitPostfixExpression(PostfixExpression node) {
_checkForAssignmentToFinal(node.operand);
_checkForIntNotAssignable(node.operand);
- return super.visitPostfixExpression(node);
+ super.visitPostfixExpression(node);
}
@override
- Object visitPrefixedIdentifier(PrefixedIdentifier node) {
+ void visitPrefixedIdentifier(PrefixedIdentifier node) {
if (node.parent is! Annotation) {
ClassElement typeReference =
ElementResolver.getTypeReference(node.prefix);
@@ -1069,11 +1066,11 @@
_checkForStaticAccessToInstanceMember(typeReference, name);
_checkForInstanceAccessToStaticMember(typeReference, name);
}
- return super.visitPrefixedIdentifier(node);
+ super.visitPrefixedIdentifier(node);
}
@override
- Object visitPrefixExpression(PrefixExpression node) {
+ void visitPrefixExpression(PrefixExpression node) {
TokenType operatorType = node.operator.type;
Expression operand = node.operand;
if (operatorType == TokenType.BANG) {
@@ -1083,49 +1080,68 @@
}
_checkForIntNotAssignable(operand);
_checkForUseOfVoidResult(operand);
- return super.visitPrefixExpression(node);
+ super.visitPrefixExpression(node);
}
@override
- Object visitPropertyAccess(PropertyAccess node) {
+ void visitPropertyAccess(PropertyAccess node) {
ClassElement typeReference =
ElementResolver.getTypeReference(node.realTarget);
SimpleIdentifier propertyName = node.propertyName;
_checkForStaticAccessToInstanceMember(typeReference, propertyName);
_checkForInstanceAccessToStaticMember(typeReference, propertyName);
- return super.visitPropertyAccess(node);
+ super.visitPropertyAccess(node);
}
@override
- Object visitRedirectingConstructorInvocation(
+ void visitRedirectingConstructorInvocation(
RedirectingConstructorInvocation node) {
_isInConstructorInitializer = true;
try {
- return super.visitRedirectingConstructorInvocation(node);
+ super.visitRedirectingConstructorInvocation(node);
} finally {
_isInConstructorInitializer = false;
}
}
@override
- Object visitRethrowExpression(RethrowExpression node) {
+ void visitRethrowExpression(RethrowExpression node) {
_checkForRethrowOutsideCatch(node);
- return super.visitRethrowExpression(node);
+ super.visitRethrowExpression(node);
}
@override
- Object visitReturnStatement(ReturnStatement node) {
+ void visitReturnStatement(ReturnStatement node) {
if (node.expression == null) {
_returnsWithout.add(node);
} else {
_returnsWith.add(node);
}
_checkForAllReturnStatementErrorCodes(node);
- return super.visitReturnStatement(node);
+ super.visitReturnStatement(node);
}
@override
- Object visitSimpleFormalParameter(SimpleFormalParameter node) {
+ void visitSetLiteral(SetLiteral node) {
+ TypeArgumentList typeArguments = node.typeArguments;
+ if (typeArguments != null) {
+ if (node.isConst) {
+ NodeList<TypeAnnotation> arguments = typeArguments.arguments;
+ if (arguments.isNotEmpty) {
+ _checkForInvalidTypeArgumentInConstTypedLiteral(arguments,
+ CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_SET);
+ }
+ }
+ _checkForExpectedOneSetTypeArgument(node, typeArguments);
+ }
+ _checkForImplicitDynamicTypedLiteral(node);
+ _checkForSetElementTypeNotAssignable(node);
+
+ super.visitSetLiteral(node);
+ }
+
+ @override
+ void visitSimpleFormalParameter(SimpleFormalParameter node) {
_checkForConstFormalParameter(node);
_checkForPrivateOptionalParameter(node);
_checkForTypeAnnotationDeferredClass(node.type);
@@ -1138,88 +1154,87 @@
// - FunctionTypedFormalParameter is a function type, not dynamic.
_checkForImplicitDynamicIdentifier(node, node.identifier);
- return super.visitSimpleFormalParameter(node);
+ super.visitSimpleFormalParameter(node);
}
@override
- Object visitSimpleIdentifier(SimpleIdentifier node) {
+ void visitSimpleIdentifier(SimpleIdentifier node) {
_checkForAmbiguousImport(node);
_checkForReferenceBeforeDeclaration(node);
_checkForImplicitThisReferenceInInitializer(node);
- _checkForTypeParameterIdentifierReferencedByStatic(node);
+ _checkForTypeParameterReferencedByStatic(node);
if (!_isUnqualifiedReferenceToNonLocalStaticMemberAllowed(node)) {
_checkForUnqualifiedReferenceToNonLocalStaticMember(node);
}
- return super.visitSimpleIdentifier(node);
+ super.visitSimpleIdentifier(node);
}
@override
- Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+ void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
_isInConstructorInitializer = true;
try {
- return super.visitSuperConstructorInvocation(node);
+ super.visitSuperConstructorInvocation(node);
} finally {
_isInConstructorInitializer = false;
}
}
@override
- Object visitSwitchCase(SwitchCase node) {
+ void visitSwitchCase(SwitchCase node) {
_checkDuplicateDeclarationInStatements(node.statements);
- return super.visitSwitchCase(node);
+ super.visitSwitchCase(node);
}
@override
- Object visitSwitchDefault(SwitchDefault node) {
+ void visitSwitchDefault(SwitchDefault node) {
_checkDuplicateDeclarationInStatements(node.statements);
- return super.visitSwitchDefault(node);
+ super.visitSwitchDefault(node);
}
@override
- Object visitSwitchStatement(SwitchStatement node) {
+ void visitSwitchStatement(SwitchStatement node) {
_checkForSwitchExpressionNotAssignable(node);
_checkForCaseBlocksNotTerminated(node);
_checkForMissingEnumConstantInSwitch(node);
- return super.visitSwitchStatement(node);
+ super.visitSwitchStatement(node);
}
@override
- Object visitThisExpression(ThisExpression node) {
+ void visitThisExpression(ThisExpression node) {
_checkForInvalidReferenceToThis(node);
- return super.visitThisExpression(node);
+ super.visitThisExpression(node);
}
@override
- Object visitThrowExpression(ThrowExpression node) {
+ void visitThrowExpression(ThrowExpression node) {
_checkForConstEvalThrowsException(node);
_checkForUseOfVoidResult(node.expression);
- return super.visitThrowExpression(node);
+ super.visitThrowExpression(node);
}
@override
- Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+ void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
_checkForFinalNotInitialized(node.variables);
- return super.visitTopLevelVariableDeclaration(node);
+ super.visitTopLevelVariableDeclaration(node);
}
@override
- Object visitTypeArgumentList(TypeArgumentList node) {
+ void visitTypeArgumentList(TypeArgumentList node) {
NodeList<TypeAnnotation> list = node.arguments;
for (TypeAnnotation type in list) {
_checkForTypeAnnotationDeferredClass(type);
}
- return super.visitTypeArgumentList(node);
+ super.visitTypeArgumentList(node);
}
@override
- Object visitTypeName(TypeName node) {
+ void visitTypeName(TypeName node) {
_checkForTypeArgumentNotMatchingBounds(node);
- _checkForTypeParameterReferencedByStatic(node);
- return super.visitTypeName(node);
+ super.visitTypeName(node);
}
@override
- Object visitTypeParameter(TypeParameter node) {
+ void visitTypeParameter(TypeParameter node) {
_checkForBuiltInIdentifierAsName(node.name,
CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME);
_checkForTypeParameterSupertypeOfItsBound(node);
@@ -1227,22 +1242,21 @@
_checkForImplicitDynamicType(node.bound);
_checkForGenericFunctionType(node.bound);
node.bound?.accept(_uninstantiatedBoundChecker);
- return super.visitTypeParameter(node);
+ super.visitTypeParameter(node);
}
@override
- Object visitTypeParameterList(TypeParameterList node) {
+ void visitTypeParameterList(TypeParameterList node) {
_checkDuplicateDefinitionInTypeParameterList(node);
- return super.visitTypeParameterList(node);
+ super.visitTypeParameterList(node);
}
@override
- Object visitVariableDeclaration(VariableDeclaration node) {
+ void visitVariableDeclaration(VariableDeclaration node) {
SimpleIdentifier nameNode = node.name;
Expression initializerNode = node.initializer;
// do checks
- _checkForInvalidAssignment(nameNode, initializerNode,
- isDeclarationCast: true);
+ _checkForInvalidAssignment(nameNode, initializerNode);
_checkForImplicitDynamicIdentifier(node, nameNode);
// visit name
nameNode.accept(this);
@@ -1268,36 +1282,34 @@
_hiddenElements.declare(element);
}
}
- // done
- return null;
}
@override
- Object visitVariableDeclarationList(VariableDeclarationList node) {
+ void visitVariableDeclarationList(VariableDeclarationList node) {
_checkForTypeAnnotationDeferredClass(node.type);
- return super.visitVariableDeclarationList(node);
+ super.visitVariableDeclarationList(node);
}
@override
- Object visitVariableDeclarationStatement(VariableDeclarationStatement node) {
+ void visitVariableDeclarationStatement(VariableDeclarationStatement node) {
_checkForFinalNotInitialized(node.variables);
- return super.visitVariableDeclarationStatement(node);
+ super.visitVariableDeclarationStatement(node);
}
@override
- Object visitWhileStatement(WhileStatement node) {
+ void visitWhileStatement(WhileStatement node) {
_checkForNonBoolCondition(node.condition);
- return super.visitWhileStatement(node);
+ super.visitWhileStatement(node);
}
@override
- Object visitWithClause(WithClause node) {
+ void visitWithClause(WithClause node) {
node.mixinTypes.forEach(_checkForImplicitDynamicType);
- return super.visitWithClause(node);
+ super.visitWithClause(node);
}
@override
- Object visitYieldStatement(YieldStatement node) {
+ void visitYieldStatement(YieldStatement node) {
if (_inGenerator) {
_checkForYieldOfInvalidType(node.expression, node.star != null);
} else {
@@ -1310,7 +1322,7 @@
_errorReporter.reportErrorForNode(errorCode, node);
}
_checkForUseOfVoidResult(node.expression);
- return super.visitYieldStatement(node);
+ super.visitYieldStatement(node);
}
/**
@@ -1911,8 +1923,7 @@
if (_checkForMixinSuperclassConstraints(
mixinNameIndex, mixinName)) {
problemReported = true;
- }
- if (_checkForMixinSuperInvokedMembers(
+ } else if (_checkForMixinSuperInvokedMembers(
mixinTypeIndex, mixinName, mixinElement, mixinType)) {
problemReported = true;
}
@@ -2218,24 +2229,20 @@
}
bool _checkForAssignableExpression(
- Expression expression, DartType expectedStaticType, ErrorCode errorCode,
- {bool isDeclarationCast = false}) {
+ Expression expression, DartType expectedStaticType, ErrorCode errorCode) {
DartType actualStaticType = getStaticType(expression);
return actualStaticType != null &&
_checkForAssignableExpressionAtType(
- expression, actualStaticType, expectedStaticType, errorCode,
- isDeclarationCast: isDeclarationCast);
+ expression, actualStaticType, expectedStaticType, errorCode);
}
bool _checkForAssignableExpressionAtType(
Expression expression,
DartType actualStaticType,
DartType expectedStaticType,
- ErrorCode errorCode,
- {bool isDeclarationCast = false}) {
+ ErrorCode errorCode) {
if (!_expressionIsAssignableAtType(
- expression, actualStaticType, expectedStaticType,
- isDeclarationCast: isDeclarationCast)) {
+ expression, actualStaticType, expectedStaticType)) {
_errorReporter.reportTypeErrorForNode(
errorCode, expression, [actualStaticType, expectedStaticType]);
return false;
@@ -2895,6 +2902,24 @@
}
/**
+ * Verify that if the given set [literal] has type arguments then there is
+ * exactly one. The [typeArguments] are the type arguments.
+ *
+ * See [StaticTypeWarningCode.EXPECTED_ONE_SET_TYPE_ARGUMENTS].
+ */
+ void _checkForExpectedOneSetTypeArgument(
+ SetLiteral literal, TypeArgumentList typeArguments) {
+ // check number of type arguments
+ int count = typeArguments.arguments.length;
+ if (count != 1) {
+ _errorReporter.reportErrorForNode(
+ StaticTypeWarningCode.EXPECTED_ONE_SET_TYPE_ARGUMENTS,
+ typeArguments,
+ [count]);
+ }
+ }
+
+ /**
* Verify that the given export [directive] has a unique name among other
* exported libraries. The [exportElement] is the [ExportElement] retrieved
* from the node, if the element in the node was `null`, then this method is
@@ -3609,8 +3634,7 @@
StaticTypeWarningCode.FOR_IN_OF_INVALID_TYPE,
node.iterable,
[iterableType, loopTypeName]);
- } else if (!_typeSystem.isAssignableTo(bestIterableType, variableType,
- isDeclarationCast: true)) {
+ } else if (!_typeSystem.isAssignableTo(bestIterableType, variableType)) {
_errorReporter.reportTypeErrorForNode(
StaticTypeWarningCode.FOR_IN_OF_INVALID_ELEMENT_TYPE,
node.iterable,
@@ -3689,8 +3713,7 @@
*
* See [StaticTypeWarningCode.INVALID_ASSIGNMENT].
*/
- void _checkForInvalidAssignment(Expression lhs, Expression rhs,
- {bool isDeclarationCast = false}) {
+ void _checkForInvalidAssignment(Expression lhs, Expression rhs) {
if (lhs == null || rhs == null) {
return;
}
@@ -3704,8 +3727,7 @@
}
_checkForAssignableExpression(
- rhs, leftType, StaticTypeWarningCode.INVALID_ASSIGNMENT,
- isDeclarationCast: isDeclarationCast);
+ rhs, leftType, StaticTypeWarningCode.INVALID_ASSIGNMENT);
}
/**
@@ -4147,6 +4169,11 @@
return false;
}
+ ClassElementImpl nominalSuperClass =
+ AbstractClassElementImpl.getImpl(_enclosingClass.supertype?.element);
+ bool nominalSuperClassHasNoSuchMethodForwarders =
+ nominalSuperClass != null && !nominalSuperClass.isAbstract;
+
InterfaceTypeImpl enclosingType = _enclosingClass.type;
Uri mixinLibraryUri = mixinElement.librarySource.uri;
for (var name in mixinElementImpl.superInvokedNames) {
@@ -4154,9 +4181,12 @@
var superMemberType = _inheritanceManager.getMember(
enclosingType, nameObject,
- forMixinIndex: mixinIndex, forSuper: true);
+ forMixinIndex: mixinIndex, concrete: true, forSuper: true);
if (superMemberType == null) {
+ if (nominalSuperClassHasNoSuchMethodForwarders) {
+ continue;
+ }
_errorReporter.reportErrorForNode(
CompileTimeErrorCode
.MIXIN_APPLICATION_NO_CONCRETE_SUPER_INVOKED_MEMBER,
@@ -4321,7 +4351,7 @@
DartType type = typeName.type;
if (type is InterfaceType) {
ClassElement element = type.element;
- if (element != null && element.isEnum) {
+ if (element.isEnum || element.isMixin) {
// We have already reported the error.
return;
}
@@ -4453,8 +4483,7 @@
return;
}
// prepare statement
- Statement statement =
- literal.getAncestor((node) => node is ExpressionStatement);
+ Statement statement = literal.thisOrAncestorOfType<ExpressionStatement>();
if (statement == null) {
return;
}
@@ -5032,6 +5061,41 @@
}
/**
+ * Verify that the elements in the given set [literal] are subtypes of the
+ * set's static type.
+ *
+ * See [CompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE], and
+ * [StaticWarningCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE].
+ */
+ void _checkForSetElementTypeNotAssignable(SetLiteral literal) {
+ // Determine the list's element type. We base this on the static type and
+ // not the literal's type arguments because in strong mode, the type
+ // arguments may be inferred.
+ DartType setType = literal.staticType;
+ assert(setType is InterfaceTypeImpl);
+
+ List<DartType> typeArguments = (setType as InterfaceTypeImpl).typeArguments;
+ assert(typeArguments.length == 1);
+
+ DartType setElementType = typeArguments[0];
+
+ // Check every list element.
+ bool isConst = literal.isConst;
+ for (Expression element in literal.elements) {
+ if (isConst) {
+ // TODO(paulberry): this error should be based on the actual type of the
+ // element, not the static type. See dartbug.com/21119.
+ _checkForArgumentTypeNotAssignableWithExpectedTypes(
+ element,
+ setElementType,
+ CheckedModeCompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE);
+ }
+ _checkForArgumentTypeNotAssignableWithExpectedTypes(element,
+ setElementType, StaticWarningCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE);
+ }
+ }
+
+ /**
* Check the given [typeReference] and that the [name] is not a reference to
* an instance member.
*
@@ -5175,10 +5239,10 @@
? argumentNodes[i]
: typeName;
if (argType is FunctionType && argType.typeFormals.isNotEmpty) {
- _errorReporter.reportTypeErrorForNode(
- CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT,
- argumentNode,
- [argType.typeFormals.join(', ')]);
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
+ argumentNode,
+ );
continue;
}
DartType boundType = parameterElements[i].bound;
@@ -5213,12 +5277,11 @@
}
}
- void _checkForTypeParameterIdentifierReferencedByStatic(
- SimpleIdentifier identifier) {
- var element = identifier.staticElement;
- if (element is TypeParameterElement &&
- element.enclosingElement is ClassElement) {
- if (_isInStaticMethod || _isInStaticVariableDeclaration) {
+ void _checkForTypeParameterReferencedByStatic(SimpleIdentifier identifier) {
+ if (_isInStaticMethod || _isInStaticVariableDeclaration) {
+ var element = identifier.staticElement;
+ if (element is TypeParameterElement &&
+ element.enclosingElement is ClassElement) {
// The class's type parameters are not in scope for static methods.
// However all other type parameters are legal (e.g. the static method's
// type parameters, or a local function's type parameters).
@@ -5229,26 +5292,6 @@
}
/**
- * Check whether the given type [name] is a type parameter being used to
- * define a static member.
- *
- * See [StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC].
- */
- void _checkForTypeParameterReferencedByStatic(TypeName name) {
- if (_isInStaticMethod || _isInStaticVariableDeclaration) {
- DartType type = name.type;
- // The class's type parameters are not in scope for static methods.
- // However all other type parameters are legal (e.g. the static method's
- // type parameters, or a local function's type parameters).
- if (type is TypeParameterType &&
- type.element.enclosingElement is ClassElement) {
- _errorReporter.reportErrorForNode(
- StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, name);
- }
- }
- }
-
- /**
* Check whether the given type [parameter] is a supertype of its bound.
*
* See [StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND].
@@ -5720,10 +5763,10 @@
DartType argType = typeArgs[i];
if (argType is FunctionType && argType.typeFormals.isNotEmpty) {
- _errorReporter.reportTypeErrorForNode(
- CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT,
- typeArgumentList[i],
- [argType.typeFormals.join(', ')]);
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
+ typeArgumentList[i],
+ );
continue;
}
@@ -5757,10 +5800,8 @@
}
bool _expressionIsAssignableAtType(Expression expression,
- DartType actualStaticType, DartType expectedStaticType,
- {isDeclarationCast: false}) {
- return _typeSystem.isAssignableTo(actualStaticType, expectedStaticType,
- isDeclarationCast: isDeclarationCast);
+ DartType actualStaticType, DartType expectedStaticType) {
+ return _typeSystem.isAssignableTo(actualStaticType, expectedStaticType);
}
InterfaceType _findInterfaceTypeForMixin(TypeName mixin,
@@ -5953,14 +5994,7 @@
}
ExecutableElement _getOverriddenMember(Element member) {
- if (member == null) {
- return null;
- }
- ClassElement classElement =
- member.getAncestor((element) => element is ClassElement);
- if (classElement == null) {
- return null;
- }
+ ClassElement classElement = member.enclosingElement;
String name = member.name;
ClassElement superclass = classElement.supertype?.element;
Set<ClassElement> visitedClasses = new Set<ClassElement>();
@@ -6082,7 +6116,7 @@
return identical(parent.constructorName, identifier);
}
if (parent is CommentReference) {
- return parent.newKeyword != null;
+ return true;
}
if (parent is ConstructorName) {
return identical(parent.name, identifier);
@@ -6349,47 +6383,45 @@
.firstWhere((ElementAnnotation e) => e.isRequired, orElse: () => null);
}
-class _HasTypedefSelfReferenceVisitor
- extends GeneralizingElementVisitor<Object> {
+class _HasTypedefSelfReferenceVisitor extends GeneralizingElementVisitor<void> {
final GenericFunctionTypeElement element;
bool hasSelfReference = false;
_HasTypedefSelfReferenceVisitor(this.element);
@override
- Object visitClassElement(ClassElement element) {
+ void visitClassElement(ClassElement element) {
// Typedefs are allowed to reference themselves via classes.
- return null;
}
@override
- Object visitFunctionElement(FunctionElement element) {
+ void visitFunctionElement(FunctionElement element) {
_addTypeToCheck(element.returnType);
- return super.visitFunctionElement(element);
+ super.visitFunctionElement(element);
}
@override
- Object visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
+ void visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
_addTypeToCheck(element.returnType);
- return super.visitFunctionTypeAliasElement(element);
+ super.visitFunctionTypeAliasElement(element);
}
@override
- Object visitGenericFunctionTypeElement(GenericFunctionTypeElement element) {
+ void visitGenericFunctionTypeElement(GenericFunctionTypeElement element) {
_addTypeToCheck(element.returnType);
- return super.visitGenericFunctionTypeElement(element);
+ super.visitGenericFunctionTypeElement(element);
}
@override
- Object visitParameterElement(ParameterElement element) {
+ void visitParameterElement(ParameterElement element) {
_addTypeToCheck(element.type);
- return super.visitParameterElement(element);
+ super.visitParameterElement(element);
}
@override
- Object visitTypeParameterElement(TypeParameterElement element) {
+ void visitTypeParameterElement(TypeParameterElement element) {
_addTypeToCheck(element.bound);
- return super.visitTypeParameterElement(element);
+ super.visitTypeParameterElement(element);
}
void _addTypeToCheck(DartType type) {
diff --git a/pkg/analyzer/lib/src/generated/package.dart b/pkg/analyzer/lib/src/generated/package.dart
deleted file mode 100644
index fba626f..0000000
--- a/pkg/analyzer/lib/src/generated/package.dart
+++ /dev/null
@@ -1,241 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:collection';
-
-import 'package:analyzer/exception/exception.dart';
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/context/builder.dart';
-import 'package:analyzer/src/file_system/file_system.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/utilities_general.dart';
-import 'package:analyzer/src/source/package_map_resolver.dart';
-import 'package:package_config/packages.dart';
-import 'package:yaml/yaml.dart';
-
-/**
- * Traverses the package structure to determine the transitive dependencies for
- * a given package.
- */
-class DependencyFinder {
- /**
- * The name of the pubspec.yaml file.
- */
- static const String pubspecName = 'pubspec.yaml';
-
- /**
- * The resource provider used to access the file system.
- */
- final ResourceProvider resourceProvider;
-
- /**
- * A table mapping the absolute paths of packages to a list of the names of
- * the packages on which those packages depend.
- */
- final Map<String, List<String>> dependencyMap =
- new HashMap<String, List<String>>();
-
- /**
- * Initialize a newly created dependency finder to use the given
- * [resourceProvider] to access the file system.
- */
- DependencyFinder(this.resourceProvider);
-
- /**
- * Return a sorted list of the directories containing all of the packages on
- * which the package at the given [packagePath] depends. The [packageMap]
- * maps the names of packages to the directories in which they are contained.
- *
- * Throws an [AnalysisException] if any of the packages are missing their
- * 'pubspec.yaml' file.
- */
- List<String> transitiveDependenciesFor(
- Map<String, List<Folder>> packageMap, String packagePath) {
- Set<String> processedPackages = new HashSet<String>();
- Set<String> processedPaths = new HashSet<String>();
- void process(String packageName) {
- if (processedPackages.add(packageName)) {
- List<Folder> folderList = packageMap[packageName];
- if (folderList == null || folderList.isEmpty) {
- throw new StateError('No mapping for package "$packageName"');
- }
- String packagePath = folderList[0].path;
- processedPaths.add(packagePath);
- List<String> dependencies = _dependenciesFor(packagePath);
- for (String dependency in dependencies) {
- process(dependency);
- }
- }
- }
-
- List<String> dependencies = _dependenciesFor(packagePath);
- dependencies.forEach(process);
- processedPaths.remove(packagePath);
- List<String> transitiveDependencies = processedPaths.toList();
- transitiveDependencies.sort();
- return transitiveDependencies;
- }
-
- /**
- * Add to the given set of [dependecies] all of the package names used as keys
- * in the given [yamlMap].
- */
- void _collectDependencies(HashSet<String> dependencies, YamlMap yamlMap) {
- if (yamlMap is Map) {
- for (var key in yamlMap.keys) {
- if (key is String) {
- dependencies.add(key);
- }
- }
- }
- }
-
- /**
- * Return a list of the names of the packages on which the package at the
- * [packagePath] depends.
- */
- List<String> _dependenciesFor(String packagePath) {
- return dependencyMap.putIfAbsent(packagePath, () {
- Set<String> dependencies = new HashSet<String>();
- YamlNode yamlNode = _readPubspec(packagePath);
- if (yamlNode is YamlMap) {
- _collectDependencies(dependencies, yamlNode['dependencies']);
- }
- return dependencies.toList();
- });
- }
-
- /**
- * Read the content of the pubspec file in the directory at the given
- * [directoryPath]. Return `null` if the file does not exist, cannot be read,
- * or has content that is not valid YAML.
- */
- YamlNode _readPubspec(String directoryPath) {
- try {
- File yamlFile = resourceProvider
- .getFolder(directoryPath)
- .getChildAssumingFile(pubspecName);
- String yamlContent = yamlFile.readAsStringSync();
- return loadYamlNode(yamlContent);
- } catch (exception, stackTrace) {
- throw new AnalysisException('Missing $pubspecName in $directoryPath',
- new CaughtException(exception, stackTrace));
- }
- }
-}
-
-/**
- * A description of the context in which a package will be analyzed.
- */
-class PackageDescription {
- /**
- * The id of the package being described. The id encodes the actual locations
- * of the package itself and all of the packages on which it depends.
- */
- final String id;
-
- /**
- * The SDK against which the package will be analyzed.
- */
- final DartSdk sdk;
-
- /**
- * The analysis options that will be used when analyzing the package.
- */
- final AnalysisOptions options;
-
- /**
- * Initialize a newly create package description to describe the package with
- * the given [id] that is being analyzed against the given [sdk] using the
- * given [options].
- */
- PackageDescription(this.id, this.sdk, this.options);
-
- @override
- int get hashCode {
- int hashCode = 0;
- for (int value in options.signature) {
- hashCode = JenkinsSmiHash.combine(hashCode, value);
- }
- hashCode = JenkinsSmiHash.combine(hashCode, id.hashCode);
- hashCode = JenkinsSmiHash.combine(hashCode, sdk.hashCode);
- return JenkinsSmiHash.finish(hashCode);
- }
-
- @override
- bool operator ==(Object other) {
- return other is PackageDescription &&
- other.sdk == sdk &&
- AnalysisOptions.signaturesEqual(
- other.options.signature, options.signature) &&
- other.id == id;
- }
-}
-
-/**
- * Manages the contexts in which each package is analyzed.
- */
-class PackageManager {
- /**
- * The resource provider used to access the file system.
- */
- final ResourceProvider resourceProvider;
-
- /**
- * A table mapping the id's of packages to the context in which the package is
- * analyzed.
- */
- final Map<PackageDescription, AnalysisContext> contextMap =
- new HashMap<PackageDescription, AnalysisContext>();
-
- /**
- * Initialize a newly created package manager.
- */
- PackageManager(this.resourceProvider);
-
- /**
- * Return the context in which the package at the given [packagePath] should
- * be analyzed when the given [packages] object is used to resolve package
- * names, the given [resolver] will be used to resolve 'dart:' URI's, and the
- * given [options] will control the analysis.
- */
- AnalysisContext getContext(String packagePath, Packages packages,
- DartUriResolver resolver, AnalysisOptions options) {
- DartSdk sdk = resolver.dartSdk;
- Map<String, List<Folder>> packageMap =
- new ContextBuilder(resourceProvider, null, null)
- .convertPackagesToMap(packages);
- PackageDescription description =
- new PackageDescription(_buildId(packagePath, packageMap), sdk, options);
- return contextMap.putIfAbsent(description, () {
- AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
- context.sourceFactory = new SourceFactory(<UriResolver>[
- resolver,
- new PackageMapUriResolver(resourceProvider, packageMap),
- new ResourceUriResolver(resourceProvider)
- ], packages, resourceProvider);
- context.analysisOptions = options;
- return context;
- });
- }
-
- /**
- * Return the id associated with the package at the given [packagePath] when
- * the given [packageMap] is used to resolve package names.
- */
- String _buildId(String packagePath, Map<String, List<Folder>> packageMap) {
- DependencyFinder finder = new DependencyFinder(resourceProvider);
- List<String> dependencies =
- finder.transitiveDependenciesFor(packageMap, packagePath);
- StringBuffer buffer = new StringBuffer();
- buffer.write(packagePath);
- for (String dependency in dependencies) {
- buffer.write(';');
- buffer.write(dependency);
- }
- return buffer.toString();
- }
-}
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index dcaf2a5..4598bdf 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -35,101 +35,71 @@
part 'parser_fasta.dart';
-/**
- * A simple data-holder for a method that needs to return multiple values.
- */
+/// Whether set literal parsing is currently enabled by default.
+/// TODO(paulberry): once we have a shared source of truth about this
+/// information, hook this constant up to it. (See phase 0 of
+/// https://github.com/dart-lang/language/issues/60)
+const bool enableSetLiteralsDefault = false;
+
+/// A simple data-holder for a method that needs to return multiple values.
class CommentAndMetadata {
- /**
- * The documentation comment that was parsed, or `null` if none was given.
- */
+ /// The documentation comment that was parsed, or `null` if none was given.
final Comment comment;
- /**
- * The metadata that was parsed, or `null` if none was given.
- */
+ /// The metadata that was parsed, or `null` if none was given.
final List<Annotation> metadata;
- /**
- * Initialize a newly created holder with the given [comment] and [metadata].
- */
+ /// Initialize a newly created holder with the given [comment] and [metadata].
CommentAndMetadata(this.comment, this.metadata);
- /**
- * Return `true` if some metadata was parsed.
- */
+ /// Return `true` if some metadata was parsed.
bool get hasMetadata => metadata != null && metadata.isNotEmpty;
}
-/**
- * A simple data-holder for a method that needs to return multiple values.
- */
+/// A simple data-holder for a method that needs to return multiple values.
class FinalConstVarOrType {
- /**
- * The 'final', 'const' or 'var' keyword, or `null` if none was given.
- */
+ /// The 'final', 'const' or 'var' keyword, or `null` if none was given.
final Token keyword;
- /**
- * The type, or `null` if no type was specified.
- */
+ /// The type, or `null` if no type was specified.
final TypeAnnotation type;
- /**
- * Initialize a newly created holder with the given [keyword] and [type].
- */
+ /// Initialize a newly created holder with the given [keyword] and [type].
FinalConstVarOrType(this.keyword, this.type);
}
-/**
- * A simple data-holder for a method that needs to return multiple values.
- */
+/// A simple data-holder for a method that needs to return multiple values.
class Modifiers {
- /**
- * The token representing the keyword 'abstract', or `null` if the keyword was
- * not found.
- */
+ /// The token representing the keyword 'abstract', or `null` if the keyword
+ /// was not found.
Token abstractKeyword;
- /**
- * The token representing the keyword 'const', or `null` if the keyword was
- * not found.
- */
+ /// The token representing the keyword 'const', or `null` if the keyword was
+ /// not found.
Token constKeyword;
- /**
- * The token representing the keyword 'covariant', or `null` if the keyword
- * was not found.
- */
+ /// The token representing the keyword 'covariant', or `null` if the keyword
+ /// was not found.
Token covariantKeyword;
- /**
- * The token representing the keyword 'external', or `null` if the keyword was
- * not found.
- */
+ /// The token representing the keyword 'external', or `null` if the keyword
+ /// was not found.
Token externalKeyword;
- /**
- * The token representing the keyword 'factory', or `null` if the keyword was
- * not found.
- */
+ /// The token representing the keyword 'factory', or `null` if the keyword was
+ /// not found.
Token factoryKeyword;
- /**
- * The token representing the keyword 'final', or `null` if the keyword was
- * not found.
- */
+ /// The token representing the keyword 'final', or `null` if the keyword was
+ /// not found.
Token finalKeyword;
- /**
- * The token representing the keyword 'static', or `null` if the keyword was
- * not found.
- */
+ /// The token representing the keyword 'static', or `null` if the keyword was
+ /// not found.
Token staticKeyword;
- /**
- * The token representing the keyword 'var', or `null` if the keyword was not
- * found.
- */
+ /// The token representing the keyword 'var', or `null` if the keyword was not
+ /// found.
Token varKeyword;
@override
@@ -145,11 +115,9 @@
return buffer.toString();
}
- /**
- * If the given [keyword] is not `null`, append it to the given [builder],
- * prefixing it with a space if [needsSpace] is `true`. Return `true` if
- * subsequent keywords need to be prefixed with a space.
- */
+ /// If the given [keyword] is not `null`, append it to the given [builder],
+ /// prefixing it with a space if [needsSpace] is `true`. Return `true` if
+ /// subsequent keywords need to be prefixed with a space.
bool _appendKeyword(StringBuffer buffer, bool needsSpace, Token keyword) {
if (keyword != null) {
if (needsSpace) {
@@ -162,9 +130,7 @@
}
}
-/**
- * A parser used to parse tokens into an AST structure.
- */
+/// A parser used to parse tokens into an AST structure.
class Parser {
static String ASYNC = Keyword.ASYNC.lexeme;
@@ -180,91 +146,61 @@
static const int _MAX_TREE_DEPTH = 300;
- /**
- * A flag indicating whether the analyzer [Parser] factory method
- * will return a fasta based parser or an analyzer based parser.
- */
+ /// A flag indicating whether the analyzer [Parser] factory method
+ /// will return a fasta based parser or an analyzer based parser.
static const bool useFasta =
const bool.fromEnvironment("useFastaParser", defaultValue: true);
- /**
- * The source being parsed.
- */
+ /// The source being parsed.
final Source _source;
- /**
- * The error listener that will be informed of any errors that are found
- * during the parse.
- */
+ /// The error listener that will be informed of any errors that are found
+ /// during the parse.
final AnalysisErrorListener _errorListener;
- /**
- * An [_errorListener] lock, if more than `0`, then errors are not reported.
- */
+ /// An [_errorListener] lock, if more than `0`, then errors are not reported.
int _errorListenerLock = 0;
- /**
- * A flag indicating whether the parser should parse instance creation
- * expressions that lack either the `new` or `const` keyword.
- */
+ /// A flag indicating whether the parser should parse instance creation
+ /// expressions that lack either the `new` or `const` keyword.
bool _enableOptionalNewAndConst = true;
- /**
- * A flag indicating whether parser is to parse function bodies.
- */
+ /// A flag indicating whether parser is to parse function bodies.
bool _parseFunctionBodies = true;
- /**
- * The next token to be parsed.
- */
+ /// The next token to be parsed.
Token _currentToken;
- /**
- * The depth of the current AST. When this depth is too high, so we're at the
- * risk of overflowing the stack, we stop parsing and report an error.
- */
+ /// The depth of the current AST. When this depth is too high, so we're at the
+ /// risk of overflowing the stack, we stop parsing and report an error.
int _treeDepth = 0;
- /**
- * A flag indicating whether the parser is currently in a function body marked
- * as being 'async'.
- */
+ /// A flag indicating whether the parser is currently in a function body
+ /// marked as being 'async'.
bool _inAsync = false;
- /**
- * A flag indicating whether the parser is currently in a function body marked
- * (by a star) as being a generator.
- */
+ /// A flag indicating whether the parser is currently in a function body
+ /// marked(by a star) as being a generator.
bool _inGenerator = false;
- /**
- * A flag indicating whether the parser is currently in the body of a loop.
- */
+ /// A flag indicating whether the parser is currently in the body of a loop.
bool _inLoop = false;
- /**
- * A flag indicating whether the parser is currently in a switch statement.
- */
+ /// A flag indicating whether the parser is currently in a switch statement.
bool _inSwitch = false;
- /**
- * A flag indicating whether the parser is currently in a constructor field
- * initializer, with no intervening parentheses, braces, or brackets.
- */
+ /// A flag indicating whether the parser is currently in a constructor field
+ /// initializer, with no intervening parentheses, braces, or brackets.
bool _inInitializer = false;
- /**
- * A flag indicating whether the parser is to parse generic method syntax.
- */
+ /// A flag indicating whether the parser is to parse generic method syntax.
@deprecated
bool parseGenericMethods = false;
bool allowNativeClause;
- /**
- * Initialize a newly created parser to parse tokens in the given [_source]
- * and to report any errors that are found to the given [_errorListener].
- */
+ /// Initialize a newly created parser to parse tokens in the given [_source]
+ /// and to report any errors that are found to the given [_errorListener].
factory Parser(Source source, AnalysisErrorListener errorListener,
{bool useFasta}) {
if (useFasta ?? Parser.useFasta) {
@@ -276,65 +212,55 @@
Parser.withoutFasta(this._source, this._errorListener);
- /**
- * Return the current token.
- */
+ /// Return the current token.
Token get currentToken => _currentToken;
- /**
- * Set the token with which the parse is to begin to the given [token].
- */
+ /// Set the token with which the parse is to begin to the given [token].
void set currentToken(Token token) {
this._currentToken = token;
}
- /**
- * Return `true` if the parser is to parse asserts in the initializer list of
- * a constructor.
- */
+ /// Return `true` if the parser is to parse asserts in the initializer list of
+ /// a constructor.
@deprecated
bool get enableAssertInitializer => true;
- /**
- * Set whether the parser is to parse asserts in the initializer list of a
- * constructor to match the given [enable] flag.
- */
+ /// Set whether the parser is to parse asserts in the initializer list of a
+ /// constructor to match the given [enable] flag.
@deprecated
void set enableAssertInitializer(bool enable) {}
- /**
- * Return `true` if the parser should parse instance creation expressions that
- * lack either the `new` or `const` keyword.
- */
+ /// Return `true` if the parser should parse instance creation expressions
+ /// that lack either the `new` or `const` keyword.
bool get enableOptionalNewAndConst => _enableOptionalNewAndConst;
- /**
- * Set whether the parser should parse instance creation expressions that lack
- * either the `new` or `const` keyword.
- */
+ /// Set whether the parser should parse instance creation expressions that
+ /// lack either the `new` or `const` keyword.
void set enableOptionalNewAndConst(bool enable) {
_enableOptionalNewAndConst = enable;
}
- /**
- * Return `true` if the parser is to allow URI's in part-of directives.
- */
+ /// Enables or disables parsing of set literals.
+ void set enableSetLiterals(bool value) {
+ if (value) {
+ throw new UnimplementedError(
+ 'set-literal experiment not supported by analyzer parser');
+ }
+ }
+
+ /// Return `true` if the parser is to allow URI's in part-of directives.
@deprecated
bool get enableUriInPartOf => true;
- /**
- * Set whether the parser is to allow URI's in part-of directives to the given
- * [enable] flag.
- */
+ /// Set whether the parser is to allow URI's in part-of directives to the
+ /// given [enable] flag.
@deprecated
void set enableUriInPartOf(bool enable) {}
- /**
- * Return `true` if the current token is the first token of a return type that
- * is followed by an identifier, possibly followed by a list of type
- * parameters, followed by a left-parenthesis. This is used by
- * [parseTypeAlias] to determine whether or not to parse a return type.
- */
+ /// Return `true` if the current token is the first token of a return type
+ /// that is followed by an identifier, possibly followed by a list of type
+ /// parameters, followed by a left-parenthesis. This is used by
+ /// [parseTypeAlias] to determine whether or not to parse a return type.
bool get hasReturnTypeInTypeAlias {
// TODO(brianwilkerson) This is too expensive as implemented and needs to be
// re-implemented or removed.
@@ -345,11 +271,9 @@
return _tokenMatchesIdentifier(next);
}
- /**
- * Set whether the parser is to parse the async support.
- *
- * Support for removing the 'async' library has been removed.
- */
+ /// Set whether the parser is to parse the async support.
+ ///
+ /// Support for removing the 'async' library has been removed.
@deprecated
void set parseAsync(bool parseAsync) {}
@@ -359,19 +283,15 @@
@deprecated
void set parseConditionalDirectives(bool value) {}
- /**
- * Set whether parser is to parse function bodies.
- */
+ /// Set whether parser is to parse function bodies.
void set parseFunctionBodies(bool parseFunctionBodies) {
this._parseFunctionBodies = parseFunctionBodies;
}
- /**
- * Return the content of a string with the given literal representation. The
- * [lexeme] is the literal representation of the string. The flag [isFirst] is
- * `true` if this is the first token in a string literal. The flag [isLast] is
- * `true` if this is the last token in a string literal.
- */
+ /// Return the content of a string with the given literal representation. The
+ /// [lexeme] is the literal representation of the string. The flag [isFirst]
+ /// is `true` if this is the first token in a string literal. The flag
+ /// [isLast] is `true` if this is the last token in a string literal.
String computeStringValue(String lexeme, bool isFirst, bool isLast) {
StringLexemeHelper helper = new StringLexemeHelper(lexeme, isFirst, isLast);
int start = helper.start;
@@ -394,9 +314,7 @@
return buffer.toString();
}
- /**
- * Return a synthetic identifier.
- */
+ /// Return a synthetic identifier.
SimpleIdentifier createSyntheticIdentifier({bool isDeclaration: false}) {
Token syntheticToken;
if (_currentToken.type.isKeyword) {
@@ -414,26 +332,21 @@
isDeclaration: isDeclaration);
}
- /**
- * Return a synthetic string literal.
- */
+ /// Return a synthetic string literal.
SimpleStringLiteral createSyntheticStringLiteral() => astFactory
.simpleStringLiteral(_createSyntheticToken(TokenType.STRING), "");
- /**
- * Advance to the next token in the token stream, making it the new current
- * token and return the token that was current before this method was invoked.
- */
+ /// Advance to the next token in the token stream, making it the new current
+ /// token and return the token that was current before this method was
+ /// invoked.
Token getAndAdvance() {
Token token = _currentToken;
_currentToken = _currentToken.next;
return token;
}
- /**
- * Return `true` if the current token appears to be the beginning of a
- * function declaration.
- */
+ /// Return `true` if the current token appears to be the beginning of a
+ /// function declaration.
bool isFunctionDeclaration() {
Keyword keyword = _currentToken.keyword;
Token afterReturnType = skipTypeWithoutFunction(_currentToken);
@@ -478,10 +391,8 @@
return false;
}
- /**
- * Return `true` if the given [token] appears to be the beginning of a
- * function expression.
- */
+ /// Return `true` if the given [token] appears to be the beginning of a
+ /// function expression.
bool isFunctionExpression(Token token) {
// Function expressions aren't allowed in initializer lists.
if (_inInitializer) {
@@ -503,30 +414,28 @@
return lexeme == ASYNC || lexeme == SYNC;
}
- /**
- * Return `true` if the current token is the first token in an initialized
- * variable declaration rather than an expression. This method assumes that we
- * have already skipped past any metadata that might be associated with the
- * declaration.
- *
- * initializedVariableDeclaration ::=
- * declaredIdentifier ('=' expression)? (',' initializedIdentifier)*
- *
- * declaredIdentifier ::=
- * metadata finalConstVarOrType identifier
- *
- * finalConstVarOrType ::=
- * 'final' type?
- * | 'const' type?
- * | 'var'
- * | type
- *
- * type ::=
- * qualified typeArguments?
- *
- * initializedIdentifier ::=
- * identifier ('=' expression)?
- */
+ /// Return `true` if the current token is the first token in an initialized
+ /// variable declaration rather than an expression. This method assumes that
+ /// we have already skipped past any metadata that might be associated with
+ /// the declaration.
+ ///
+ /// initializedVariableDeclaration ::=
+ /// declaredIdentifier ('=' expression)? (',' initializedIdentifier)*
+ ///
+ /// declaredIdentifier ::=
+ /// metadata finalConstVarOrType identifier
+ ///
+ /// finalConstVarOrType ::=
+ /// 'final' type?
+ /// | 'const' type?
+ /// | 'var'
+ /// | type
+ ///
+ /// type ::=
+ /// qualified typeArguments?
+ ///
+ /// initializedIdentifier ::=
+ /// identifier ('=' expression)?
bool isInitializedVariableDeclaration() {
Keyword keyword = _currentToken.keyword;
if (keyword == Keyword.FINAL ||
@@ -601,10 +510,8 @@
return false;
}
- /**
- * Return `true` if the current token appears to be the beginning of a switch
- * member.
- */
+ /// Return `true` if the current token appears to be the beginning of a switch
+ /// member.
bool isSwitchMember() {
Token token = _currentToken;
while (_tokenMatches(token, TokenType.IDENTIFIER) &&
@@ -615,14 +522,12 @@
return keyword == Keyword.CASE || keyword == Keyword.DEFAULT;
}
- /**
- * Parse an additive expression. Return the additive expression that was
- * parsed.
- *
- * additiveExpression ::=
- * multiplicativeExpression (additiveOperator multiplicativeExpression)*
- * | 'super' (additiveOperator multiplicativeExpression)+
- */
+ /// Parse an additive expression. Return the additive expression that was
+ /// parsed.
+ ///
+ /// additiveExpression ::=
+ /// multiplicativeExpression (additiveOperator multiplicativeExpression)*
+ /// | 'super' (additiveOperator multiplicativeExpression)+
Expression parseAdditiveExpression() {
Expression expression;
if (_currentToken.keyword == Keyword.SUPER &&
@@ -638,14 +543,12 @@
return expression;
}
- /**
- * Parse an annotation. Return the annotation that was parsed.
- *
- * This method assumes that the current token matches [TokenType.AT].
- *
- * annotation ::=
- * '@' qualified ('.' identifier)? arguments?
- */
+ /// Parse an annotation. Return the annotation that was parsed.
+ ///
+ /// This method assumes that the current token matches [TokenType.AT].
+ ///
+ /// annotation ::=
+ /// '@' qualified ('.' identifier)? arguments?
Annotation parseAnnotation() {
Token atSign = getAndAdvance();
Identifier name = parsePrefixedIdentifier();
@@ -663,16 +566,14 @@
atSign, name, period, constructorName, arguments);
}
- /**
- * Parse an argument. Return the argument that was parsed.
- *
- * argument ::=
- * namedArgument
- * | expression
- *
- * namedArgument ::=
- * label expression
- */
+ /// Parse an argument. Return the argument that was parsed.
+ ///
+ /// argument ::=
+ /// namedArgument
+ /// | expression
+ ///
+ /// namedArgument ::=
+ /// label expression
Expression parseArgument() {
// TODO(brianwilkerson) Consider returning a wrapper indicating whether the
// expression is a named expression in order to remove the 'is' check in
@@ -688,29 +589,25 @@
}
}
- /**
- * Parse a list of arguments. Return the argument list that was parsed.
- *
- * This method assumes that the current token matches [TokenType.OPEN_PAREN].
- *
- * arguments ::=
- * '(' argumentList? ')'
- *
- * argumentList ::=
- * namedArgument (',' namedArgument)*
- * | expressionList (',' namedArgument)*
- */
+ /// Parse a list of arguments. Return the argument list that was parsed.
+ ///
+ /// This method assumes that the current token matches [TokenType.OPEN_PAREN].
+ ///
+ /// arguments ::=
+ /// '(' argumentList? ')'
+ ///
+ /// argumentList ::=
+ /// namedArgument (',' namedArgument)*
+ /// | expressionList (',' namedArgument)*
ArgumentList parseArgumentList() {
Token leftParenthesis = getAndAdvance();
if (_matches(TokenType.CLOSE_PAREN)) {
return astFactory.argumentList(leftParenthesis, null, getAndAdvance());
}
- /**
- * Return `true` if the parser appears to be at the beginning of an argument
- * even though there was no comma. This is a special case of the more
- * general recovery technique described below.
- */
+ /// Return `true` if the parser appears to be at the beginning of an
+ /// argument even though there was no comma. This is a special case of the
+ /// more general recovery technique described below.
bool isLikelyMissingComma() {
if (_matchesIdentifier() &&
_tokenMatches(_currentToken.next, TokenType.COLON) &&
@@ -770,14 +667,12 @@
}
}
- /**
- * Parse an assert statement. Return the assert statement.
- *
- * This method assumes that the current token matches `Keyword.ASSERT`.
- *
- * assertStatement ::=
- * 'assert' '(' expression [',' expression] ')' ';'
- */
+ /// Parse an assert statement. Return the assert statement.
+ ///
+ /// This method assumes that the current token matches `Keyword.ASSERT`.
+ ///
+ /// assertStatement ::=
+ /// 'assert' '(' expression [',' expression] ')' ';'
AssertStatement parseAssertStatement() {
Token keyword = getAndAdvance();
Token leftParen = _expect(TokenType.OPEN_PAREN);
@@ -803,16 +698,14 @@
keyword, leftParen, expression, comma, message, rightParen, semicolon);
}
- /**
- * Parse an assignable expression. The [primaryAllowed] is `true` if the
- * expression is allowed to be a primary without any assignable selector.
- * Return the assignable expression that was parsed.
- *
- * assignableExpression ::=
- * primary (arguments* assignableSelector)+
- * | 'super' unconditionalAssignableSelector
- * | identifier
- */
+ /// Parse an assignable expression. The [primaryAllowed] is `true` if the
+ /// expression is allowed to be a primary without any assignable selector.
+ /// Return the assignable expression that was parsed.
+ ///
+ /// assignableExpression ::=
+ /// primary (arguments* assignableSelector)+
+ /// | 'super' unconditionalAssignableSelector
+ /// | identifier
Expression parseAssignableExpression(bool primaryAllowed) {
//
// A primary expression can start with an identifier. We resolve the
@@ -862,21 +755,19 @@
}
}
- /**
- * Parse an assignable selector. The [prefix] is the expression preceding the
- * selector. The [optional] is `true` if the selector is optional. Return the
- * assignable selector that was parsed, or the original prefix if there was no
- * assignable selector. If [allowConditional] is false, then the '?.'
- * operator will still be parsed, but a parse error will be generated.
- *
- * unconditionalAssignableSelector ::=
- * '[' expression ']'
- * | '.' identifier
- *
- * assignableSelector ::=
- * unconditionalAssignableSelector
- * | '?.' identifier
- */
+ /// Parse an assignable selector. The [prefix] is the expression preceding the
+ /// selector. The [optional] is `true` if the selector is optional. Return the
+ /// assignable selector that was parsed, or the original prefix if there was
+ /// no assignable selector. If [allowConditional] is false, then the '?.'
+ /// operator will still be parsed, but a parse error will be generated.
+ ///
+ /// unconditionalAssignableSelector ::=
+ /// '[' expression ']'
+ /// | '.' identifier
+ ///
+ /// assignableSelector ::=
+ /// unconditionalAssignableSelector
+ /// | '?.' identifier
Expression parseAssignableSelector(Expression prefix, bool optional,
{bool allowConditional: true}) {
TokenType type = _currentToken.type;
@@ -921,28 +812,24 @@
}
}
- /**
- * Parse a await expression. Return the await expression that was parsed.
- *
- * This method assumes that the current token matches `_AWAIT`.
- *
- * awaitExpression ::=
- * 'await' unaryExpression
- */
+ /// Parse a await expression. Return the await expression that was parsed.
+ ///
+ /// This method assumes that the current token matches `_AWAIT`.
+ ///
+ /// awaitExpression ::=
+ /// 'await' unaryExpression
AwaitExpression parseAwaitExpression() {
Token awaitToken = getAndAdvance();
Expression expression = parseUnaryExpression();
return astFactory.awaitExpression(awaitToken, expression);
}
- /**
- * Parse a bitwise and expression. Return the bitwise and expression that was
- * parsed.
- *
- * bitwiseAndExpression ::=
- * shiftExpression ('&' shiftExpression)*
- * | 'super' ('&' shiftExpression)+
- */
+ /// Parse a bitwise and expression. Return the bitwise and expression that was
+ /// parsed.
+ ///
+ /// bitwiseAndExpression ::=
+ /// shiftExpression ('&' shiftExpression)*
+ /// | 'super' ('&' shiftExpression)+
Expression parseBitwiseAndExpression() {
Expression expression;
if (_currentToken.keyword == Keyword.SUPER &&
@@ -958,14 +845,12 @@
return expression;
}
- /**
- * Parse a bitwise or expression. Return the bitwise or expression that was
- * parsed.
- *
- * bitwiseOrExpression ::=
- * bitwiseXorExpression ('|' bitwiseXorExpression)*
- * | 'super' ('|' bitwiseXorExpression)+
- */
+ /// Parse a bitwise or expression. Return the bitwise or expression that was
+ /// parsed.
+ ///
+ /// bitwiseOrExpression ::=
+ /// bitwiseXorExpression ('|' bitwiseXorExpression)*
+ /// | 'super' ('|' bitwiseXorExpression)+
Expression parseBitwiseOrExpression() {
Expression expression;
if (_currentToken.keyword == Keyword.SUPER &&
@@ -981,14 +866,12 @@
return expression;
}
- /**
- * Parse a bitwise exclusive-or expression. Return the bitwise exclusive-or
- * expression that was parsed.
- *
- * bitwiseXorExpression ::=
- * bitwiseAndExpression ('^' bitwiseAndExpression)*
- * | 'super' ('^' bitwiseAndExpression)+
- */
+ /// Parse a bitwise exclusive-or expression. Return the bitwise exclusive-or
+ /// expression that was parsed.
+ ///
+ /// bitwiseXorExpression ::=
+ /// bitwiseAndExpression ('^' bitwiseAndExpression)*
+ /// | 'super' ('^' bitwiseAndExpression)+
Expression parseBitwiseXorExpression() {
Expression expression;
if (_currentToken.keyword == Keyword.SUPER &&
@@ -1004,15 +887,13 @@
return expression;
}
- /**
- * Parse a block. Return the block that was parsed.
- *
- * This method assumes that the current token matches
- * [TokenType.OPEN_CURLY_BRACKET].
- *
- * block ::=
- * '{' statements '}'
- */
+ /// Parse a block. Return the block that was parsed.
+ ///
+ /// This method assumes that the current token matches
+ /// [TokenType.OPEN_CURLY_BRACKET].
+ ///
+ /// block ::=
+ /// '{' statements '}'
Block parseBlock() {
bool isEndOfBlock() {
TokenType type = _currentToken.type;
@@ -1042,14 +923,12 @@
return astFactory.block(leftBracket, statements, rightBracket);
}
- /**
- * Parse a break statement. Return the break statement that was parsed.
- *
- * This method assumes that the current token matches `Keyword.BREAK`.
- *
- * breakStatement ::=
- * 'break' identifier? ';'
- */
+ /// Parse a break statement. Return the break statement that was parsed.
+ ///
+ /// This method assumes that the current token matches `Keyword.BREAK`.
+ ///
+ /// breakStatement ::=
+ /// 'break' identifier? ';'
Statement parseBreakStatement() {
Token breakKeyword = getAndAdvance();
SimpleIdentifier label = null;
@@ -1063,24 +942,22 @@
return astFactory.breakStatement(breakKeyword, label, semicolon);
}
- /**
- * Parse a cascade section. Return the expression representing the cascaded
- * method invocation.
- *
- * This method assumes that the current token matches
- * `TokenType.PERIOD_PERIOD`.
- *
- * cascadeSection ::=
- * '..' (cascadeSelector typeArguments? arguments*)
- * (assignableSelector typeArguments? arguments*)* cascadeAssignment?
- *
- * cascadeSelector ::=
- * '[' expression ']'
- * | identifier
- *
- * cascadeAssignment ::=
- * assignmentOperator expressionWithoutCascade
- */
+ /// Parse a cascade section. Return the expression representing the cascaded
+ /// method invocation.
+ ///
+ /// This method assumes that the current token matches
+ /// `TokenType.PERIOD_PERIOD`.
+ ///
+ /// cascadeSection ::=
+ /// '..' (cascadeSelector typeArguments? arguments*)
+ /// (assignableSelector typeArguments? arguments*)* cascadeAssignment?
+ ///
+ /// cascadeSelector ::=
+ /// '[' expression ']'
+ /// | identifier
+ ///
+ /// cascadeAssignment ::=
+ /// assignmentOperator expressionWithoutCascade
Expression parseCascadeSection() {
Token period = getAndAdvance();
Expression expression = null;
@@ -1162,18 +1039,16 @@
return expression;
}
- /**
- * Parse a class declaration. The [commentAndMetadata] is the metadata to be
- * associated with the member. The [abstractKeyword] is the token for the
- * keyword 'abstract', or `null` if the keyword was not given. Return the
- * class declaration that was parsed.
- *
- * This method assumes that the current token matches `Keyword.CLASS`.
- *
- * classDeclaration ::=
- * metadata 'abstract'? 'class' name typeParameterList? (extendsClause withClause?)? implementsClause? '{' classMembers '}' |
- * metadata 'abstract'? 'class' mixinApplicationClass
- */
+ /// Parse a class declaration. The [commentAndMetadata] is the metadata to be
+ /// associated with the member. The [abstractKeyword] is the token for the
+ /// keyword 'abstract', or `null` if the keyword was not given. Return the
+ /// class declaration that was parsed.
+ ///
+ /// This method assumes that the current token matches `Keyword.CLASS`.
+ ///
+ /// classDeclaration ::=
+ /// metadata 'abstract'? 'class' name typeParameterList? (extendsClause withClause?)? implementsClause? '{' classMembers '}' |
+ /// metadata 'abstract'? 'class' mixinApplicationClass
CompilationUnitMember parseClassDeclaration(
CommentAndMetadata commentAndMetadata, Token abstractKeyword) {
//
@@ -1292,15 +1167,13 @@
return classDeclaration;
}
- /**
- * Parse a class member. The [className] is the name of the class containing
- * the member being parsed. Return the class member that was parsed, or `null`
- * if what was found was not a valid class member.
- *
- * classMemberDefinition ::=
- * declaration ';'
- * | methodSignature functionBody
- */
+ /// Parse a class member. The [className] is the name of the class containing
+ /// the member being parsed. Return the class member that was parsed, or
+ /// `null` if what was found was not a valid class member.
+ ///
+ /// classMemberDefinition ::=
+ /// declaration ';'
+ /// | methodSignature functionBody
ClassMember parseClassMember(String className) {
CommentAndMetadata commentAndMetadata = parseCommentAndMetadata();
Modifiers modifiers = parseModifiers();
@@ -1648,14 +1521,12 @@
type);
}
- /**
- * Parse a single combinator. Return the combinator that was parsed, or `null`
- * if no combinator is found.
- *
- * combinator ::=
- * 'show' identifier (',' identifier)*
- * | 'hide' identifier (',' identifier)*
- */
+ /// Parse a single combinator. Return the combinator that was parsed, or
+ /// `null` if no combinator is found.
+ ///
+ /// combinator ::=
+ /// 'show' identifier (',' identifier)*
+ /// | 'hide' identifier (',' identifier)*
Combinator parseCombinator() {
if (_matchesKeyword(Keyword.SHOW)) {
return astFactory.showCombinator(getAndAdvance(), parseIdentifierList());
@@ -1665,14 +1536,12 @@
return null;
}
- /**
- * Parse a list of combinators in a directive. Return the combinators that
- * were parsed, or `null` if there are no combinators.
- *
- * combinator ::=
- * 'show' identifier (',' identifier)*
- * | 'hide' identifier (',' identifier)*
- */
+ /// Parse a list of combinators in a directive. Return the combinators that
+ /// were parsed, or `null` if there are no combinators.
+ ///
+ /// combinator ::=
+ /// 'show' identifier (',' identifier)*
+ /// | 'hide' identifier (',' identifier)*
List<Combinator> parseCombinators() {
List<Combinator> combinators = null;
while (true) {
@@ -1686,16 +1555,14 @@
return combinators;
}
- /**
- * Parse the documentation comment and metadata preceding a declaration. This
- * method allows any number of documentation comments to occur before, after
- * or between the metadata, but only returns the last (right-most)
- * documentation comment that is found. Return the documentation comment and
- * metadata that were parsed.
- *
- * metadata ::=
- * annotation*
- */
+ /// Parse the documentation comment and metadata preceding a declaration. This
+ /// method allows any number of documentation comments to occur before, after
+ /// or between the metadata, but only returns the last (right-most)
+ /// documentation comment that is found. Return the documentation comment and
+ /// metadata that were parsed.
+ ///
+ /// metadata ::=
+ /// annotation*
CommentAndMetadata parseCommentAndMetadata() {
// TODO(brianwilkerson) Consider making the creation of documentation
// comments be lazy.
@@ -1713,16 +1580,14 @@
return new CommentAndMetadata(parseDocumentationComment(tokens), metadata);
}
- /**
- * Parse a comment reference from the source between square brackets. The
- * [referenceSource] is the source occurring between the square brackets
- * within a documentation comment. The [sourceOffset] is the offset of the
- * first character of the reference source. Return the comment reference that
- * was parsed, or `null` if no reference could be found.
- *
- * commentReference ::=
- * 'new'? prefixedIdentifier
- */
+ /// Parse a comment reference from the source between square brackets. The
+ /// [referenceSource] is the source occurring between the square brackets
+ /// within a documentation comment. The [sourceOffset] is the offset of the
+ /// first character of the reference source. Return the comment reference that
+ /// was parsed, or `null` if no reference could be found.
+ ///
+ /// commentReference ::=
+ /// 'new'? prefixedIdentifier
CommentReference parseCommentReference(
String referenceSource, int sourceOffset) {
// TODO(brianwilkerson) The errors are not getting the right offset/length
@@ -1822,18 +1687,16 @@
return null;
}
- /**
- * Parse all of the comment references occurring in the given array of
- * documentation comments. The [tokens] are the comment tokens representing
- * the documentation comments to be parsed. Return the comment references that
- * were parsed.
- *
- * commentReference ::=
- * '[' 'new'? qualified ']' libraryReference?
- *
- * libraryReference ::=
- * '(' stringLiteral ')'
- */
+ /// Parse all of the comment references occurring in the given array of
+ /// documentation comments. The [tokens] are the comment tokens representing
+ /// the documentation comments to be parsed. Return the comment references
+ /// that were parsed.
+ ///
+ /// commentReference ::=
+ /// '[' 'new'? qualified ']' libraryReference?
+ ///
+ /// libraryReference ::=
+ /// '(' stringLiteral ')'
List<CommentReference> parseCommentReferences(
List<DocumentationCommentToken> tokens) {
List<CommentReference> references = <CommentReference>[];
@@ -1904,32 +1767,28 @@
return references;
}
- /**
- * Parse a compilation unit, starting with the given [token]. Return the
- * compilation unit that was parsed.
- */
+ /// Parse a compilation unit, starting with the given [token]. Return the
+ /// compilation unit that was parsed.
CompilationUnit parseCompilationUnit(Token token) {
_currentToken = token;
return parseCompilationUnit2();
}
- /**
- * Parse a compilation unit. Return the compilation unit that was parsed.
- *
- * Specified:
- *
- * compilationUnit ::=
- * scriptTag? directive* topLevelDeclaration*
- *
- * Actual:
- *
- * compilationUnit ::=
- * scriptTag? topLevelElement*
- *
- * topLevelElement ::=
- * directive
- * | topLevelDeclaration
- */
+ /// Parse a compilation unit. Return the compilation unit that was parsed.
+ ///
+ /// Specified:
+ ///
+ /// compilationUnit ::=
+ /// scriptTag? directive* topLevelDeclaration*
+ ///
+ /// Actual:
+ ///
+ /// compilationUnit ::=
+ /// scriptTag? topLevelElement*
+ ///
+ /// topLevelElement ::=
+ /// directive
+ /// | topLevelDeclaration
CompilationUnit parseCompilationUnit2() {
Token firstToken = _currentToken;
ScriptTag scriptTag = null;
@@ -2075,23 +1934,21 @@
firstToken, scriptTag, directives, declarations, _currentToken);
}
- /**
- * Parse a compilation unit member. The [commentAndMetadata] is the metadata
- * to be associated with the member. Return the compilation unit member that
- * was parsed, or `null` if what was parsed could not be represented as a
- * compilation unit member.
- *
- * compilationUnitMember ::=
- * classDefinition
- * | functionTypeAlias
- * | external functionSignature
- * | external getterSignature
- * | external setterSignature
- * | functionSignature functionBody
- * | returnType? getOrSet identifier formalParameterList functionBody
- * | (final | const) type? staticFinalDeclarationList ';'
- * | variableDeclaration ';'
- */
+ /// Parse a compilation unit member. The [commentAndMetadata] is the metadata
+ /// to be associated with the member. Return the compilation unit member that
+ /// was parsed, or `null` if what was parsed could not be represented as a
+ /// compilation unit member.
+ ///
+ /// compilationUnitMember ::=
+ /// classDefinition
+ /// | functionTypeAlias
+ /// | external functionSignature
+ /// | external getterSignature
+ /// | external setterSignature
+ /// | functionSignature functionBody
+ /// | returnType? getOrSet identifier formalParameterList functionBody
+ /// | (final | const) type? staticFinalDeclarationList ';'
+ /// | variableDeclaration ';'
CompilationUnitMember parseCompilationUnitMember(
CommentAndMetadata commentAndMetadata) {
Modifiers modifiers = parseModifiers();
@@ -2290,13 +2147,11 @@
_expect(TokenType.SEMICOLON));
}
- /**
- * Parse a conditional expression. Return the conditional expression that was
- * parsed.
- *
- * conditionalExpression ::=
- * ifNullExpression ('?' expressionWithoutCascade ':' expressionWithoutCascade)?
- */
+ /// Parse a conditional expression. Return the conditional expression that was
+ /// parsed.
+ ///
+ /// conditionalExpression ::=
+ /// ifNullExpression ('?' expressionWithoutCascade ':' expressionWithoutCascade)?
Expression parseConditionalExpression() {
Expression condition = parseIfNullExpression();
if (_currentToken.type != TokenType.QUESTION) {
@@ -2310,20 +2165,18 @@
condition, question, thenExpression, colon, elseExpression);
}
- /**
- * Parse a configuration in either an import or export directive.
- *
- * This method assumes that the current token matches `Keyword.IF`.
- *
- * configuration ::=
- * 'if' '(' test ')' uri
- *
- * test ::=
- * dottedName ('==' stringLiteral)?
- *
- * dottedName ::=
- * identifier ('.' identifier)*
- */
+ /// Parse a configuration in either an import or export directive.
+ ///
+ /// This method assumes that the current token matches `Keyword.IF`.
+ ///
+ /// configuration ::=
+ /// 'if' '(' test ')' uri
+ ///
+ /// test ::=
+ /// dottedName ('==' stringLiteral)?
+ ///
+ /// dottedName ::=
+ /// identifier ('.' identifier)*
Configuration parseConfiguration() {
Token ifKeyword = getAndAdvance();
Token leftParenthesis = _expect(TokenType.OPEN_PAREN);
@@ -2344,16 +2197,14 @@
equalToken, value, rightParenthesis, libraryUri);
}
- /**
- * Parse a const expression. Return the const expression that was parsed.
- *
- * This method assumes that the current token matches `Keyword.CONST`.
- *
- * constExpression ::=
- * instanceCreationExpression
- * | listLiteral
- * | mapLiteral
- */
+ /// Parse a const expression. Return the const expression that was parsed.
+ ///
+ /// This method assumes that the current token matches `Keyword.CONST`.
+ ///
+ /// constExpression ::=
+ /// instanceCreationExpression
+ /// | listLiteral
+ /// | mapLiteral
Expression parseConstExpression() {
Token keyword = getAndAdvance();
TokenType type = _currentToken.type;
@@ -2368,14 +2219,12 @@
return parseInstanceCreationExpression(keyword);
}
- /**
- * Parse a field initializer within a constructor. The flag [hasThis] should
- * be true if the current token is `this`. Return the field initializer that
- * was parsed.
- *
- * fieldInitializer:
- * ('this' '.')? identifier '=' conditionalExpression cascadeSection*
- */
+ /// Parse a field initializer within a constructor. The flag [hasThis] should
+ /// be true if the current token is `this`. Return the field initializer that
+ /// was parsed.
+ ///
+ /// fieldInitializer:
+ /// ('this' '.')? identifier '=' conditionalExpression cascadeSection*
ConstructorFieldInitializer parseConstructorFieldInitializer(bool hasThis) {
Token keywordToken = null;
Token period = null;
@@ -2427,13 +2276,11 @@
}
}
- /**
- * Parse the name of a constructor. Return the constructor name that was
- * parsed.
- *
- * constructorName:
- * type ('.' identifier)?
- */
+ /// Parse the name of a constructor. Return the constructor name that was
+ /// parsed.
+ ///
+ /// constructorName:
+ /// type ('.' identifier)?
ConstructorName parseConstructorName() {
TypeName type = parseTypeName(false);
Token period = null;
@@ -2445,14 +2292,12 @@
return astFactory.constructorName(type, period, name);
}
- /**
- * Parse a continue statement. Return the continue statement that was parsed.
- *
- * This method assumes that the current token matches `Keyword.CONTINUE`.
- *
- * continueStatement ::=
- * 'continue' identifier? ';'
- */
+ /// Parse a continue statement. Return the continue statement that was parsed.
+ ///
+ /// This method assumes that the current token matches `Keyword.CONTINUE`.
+ ///
+ /// continueStatement ::=
+ /// 'continue' identifier? ';'
Statement parseContinueStatement() {
Token continueKeyword = getAndAdvance();
if (!_inLoop && !_inSwitch) {
@@ -2471,16 +2316,14 @@
return astFactory.continueStatement(continueKeyword, label, semicolon);
}
- /**
- * Parse a directive. The [commentAndMetadata] is the metadata to be
- * associated with the directive. Return the directive that was parsed.
- *
- * directive ::=
- * exportDirective
- * | libraryDirective
- * | importDirective
- * | partDirective
- */
+ /// Parse a directive. The [commentAndMetadata] is the metadata to be
+ /// associated with the directive. Return the directive that was parsed.
+ ///
+ /// directive ::=
+ /// exportDirective
+ /// | libraryDirective
+ /// | importDirective
+ /// | partDirective
Directive parseDirective(CommentAndMetadata commentAndMetadata) {
if (_matchesKeyword(Keyword.IMPORT)) {
return parseImportDirective(commentAndMetadata);
@@ -2498,25 +2341,21 @@
}
}
- /**
- * Parse the script tag and directives in a compilation unit, starting with
- * the given [token], until the first non-directive is encountered. The
- * remainder of the compilation unit will not be parsed. Specifically, if
- * there are directives later in the file, they will not be parsed. Return the
- * compilation unit that was parsed.
- */
+ /// Parse the script tag and directives in a compilation unit, starting with
+ /// the given [token], until the first non-directive is encountered. The
+ /// remainder of the compilation unit will not be parsed. Specifically, if
+ /// there are directives later in the file, they will not be parsed. Return
+ /// the compilation unit that was parsed.
CompilationUnit parseDirectives(Token token) {
_currentToken = token;
return parseDirectives2();
}
- /**
- * Parse the script tag and directives in a compilation unit until the first
- * non-directive is encountered. Return the compilation unit that was parsed.
- *
- * compilationUnit ::=
- * scriptTag? directive*
- */
+ /// Parse the script tag and directives in a compilation unit until the first
+ /// non-directive is encountered. Return the compilation unit that was parsed.
+ ///
+ /// compilationUnit ::=
+ /// scriptTag? directive*
CompilationUnit parseDirectives2() {
Token firstToken = _currentToken;
ScriptTag scriptTag = null;
@@ -2550,15 +2389,13 @@
firstToken, scriptTag, directives, null, _currentToken);
}
- /**
- * Parse a documentation comment based on the given list of documentation
- * comment tokens. Return the documentation comment that was parsed, or `null`
- * if there was no comment.
- *
- * documentationComment ::=
- * multiLineComment?
- * | singleLineComment*
- */
+ /// Parse a documentation comment based on the given list of documentation
+ /// comment tokens. Return the documentation comment that was parsed, or
+ /// `null` if there was no comment.
+ ///
+ /// documentationComment ::=
+ /// multiLineComment?
+ /// | singleLineComment*
Comment parseDocumentationComment(List<DocumentationCommentToken> tokens) {
if (tokens == null) {
return null;
@@ -2567,14 +2404,12 @@
return astFactory.documentationComment(tokens, references);
}
- /**
- * Parse a documentation comment. Return the documentation comment that was
- * parsed, or `null` if there was no comment.
- *
- * documentationComment ::=
- * multiLineComment?
- * | singleLineComment*
- */
+ /// Parse a documentation comment. Return the documentation comment that was
+ /// parsed, or `null` if there was no comment.
+ ///
+ /// documentationComment ::=
+ /// multiLineComment?
+ /// | singleLineComment*
List<DocumentationCommentToken> parseDocumentationCommentTokens() {
List<DocumentationCommentToken> tokens = <DocumentationCommentToken>[];
CommentToken commentToken = _currentToken.precedingComments;
@@ -2596,14 +2431,12 @@
return tokens.isEmpty ? null : tokens;
}
- /**
- * Parse a do statement. Return the do statement that was parsed.
- *
- * This method assumes that the current token matches `Keyword.DO`.
- *
- * doStatement ::=
- * 'do' statement 'while' '(' expression ')' ';'
- */
+ /// Parse a do statement. Return the do statement that was parsed.
+ ///
+ /// This method assumes that the current token matches `Keyword.DO`.
+ ///
+ /// doStatement ::=
+ /// 'do' statement 'while' '(' expression ')' ';'
Statement parseDoStatement() {
bool wasInLoop = _inLoop;
_inLoop = true;
@@ -2622,12 +2455,10 @@
}
}
- /**
- * Parse a dotted name. Return the dotted name that was parsed.
- *
- * dottedName ::=
- * identifier ('.' identifier)*
- */
+ /// Parse a dotted name. Return the dotted name that was parsed.
+ ///
+ /// dottedName ::=
+ /// identifier ('.' identifier)*
DottedName parseDottedName() {
List<SimpleIdentifier> components = <SimpleIdentifier>[
parseSimpleIdentifier()
@@ -2638,25 +2469,21 @@
return astFactory.dottedName(components);
}
- /**
- * Parse an empty statement. Return the empty statement that was parsed.
- *
- * This method assumes that the current token matches `TokenType.SEMICOLON`.
- *
- * emptyStatement ::=
- * ';'
- */
+ /// Parse an empty statement. Return the empty statement that was parsed.
+ ///
+ /// This method assumes that the current token matches `TokenType.SEMICOLON`.
+ ///
+ /// emptyStatement ::=
+ /// ';'
Statement parseEmptyStatement() => astFactory.emptyStatement(getAndAdvance());
- /**
- * Parse an enum declaration. The [commentAndMetadata] is the metadata to be
- * associated with the member. Return the enum declaration that was parsed.
- *
- * This method assumes that the current token matches `Keyword.ENUM`.
- *
- * enumType ::=
- * metadata 'enum' id '{' id (',' id)* (',')? '}'
- */
+ /// Parse an enum declaration. The [commentAndMetadata] is the metadata to be
+ /// associated with the member. Return the enum declaration that was parsed.
+ ///
+ /// This method assumes that the current token matches `Keyword.ENUM`.
+ ///
+ /// enumType ::=
+ /// metadata 'enum' id '{' id (',' id)* (',')? '}'
EnumDeclaration parseEnumDeclaration(CommentAndMetadata commentAndMetadata) {
Token keyword = getAndAdvance();
SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true);
@@ -2697,14 +2524,12 @@
rightBracket);
}
- /**
- * Parse an equality expression. Return the equality expression that was
- * parsed.
- *
- * equalityExpression ::=
- * relationalExpression (equalityOperator relationalExpression)?
- * | 'super' equalityOperator relationalExpression
- */
+ /// Parse an equality expression. Return the equality expression that was
+ /// parsed.
+ ///
+ /// equalityExpression ::=
+ /// relationalExpression (equalityOperator relationalExpression)?
+ /// | 'super' equalityOperator relationalExpression
Expression parseEqualityExpression() {
Expression expression;
if (_currentToken.keyword == Keyword.SUPER &&
@@ -2726,15 +2551,14 @@
return expression;
}
- /**
- * Parse an export directive. The [commentAndMetadata] is the metadata to be
- * associated with the directive. Return the export directive that was parsed.
- *
- * This method assumes that the current token matches `Keyword.EXPORT`.
- *
- * exportDirective ::=
- * metadata 'export' stringLiteral configuration* combinator*';'
- */
+ /// Parse an export directive. The [commentAndMetadata] is the metadata to be
+ /// associated with the directive. Return the export directive that was
+ /// parsed.
+ ///
+ /// This method assumes that the current token matches `Keyword.EXPORT`.
+ ///
+ /// exportDirective ::=
+ /// metadata 'export' stringLiteral configuration* combinator*';'
ExportDirective parseExportDirective(CommentAndMetadata commentAndMetadata) {
Token exportKeyword = getAndAdvance();
StringLiteral libraryUri = _parseUri();
@@ -2751,25 +2575,21 @@
semicolon);
}
- /**
- * Parse an expression, starting with the given [token]. Return the expression
- * that was parsed, or `null` if the tokens do not represent a recognizable
- * expression.
- */
+ /// Parse an expression, starting with the given [token]. Return the
+ /// expression that was parsed, or `null` if the tokens do not represent a
+ /// recognizable expression.
Expression parseExpression(Token token) {
_currentToken = token;
return parseExpression2();
}
- /**
- * Parse an expression that might contain a cascade. Return the expression
- * that was parsed.
- *
- * expression ::=
- * assignableExpression assignmentOperator expression
- * | conditionalExpression cascadeSection*
- * | throwExpression
- */
+ /// Parse an expression that might contain a cascade. Return the expression
+ /// that was parsed.
+ ///
+ /// expression ::=
+ /// assignableExpression assignmentOperator expression
+ /// | conditionalExpression cascadeSection*
+ /// | throwExpression
Expression parseExpression2() {
if (_treeDepth > _MAX_TREE_DEPTH) {
throw new _TooDeepTreeError();
@@ -2812,12 +2632,10 @@
}
}
- /**
- * Parse a list of expressions. Return the expression that was parsed.
- *
- * expressionList ::=
- * expression (',' expression)*
- */
+ /// Parse a list of expressions. Return the expression that was parsed.
+ ///
+ /// expressionList ::=
+ /// expression (',' expression)*
List<Expression> parseExpressionList() {
List<Expression> expressions = <Expression>[parseExpression2()];
while (_optional(TokenType.COMMA)) {
@@ -2826,15 +2644,13 @@
return expressions;
}
- /**
- * Parse an expression that does not contain any cascades. Return the
- * expression that was parsed.
- *
- * expressionWithoutCascade ::=
- * assignableExpression assignmentOperator expressionWithoutCascade
- * | conditionalExpression
- * | throwExpressionWithoutCascade
- */
+ /// Parse an expression that does not contain any cascades. Return the
+ /// expression that was parsed.
+ ///
+ /// expressionWithoutCascade ::=
+ /// assignableExpression assignmentOperator expressionWithoutCascade
+ /// | conditionalExpression
+ /// | throwExpressionWithoutCascade
Expression parseExpressionWithoutCascade() {
if (_matchesKeyword(Keyword.THROW)) {
return parseThrowExpressionWithoutCascade();
@@ -2857,32 +2673,28 @@
return expression;
}
- /**
- * Parse a class extends clause. Return the class extends clause that was
- * parsed.
- *
- * This method assumes that the current token matches `Keyword.EXTENDS`.
- *
- * classExtendsClause ::=
- * 'extends' type
- */
+ /// Parse a class extends clause. Return the class extends clause that was
+ /// parsed.
+ ///
+ /// This method assumes that the current token matches `Keyword.EXTENDS`.
+ ///
+ /// classExtendsClause ::=
+ /// 'extends' type
ExtendsClause parseExtendsClause() {
Token keyword = getAndAdvance();
TypeName superclass = parseTypeName(false);
return astFactory.extendsClause(keyword, superclass);
}
- /**
- * Parse the 'final', 'const', 'var' or type preceding a variable declaration.
- * The [optional] is `true` if the keyword and type are optional. Return the
- * 'final', 'const', 'var' or type that was parsed.
- *
- * finalConstVarOrType ::=
- * 'final' type?
- * | 'const' type?
- * | 'var'
- * | type
- */
+ /// Parse the 'final', 'const', 'var' or type preceding a variable
+ /// declaration. The [optional] is `true` if the keyword and type are
+ /// optional. Return the 'final', 'const', 'var' or type that was parsed.
+ ///
+ /// finalConstVarOrType ::=
+ /// 'final' type?
+ /// | 'const' type?
+ /// | 'var'
+ /// | type
FinalConstVarOrType parseFinalConstVarOrType(bool optional,
{bool inFunctionType: false}) {
Token keywordToken = null;
@@ -2925,19 +2737,17 @@
return new FinalConstVarOrType(keywordToken, type);
}
- /**
- * Parse a formal parameter. At most one of `isOptional` and `isNamed` can be
- * `true`. The [kind] is the kind of parameter being expected based on the
- * presence or absence of group delimiters. Return the formal parameter that
- * was parsed.
- *
- * defaultFormalParameter ::=
- * normalFormalParameter ('=' expression)?
- *
- * defaultNamedParameter ::=
- * normalFormalParameter ('=' expression)?
- * normalFormalParameter (':' expression)?
- */
+ /// Parse a formal parameter. At most one of `isOptional` and `isNamed` can be
+ /// `true`. The [kind] is the kind of parameter being expected based on the
+ /// presence or absence of group delimiters. Return the formal parameter that
+ /// was parsed.
+ ///
+ /// defaultFormalParameter ::=
+ /// normalFormalParameter ('=' expression)?
+ ///
+ /// defaultNamedParameter ::=
+ /// normalFormalParameter ('=' expression)?
+ /// normalFormalParameter (':' expression)?
FormalParameter parseFormalParameter(ParameterKind kind,
{bool inFunctionType: false}) {
NormalFormalParameter parameter =
@@ -3000,28 +2810,26 @@
return parameter;
}
- /**
- * Parse a list of formal parameters. Return the formal parameters that were
- * parsed.
- *
- * formalParameterList ::=
- * '(' ')'
- * | '(' normalFormalParameters (',' optionalFormalParameters)? ')'
- * | '(' optionalFormalParameters ')'
- *
- * normalFormalParameters ::=
- * normalFormalParameter (',' normalFormalParameter)*
- *
- * optionalFormalParameters ::=
- * optionalPositionalFormalParameters
- * | namedFormalParameters
- *
- * optionalPositionalFormalParameters ::=
- * '[' defaultFormalParameter (',' defaultFormalParameter)* ']'
- *
- * namedFormalParameters ::=
- * '{' defaultNamedParameter (',' defaultNamedParameter)* '}'
- */
+ /// Parse a list of formal parameters. Return the formal parameters that were
+ /// parsed.
+ ///
+ /// formalParameterList ::=
+ /// '(' ')'
+ /// | '(' normalFormalParameters (',' optionalFormalParameters)? ')'
+ /// | '(' optionalFormalParameters ')'
+ ///
+ /// normalFormalParameters ::=
+ /// normalFormalParameter (',' normalFormalParameter)*
+ ///
+ /// optionalFormalParameters ::=
+ /// optionalPositionalFormalParameters
+ /// | namedFormalParameters
+ ///
+ /// optionalPositionalFormalParameters ::=
+ /// '[' defaultFormalParameter (',' defaultFormalParameter)* ']'
+ ///
+ /// namedFormalParameters ::=
+ /// '{' defaultNamedParameter (',' defaultNamedParameter)* '}'
FormalParameterList parseFormalParameterList({bool inFunctionType: false}) {
if (_matches(TokenType.OPEN_PAREN)) {
return _parseFormalParameterListUnchecked(inFunctionType: inFunctionType);
@@ -3035,21 +2843,19 @@
_createSyntheticToken(TokenType.OPEN_PAREN));
}
- /**
- * Parse a for statement. Return the for statement that was parsed.
- *
- * forStatement ::=
- * 'for' '(' forLoopParts ')' statement
- *
- * forLoopParts ::=
- * forInitializerStatement expression? ';' expressionList?
- * | declaredIdentifier 'in' expression
- * | identifier 'in' expression
- *
- * forInitializerStatement ::=
- * localVariableDeclaration ';'
- * | expression? ';'
- */
+ /// Parse a for statement. Return the for statement that was parsed.
+ ///
+ /// forStatement ::=
+ /// 'for' '(' forLoopParts ')' statement
+ ///
+ /// forLoopParts ::=
+ /// forInitializerStatement expression? ';' expressionList?
+ /// | declaredIdentifier 'in' expression
+ /// | identifier 'in' expression
+ ///
+ /// forInitializerStatement ::=
+ /// localVariableDeclaration ';'
+ /// | expression? ';'
Statement parseForStatement() {
bool wasInLoop = _inLoop;
_inLoop = true;
@@ -3181,21 +2987,20 @@
}
}
- /**
- * Parse a function body. The [mayBeEmpty] is `true` if the function body is
- * allowed to be empty. The [emptyErrorCode] is the error code to report if
- * function body expected, but not found. The [inExpression] is `true` if the
- * function body is being parsed as part of an expression and therefore does
- * not have a terminating semicolon. Return the function body that was parsed.
- *
- * functionBody ::=
- * '=>' expression ';'
- * | block
- *
- * functionExpressionBody ::=
- * '=>' expression
- * | block
- */
+ /// Parse a function body. The [mayBeEmpty] is `true` if the function body is
+ /// allowed to be empty. The [emptyErrorCode] is the error code to report if
+ /// function body expected, but not found. The [inExpression] is `true` if the
+ /// function body is being parsed as part of an expression and therefore does
+ /// not have a terminating semicolon. Return the function body that was
+ /// parsed.
+ ///
+ /// functionBody ::=
+ /// '=>' expression ';'
+ /// | block
+ ///
+ /// functionExpressionBody ::=
+ /// '=>' expression
+ /// | block
FunctionBody parseFunctionBody(
bool mayBeEmpty, ParserErrorCode emptyErrorCode, bool inExpression) {
bool wasInAsync = _inAsync;
@@ -3301,19 +3106,17 @@
}
}
- /**
- * Parse a function declaration. The [commentAndMetadata] is the documentation
- * comment and metadata to be associated with the declaration. The
- * [externalKeyword] is the 'external' keyword, or `null` if the function is
- * not external. The [returnType] is the return type, or `null` if there is no
- * return type. The [isStatement] is `true` if the function declaration is
- * being parsed as a statement. Return the function declaration that was
- * parsed.
- *
- * functionDeclaration ::=
- * functionSignature functionBody
- * | returnType? getOrSet identifier formalParameterList functionBody
- */
+ /// Parse a function declaration. The [commentAndMetadata] is the
+ /// documentation comment and metadata to be associated with the declaration.
+ /// The [externalKeyword] is the 'external' keyword, or `null` if the
+ /// function is not external. The [returnType] is the return type, or `null`
+ /// if there is no return type. The [isStatement] is `true` if the function
+ /// declaration is being parsed as a statement. Return the function
+ /// declaration that was parsed.
+ ///
+ /// functionDeclaration ::=
+ /// functionSignature functionBody
+ /// | returnType? getOrSet identifier formalParameterList functionBody
FunctionDeclaration parseFunctionDeclaration(
CommentAndMetadata commentAndMetadata,
Token externalKeyword,
@@ -3377,13 +3180,11 @@
astFactory.functionExpression(typeParameters, parameters, body));
}
- /**
- * Parse a function declaration statement. Return the function declaration
- * statement that was parsed.
- *
- * functionDeclarationStatement ::=
- * functionSignature functionBody
- */
+ /// Parse a function declaration statement. Return the function declaration
+ /// statement that was parsed.
+ ///
+ /// functionDeclarationStatement ::=
+ /// functionSignature functionBody
Statement parseFunctionDeclarationStatement() {
Modifiers modifiers = parseModifiers();
_validateModifiersForFunctionDeclarationStatement(modifiers);
@@ -3391,13 +3192,11 @@
parseCommentAndMetadata(), _parseOptionalReturnType());
}
- /**
- * Parse a function expression. Return the function expression that was
- * parsed.
- *
- * functionExpression ::=
- * typeParameters? formalParameterList functionExpressionBody
- */
+ /// Parse a function expression. Return the function expression that was
+ /// parsed.
+ ///
+ /// functionExpression ::=
+ /// typeParameters? formalParameterList functionExpressionBody
FunctionExpression parseFunctionExpression() {
TypeParameterList typeParameters = _parseGenericMethodTypeParameters();
FormalParameterList parameters = parseFormalParameterList();
@@ -3407,29 +3206,27 @@
return astFactory.functionExpression(typeParameters, parameters, body);
}
- /**
- * Parse the portion of a generic function type following the [returnType].
- *
- * functionType ::=
- * returnType? 'Function' typeParameters? parameterTypeList
- * parameterTypeList ::=
- * '(' ')' |
- * | '(' normalParameterTypes ','? ')' |
- * | '(' normalParameterTypes ',' optionalParameterTypes ')' |
- * | '(' optionalParameterTypes ')'
- * normalParameterTypes ::=
- * normalParameterType (',' normalParameterType)*
- * normalParameterType ::=
- * type | typedIdentifier
- * optionalParameterTypes ::=
- * optionalPositionalParameterTypes | namedParameterTypes
- * optionalPositionalParameterTypes ::=
- * '[' normalParameterTypes ','? ']'
- * namedParameterTypes ::=
- * '{' typedIdentifier (',' typedIdentifier)* ','? '}'
- * typedIdentifier ::=
- * type identifier
- */
+ /// Parse the portion of a generic function type following the [returnType].
+ ///
+ /// functionType ::=
+ /// returnType? 'Function' typeParameters? parameterTypeList
+ /// parameterTypeList ::=
+ /// '(' ')' |
+ /// | '(' normalParameterTypes ','? ')' |
+ /// | '(' normalParameterTypes ',' optionalParameterTypes ')' |
+ /// | '(' optionalParameterTypes ')'
+ /// normalParameterTypes ::=
+ /// normalParameterType (',' normalParameterType)*
+ /// normalParameterType ::=
+ /// type | typedIdentifier
+ /// optionalParameterTypes ::=
+ /// optionalPositionalParameterTypes | namedParameterTypes
+ /// optionalPositionalParameterTypes ::=
+ /// '[' normalParameterTypes ','? ']'
+ /// namedParameterTypes ::=
+ /// '{' typedIdentifier (',' typedIdentifier)* ','? '}'
+ /// typedIdentifier ::=
+ /// type identifier
GenericFunctionType parseGenericFunctionTypeAfterReturnType(
TypeAnnotation returnType) {
Token functionKeyword = null;
@@ -3450,14 +3247,12 @@
returnType, functionKeyword, typeParameters, parameters);
}
- /**
- * Parse a generic function type alias.
- *
- * This method assumes that the current token is an identifier.
- *
- * genericTypeAlias ::=
- * 'typedef' identifier typeParameterList? '=' functionType ';'
- */
+ /// Parse a generic function type alias.
+ ///
+ /// This method assumes that the current token is an identifier.
+ ///
+ /// genericTypeAlias ::=
+ /// 'typedef' identifier typeParameterList? '=' functionType ';'
GenericTypeAlias parseGenericTypeAlias(
CommentAndMetadata commentAndMetadata, Token keyword) {
Identifier name = _parseSimpleIdentifierUnchecked(isDeclaration: true);
@@ -3494,22 +3289,20 @@
semicolon);
}
- /**
- * Parse a getter. The [commentAndMetadata] is the documentation comment and
- * metadata to be associated with the declaration. The externalKeyword] is the
- * 'external' token. The staticKeyword] is the static keyword, or `null` if
- * the getter is not static. The [returnType] the return type that has already
- * been parsed, or `null` if there was no return type. Return the getter that
- * was parsed.
- *
- * This method assumes that the current token matches `Keyword.GET`.
- *
- * getter ::=
- * getterSignature functionBody?
- *
- * getterSignature ::=
- * 'external'? 'static'? returnType? 'get' identifier
- */
+ /// Parse a getter. The [commentAndMetadata] is the documentation comment and
+ /// metadata to be associated with the declaration. The externalKeyword] is
+ /// the 'external' token. The staticKeyword] is the static keyword, or `null`
+ /// if the getter is not static. The [returnType] the return type that has
+ /// already been parsed, or `null` if there was no return type. Return the
+ /// getter that was parsed.
+ ///
+ /// This method assumes that the current token matches `Keyword.GET`.
+ ///
+ /// getter ::=
+ /// getterSignature functionBody?
+ ///
+ /// getterSignature ::=
+ /// 'external'? 'static'? returnType? 'get' identifier
MethodDeclaration parseGetter(CommentAndMetadata commentAndMetadata,
Token externalKeyword, Token staticKeyword, TypeAnnotation returnType) {
Token propertyKeyword = getAndAdvance();
@@ -3541,13 +3334,11 @@
body);
}
- /**
- * Parse a list of identifiers. Return the list of identifiers that were
- * parsed.
- *
- * identifierList ::=
- * identifier (',' identifier)*
- */
+ /// Parse a list of identifiers. Return the list of identifiers that were
+ /// parsed.
+ ///
+ /// identifierList ::=
+ /// identifier (',' identifier)*
List<SimpleIdentifier> parseIdentifierList() {
List<SimpleIdentifier> identifiers = <SimpleIdentifier>[
parseSimpleIdentifier()
@@ -3558,12 +3349,10 @@
return identifiers;
}
- /**
- * Parse an if-null expression. Return the if-null expression that was
- * parsed.
- *
- * ifNullExpression ::= logicalOrExpression ('??' logicalOrExpression)*
- */
+ /// Parse an if-null expression. Return the if-null expression that was
+ /// parsed.
+ ///
+ /// ifNullExpression ::= logicalOrExpression ('??' logicalOrExpression)*
Expression parseIfNullExpression() {
Expression expression = parseLogicalOrExpression();
while (_currentToken.type == TokenType.QUESTION_QUESTION) {
@@ -3573,14 +3362,12 @@
return expression;
}
- /**
- * Parse an if statement. Return the if statement that was parsed.
- *
- * This method assumes that the current token matches `Keyword.IF`.
- *
- * ifStatement ::=
- * 'if' '(' expression ')' statement ('else' statement)?
- */
+ /// Parse an if statement. Return the if statement that was parsed.
+ ///
+ /// This method assumes that the current token matches `Keyword.IF`.
+ ///
+ /// ifStatement ::=
+ /// 'if' '(' expression ')' statement ('else' statement)?
Statement parseIfStatement() {
Token ifKeyword = getAndAdvance();
Token leftParenthesis = _expect(TokenType.OPEN_PAREN);
@@ -3597,14 +3384,12 @@
rightParenthesis, thenStatement, elseKeyword, elseStatement);
}
- /**
- * Parse an implements clause. Return the implements clause that was parsed.
- *
- * This method assumes that the current token matches `Keyword.IMPLEMENTS`.
- *
- * implementsClause ::=
- * 'implements' type (',' type)*
- */
+ /// Parse an implements clause. Return the implements clause that was parsed.
+ ///
+ /// This method assumes that the current token matches `Keyword.IMPLEMENTS`.
+ ///
+ /// implementsClause ::=
+ /// 'implements' type (',' type)*
ImplementsClause parseImplementsClause() {
Token keyword = getAndAdvance();
List<TypeName> interfaces = <TypeName>[];
@@ -3615,15 +3400,14 @@
return astFactory.implementsClause(keyword, interfaces);
}
- /**
- * Parse an import directive. The [commentAndMetadata] is the metadata to be
- * associated with the directive. Return the import directive that was parsed.
- *
- * This method assumes that the current token matches `Keyword.IMPORT`.
- *
- * importDirective ::=
- * metadata 'import' stringLiteral configuration* (deferred)? ('as' identifier)? combinator*';'
- */
+ /// Parse an import directive. The [commentAndMetadata] is the metadata to be
+ /// associated with the directive. Return the import directive that was
+ /// parsed.
+ ///
+ /// This method assumes that the current token matches `Keyword.IMPORT`.
+ ///
+ /// importDirective ::=
+ /// metadata 'import' stringLiteral configuration* (deferred)? ('as' identifier)? combinator*';'
ImportDirective parseImportDirective(CommentAndMetadata commentAndMetadata) {
Token importKeyword = getAndAdvance();
StringLiteral libraryUri = _parseUri();
@@ -3671,25 +3455,23 @@
semicolon);
}
- /**
- * Parse a list of initialized identifiers. The [commentAndMetadata] is the
- * documentation comment and metadata to be associated with the declaration.
- * The [staticKeyword] is the static keyword, or `null` if the getter is not
- * static. The [keyword] is the token representing the 'final', 'const' or
- * 'var' keyword, or `null` if there is no keyword. The [type] is the type
- * that has already been parsed, or `null` if 'var' was provided. Return the
- * getter that was parsed.
- *
- * declaration ::=
- * ('static' | 'covariant')? ('var' | type) initializedIdentifierList ';'
- * | 'final' type? initializedIdentifierList ';'
- *
- * initializedIdentifierList ::=
- * initializedIdentifier (',' initializedIdentifier)*
- *
- * initializedIdentifier ::=
- * identifier ('=' expression)?
- */
+ /// Parse a list of initialized identifiers. The [commentAndMetadata] is the
+ /// documentation comment and metadata to be associated with the declaration.
+ /// The [staticKeyword] is the static keyword, or `null` if the getter is not
+ /// static. The [keyword] is the token representing the 'final', 'const' or
+ /// 'var' keyword, or `null` if there is no keyword. The [type] is the type
+ /// that has already been parsed, or `null` if 'var' was provided. Return the
+ /// getter that was parsed.
+ ///
+ /// declaration ::=
+ /// ('static' | 'covariant')? ('var' | type) initializedIdentifierList ';'
+ /// | 'final' type? initializedIdentifierList ';'
+ ///
+ /// initializedIdentifierList ::=
+ /// initializedIdentifier (',' initializedIdentifier)*
+ ///
+ /// initializedIdentifier ::=
+ /// identifier ('=' expression)?
FieldDeclaration parseInitializedIdentifierList(
CommentAndMetadata commentAndMetadata,
Token staticKeyword,
@@ -3707,14 +3489,12 @@
semicolon: _expect(TokenType.SEMICOLON));
}
- /**
- * Parse an instance creation expression. The [keyword] is the 'new' or
- * 'const' keyword that introduces the expression. Return the instance
- * creation expression that was parsed.
- *
- * instanceCreationExpression ::=
- * ('new' | 'const') type ('.' identifier)? argumentList
- */
+ /// Parse an instance creation expression. The [keyword] is the 'new' or
+ /// 'const' keyword that introduces the expression. Return the instance
+ /// creation expression that was parsed.
+ ///
+ /// instanceCreationExpression ::=
+ /// ('new' | 'const') type ('.' identifier)? argumentList
InstanceCreationExpression parseInstanceCreationExpression(Token keyword) {
ConstructorName constructorName = parseConstructorName();
ArgumentList argumentList = _parseArgumentListChecked();
@@ -3722,15 +3502,13 @@
keyword, constructorName, argumentList);
}
- /**
- * Parse a label. Return the label that was parsed.
- *
- * This method assumes that the current token matches an identifier and that
- * the following token matches `TokenType.COLON`.
- *
- * label ::=
- * identifier ':'
- */
+ /// Parse a label. Return the label that was parsed.
+ ///
+ /// This method assumes that the current token matches an identifier and that
+ /// the following token matches `TokenType.COLON`.
+ ///
+ /// label ::=
+ /// identifier ':'
Label parseLabel({bool isDeclaration: false}) {
SimpleIdentifier label =
_parseSimpleIdentifierUnchecked(isDeclaration: isDeclaration);
@@ -3738,16 +3516,14 @@
return astFactory.label(label, colon);
}
- /**
- * Parse a library directive. The [commentAndMetadata] is the metadata to be
- * associated with the directive. Return the library directive that was
- * parsed.
- *
- * This method assumes that the current token matches `Keyword.LIBRARY`.
- *
- * libraryDirective ::=
- * metadata 'library' identifier ';'
- */
+ /// Parse a library directive. The [commentAndMetadata] is the metadata to be
+ /// associated with the directive. Return the library directive that was
+ /// parsed.
+ ///
+ /// This method assumes that the current token matches `Keyword.LIBRARY`.
+ ///
+ /// libraryDirective ::=
+ /// metadata 'library' identifier ';'
LibraryDirective parseLibraryDirective(
CommentAndMetadata commentAndMetadata) {
Token keyword = getAndAdvance();
@@ -3758,12 +3534,10 @@
commentAndMetadata.metadata, keyword, libraryName, semicolon);
}
- /**
- * Parse a library identifier. Return the library identifier that was parsed.
- *
- * libraryIdentifier ::=
- * identifier ('.' identifier)*
- */
+ /// Parse a library identifier. Return the library identifier that was parsed.
+ ///
+ /// libraryIdentifier ::=
+ /// identifier ('.' identifier)*
LibraryIdentifier parseLibraryIdentifier() {
List<SimpleIdentifier> components = <SimpleIdentifier>[];
components.add(parseSimpleIdentifier());
@@ -3773,18 +3547,16 @@
return astFactory.libraryIdentifier(components);
}
- /**
- * Parse a list literal. The [modifier] is the 'const' modifier appearing
- * before the literal, or `null` if there is no modifier. The [typeArguments]
- * is the type arguments appearing before the literal, or `null` if there are
- * no type arguments. Return the list literal that was parsed.
- *
- * This method assumes that the current token matches either
- * `TokenType.OPEN_SQUARE_BRACKET` or `TokenType.INDEX`.
- *
- * listLiteral ::=
- * 'const'? typeArguments? '[' (expressionList ','?)? ']'
- */
+ /// Parse a list literal. The [modifier] is the 'const' modifier appearing
+ /// before the literal, or `null` if there is no modifier. The [typeArguments]
+ /// is the type arguments appearing before the literal, or `null` if there are
+ /// no type arguments. Return the list literal that was parsed.
+ ///
+ /// This method assumes that the current token matches either
+ /// `TokenType.OPEN_SQUARE_BRACKET` or `TokenType.INDEX`.
+ ///
+ /// listLiteral ::=
+ /// 'const'? typeArguments? '[' (expressionList ','?)? ']'
ListLiteral parseListLiteral(Token modifier, TypeArgumentList typeArguments) {
if (_matches(TokenType.INDEX)) {
_splitIndex();
@@ -3815,15 +3587,13 @@
}
}
- /**
- * Parse a list or map literal. The [modifier] is the 'const' modifier
- * appearing before the literal, or `null` if there is no modifier. Return the
- * list or map literal that was parsed.
- *
- * listOrMapLiteral ::=
- * listLiteral
- * | mapLiteral
- */
+ /// Parse a list or map literal. The [modifier] is the 'const' modifier
+ /// appearing before the literal, or `null` if there is no modifier. Return
+ /// the list or map literal that was parsed.
+ ///
+ /// listOrMapLiteral ::=
+ /// listLiteral
+ /// | mapLiteral
TypedLiteral parseListOrMapLiteral(Token modifier) {
TypeArgumentList typeArguments = _parseOptionalTypeArguments();
if (_matches(TokenType.OPEN_CURLY_BRACKET)) {
@@ -3841,13 +3611,11 @@
_createSyntheticToken(TokenType.CLOSE_SQUARE_BRACKET));
}
- /**
- * Parse a logical and expression. Return the logical and expression that was
- * parsed.
- *
- * logicalAndExpression ::=
- * equalityExpression ('&&' equalityExpression)*
- */
+ /// Parse a logical and expression. Return the logical and expression that was
+ /// parsed.
+ ///
+ /// logicalAndExpression ::=
+ /// equalityExpression ('&&' equalityExpression)*
Expression parseLogicalAndExpression() {
Expression expression = parseEqualityExpression();
while (_currentToken.type == TokenType.AMPERSAND_AMPERSAND) {
@@ -3857,13 +3625,11 @@
return expression;
}
- /**
- * Parse a logical or expression. Return the logical or expression that was
- * parsed.
- *
- * logicalOrExpression ::=
- * logicalAndExpression ('||' logicalAndExpression)*
- */
+ /// Parse a logical or expression. Return the logical or expression that was
+ /// parsed.
+ ///
+ /// logicalOrExpression ::=
+ /// logicalAndExpression ('||' logicalAndExpression)*
Expression parseLogicalOrExpression() {
Expression expression = parseLogicalAndExpression();
while (_currentToken.type == TokenType.BAR_BAR) {
@@ -3873,18 +3639,16 @@
return expression;
}
- /**
- * Parse a map literal. The [modifier] is the 'const' modifier appearing
- * before the literal, or `null` if there is no modifier. The [typeArguments]
- * is the type arguments that were declared, or `null` if there are no type
- * arguments. Return the map literal that was parsed.
- *
- * This method assumes that the current token matches
- * `TokenType.OPEN_CURLY_BRACKET`.
- *
- * mapLiteral ::=
- * 'const'? typeArguments? '{' (mapLiteralEntry (',' mapLiteralEntry)* ','?)? '}'
- */
+ /// Parse a map literal. The [modifier] is the 'const' modifier appearing
+ /// before the literal, or `null` if there is no modifier. The [typeArguments]
+ /// is the type arguments that were declared, or `null` if there are no type
+ /// arguments. Return the map literal that was parsed.
+ ///
+ /// This method assumes that the current token matches
+ /// `TokenType.OPEN_CURLY_BRACKET`.
+ ///
+ /// mapLiteral ::=
+ /// 'const'? typeArguments? '{' (mapLiteralEntry (',' mapLiteralEntry)* ','?)? '}'
MapLiteral parseMapLiteral(Token modifier, TypeArgumentList typeArguments) {
Token leftBracket = getAndAdvance();
if (_matches(TokenType.CLOSE_CURLY_BRACKET)) {
@@ -3910,12 +3674,10 @@
}
}
- /**
- * Parse a map literal entry. Return the map literal entry that was parsed.
- *
- * mapLiteralEntry ::=
- * expression ':' expression
- */
+ /// Parse a map literal entry. Return the map literal entry that was parsed.
+ ///
+ /// mapLiteralEntry ::=
+ /// expression ':' expression
MapLiteralEntry parseMapLiteralEntry() {
Expression key = parseExpression2();
Token separator = _expect(TokenType.COLON);
@@ -3923,17 +3685,15 @@
return astFactory.mapLiteralEntry(key, separator, value);
}
- /**
- * Parse the modifiers preceding a declaration. This method allows the
- * modifiers to appear in any order but does generate errors for duplicated
- * modifiers. Checks for other problems, such as having the modifiers appear
- * in the wrong order or specifying both 'const' and 'final', are reported in
- * one of the methods whose name is prefixed with `validateModifiersFor`.
- * Return the modifiers that were parsed.
- *
- * modifiers ::=
- * ('abstract' | 'const' | 'external' | 'factory' | 'final' | 'static' | 'var')*
- */
+ /// Parse the modifiers preceding a declaration. This method allows the
+ /// modifiers to appear in any order but does generate errors for duplicated
+ /// modifiers. Checks for other problems, such as having the modifiers appear
+ /// in the wrong order or specifying both 'const' and 'final', are reported in
+ /// one of the methods whose name is prefixed with `validateModifiersFor`.
+ /// Return the modifiers that were parsed.
+ ///
+ /// modifiers ::=
+ /// ('abstract' | 'const' | 'external' | 'factory' | 'final' | 'static' | 'var')*
Modifiers parseModifiers() {
Modifiers modifiers = new Modifiers();
bool progress = true;
@@ -4016,14 +3776,12 @@
return modifiers;
}
- /**
- * Parse a multiplicative expression. Return the multiplicative expression
- * that was parsed.
- *
- * multiplicativeExpression ::=
- * unaryExpression (multiplicativeOperator unaryExpression)*
- * | 'super' (multiplicativeOperator unaryExpression)+
- */
+ /// Parse a multiplicative expression. Return the multiplicative expression
+ /// that was parsed.
+ ///
+ /// multiplicativeExpression ::=
+ /// unaryExpression (multiplicativeOperator unaryExpression)*
+ /// | 'super' (multiplicativeOperator unaryExpression)+
Expression parseMultiplicativeExpression() {
Expression expression;
if (_currentToken.keyword == Keyword.SUPER &&
@@ -4039,37 +3797,33 @@
return expression;
}
- /**
- * Parse a new expression. Return the new expression that was parsed.
- *
- * This method assumes that the current token matches `Keyword.NEW`.
- *
- * newExpression ::=
- * instanceCreationExpression
- */
+ /// Parse a new expression. Return the new expression that was parsed.
+ ///
+ /// This method assumes that the current token matches `Keyword.NEW`.
+ ///
+ /// newExpression ::=
+ /// instanceCreationExpression
InstanceCreationExpression parseNewExpression() =>
parseInstanceCreationExpression(getAndAdvance());
- /**
- * Parse a non-labeled statement. Return the non-labeled statement that was
- * parsed.
- *
- * nonLabeledStatement ::=
- * block
- * | assertStatement
- * | breakStatement
- * | continueStatement
- * | doStatement
- * | forStatement
- * | ifStatement
- * | returnStatement
- * | switchStatement
- * | tryStatement
- * | whileStatement
- * | variableDeclarationList ';'
- * | expressionStatement
- * | functionSignature functionBody
- */
+ /// Parse a non-labeled statement. Return the non-labeled statement that was
+ /// parsed.
+ ///
+ /// nonLabeledStatement ::=
+ /// block
+ /// | assertStatement
+ /// | breakStatement
+ /// | continueStatement
+ /// | doStatement
+ /// | forStatement
+ /// | ifStatement
+ /// | returnStatement
+ /// | switchStatement
+ /// | tryStatement
+ /// | whileStatement
+ /// | variableDeclarationList ';'
+ /// | expressionStatement
+ /// | functionSignature functionBody
Statement parseNonLabeledStatement() {
// TODO(brianwilkerson) Pass the comment and metadata on where appropriate.
CommentAndMetadata commentAndMetadata = parseCommentAndMetadata();
@@ -4269,25 +4023,23 @@
}
}
- /**
- * Parse a normal formal parameter. Return the normal formal parameter that
- * was parsed.
- *
- * normalFormalParameter ::=
- * functionSignature
- * | fieldFormalParameter
- * | simpleFormalParameter
- *
- * functionSignature:
- * metadata returnType? identifier typeParameters? formalParameterList
- *
- * fieldFormalParameter ::=
- * metadata finalConstVarOrType? 'this' '.' identifier
- *
- * simpleFormalParameter ::=
- * declaredIdentifier
- * | metadata identifier
- */
+ /// Parse a normal formal parameter. Return the normal formal parameter that
+ /// was parsed.
+ ///
+ /// normalFormalParameter ::=
+ /// functionSignature
+ /// | fieldFormalParameter
+ /// | simpleFormalParameter
+ ///
+ /// functionSignature:
+ /// metadata returnType? identifier typeParameters? formalParameterList
+ ///
+ /// fieldFormalParameter ::=
+ /// metadata finalConstVarOrType? 'this' '.' identifier
+ ///
+ /// simpleFormalParameter ::=
+ /// declaredIdentifier
+ /// | metadata identifier
NormalFormalParameter parseNormalFormalParameter(
{bool inFunctionType: false}) {
Token covariantKeyword;
@@ -4387,19 +4139,17 @@
astFactory.simpleIdentifier(identifier.token, isDeclaration: true));
}
- /**
- * Parse an operator declaration. The [commentAndMetadata] is the
- * documentation comment and metadata to be associated with the declaration.
- * The [externalKeyword] is the 'external' token. The [returnType] is the
- * return type that has already been parsed, or `null` if there was no return
- * type. Return the operator declaration that was parsed.
- *
- * operatorDeclaration ::=
- * operatorSignature (';' | functionBody)
- *
- * operatorSignature ::=
- * 'external'? returnType? 'operator' operator formalParameterList
- */
+ /// Parse an operator declaration. The [commentAndMetadata] is the
+ /// documentation comment and metadata to be associated with the declaration.
+ /// The [externalKeyword] is the 'external' token. The [returnType] is the
+ /// return type that has already been parsed, or `null` if there was no return
+ /// type. Return the operator declaration that was parsed.
+ ///
+ /// operatorDeclaration ::=
+ /// operatorSignature (';' | functionBody)
+ ///
+ /// operatorSignature ::=
+ /// 'external'? returnType? 'operator' operator formalParameterList
MethodDeclaration parseOperator(CommentAndMetadata commentAndMetadata,
Token externalKeyword, TypeName returnType) {
Token operatorKeyword;
@@ -4414,19 +4164,17 @@
commentAndMetadata, externalKeyword, returnType, operatorKeyword);
}
- /**
- * Parse a part or part-of directive. The [commentAndMetadata] is the metadata
- * to be associated with the directive. Return the part or part-of directive
- * that was parsed.
- *
- * This method assumes that the current token matches `Keyword.PART`.
- *
- * partDirective ::=
- * metadata 'part' stringLiteral ';'
- *
- * partOfDirective ::=
- * metadata 'part' 'of' identifier ';'
- */
+ /// Parse a part or part-of directive. The [commentAndMetadata] is the
+ /// metadata to be associated with the directive. Return the part or part-of
+ /// directive that was parsed.
+ ///
+ /// This method assumes that the current token matches `Keyword.PART`.
+ ///
+ /// partDirective ::=
+ /// metadata 'part' stringLiteral ';'
+ ///
+ /// partOfDirective ::=
+ /// metadata 'part' 'of' identifier ';'
Directive parsePartOrPartOfDirective(CommentAndMetadata commentAndMetadata) {
if (_tokenMatchesKeyword(_peek(), Keyword.OF)) {
return _parsePartOfDirective(commentAndMetadata);
@@ -4434,17 +4182,15 @@
return _parsePartDirective(commentAndMetadata);
}
- /**
- * Parse a postfix expression. Return the postfix expression that was parsed.
- *
- * postfixExpression ::=
- * assignableExpression postfixOperator
- * | primary selector*
- *
- * selector ::=
- * assignableSelector
- * | argumentPart
- */
+ /// Parse a postfix expression. Return the postfix expression that was parsed.
+ ///
+ /// postfixExpression ::=
+ /// assignableExpression postfixOperator
+ /// | primary selector*
+ ///
+ /// selector ::=
+ /// assignableSelector
+ /// | argumentPart
Expression parsePostfixExpression() {
Expression operand = parseAssignableExpression(true);
TokenType type = _currentToken.type;
@@ -4499,40 +4245,36 @@
return astFactory.postfixExpression(operand, operator);
}
- /**
- * Parse a prefixed identifier. Return the prefixed identifier that was
- * parsed.
- *
- * prefixedIdentifier ::=
- * identifier ('.' identifier)?
- */
+ /// Parse a prefixed identifier. Return the prefixed identifier that was
+ /// parsed.
+ ///
+ /// prefixedIdentifier ::=
+ /// identifier ('.' identifier)?
Identifier parsePrefixedIdentifier() {
return _parsePrefixedIdentifierAfterIdentifier(parseSimpleIdentifier());
}
- /**
- * Parse a primary expression. Return the primary expression that was parsed.
- *
- * primary ::=
- * thisExpression
- * | 'super' unconditionalAssignableSelector
- * | functionExpression
- * | literal
- * | identifier
- * | newExpression
- * | constObjectExpression
- * | '(' expression ')'
- * | argumentDefinitionTest
- *
- * literal ::=
- * nullLiteral
- * | booleanLiteral
- * | numericLiteral
- * | stringLiteral
- * | symbolLiteral
- * | mapLiteral
- * | listLiteral
- */
+ /// Parse a primary expression. Return the primary expression that was parsed.
+ ///
+ /// primary ::=
+ /// thisExpression
+ /// | 'super' unconditionalAssignableSelector
+ /// | functionExpression
+ /// | literal
+ /// | identifier
+ /// | newExpression
+ /// | constObjectExpression
+ /// | '(' expression ')'
+ /// | argumentDefinitionTest
+ ///
+ /// literal ::=
+ /// nullLiteral
+ /// | booleanLiteral
+ /// | numericLiteral
+ /// | stringLiteral
+ /// | symbolLiteral
+ /// | mapLiteral
+ /// | listLiteral
Expression parsePrimaryExpression() {
if (_matchesIdentifier()) {
// TODO(brianwilkerson) The code below was an attempt to recover from an
@@ -4646,16 +4388,14 @@
}
}
- /**
- * Parse a redirecting constructor invocation. The flag [hasPeriod] should be
- * `true` if the `this` is followed by a period. Return the redirecting
- * constructor invocation that was parsed.
- *
- * This method assumes that the current token matches `Keyword.THIS`.
- *
- * redirectingConstructorInvocation ::=
- * 'this' ('.' identifier)? arguments
- */
+ /// Parse a redirecting constructor invocation. The flag [hasPeriod] should be
+ /// `true` if the `this` is followed by a period. Return the redirecting
+ /// constructor invocation that was parsed.
+ ///
+ /// This method assumes that the current token matches `Keyword.THIS`.
+ ///
+ /// redirectingConstructorInvocation ::=
+ /// 'this' ('.' identifier)? arguments
RedirectingConstructorInvocation parseRedirectingConstructorInvocation(
bool hasPeriod) {
Token keyword = getAndAdvance();
@@ -4676,14 +4416,12 @@
keyword, period, constructorName, argumentList);
}
- /**
- * Parse a relational expression. Return the relational expression that was
- * parsed.
- *
- * relationalExpression ::=
- * bitwiseOrExpression ('is' '!'? type | 'as' type | relationalOperator bitwiseOrExpression)?
- * | 'super' relationalOperator bitwiseOrExpression
- */
+ /// Parse a relational expression. Return the relational expression that was
+ /// parsed.
+ ///
+ /// relationalExpression ::=
+ /// bitwiseOrExpression ('is' '!'? type | 'as' type | relationalOperator bitwiseOrExpression)?
+ /// | 'super' relationalOperator bitwiseOrExpression
Expression parseRelationalExpression() {
if (_currentToken.keyword == Keyword.SUPER &&
_currentToken.next.type.isRelationalOperator) {
@@ -4714,25 +4452,21 @@
return expression;
}
- /**
- * Parse a rethrow expression. Return the rethrow expression that was parsed.
- *
- * This method assumes that the current token matches `Keyword.RETHROW`.
- *
- * rethrowExpression ::=
- * 'rethrow'
- */
+ /// Parse a rethrow expression. Return the rethrow expression that was parsed.
+ ///
+ /// This method assumes that the current token matches `Keyword.RETHROW`.
+ ///
+ /// rethrowExpression ::=
+ /// 'rethrow'
Expression parseRethrowExpression() =>
astFactory.rethrowExpression(getAndAdvance());
- /**
- * Parse a return statement. Return the return statement that was parsed.
- *
- * This method assumes that the current token matches `Keyword.RETURN`.
- *
- * returnStatement ::=
- * 'return' expression? ';'
- */
+ /// Parse a return statement. Return the return statement that was parsed.
+ ///
+ /// This method assumes that the current token matches `Keyword.RETURN`.
+ ///
+ /// returnStatement ::=
+ /// 'return' expression? ';'
Statement parseReturnStatement() {
Token returnKeyword = getAndAdvance();
if (_matches(TokenType.SEMICOLON)) {
@@ -4743,22 +4477,20 @@
return astFactory.returnStatement(returnKeyword, expression, semicolon);
}
- /**
- * Parse a setter. The [commentAndMetadata] is the documentation comment and
- * metadata to be associated with the declaration. The [externalKeyword] is
- * the 'external' token. The [staticKeyword] is the static keyword, or `null`
- * if the setter is not static. The [returnType] is the return type that has
- * already been parsed, or `null` if there was no return type. Return the
- * setter that was parsed.
- *
- * This method assumes that the current token matches `Keyword.SET`.
- *
- * setter ::=
- * setterSignature functionBody?
- *
- * setterSignature ::=
- * 'external'? 'static'? returnType? 'set' identifier formalParameterList
- */
+ /// Parse a setter. The [commentAndMetadata] is the documentation comment and
+ /// metadata to be associated with the declaration. The [externalKeyword] is
+ /// the 'external' token. The [staticKeyword] is the static keyword, or `null`
+ /// if the setter is not static. The [returnType] is the return type that has
+ /// already been parsed, or `null` if there was no return type. Return the
+ /// setter that was parsed.
+ ///
+ /// This method assumes that the current token matches `Keyword.SET`.
+ ///
+ /// setter ::=
+ /// setterSignature functionBody?
+ ///
+ /// setterSignature ::=
+ /// 'external'? 'static'? returnType? 'set' identifier formalParameterList
MethodDeclaration parseSetter(CommentAndMetadata commentAndMetadata,
Token externalKeyword, Token staticKeyword, TypeAnnotation returnType) {
Token propertyKeyword = getAndAdvance();
@@ -4786,13 +4518,11 @@
body);
}
- /**
- * Parse a shift expression. Return the shift expression that was parsed.
- *
- * shiftExpression ::=
- * additiveExpression (shiftOperator additiveExpression)*
- * | 'super' (shiftOperator additiveExpression)+
- */
+ /// Parse a shift expression. Return the shift expression that was parsed.
+ ///
+ /// shiftExpression ::=
+ /// additiveExpression (shiftOperator additiveExpression)*
+ /// | 'super' (shiftOperator additiveExpression)+
Expression parseShiftExpression() {
Expression expression;
if (_currentToken.keyword == Keyword.SUPER &&
@@ -4808,12 +4538,10 @@
return expression;
}
- /**
- * Parse a simple identifier. Return the simple identifier that was parsed.
- *
- * identifier ::=
- * IDENTIFIER
- */
+ /// Parse a simple identifier. Return the simple identifier that was parsed.
+ ///
+ /// identifier ::=
+ /// IDENTIFIER
SimpleIdentifier parseSimpleIdentifier(
{bool allowKeyword: false, bool isDeclaration: false}) {
if (_matchesIdentifier() ||
@@ -4824,22 +4552,18 @@
return createSyntheticIdentifier(isDeclaration: isDeclaration);
}
- /**
- * Parse a statement, starting with the given [token]. Return the statement
- * that was parsed, or `null` if the tokens do not represent a recognizable
- * statement.
- */
+ /// Parse a statement, starting with the given [token]. Return the statement
+ /// that was parsed, or `null` if the tokens do not represent a recognizable
+ /// statement.
Statement parseStatement(Token token) {
_currentToken = token;
return parseStatement2();
}
- /**
- * Parse a statement. Return the statement that was parsed.
- *
- * statement ::=
- * label* nonLabeledStatement
- */
+ /// Parse a statement. Return the statement that was parsed.
+ ///
+ /// statement ::=
+ /// label* nonLabeledStatement
Statement parseStatement2() {
if (_treeDepth > _MAX_TREE_DEPTH) {
throw new _TooDeepTreeError();
@@ -4866,23 +4590,19 @@
}
}
- /**
- * Parse a sequence of statements, starting with the given [token]. Return the
- * statements that were parsed, or `null` if the tokens do not represent a
- * recognizable sequence of statements.
- */
+ /// Parse a sequence of statements, starting with the given [token]. Return
+ /// the statements that were parsed, or `null` if the tokens do not represent
+ /// a recognizable sequence of statements.
List<Statement> parseStatements(Token token) {
_currentToken = token;
return _parseStatementList();
}
- /**
- * Parse a string literal. Return the string literal that was parsed.
- *
- * stringLiteral ::=
- * MULTI_LINE_STRING+
- * | SINGLE_LINE_STRING+
- */
+ /// Parse a string literal. Return the string literal that was parsed.
+ ///
+ /// stringLiteral ::=
+ /// MULTI_LINE_STRING+
+ /// | SINGLE_LINE_STRING+
StringLiteral parseStringLiteral() {
if (_matches(TokenType.STRING)) {
return _parseStringLiteralUnchecked();
@@ -4891,15 +4611,13 @@
return createSyntheticStringLiteral();
}
- /**
- * Parse a super constructor invocation. Return the super constructor
- * invocation that was parsed.
- *
- * This method assumes that the current token matches [Keyword.SUPER].
- *
- * superConstructorInvocation ::=
- * 'super' ('.' identifier)? arguments
- */
+ /// Parse a super constructor invocation. Return the super constructor
+ /// invocation that was parsed.
+ ///
+ /// This method assumes that the current token matches [Keyword.SUPER].
+ ///
+ /// superConstructorInvocation ::=
+ /// 'super' ('.' identifier)? arguments
SuperConstructorInvocation parseSuperConstructorInvocation() {
Token keyword = getAndAdvance();
Token period = null;
@@ -4913,18 +4631,16 @@
keyword, period, constructorName, argumentList);
}
- /**
- * Parse a switch statement. Return the switch statement that was parsed.
- *
- * switchStatement ::=
- * 'switch' '(' expression ')' '{' switchCase* defaultCase? '}'
- *
- * switchCase ::=
- * label* ('case' expression ':') statements
- *
- * defaultCase ::=
- * label* 'default' ':' statements
- */
+ /// Parse a switch statement. Return the switch statement that was parsed.
+ ///
+ /// switchStatement ::=
+ /// 'switch' '(' expression ')' '{' switchCase* defaultCase? '}'
+ ///
+ /// switchCase ::=
+ /// label* ('case' expression ':') statements
+ ///
+ /// defaultCase ::=
+ /// label* 'default' ':' statements
SwitchStatement parseSwitchStatement() {
bool wasInSwitch = _inSwitch;
_inSwitch = true;
@@ -5005,14 +4721,12 @@
}
}
- /**
- * Parse a symbol literal. Return the symbol literal that was parsed.
- *
- * This method assumes that the current token matches [TokenType.HASH].
- *
- * symbolLiteral ::=
- * '#' identifier ('.' identifier)*
- */
+ /// Parse a symbol literal. Return the symbol literal that was parsed.
+ ///
+ /// This method assumes that the current token matches [TokenType.HASH].
+ ///
+ /// symbolLiteral ::=
+ /// '#' identifier ('.' identifier)*
SymbolLiteral parseSymbolLiteral() {
Token poundSign = getAndAdvance();
List<Token> components = <Token>[];
@@ -5038,14 +4752,12 @@
return astFactory.symbolLiteral(poundSign, components);
}
- /**
- * Parse a throw expression. Return the throw expression that was parsed.
- *
- * This method assumes that the current token matches [Keyword.THROW].
- *
- * throwExpression ::=
- * 'throw' expression
- */
+ /// Parse a throw expression. Return the throw expression that was parsed.
+ ///
+ /// This method assumes that the current token matches [Keyword.THROW].
+ ///
+ /// throwExpression ::=
+ /// 'throw' expression
Expression parseThrowExpression() {
Token keyword = getAndAdvance();
TokenType type = _currentToken.type;
@@ -5058,14 +4770,12 @@
return astFactory.throwExpression(keyword, expression);
}
- /**
- * Parse a throw expression. Return the throw expression that was parsed.
- *
- * This method assumes that the current token matches [Keyword.THROW].
- *
- * throwExpressionWithoutCascade ::=
- * 'throw' expressionWithoutCascade
- */
+ /// Parse a throw expression. Return the throw expression that was parsed.
+ ///
+ /// This method assumes that the current token matches [Keyword.THROW].
+ ///
+ /// throwExpressionWithoutCascade ::=
+ /// 'throw' expressionWithoutCascade
Expression parseThrowExpressionWithoutCascade() {
Token keyword = getAndAdvance();
TokenType type = _currentToken.type;
@@ -5078,24 +4788,22 @@
return astFactory.throwExpression(keyword, expression);
}
- /**
- * Parse a try statement. Return the try statement that was parsed.
- *
- * This method assumes that the current token matches [Keyword.TRY].
- *
- * tryStatement ::=
- * 'try' block (onPart+ finallyPart? | finallyPart)
- *
- * onPart ::=
- * catchPart block
- * | 'on' type catchPart? block
- *
- * catchPart ::=
- * 'catch' '(' identifier (',' identifier)? ')'
- *
- * finallyPart ::=
- * 'finally' block
- */
+ /// Parse a try statement. Return the try statement that was parsed.
+ ///
+ /// This method assumes that the current token matches [Keyword.TRY].
+ ///
+ /// tryStatement ::=
+ /// 'try' block (onPart+ finallyPart? | finallyPart)
+ ///
+ /// onPart ::=
+ /// catchPart block
+ /// | 'on' type catchPart? block
+ ///
+ /// catchPart ::=
+ /// 'catch' '(' identifier (',' identifier)? ')'
+ ///
+ /// finallyPart ::=
+ /// 'finally' block
Statement parseTryStatement() {
Token tryKeyword = getAndAdvance();
Block body = _parseBlockChecked();
@@ -5147,25 +4855,23 @@
tryKeyword, body, catchClauses, finallyKeyword, finallyClause);
}
- /**
- * Parse a type alias. The [commentAndMetadata] is the metadata to be
- * associated with the member. Return the type alias that was parsed.
- *
- * This method assumes that the current token matches [Keyword.TYPEDEF].
- *
- * typeAlias ::=
- * 'typedef' typeAliasBody
- * | genericTypeAlias
- *
- * typeAliasBody ::=
- * functionTypeAlias
- *
- * functionTypeAlias ::=
- * functionPrefix typeParameterList? formalParameterList ';'
- *
- * functionPrefix ::=
- * returnType? name
- */
+ /// Parse a type alias. The [commentAndMetadata] is the metadata to be
+ /// associated with the member. Return the type alias that was parsed.
+ ///
+ /// This method assumes that the current token matches [Keyword.TYPEDEF].
+ ///
+ /// typeAlias ::=
+ /// 'typedef' typeAliasBody
+ /// | genericTypeAlias
+ ///
+ /// typeAliasBody ::=
+ /// functionTypeAlias
+ ///
+ /// functionTypeAlias ::=
+ /// functionPrefix typeParameterList? formalParameterList ';'
+ ///
+ /// functionPrefix ::=
+ /// returnType? name
TypeAlias parseTypeAlias(CommentAndMetadata commentAndMetadata) {
Token keyword = getAndAdvance();
if (_matchesIdentifier()) {
@@ -5186,13 +4892,11 @@
return _parseFunctionTypeAlias(commentAndMetadata, keyword);
}
- /**
- * Parse a type.
- *
- * type ::=
- * typeWithoutFunction
- * | functionType
- */
+ /// Parse a type.
+ ///
+ /// type ::=
+ /// typeWithoutFunction
+ /// | functionType
TypeAnnotation parseTypeAnnotation(bool inExpression) {
TypeAnnotation type = null;
if (_atGenericFunctionTypeAfterReturnType(_currentToken)) {
@@ -5207,18 +4911,16 @@
return type;
}
- /**
- * Parse a list of type arguments. Return the type argument list that was
- * parsed.
- *
- * This method assumes that the current token matches `TokenType.LT`.
- *
- * typeArguments ::=
- * '<' typeList '>'
- *
- * typeList ::=
- * type (',' type)*
- */
+ /// Parse a list of type arguments. Return the type argument list that was
+ /// parsed.
+ ///
+ /// This method assumes that the current token matches `TokenType.LT`.
+ ///
+ /// typeArguments ::=
+ /// '<' typeList '>'
+ ///
+ /// typeList ::=
+ /// type (',' type)*
TypeArgumentList parseTypeArgumentList() {
Token leftBracket = getAndAdvance();
List<TypeAnnotation> arguments = <TypeAnnotation>[
@@ -5231,26 +4933,22 @@
return astFactory.typeArgumentList(leftBracket, arguments, rightBracket);
}
- /**
- * Parse a type which is not void and is not a function type. Return the type
- * that was parsed.
- *
- * typeNotVoidWithoutFunction ::=
- * qualified typeArguments?
- */
+ /// Parse a type which is not void and is not a function type. Return the type
+ /// that was parsed.
+ ///
+ /// typeNotVoidWithoutFunction ::=
+ /// qualified typeArguments?
// TODO(eernst): Rename this to `parseTypeNotVoidWithoutFunction`?
// Apparently, it was named `parseTypeName` before type arguments existed.
TypeName parseTypeName(bool inExpression) {
return _parseTypeName(inExpression);
}
- /**
- * Parse a type which is not `void`.
- *
- * typeNotVoid ::=
- * functionType
- * | typeNotVoidWithoutFunction
- */
+ /// Parse a type which is not `void`.
+ ///
+ /// typeNotVoid ::=
+ /// functionType
+ /// | typeNotVoidWithoutFunction
TypeAnnotation parseTypeNotVoid(bool inExpression) {
TypeAnnotation type = null;
if (_atGenericFunctionTypeAfterReturnType(_currentToken)) {
@@ -5269,12 +4967,10 @@
return type;
}
- /**
- * Parse a type parameter. Return the type parameter that was parsed.
- *
- * typeParameter ::=
- * metadata name ('extends' bound)?
- */
+ /// Parse a type parameter. Return the type parameter that was parsed.
+ ///
+ /// typeParameter ::=
+ /// metadata name ('extends' bound)?
TypeParameter parseTypeParameter() {
CommentAndMetadata commentAndMetadata = parseCommentAndMetadata();
SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true);
@@ -5288,15 +4984,13 @@
commentAndMetadata.metadata, name, null, null);
}
- /**
- * Parse a list of type parameters. Return the list of type parameters that
- * were parsed.
- *
- * This method assumes that the current token matches `TokenType.LT`.
- *
- * typeParameterList ::=
- * '<' typeParameter (',' typeParameter)* '>'
- */
+ /// Parse a list of type parameters. Return the list of type parameters that
+ /// were parsed.
+ ///
+ /// This method assumes that the current token matches `TokenType.LT`.
+ ///
+ /// typeParameterList ::=
+ /// '<' typeParameter (',' typeParameter)* '>'
TypeParameterList parseTypeParameterList() {
Token leftBracket = getAndAdvance();
List<TypeParameter> typeParameters = <TypeParameter>[parseTypeParameter()];
@@ -5308,13 +5002,11 @@
leftBracket, typeParameters, rightBracket);
}
- /**
- * Parse a type which is not a function type.
- *
- * typeWithoutFunction ::=
- * `void`
- * | typeNotVoidWithoutFunction
- */
+ /// Parse a type which is not a function type.
+ ///
+ /// typeWithoutFunction ::=
+ /// `void`
+ /// | typeNotVoidWithoutFunction
TypeAnnotation parseTypeWithoutFunction(bool inExpression) {
if (_currentToken.keyword == Keyword.VOID) {
return astFactory.typeName(
@@ -5324,17 +5016,15 @@
}
}
- /**
- * Parse a unary expression. Return the unary expression that was parsed.
- *
- * unaryExpression ::=
- * prefixOperator unaryExpression
- * | awaitExpression
- * | postfixExpression
- * | unaryOperator 'super'
- * | '-' 'super'
- * | incrementOperator assignableExpression
- */
+ /// Parse a unary expression. Return the unary expression that was parsed.
+ ///
+ /// unaryExpression ::=
+ /// prefixOperator unaryExpression
+ /// | awaitExpression
+ /// | postfixExpression
+ /// | unaryOperator 'super'
+ /// | '-' 'super'
+ /// | incrementOperator assignableExpression
Expression parseUnaryExpression() {
TokenType type = _currentToken.type;
if (type == TokenType.MINUS ||
@@ -5400,13 +5090,11 @@
return parsePostfixExpression();
}
- /**
- * Parse a variable declaration. Return the variable declaration that was
- * parsed.
- *
- * variableDeclaration ::=
- * identifier ('=' expression)?
- */
+ /// Parse a variable declaration. Return the variable declaration that was
+ /// parsed.
+ ///
+ /// variableDeclaration ::=
+ /// identifier ('=' expression)?
VariableDeclaration parseVariableDeclaration() {
// TODO(paulberry): prior to the fix for bug 23204, we permitted
// annotations before variable declarations (e.g. "String @deprecated s;").
@@ -5427,14 +5115,12 @@
return astFactory.variableDeclaration(name, equals, initializer);
}
- /**
- * Parse a variable declaration list. The [commentAndMetadata] is the metadata
- * to be associated with the variable declaration list. Return the variable
- * declaration list that was parsed.
- *
- * variableDeclarationList ::=
- * finalConstVarOrType variableDeclaration (',' variableDeclaration)*
- */
+ /// Parse a variable declaration list. The [commentAndMetadata] is the
+ /// metadata to be associated with the variable declaration list. Return the
+ /// variable declaration list that was parsed.
+ ///
+ /// variableDeclarationList ::=
+ /// finalConstVarOrType variableDeclaration (',' variableDeclaration)*
VariableDeclarationList parseVariableDeclarationListAfterMetadata(
CommentAndMetadata commentAndMetadata) {
FinalConstVarOrType holder = parseFinalConstVarOrType(false);
@@ -5442,17 +5128,15 @@
commentAndMetadata, holder.keyword, holder.type);
}
- /**
- * Parse a variable declaration list. The [commentAndMetadata] is the metadata
- * to be associated with the variable declaration list, or `null` if there is
- * no attempt at parsing the comment and metadata. The [keyword] is the token
- * representing the 'final', 'const' or 'var' keyword, or `null` if there is
- * no keyword. The [type] is the type of the variables in the list. Return the
- * variable declaration list that was parsed.
- *
- * variableDeclarationList ::=
- * finalConstVarOrType variableDeclaration (',' variableDeclaration)*
- */
+ /// Parse a variable declaration list. The [commentAndMetadata] is the
+ /// metadata to be associated with the variable declaration list, or `null`
+ /// if there is no attempt at parsing the comment and metadata. The [keyword]
+ /// is the token representing the 'final', 'const' or 'var' keyword, or
+ /// `null` if there is no keyword. The [type] is the type of the variables in
+ /// the list. Return the variable declaration list that was parsed.
+ ///
+ /// variableDeclarationList ::=
+ /// finalConstVarOrType variableDeclaration (',' variableDeclaration)*
VariableDeclarationList parseVariableDeclarationListAfterType(
CommentAndMetadata commentAndMetadata,
Token keyword,
@@ -5472,15 +5156,13 @@
commentAndMetadata?.metadata, keyword, type, variables);
}
- /**
- * Parse a variable declaration statement. The [commentAndMetadata] is the
- * metadata to be associated with the variable declaration statement, or
- * `null` if there is no attempt at parsing the comment and metadata. Return
- * the variable declaration statement that was parsed.
- *
- * variableDeclarationStatement ::=
- * variableDeclarationList ';'
- */
+ /// Parse a variable declaration statement. The [commentAndMetadata] is the
+ /// metadata to be associated with the variable declaration statement, or
+ /// `null` if there is no attempt at parsing the comment and metadata. Return
+ /// the variable declaration statement that was parsed.
+ ///
+ /// variableDeclarationStatement ::=
+ /// variableDeclarationList ';'
VariableDeclarationStatement parseVariableDeclarationStatementAfterMetadata(
CommentAndMetadata commentAndMetadata) {
// Token startToken = currentToken;
@@ -5496,14 +5178,12 @@
return astFactory.variableDeclarationStatement(variableList, semicolon);
}
- /**
- * Parse a while statement. Return the while statement that was parsed.
- *
- * This method assumes that the current token matches [Keyword.WHILE].
- *
- * whileStatement ::=
- * 'while' '(' expression ')' statement
- */
+ /// Parse a while statement. Return the while statement that was parsed.
+ ///
+ /// This method assumes that the current token matches [Keyword.WHILE].
+ ///
+ /// whileStatement ::=
+ /// 'while' '(' expression ')' statement
Statement parseWhileStatement() {
bool wasInLoop = _inLoop;
_inLoop = true;
@@ -5520,14 +5200,12 @@
}
}
- /**
- * Parse a with clause. Return the with clause that was parsed.
- *
- * This method assumes that the current token matches `Keyword.WITH`.
- *
- * withClause ::=
- * 'with' typeName (',' typeName)*
- */
+ /// Parse a with clause. Return the with clause that was parsed.
+ ///
+ /// This method assumes that the current token matches `Keyword.WITH`.
+ ///
+ /// withClause ::=
+ /// 'with' typeName (',' typeName)*
WithClause parseWithClause() {
Token withKeyword = getAndAdvance();
List<TypeName> types = <TypeName>[];
@@ -5538,14 +5216,12 @@
return astFactory.withClause(withKeyword, types);
}
- /**
- * Parse a yield statement. Return the yield statement that was parsed.
- *
- * This method assumes that the current token matches [Keyword.YIELD].
- *
- * yieldStatement ::=
- * 'yield' '*'? expression ';'
- */
+ /// Parse a yield statement. Return the yield statement that was parsed.
+ ///
+ /// This method assumes that the current token matches [Keyword.YIELD].
+ ///
+ /// yieldStatement ::=
+ /// 'yield' '*'? expression ';'
YieldStatement parseYieldStatement() {
Token yieldToken = getAndAdvance();
Token star = null;
@@ -5557,14 +5233,12 @@
return astFactory.yieldStatement(yieldToken, star, expression, semicolon);
}
- /**
- * Parse a formal parameter list, starting at the [startToken], without
- * actually creating a formal parameter list or changing the current token.
- * Return the token following the parameter list that was parsed, or `null`
- * if the given token is not the first token in a valid parameter list.
- *
- * This method must be kept in sync with [parseFormalParameterList].
- */
+ /// Parse a formal parameter list, starting at the [startToken], without
+ /// actually creating a formal parameter list or changing the current token.
+ /// Return the token following the parameter list that was parsed, or `null`
+ /// if the given token is not the first token in a valid parameter list.
+ ///
+ /// This method must be kept in sync with [parseFormalParameterList].
Token skipFormalParameterList(Token startToken) {
if (!_tokenMatches(startToken, TokenType.OPEN_PAREN)) {
return null;
@@ -5572,16 +5246,14 @@
return (startToken as BeginToken).endToken?.next;
}
- /**
- * Parse the portion of a generic function type after the return type,
- * starting at the [startToken], without actually creating a generic function
- * type or changing the current token. Return the token following the generic
- * function type that was parsed, or `null` if the given token is not the
- * first token in a valid generic function type.
- *
- * This method must be kept in sync with
- * [parseGenericFunctionTypeAfterReturnType].
- */
+ /// Parse the portion of a generic function type after the return type,
+ /// starting at the [startToken], without actually creating a generic function
+ /// type or changing the current token. Return the token following the generic
+ /// function type that was parsed, or `null` if the given token is not the
+ /// first token in a valid generic function type.
+ ///
+ /// This method must be kept in sync with
+ /// [parseGenericFunctionTypeAfterReturnType].
Token skipGenericFunctionTypeAfterReturnType(Token startToken) {
Token next = startToken.next; // Skip 'Function'
if (_tokenMatches(next, TokenType.LT)) {
@@ -5593,17 +5265,16 @@
return skipFormalParameterList(next);
}
- /**
- * Parse a prefixed identifier, starting at the [startToken], without actually
- * creating a prefixed identifier or changing the current token. Return the
- * token following the prefixed identifier that was parsed, or `null` if the
- * given token is not the first token in a valid prefixed identifier.
- *
- * This method must be kept in sync with [parsePrefixedIdentifier].
- *
- * prefixedIdentifier ::=
- * identifier ('.' identifier)?
- */
+ /// Parse a prefixed identifier, starting at the [startToken], without
+ /// actually creating a prefixed identifier or changing the current token.
+ /// Return the token following the prefixed identifier that was parsed, or
+ /// `null` if the given token is not the first token in a valid prefixed
+ /// identifier.
+ ///
+ /// This method must be kept in sync with [parsePrefixedIdentifier].
+ ///
+ /// prefixedIdentifier ::=
+ /// identifier ('.' identifier)?
Token skipPrefixedIdentifier(Token startToken) {
Token token = skipSimpleIdentifier(startToken);
if (token == null) {
@@ -5625,17 +5296,15 @@
return null;
}
- /**
- * Parse a simple identifier, starting at the [startToken], without actually
- * creating a simple identifier or changing the current token. Return the
- * token following the simple identifier that was parsed, or `null` if the
- * given token is not the first token in a valid simple identifier.
- *
- * This method must be kept in sync with [parseSimpleIdentifier].
- *
- * identifier ::=
- * IDENTIFIER
- */
+ /// Parse a simple identifier, starting at the [startToken], without actually
+ /// creating a simple identifier or changing the current token. Return the
+ /// token following the simple identifier that was parsed, or `null` if the
+ /// given token is not the first token in a valid simple identifier.
+ ///
+ /// This method must be kept in sync with [parseSimpleIdentifier].
+ ///
+ /// identifier ::=
+ /// IDENTIFIER
Token skipSimpleIdentifier(Token startToken) {
if (_tokenMatches(startToken, TokenType.IDENTIFIER) ||
_tokenMatchesPseudoKeyword(startToken)) {
@@ -5644,18 +5313,16 @@
return null;
}
- /**
- * Parse a string literal, starting at the [startToken], without actually
- * creating a string literal or changing the current token. Return the token
- * following the string literal that was parsed, or `null` if the given token
- * is not the first token in a valid string literal.
- *
- * This method must be kept in sync with [parseStringLiteral].
- *
- * stringLiteral ::=
- * MULTI_LINE_STRING+
- * | SINGLE_LINE_STRING+
- */
+ /// Parse a string literal, starting at the [startToken], without actually
+ /// creating a string literal or changing the current token. Return the token
+ /// following the string literal that was parsed, or `null` if the given token
+ /// is not the first token in a valid string literal.
+ ///
+ /// This method must be kept in sync with [parseStringLiteral].
+ ///
+ /// stringLiteral ::=
+ /// MULTI_LINE_STRING+
+ /// | SINGLE_LINE_STRING+
Token skipStringLiteral(Token startToken) {
Token token = startToken;
while (token != null && _tokenMatches(token, TokenType.STRING)) {
@@ -5672,14 +5339,12 @@
return token;
}
- /**
- * Parse a type annotation, starting at the [startToken], without actually
- * creating a type annotation or changing the current token. Return the token
- * following the type annotation that was parsed, or `null` if the given token
- * is not the first token in a valid type annotation.
- *
- * This method must be kept in sync with [parseTypeAnnotation].
- */
+ /// Parse a type annotation, starting at the [startToken], without actually
+ /// creating a type annotation or changing the current token. Return the token
+ /// following the type annotation that was parsed, or `null` if the given
+ /// token is not the first token in a valid type annotation.
+ ///
+ /// This method must be kept in sync with [parseTypeAnnotation].
Token skipTypeAnnotation(Token startToken) {
Token next = null;
if (_atGenericFunctionTypeAfterReturnType(startToken)) {
@@ -5694,21 +5359,19 @@
return next;
}
- /**
- * Parse a list of type arguments, starting at the [startToken], without
- * actually creating a type argument list or changing the current token.
- * Return the token following the type argument list that was parsed, or
- * `null` if the given token is not the first token in a valid type argument
- * list.
- *
- * This method must be kept in sync with [parseTypeArgumentList].
- *
- * typeArguments ::=
- * '<' typeList '>'
- *
- * typeList ::=
- * type (',' type)*
- */
+ /// Parse a list of type arguments, starting at the [startToken], without
+ /// actually creating a type argument list or changing the current token.
+ /// Return the token following the type argument list that was parsed, or
+ /// `null` if the given token is not the first token in a valid type argument
+ /// list.
+ ///
+ /// This method must be kept in sync with [parseTypeArgumentList].
+ ///
+ /// typeArguments ::=
+ /// '<' typeList '>'
+ ///
+ /// typeList ::=
+ /// type (',' type)*
Token skipTypeArgumentList(Token startToken) {
Token token = startToken;
if (!_tokenMatches(token, TokenType.LT)) {
@@ -5740,17 +5403,15 @@
return null;
}
- /**
- * Parse a type name, starting at the [startToken], without actually creating
- * a type name or changing the current token. Return the token following the
- * type name that was parsed, or `null` if the given token is not the first
- * token in a valid type name.
- *
- * This method must be kept in sync with [parseTypeName].
- *
- * type ::=
- * qualified typeArguments?
- */
+ /// Parse a type name, starting at the [startToken], without actually creating
+ /// a type name or changing the current token. Return the token following the
+ /// type name that was parsed, or `null` if the given token is not the first
+ /// token in a valid type name.
+ ///
+ /// This method must be kept in sync with [parseTypeName].
+ ///
+ /// type ::=
+ /// qualified typeArguments?
Token skipTypeName(Token startToken) {
Token token = skipPrefixedIdentifier(startToken);
if (token == null) {
@@ -5762,14 +5423,13 @@
return token;
}
- /**
- * Parse a type parameter list, starting at the [startToken], without actually
- * creating a type parameter list or changing the current token. Return the
- * token following the type parameter list that was parsed, or `null` if the
- * given token is not the first token in a valid type parameter list.
- *
- * This method must be kept in sync with [parseTypeParameterList].
- */
+ /// Parse a type parameter list, starting at the [startToken], without
+ /// actually creating a type parameter list or changing the current token.
+ /// Return the token following the type parameter list that was parsed, or
+ /// `null` if the given token is not the first token in a valid type parameter
+ /// list.
+ ///
+ /// This method must be kept in sync with [parseTypeParameterList].
Token skipTypeParameterList(Token startToken) {
if (!_tokenMatches(startToken, TokenType.LT)) {
return null;
@@ -5792,14 +5452,12 @@
return null;
}
- /**
- * Parse a typeWithoutFunction, starting at the [startToken], without actually
- * creating a TypeAnnotation or changing the current token. Return the token
- * following the typeWithoutFunction that was parsed, or `null` if the given
- * token is not the first token in a valid typeWithoutFunction.
- *
- * This method must be kept in sync with [parseTypeWithoutFunction].
- */
+ /// Parse a typeWithoutFunction, starting at the [startToken], without
+ /// actually creating a TypeAnnotation or changing the current token. Return
+ /// the token following the typeWithoutFunction that was parsed, or `null` if
+ /// the given token is not the first token in a valid typeWithoutFunction.
+ ///
+ /// This method must be kept in sync with [parseTypeWithoutFunction].
Token skipTypeWithoutFunction(Token startToken) {
if (startToken.keyword == Keyword.VOID) {
return startToken.next;
@@ -5808,20 +5466,16 @@
}
}
- /**
- * Advance to the next token in the token stream.
- */
+ /// Advance to the next token in the token stream.
void _advance() {
_currentToken = _currentToken.next;
}
- /**
- * Append the character equivalent of the given [codePoint] to the given
- * [builder]. Use the [startIndex] and [endIndex] to report an error, and
- * don't append anything to the builder, if the code point is invalid. The
- * [escapeSequence] is the escape sequence that was parsed to produce the
- * code point (used for error reporting).
- */
+ /// Append the character equivalent of the given [codePoint] to the given
+ /// [builder]. Use the [startIndex] and [endIndex] to report an error, and
+ /// don't append anything to the builder, if the code point is invalid. The
+ /// [escapeSequence] is the escape sequence that was parsed to produce the
+ /// code point (used for error reporting).
void _appendCodePoint(StringBuffer buffer, String source, int codePoint,
int startIndex, int endIndex) {
if (codePoint < 0 || codePoint > Character.MAX_CODE_POINT) {
@@ -5837,10 +5491,8 @@
}
}
- /**
- * Return `true` if we are positioned at the keyword 'Function' in a generic
- * function type alias.
- */
+ /// Return `true` if we are positioned at the keyword 'Function' in a generic
+ /// function type alias.
bool _atGenericFunctionTypeAfterReturnType(Token startToken) {
if (_tokenMatchesKeyword(startToken, Keyword.FUNCTION)) {
Token next = startToken.next;
@@ -5853,11 +5505,9 @@
return false;
}
- /**
- * Convert the given [method] declaration into the nearest valid top-level
- * function declaration (that is, the function declaration that most closely
- * captures the components of the given method declaration).
- */
+ /// Convert the given [method] declaration into the nearest valid top-level
+ /// function declaration (that is, the function declaration that most closely
+ /// captures the components of the given method declaration).
FunctionDeclaration _convertToFunctionDeclaration(MethodDeclaration method) =>
astFactory.functionDeclaration(
method.documentationComment,
@@ -5869,12 +5519,10 @@
astFactory.functionExpression(
method.typeParameters, method.parameters, method.body));
- /**
- * Return `true` if the current token could be the start of a compilation unit
- * member. This method is used for recovery purposes to decide when to stop
- * skipping tokens after finding an error while parsing a compilation unit
- * member.
- */
+ /// Return `true` if the current token could be the start of a compilation
+ /// unit member. This method is used for recovery purposes to decide when to
+ /// stop skipping tokens after finding an error while parsing a compilation
+ /// unit member.
bool _couldBeStartOfCompilationUnitMember() {
Keyword keyword = _currentToken.keyword;
Token next = _currentToken.next;
@@ -5921,23 +5569,17 @@
return false;
}
- /**
- * Return a synthetic token representing the given [keyword].
- */
+ /// Return a synthetic token representing the given [keyword].
Token _createSyntheticKeyword(Keyword keyword) =>
_injectToken(new SyntheticKeywordToken(keyword, _currentToken.offset));
- /**
- * Return a synthetic token with the given [type].
- */
+ /// Return a synthetic token with the given [type].
Token _createSyntheticToken(TokenType type) =>
_injectToken(new StringToken(type, "", _currentToken.offset));
- /**
- * Create and return a new token with the given [type]. The token will replace
- * the first portion of the given [token], so it will have the same offset and
- * will have any comments that might have preceeded the token.
- */
+ /// Create and return a new token with the given [type]. The token will
+ /// replace the first portion of the given [token], so it will have the same
+ /// offset and will have any comments that might have preceeded the token.
Token _createToken(Token token, TokenType type, {bool isBegin: false}) {
CommentToken comments = token.precedingComments;
if (comments == null) {
@@ -5951,23 +5593,21 @@
return new Token(type, token.offset, comments);
}
- /**
- * Check that the given [expression] is assignable and report an error if it
- * isn't.
- *
- * assignableExpression ::=
- * primary (arguments* assignableSelector)+
- * | 'super' unconditionalAssignableSelector
- * | identifier
- *
- * unconditionalAssignableSelector ::=
- * '[' expression ']'
- * | '.' identifier
- *
- * assignableSelector ::=
- * unconditionalAssignableSelector
- * | '?.' identifier
- */
+ /// Check that the given [expression] is assignable and report an error if it
+ /// isn't.
+ ///
+ /// assignableExpression ::=
+ /// primary (arguments* assignableSelector)+
+ /// | 'super' unconditionalAssignableSelector
+ /// | identifier
+ ///
+ /// unconditionalAssignableSelector ::=
+ /// '[' expression ']'
+ /// | '.' identifier
+ ///
+ /// assignableSelector ::=
+ /// unconditionalAssignableSelector
+ /// | '?.' identifier
void _ensureAssignable(Expression expression) {
if (expression != null && !expression.isAssignable) {
_reportErrorForCurrentToken(
@@ -5975,16 +5615,14 @@
}
}
- /**
- * If the current token has the expected type, return it after advancing to
- * the next token. Otherwise report an error and return the current token
- * without advancing.
- *
- * Note that the method [_expectGt] should be used if the argument to this
- * method would be [TokenType.GT].
- *
- * The [type] is the type of token that is expected.
- */
+ /// If the current token has the expected type, return it after advancing to
+ /// the next token. Otherwise report an error and return the current token
+ /// without advancing.
+ ///
+ /// Note that the method [_expectGt] should be used if the argument to this
+ /// method would be [TokenType.GT].
+ ///
+ /// The [type] is the type of token that is expected.
Token _expect(TokenType type) {
if (_matches(type)) {
return getAndAdvance();
@@ -6006,10 +5644,9 @@
return _createSyntheticToken(type);
}
- /**
- * If the current token has the type [TokenType.GT], return it after advancing
- * to the next token. Otherwise report an error and create a synthetic token.
- */
+ /// If the current token has the type [TokenType.GT], return it after
+ /// advancing to the next token. Otherwise report an error and create a
+ /// synthetic token.
Token _expectGt() {
if (_matchesGt()) {
return getAndAdvance();
@@ -6019,11 +5656,9 @@
return _createSyntheticToken(TokenType.GT);
}
- /**
- * If the current token is a keyword matching the given [keyword], return it
- * after advancing to the next token. Otherwise report an error and return the
- * current token without advancing.
- */
+ /// If the current token is a keyword matching the given [keyword], return it
+ /// after advancing to the next token. Otherwise report an error and return
+ /// the current token without advancing.
Token _expectKeyword(Keyword keyword) {
if (_matchesKeyword(keyword)) {
return getAndAdvance();
@@ -6035,11 +5670,9 @@
return _currentToken;
}
- /**
- * Search the given list of [ranges] for a range that contains the given
- * [index]. Return the range that was found, or `null` if none of the ranges
- * contain the index.
- */
+ /// Search the given list of [ranges] for a range that contains the given
+ /// [index]. Return the range that was found, or `null` if none of the ranges
+ /// contain the index.
List<int> _findRange(List<List<int>> ranges, int index) {
int rangeCount = ranges.length;
for (int i = 0; i < rangeCount; i++) {
@@ -6053,10 +5686,8 @@
return null;
}
- /**
- * Return a list of the ranges of characters in the given [comment] that
- * should be treated as code blocks.
- */
+ /// Return a list of the ranges of characters in the given [comment] that
+ /// should be treated as code blocks.
List<List<int>> _getCodeBlockRanges(String comment) {
List<List<int>> ranges = <List<int>>[];
int length = comment.length;
@@ -6118,11 +5749,9 @@
return ranges;
}
- /**
- * Return the end token associated with the given [beginToken], or `null` if
- * either the given token is not a begin token or it does not have an end
- * token associated with it.
- */
+ /// Return the end token associated with the given [beginToken], or `null` if
+ /// either the given token is not a begin token or it does not have an end
+ /// token associated with it.
Token _getEndToken(Token beginToken) {
if (beginToken is BeginToken) {
return beginToken.endToken;
@@ -6130,10 +5759,8 @@
return null;
}
- /**
- * Inject the given [token] into the token stream immediately before the
- * current token.
- */
+ /// Inject the given [token] into the token stream immediately before the
+ /// current token.
Token _injectToken(Token token) {
Token previous = _currentToken.previous;
token.setNext(_currentToken);
@@ -6141,9 +5768,7 @@
return token;
}
- /**
- * Return `true` if the given [character] is a valid hexadecimal digit.
- */
+ /// Return `true` if the given [character] is a valid hexadecimal digit.
bool _isHexDigit(int character) =>
(0x30 <= character && character <= 0x39) ||
(0x41 <= character && character <= 0x46) ||
@@ -6159,13 +5784,11 @@
return token != null && _tokenMatches(token, TokenType.OPEN_PAREN);
}
- /**
- * Return `true` if it looks like we have found the invocation of a named
- * constructor following the name of the type:
- * ```
- * typeArguments? '.' identifier '('
- * ```
- */
+ /// Return `true` if it looks like we have found the invocation of a named
+ /// constructor following the name of the type:
+ /// ```
+ /// typeArguments? '.' identifier '('
+ /// ```
bool _isLikelyNamedInstanceCreation() {
Token token = skipTypeArgumentList(_currentToken);
if (token != null && _tokenMatches(token, TokenType.PERIOD)) {
@@ -6177,17 +5800,16 @@
return false;
}
- /**
- * Given that we have just found bracketed text within the given [comment],
- * look to see whether that text is (a) followed by a parenthesized link
- * address, (b) followed by a colon, or (c) followed by optional whitespace
- * and another square bracket. The [rightIndex] is the index of the right
- * bracket. Return `true` if the bracketed text is followed by a link address.
- *
- * This method uses the syntax described by the
- * <a href="http://daringfireball.net/projects/markdown/syntax">markdown</a>
- * project.
- */
+ /// Given that we have just found bracketed text within the given [comment],
+ /// look to see whether that text is (a) followed by a parenthesized link
+ /// address, (b) followed by a colon, or (c) followed by optional whitespace
+ /// and another square bracket. The [rightIndex] is the index of the right
+ /// bracket. Return `true` if the bracketed text is followed by a link
+ /// address.
+ ///
+ /// This method uses the syntax described by the
+ /// <a href="http://daringfireball.net/projects/markdown/syntax">markdown</a>
+ /// project.
bool _isLinkText(String comment, int rightIndex) {
int length = comment.length;
int index = rightIndex + 1;
@@ -6208,10 +5830,8 @@
return nextChar == 0x5B;
}
- /**
- * Return `true` if the given [startToken] appears to be the beginning of an
- * operator declaration.
- */
+ /// Return `true` if the given [startToken] appears to be the beginning of an
+ /// operator declaration.
bool _isOperator(Token startToken) {
// Accept any operator here, even if it is not user definable.
if (!startToken.isOperator) {
@@ -6235,10 +5855,8 @@
return token != null && _tokenMatches(token, TokenType.OPEN_PAREN);
}
- /**
- * Return `true` if the [startToken] appears to be the first token of a type
- * name that is followed by a variable or field formal parameter.
- */
+ /// Return `true` if the [startToken] appears to be the first token of a type
+ /// name that is followed by a variable or field formal parameter.
bool _isTypedIdentifier(Token startToken) {
Token token = skipTypeAnnotation(startToken);
if (token == null) {
@@ -6258,10 +5876,8 @@
return false;
}
- /**
- * Return `true` if the given [expression] is a primary expression that is
- * allowed to be an assignable expression without any assignable selector.
- */
+ /// Return `true` if the given [expression] is a primary expression that is
+ /// allowed to be an assignable expression without any assignable selector.
bool _isValidAssignableExpression(Expression expression) {
if (expression is SimpleIdentifier) {
return true;
@@ -6273,28 +5889,22 @@
return false;
}
- /**
- * Increments the error reporting lock level. If level is more than `0`, then
- * [reportError] wont report any error.
- */
+ /// Increments the error reporting lock level. If level is more than `0`, then
+ /// [reportError] wont report any error.
void _lockErrorListener() {
_errorListenerLock++;
}
- /**
- * Return `true` if the current token has the given [type]. Note that the
- * method [_matchesGt] should be used if the argument to this method would be
- * [TokenType.GT].
- */
+ /// Return `true` if the current token has the given [type]. Note that the
+ /// method [_matchesGt] should be used if the argument to this method would be
+ /// [TokenType.GT].
bool _matches(TokenType type) => _currentToken.type == type;
- /**
- * Return `true` if the current token has a type of [TokenType.GT]. Note that
- * this method, unlike other variants, will modify the token stream if
- * possible to match desired type. In particular, if the next token is either
- * a '>>' or '>>>', the token stream will be re-written and `true` will be
- * returned.
- */
+ /// Return `true` if the current token has a type of [TokenType.GT]. Note that
+ /// this method, unlike other variants, will modify the token stream if
+ /// possible to match desired type. In particular, if the next token is either
+ /// a '>>' or '>>>', the token stream will be re-written and `true` will be
+ /// returned.
bool _matchesGt() {
TokenType currentType = _currentToken.type;
if (currentType == TokenType.GT) {
@@ -6330,23 +5940,17 @@
return false;
}
- /**
- * Return `true` if the current token is a valid identifier. Valid identifiers
- * include built-in identifiers (pseudo-keywords).
- */
+ /// Return `true` if the current token is a valid identifier. Valid
+ /// identifiers include built-in identifiers (pseudo-keywords).
bool _matchesIdentifier() => _tokenMatchesIdentifier(_currentToken);
- /**
- * Return `true` if the current token matches the given [keyword].
- */
+ /// Return `true` if the current token matches the given [keyword].
bool _matchesKeyword(Keyword keyword) =>
_tokenMatchesKeyword(_currentToken, keyword);
- /**
- * If the current token has the given [type], then advance to the next token
- * and return `true`. Otherwise, return `false` without advancing. This method
- * should not be invoked with an argument value of [TokenType.GT].
- */
+ /// If the current token has the given [type], then advance to the next token
+ /// and return `true`. Otherwise, return `false` without advancing. This
+ /// method should not be invoked with an argument value of [TokenType.GT].
bool _optional(TokenType type) {
if (_currentToken.type == type) {
_advance();
@@ -6355,10 +5959,8 @@
return false;
}
- /**
- * Parse an argument list when we need to check for an open paren and recover
- * when there isn't one. Return the argument list that was parsed.
- */
+ /// Parse an argument list when we need to check for an open paren and recover
+ /// when there isn't one. Return the argument list that was parsed.
ArgumentList _parseArgumentListChecked() {
if (_matches(TokenType.OPEN_PAREN)) {
return parseArgumentList();
@@ -6371,14 +5973,13 @@
null, _createSyntheticToken(TokenType.CLOSE_PAREN));
}
- /**
- * Parse an assert within a constructor's initializer list. Return the assert.
- *
- * This method assumes that the current token matches `Keyword.ASSERT`.
- *
- * assertInitializer ::=
- * 'assert' '(' expression [',' expression] ')'
- */
+ /// Parse an assert within a constructor's initializer list. Return the
+ /// assert.
+ ///
+ /// This method assumes that the current token matches `Keyword.ASSERT`.
+ ///
+ /// assertInitializer ::=
+ /// 'assert' '(' expression [',' expression] ')'
AssertInitializer _parseAssertInitializer() {
Token keyword = getAndAdvance();
Token leftParen = _expect(TokenType.OPEN_PAREN);
@@ -6401,13 +6002,11 @@
keyword, leftParen, expression, comma, message, rightParen);
}
- /**
- * Parse a block when we need to check for an open curly brace and recover
- * when there isn't one. Return the block that was parsed.
- *
- * block ::=
- * '{' statements '}'
- */
+ /// Parse a block when we need to check for an open curly brace and recover
+ /// when there isn't one. Return the block that was parsed.
+ ///
+ /// block ::=
+ /// '{' statements '}'
Block _parseBlockChecked() {
if (_matches(TokenType.OPEN_CURLY_BRACKET)) {
return parseBlock();
@@ -6421,15 +6020,13 @@
null, _createSyntheticToken(TokenType.CLOSE_CURLY_BRACKET));
}
- /**
- * Parse a list of class members. The [className] is the name of the class
- * whose members are being parsed. The [closingBracket] is the closing bracket
- * for the class, or `null` if the closing bracket is missing. Return the list
- * of class members that were parsed.
- *
- * classMembers ::=
- * (metadata memberDefinition)*
- */
+ /// Parse a list of class members. The [className] is the name of the class
+ /// whose members are being parsed. The [closingBracket] is the closing
+ /// bracket for the class, or `null` if the closing bracket is missing.
+ /// Return the list of class members that were parsed.
+ ///
+ /// classMembers ::=
+ /// (metadata memberDefinition)*
List<ClassMember> _parseClassMembers(String className, Token closingBracket) {
List<ClassMember> members = <ClassMember>[];
Token memberStart = _currentToken;
@@ -6461,20 +6058,18 @@
return members;
}
- /**
- * Parse a class type alias. The [commentAndMetadata] is the metadata to be
- * associated with the member. The [abstractKeyword] is the token representing
- * the 'abstract' keyword. The [classKeyword] is the token representing the
- * 'class' keyword. The [className] is the name of the alias, and the
- * [typeParameters] are the type parameters following the name. Return the
- * class type alias that was parsed.
- *
- * classTypeAlias ::=
- * identifier typeParameters? '=' 'abstract'? mixinApplication
- *
- * mixinApplication ::=
- * type withClause implementsClause? ';'
- */
+ /// Parse a class type alias. The [commentAndMetadata] is the metadata to be
+ /// associated with the member. The [abstractKeyword] is the token
+ /// representing the 'abstract' keyword. The [classKeyword] is the token
+ /// representing the 'class' keyword. The [className] is the name of the
+ /// alias, and the [typeParameters] are the type parameters following the
+ /// name. Return the class type alias that was parsed.
+ ///
+ /// classTypeAlias ::=
+ /// identifier typeParameters? '=' 'abstract'? mixinApplication
+ ///
+ /// mixinApplication ::=
+ /// type withClause implementsClause? ';'
ClassTypeAlias _parseClassTypeAliasAfterName(
CommentAndMetadata commentAndMetadata,
Token abstractKeyword,
@@ -6524,10 +6119,8 @@
semicolon);
}
- /**
- * Parse a list of configurations. Return the configurations that were parsed,
- * or `null` if there are no configurations.
- */
+ /// Parse a list of configurations. Return the configurations that were
+ /// parsed, or `null` if there are no configurations.
List<Configuration> _parseConfigurations() {
List<Configuration> configurations = null;
while (_matchesKeyword(Keyword.IF)) {
@@ -6637,20 +6230,18 @@
body);
}
- /**
- * Parse an enum constant declaration. Return the enum constant declaration
- * that was parsed.
- *
- * Specified:
- *
- * enumConstant ::=
- * id
- *
- * Actual:
- *
- * enumConstant ::=
- * metadata id
- */
+ /// Parse an enum constant declaration. Return the enum constant declaration
+ /// that was parsed.
+ ///
+ /// Specified:
+ ///
+ /// enumConstant ::=
+ /// id
+ ///
+ /// Actual:
+ ///
+ /// enumConstant ::=
+ /// metadata id
EnumConstantDeclaration _parseEnumConstantDeclaration() {
CommentAndMetadata commentAndMetadata = parseCommentAndMetadata();
SimpleIdentifier name;
@@ -6663,10 +6254,8 @@
commentAndMetadata.comment, commentAndMetadata.metadata, name);
}
- /**
- * Parse a list of formal parameters given that the list starts with the given
- * [leftParenthesis]. Return the formal parameters that were parsed.
- */
+ /// Parse a list of formal parameters given that the list starts with the
+ /// given [leftParenthesis]. Return the formal parameters that were parsed.
FormalParameterList _parseFormalParameterListAfterParen(Token leftParenthesis,
{bool inFunctionType: false}) {
if (_matches(TokenType.CLOSE_PAREN)) {
@@ -6837,27 +6426,23 @@
leftSquareBracket, rightSquareBracket, rightParenthesis);
}
- /**
- * Parse a list of formal parameters. Return the formal parameters that were
- * parsed.
- *
- * This method assumes that the current token matches `TokenType.OPEN_PAREN`.
- */
+ /// Parse a list of formal parameters. Return the formal parameters that were
+ /// parsed.
+ ///
+ /// This method assumes that the current token matches `TokenType.OPEN_PAREN`.
FormalParameterList _parseFormalParameterListUnchecked(
{bool inFunctionType: false}) {
return _parseFormalParameterListAfterParen(getAndAdvance(),
inFunctionType: inFunctionType);
}
- /**
- * Parse a function declaration statement. The [commentAndMetadata] is the
- * documentation comment and metadata to be associated with the declaration.
- * The [returnType] is the return type, or `null` if there is no return type.
- * Return the function declaration statement that was parsed.
- *
- * functionDeclarationStatement ::=
- * functionSignature functionBody
- */
+ /// Parse a function declaration statement. The [commentAndMetadata] is the
+ /// documentation comment and metadata to be associated with the declaration.
+ /// The [returnType] is the return type, or `null` if there is no return type.
+ /// Return the function declaration statement that was parsed.
+ ///
+ /// functionDeclarationStatement ::=
+ /// functionSignature functionBody
Statement _parseFunctionDeclarationStatementAfterReturnType(
CommentAndMetadata commentAndMetadata, TypeAnnotation returnType) {
FunctionDeclaration declaration =
@@ -6875,17 +6460,15 @@
return astFactory.functionDeclarationStatement(declaration);
}
- /**
- * Parse a function type alias. The [commentAndMetadata] is the metadata to be
- * associated with the member. The [keyword] is the token representing the
- * 'typedef' keyword. Return the function type alias that was parsed.
- *
- * functionTypeAlias ::=
- * functionPrefix typeParameterList? formalParameterList ';'
- *
- * functionPrefix ::=
- * returnType? name
- */
+ /// Parse a function type alias. The [commentAndMetadata] is the metadata to
+ /// be associated with the member. The [keyword] is the token representing the
+ /// 'typedef' keyword. Return the function type alias that was parsed.
+ ///
+ /// functionTypeAlias ::=
+ /// functionPrefix typeParameterList? formalParameterList ';'
+ ///
+ /// functionPrefix ::=
+ /// returnType? name
FunctionTypeAlias _parseFunctionTypeAlias(
CommentAndMetadata commentAndMetadata, Token keyword) {
TypeAnnotation returnType = null;
@@ -6951,12 +6534,10 @@
}
}
- /**
- * Parse the generic method or function's type parameters.
- *
- * For backwards compatibility this can optionally use comments.
- * See [parseGenericMethodComments].
- */
+ /// Parse the generic method or function's type parameters.
+ ///
+ /// For backwards compatibility this can optionally use comments.
+ /// See [parseGenericMethodComments].
TypeParameterList _parseGenericMethodTypeParameters() {
if (_matches(TokenType.LT)) {
return parseTypeParameterList();
@@ -6964,15 +6545,13 @@
return null;
}
- /**
- * Parse a library name. The [missingNameError] is the error code to be used
- * if the library name is missing. The [missingNameToken] is the token
- * associated with the error produced if the library name is missing. Return
- * the library name that was parsed.
- *
- * libraryName ::=
- * libraryIdentifier
- */
+ /// Parse a library name. The [missingNameError] is the error code to be used
+ /// if the library name is missing. The [missingNameToken] is the token
+ /// associated with the error produced if the library name is missing. Return
+ /// the library name that was parsed.
+ ///
+ /// libraryName ::=
+ /// libraryIdentifier
LibraryIdentifier _parseLibraryName(
ParserErrorCode missingNameError, Token missingNameToken) {
if (_matchesIdentifier()) {
@@ -6989,19 +6568,17 @@
.libraryIdentifier(<SimpleIdentifier>[createSyntheticIdentifier()]);
}
- /**
- * Parse a method declaration. The [commentAndMetadata] is the documentation
- * comment and metadata to be associated with the declaration. The
- * [externalKeyword] is the 'external' token. The [staticKeyword] is the
- * static keyword, or `null` if the getter is not static. The [returnType] is
- * the return type of the method. The [name] is the name of the method. The
- * [parameters] is the parameters to the method. Return the method declaration
- * that was parsed.
- *
- * functionDeclaration ::=
- * ('external' 'static'?)? functionSignature functionBody
- * | 'external'? functionSignature ';'
- */
+ /// Parse a method declaration. The [commentAndMetadata] is the documentation
+ /// comment and metadata to be associated with the declaration. The
+ /// [externalKeyword] is the 'external' token. The [staticKeyword] is the
+ /// static keyword, or `null` if the getter is not static. The [returnType] is
+ /// the return type of the method. The [name] is the name of the method. The
+ /// [parameters] is the parameters to the method. Return the method
+ /// declaration that was parsed.
+ ///
+ /// functionDeclaration ::=
+ /// ('external' 'static'?)? functionSignature functionBody
+ /// | 'external'? functionSignature ';'
MethodDeclaration _parseMethodDeclarationAfterParameters(
CommentAndMetadata commentAndMetadata,
Token externalKeyword,
@@ -7037,18 +6614,16 @@
body);
}
- /**
- * Parse a method declaration. The [commentAndMetadata] is the documentation
- * comment and metadata to be associated with the declaration. The
- * [externalKeyword] is the 'external' token. The [staticKeyword] is the
- * static keyword, or `null` if the getter is not static. The [returnType] is
- * the return type of the method. Return the method declaration that was
- * parsed.
- *
- * functionDeclaration ::=
- * 'external'? 'static'? functionSignature functionBody
- * | 'external'? functionSignature ';'
- */
+ /// Parse a method declaration. The [commentAndMetadata] is the documentation
+ /// comment and metadata to be associated with the declaration. The
+ /// [externalKeyword] is the 'external' token. The [staticKeyword] is the
+ /// static keyword, or `null` if the getter is not static. The [returnType] is
+ /// the return type of the method. Return the method declaration that was
+ /// parsed.
+ ///
+ /// functionDeclaration ::=
+ /// 'external'? 'static'? functionSignature functionBody
+ /// | 'external'? functionSignature ';'
MethodDeclaration _parseMethodDeclarationAfterReturnType(
CommentAndMetadata commentAndMetadata,
Token externalKeyword,
@@ -7084,34 +6659,30 @@
parameters);
}
- /**
- * Parse a class native clause. Return the native clause that was parsed.
- *
- * This method assumes that the current token matches `_NATIVE`.
- *
- * classNativeClause ::=
- * 'native' name
- */
+ /// Parse a class native clause. Return the native clause that was parsed.
+ ///
+ /// This method assumes that the current token matches `_NATIVE`.
+ ///
+ /// classNativeClause ::=
+ /// 'native' name
NativeClause _parseNativeClause() {
Token keyword = getAndAdvance();
StringLiteral name = parseStringLiteral();
return astFactory.nativeClause(keyword, name);
}
- /**
- * Parse an operator declaration starting after the 'operator' keyword. The
- * [commentAndMetadata] is the documentation comment and metadata to be
- * associated with the declaration. The [externalKeyword] is the 'external'
- * token. The [returnType] is the return type that has already been parsed, or
- * `null` if there was no return type. The [operatorKeyword] is the 'operator'
- * keyword. Return the operator declaration that was parsed.
- *
- * operatorDeclaration ::=
- * operatorSignature (';' | functionBody)
- *
- * operatorSignature ::=
- * 'external'? returnType? 'operator' operator formalParameterList
- */
+ /// Parse an operator declaration starting after the 'operator' keyword. The
+ /// [commentAndMetadata] is the documentation comment and metadata to be
+ /// associated with the declaration. The [externalKeyword] is the 'external'
+ /// token. The [returnType] is the return type that has already been parsed,
+ /// or `null` if there was no return type. The [operatorKeyword] is the
+ /// 'operator' keyword. Return the operator declaration that was parsed.
+ ///
+ /// operatorDeclaration ::=
+ /// operatorSignature (';' | functionBody)
+ ///
+ /// operatorSignature ::=
+ /// 'external'? returnType? 'operator' operator formalParameterList
MethodDeclaration _parseOperatorAfterKeyword(
CommentAndMetadata commentAndMetadata,
Token externalKeyword,
@@ -7157,10 +6728,8 @@
body);
}
- /**
- * Parse a return type if one is given, otherwise return `null` without
- * advancing. Return the return type that was parsed.
- */
+ /// Parse a return type if one is given, otherwise return `null` without
+ /// advancing. Return the return type that was parsed.
TypeAnnotation _parseOptionalReturnType() {
Keyword keyword = _currentToken.keyword;
if (keyword == Keyword.VOID) {
@@ -7198,10 +6767,8 @@
return null;
}
- /**
- * Parse a [TypeArgumentList] if present, otherwise return null.
- * This also supports the comment form, if enabled: `/*<T>*/`
- */
+ /// Parse a [TypeArgumentList] if present, otherwise return null.
+ /// This also supports the comment form, if enabled: `/*<T>*/`
TypeArgumentList _parseOptionalTypeArguments() {
if (_matches(TokenType.LT)) {
return parseTypeArgumentList();
@@ -7209,16 +6776,14 @@
return null;
}
- /**
- * Parse a part directive. The [commentAndMetadata] is the metadata to be
- * associated with the directive. Return the part or part-of directive that
- * was parsed.
- *
- * This method assumes that the current token matches `Keyword.PART`.
- *
- * partDirective ::=
- * metadata 'part' stringLiteral ';'
- */
+ /// Parse a part directive. The [commentAndMetadata] is the metadata to be
+ /// associated with the directive. Return the part or part-of directive that
+ /// was parsed.
+ ///
+ /// This method assumes that the current token matches `Keyword.PART`.
+ ///
+ /// partDirective ::=
+ /// metadata 'part' stringLiteral ';'
Directive _parsePartDirective(CommentAndMetadata commentAndMetadata) {
Token partKeyword = getAndAdvance();
StringLiteral partUri = _parseUri();
@@ -7227,17 +6792,15 @@
commentAndMetadata.metadata, partKeyword, partUri, semicolon);
}
- /**
- * Parse a part-of directive. The [commentAndMetadata] is the metadata to be
- * associated with the directive. Return the part or part-of directive that
- * was parsed.
- *
- * This method assumes that the current token matches [Keyword.PART] and that
- * the following token matches the identifier 'of'.
- *
- * partOfDirective ::=
- * metadata 'part' 'of' identifier ';'
- */
+ /// Parse a part-of directive. The [commentAndMetadata] is the metadata to be
+ /// associated with the directive. Return the part or part-of directive that
+ /// was parsed.
+ ///
+ /// This method assumes that the current token matches [Keyword.PART] and that
+ /// the following token matches the identifier 'of'.
+ ///
+ /// partOfDirective ::=
+ /// metadata 'part' 'of' identifier ';'
Directive _parsePartOfDirective(CommentAndMetadata commentAndMetadata) {
Token partKeyword = getAndAdvance();
Token ofKeyword = getAndAdvance();
@@ -7266,13 +6829,11 @@
semicolon);
}
- /**
- * Parse a prefixed identifier given that the given [qualifier] was already
- * parsed. Return the prefixed identifier that was parsed.
- *
- * prefixedIdentifier ::=
- * identifier ('.' identifier)?
- */
+ /// Parse a prefixed identifier given that the given [qualifier] was already
+ /// parsed. Return the prefixed identifier that was parsed.
+ ///
+ /// prefixedIdentifier ::=
+ /// identifier ('.' identifier)?
Identifier _parsePrefixedIdentifierAfterIdentifier(
SimpleIdentifier qualifier) {
if (!_matches(TokenType.PERIOD)) {
@@ -7283,28 +6844,24 @@
return astFactory.prefixedIdentifier(qualifier, period, qualified);
}
- /**
- * Parse a prefixed identifier. Return the prefixed identifier that was
- * parsed.
- *
- * This method assumes that the current token matches an identifier.
- *
- * prefixedIdentifier ::=
- * identifier ('.' identifier)?
- */
+ /// Parse a prefixed identifier. Return the prefixed identifier that was
+ /// parsed.
+ ///
+ /// This method assumes that the current token matches an identifier.
+ ///
+ /// prefixedIdentifier ::=
+ /// identifier ('.' identifier)?
Identifier _parsePrefixedIdentifierUnchecked() {
return _parsePrefixedIdentifierAfterIdentifier(
_parseSimpleIdentifierUnchecked());
}
- /**
- * Parse a simple identifier. Return the simple identifier that was parsed.
- *
- * This method assumes that the current token matches an identifier.
- *
- * identifier ::=
- * IDENTIFIER
- */
+ /// Parse a simple identifier. Return the simple identifier that was parsed.
+ ///
+ /// This method assumes that the current token matches an identifier.
+ ///
+ /// identifier ::=
+ /// IDENTIFIER
SimpleIdentifier _parseSimpleIdentifierUnchecked(
{bool isDeclaration: false}) {
String lexeme = _currentToken.lexeme;
@@ -7317,13 +6874,11 @@
isDeclaration: isDeclaration);
}
- /**
- * Parse a list of statements within a switch statement. Return the statements
- * that were parsed.
- *
- * statements ::=
- * statement*
- */
+ /// Parse a list of statements within a switch statement. Return the
+ /// statements that were parsed.
+ ///
+ /// statements ::=
+ /// statement*
List<Statement> _parseStatementList() {
List<Statement> statements = <Statement>[];
Token statementStart = _currentToken;
@@ -7343,14 +6898,12 @@
return statements;
}
- /**
- * Parse a string literal that contains interpolations. Return the string
- * literal that was parsed.
- *
- * This method assumes that the current token matches either
- * [TokenType.STRING_INTERPOLATION_EXPRESSION] or
- * [TokenType.STRING_INTERPOLATION_IDENTIFIER].
- */
+ /// Parse a string literal that contains interpolations. Return the string
+ /// literal that was parsed.
+ ///
+ /// This method assumes that the current token matches either
+ /// [TokenType.STRING_INTERPOLATION_EXPRESSION] or
+ /// [TokenType.STRING_INTERPOLATION_IDENTIFIER].
StringInterpolation _parseStringInterpolation(Token string) {
List<InterpolationElement> elements = <InterpolationElement>[
astFactory.interpolationString(
@@ -7396,15 +6949,13 @@
return astFactory.stringInterpolation(elements);
}
- /**
- * Parse a string literal. Return the string literal that was parsed.
- *
- * This method assumes that the current token matches `TokenType.STRING`.
- *
- * stringLiteral ::=
- * MULTI_LINE_STRING+
- * | SINGLE_LINE_STRING+
- */
+ /// Parse a string literal. Return the string literal that was parsed.
+ ///
+ /// This method assumes that the current token matches `TokenType.STRING`.
+ ///
+ /// stringLiteral ::=
+ /// MULTI_LINE_STRING+
+ /// | SINGLE_LINE_STRING+
StringLiteral _parseStringLiteralUnchecked() {
List<StringLiteral> strings = <StringLiteral>[];
do {
@@ -7422,15 +6973,13 @@
: astFactory.adjacentStrings(strings);
}
- /**
- * Parse a type annotation, possibly superseded by a type name in a comment.
- * Return the type name that was parsed.
- *
- * This method assumes that the current token is an identifier.
- *
- * type ::=
- * qualified typeArguments?
- */
+ /// Parse a type annotation, possibly superseded by a type name in a comment.
+ /// Return the type name that was parsed.
+ ///
+ /// This method assumes that the current token is an identifier.
+ ///
+ /// type ::=
+ /// qualified typeArguments?
TypeAnnotation _parseTypeAnnotationAfterIdentifier() {
return parseTypeAnnotation(false);
}
@@ -7450,10 +6999,8 @@
return astFactory.typeName(typeName, typeArguments);
}
- /**
- * Parse a string literal representing a URI. Return the string literal that
- * was parsed.
- */
+ /// Parse a string literal representing a URI. Return the string literal that
+ /// was parsed.
StringLiteral _parseUri() {
// TODO(brianwilkerson) Should this function also return true for valid
// top-level keywords?
@@ -7510,17 +7057,15 @@
return parseStringLiteral();
}
- /**
- * Parse a variable declaration statement. The [commentAndMetadata] is the
- * metadata to be associated with the variable declaration statement, or
- * `null` if there is no attempt at parsing the comment and metadata. The
- * [keyword] is the token representing the 'final', 'const' or 'var' keyword,
- * or `null` if there is no keyword. The [type] is the type of the variables
- * in the list. Return the variable declaration statement that was parsed.
- *
- * variableDeclarationStatement ::=
- * variableDeclarationList ';'
- */
+ /// Parse a variable declaration statement. The [commentAndMetadata] is the
+ /// metadata to be associated with the variable declaration statement, or
+ /// `null` if there is no attempt at parsing the comment and metadata. The
+ /// [keyword] is the token representing the 'final', 'const' or 'var' keyword,
+ /// or `null` if there is no keyword. The [type] is the type of the variables
+ /// in the list. Return the variable declaration statement that was parsed.
+ ///
+ /// variableDeclarationStatement ::=
+ /// variableDeclarationList ';'
VariableDeclarationStatement _parseVariableDeclarationStatementAfterType(
CommentAndMetadata commentAndMetadata,
Token keyword,
@@ -7532,17 +7077,13 @@
return astFactory.variableDeclarationStatement(variableList, semicolon);
}
- /**
- * Return the token that is immediately after the current token. This is
- * equivalent to [_peekAt](1).
- */
+ /// Return the token that is immediately after the current token. This is
+ /// equivalent to [_peekAt](1).
Token _peek() => _currentToken.next;
- /**
- * Return the token that is the given [distance] after the current token,
- * where the distance is the number of tokens to look ahead. A distance of `0`
- * is the current token, `1` is the next token, etc.
- */
+ /// Return the token that is the given [distance] after the current token,
+ /// where the distance is the number of tokens to look ahead. A distance of
+ /// `0` is the current token, `1` is the next token, etc.
Token _peekAt(int distance) {
Token token = _currentToken;
for (int i = 0; i < distance; i++) {
@@ -7570,9 +7111,7 @@
return comment;
}
- /**
- * Report the given [error].
- */
+ /// Report the given [error].
void _reportError(AnalysisError error) {
if (_errorListenerLock != 0) {
return;
@@ -7580,29 +7119,23 @@
_errorListener.onError(error);
}
- /**
- * Report an error with the given [errorCode] and [arguments] associated with
- * the current token.
- */
+ /// Report an error with the given [errorCode] and [arguments] associated with
+ /// the current token.
void _reportErrorForCurrentToken(ParserErrorCode errorCode,
[List<Object> arguments]) {
_reportErrorForToken(errorCode, _currentToken, arguments);
}
- /**
- * Report an error with the given [errorCode] and [arguments] associated with
- * the given [node].
- */
+ /// Report an error with the given [errorCode] and [arguments] associated with
+ /// the given [node].
void _reportErrorForNode(ParserErrorCode errorCode, AstNode node,
[List<Object> arguments]) {
_reportError(new AnalysisError(
_source, node.offset, node.length, errorCode, arguments));
}
- /**
- * Report an error with the given [errorCode] and [arguments] associated with
- * the given [token].
- */
+ /// Report an error with the given [errorCode] and [arguments] associated with
+ /// the given [token].
void _reportErrorForToken(ErrorCode errorCode, Token token,
[List<Object> arguments]) {
if (token.type == TokenType.EOF) {
@@ -7612,9 +7145,7 @@
math.max(token.length, 1), errorCode, arguments));
}
- /**
- * Skips a block with all containing blocks.
- */
+ /// Skips a block with all containing blocks.
void _skipBlock() {
Token endToken = (_currentToken as BeginToken).endToken;
if (endToken == null) {
@@ -7630,20 +7161,18 @@
}
}
- /**
- * Parse the 'final', 'const', 'var' or type preceding a variable declaration,
- * starting at the given token, without actually creating a type or changing
- * the current token. Return the token following the type that was parsed, or
- * `null` if the given token is not the first token in a valid type. The
- * [startToken] is the token at which parsing is to begin. Return the token
- * following the type that was parsed.
- *
- * finalConstVarOrType ::=
- * | 'final' type?
- * | 'const' type?
- * | 'var'
- * | type
- */
+ /// Parse the 'final', 'const', 'var' or type preceding a variable
+ /// declaration, starting at the given token, without actually creating a
+ /// type or changing the current token. Return the token following the type
+ /// that was parsed, or `null` if the given token is not the first token in a
+ /// valid type. The [startToken] is the token at which parsing is to begin.
+ /// Return the token following the type that was parsed.
+ ///
+ /// finalConstVarOrType ::=
+ /// | 'final' type?
+ /// | 'const' type?
+ /// | 'var'
+ /// | type
Token _skipFinalConstVarOrType(Token startToken) {
Keyword keyword = startToken.keyword;
if (keyword == Keyword.FINAL || keyword == Keyword.CONST) {
@@ -7677,40 +7206,38 @@
return null;
}
- /**
- * Parse a list of formal parameters, starting at the [startToken], without
- * actually creating a formal parameter list or changing the current token.
- * Return the token following the formal parameter list that was parsed, or
- * `null` if the given token is not the first token in a valid list of formal
- * parameter.
- *
- * Note that unlike other skip methods, this method uses a heuristic. In the
- * worst case, the parameters could be prefixed by metadata, which would
- * require us to be able to skip arbitrary expressions. Rather than duplicate
- * the logic of most of the parse methods we simply look for something that is
- * likely to be a list of parameters and then skip to returning the token
- * after the closing parenthesis.
- *
- * This method must be kept in sync with [parseFormalParameterList].
- *
- * formalParameterList ::=
- * '(' ')'
- * | '(' normalFormalParameters (',' optionalFormalParameters)? ')'
- * | '(' optionalFormalParameters ')'
- *
- * normalFormalParameters ::=
- * normalFormalParameter (',' normalFormalParameter)*
- *
- * optionalFormalParameters ::=
- * optionalPositionalFormalParameters
- * | namedFormalParameters
- *
- * optionalPositionalFormalParameters ::=
- * '[' defaultFormalParameter (',' defaultFormalParameter)* ']'
- *
- * namedFormalParameters ::=
- * '{' defaultNamedParameter (',' defaultNamedParameter)* '}'
- */
+ /// Parse a list of formal parameters, starting at the [startToken], without
+ /// actually creating a formal parameter list or changing the current token.
+ /// Return the token following the formal parameter list that was parsed, or
+ /// `null` if the given token is not the first token in a valid list of formal
+ /// parameter.
+ ///
+ /// Note that unlike other skip methods, this method uses a heuristic. In the
+ /// worst case, the parameters could be prefixed by metadata, which would
+ /// require us to be able to skip arbitrary expressions. Rather than duplicate
+ /// the logic of most of the parse methods we simply look for something that
+ /// is likely to be a list of parameters and then skip to returning the token
+ /// after the closing parenthesis.
+ ///
+ /// This method must be kept in sync with [parseFormalParameterList].
+ ///
+ /// formalParameterList ::=
+ /// '(' ')'
+ /// | '(' normalFormalParameters (',' optionalFormalParameters)? ')'
+ /// | '(' optionalFormalParameters ')'
+ ///
+ /// normalFormalParameters ::=
+ /// normalFormalParameter (',' normalFormalParameter)*
+ ///
+ /// optionalFormalParameters ::=
+ /// optionalPositionalFormalParameters
+ /// | namedFormalParameters
+ ///
+ /// optionalPositionalFormalParameters ::=
+ /// '[' defaultFormalParameter (',' defaultFormalParameter)* ']'
+ ///
+ /// namedFormalParameters ::=
+ /// '{' defaultNamedParameter (',' defaultNamedParameter)* '}'
Token _skipFormalParameterList(Token startToken) {
if (!_tokenMatches(startToken, TokenType.OPEN_PAREN)) {
return null;
@@ -7761,10 +7288,8 @@
return _skipPastMatchingToken(startToken);
}
- /**
- * If the [startToken] is a begin token with an associated end token, then
- * return the token following the end token. Otherwise, return `null`.
- */
+ /// If the [startToken] is a begin token with an associated end token, then
+ /// return the token following the end token. Otherwise, return `null`.
Token _skipPastMatchingToken(Token startToken) {
if (startToken is! BeginToken) {
return null;
@@ -7776,15 +7301,13 @@
return closeParen.next;
}
- /**
- * Parse a string literal that contains interpolations, starting at the
- * [startToken], without actually creating a string literal or changing the
- * current token. Return the token following the string literal that was
- * parsed, or `null` if the given token is not the first token in a valid
- * string literal.
- *
- * This method must be kept in sync with [parseStringInterpolation].
- */
+ /// Parse a string literal that contains interpolations, starting at the
+ /// [startToken], without actually creating a string literal or changing the
+ /// current token. Return the token following the string literal that was
+ /// parsed, or `null` if the given token is not the first token in a valid
+ /// string literal.
+ ///
+ /// This method must be kept in sync with [parseStringInterpolation].
Token _skipStringInterpolation(Token startToken) {
Token token = startToken;
TokenType type = token.type;
@@ -7836,18 +7359,16 @@
return token;
}
- /**
- * Parse a list of type parameters, starting at the [startToken], without
- * actually creating a type parameter list or changing the current token.
- * Return the token following the type parameter list that was parsed, or
- * `null` if the given token is not the first token in a valid type parameter
- * list.
- *
- * This method must be kept in sync with [parseTypeParameterList].
- *
- * typeParameterList ::=
- * '<' typeParameter (',' typeParameter)* '>'
- */
+ /// Parse a list of type parameters, starting at the [startToken], without
+ /// actually creating a type parameter list or changing the current token.
+ /// Return the token following the type parameter list that was parsed, or
+ /// `null` if the given token is not the first token in a valid type parameter
+ /// list.
+ ///
+ /// This method must be kept in sync with [parseTypeParameterList].
+ ///
+ /// typeParameterList ::=
+ /// '<' typeParameter (',' typeParameter)* '>'
Token _skipTypeParameterList(Token startToken) {
if (!_tokenMatches(startToken, TokenType.LT)) {
return null;
@@ -7889,10 +7410,8 @@
return next;
}
- /**
- * Assuming that the current token is an index token ('[]'), split it into two
- * tokens ('[' and ']'), leaving the left bracket as the current token.
- */
+ /// Assuming that the current token is an index token ('[]'), split it into
+ /// two tokens ('[' and ']'), leaving the left bracket as the current token.
void _splitIndex() {
// Split the token into two separate tokens.
BeginToken leftBracket = _createToken(
@@ -7907,42 +7426,30 @@
_currentToken = leftBracket;
}
- /**
- * Return `true` if the given [token] has the given [type].
- */
+ /// Return `true` if the given [token] has the given [type].
bool _tokenMatches(Token token, TokenType type) => token.type == type;
- /**
- * Return `true` if the given [token] is a valid identifier. Valid identifiers
- * include built-in identifiers (pseudo-keywords).
- */
+ /// Return `true` if the given [token] is a valid identifier. Valid
+ /// identifiers include built-in identifiers (pseudo-keywords).
bool _tokenMatchesIdentifier(Token token) =>
_tokenMatches(token, TokenType.IDENTIFIER) ||
_tokenMatchesPseudoKeyword(token);
- /**
- * Return `true` if the given [token] is either an identifier or a keyword.
- */
+ /// Return `true` if the given [token] is either an identifier or a keyword.
bool _tokenMatchesIdentifierOrKeyword(Token token) =>
_tokenMatches(token, TokenType.IDENTIFIER) || token.type.isKeyword;
- /**
- * Return `true` if the given [token] matches the given [keyword].
- */
+ /// Return `true` if the given [token] matches the given [keyword].
bool _tokenMatchesKeyword(Token token, Keyword keyword) =>
token.keyword == keyword;
- /**
- * Return `true` if the given [token] matches a pseudo keyword.
- */
+ /// Return `true` if the given [token] matches a pseudo keyword.
bool _tokenMatchesPseudoKeyword(Token token) =>
token.keyword?.isBuiltInOrPseudo ?? false;
- /**
- * Translate the characters at the given [index] in the given [lexeme],
- * appending the translated character to the given [buffer]. The index is
- * assumed to be valid.
- */
+ /// Translate the characters at the given [index] in the given [lexeme],
+ /// appending the translated character to the given [buffer]. The index is
+ /// assumed to be valid.
int _translateCharacter(StringBuffer buffer, String lexeme, int index) {
int currentChar = lexeme.codeUnitAt(index);
if (currentChar != 0x5C) {
@@ -8081,10 +7588,8 @@
return currentIndex + 1;
}
- /**
- * Decrements the error reporting lock level. If level is more than `0`, then
- * [reportError] wont report any error.
- */
+ /// Decrements the error reporting lock level. If level is more than `0`, then
+ /// [reportError] wont report any error.
void _unlockErrorListener() {
if (_errorListenerLock == 0) {
throw new StateError("Attempt to unlock not locked error listener.");
@@ -8092,10 +7597,8 @@
_errorListenerLock--;
}
- /**
- * Validate that the given [parameterList] does not contain any field
- * initializers.
- */
+ /// Validate that the given [parameterList] does not contain any field
+ /// initializers.
void _validateFormalParameterList(FormalParameterList parameterList) {
for (FormalParameter parameter in parameterList.parameters) {
if (parameter is FieldFormalParameter) {
@@ -8106,10 +7609,8 @@
}
}
- /**
- * Validate that the given set of [modifiers] is appropriate for a class and
- * return the 'abstract' keyword if there is one.
- */
+ /// Validate that the given set of [modifiers] is appropriate for a class and
+ /// return the 'abstract' keyword if there is one.
Token _validateModifiersForClass(Modifiers modifiers) {
_validateModifiersForTopLevelDeclaration(modifiers);
if (modifiers.constKeyword != null) {
@@ -8128,10 +7629,8 @@
return modifiers.abstractKeyword;
}
- /**
- * Validate that the given set of [modifiers] is appropriate for a constructor
- * and return the 'const' keyword if there is one.
- */
+ /// Validate that the given set of [modifiers] is appropriate for a
+ /// constructor and return the 'const' keyword if there is one.
Token _validateModifiersForConstructor(Modifiers modifiers) {
if (modifiers.abstractKeyword != null) {
_reportErrorForToken(
@@ -8171,10 +7670,8 @@
return constKeyword;
}
- /**
- * Validate that the given set of [modifiers] is appropriate for an enum and
- * return the 'abstract' keyword if there is one.
- */
+ /// Validate that the given set of [modifiers] is appropriate for an enum and
+ /// return the 'abstract' keyword if there is one.
void _validateModifiersForEnum(Modifiers modifiers) {
_validateModifiersForTopLevelDeclaration(modifiers);
if (modifiers.abstractKeyword != null) {
@@ -8196,10 +7693,8 @@
}
}
- /**
- * Validate that the given set of [modifiers] is appropriate for a field and
- * return the 'final', 'const' or 'var' keyword if there is one.
- */
+ /// Validate that the given set of [modifiers] is appropriate for a field and
+ /// return the 'final', 'const' or 'var' keyword if there is one.
Token _validateModifiersForField(Modifiers modifiers) {
if (modifiers.abstractKeyword != null) {
_reportErrorForCurrentToken(ParserErrorCode.ABSTRACT_CLASS_MEMBER);
@@ -8258,10 +7753,8 @@
return Token.lexicallyFirst([constKeyword, finalKeyword, varKeyword]);
}
- /**
- * Validate that the given set of [modifiers] is appropriate for a local
- * function.
- */
+ /// Validate that the given set of [modifiers] is appropriate for a local
+ /// function.
void _validateModifiersForFunctionDeclarationStatement(Modifiers modifiers) {
if (modifiers.abstractKeyword != null ||
modifiers.constKeyword != null ||
@@ -8275,10 +7768,8 @@
}
}
- /**
- * Validate that the given set of [modifiers] is appropriate for a getter,
- * setter, or method.
- */
+ /// Validate that the given set of [modifiers] is appropriate for a getter,
+ /// setter, or method.
void _validateModifiersForGetterOrSetterOrMethod(Modifiers modifiers) {
if (modifiers.abstractKeyword != null) {
_reportErrorForCurrentToken(ParserErrorCode.ABSTRACT_CLASS_MEMBER);
@@ -8313,10 +7804,8 @@
}
}
- /**
- * Validate that the given set of [modifiers] is appropriate for a getter,
- * setter, or method.
- */
+ /// Validate that the given set of [modifiers] is appropriate for a getter,
+ /// setter, or method.
void _validateModifiersForOperator(Modifiers modifiers) {
if (modifiers.abstractKeyword != null) {
_reportErrorForCurrentToken(ParserErrorCode.ABSTRACT_CLASS_MEMBER);
@@ -8343,10 +7832,8 @@
}
}
- /**
- * Validate that the given set of [modifiers] is appropriate for a top-level
- * declaration.
- */
+ /// Validate that the given set of [modifiers] is appropriate for a top-level
+ /// declaration.
void _validateModifiersForTopLevelDeclaration(Modifiers modifiers) {
if (modifiers.covariantKeyword != null) {
_reportErrorForToken(ParserErrorCode.COVARIANT_TOP_LEVEL_DECLARATION,
@@ -8362,10 +7849,8 @@
}
}
- /**
- * Validate that the given set of [modifiers] is appropriate for a top-level
- * function.
- */
+ /// Validate that the given set of [modifiers] is appropriate for a top-level
+ /// function.
void _validateModifiersForTopLevelFunction(Modifiers modifiers) {
_validateModifiersForTopLevelDeclaration(modifiers);
if (modifiers.abstractKeyword != null) {
@@ -8383,10 +7868,8 @@
}
}
- /**
- * Validate that the given set of [modifiers] is appropriate for a field and
- * return the 'final', 'const' or 'var' keyword if there is one.
- */
+ /// Validate that the given set of [modifiers] is appropriate for a field and
+ /// return the 'final', 'const' or 'var' keyword if there is one.
Token _validateModifiersForTopLevelVariable(Modifiers modifiers) {
_validateModifiersForTopLevelDeclaration(modifiers);
if (modifiers.abstractKeyword != null) {
@@ -8414,10 +7897,8 @@
return Token.lexicallyFirst([constKeyword, finalKeyword, varKeyword]);
}
- /**
- * Validate that the given set of [modifiers] is appropriate for a class and
- * return the 'abstract' keyword if there is one.
- */
+ /// Validate that the given set of [modifiers] is appropriate for a class and
+ /// return the 'abstract' keyword if there is one.
void _validateModifiersForTypedef(Modifiers modifiers) {
_validateModifiersForTopLevelDeclaration(modifiers);
if (modifiers.abstractKeyword != null) {
@@ -8442,9 +7923,7 @@
}
}
-/**
- * Instances of this class are thrown when the parser detects that AST has
- * too many nested expressions to be parsed safely and avoid possibility of
- * [StackOverflowError] in the parser or during later analysis.
- */
+/// Instances of this class are thrown when the parser detects that AST has
+/// too many nested expressions to be parsed safely and avoid possibility of
+/// [StackOverflowError] in the parser or during later analysis.
class _TooDeepTreeError {}
diff --git a/pkg/analyzer/lib/src/generated/parser_fasta.dart b/pkg/analyzer/lib/src/generated/parser_fasta.dart
index 946f327..dfb3261 100644
--- a/pkg/analyzer/lib/src/generated/parser_fasta.dart
+++ b/pkg/analyzer/lib/src/generated/parser_fasta.dart
@@ -44,6 +44,11 @@
void set enableOptionalNewAndConst(bool enable) {}
@override
+ void set enableSetLiterals(bool value) {
+ fastaParser.parseSetLiterals = value;
+ }
+
+ @override
void set parseFunctionBodies(bool parseFunctionBodies) {
astBuilder.parseFunctionBodies = parseFunctionBodies;
}
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 7fd6ce9..70d2b41 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -58,14 +58,14 @@
nameScope: nameScope);
@override
- Object visitMethodInvocation(MethodInvocation node) {
+ void visitMethodInvocation(MethodInvocation node) {
super.visitMethodInvocation(node);
SimpleIdentifier methodName = node.methodName;
if (methodName.isSynthetic) {
// This isn't a constructor invocation because the method name is
// synthetic.
- return null;
+ return;
}
Expression target = node.target;
@@ -73,7 +73,7 @@
// Possible cases: C() or C<>()
if (node.realTarget != null) {
// This isn't a constructor invocation because it's in a cascade.
- return null;
+ return;
}
Element element = nameScope.lookup(methodName, definingLibrary);
if (element is ClassElement) {
@@ -204,7 +204,6 @@
}
}
}
- return null;
}
/// Return the token that should be used in the [InstanceCreationExpression]
@@ -220,27 +219,35 @@
static InterfaceType getType(TypeSystem typeSystem, ClassElement element,
TypeArgumentList typeArguments) {
DartType type = element.type;
+
List<TypeParameterElement> typeParameters = element.typeParameters;
- if (typeArguments != null &&
- typeParameters != null &&
- typeArguments.arguments.length == typeParameters.length) {
- List<DartType> argumentTypes = typeArguments.arguments
+ if (typeParameters.isEmpty) {
+ return type;
+ }
+
+ if (typeArguments == null) {
+ return typeSystem.instantiateToBounds(type);
+ }
+
+ List<DartType> argumentTypes;
+ if (typeArguments.arguments.length == typeParameters.length) {
+ argumentTypes = typeArguments.arguments
.map((TypeAnnotation argument) => argument.type)
.toList();
- List<DartType> parameterTypes = typeParameters
- .map((TypeParameterElement parameter) => parameter.type)
- .toList();
- type = type.substitute2(argumentTypes, parameterTypes);
- } else if (typeArguments == null && typeParameters != null) {
- type = typeSystem.instantiateToBounds(type);
+ } else {
+ argumentTypes = List<DartType>.filled(
+ typeParameters.length, DynamicTypeImpl.instance);
}
- return type;
+ List<DartType> parameterTypes = typeParameters
+ .map((TypeParameterElement parameter) => parameter.type)
+ .toList();
+ return type.substitute2(argumentTypes, parameterTypes);
}
}
/// Instances of the class `BestPracticesVerifier` traverse an AST structure
/// looking for violations of Dart best practices.
-class BestPracticesVerifier extends RecursiveAstVisitor<Object> {
+class BestPracticesVerifier extends RecursiveAstVisitor<void> {
// static String _HASHCODE_GETTER_NAME = "hashCode";
static String _NULL_TYPE_NAME = "Null";
@@ -288,7 +295,7 @@
}
@override
- Object visitAnnotation(Annotation node) {
+ void visitAnnotation(Annotation node) {
ElementAnnotation element =
resolutionMap.elementAnnotationForAnnotation(node);
if (element?.isFactory == true) {
@@ -306,46 +313,46 @@
HintCode.INVALID_IMMUTABLE_ANNOTATION, node, []);
}
}
- return super.visitAnnotation(node);
+ super.visitAnnotation(node);
}
@override
- Object visitArgumentList(ArgumentList node) {
+ void visitArgumentList(ArgumentList node) {
for (Expression argument in node.arguments) {
ParameterElement parameter = argument.staticParameterElement;
if (parameter?.isOptionalPositional == true) {
_checkForDeprecatedMemberUse(parameter, argument);
}
}
- return super.visitArgumentList(node);
+ super.visitArgumentList(node);
}
@override
- Object visitAsExpression(AsExpression node) {
+ void visitAsExpression(AsExpression node) {
_checkForUnnecessaryCast(node);
- return super.visitAsExpression(node);
+ super.visitAsExpression(node);
}
@override
- Object visitAssignmentExpression(AssignmentExpression node) {
+ void visitAssignmentExpression(AssignmentExpression node) {
TokenType operatorType = node.operator.type;
if (operatorType == TokenType.EQ) {
_checkForInvalidAssignment(node.leftHandSide, node.rightHandSide);
} else {
_checkForDeprecatedMemberUse(node.staticElement, node);
}
- return super.visitAssignmentExpression(node);
+ super.visitAssignmentExpression(node);
}
@override
- Object visitBinaryExpression(BinaryExpression node) {
+ void visitBinaryExpression(BinaryExpression node) {
_checkForDivisionOptimizationHint(node);
_checkForDeprecatedMemberUse(node.staticElement, node);
- return super.visitBinaryExpression(node);
+ super.visitBinaryExpression(node);
}
@override
- Object visitClassDeclaration(ClassDeclaration node) {
+ void visitClassDeclaration(ClassDeclaration node) {
var element = AbstractClassElementImpl.getImpl(node.declaredElement);
_enclosingClass = element;
_invalidAccessVerifier._enclosingClass = element;
@@ -359,7 +366,7 @@
// Commented out until we decide that we want this hint in the analyzer
// checkForOverrideEqualsButNotHashCode(node);
_checkForImmutable(node);
- return super.visitClassDeclaration(node);
+ super.visitClassDeclaration(node);
} finally {
_enclosingClass = null;
_invalidAccessVerifier._enclosingClass = null;
@@ -368,7 +375,7 @@
}
@override
- Object visitConstructorDeclaration(ConstructorDeclaration node) {
+ void visitConstructorDeclaration(ConstructorDeclaration node) {
if (resolutionMap.elementDeclaredByConstructorDeclaration(node).isFactory) {
if (node.body is BlockFunctionBody) {
// Check the block for a return statement, if not, create the hint.
@@ -378,37 +385,37 @@
}
}
}
- return super.visitConstructorDeclaration(node);
+ super.visitConstructorDeclaration(node);
}
@override
- Object visitExportDirective(ExportDirective node) {
+ void visitExportDirective(ExportDirective node) {
_checkForDeprecatedMemberUse(node.uriElement, node);
- return super.visitExportDirective(node);
+ super.visitExportDirective(node);
}
@override
- Object visitFieldDeclaration(FieldDeclaration node) {
+ void visitFieldDeclaration(FieldDeclaration node) {
bool wasInDeprecatedMember = _inDeprecatedMember;
if (_hasDeprecatedAnnotation(node.metadata)) {
_inDeprecatedMember = true;
}
try {
- return super.visitFieldDeclaration(node);
+ super.visitFieldDeclaration(node);
} finally {
_inDeprecatedMember = wasInDeprecatedMember;
}
}
@override
- Object visitFormalParameterList(FormalParameterList node) {
+ void visitFormalParameterList(FormalParameterList node) {
_checkRequiredParameter(node);
- return super.visitFormalParameterList(node);
+ super.visitFormalParameterList(node);
}
@override
- Object visitFunctionDeclaration(FunctionDeclaration node) {
+ void visitFunctionDeclaration(FunctionDeclaration node) {
bool wasInDeprecatedMember = _inDeprecatedMember;
ExecutableElement element = node.declaredElement;
if (element != null && element.hasDeprecated) {
@@ -417,42 +424,42 @@
try {
_checkForMissingReturn(
node.returnType, node.functionExpression.body, element, node);
- return super.visitFunctionDeclaration(node);
+ super.visitFunctionDeclaration(node);
} finally {
_inDeprecatedMember = wasInDeprecatedMember;
}
}
@override
- Object visitImportDirective(ImportDirective node) {
+ void visitImportDirective(ImportDirective node) {
_checkForDeprecatedMemberUse(node.uriElement, node);
ImportElement importElement = node.element;
if (importElement != null && importElement.isDeferred) {
_checkForLoadLibraryFunction(node, importElement);
}
- return super.visitImportDirective(node);
+ super.visitImportDirective(node);
}
@override
- Object visitIndexExpression(IndexExpression node) {
+ void visitIndexExpression(IndexExpression node) {
_checkForDeprecatedMemberUse(node.staticElement, node);
- return super.visitIndexExpression(node);
+ super.visitIndexExpression(node);
}
@override
- Object visitInstanceCreationExpression(InstanceCreationExpression node) {
+ void visitInstanceCreationExpression(InstanceCreationExpression node) {
_checkForDeprecatedMemberUse(node.staticElement, node);
- return super.visitInstanceCreationExpression(node);
+ super.visitInstanceCreationExpression(node);
}
@override
- Object visitIsExpression(IsExpression node) {
+ void visitIsExpression(IsExpression node) {
_checkAllTypeChecks(node);
- return super.visitIsExpression(node);
+ super.visitIsExpression(node);
}
@override
- Object visitMethodDeclaration(MethodDeclaration node) {
+ void visitMethodDeclaration(MethodDeclaration node) {
bool wasInDeprecatedMember = _inDeprecatedMember;
ExecutableElement element = node.declaredElement;
if (element != null && element.hasDeprecated) {
@@ -463,14 +470,14 @@
//checkForOverridingPrivateMember(node);
_checkForMissingReturn(node.returnType, node.body, element, node);
_checkForUnnecessaryNoSuchMethod(node);
- return super.visitMethodDeclaration(node);
+ super.visitMethodDeclaration(node);
} finally {
_inDeprecatedMember = wasInDeprecatedMember;
}
}
@override
- Object visitMethodInvocation(MethodInvocation node) {
+ void visitMethodInvocation(MethodInvocation node) {
_checkForNullAwareHints(node, node.operator);
DartType staticInvokeType = node.staticInvokeType;
Element callElement = staticInvokeType?.element;
@@ -478,11 +485,11 @@
callElement.name == FunctionElement.CALL_METHOD_NAME) {
_checkForDeprecatedMemberUse(callElement, node);
}
- return super.visitMethodInvocation(node);
+ super.visitMethodInvocation(node);
}
@override
- Object visitMixinDeclaration(MixinDeclaration node) {
+ void visitMixinDeclaration(MixinDeclaration node) {
_enclosingClass = node.declaredElement;
_invalidAccessVerifier._enclosingClass = _enclosingClass;
@@ -492,7 +499,7 @@
}
try {
- return super.visitMixinDeclaration(node);
+ super.visitMixinDeclaration(node);
} finally {
_enclosingClass = null;
_invalidAccessVerifier._enclosingClass = null;
@@ -501,61 +508,61 @@
}
@override
- Object visitPostfixExpression(PostfixExpression node) {
+ void visitPostfixExpression(PostfixExpression node) {
_checkForDeprecatedMemberUse(node.staticElement, node);
- return super.visitPostfixExpression(node);
+ super.visitPostfixExpression(node);
}
@override
- Object visitPrefixExpression(PrefixExpression node) {
+ void visitPrefixExpression(PrefixExpression node) {
_checkForDeprecatedMemberUse(node.staticElement, node);
- return super.visitPrefixExpression(node);
+ super.visitPrefixExpression(node);
}
@override
- Object visitPropertyAccess(PropertyAccess node) {
+ void visitPropertyAccess(PropertyAccess node) {
_checkForNullAwareHints(node, node.operator);
- return super.visitPropertyAccess(node);
+ super.visitPropertyAccess(node);
}
@override
- Object visitRedirectingConstructorInvocation(
+ void visitRedirectingConstructorInvocation(
RedirectingConstructorInvocation node) {
_checkForDeprecatedMemberUse(node.staticElement, node);
- return super.visitRedirectingConstructorInvocation(node);
+ super.visitRedirectingConstructorInvocation(node);
}
@override
- Object visitSimpleIdentifier(SimpleIdentifier node) {
+ void visitSimpleIdentifier(SimpleIdentifier node) {
_checkForDeprecatedMemberUseAtIdentifier(node);
_invalidAccessVerifier.verify(node);
- return super.visitSimpleIdentifier(node);
+ super.visitSimpleIdentifier(node);
}
@override
- Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+ void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
_checkForDeprecatedMemberUse(node.staticElement, node);
- return super.visitSuperConstructorInvocation(node);
+ super.visitSuperConstructorInvocation(node);
}
@override
- Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+ void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
bool wasInDeprecatedMember = _inDeprecatedMember;
if (_hasDeprecatedAnnotation(node.metadata)) {
_inDeprecatedMember = true;
}
try {
- return super.visitTopLevelVariableDeclaration(node);
+ super.visitTopLevelVariableDeclaration(node);
} finally {
_inDeprecatedMember = wasInDeprecatedMember;
}
}
@override
- Object visitVariableDeclaration(VariableDeclaration node) {
+ void visitVariableDeclaration(VariableDeclaration node) {
_checkForInvalidAssignment(node.name, node.initializer);
- return super.visitVariableDeclaration(node);
+ super.visitVariableDeclaration(node);
}
/// Check for the passed is expression for the unnecessary type check hint
@@ -641,8 +648,7 @@
bool isLocalParameter(Element element, AstNode node) {
if (element is ParameterElement) {
ExecutableElement definingFunction = element.enclosingElement;
- FunctionBody body =
- node.getAncestor((ancestor) => ancestor is FunctionBody);
+ FunctionBody body = node.thisOrAncestorOfType<FunctionBody>();
while (body != null) {
ExecutableElement enclosingFunction;
AstNode parent = body.parent;
@@ -656,7 +662,7 @@
if (enclosingFunction == definingFunction) {
return true;
}
- body = parent?.getAncestor((ancestor) => ancestor is FunctionBody);
+ body = parent?.thisOrAncestorOfType<FunctionBody>();
}
}
return false;
@@ -849,16 +855,14 @@
? ErrorVerifier.getStaticType(lhs)
: leftVariableElement.type;
DartType staticRightType = ErrorVerifier.getStaticType(rhs);
- if (!_typeSystem.isAssignableTo(staticRightType, leftType,
- isDeclarationCast: true)) {
+ if (!_typeSystem.isAssignableTo(staticRightType, leftType)) {
// The warning was generated on this rhs
return false;
}
// Test for, and then generate the hint
DartType bestRightType = rhs.staticType;
if (leftType != null && bestRightType != null) {
- if (!_typeSystem.isAssignableTo(bestRightType, leftType,
- isDeclarationCast: true)) {
+ if (!_typeSystem.isAssignableTo(bestRightType, leftType)) {
_errorReporter.reportTypeErrorForNode(
HintCode.INVALID_ASSIGNMENT, rhs, [bestRightType, leftType]);
return true;
@@ -1316,7 +1320,7 @@
/// Instances of the class `Dart2JSVerifier` traverse an AST structure looking
/// for hints for code that will be compiled to JS, such as
/// [HintCode.IS_DOUBLE].
-class Dart2JSVerifier extends RecursiveAstVisitor<Object> {
+class Dart2JSVerifier extends RecursiveAstVisitor<void> {
/// The name of the `double` type.
static String _DOUBLE_TYPE_NAME = "double";
@@ -1329,9 +1333,9 @@
Dart2JSVerifier(this._errorReporter);
@override
- Object visitIsExpression(IsExpression node) {
+ void visitIsExpression(IsExpression node) {
_checkForIsDoubleHints(node);
- return super.visitIsExpression(node);
+ super.visitIsExpression(node);
}
/// Check for instances of `x is double`, `x is int`, `x is! double` and
@@ -1374,7 +1378,7 @@
}
/// A visitor that finds dead code and unused labels.
-class DeadCodeVerifier extends RecursiveAstVisitor<Object> {
+class DeadCodeVerifier extends RecursiveAstVisitor<void> {
/// The error reporter by which errors will be reported.
final ErrorReporter _errorReporter;
@@ -1391,7 +1395,7 @@
: this._typeSystem = typeSystem ?? new StrongTypeSystemImpl(null);
@override
- Object visitBinaryExpression(BinaryExpression node) {
+ void visitBinaryExpression(BinaryExpression node) {
Token operator = node.operator;
bool isAmpAmp = operator.type == TokenType.AMPERSAND_AMPERSAND;
bool isBarBar = operator.type == TokenType.BAR_BAR;
@@ -1407,14 +1411,14 @@
HintCode.DEAD_CODE, node.rightOperand);
// Only visit the LHS:
lhsCondition?.accept(this);
- return null;
+ return;
} else if (value == false && isAmpAmp) {
// Report error on "if" block: false && !e!
_errorReporter.reportErrorForNode(
HintCode.DEAD_CODE, node.rightOperand);
// Only visit the LHS:
lhsCondition?.accept(this);
- return null;
+ return;
}
}
}
@@ -1438,27 +1442,25 @@
// }
// }
}
- return super.visitBinaryExpression(node);
+ super.visitBinaryExpression(node);
}
/// For each block, this method reports and error on all statements between
/// the end of the block and the first return statement (assuming there it is
/// not at the end of the block.)
@override
- Object visitBlock(Block node) {
+ void visitBlock(Block node) {
NodeList<Statement> statements = node.statements;
_checkForDeadStatementsInNodeList(statements);
- return null;
}
@override
- Object visitBreakStatement(BreakStatement node) {
+ void visitBreakStatement(BreakStatement node) {
labelTracker?.recordUsage(node.label?.name);
- return null;
}
@override
- Object visitConditionalExpression(ConditionalExpression node) {
+ void visitConditionalExpression(ConditionalExpression node) {
Expression conditionExpression = node.condition;
conditionExpression?.accept(this);
if (!_isDebugConstant(conditionExpression)) {
@@ -1470,27 +1472,26 @@
_errorReporter.reportErrorForNode(
HintCode.DEAD_CODE, node.elseExpression);
node.thenExpression?.accept(this);
- return null;
+ return;
} else {
// Report error on "if" block: false ? !1! : 2
_errorReporter.reportErrorForNode(
HintCode.DEAD_CODE, node.thenExpression);
node.elseExpression?.accept(this);
- return null;
+ return;
}
}
}
- return super.visitConditionalExpression(node);
+ super.visitConditionalExpression(node);
}
@override
- Object visitContinueStatement(ContinueStatement node) {
+ void visitContinueStatement(ContinueStatement node) {
labelTracker?.recordUsage(node.label?.name);
- return null;
}
@override
- Object visitExportDirective(ExportDirective node) {
+ void visitExportDirective(ExportDirective node) {
ExportElement exportElement = node.element;
if (exportElement != null) {
// The element is null when the URI is invalid.
@@ -1501,11 +1502,11 @@
}
}
}
- return super.visitExportDirective(node);
+ super.visitExportDirective(node);
}
@override
- Object visitIfStatement(IfStatement node) {
+ void visitIfStatement(IfStatement node) {
Expression conditionExpression = node.condition;
conditionExpression?.accept(this);
if (!_isDebugConstant(conditionExpression)) {
@@ -1519,22 +1520,22 @@
_errorReporter.reportErrorForNode(
HintCode.DEAD_CODE, elseStatement);
node.thenStatement?.accept(this);
- return null;
+ return;
}
} else {
// Report error on if block: if (false) {!} else {}
_errorReporter.reportErrorForNode(
HintCode.DEAD_CODE, node.thenStatement);
node.elseStatement?.accept(this);
- return null;
+ return;
}
}
}
- return super.visitIfStatement(node);
+ super.visitIfStatement(node);
}
@override
- Object visitImportDirective(ImportDirective node) {
+ void visitImportDirective(ImportDirective node) {
ImportElement importElement = node.element;
if (importElement != null) {
// The element is null when the URI is invalid, but not when the URI is
@@ -1546,34 +1547,33 @@
}
}
}
- return super.visitImportDirective(node);
+ super.visitImportDirective(node);
}
@override
- Object visitLabeledStatement(LabeledStatement node) {
+ void visitLabeledStatement(LabeledStatement node) {
_pushLabels(node.labels);
try {
super.visitLabeledStatement(node);
} finally {
_popLabels();
}
- return null;
}
@override
- Object visitSwitchCase(SwitchCase node) {
+ void visitSwitchCase(SwitchCase node) {
_checkForDeadStatementsInNodeList(node.statements, allowMandated: true);
- return super.visitSwitchCase(node);
+ super.visitSwitchCase(node);
}
@override
- Object visitSwitchDefault(SwitchDefault node) {
+ void visitSwitchDefault(SwitchDefault node) {
_checkForDeadStatementsInNodeList(node.statements, allowMandated: true);
- return super.visitSwitchDefault(node);
+ super.visitSwitchDefault(node);
}
@override
- Object visitSwitchStatement(SwitchStatement node) {
+ void visitSwitchStatement(SwitchStatement node) {
List<Label> labels = <Label>[];
for (SwitchMember member in node.members) {
labels.addAll(member.labels);
@@ -1584,11 +1584,10 @@
} finally {
_popLabels();
}
- return null;
}
@override
- Object visitTryStatement(TryStatement node) {
+ void visitTryStatement(TryStatement node) {
node.body?.accept(this);
node.finallyBlock?.accept(this);
NodeList<CatchClause> catchClauses = node.catchClauses;
@@ -1615,7 +1614,7 @@
int length = lastCatchClause.end - offset;
_errorReporter.reportErrorForOffset(
HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH, offset, length);
- return null;
+ return;
}
}
int length = visitedTypes.length;
@@ -1630,7 +1629,7 @@
offset,
length,
[currentType.displayName, type.displayName]);
- return null;
+ return;
}
}
visitedTypes.add(currentType);
@@ -1649,15 +1648,14 @@
int length = lastCatchClause.end - offset;
_errorReporter.reportErrorForOffset(
HintCode.DEAD_CODE_CATCH_FOLLOWING_CATCH, offset, length);
- return null;
+ return;
}
}
}
- return null;
}
@override
- Object visitWhileStatement(WhileStatement node) {
+ void visitWhileStatement(WhileStatement node) {
Expression conditionExpression = node.condition;
conditionExpression?.accept(this);
if (!_isDebugConstant(conditionExpression)) {
@@ -1667,12 +1665,11 @@
if (result.value.toBoolValue() == false) {
// Report error on while block: while (false) {!}
_errorReporter.reportErrorForNode(HintCode.DEAD_CODE, node.body);
- return null;
+ return;
}
}
}
node.body?.accept(this);
- return null;
}
/// Resolve the names in the given [combinator] in the scope of the given
@@ -2273,7 +2270,7 @@
/// Instances of the class `EnumMemberBuilder` build the members in enum
/// declarations.
-class EnumMemberBuilder extends RecursiveAstVisitor<Object> {
+class EnumMemberBuilder extends RecursiveAstVisitor<void> {
/// The type provider used to access the types needed to build an element
/// model for enum declarations.
final TypeProvider _typeProvider;
@@ -2285,7 +2282,7 @@
EnumMemberBuilder(this._typeProvider);
@override
- Object visitEnumDeclaration(EnumDeclaration node) {
+ void visitEnumDeclaration(EnumDeclaration node) {
//
// Finish building the enum.
//
@@ -2351,7 +2348,7 @@
enumElement.accessors = getters;
// Client code isn't allowed to invoke the constructor, so we do not model
// it.
- return super.visitEnumDeclaration(node);
+ super.visitEnumDeclaration(node);
}
/// Create a getter that corresponds to the given [field].
@@ -3907,38 +3904,38 @@
nameScope: nameScope);
@override
- Object visitBlockFunctionBody(BlockFunctionBody node) {
+ void visitBlockFunctionBody(BlockFunctionBody node) {
if (_shouldBeSkipped(node)) {
return null;
}
- return super.visitBlockFunctionBody(node);
+ super.visitBlockFunctionBody(node);
}
@override
- Object visitExpressionFunctionBody(ExpressionFunctionBody node) {
+ void visitExpressionFunctionBody(ExpressionFunctionBody node) {
if (_shouldBeSkipped(node)) {
return null;
}
- return super.visitExpressionFunctionBody(node);
+ super.visitExpressionFunctionBody(node);
}
@override
- Object visitFieldDeclaration(FieldDeclaration node) {
+ void visitFieldDeclaration(FieldDeclaration node) {
if (node.isStatic) {
_addStaticVariables(node.fields.variables);
}
- return super.visitFieldDeclaration(node);
+ super.visitFieldDeclaration(node);
}
@override
- Object visitNode(AstNode node) {
- return super.visitNode(node);
+ void visitNode(AstNode node) {
+ super.visitNode(node);
}
@override
- Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+ void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
_addStaticVariables(node.variables.variables);
- return super.visitTopLevelVariableDeclaration(node);
+ super.visitTopLevelVariableDeclaration(node);
}
/// Add all of the [variables] with initializers to the list of variables
@@ -4341,12 +4338,12 @@
}
@override
- Object visitAnnotation(Annotation node) {
+ void visitAnnotation(Annotation node) {
AstNode parent = node.parent;
if (identical(parent, _enclosingClassDeclaration) ||
identical(parent, _enclosingFunctionTypeAlias) ||
identical(parent, _enclosingMixinDeclaration)) {
- return null;
+ return;
}
node.name?.accept(this);
node.constructorName?.accept(this);
@@ -4364,11 +4361,10 @@
} else {
elementAnnotationImpl.annotationAst = _createCloner().cloneNode(node);
}
- return null;
}
@override
- Object visitArgumentList(ArgumentList node) {
+ void visitArgumentList(ArgumentList node) {
DartType callerType = InferenceContext.getContext(node);
if (callerType is FunctionType) {
Map<String, DartType> namedParameterTypes =
@@ -4408,26 +4404,24 @@
}
}
}
- return super.visitArgumentList(node);
+ super.visitArgumentList(node);
}
@override
- Object visitAssertInitializer(AssertInitializer node) {
+ void visitAssertInitializer(AssertInitializer node) {
InferenceContext.setType(node.condition, typeProvider.boolType);
super.visitAssertInitializer(node);
- return null;
}
@override
- Object visitAssertStatement(AssertStatement node) {
+ void visitAssertStatement(AssertStatement node) {
InferenceContext.setType(node.condition, typeProvider.boolType);
super.visitAssertStatement(node);
_propagateTrueState(node.condition);
- return null;
}
@override
- Object visitAssignmentExpression(AssignmentExpression node) {
+ void visitAssignmentExpression(AssignmentExpression node) {
node.leftHandSide?.accept(this);
TokenType operator = node.operator.type;
if (operator == TokenType.EQ ||
@@ -4438,21 +4432,20 @@
node.rightHandSide?.accept(this);
node.accept(elementResolver);
node.accept(typeAnalyzer);
- return null;
}
@override
- Object visitAwaitExpression(AwaitExpression node) {
+ void visitAwaitExpression(AwaitExpression node) {
DartType contextType = InferenceContext.getContext(node);
if (contextType != null) {
var futureUnion = _createFutureOr(contextType);
InferenceContext.setType(node.expression, futureUnion);
}
- return super.visitAwaitExpression(node);
+ super.visitAwaitExpression(node);
}
@override
- Object visitBinaryExpression(BinaryExpression node) {
+ void visitBinaryExpression(BinaryExpression node) {
TokenType operatorType = node.operator.type;
Expression leftOperand = node.leftOperand;
Expression rightOperand = node.rightOperand;
@@ -4527,11 +4520,10 @@
rightOperand?.accept(this);
}
node.accept(typeAnalyzer);
- return null;
}
@override
- Object visitBlockFunctionBody(BlockFunctionBody node) {
+ void visitBlockFunctionBody(BlockFunctionBody node) {
_overrideManager.enterScope();
try {
inferenceContext.pushReturnContext(node);
@@ -4540,28 +4532,26 @@
_overrideManager.exitScope();
inferenceContext.popReturnContext(node);
}
- return null;
}
@override
- Object visitBreakStatement(BreakStatement node) {
+ void visitBreakStatement(BreakStatement node) {
//
// We do not visit the label because it needs to be visited in the context
// of the statement.
//
node.accept(elementResolver);
node.accept(typeAnalyzer);
- return null;
}
@override
- Object visitCascadeExpression(CascadeExpression node) {
+ void visitCascadeExpression(CascadeExpression node) {
InferenceContext.setTypeFromNode(node.target, node);
- return super.visitCascadeExpression(node);
+ super.visitCascadeExpression(node);
}
@override
- Object visitClassDeclaration(ClassDeclaration node) {
+ void visitClassDeclaration(ClassDeclaration node) {
//
// Resolve the metadata in the library scope.
//
@@ -4582,12 +4572,11 @@
enclosingClass = outerType;
_enclosingClassDeclaration = null;
}
- return null;
}
/// Implementation of this method should be synchronized with
/// [visitClassDeclaration].
- visitClassDeclarationIncrementally(ClassDeclaration node) {
+ void visitClassDeclarationIncrementally(ClassDeclaration node) {
//
// Resolve the metadata in the library scope.
//
@@ -4603,31 +4592,29 @@
}
@override
- Object visitComment(Comment node) {
+ void visitComment(Comment node) {
AstNode parent = node.parent;
if (parent is FunctionDeclaration ||
parent is FunctionTypeAlias ||
parent is ConstructorDeclaration ||
parent is MethodDeclaration) {
- return null;
+ return;
}
super.visitComment(node);
- return null;
}
@override
- Object visitCommentReference(CommentReference node) {
+ void visitCommentReference(CommentReference node) {
//
// We do not visit the identifier because it needs to be visited in the
// context of the reference.
//
node.accept(elementResolver);
node.accept(typeAnalyzer);
- return null;
}
@override
- Object visitCompilationUnit(CompilationUnit node) {
+ void visitCompilationUnit(CompilationUnit node) {
_overrideManager.enterScope();
try {
NodeList<Directive> directives = node.directives;
@@ -4645,11 +4632,10 @@
}
node.accept(elementResolver);
node.accept(typeAnalyzer);
- return null;
}
@override
- Object visitConditionalExpression(ConditionalExpression node) {
+ void visitConditionalExpression(ConditionalExpression node) {
Expression condition = node.condition;
condition?.accept(this);
Expression thenExpression = node.thenExpression;
@@ -4696,11 +4682,10 @@
_propagateFalseState(condition);
_propagateState(elseExpression);
}
- return null;
}
@override
- Object visitConstructorDeclaration(ConstructorDeclaration node) {
+ void visitConstructorDeclaration(ConstructorDeclaration node) {
ExecutableElement outerFunction = _enclosingFunction;
FunctionBody outerFunctionBody = _currentFunctionBody;
try {
@@ -4716,7 +4701,6 @@
ConstructorElementImpl constructor = node.declaredElement;
constructor.constantInitializers =
_createCloner().cloneNodeList(node.initializers);
- return null;
}
@override
@@ -4732,7 +4716,7 @@
}
@override
- Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
+ void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
//
// We visit the expression, but do not visit the field name because it needs
// to be visited in the context of the constructor field initializer node.
@@ -4742,11 +4726,10 @@
node.expression?.accept(this);
node.accept(elementResolver);
node.accept(typeAnalyzer);
- return null;
}
@override
- Object visitConstructorName(ConstructorName node) {
+ void visitConstructorName(ConstructorName node) {
//
// We do not visit either the type name, because it won't be visited anyway,
// or the name, because it needs to be visited in the context of the
@@ -4754,22 +4737,20 @@
//
node.accept(elementResolver);
node.accept(typeAnalyzer);
- return null;
}
@override
- Object visitContinueStatement(ContinueStatement node) {
+ void visitContinueStatement(ContinueStatement node) {
//
// We do not visit the label because it needs to be visited in the context
// of the statement.
//
node.accept(elementResolver);
node.accept(typeAnalyzer);
- return null;
}
@override
- Object visitDefaultFormalParameter(DefaultFormalParameter node) {
+ void visitDefaultFormalParameter(DefaultFormalParameter node) {
InferenceContext.setType(node.defaultValue,
resolutionMap.elementDeclaredByFormalParameter(node.parameter)?.type);
super.visitDefaultFormalParameter(node);
@@ -4785,11 +4766,10 @@
(element as ConstVariableElement).constantInitializer =
_createCloner().cloneNode(node.defaultValue);
}
- return null;
}
@override
- Object visitDoStatement(DoStatement node) {
+ void visitDoStatement(DoStatement node) {
_overrideManager.enterScope();
try {
InferenceContext.setType(node.condition, typeProvider.boolType);
@@ -4799,19 +4779,18 @@
}
// TODO(brianwilkerson) If the loop can only be exited because the condition
// is false, then propagateFalseState(node.getCondition());
- return null;
}
@override
- Object visitEmptyFunctionBody(EmptyFunctionBody node) {
+ void visitEmptyFunctionBody(EmptyFunctionBody node) {
if (resolveOnlyCommentInFunctionBody) {
- return null;
+ return;
}
- return super.visitEmptyFunctionBody(node);
+ super.visitEmptyFunctionBody(node);
}
@override
- Object visitEnumDeclaration(EnumDeclaration node) {
+ void visitEnumDeclaration(EnumDeclaration node) {
//
// Resolve the metadata in the library scope
// and associate the annotations with the element.
@@ -4836,13 +4815,12 @@
enclosingClass = outerType;
_enclosingClassDeclaration = null;
}
- return null;
}
@override
- Object visitExpressionFunctionBody(ExpressionFunctionBody node) {
+ void visitExpressionFunctionBody(ExpressionFunctionBody node) {
if (resolveOnlyCommentInFunctionBody) {
- return null;
+ return;
}
_overrideManager.enterScope();
try {
@@ -4861,11 +4839,10 @@
_overrideManager.exitScope();
inferenceContext.popReturnContext(node);
}
- return null;
}
@override
- Object visitFieldDeclaration(FieldDeclaration node) {
+ void visitFieldDeclaration(FieldDeclaration node) {
_overrideManager.enterScope();
try {
super.visitFieldDeclaration(node);
@@ -4875,18 +4852,16 @@
_overrideManager.exitScope();
_overrideManager.applyOverrides(overrides);
}
- return null;
}
@override
- Object visitForEachStatement(ForEachStatement node) {
+ void visitForEachStatement(ForEachStatement node) {
_overrideManager.enterScope();
try {
super.visitForEachStatement(node);
} finally {
_overrideManager.exitScope();
}
- return null;
}
@override
@@ -4959,14 +4934,13 @@
}
@override
- Object visitForStatement(ForStatement node) {
+ void visitForStatement(ForStatement node) {
_overrideManager.enterScope();
try {
super.visitForStatement(node);
} finally {
_overrideManager.exitScope();
}
- return null;
}
@override
@@ -4988,7 +4962,7 @@
}
@override
- Object visitFunctionDeclaration(FunctionDeclaration node) {
+ void visitFunctionDeclaration(FunctionDeclaration node) {
ExecutableElement outerFunction = _enclosingFunction;
FunctionBody outerFunctionBody = _currentFunctionBody;
try {
@@ -5002,7 +4976,6 @@
_currentFunctionBody = outerFunctionBody;
_enclosingFunction = outerFunction;
}
- return null;
}
@override
@@ -5012,7 +4985,7 @@
}
@override
- Object visitFunctionExpression(FunctionExpression node) {
+ void visitFunctionExpression(FunctionExpression node) {
ExecutableElement outerFunction = _enclosingFunction;
FunctionBody outerFunctionBody = _currentFunctionBody;
try {
@@ -5039,21 +5012,19 @@
_currentFunctionBody = outerFunctionBody;
_enclosingFunction = outerFunction;
}
- return null;
}
@override
- Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+ void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
node.function?.accept(this);
node.accept(elementResolver);
_inferArgumentTypesForInvocation(node);
node.argumentList?.accept(this);
node.accept(typeAnalyzer);
- return null;
}
@override
- Object visitFunctionTypeAlias(FunctionTypeAlias node) {
+ void visitFunctionTypeAlias(FunctionTypeAlias node) {
// Resolve the metadata in the library scope.
if (node.metadata != null) {
node.metadata.accept(this);
@@ -5065,7 +5036,6 @@
} finally {
_enclosingFunctionTypeAlias = outerAlias;
}
- return null;
}
@override
@@ -5075,20 +5045,19 @@
}
@override
- Object visitGenericFunctionType(GenericFunctionType node) => null;
+ void visitGenericFunctionType(GenericFunctionType node) {}
@override
- Object visitGenericTypeAliasInFunctionScope(GenericTypeAlias node) {
+ void visitGenericTypeAliasInFunctionScope(GenericTypeAlias node) {
super.visitGenericTypeAliasInFunctionScope(node);
safelyVisitComment(node.documentationComment);
- return null;
}
@override
- Object visitHideCombinator(HideCombinator node) => null;
+ void visitHideCombinator(HideCombinator node) {}
@override
- Object visitIfStatement(IfStatement node) {
+ void visitIfStatement(IfStatement node) {
Expression condition = node.condition;
InferenceContext.setType(condition, typeProvider.boolType);
condition?.accept(this);
@@ -5147,11 +5116,10 @@
perBranchOverrides.add(elseOverrides);
_overrideManager.mergeOverrides(perBranchOverrides);
}
- return null;
}
@override
- Object visitIndexExpression(IndexExpression node) {
+ void visitIndexExpression(IndexExpression node) {
node.target?.accept(this);
node.accept(elementResolver);
var method = node.staticElement;
@@ -5161,27 +5129,25 @@
}
node.index?.accept(this);
node.accept(typeAnalyzer);
- return null;
}
@override
- Object visitInstanceCreationExpression(InstanceCreationExpression node) {
+ void visitInstanceCreationExpression(InstanceCreationExpression node) {
node.constructorName?.accept(this);
_inferArgumentTypesForInstanceCreate(node);
node.argumentList?.accept(this);
node.accept(elementResolver);
node.accept(typeAnalyzer);
- return null;
}
@override
- Object visitLabel(Label node) => null;
+ void visitLabel(Label node) {}
@override
- Object visitLibraryIdentifier(LibraryIdentifier node) => null;
+ void visitLibraryIdentifier(LibraryIdentifier node) {}
@override
- Object visitListLiteral(ListLiteral node) {
+ void visitListLiteral(ListLiteral node) {
InterfaceType listT;
if (node.typeArguments != null) {
@@ -5202,11 +5168,10 @@
InferenceContext.clearType(node);
}
super.visitListLiteral(node);
- return null;
}
@override
- Object visitMapLiteral(MapLiteral node) {
+ void visitMapLiteral(MapLiteral node) {
InterfaceType mapT;
if (node.typeArguments != null) {
var targs = node.typeArguments.arguments.map((t) => t.type).toList();
@@ -5215,6 +5180,15 @@
}
} else {
mapT = typeAnalyzer.inferMapType(node, downwards: true);
+ if (mapT != null &&
+ node.typeArguments == null &&
+ node.entries.isEmpty &&
+ typeSystem.isAssignableTo(typeProvider.setNullType, mapT) &&
+ !typeSystem.isAssignableTo(typeProvider.mapNullNullType, mapT)) {
+ // The node is really an empty set literal with no type arguments, so
+ // don't try to visit the replaced map literal.
+ return;
+ }
}
if (mapT != null) {
DartType kType = mapT.typeArguments[0];
@@ -5228,11 +5202,10 @@
InferenceContext.clearType(node);
}
super.visitMapLiteral(node);
- return null;
}
@override
- Object visitMethodDeclaration(MethodDeclaration node) {
+ void visitMethodDeclaration(MethodDeclaration node) {
ExecutableElement outerFunction = _enclosingFunction;
FunctionBody outerFunctionBody = _currentFunctionBody;
try {
@@ -5246,7 +5219,6 @@
_currentFunctionBody = outerFunctionBody;
_enclosingFunction = outerFunction;
}
- return null;
}
@override
@@ -5256,7 +5228,7 @@
}
@override
- Object visitMethodInvocation(MethodInvocation node) {
+ void visitMethodInvocation(MethodInvocation node) {
//
// We visit the target and argument list, but do not visit the method name
// because it needs to be visited in the context of the invocation.
@@ -5267,11 +5239,10 @@
_inferArgumentTypesForInvocation(node);
node.argumentList?.accept(this);
node.accept(typeAnalyzer);
- return null;
}
@override
- Object visitMixinDeclaration(MixinDeclaration node) {
+ void visitMixinDeclaration(MixinDeclaration node) {
//
// Resolve the metadata in the library scope.
//
@@ -5292,31 +5263,29 @@
enclosingClass = outerType;
_enclosingMixinDeclaration = null;
}
- return null;
}
@override
- Object visitNamedExpression(NamedExpression node) {
+ void visitNamedExpression(NamedExpression node) {
InferenceContext.setTypeFromNode(node.expression, node);
- return super.visitNamedExpression(node);
+ super.visitNamedExpression(node);
}
@override
- Object visitNode(AstNode node) {
+ void visitNode(AstNode node) {
node.visitChildren(this);
node.accept(elementResolver);
node.accept(typeAnalyzer);
- return null;
}
@override
- Object visitParenthesizedExpression(ParenthesizedExpression node) {
+ void visitParenthesizedExpression(ParenthesizedExpression node) {
InferenceContext.setTypeFromNode(node.expression, node);
- return super.visitParenthesizedExpression(node);
+ super.visitParenthesizedExpression(node);
}
@override
- Object visitPrefixedIdentifier(PrefixedIdentifier node) {
+ void visitPrefixedIdentifier(PrefixedIdentifier node) {
//
// We visit the prefix, but do not visit the identifier because it needs to
// be visited in the context of the prefix.
@@ -5324,11 +5293,10 @@
node.prefix?.accept(this);
node.accept(elementResolver);
node.accept(typeAnalyzer);
- return null;
}
@override
- Object visitPropertyAccess(PropertyAccess node) {
+ void visitPropertyAccess(PropertyAccess node) {
//
// We visit the target, but do not visit the property name because it needs
// to be visited in the context of the property access node.
@@ -5336,11 +5304,10 @@
node.target?.accept(this);
node.accept(elementResolver);
node.accept(typeAnalyzer);
- return null;
}
@override
- Object visitRedirectingConstructorInvocation(
+ void visitRedirectingConstructorInvocation(
RedirectingConstructorInvocation node) {
//
// We visit the argument list, but do not visit the optional identifier
@@ -5352,11 +5319,10 @@
node.argumentList?.accept(this);
node.accept(elementResolver);
node.accept(typeAnalyzer);
- return null;
}
@override
- Object visitReturnStatement(ReturnStatement node) {
+ void visitReturnStatement(ReturnStatement node) {
Expression e = node.expression;
InferenceContext.setType(e, inferenceContext.returnContext);
super.visitReturnStatement(node);
@@ -5369,14 +5335,13 @@
}
inferenceContext.addReturnOrYieldType(type);
}
- return null;
}
@override
- Object visitShowCombinator(ShowCombinator node) => null;
+ void visitShowCombinator(ShowCombinator node) {}
@override
- Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+ void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
//
// We visit the argument list, but do not visit the optional identifier
// because it needs to be visited in the context of the constructor
@@ -5387,11 +5352,10 @@
node.argumentList?.accept(this);
node.accept(elementResolver);
node.accept(typeAnalyzer);
- return null;
}
@override
- Object visitSwitchCase(SwitchCase node) {
+ void visitSwitchCase(SwitchCase node) {
_overrideManager.enterScope();
try {
InferenceContext.setType(
@@ -5400,22 +5364,20 @@
} finally {
_overrideManager.exitScope();
}
- return null;
}
@override
- Object visitSwitchDefault(SwitchDefault node) {
+ void visitSwitchDefault(SwitchDefault node) {
_overrideManager.enterScope();
try {
super.visitSwitchDefault(node);
} finally {
_overrideManager.exitScope();
}
- return null;
}
@override
- Object visitSwitchStatementInScope(SwitchStatement node) {
+ void visitSwitchStatementInScope(SwitchStatement node) {
var previousExpressionType = _enclosingSwitchStatementExpressionType;
try {
node.expression?.accept(this);
@@ -5424,11 +5386,10 @@
} finally {
_enclosingSwitchStatementExpressionType = previousExpressionType;
}
- return null;
}
@override
- Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+ void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
_overrideManager.enterScope();
try {
super.visitTopLevelVariableDeclaration(node);
@@ -5438,14 +5399,13 @@
_overrideManager.exitScope();
_overrideManager.applyOverrides(overrides);
}
- return null;
}
@override
- Object visitTypeName(TypeName node) => null;
+ void visitTypeName(TypeName node) {}
@override
- Object visitVariableDeclaration(VariableDeclaration node) {
+ void visitVariableDeclaration(VariableDeclaration node) {
InferenceContext.setTypeFromNode(node.initializer, node);
super.visitVariableDeclaration(node);
VariableElement element = node.declaredElement;
@@ -5461,22 +5421,20 @@
(element as ConstVariableElement).constantInitializer =
_createCloner().cloneNode(node.initializer);
}
- return null;
}
@override
- Object visitVariableDeclarationList(VariableDeclarationList node) {
+ void visitVariableDeclarationList(VariableDeclarationList node) {
for (VariableDeclaration decl in node.variables) {
VariableElement variableElement =
resolutionMap.elementDeclaredByVariableDeclaration(decl);
InferenceContext.setType(decl, variableElement?.type);
}
super.visitVariableDeclarationList(node);
- return null;
}
@override
- Object visitWhileStatement(WhileStatement node) {
+ void visitWhileStatement(WhileStatement node) {
// Note: since we don't call the base class, we have to maintain
// _implicitLabelScope ourselves.
ImplicitLabelScope outerImplicitScope = _implicitLabelScope;
@@ -5502,11 +5460,10 @@
// is false, then propagateFalseState(condition);
node.accept(elementResolver);
node.accept(typeAnalyzer);
- return null;
}
@override
- Object visitYieldStatement(YieldStatement node) {
+ void visitYieldStatement(YieldStatement node) {
Expression e = node.expression;
DartType returnType = inferenceContext.returnContext;
bool isGenerator = _enclosingFunction?.isGenerator ?? false;
@@ -5542,7 +5499,6 @@
inferenceContext.addReturnOrYieldType(type);
}
}
- return null;
}
/// Checks each promoted variable in the current scope for compliance with the
@@ -6110,7 +6066,7 @@
/// The abstract class `ScopedVisitor` maintains name and label scopes as an AST
/// structure is being visited.
-abstract class ScopedVisitor extends UnifyingAstVisitor<Object> {
+abstract class ScopedVisitor extends UnifyingAstVisitor<void> {
/// The element for the library containing the compilation unit being visited.
final LibraryElement definingLibrary;
@@ -6185,7 +6141,7 @@
}
@override
- Object visitBlock(Block node) {
+ void visitBlock(Block node) {
Scope outerScope = nameScope;
try {
EnclosedScope enclosedScope = new BlockScope(nameScope, node);
@@ -6194,11 +6150,10 @@
} finally {
nameScope = outerScope;
}
- return null;
}
@override
- Object visitBlockFunctionBody(BlockFunctionBody node) {
+ void visitBlockFunctionBody(BlockFunctionBody node) {
ImplicitLabelScope implicitOuterScope = _implicitLabelScope;
try {
_implicitLabelScope = ImplicitLabelScope.ROOT;
@@ -6206,11 +6161,10 @@
} finally {
_implicitLabelScope = implicitOuterScope;
}
- return null;
}
@override
- Object visitCatchClause(CatchClause node) {
+ void visitCatchClause(CatchClause node) {
SimpleIdentifier exception = node.exceptionParameter;
if (exception != null) {
Scope outerScope = nameScope;
@@ -6228,11 +6182,10 @@
} else {
super.visitCatchClause(node);
}
- return null;
}
@override
- Object visitClassDeclaration(ClassDeclaration node) {
+ void visitClassDeclaration(ClassDeclaration node) {
ClassElement classElement = node.declaredElement;
Scope outerScope = nameScope;
try {
@@ -6256,7 +6209,6 @@
} finally {
nameScope = outerScope;
}
- return null;
}
void visitClassDeclarationInScope(ClassDeclaration node) {
@@ -6275,7 +6227,7 @@
}
@override
- Object visitClassTypeAlias(ClassTypeAlias node) {
+ void visitClassTypeAlias(ClassTypeAlias node) {
Scope outerScope = nameScope;
try {
ClassElement element = node.declaredElement;
@@ -6285,11 +6237,10 @@
} finally {
nameScope = outerScope;
}
- return null;
}
@override
- Object visitConstructorDeclaration(ConstructorDeclaration node) {
+ void visitConstructorDeclaration(ConstructorDeclaration node) {
ConstructorElement constructorElement = node.declaredElement;
if (constructorElement == null) {
StringBuffer buffer = new StringBuffer();
@@ -6329,7 +6280,6 @@
} finally {
nameScope = outerScope;
}
- return null;
}
void visitConstructorDeclarationInScope(ConstructorDeclaration node) {
@@ -6337,17 +6287,16 @@
}
@override
- Object visitDeclaredIdentifier(DeclaredIdentifier node) {
+ void visitDeclaredIdentifier(DeclaredIdentifier node) {
VariableElement element = node.declaredElement;
if (element != null) {
nameScope.define(element);
}
super.visitDeclaredIdentifier(node);
- return null;
}
@override
- Object visitDoStatement(DoStatement node) {
+ void visitDoStatement(DoStatement node) {
ImplicitLabelScope outerImplicitScope = _implicitLabelScope;
try {
_implicitLabelScope = _implicitLabelScope.nest(node);
@@ -6356,11 +6305,10 @@
} finally {
_implicitLabelScope = outerImplicitScope;
}
- return null;
}
@override
- Object visitEnumDeclaration(EnumDeclaration node) {
+ void visitEnumDeclaration(EnumDeclaration node) {
ClassElement classElement = node.declaredElement;
Scope outerScope = nameScope;
try {
@@ -6382,7 +6330,6 @@
} finally {
nameScope = outerScope;
}
- return null;
}
void visitEnumMembersInScope(EnumDeclaration node) {
@@ -6392,7 +6339,7 @@
}
@override
- Object visitForEachStatement(ForEachStatement node) {
+ void visitForEachStatement(ForEachStatement node) {
Scope outerNameScope = nameScope;
ImplicitLabelScope outerImplicitScope = _implicitLabelScope;
try {
@@ -6403,7 +6350,6 @@
nameScope = outerNameScope;
_implicitLabelScope = outerImplicitScope;
}
- return null;
}
/// Visit the given statement after it's scope has been created. This replaces
@@ -6423,7 +6369,7 @@
}
@override
- Object visitFormalParameterList(FormalParameterList node) {
+ void visitFormalParameterList(FormalParameterList node) {
super.visitFormalParameterList(node);
// We finished resolving function signature, now include formal parameters
// scope. Note: we must not do this if the parent is a
@@ -6436,11 +6382,10 @@
if (nameScope is FunctionTypeScope) {
(nameScope as FunctionTypeScope).defineParameters();
}
- return null;
}
@override
- Object visitForStatement(ForStatement node) {
+ void visitForStatement(ForStatement node) {
Scope outerNameScope = nameScope;
ImplicitLabelScope outerImplicitScope = _implicitLabelScope;
try {
@@ -6451,7 +6396,6 @@
nameScope = outerNameScope;
_implicitLabelScope = outerImplicitScope;
}
- return null;
}
/// Visit the given statement after it's scope has been created. This replaces
@@ -6468,7 +6412,7 @@
}
@override
- Object visitFunctionDeclaration(FunctionDeclaration node) {
+ void visitFunctionDeclaration(FunctionDeclaration node) {
ExecutableElement functionElement = node.declaredElement;
if (functionElement != null &&
functionElement.enclosingElement is! CompilationUnitElement) {
@@ -6487,7 +6431,6 @@
} finally {
nameScope = outerScope;
}
- return null;
}
void visitFunctionDeclarationInScope(FunctionDeclaration node) {
@@ -6495,7 +6438,7 @@
}
@override
- Object visitFunctionExpression(FunctionExpression node) {
+ void visitFunctionExpression(FunctionExpression node) {
if (node.parent is FunctionDeclaration) {
// We have already created a function scope and don't need to do so again.
super.visitFunctionExpression(node);
@@ -6528,11 +6471,10 @@
nameScope = outerScope;
}
}
- return null;
}
@override
- Object visitFunctionTypeAlias(FunctionTypeAlias node) {
+ void visitFunctionTypeAlias(FunctionTypeAlias node) {
Scope outerScope = nameScope;
try {
nameScope = new FunctionTypeScope(nameScope, node.declaredElement);
@@ -6540,7 +6482,6 @@
} finally {
nameScope = outerScope;
}
- return null;
}
void visitFunctionTypeAliasInScope(FunctionTypeAlias node) {
@@ -6548,7 +6489,7 @@
}
@override
- Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+ void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
Scope outerScope = nameScope;
try {
ParameterElement parameterElement = node.declaredElement;
@@ -6569,16 +6510,16 @@
} finally {
nameScope = outerScope;
}
- return null;
}
@override
- Object visitGenericFunctionType(GenericFunctionType node) {
+ void visitGenericFunctionType(GenericFunctionType node) {
DartType type = node.type;
if (type == null) {
// The function type hasn't been resolved yet, so we can't create a scope
// for its parameters.
- return super.visitGenericFunctionType(node);
+ super.visitGenericFunctionType(node);
+ return;
}
GenericFunctionTypeElement element = type.element;
Scope outerScope = nameScope;
@@ -6595,11 +6536,10 @@
} finally {
nameScope = outerScope;
}
- return null;
}
@override
- Object visitGenericTypeAlias(GenericTypeAlias node) {
+ void visitGenericTypeAlias(GenericTypeAlias node) {
GenericTypeAliasElement element = node.declaredElement;
Scope outerScope = nameScope;
try {
@@ -6622,34 +6562,29 @@
} finally {
nameScope = outerScope;
}
- return null;
}
- Object visitGenericTypeAliasInFunctionScope(GenericTypeAlias node) {
- return null;
- }
+ void visitGenericTypeAliasInFunctionScope(GenericTypeAlias node) {}
@override
- Object visitIfStatement(IfStatement node) {
+ void visitIfStatement(IfStatement node) {
node.condition?.accept(this);
visitStatementInScope(node.thenStatement);
visitStatementInScope(node.elseStatement);
- return null;
}
@override
- Object visitLabeledStatement(LabeledStatement node) {
+ void visitLabeledStatement(LabeledStatement node) {
LabelScope outerScope = _addScopesFor(node.labels, node.unlabeled);
try {
super.visitLabeledStatement(node);
} finally {
labelScope = outerScope;
}
- return null;
}
@override
- Object visitMethodDeclaration(MethodDeclaration node) {
+ void visitMethodDeclaration(MethodDeclaration node) {
Scope outerScope = nameScope;
try {
ExecutableElement methodElement = node.declaredElement;
@@ -6664,7 +6599,6 @@
} finally {
nameScope = outerScope;
}
- return null;
}
void visitMethodDeclarationInScope(MethodDeclaration node) {
@@ -6672,7 +6606,7 @@
}
@override
- Object visitMixinDeclaration(MixinDeclaration node) {
+ void visitMixinDeclaration(MixinDeclaration node) {
ClassElement element = node.declaredElement;
Scope outerScope = nameScope;
@@ -6689,7 +6623,6 @@
nameScope = outerScope;
enclosingClass = outerClass;
}
- return null;
}
void visitMixinDeclarationInScope(MixinDeclaration node) {
@@ -6727,7 +6660,7 @@
}
@override
- Object visitSwitchCase(SwitchCase node) {
+ void visitSwitchCase(SwitchCase node) {
node.expression.accept(this);
Scope outerNameScope = nameScope;
try {
@@ -6736,11 +6669,10 @@
} finally {
nameScope = outerNameScope;
}
- return null;
}
@override
- Object visitSwitchDefault(SwitchDefault node) {
+ void visitSwitchDefault(SwitchDefault node) {
Scope outerNameScope = nameScope;
try {
nameScope = new EnclosedScope(nameScope);
@@ -6748,11 +6680,10 @@
} finally {
nameScope = outerNameScope;
}
- return null;
}
@override
- Object visitSwitchStatement(SwitchStatement node) {
+ void visitSwitchStatement(SwitchStatement node) {
LabelScope outerScope = labelScope;
ImplicitLabelScope outerImplicitScope = _implicitLabelScope;
try {
@@ -6770,7 +6701,6 @@
labelScope = outerScope;
_implicitLabelScope = outerImplicitScope;
}
- return null;
}
void visitSwitchStatementInScope(SwitchStatement node) {
@@ -6778,7 +6708,7 @@
}
@override
- Object visitVariableDeclaration(VariableDeclaration node) {
+ void visitVariableDeclaration(VariableDeclaration node) {
super.visitVariableDeclaration(node);
if (node.parent.parent is! TopLevelVariableDeclaration &&
node.parent.parent is! FieldDeclaration) {
@@ -6787,11 +6717,10 @@
nameScope.define(element);
}
}
- return null;
}
@override
- Object visitWhileStatement(WhileStatement node) {
+ void visitWhileStatement(WhileStatement node) {
node.condition?.accept(this);
ImplicitLabelScope outerImplicitScope = _implicitLabelScope;
try {
@@ -6800,7 +6729,6 @@
} finally {
_implicitLabelScope = outerImplicitScope;
}
- return null;
}
/// Add scopes for each of the given labels.
@@ -7889,6 +7817,9 @@
/// Return the type representing the built-in type 'List'.
InterfaceType get listType;
+ /// Return the type representing 'Map<Null, Null>'.
+ InterfaceType get mapNullNullType;
+
/// Return the type representing the built-in type 'Map'.
InterfaceType get mapType;
@@ -7908,6 +7839,12 @@
/// Return the type representing the built-in type 'Object'.
InterfaceType get objectType;
+ /// Return the type representing 'Set<Null>'.
+ InterfaceType get setNullType;
+
+ /// Return the type representing the built-in type 'Set'.
+ InterfaceType get setType;
+
/// Return the type representing the built-in type 'StackTrace'.
InterfaceType get stackTraceType;
@@ -8025,9 +7962,18 @@
/// The type representing the built-in type 'Map'.
InterfaceType _mapType;
+ /// The type representing the built-in type 'Map<Null, Null>'.
+ InterfaceType _mapNullNullType;
+
/// An shared object representing the value 'null'.
DartObjectImpl _nullObject;
+ /// The type representing the type 'Set'.
+ InterfaceType _setType;
+
+ /// The type representing the type 'Set<Null>'.
+ InterfaceType _setNullType;
+
/// The type representing the type 'Null'.
InterfaceType _nullType;
@@ -8121,6 +8067,9 @@
InterfaceType get listType => _listType;
@override
+ InterfaceType get mapNullNullType => _mapNullNullType;
+
+ @override
InterfaceType get mapType => _mapType;
@override
@@ -8141,6 +8090,12 @@
InterfaceType get objectType => _objectType;
@override
+ InterfaceType get setNullType => _setNullType;
+
+ @override
+ InterfaceType get setType => _setType;
+
+ @override
InterfaceType get stackTraceType => _stackTraceType;
@override
@@ -8195,6 +8150,7 @@
_nullType = _getType(coreNamespace, "Null");
_numType = _getType(coreNamespace, "num");
_objectType = _getType(coreNamespace, "Object");
+ _setType = _getType(coreNamespace, "Set");
_stackTraceType = _getType(coreNamespace, "StackTrace");
_streamType = _getType(asyncNamespace, "Stream");
_stringType = _getType(coreNamespace, "String");
@@ -8204,6 +8160,8 @@
_futureDynamicType = _futureType.instantiate(<DartType>[_dynamicType]);
_futureNullType = _futureType.instantiate(<DartType>[_nullType]);
_iterableDynamicType = _iterableType.instantiate(<DartType>[_dynamicType]);
+ _mapNullNullType = _mapType.instantiate(<DartType>[_nullType, _nullType]);
+ _setNullType = _setType.instantiate(<DartType>[_nullType]);
_streamDynamicType = _streamType.instantiate(<DartType>[_dynamicType]);
// FutureOr<T> is still fairly new, so if we're analyzing an SDK that
// doesn't have it yet, create an element for it.
@@ -8311,7 +8269,7 @@
}
@override
- Object visitAnnotation(Annotation node) {
+ void visitAnnotation(Annotation node) {
//
// Visit annotations, if the annotation is @proxy, on a class, and "proxy"
// resolves to the proxy annotation in dart.core, then resolve the
@@ -8336,11 +8294,10 @@
elementAnnotation.element = element;
}
}
- return null;
}
@override
- Object visitCatchClause(CatchClause node) {
+ void visitCatchClause(CatchClause node) {
super.visitCatchClause(node);
SimpleIdentifier exception = node.exceptionParameter;
if (exception != null) {
@@ -8372,11 +8329,10 @@
// TODO(brianwilkerson) Report the internal error
}
}
- return null;
}
@override
- Object visitClassDeclaration(ClassDeclaration node) {
+ void visitClassDeclaration(ClassDeclaration node) {
_hasReferenceToSuper = false;
super.visitClassDeclaration(node);
ClassElementImpl classElement = _getClassElement(node.name);
@@ -8385,7 +8341,6 @@
classElement.hasBeenInferred = false;
classElement.hasReferenceToSuper = _hasReferenceToSuper;
}
- return null;
}
@override
@@ -8414,7 +8369,6 @@
}
_resolveWithClause(classElement, withClause);
_resolveImplementsClause(classElement, implementsClause);
- return null;
}
@override
@@ -8443,7 +8397,7 @@
}
@override
- Object visitClassTypeAlias(ClassTypeAlias node) {
+ void visitClassTypeAlias(ClassTypeAlias node) {
super.visitClassTypeAlias(node);
ErrorCode errorCode = CompileTimeErrorCode.MIXIN_WITH_NON_CLASS_SUPERCLASS;
InterfaceType superclassType =
@@ -8457,15 +8411,14 @@
}
_resolveWithClause(classElement, node.withClause);
_resolveImplementsClause(classElement, node.implementsClause);
- return null;
}
@override
- Object visitConstructorDeclaration(ConstructorDeclaration node) {
+ void visitConstructorDeclaration(ConstructorDeclaration node) {
super.visitConstructorDeclaration(node);
if (node.declaredElement == null) {
ClassDeclaration classNode =
- node.getAncestor((node) => node is ClassDeclaration);
+ node.thisOrAncestorOfType<ClassDeclaration>();
StringBuffer buffer = new StringBuffer();
buffer.write("The element for the constructor ");
buffer.write(node.name == null ? "<unnamed>" : node.name.name);
@@ -8481,11 +8434,10 @@
AnalysisEngine.instance.logger.logError(buffer.toString(),
new CaughtException(new AnalysisException(), null));
}
- return null;
}
@override
- Object visitDeclaredIdentifier(DeclaredIdentifier node) {
+ void visitDeclaredIdentifier(DeclaredIdentifier node) {
super.visitDeclaredIdentifier(node);
DartType declaredType;
TypeAnnotation typeName = node.type;
@@ -8497,11 +8449,10 @@
LocalVariableElementImpl element =
node.declaredElement as LocalVariableElementImpl;
element.declaredType = declaredType;
- return null;
}
@override
- Object visitFieldFormalParameter(FieldFormalParameter node) {
+ void visitFieldFormalParameter(FieldFormalParameter node) {
super.visitFieldFormalParameter(node);
Element element = node.identifier.staticElement;
if (element is ParameterElementImpl) {
@@ -8526,11 +8477,10 @@
} else {
// TODO(brianwilkerson) Report this internal error
}
- return null;
}
@override
- Object visitFunctionDeclaration(FunctionDeclaration node) {
+ void visitFunctionDeclaration(FunctionDeclaration node) {
super.visitFunctionDeclaration(node);
ExecutableElementImpl element =
node.declaredElement as ExecutableElementImpl;
@@ -8547,19 +8497,17 @@
element.declaredReturnType = _computeReturnType(node.returnType);
element.type = new FunctionTypeImpl(element);
_inferSetterReturnType(element);
- return null;
}
@override
- Object visitFunctionTypeAlias(FunctionTypeAlias node) {
+ void visitFunctionTypeAlias(FunctionTypeAlias node) {
var element = node.declaredElement as GenericTypeAliasElementImpl;
super.visitFunctionTypeAlias(node);
element.function.returnType = _computeReturnType(node.returnType);
- return null;
}
@override
- Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+ void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
super.visitFunctionTypedFormalParameter(node);
Element element = node.identifier.staticElement;
if (element is ParameterElementImpl) {
@@ -8567,28 +8515,26 @@
} else {
// TODO(brianwilkerson) Report this internal error
}
- return null;
}
@override
- Object visitGenericFunctionType(GenericFunctionType node) {
+ void visitGenericFunctionType(GenericFunctionType node) {
GenericFunctionTypeElementImpl element = node.type?.element;
if (element != null) {
super.visitGenericFunctionType(node);
element.returnType =
_computeReturnType(node.returnType) ?? DynamicTypeImpl.instance;
}
- return null;
}
@override
- Object visitMethodDeclaration(MethodDeclaration node) {
+ void visitMethodDeclaration(MethodDeclaration node) {
super.visitMethodDeclaration(node);
ExecutableElementImpl element =
node.declaredElement as ExecutableElementImpl;
if (element == null) {
ClassDeclaration classNode =
- node.getAncestor((node) => node is ClassDeclaration);
+ node.thisOrAncestorOfType<ClassDeclaration>();
StringBuffer buffer = new StringBuffer();
buffer.write("The element for the method ");
buffer.write(node.name.name);
@@ -8609,7 +8555,7 @@
// already set - statically or inferred. We don't want to overwrite them.
if (LibraryElementImpl.hasResolutionCapability(
definingLibrary, LibraryResolutionCapability.resolvedTypeNames)) {
- return null;
+ return;
}
element.declaredReturnType = _computeReturnType(node.returnType);
@@ -8630,8 +8576,6 @@
variable.declaredType = type;
}
}
-
- return null;
}
@override
@@ -8640,25 +8584,24 @@
MixinElementImpl element = node.declaredElement;
_resolveOnClause(element, node.onClause);
_resolveImplementsClause(element, node.implementsClause);
- return null;
}
@override
- Object visitNode(AstNode node) {
+ void visitNode(AstNode node) {
// In API mode we need to skip:
// - function bodies;
// - default values of parameters;
// - initializers of top-level variables.
if (mode == TypeResolverMode.api) {
if (node is FunctionBody) {
- return null;
+ return;
}
if (node is DefaultFormalParameter) {
node.parameter.accept(this);
- return null;
+ return;
}
if (node is VariableDeclaration) {
- return null;
+ return;
}
}
@@ -8672,7 +8615,8 @@
if (mode == TypeResolverMode.local) {
// We are in the state of visiting all nodes.
if (_localModeVisitAll) {
- return super.visitNode(node);
+ super.visitNode(node);
+ return;
}
// Ensure that the name scope is ready.
@@ -8740,15 +8684,14 @@
} else if (node is VariableDeclarationList) {
node.variables.forEach(visitNode);
}
- return null;
+ return;
}
-
// The mode in which we visit all nodes.
- return super.visitNode(node);
+ super.visitNode(node);
}
@override
- Object visitSimpleFormalParameter(SimpleFormalParameter node) {
+ void visitSimpleFormalParameter(SimpleFormalParameter node) {
super.visitSimpleFormalParameter(node);
DartType declaredType;
TypeAnnotation typeName = node.type;
@@ -8763,25 +8706,23 @@
} else {
// TODO(brianwilkerson) Report the internal error.
}
- return null;
}
@override
- Object visitSuperExpression(SuperExpression node) {
+ void visitSuperExpression(SuperExpression node) {
_hasReferenceToSuper = true;
- return super.visitSuperExpression(node);
+ super.visitSuperExpression(node);
}
@override
- Object visitTypeName(TypeName node) {
+ void visitTypeName(TypeName node) {
super.visitTypeName(node);
_typeNameResolver.nameScope = this.nameScope;
_typeNameResolver.resolveTypeName(node);
- return null;
}
@override
- Object visitTypeParameter(TypeParameter node) {
+ void visitTypeParameter(TypeParameter node) {
super.visitTypeParameter(node);
AstNode parent2 = node.parent?.parent;
if (parent2 is ClassDeclaration ||
@@ -8800,11 +8741,10 @@
}
}
}
- return null;
}
@override
- Object visitVariableDeclaration(VariableDeclaration node) {
+ void visitVariableDeclaration(VariableDeclaration node) {
super.visitVariableDeclaration(node);
var variableList = node.parent as VariableDeclarationList;
// When the library is resynthesized, the types of field elements are
@@ -8812,7 +8752,7 @@
if (variableList.parent is FieldDeclaration &&
LibraryElementImpl.hasResolutionCapability(
definingLibrary, LibraryResolutionCapability.resolvedTypeNames)) {
- return null;
+ return;
}
// Resolve the type.
DartType declaredType;
@@ -8826,7 +8766,6 @@
if (element is VariableElementImpl) {
element.declaredType = declaredType;
}
- return null;
}
/// Given the [returnType] of a function, compute the return type of the
@@ -9264,20 +9203,20 @@
nameScope: nameScope);
@override
- Object visitBlockFunctionBody(BlockFunctionBody node) {
+ void visitBlockFunctionBody(BlockFunctionBody node) {
assert(_localVariableInfo != null);
- return super.visitBlockFunctionBody(node);
+ super.visitBlockFunctionBody(node);
}
@override
- Object visitConstructorDeclaration(ConstructorDeclaration node) {
+ void visitConstructorDeclaration(ConstructorDeclaration node) {
ExecutableElement outerFunction = _enclosingFunction;
LocalVariableInfo outerLocalVariableInfo = _localVariableInfo;
try {
_localVariableInfo ??= new LocalVariableInfo();
(node.body as FunctionBodyImpl).localVariableInfo = _localVariableInfo;
_enclosingFunction = node.declaredElement;
- return super.visitConstructorDeclaration(node);
+ super.visitConstructorDeclaration(node);
} finally {
_localVariableInfo = outerLocalVariableInfo;
_enclosingFunction = outerFunction;
@@ -9285,16 +9224,16 @@
}
@override
- Object visitExportDirective(ExportDirective node) => null;
+ void visitExportDirective(ExportDirective node) {}
@override
- Object visitExpressionFunctionBody(ExpressionFunctionBody node) {
+ void visitExpressionFunctionBody(ExpressionFunctionBody node) {
assert(_localVariableInfo != null);
- return super.visitExpressionFunctionBody(node);
+ super.visitExpressionFunctionBody(node);
}
@override
- Object visitFunctionDeclaration(FunctionDeclaration node) {
+ void visitFunctionDeclaration(FunctionDeclaration node) {
ExecutableElement outerFunction = _enclosingFunction;
LocalVariableInfo outerLocalVariableInfo = _localVariableInfo;
try {
@@ -9302,7 +9241,7 @@
(node.functionExpression.body as FunctionBodyImpl).localVariableInfo =
_localVariableInfo;
_enclosingFunction = node.declaredElement;
- return super.visitFunctionDeclaration(node);
+ super.visitFunctionDeclaration(node);
} finally {
_localVariableInfo = outerLocalVariableInfo;
_enclosingFunction = outerFunction;
@@ -9310,7 +9249,7 @@
}
@override
- Object visitFunctionExpression(FunctionExpression node) {
+ void visitFunctionExpression(FunctionExpression node) {
if (node.parent is! FunctionDeclaration) {
ExecutableElement outerFunction = _enclosingFunction;
LocalVariableInfo outerLocalVariableInfo = _localVariableInfo;
@@ -9318,28 +9257,28 @@
_localVariableInfo ??= new LocalVariableInfo();
(node.body as FunctionBodyImpl).localVariableInfo = _localVariableInfo;
_enclosingFunction = node.declaredElement;
- return super.visitFunctionExpression(node);
+ super.visitFunctionExpression(node);
} finally {
_localVariableInfo = outerLocalVariableInfo;
_enclosingFunction = outerFunction;
}
} else {
- return super.visitFunctionExpression(node);
+ super.visitFunctionExpression(node);
}
}
@override
- Object visitImportDirective(ImportDirective node) => null;
+ void visitImportDirective(ImportDirective node) {}
@override
- Object visitMethodDeclaration(MethodDeclaration node) {
+ void visitMethodDeclaration(MethodDeclaration node) {
ExecutableElement outerFunction = _enclosingFunction;
LocalVariableInfo outerLocalVariableInfo = _localVariableInfo;
try {
_localVariableInfo ??= new LocalVariableInfo();
(node.body as FunctionBodyImpl).localVariableInfo = _localVariableInfo;
_enclosingFunction = node.declaredElement;
- return super.visitMethodDeclaration(node);
+ super.visitMethodDeclaration(node);
} finally {
_localVariableInfo = outerLocalVariableInfo;
_enclosingFunction = outerFunction;
@@ -9347,43 +9286,43 @@
}
@override
- Object visitSimpleIdentifier(SimpleIdentifier node) {
+ void visitSimpleIdentifier(SimpleIdentifier node) {
// Ignore if already resolved - declaration or type.
if (node.inDeclarationContext()) {
- return null;
+ return;
}
// Ignore if it cannot be a reference to a local variable.
AstNode parent = node.parent;
if (parent is FieldFormalParameter) {
- return null;
+ return;
} else if (parent is ConstructorDeclaration && parent.returnType == node) {
- return null;
+ return;
} else if (parent is ConstructorFieldInitializer &&
parent.fieldName == node) {
- return null;
+ return;
}
// Ignore if qualified.
if (parent is PrefixedIdentifier && identical(parent.identifier, node)) {
- return null;
+ return;
}
if (parent is PropertyAccess && identical(parent.propertyName, node)) {
- return null;
+ return;
}
if (parent is MethodInvocation &&
identical(parent.methodName, node) &&
parent.realTarget != null) {
- return null;
+ return;
}
if (parent is ConstructorName) {
- return null;
+ return;
}
if (parent is Label) {
- return null;
+ return;
}
// Prepare VariableElement.
Element element = nameScope.lookup(node, definingLibrary);
if (element is! VariableElement) {
- return null;
+ return;
}
// Must be local or parameter.
ElementKind kind = element.kind;
@@ -9396,13 +9335,10 @@
}
}
}
- return null;
}
@override
- Object visitTypeName(TypeName node) {
- return null;
- }
+ void visitTypeName(TypeName node) {}
}
class _InvalidAccessVerifier {
@@ -9614,7 +9550,7 @@
}
class _ResolverVisitor_isVariableAccessedInClosure
- extends RecursiveAstVisitor<Object> {
+ extends RecursiveAstVisitor<void> {
final Element variable;
bool result = false;
@@ -9624,30 +9560,29 @@
_ResolverVisitor_isVariableAccessedInClosure(this.variable);
@override
- Object visitFunctionExpression(FunctionExpression node) {
+ void visitFunctionExpression(FunctionExpression node) {
bool inClosure = this._inClosure;
try {
this._inClosure = true;
- return super.visitFunctionExpression(node);
+ super.visitFunctionExpression(node);
} finally {
this._inClosure = inClosure;
}
}
@override
- Object visitSimpleIdentifier(SimpleIdentifier node) {
+ void visitSimpleIdentifier(SimpleIdentifier node) {
if (result) {
- return null;
+ return;
}
if (_inClosure && identical(node.staticElement, variable)) {
result = true;
}
- return null;
}
}
class _ResolverVisitor_isVariablePotentiallyMutatedIn
- extends RecursiveAstVisitor<Object> {
+ extends RecursiveAstVisitor<void> {
final Element variable;
bool result = false;
@@ -9655,15 +9590,14 @@
_ResolverVisitor_isVariablePotentiallyMutatedIn(this.variable);
@override
- Object visitSimpleIdentifier(SimpleIdentifier node) {
+ void visitSimpleIdentifier(SimpleIdentifier node) {
if (result) {
- return null;
+ return;
}
if (identical(node.staticElement, variable)) {
if (node.inSetterContext()) {
result = true;
}
}
- return null;
}
}
diff --git a/pkg/analyzer/lib/src/generated/sdk.dart b/pkg/analyzer/lib/src/generated/sdk.dart
index d024db1..c7ae2db 100644
--- a/pkg/analyzer/lib/src/generated/sdk.dart
+++ b/pkg/analyzer/lib/src/generated/sdk.dart
@@ -265,7 +265,7 @@
}
}
-class SdkLibrariesReader_LibraryBuilder extends RecursiveAstVisitor<Object> {
+class SdkLibrariesReader_LibraryBuilder extends RecursiveAstVisitor<void> {
/**
* The prefix added to the name of a library to form the URI used in code to
* reference the library.
@@ -351,7 +351,7 @@
}
@override
- Object visitMapLiteralEntry(MapLiteralEntry node) {
+ void visitMapLiteralEntry(MapLiteralEntry node) {
String libraryName = null;
Expression key = node.key;
if (key is SimpleStringLiteral) {
@@ -392,7 +392,6 @@
}
_librariesMap.setLibrary(libraryName, library);
}
- return null;
}
}
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index dfc94e4..378592a 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -11,6 +11,8 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/ast/ast_factory.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/member.dart' show ConstructorMember;
import 'package:analyzer/src/dart/element/type.dart';
@@ -28,7 +30,7 @@
* * Every node representing an expression should be resolved to the Type of the expression.
* </ol>
*/
-class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
+class StaticTypeAnalyzer extends SimpleAstVisitor<void> {
/**
* The resolver driving the resolution and type analysis.
*/
@@ -171,6 +173,22 @@
ParameterizedType inferMapType(MapLiteral node, {bool downwards: false}) {
DartType contextType = InferenceContext.getContext(node);
+ if (contextType != null &&
+ node.typeArguments == null &&
+ node.entries.isEmpty &&
+ _typeSystem.isAssignableTo(_typeProvider.setNullType, contextType) &&
+ !_typeSystem.isAssignableTo(
+ _typeProvider.mapNullNullType, contextType)) {
+ // The node is really an empty set literal with no type arguments. Rewrite
+ // the AST and infer the type of the set as appropriate.
+ SetLiteral setLiteral = new AstFactoryImpl().setLiteral(
+ node.constKeyword, null, node.leftBracket, null, node.rightBracket);
+ InferenceContext.setType(setLiteral, contextType);
+ NodeReplacer.replace(node, setLiteral);
+ DartType type = inferSetType(setLiteral, downwards: downwards);
+ setLiteral.staticType = type;
+ return type;
+ }
List<DartType> elementTypes;
List<ParameterElement> parameters;
if (downwards) {
@@ -206,14 +224,46 @@
return inferred;
}
+ DartType inferSetType(SetLiteral node, {bool downwards: false}) {
+ DartType contextType = InferenceContext.getContext(node);
+
+ var ts = _typeSystem as StrongTypeSystemImpl;
+ List<DartType> elementTypes;
+ List<ParameterElement> parameters;
+
+ if (downwards) {
+ if (contextType == null) {
+ return null;
+ }
+
+ elementTypes = [];
+ parameters = [];
+ } else {
+ // Also use upwards information to infer the type.
+ elementTypes = node.elements
+ .map((e) => e.staticType)
+ .where((t) => t != null)
+ .toList();
+ var setTypeParam = _typeProvider.setType.typeParameters[0].type;
+ var syntheticParamElement = new ParameterElementImpl.synthetic(
+ 'element', setTypeParam, ParameterKind.POSITIONAL);
+ parameters = new List.filled(elementTypes.length, syntheticParamElement);
+ }
+ DartType inferred = ts.inferGenericFunctionOrType<InterfaceType>(
+ _typeProvider.setType, parameters, elementTypes, contextType,
+ downwards: downwards,
+ errorReporter: _resolver.errorReporter,
+ errorNode: node);
+ return inferred;
+ }
+
/**
* The Dart Language Specification, 12.5: <blockquote>The static type of a string literal is
* `String`.</blockquote>
*/
@override
- Object visitAdjacentStrings(AdjacentStrings node) {
+ void visitAdjacentStrings(AdjacentStrings node) {
_recordStaticType(node, _typeProvider.stringType);
- return null;
}
/**
@@ -225,9 +275,8 @@
* The static type of a cast expression <i>e as T</i> is <i>T</i>.</blockquote>
*/
@override
- Object visitAsExpression(AsExpression node) {
+ void visitAsExpression(AsExpression node) {
_recordStaticType(node, _getType(node.type));
- return null;
}
/**
@@ -270,7 +319,7 @@
* <i>e<sub>3</sub></i>.</blockquote>
*/
@override
- Object visitAssignmentExpression(AssignmentExpression node) {
+ void visitAssignmentExpression(AssignmentExpression node) {
TokenType operator = node.operator.type;
if (operator == TokenType.EQ) {
Expression rightHandSide = node.rightHandSide;
@@ -281,7 +330,7 @@
// bound of the static types of the LHS and RHS.
_analyzeLeastUpperBound(node, node.leftHandSide, node.rightHandSide,
read: true);
- return null;
+ return;
} else if (operator == TokenType.AMPERSAND_AMPERSAND_EQ ||
operator == TokenType.BAR_BAR_EQ) {
_recordStaticType(node, _typeProvider.boolType);
@@ -295,7 +344,6 @@
staticType);
_recordStaticType(node, staticType);
}
- return null;
}
/**
@@ -305,7 +353,7 @@
* the static type of e.
*/
@override
- Object visitAwaitExpression(AwaitExpression node) {
+ void visitAwaitExpression(AwaitExpression node) {
// Await the Future. This results in whatever type is (ultimately) returned.
DartType awaitType(DartType awaitedType) {
if (awaitedType == null) {
@@ -318,7 +366,6 @@
}
_recordStaticType(node, awaitType(_getStaticType(node.expression)));
- return null;
}
/**
@@ -359,14 +406,14 @@
* <i>super.op(e<sub>2</sub>)</i>.</blockquote>
*/
@override
- Object visitBinaryExpression(BinaryExpression node) {
+ void visitBinaryExpression(BinaryExpression node) {
if (node.operator.type == TokenType.QUESTION_QUESTION) {
// Evaluation of an if-null expression e of the form e1 ?? e2 is
// equivalent to the evaluation of the expression
// ((x) => x == null ? e2 : x)(e1). The static type of e is the least
// upper bound of the static type of e1 and the static type of e2.
_analyzeLeastUpperBound(node, node.leftOperand, node.rightOperand);
- return null;
+ return;
}
DartType staticType = node.staticInvokeType?.returnType ?? _dynamicType;
staticType = _typeSystem.refineBinaryExpressionType(
@@ -375,7 +422,6 @@
node.rightOperand.staticType,
staticType);
_recordStaticType(node, staticType);
- return null;
}
/**
@@ -383,9 +429,8 @@
* bool.</blockquote>
*/
@override
- Object visitBooleanLiteral(BooleanLiteral node) {
+ void visitBooleanLiteral(BooleanLiteral node) {
_recordStaticType(node, _typeProvider.boolType);
- return null;
}
/**
@@ -394,9 +439,8 @@
* t;}(e)</i>.</blockquote>
*/
@override
- Object visitCascadeExpression(CascadeExpression node) {
+ void visitCascadeExpression(CascadeExpression node) {
_recordStaticType(node, _getStaticType(node.target));
- return null;
}
/**
@@ -409,16 +453,14 @@
* and the static type of <i>e<sub>3</sub></i>.</blockquote>
*/
@override
- Object visitConditionalExpression(ConditionalExpression node) {
+ void visitConditionalExpression(ConditionalExpression node) {
_analyzeLeastUpperBound(node, node.thenExpression, node.elseExpression);
- return null;
}
@override
- Object visitDeclaredIdentifier(DeclaredIdentifier node) {
+ void visitDeclaredIdentifier(DeclaredIdentifier node) {
super.visitDeclaredIdentifier(node);
_inferForEachLoopVariableType(node);
- return null;
}
/**
@@ -426,13 +468,12 @@
* double.</blockquote>
*/
@override
- Object visitDoubleLiteral(DoubleLiteral node) {
+ void visitDoubleLiteral(DoubleLiteral node) {
_recordStaticType(node, _typeProvider.doubleType);
- return null;
}
@override
- Object visitFunctionDeclaration(FunctionDeclaration node) {
+ void visitFunctionDeclaration(FunctionDeclaration node) {
FunctionExpression function = node.functionExpression;
ExecutableElementImpl functionElement =
node.declaredElement as ExecutableElementImpl;
@@ -441,13 +482,12 @@
// we only need to handle local functions.
if (node.returnType == null) {
_inferLocalFunctionReturnType(node.functionExpression);
- return null;
+ return;
}
functionElement.returnType =
_computeStaticReturnTypeOfFunctionDeclaration(node);
}
_recordStaticType(function, functionElement.type);
- return null;
}
/**
@@ -481,14 +521,13 @@
* specified as dynamic.</blockquote>
*/
@override
- Object visitFunctionExpression(FunctionExpression node) {
+ void visitFunctionExpression(FunctionExpression node) {
if (node.parent is FunctionDeclaration) {
// The function type will be resolved and set when we visit the parent
// node.
- return null;
+ return;
}
_inferLocalFunctionReturnType(node);
- return null;
}
/**
@@ -504,11 +543,10 @@
* static type of <i>i</i> is the declared return type of <i>F</i>.</blockquote>
*/
@override
- Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+ void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
_inferGenericInvocationExpression(node);
DartType staticType = _computeInvokeReturnType(node.staticInvokeType);
_recordStaticType(node, staticType);
- return null;
}
/**
@@ -517,7 +555,7 @@
* <i>[]</i> on <i>e<sub>1</sub></i> with argument <i>e<sub>2</sub></i>.</blockquote>
*/
@override
- Object visitIndexExpression(IndexExpression node) {
+ void visitIndexExpression(IndexExpression node) {
if (node.inSetterContext()) {
ExecutableElement staticMethodElement = node.staticElement;
DartType staticType = _computeArgumentType(staticMethodElement);
@@ -527,7 +565,6 @@
DartType staticType = _computeStaticReturnType(staticMethodElement);
_recordStaticType(node, staticType);
}
- return null;
}
/**
@@ -540,11 +577,9 @@
* form <i>const T(a<sub>1</sub>, …, a<sub>n</sub>)</i> is <i>T</i>. </blockquote>
*/
@override
- Object visitInstanceCreationExpression(InstanceCreationExpression node) {
+ void visitInstanceCreationExpression(InstanceCreationExpression node) {
_inferInstanceCreationExpression(node);
-
_recordStaticType(node, node.constructorName.type.type);
- return null;
}
/**
@@ -565,7 +600,7 @@
* </blockquote>
*/
@override
- Object visitIntegerLiteral(IntegerLiteral node) {
+ void visitIntegerLiteral(IntegerLiteral node) {
// Check the parent context for negated integer literals.
var context = InferenceContext.getContext(
(node as IntegerLiteralImpl).immediatelyNegated ? node.parent : node);
@@ -576,7 +611,6 @@
} else {
_recordStaticType(node, _typeProvider.doubleType);
}
- return null;
}
/**
@@ -586,9 +620,8 @@
* The static type of an is-expression is `bool`.</blockquote>
*/
@override
- Object visitIsExpression(IsExpression node) {
+ void visitIsExpression(IsExpression node) {
_recordStaticType(node, _typeProvider.boolType);
- return null;
}
/**
@@ -600,7 +633,7 @@
* .</blockquote>
*/
@override
- Object visitListLiteral(ListLiteral node) {
+ void visitListLiteral(ListLiteral node) {
TypeArgumentList typeArguments = node.typeArguments;
// If we have explicit arguments, use them
@@ -615,7 +648,7 @@
}
_recordStaticType(
node, _typeProvider.listType.instantiate(<DartType>[staticType]));
- return null;
+ return;
}
DartType listDynamicType =
@@ -631,12 +664,11 @@
// everything was successful?
_resolver.inferenceContext.recordInference(node, inferred);
_recordStaticType(node, inferred);
- return null;
+ return;
}
// If we have no type arguments and couldn't infer any, use dynamic.
_recordStaticType(node, listDynamicType);
- return null;
}
/**
@@ -652,12 +684,9 @@
* <i>String</i>.</blockquote>
*/
@override
- Object visitMapLiteral(MapLiteral node) {
+ void visitMapLiteral(MapLiteral node) {
TypeArgumentList typeArguments = node.typeArguments;
- DartType mapDynamicType = _typeProvider.mapType
- .instantiate(<DartType>[_dynamicType, _dynamicType]);
-
// If we have type arguments, use them
if (typeArguments != null) {
DartType staticKeyType = _dynamicType;
@@ -677,9 +706,12 @@
node,
_typeProvider.mapType
.instantiate(<DartType>[staticKeyType, staticValueType]));
- return null;
+ return;
}
+ DartType mapDynamicType = _typeProvider.mapType
+ .instantiate(<DartType>[_dynamicType, _dynamicType]);
+
// If we have no explicit type arguments, try to infer type arguments.
ParameterizedType inferred = inferMapType(node);
@@ -690,12 +722,11 @@
// everything was successful?
_resolver.inferenceContext.recordInference(node, inferred);
_recordStaticType(node, inferred);
- return null;
+ return;
}
// If no type arguments and no inference, use dynamic
_recordStaticType(node, mapDynamicType);
- return null;
}
/**
@@ -735,7 +766,7 @@
* <i>F</i>.</blockquote>
*/
@override
- Object visitMethodInvocation(MethodInvocation node) {
+ void visitMethodInvocation(MethodInvocation node) {
_inferGenericInvocationExpression(node);
// Record static return type of the static element.
bool inferredStaticType = _inferMethodInvocationObject(node) ||
@@ -746,14 +777,12 @@
_computeInvokeReturnType(node.staticInvokeType);
_recordStaticType(node, staticStaticType);
}
- return null;
}
@override
- Object visitNamedExpression(NamedExpression node) {
+ void visitNamedExpression(NamedExpression node) {
Expression expression = node.expression;
_recordStaticType(node, _getStaticType(expression));
- return null;
}
/**
@@ -761,16 +790,14 @@
* </blockquote>
*/
@override
- Object visitNullLiteral(NullLiteral node) {
+ void visitNullLiteral(NullLiteral node) {
_recordStaticType(node, _typeProvider.nullType);
- return null;
}
@override
- Object visitParenthesizedExpression(ParenthesizedExpression node) {
+ void visitParenthesizedExpression(ParenthesizedExpression node) {
Expression expression = node.expression;
_recordStaticType(node, _getStaticType(expression));
- return null;
}
/**
@@ -800,7 +827,7 @@
* = r - 1; return r}(e1, e2)</i></blockquote>
*/
@override
- Object visitPostfixExpression(PostfixExpression node) {
+ void visitPostfixExpression(PostfixExpression node) {
Expression operand = node.operand;
DartType staticType = _getStaticType(operand, read: true);
TokenType operator = node.operator.type;
@@ -811,14 +838,13 @@
}
}
_recordStaticType(node, staticType);
- return null;
}
/**
* See [visitSimpleIdentifier].
*/
@override
- Object visitPrefixedIdentifier(PrefixedIdentifier node) {
+ void visitPrefixedIdentifier(PrefixedIdentifier node) {
SimpleIdentifier prefixedIdentifier = node.identifier;
Element staticElement = prefixedIdentifier.staticElement;
DartType staticType = _dynamicType;
@@ -850,7 +876,6 @@
_recordStaticType(prefixedIdentifier, staticType);
_recordStaticType(node, staticType);
}
- return null;
}
/**
@@ -859,7 +884,7 @@
* form <i>op super</i> is equivalent to the method invocation <i>super.op()<i>.</blockquote>
*/
@override
- Object visitPrefixExpression(PrefixExpression node) {
+ void visitPrefixExpression(PrefixExpression node) {
TokenType operator = node.operator.type;
if (operator == TokenType.BANG) {
_recordStaticType(node, _typeProvider.boolType);
@@ -876,7 +901,6 @@
}
_recordStaticType(node, staticType);
}
- return null;
}
/**
@@ -921,7 +945,7 @@
* The static type of <i>i</i> is the declared return type of <i>m</i>.</blockquote>
*/
@override
- Object visitPropertyAccess(PropertyAccess node) {
+ void visitPropertyAccess(PropertyAccess node) {
SimpleIdentifier propertyName = node.propertyName;
Element staticElement = propertyName.staticElement;
DartType staticType = _dynamicType;
@@ -937,7 +961,6 @@
_recordStaticType(propertyName, staticType);
_recordStaticType(node, staticType);
}
- return null;
}
/**
@@ -945,9 +968,47 @@
* bottom.</blockquote>
*/
@override
- Object visitRethrowExpression(RethrowExpression node) {
+ void visitRethrowExpression(RethrowExpression node) {
_recordStaticType(node, _typeProvider.bottomType);
- return null;
+ }
+
+ @override
+ void visitSetLiteral(SetLiteral node) {
+ TypeArgumentList typeArguments = node.typeArguments;
+
+ // If we have type arguments, use them
+ if (typeArguments != null) {
+ DartType elementType = _dynamicType;
+ NodeList<TypeAnnotation> arguments = typeArguments.arguments;
+ if (arguments != null && arguments.length == 1) {
+ DartType type = _getType(arguments[0]);
+ if (type != null) {
+ elementType = type;
+ }
+ }
+ _recordStaticType(
+ node, _typeProvider.setType.instantiate(<DartType>[elementType]));
+ return;
+ }
+
+ DartType setDynamicType =
+ _typeProvider.setType.instantiate(<DartType>[_dynamicType]);
+
+ // If we have no explicit type arguments, try to infer type arguments.
+ ParameterizedType inferred = inferSetType(node);
+
+ if (inferred != setDynamicType) {
+ // TODO(jmesserly): this results in an "inferred" message even when we
+ // in fact had an error above, because it will still attempt to return
+ // a type. Perhaps we should record inference from TypeSystem if
+ // everything was successful?
+ _resolver.inferenceContext.recordInference(node, inferred);
+ _recordStaticType(node, inferred);
+ return;
+ }
+
+ // If no type arguments and no inference, use dynamic
+ _recordStaticType(node, setDynamicType);
}
/**
@@ -989,7 +1050,7 @@
* </blockquote>
*/
@override
- Object visitSimpleIdentifier(SimpleIdentifier node) {
+ void visitSimpleIdentifier(SimpleIdentifier node) {
Element element = node.staticElement;
DartType staticType = _dynamicType;
if (element is ClassElement) {
@@ -1019,7 +1080,7 @@
var parent = node.parent;
if (parent is PrefixedIdentifier && parent.prefix == node ||
parent is MethodInvocation && parent.target == node) {
- return null;
+ return;
}
staticType = _typeProvider.dynamicType;
} else if (element is DynamicElementImpl) {
@@ -1029,7 +1090,6 @@
}
staticType = _inferGenericInstantiationFromContext(node, staticType);
_recordStaticType(node, staticType);
- return null;
}
/**
@@ -1037,9 +1097,8 @@
* `String`.</blockquote>
*/
@override
- Object visitSimpleStringLiteral(SimpleStringLiteral node) {
+ void visitSimpleStringLiteral(SimpleStringLiteral node) {
_recordStaticType(node, _typeProvider.stringType);
- return null;
}
/**
@@ -1047,13 +1106,12 @@
* `String`.</blockquote>
*/
@override
- Object visitStringInterpolation(StringInterpolation node) {
+ void visitStringInterpolation(StringInterpolation node) {
_recordStaticType(node, _typeProvider.stringType);
- return null;
}
@override
- Object visitSuperExpression(SuperExpression node) {
+ void visitSuperExpression(SuperExpression node) {
if (thisType == null) {
// TODO(brianwilkerson) Report this error if it hasn't already been
// reported.
@@ -1061,13 +1119,11 @@
} else {
_recordStaticType(node, thisType);
}
- return null;
}
@override
- Object visitSymbolLiteral(SymbolLiteral node) {
+ void visitSymbolLiteral(SymbolLiteral node) {
_recordStaticType(node, _typeProvider.symbolType);
- return null;
}
/**
@@ -1075,7 +1131,7 @@
* interface of the immediately enclosing class.</blockquote>
*/
@override
- Object visitThisExpression(ThisExpression node) {
+ void visitThisExpression(ThisExpression node) {
if (thisType == null) {
// TODO(brianwilkerson) Report this error if it hasn't already been
// reported.
@@ -1083,7 +1139,6 @@
} else {
_recordStaticType(node, thisType);
}
- return null;
}
/**
@@ -1091,13 +1146,12 @@
* bottom.</blockquote>
*/
@override
- Object visitThrowExpression(ThrowExpression node) {
+ void visitThrowExpression(ThrowExpression node) {
_recordStaticType(node, _typeProvider.bottomType);
- return null;
}
@override
- Object visitVariableDeclaration(VariableDeclaration node) {
+ void visitVariableDeclaration(VariableDeclaration node) {
Expression initializer = node.initializer;
_inferLocalVariableType(node, initializer);
if (initializer != null) {
@@ -1108,7 +1162,6 @@
_resolver.overrideVariable(element, rightType, true);
}
}
- return null;
}
/**
diff --git a/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart b/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
index 8dcf359..7da4bb2 100644
--- a/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
@@ -1066,6 +1066,15 @@
static ScriptTag scriptTag(String scriptTag) =>
astFactory.scriptTag(TokenFactory.tokenFromString(scriptTag));
+ static SetLiteral setLiteral(Keyword keyword, TypeArgumentList typeArguments,
+ List<Expression> elements) =>
+ astFactory.setLiteral(
+ keyword == null ? null : TokenFactory.tokenFromKeyword(keyword),
+ typeArguments,
+ TokenFactory.tokenFromType(TokenType.OPEN_CURLY_BRACKET),
+ elements,
+ TokenFactory.tokenFromType(TokenType.CLOSE_CURLY_BRACKET));
+
static ShowCombinator showCombinator(List<SimpleIdentifier> identifiers) =>
astFactory.showCombinator(
TokenFactory.tokenFromString("show"), identifiers);
diff --git a/pkg/analyzer/lib/src/generated/testing/element_factory.dart b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
index 27a7460..8dfa63d 100644
--- a/pkg/analyzer/lib/src/generated/testing/element_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
@@ -416,8 +416,8 @@
AnalysisContext context, String libraryName) {
String fileName = "/$libraryName.dart";
CompilationUnitElementImpl unit = compilationUnit(fileName);
- LibraryElementImpl library =
- new LibraryElementImpl(context, libraryName, 0, libraryName.length);
+ LibraryElementImpl library = new LibraryElementImpl(
+ context, null, libraryName, 0, libraryName.length);
library.definingCompilationUnit = unit;
return library;
}
diff --git a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
index 17afba9..1f4cc10 100644
--- a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
+++ b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -6,6 +6,7 @@
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/constant.dart';
@@ -108,6 +109,11 @@
InterfaceType _mapType;
/**
+ * The type representing the built-in type 'Map'.
+ */
+ InterfaceType _mapNullNullType;
+
+ /**
* An shared object representing the value 'null'.
*/
DartObjectImpl _nullObject;
@@ -128,6 +134,16 @@
InterfaceType _objectType;
/**
+ * The type representing the built-in type 'Set'.
+ */
+ InterfaceType _setType;
+
+ /**
+ * The type representing the built-in type 'Set'.
+ */
+ InterfaceType _setNullType;
+
+ /**
* The type representing the built-in type 'StackTrace'.
*/
InterfaceType _stackTraceType;
@@ -168,7 +184,13 @@
*/
AnalysisContext _context;
- TestTypeProvider([this._context]);
+ /**
+ * The analysis driver, if any. Used to create an appropriate 'dart:async'
+ * library to back `Future<T>`.
+ */
+ AnalysisDriver _driver;
+
+ TestTypeProvider([this._context, this._driver]);
@override
InterfaceType get boolType {
@@ -377,6 +399,14 @@
}
@override
+ InterfaceType get mapNullNullType {
+ if (_mapNullNullType == null) {
+ _mapNullNullType = mapType.instantiate(<DartType>[nullType, nullType]);
+ }
+ return _mapNullNullType;
+ }
+
+ @override
InterfaceType get mapType {
if (_mapType == null) {
ClassElementImpl mapElement =
@@ -422,7 +452,7 @@
// Create a library element for "dart:core"
// This enables the "isDartCoreNull" getter.
var library = new LibraryElementImpl.forNode(
- _context, AstTestFactory.libraryIdentifier2(["dart.core"]));
+ _context, null, AstTestFactory.libraryIdentifier2(["dart.core"]));
var unit = new CompilationUnitElementImpl();
library.definingCompilationUnit = unit;
unit.librarySource = unit.source = new StringSource('', null);
@@ -464,6 +494,23 @@
}
@override
+ InterfaceType get setNullType {
+ if (_setNullType == null) {
+ _setNullType = setType.instantiate(<DartType>[nullType]);
+ }
+ return _setNullType;
+ }
+
+ @override
+ InterfaceType get setType {
+ if (_setType == null) {
+ ClassElementImpl setElement = ElementFactory.classElement2("Set", ["E"]);
+ _setType = setElement.type;
+ }
+ return _setType;
+ }
+
+ @override
InterfaceType get stackTraceType {
if (_stackTraceType == null) {
ClassElementImpl stackTraceElement =
@@ -558,11 +605,16 @@
}
void _initDartAsync() {
- Source asyncSource = _context.sourceFactory.forUri(DartSdk.DART_ASYNC);
- _context.setContents(asyncSource, "");
+ Source asyncSource;
+ if (_driver == null) {
+ asyncSource = _context.sourceFactory.forUri(DartSdk.DART_ASYNC);
+ _context.setContents(asyncSource, "");
+ } else {
+ asyncSource = _driver.sourceFactory.forUri(DartSdk.DART_ASYNC);
+ }
CompilationUnitElementImpl asyncUnit = new CompilationUnitElementImpl();
LibraryElementImpl asyncLibrary = new LibraryElementImpl.forNode(
- _context, AstTestFactory.libraryIdentifier2(["dart.async"]));
+ _context, null, AstTestFactory.libraryIdentifier2(["dart.async"]));
asyncLibrary.definingCompilationUnit = asyncUnit;
asyncUnit.librarySource = asyncUnit.source = asyncSource;
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index beb1160..540a948 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -466,7 +466,8 @@
List<DartType> tArgs2 = i2.typeArguments;
assert(tArgs1.length == tArgs2.length);
for (int i = 0; i < tArgs1.length; i++) {
- if (!_matchSubtypeOf(tArgs1[i], tArgs2[i], visited, origin,
+ if (!_matchSubtypeOf(
+ tArgs1[i], tArgs2[i], new HashSet<Element>(), origin,
covariant: covariant)) {
return false;
}
@@ -478,22 +479,12 @@
}
// Guard against loops in the class hierarchy
- //
- // TODO(jmesserly): this function isn't guarding against anything (it's not
- // passsing down `visitedSet`, so adding the element has no effect).
- //
- // If that's fixed, it breaks inference tests for types like
- // `Iterable<Iterable<?>>` matched aganinst `List<List<int>>`.
- //
- // The fix is for type arguments (above) to not pass down `visited`, similar
- // to how _isInterfaceSubtypeOf does not pass down `visited` for type
- // arguments.
bool guardedInterfaceSubtype(InterfaceType t1) {
- var visitedSet = visited ?? new HashSet<Element>();
- if (visitedSet.add(t1.element)) {
+ visited ??= new HashSet<Element>();
+ if (visited.add(t1.element)) {
bool matched = _matchInterfaceSubtypeOf(t1, i2, visited, origin,
covariant: covariant);
- visitedSet.remove(t1.element);
+ visited.remove(t1.element);
return matched;
} else {
// In the case of a recursive type parameter, consider the subtype
@@ -729,13 +720,6 @@
static bool _comparingTypeParameterBounds = false;
/**
- * True if declaration casts should be allowed, otherwise false.
- *
- * This affects the behavior of [isAssignableTo].
- */
- final bool declarationCasts;
-
- /**
* True if implicit casts should be allowed, otherwise false.
*
* This affects the behavior of [isAssignableTo].
@@ -744,8 +728,7 @@
final TypeProvider typeProvider;
- StrongTypeSystemImpl(this.typeProvider,
- {this.declarationCasts: true, this.implicitCasts: true});
+ StrongTypeSystemImpl(this.typeProvider, {this.implicitCasts: true});
@override
bool get isStrong => true;
@@ -1048,8 +1031,7 @@
}
@override
- bool isAssignableTo(DartType fromType, DartType toType,
- {bool isDeclarationCast = false}) {
+ bool isAssignableTo(DartType fromType, DartType toType) {
// An actual subtype
if (isSubtypeOf(fromType, toType)) {
return true;
@@ -1063,11 +1045,7 @@
}
}
- if (isDeclarationCast) {
- if (!declarationCasts) {
- return false;
- }
- } else if (!implicitCasts) {
+ if (!implicitCasts) {
return false;
}
@@ -1819,8 +1797,7 @@
* Return `true` if the [leftType] is assignable to the [rightType] (that is,
* if leftType <==> rightType).
*/
- bool isAssignableTo(DartType leftType, DartType rightType,
- {bool isDeclarationCast = false});
+ bool isAssignableTo(DartType leftType, DartType rightType);
/**
* Return `true` if the [leftType] is more specific than the [rightType]
@@ -2096,7 +2073,6 @@
static TypeSystem create(AnalysisContext context) {
var options = context.analysisOptions as AnalysisOptionsImpl;
return new StrongTypeSystemImpl(context.typeProvider,
- declarationCasts: options.declarationCasts,
implicitCasts: options.implicitCasts);
}
}
diff --git a/pkg/analyzer/lib/src/hint/sdk_constraint_extractor.dart b/pkg/analyzer/lib/src/hint/sdk_constraint_extractor.dart
index 9ff1b29..0cd3180 100644
--- a/pkg/analyzer/lib/src/hint/sdk_constraint_extractor.dart
+++ b/pkg/analyzer/lib/src/hint/sdk_constraint_extractor.dart
@@ -12,44 +12,84 @@
/// The file from which the constraint is to be extracted.
final File pubspecFile;
- /// The version range that was
+ /// A flag indicating whether the [_constraintText], [_constraintOffset] and
+ /// [_constraint] have been initialized.
+ bool _initialized = false;
+
+ /// The text of the constraint, or `null` if the range has not yet been
+ /// computed or if there was an error when attempting to compute the range.
+ String _constraintText;
+
+ /// The offset of the constraint text, or `-1` if the offset is not known.
+ int _constraintOffset = -1;
+
+ /// The cached range of supported versions, or `null` if the range has not yet
+ /// been computed or if there was an error when attempting to compute the
+ /// range.
VersionConstraint _constraint;
/// Initialize a newly created extractor to extract the SDK version constraint
/// from the given `pubspec.yaml` file.
SdkConstraintExtractor(this.pubspecFile);
- /// Return the range of supported versions.
+ /// Return the range of supported versions, or `null` if the range could not
+ /// be computed.
VersionConstraint constraint() {
if (_constraint == null) {
- try {
- String constraintText = _getConstraintText();
- if (constraintText != null) {
- _constraint = new VersionConstraint.parse(constraintText);
+ String text = constraintText();
+ if (text != null) {
+ try {
+ _constraint = new VersionConstraint.parse(text);
+ } catch (e) {
+ // Ignore this, leaving [_constraint] unset.
}
- } catch (e) {
- // Return `null` by falling through without setting `_versionRange`.
}
}
return _constraint;
}
+ /// Return the offset of the constraint text.
+ int constraintOffset() {
+ if (_constraintText == null) {
+ _initializeTextAndOffset();
+ }
+ return _constraintOffset;
+ }
+
/// Return the constraint text following "sdk:".
- String _getConstraintText() {
- String fileContent = pubspecFile.readAsStringSync();
- YamlDocument document = loadYamlDocument(fileContent);
- YamlNode contents = document.contents;
- if (contents is YamlMap) {
- var environment = contents['environment'];
- if (environment is YamlMap) {
- var sdk = environment['sdk'];
- if (sdk is String) {
- return sdk;
- } else if (sdk is YamlScalar) {
- return sdk.toString();
+ String constraintText() {
+ if (_constraintText == null) {
+ _initializeTextAndOffset();
+ }
+ return _constraintText;
+ }
+
+ /// Initialize both [_constraintText] and [_constraintOffset], or neither if
+ /// there is an error or if the pubspec does not contain an sdk constraint.
+ void _initializeTextAndOffset() {
+ if (!_initialized) {
+ _initialized = true;
+ try {
+ String fileContent = pubspecFile.readAsStringSync();
+ YamlDocument document = loadYamlDocument(fileContent);
+ YamlNode contents = document.contents;
+ if (contents is YamlMap) {
+ YamlNode environment = contents.nodes['environment'];
+ if (environment is YamlMap) {
+ YamlNode sdk = environment.nodes['sdk'];
+ if (sdk is YamlScalar) {
+ _constraintText = sdk.value;
+ _constraintOffset = sdk.span.start.offset;
+ if (sdk.style == ScalarStyle.SINGLE_QUOTED ||
+ sdk.style == ScalarStyle.DOUBLE_QUOTED) {
+ _constraintOffset++;
+ }
+ }
+ }
}
+ } catch (e) {
+ // Ignore this, leaving both fields unset.
}
}
- return null;
}
}
diff --git a/pkg/analyzer/lib/src/hint/sdk_constraint_verifier.dart b/pkg/analyzer/lib/src/hint/sdk_constraint_verifier.dart
index 3636897..429883f 100644
--- a/pkg/analyzer/lib/src/hint/sdk_constraint_verifier.dart
+++ b/pkg/analyzer/lib/src/hint/sdk_constraint_verifier.dart
@@ -44,6 +44,16 @@
_checkFutureAndStream ??= !before_2_1_0.intersect(_versionRange).isEmpty;
@override
+ void visitHideCombinator(HideCombinator node) {
+ // Don't flag references to either `Future` or `Stream` within a combinator.
+ }
+
+ @override
+ void visitShowCombinator(ShowCombinator node) {
+ // Don't flag references to either `Future` or `Stream` within a combinator.
+ }
+
+ @override
void visitSimpleIdentifier(SimpleIdentifier node) {
if (node.inDeclarationContext()) {
return;
diff --git a/pkg/analyzer/lib/src/lint/analysis.dart b/pkg/analyzer/lib/src/lint/analysis.dart
index bc4e089..be9fa8e 100644
--- a/pkg/analyzer/lib/src/lint/analysis.dart
+++ b/pkg/analyzer/lib/src/lint/analysis.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2015, 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.
@@ -6,12 +6,15 @@
import 'dart:collection';
import 'dart:io' as io;
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/file_system/file_system.dart'
show File, Folder, ResourceProvider, ResourceUriResolver;
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/src/context/builder.dart';
+import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
+import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart' hide AnalysisResult;
@@ -25,8 +28,6 @@
import 'package:analyzer/src/services/lint.dart';
import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer/src/util/sdk.dart';
-import 'package:analyzer/src/dart/analysis/byte_store.dart';
-import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:package_config/packages.dart' show Packages;
import 'package:package_config/packages_file.dart' as pkgfile show parse;
import 'package:package_config/src/packages_impl.dart' show MapPackages;
@@ -49,7 +50,6 @@
AnalysisOptions _buildAnalyzerOptions(LinterOptions options) {
AnalysisOptionsImpl analysisOptions = new AnalysisOptionsImpl();
analysisOptions.hint = false;
- analysisOptions.previewDart2 = options.previewDart2;
analysisOptions.lint = options.enableLints;
analysisOptions.generateSdkErrors = options.showSdkWarnings;
analysisOptions.enableTiming = options.enableTiming;
@@ -83,9 +83,6 @@
/// Whether to use Dart's Strong Mode analyzer.
bool strongMode = true;
- /// Whether to use Dart 2.0 features.
- bool previewDart2 = false;
-
/// The mock SDK (to speed up testing) or `null` to use the actual SDK.
DartSdk mockSdk;
@@ -100,6 +97,13 @@
void set enableAssertInitializer(bool enable) {
// Ignored because the option is now always enabled.
}
+
+ /// Whether to use Dart 2.0 features.
+ @deprecated
+ bool get previewDart2 => true;
+
+ @deprecated
+ void set previewDart2(bool value) {}
}
class LintDriver {
diff --git a/pkg/analyzer/lib/src/lint/linter.dart b/pkg/analyzer/lib/src/lint/linter.dart
index 1732ba7..348322f 100644
--- a/pkg/analyzer/lib/src/lint/linter.dart
+++ b/pkg/analyzer/lib/src/lint/linter.dart
@@ -1,14 +1,20 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2015, 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 'dart:io';
-import 'package:analyzer/analyzer.dart';
import 'package:analyzer/dart/analysis/declared_variables.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/error/error.dart';
+import 'package:analyzer/error/listener.dart';
import 'package:analyzer/file_system/file_system.dart' as file_system;
+import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/ast/token.dart';
+import 'package:analyzer/src/dart/error/lint_codes.dart';
import 'package:analyzer/src/generated/engine.dart'
show AnalysisErrorInfo, AnalysisErrorInfoImpl, Logger;
import 'package:analyzer/src/generated/java_engine.dart' show CaughtException;
@@ -200,6 +206,16 @@
TypeProvider get typeProvider;
TypeSystem get typeSystem;
+
+ /// Return `true` if it would be valid for the given instance creation
+ /// [expression] to have a keyword of `const`.
+ ///
+ /// The [expression] is expected to be a node within one of the compilation
+ /// units in [allUnits].
+ ///
+ /// Note that this method can cause constant evaluation to occur, which can be
+ /// computationally expensive.
+ bool canBeConst(InstanceCreationExpression expression);
}
/// Implementation of [LinterContext]
@@ -221,6 +237,34 @@
LinterContextImpl(this.allUnits, this.currentUnit, this.declaredVariables,
this.typeProvider, this.typeSystem);
+
+ @override
+ bool canBeConst(InstanceCreationExpression expression) {
+ //
+ // Verify that the invoked constructor is a const constructor.
+ //
+ ConstructorElement element = expression.staticElement;
+ if (element == null || !element.isConst) {
+ return false;
+ }
+ //
+ // Verify that the evaluation of the constructor would not produce an
+ // exception.
+ //
+ Token oldKeyword = expression.keyword;
+ ConstantAnalysisErrorListener listener =
+ new ConstantAnalysisErrorListener();
+ try {
+ expression.keyword = new KeywordToken(Keyword.CONST, expression.offset);
+ LibraryElement library = element.library;
+ ErrorReporter errorReporter = new ErrorReporter(listener, element.source);
+ expression.accept(new ConstantVerifier(
+ errorReporter, library, typeProvider, declaredVariables));
+ } finally {
+ expression.keyword = oldKeyword;
+ }
+ return !listener.hasConstError;
+ }
}
class LinterContextUnit {
@@ -319,15 +363,21 @@
@override
AstVisitor getVisitor() => null;
- void reportLint(AstNode node, {bool ignoreSyntheticNodes: true}) {
+ void reportLint(AstNode node,
+ {List<Object> arguments: const [],
+ ErrorCode errorCode,
+ bool ignoreSyntheticNodes: true}) {
if (node != null && (!node.isSynthetic || !ignoreSyntheticNodes)) {
- reporter.reportErrorForNode(lintCode, node, []);
+ reporter.reportErrorForNode(lintCode, node, arguments);
}
}
- void reportLintForToken(Token token, {bool ignoreSyntheticTokens: true}) {
+ void reportLintForToken(Token token,
+ {List<Object> arguments: const [],
+ ErrorCode errorCode,
+ bool ignoreSyntheticTokens: true}) {
if (token != null && (!token.isSynthetic || !ignoreSyntheticTokens)) {
- reporter.reportErrorForToken(lintCode, token, []);
+ reporter.reportErrorForToken(lintCode, token, arguments);
}
}
@@ -380,27 +430,19 @@
/// This method is invoked to let the [LintRule] register node processors
/// in the given [registry].
///
- /// In a future release of the analyzer, a `context` argument will be added.
- /// To opt into the new API, use [NodeLintRuleWithContext] instead.
- void registerNodeProcessors(NodeLintRegistry registry);
+ /// The node processors may use the provided [context] to access information
+ /// that is not available from the AST nodes or their associated elements.
+ void registerNodeProcessors(NodeLintRegistry registry, LinterContext context);
}
/// [LintRule]s that implement this interface want to process only some types
/// of AST nodes, and will register their processors in the registry.
///
-/// TODO(paulberry): once NodeLintRule is removed, rename this interface to
-/// NodeLintRule.
-abstract class NodeLintRuleWithContext extends NodeLintRule {
- /// This method is invoked to let the [LintRule] register node processors
- /// in the given [registry].
- ///
- /// The node processors may use the provided [context] to access information
- /// that is not available from the AST nodes or their associated elements.
- /// In a future release of the analyzer, [context] will become a required
- /// parameter.
- void registerNodeProcessors(NodeLintRegistry registry,
- [LinterContext context]);
-}
+/// This class exists solely to allow a smoother transition from analyzer
+/// version 0.33.*. It will be removed in a future analyzer release, so please
+/// use [NodeLintRule] instead.
+@deprecated
+abstract class NodeLintRuleWithContext extends NodeLintRule {}
class PrintingReporter implements Reporter, Logger {
final Printer _print;
diff --git a/pkg/analyzer/lib/src/lint/options_rule_validator.dart b/pkg/analyzer/lib/src/lint/options_rule_validator.dart
index 2d6911a..0858037 100644
--- a/pkg/analyzer/lib/src/lint/options_rule_validator.dart
+++ b/pkg/analyzer/lib/src/lint/options_rule_validator.dart
@@ -2,13 +2,26 @@
// 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:analyzer/analyzer.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/src/analysis_options/error/option_codes.dart';
+import 'package:analyzer/src/lint/linter.dart';
import 'package:analyzer/src/lint/registry.dart';
import 'package:analyzer/src/plugin/options.dart';
import 'package:analyzer/src/util/yaml.dart';
import 'package:yaml/yaml.dart';
/**
+ * A hint code indicating reference to a deprecated lint.
+ *
+ * Parameters:
+ * 0: the rule name
+ */
+const AnalysisOptionsHintCode DEPRECATED_LINT_HINT =
+ const AnalysisOptionsHintCode('DEPRECATED_LINT_HINT',
+ "'{0}' is a deprecated lint rule and should not be used");
+
+/**
* An error code indicating an undefined lint rule.
*
* Parameters:
@@ -19,12 +32,22 @@
'UNDEFINED_LINT_WARNING', "'{0}' is not a recognized lint rule");
/**
+ * Rule provider.
+ */
+typedef LintRuleProvider = Iterable<LintRule> Function();
+
+/**
* Validates `linter` rule configurations.
*/
class LinterRuleOptionsValidator extends OptionsValidator {
static const linter = 'linter';
static const rulesKey = 'rules';
+ final LintRuleProvider ruleProvider;
+
+ LinterRuleOptionsValidator({LintRuleProvider provider})
+ : ruleProvider = provider ?? (() => Registry.ruleRegistry.rules);
+
@override
List<AnalysisError> validate(ErrorReporter reporter, YamlMap options) {
List<AnalysisError> errors = <AnalysisError>[];
@@ -38,15 +61,22 @@
validateRules(YamlNode rules, ErrorReporter reporter) {
if (rules is YamlList) {
- List<String> registeredLints =
- Registry.ruleRegistry.map((r) => r.name).toList();
rules.nodes.forEach((YamlNode ruleNode) {
Object value = ruleNode.value;
- if (value != null && !registeredLints.contains(value)) {
- reporter.reportErrorForSpan(
- UNDEFINED_LINT_WARNING, ruleNode.span, [value]);
+ if (value != null) {
+ LintRule rule = getRegisteredLint(value);
+ if (rule == null) {
+ reporter.reportErrorForSpan(
+ UNDEFINED_LINT_WARNING, ruleNode.span, [value]);
+ } else if (rule.maturity == Maturity.deprecated) {
+ reporter.reportErrorForSpan(
+ DEPRECATED_LINT_HINT, ruleNode.span, [value]);
+ }
}
});
}
}
+
+ LintRule getRegisteredLint(Object value) => ruleProvider()
+ .firstWhere((rule) => rule.name == value, orElse: () => null);
}
diff --git a/pkg/analyzer/lib/src/lint/project.dart b/pkg/analyzer/lib/src/lint/project.dart
index f87c70f..7243747 100644
--- a/pkg/analyzer/lib/src/lint/project.dart
+++ b/pkg/analyzer/lib/src/lint/project.dart
@@ -5,6 +5,7 @@
import 'dart:async';
import 'dart:io';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/generated/resolver.dart';
@@ -135,7 +136,7 @@
for (Source source in sources) {
String path = source.uri.path;
if (path.startsWith(libDir) && !path.startsWith(libSrcDir)) {
- AnalysisResult result = await driver.getResult(source.fullName);
+ ResolvedUnitResult result = await driver.getResult(source.fullName);
LibraryElement library = result.libraryElement;
NamespaceBuilder namespaceBuilder = new NamespaceBuilder();
diff --git a/pkg/analyzer/lib/src/lint/pub.dart b/pkg/analyzer/lib/src/lint/pub.dart
index 1db39bf..8e6deed 100644
--- a/pkg/analyzer/lib/src/lint/pub.dart
+++ b/pkg/analyzer/lib/src/lint/pub.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2015, 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.
@@ -81,8 +81,7 @@
PSEntry get version;
}
-abstract class PSDependencyList extends Object
- with IterableMixin<PSDependency> {}
+abstract class PSDependencyList with IterableMixin<PSDependency> {}
class PSEntry {
final PSNode key;
@@ -110,7 +109,7 @@
String get text;
}
-abstract class PSNodeList extends Object with IterableMixin<PSNode> {
+abstract class PSNodeList with IterableMixin<PSNode> {
@override
Iterator<PSNode> get iterator;
PSNode get token;
@@ -137,8 +136,8 @@
T visitPackageAuthors(PSNodeList authors) => null;
T visitPackageDependencies(PSDependencyList dependencies) => null;
T visitPackageDependency(PSDependency dependency) => null;
- T visitPackageDependencyOverrides(PSDependencyList dependencies) => null;
T visitPackageDependencyOverride(PSDependency dependency) => null;
+ T visitPackageDependencyOverrides(PSDependencyList dependencies) => null;
T visitPackageDescription(PSEntry description) => null;
T visitPackageDevDependencies(PSDependencyList dependencies) => null;
T visitPackageDevDependency(PSDependency dependency) => null;
diff --git a/pkg/analyzer/lib/src/lint/registry.dart b/pkg/analyzer/lib/src/lint/registry.dart
index 24b5e47..4e02ac7 100644
--- a/pkg/analyzer/lib/src/lint/registry.dart
+++ b/pkg/analyzer/lib/src/lint/registry.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2015, 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.
@@ -10,7 +10,7 @@
/**
* Registry of lint rules.
*/
-class Registry extends Object with IterableMixin<LintRule> {
+class Registry with IterableMixin<LintRule> {
/**
* The default registry to be used by clients.
*/
diff --git a/pkg/analyzer/lib/src/lint/util.dart b/pkg/analyzer/lib/src/lint/util.dart
index 39248bc..2e12794 100644
--- a/pkg/analyzer/lib/src/lint/util.dart
+++ b/pkg/analyzer/lib/src/lint/util.dart
@@ -1,17 +1,20 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2015, 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:io';
-import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/dart/ast/token.dart';
import 'package:analyzer/src/dart/scanner/reader.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart';
import 'package:analyzer/src/generated/parser.dart' show Parser;
import 'package:analyzer/src/string_source.dart' show StringSource;
-import 'package:path/path.dart' as p;
+import 'package:path/path.dart' as path;
final _identifier = new RegExp(r'^([(_|$)a-zA-Z]+([_a-zA-Z0-9])*)$');
@@ -32,21 +35,21 @@
String createLibraryNamePrefix(
{String libraryPath, String projectRoot, String packageName}) {
// Use the posix context to canonicalize separators (`\`).
- var libraryDirectory = p.posix.dirname(libraryPath);
- var path = p.posix.relative(libraryDirectory, from: projectRoot);
+ var libraryDirectory = path.posix.dirname(libraryPath);
+ var relativePath = path.posix.relative(libraryDirectory, from: projectRoot);
// Drop 'lib/'.
- var segments = p.split(path);
+ var segments = path.split(relativePath);
if (segments[0] == 'lib') {
- path = p.posix.joinAll(segments.sublist(1));
+ relativePath = path.posix.joinAll(segments.sublist(1));
}
// Replace separators.
- path = path.replaceAll('/', '.');
+ relativePath = relativePath.replaceAll('/', '.');
// Add separator if needed.
- if (path.isNotEmpty) {
- path = '.$path';
+ if (relativePath.isNotEmpty) {
+ relativePath = '.$relativePath';
}
- return '$packageName$path';
+ return '$packageName$relativePath';
}
/// Returns `true` if this [fileName] is a Dart file.
diff --git a/pkg/analyzer/lib/src/summary/expr_builder.dart b/pkg/analyzer/lib/src/summary/expr_builder.dart
index 66112ea..77d31cd 100644
--- a/pkg/analyzer/lib/src/summary/expr_builder.dart
+++ b/pkg/analyzer/lib/src/summary/expr_builder.dart
@@ -48,239 +48,245 @@
if (requireValidConst && !uc.isValidConst) {
return null;
}
- try {
- for (UnlinkedExprOperation operation in uc.operations) {
- switch (operation) {
- case UnlinkedExprOperation.pushNull:
- _push(AstTestFactory.nullLiteral());
- break;
- // bool
- case UnlinkedExprOperation.pushFalse:
- _push(AstTestFactory.booleanLiteral(false));
- break;
- case UnlinkedExprOperation.pushTrue:
- _push(AstTestFactory.booleanLiteral(true));
- break;
- // literals
- case UnlinkedExprOperation.pushInt:
- int value = uc.ints[intPtr++];
- _push(AstTestFactory.integer(value));
- break;
- case UnlinkedExprOperation.pushLongInt:
- int value = 0;
- int count = uc.ints[intPtr++];
- for (int i = 0; i < count; i++) {
- int next = uc.ints[intPtr++];
- value = value << 32 | next;
- }
- _push(AstTestFactory.integer(value));
- break;
- case UnlinkedExprOperation.pushDouble:
- double value = uc.doubles[doublePtr++];
- _push(AstTestFactory.doubleLiteral(value));
- break;
- case UnlinkedExprOperation.makeSymbol:
- String component = uc.strings[stringPtr++];
- _push(AstTestFactory.symbolLiteral([component]));
- break;
- // String
- case UnlinkedExprOperation.pushString:
- String value = uc.strings[stringPtr++];
- _push(AstTestFactory.string2(value));
- break;
- case UnlinkedExprOperation.concatenate:
- int count = uc.ints[intPtr++];
- List<InterpolationElement> elements = <InterpolationElement>[];
- for (int i = 0; i < count; i++) {
- Expression expr = _pop();
- InterpolationElement element = _newInterpolationElement(expr);
- elements.insert(0, element);
- }
- _push(AstTestFactory.string(elements));
- break;
- // binary
- case UnlinkedExprOperation.equal:
- _pushBinary(TokenType.EQ_EQ);
- break;
- case UnlinkedExprOperation.notEqual:
- _pushBinary(TokenType.BANG_EQ);
- break;
- case UnlinkedExprOperation.and:
- _pushBinary(TokenType.AMPERSAND_AMPERSAND);
- break;
- case UnlinkedExprOperation.or:
- _pushBinary(TokenType.BAR_BAR);
- break;
- case UnlinkedExprOperation.bitXor:
- _pushBinary(TokenType.CARET);
- break;
- case UnlinkedExprOperation.bitAnd:
- _pushBinary(TokenType.AMPERSAND);
- break;
- case UnlinkedExprOperation.bitOr:
- _pushBinary(TokenType.BAR);
- break;
- case UnlinkedExprOperation.bitShiftLeft:
- _pushBinary(TokenType.LT_LT);
- break;
- case UnlinkedExprOperation.bitShiftRight:
- _pushBinary(TokenType.GT_GT);
- break;
- case UnlinkedExprOperation.add:
- _pushBinary(TokenType.PLUS);
- break;
- case UnlinkedExprOperation.subtract:
- _pushBinary(TokenType.MINUS);
- break;
- case UnlinkedExprOperation.multiply:
- _pushBinary(TokenType.STAR);
- break;
- case UnlinkedExprOperation.divide:
- _pushBinary(TokenType.SLASH);
- break;
- case UnlinkedExprOperation.floorDivide:
- _pushBinary(TokenType.TILDE_SLASH);
- break;
- case UnlinkedExprOperation.modulo:
- _pushBinary(TokenType.PERCENT);
- break;
- case UnlinkedExprOperation.greater:
- _pushBinary(TokenType.GT);
- break;
- case UnlinkedExprOperation.greaterEqual:
- _pushBinary(TokenType.GT_EQ);
- break;
- case UnlinkedExprOperation.less:
- _pushBinary(TokenType.LT);
- break;
- case UnlinkedExprOperation.lessEqual:
- _pushBinary(TokenType.LT_EQ);
- break;
- // prefix
- case UnlinkedExprOperation.complement:
- _pushPrefix(TokenType.TILDE);
- break;
- case UnlinkedExprOperation.negate:
- _pushPrefix(TokenType.MINUS);
- break;
- case UnlinkedExprOperation.not:
- _pushPrefix(TokenType.BANG);
- break;
- // conditional
- case UnlinkedExprOperation.conditional:
- Expression elseExpr = _pop();
- Expression thenExpr = _pop();
- Expression condition = _pop();
- _push(AstTestFactory.conditionalExpression(
- condition, thenExpr, elseExpr));
- break;
- case UnlinkedExprOperation.invokeMethodRef:
- _pushInvokeMethodRef();
- break;
- case UnlinkedExprOperation.invokeMethod:
- List<Expression> arguments = _buildArguments();
- TypeArgumentList typeArguments = _buildTypeArguments();
- Expression target = _pop();
- String name = uc.strings[stringPtr++];
- _push(AstTestFactory.methodInvocation3(
- target, name, typeArguments, arguments));
- break;
- // containers
- case UnlinkedExprOperation.makeUntypedList:
- _pushList(null);
- break;
- case UnlinkedExprOperation.makeTypedList:
- TypeAnnotation itemType = _newTypeName();
- _pushList(
- AstTestFactory.typeArgumentList(<TypeAnnotation>[itemType]));
- break;
- case UnlinkedExprOperation.makeUntypedMap:
- _pushMap(null);
- break;
- case UnlinkedExprOperation.makeTypedMap:
- TypeAnnotation keyType = _newTypeName();
- TypeAnnotation valueType = _newTypeName();
- _pushMap(AstTestFactory.typeArgumentList(
- <TypeAnnotation>[keyType, valueType]));
- break;
- case UnlinkedExprOperation.pushReference:
- _pushReference();
- break;
- case UnlinkedExprOperation.extractProperty:
- _pushExtractProperty();
- break;
- case UnlinkedExprOperation.invokeConstructor:
- _pushInstanceCreation();
- break;
- case UnlinkedExprOperation.pushParameter:
- String name = uc.strings[stringPtr++];
- SimpleIdentifier identifier = AstTestFactory.identifier3(name);
- identifier.staticElement = parametersInScope[name];
- _push(identifier);
- break;
- case UnlinkedExprOperation.ifNull:
- _pushBinary(TokenType.QUESTION_QUESTION);
- break;
- case UnlinkedExprOperation.await:
- Expression expression = _pop();
- _push(AstTestFactory.awaitExpression(expression));
- break;
- case UnlinkedExprOperation.pushLocalFunctionReference:
- _pushLocalFunctionReference();
- break;
- case UnlinkedExprOperation.assignToRef:
- var ref = _createReference();
- _push(_createAssignment(ref));
- break;
- case UnlinkedExprOperation.typeCast:
- Expression expression = _pop();
- TypeAnnotation type = _newTypeName();
- _push(AstTestFactory.asExpression(expression, type));
- break;
- case UnlinkedExprOperation.typeCheck:
- Expression expression = _pop();
- TypeAnnotation type = _newTypeName();
- _push(AstTestFactory.isExpression(expression, false, type));
- break;
- case UnlinkedExprOperation.throwException:
- Expression expression = _pop();
- _push(AstTestFactory.throwExpression2(expression));
- break;
- case UnlinkedExprOperation.assignToProperty:
- Expression target = _pop();
- String name = uc.strings[stringPtr++];
- SimpleIdentifier propertyNode = AstTestFactory.identifier3(name);
- PropertyAccess propertyAccess =
- AstTestFactory.propertyAccess(target, propertyNode);
- _push(_createAssignment(propertyAccess));
- break;
- case UnlinkedExprOperation.assignToIndex:
- Expression index = _pop();
- Expression target = _pop();
- IndexExpression indexExpression =
- AstTestFactory.indexExpression(target, index);
- _push(_createAssignment(indexExpression));
- break;
- case UnlinkedExprOperation.extractIndex:
- Expression index = _pop();
- Expression target = _pop();
- _push(AstTestFactory.indexExpression(target, index));
- break;
- case UnlinkedExprOperation.pushSuper:
- case UnlinkedExprOperation.pushThis:
- throw const _InvalidConstantException(); // TODO(paulberry)
- case UnlinkedExprOperation.cascadeSectionBegin:
- case UnlinkedExprOperation.cascadeSectionEnd:
- case UnlinkedExprOperation.pushLocalFunctionReference:
- case UnlinkedExprOperation.pushError:
- case UnlinkedExprOperation.pushTypedAbstract:
- case UnlinkedExprOperation.pushUntypedAbstract:
- throw new UnimplementedError(
- 'Unexpected $operation in a constant expression.');
- }
+ for (UnlinkedExprOperation operation in uc.operations) {
+ switch (operation) {
+ case UnlinkedExprOperation.pushNull:
+ _push(AstTestFactory.nullLiteral());
+ break;
+ // bool
+ case UnlinkedExprOperation.pushFalse:
+ _push(AstTestFactory.booleanLiteral(false));
+ break;
+ case UnlinkedExprOperation.pushTrue:
+ _push(AstTestFactory.booleanLiteral(true));
+ break;
+ // literals
+ case UnlinkedExprOperation.pushInt:
+ int value = uc.ints[intPtr++];
+ _push(AstTestFactory.integer(value));
+ break;
+ case UnlinkedExprOperation.pushLongInt:
+ int value = 0;
+ int count = uc.ints[intPtr++];
+ for (int i = 0; i < count; i++) {
+ int next = uc.ints[intPtr++];
+ value = value << 32 | next;
+ }
+ _push(AstTestFactory.integer(value));
+ break;
+ case UnlinkedExprOperation.pushDouble:
+ double value = uc.doubles[doublePtr++];
+ _push(AstTestFactory.doubleLiteral(value));
+ break;
+ case UnlinkedExprOperation.makeSymbol:
+ String component = uc.strings[stringPtr++];
+ _push(AstTestFactory.symbolLiteral([component]));
+ break;
+ // String
+ case UnlinkedExprOperation.pushString:
+ String value = uc.strings[stringPtr++];
+ _push(AstTestFactory.string2(value));
+ break;
+ case UnlinkedExprOperation.concatenate:
+ int count = uc.ints[intPtr++];
+ List<InterpolationElement> elements = <InterpolationElement>[];
+ for (int i = 0; i < count; i++) {
+ Expression expr = _pop();
+ InterpolationElement element = _newInterpolationElement(expr);
+ elements.insert(0, element);
+ }
+ _push(AstTestFactory.string(elements));
+ break;
+ // binary
+ case UnlinkedExprOperation.equal:
+ _pushBinary(TokenType.EQ_EQ);
+ break;
+ case UnlinkedExprOperation.notEqual:
+ _pushBinary(TokenType.BANG_EQ);
+ break;
+ case UnlinkedExprOperation.and:
+ _pushBinary(TokenType.AMPERSAND_AMPERSAND);
+ break;
+ case UnlinkedExprOperation.or:
+ _pushBinary(TokenType.BAR_BAR);
+ break;
+ case UnlinkedExprOperation.bitXor:
+ _pushBinary(TokenType.CARET);
+ break;
+ case UnlinkedExprOperation.bitAnd:
+ _pushBinary(TokenType.AMPERSAND);
+ break;
+ case UnlinkedExprOperation.bitOr:
+ _pushBinary(TokenType.BAR);
+ break;
+ case UnlinkedExprOperation.bitShiftLeft:
+ _pushBinary(TokenType.LT_LT);
+ break;
+ case UnlinkedExprOperation.bitShiftRight:
+ _pushBinary(TokenType.GT_GT);
+ break;
+ case UnlinkedExprOperation.add:
+ _pushBinary(TokenType.PLUS);
+ break;
+ case UnlinkedExprOperation.subtract:
+ _pushBinary(TokenType.MINUS);
+ break;
+ case UnlinkedExprOperation.multiply:
+ _pushBinary(TokenType.STAR);
+ break;
+ case UnlinkedExprOperation.divide:
+ _pushBinary(TokenType.SLASH);
+ break;
+ case UnlinkedExprOperation.floorDivide:
+ _pushBinary(TokenType.TILDE_SLASH);
+ break;
+ case UnlinkedExprOperation.modulo:
+ _pushBinary(TokenType.PERCENT);
+ break;
+ case UnlinkedExprOperation.greater:
+ _pushBinary(TokenType.GT);
+ break;
+ case UnlinkedExprOperation.greaterEqual:
+ _pushBinary(TokenType.GT_EQ);
+ break;
+ case UnlinkedExprOperation.less:
+ _pushBinary(TokenType.LT);
+ break;
+ case UnlinkedExprOperation.lessEqual:
+ _pushBinary(TokenType.LT_EQ);
+ break;
+ // prefix
+ case UnlinkedExprOperation.complement:
+ _pushPrefix(TokenType.TILDE);
+ break;
+ case UnlinkedExprOperation.negate:
+ _pushPrefix(TokenType.MINUS);
+ break;
+ case UnlinkedExprOperation.not:
+ _pushPrefix(TokenType.BANG);
+ break;
+ // conditional
+ case UnlinkedExprOperation.conditional:
+ Expression elseExpr = _pop();
+ Expression thenExpr = _pop();
+ Expression condition = _pop();
+ _push(AstTestFactory.conditionalExpression(
+ condition, thenExpr, elseExpr));
+ break;
+ case UnlinkedExprOperation.invokeMethodRef:
+ _pushInvokeMethodRef();
+ break;
+ case UnlinkedExprOperation.invokeMethod:
+ List<Expression> arguments = _buildArguments();
+ TypeArgumentList typeArguments = _buildTypeArguments();
+ Expression target = _pop();
+ String name = uc.strings[stringPtr++];
+ _push(AstTestFactory.methodInvocation3(
+ target, name, typeArguments, arguments));
+ break;
+ // containers
+ case UnlinkedExprOperation.makeUntypedList:
+ _pushList(null);
+ break;
+ case UnlinkedExprOperation.makeTypedList:
+ TypeAnnotation itemType = _newTypeName();
+ _pushList(
+ AstTestFactory.typeArgumentList(<TypeAnnotation>[itemType]));
+ break;
+ case UnlinkedExprOperation.makeUntypedMap:
+ _pushMap(null);
+ break;
+ case UnlinkedExprOperation.makeTypedMap:
+ TypeAnnotation keyType = _newTypeName();
+ TypeAnnotation valueType = _newTypeName();
+ _pushMap(AstTestFactory.typeArgumentList(
+ <TypeAnnotation>[keyType, valueType]));
+ break;
+ case UnlinkedExprOperation.makeUntypedSet:
+ _pushSet(null);
+ break;
+ case UnlinkedExprOperation.makeTypedSet:
+ TypeAnnotation itemType = _newTypeName();
+ _pushSet(AstTestFactory.typeArgumentList(<TypeAnnotation>[itemType]));
+ break;
+ case UnlinkedExprOperation.pushReference:
+ _pushReference();
+ break;
+ case UnlinkedExprOperation.extractProperty:
+ _pushExtractProperty();
+ break;
+ case UnlinkedExprOperation.invokeConstructor:
+ _pushInstanceCreation();
+ break;
+ case UnlinkedExprOperation.pushParameter:
+ String name = uc.strings[stringPtr++];
+ SimpleIdentifier identifier = AstTestFactory.identifier3(name);
+ identifier.staticElement = parametersInScope[name];
+ _push(identifier);
+ break;
+ case UnlinkedExprOperation.ifNull:
+ _pushBinary(TokenType.QUESTION_QUESTION);
+ break;
+ case UnlinkedExprOperation.await:
+ Expression expression = _pop();
+ _push(AstTestFactory.awaitExpression(expression));
+ break;
+ case UnlinkedExprOperation.pushLocalFunctionReference:
+ _pushLocalFunctionReference();
+ break;
+ case UnlinkedExprOperation.assignToRef:
+ var ref = _createReference();
+ _push(_createAssignment(ref));
+ break;
+ case UnlinkedExprOperation.typeCast:
+ Expression expression = _pop();
+ TypeAnnotation type = _newTypeName();
+ _push(AstTestFactory.asExpression(expression, type));
+ break;
+ case UnlinkedExprOperation.typeCheck:
+ Expression expression = _pop();
+ TypeAnnotation type = _newTypeName();
+ _push(AstTestFactory.isExpression(expression, false, type));
+ break;
+ case UnlinkedExprOperation.throwException:
+ Expression expression = _pop();
+ _push(AstTestFactory.throwExpression2(expression));
+ break;
+ case UnlinkedExprOperation.assignToProperty:
+ Expression target = _pop();
+ String name = uc.strings[stringPtr++];
+ SimpleIdentifier propertyNode = AstTestFactory.identifier3(name);
+ PropertyAccess propertyAccess =
+ AstTestFactory.propertyAccess(target, propertyNode);
+ _push(_createAssignment(propertyAccess));
+ break;
+ case UnlinkedExprOperation.assignToIndex:
+ Expression index = _pop();
+ Expression target = _pop();
+ IndexExpression indexExpression =
+ AstTestFactory.indexExpression(target, index);
+ _push(_createAssignment(indexExpression));
+ break;
+ case UnlinkedExprOperation.extractIndex:
+ Expression index = _pop();
+ Expression target = _pop();
+ _push(AstTestFactory.indexExpression(target, index));
+ break;
+ case UnlinkedExprOperation.pushSuper:
+ _push(AstTestFactory.superExpression());
+ break;
+ case UnlinkedExprOperation.pushThis:
+ _push(AstTestFactory.thisExpression());
+ break;
+ case UnlinkedExprOperation.cascadeSectionBegin:
+ case UnlinkedExprOperation.cascadeSectionEnd:
+ case UnlinkedExprOperation.pushLocalFunctionReference:
+ case UnlinkedExprOperation.pushError:
+ case UnlinkedExprOperation.pushTypedAbstract:
+ case UnlinkedExprOperation.pushUntypedAbstract:
+ throw new UnimplementedError(
+ 'Unexpected $operation in a constant expression.');
}
- } on _InvalidConstantException {
- return AstTestFactory.identifier3(r'#invalidConst');
}
return stack.single;
}
@@ -430,9 +436,6 @@
..staticElement = element;
return AstTestFactory.identifier(enclosing, identifier);
}
- if (requireValidConst && element == null) {
- throw const _InvalidConstantException();
- }
SimpleIdentifier property = AstTestFactory.identifier3(info.name)
..staticElement = element;
return AstTestFactory.propertyAccess(enclosing, property);
@@ -522,12 +525,16 @@
Expression _createReference() {
EntityRef ref = uc.references[refPtr++];
- ReferenceInfo info = resynthesizer.getReferenceInfo(ref.reference);
- Expression node = _buildIdentifierSequence(info);
- if (requireValidConst && node is Identifier && node.staticElement == null) {
- throw const _InvalidConstantException();
+ if (ref.paramReference != 0) {
+ // This is a reference to a type parameter. For type inference purposes
+ // we don't actually need to know which type parameter it's a reference
+ // to; we just need to know that it represents a type. So map it to
+ // `Object`.
+ return AstTestFactory.identifier3('Object')
+ ..staticElement = resynthesizer.typeProvider.objectType.element;
}
- return node;
+ ReferenceInfo info = resynthesizer.getReferenceInfo(ref.reference);
+ return _buildIdentifierSequence(info);
}
PropertyAccessorElement _getStringLengthElement() =>
@@ -605,11 +612,11 @@
} else if (info.element is ClassElement) {
constructorName = null;
} else {
- List<Expression> arguments = _buildArguments();
- SimpleIdentifier name = AstTestFactory.identifier3(info.name);
- name.staticElement = info.element;
- name.setProperty(ARGUMENT_LIST, AstTestFactory.argumentList(arguments));
- _push(name);
+ // Unexpected element, consider it unresolved.
+ _buildArguments();
+ var identifier = AstTestFactory.identifier3('__unresolved__')
+ ..staticType = resynthesizer.typeProvider.dynamicType;
+ _push(identifier);
return;
}
InterfaceType definingType = resynthesizer.createConstructorDefiningType(
@@ -657,9 +664,6 @@
constructorNode = AstTestFactory.constructorName(typeNode, null);
}
constructorNode.staticElement = constructorElement;
- if (constructorElement == null) {
- throw const _InvalidConstantException();
- }
// create InstanceCreationExpression
InstanceCreationExpression instanceCreation =
AstTestFactory.instanceCreationExpression(
@@ -720,7 +724,6 @@
}
void _pushLocalFunctionReference() {
- _throwIfConst();
int popCount = uc.ints[intPtr++];
// Note: nonzero popCount is no longer used.
assert(popCount == 0);
@@ -796,6 +799,15 @@
_push(_createReference());
}
+ void _pushSet(TypeArgumentList typeArguments) {
+ int count = uc.ints[intPtr++];
+ List<Expression> elements = <Expression>[];
+ for (int i = 0; i < count; i++) {
+ elements.insert(0, _pop());
+ }
+ _push(AstTestFactory.setLiteral(Keyword.CONST, typeArguments, elements));
+ }
+
List<Expression> _removeTopItems(int count) {
int start = stack.length - count;
int end = stack.length;
@@ -804,12 +816,6 @@
return items;
}
- void _throwIfConst() {
- if (requireValidConst) {
- throw const _InvalidConstantException();
- }
- }
-
/// Figures out the default value of [parametersInScope] based on [context].
///
/// If [context] is (or contains) a constructor, then its parameters are used.
@@ -827,11 +833,3 @@
return result;
}
}
-
-/**
- * This exception is thrown when we detect that the constant expression
- * being resynthesized is not a valid constant expression.
- */
-class _InvalidConstantException {
- const _InvalidConstantException();
-}
diff --git a/pkg/analyzer/lib/src/summary/flat_buffers.dart b/pkg/analyzer/lib/src/summary/flat_buffers.dart
index 3449a3b..c291d61 100644
--- a/pkg/analyzer/lib/src/summary/flat_buffers.dart
+++ b/pkg/analyzer/lib/src/summary/flat_buffers.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -757,7 +757,7 @@
/**
* List of booleans backed by 8-bit unsigned integers.
*/
-class _FbBoolList extends Object with ListMixin<bool> implements List<bool> {
+class _FbBoolList with ListMixin<bool> implements List<bool> {
final BufferContext bc;
final int offset;
int _length;
@@ -829,7 +829,7 @@
/**
* The base class for immutable lists read from flat buffers.
*/
-abstract class _FbList<E> extends Object with ListMixin<E> implements List<E> {
+abstract class _FbList<E> with ListMixin<E> implements List<E> {
final BufferContext bc;
final int offset;
int _length;
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index 4289b7f..44e6520d 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -639,7 +639,19 @@
pushThis,
/// Push `super` expression onto the stack.
- pushSuper
+ pushSuper,
+
+ /// Pop the top n values from the stack (where n is obtained from
+ /// [UnlinkedExpr.ints]), place them in a [Set], and push the result back
+ /// onto the stack. The type parameter for the [Set] is implicitly
+ /// `dynamic`.
+ makeUntypedSet,
+
+ /// Pop the top n values from the stack (where n is obtained from
+ /// [UnlinkedExpr.ints]), place them in a [Set], and push the result back
+ /// onto the stack. The type parameter for the [Set] is obtained from
+ /// [UnlinkedExpr.references].
+ makeTypedSet
}
/// Enum used to indicate the kind of a parameter.
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index 8a85d55..02bd1fd 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -1954,6 +1954,18 @@
/// Push `super` expression onto the stack.
pushSuper,
+
+ /// Pop the top n values from the stack (where n is obtained from
+ /// [UnlinkedExpr.ints]), place them in a [Set], and push the result back
+ /// onto the stack. The type parameter for the [Set] is implicitly
+ /// `dynamic`.
+ makeUntypedSet,
+
+ /// Pop the top n values from the stack (where n is obtained from
+ /// [UnlinkedExpr.ints]), place them in a [Set], and push the result back
+ /// onto the stack. The type parameter for the [Set] is obtained from
+ /// [UnlinkedExpr.references].
+ makeTypedSet,
}
/// Unlinked summary information about an import declaration.
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
index 7feaae8..8e0381c 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -1,7 +1,9 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'package:analyzer/dart/analysis/session.dart';
+
/// This library is capable of producing linked summaries from unlinked
/// ones (or prelinked ones). It functions by building a miniature
/// element model to represent the contents of the summaries, and then
@@ -416,14 +418,12 @@
AnalysisOptionsForLink(this._linker);
@override
- bool get declarationCasts => true;
-
- @override
bool get hint => false;
@override
bool get implicitCasts => true;
+ @deprecated
@override
bool get previewDart2 => true;
@@ -439,7 +439,7 @@
/// Element representing a class or enum resynthesized from a summary
/// during linking.
-abstract class ClassElementForLink extends Object
+abstract class ClassElementForLink
with ReferenceableElementForLink
implements AbstractClassElementImpl {
Map<String, ReferenceableElementForLink> _containedNames;
@@ -800,6 +800,9 @@
String get name => _unlinkedClass.name;
@override
+ AnalysisSession get session => enclosingUnit.session;
+
+ @override
List<InterfaceType> get superclassConstraints {
if (_superclassConstraints == null) {
if (isMixin) {
@@ -1229,6 +1232,9 @@
ResynthesizerContext get resynthesizerContext => this;
@override
+ AnalysisSession get session => library.session;
+
+ @override
List<TopLevelVariableElementForLink> get topLevelVariables {
if (_topLevelVariables == null) {
List<Expression> initializerExpressionsForInference;
@@ -1908,6 +1914,7 @@
break;
case UnlinkedExprOperation.makeUntypedList:
case UnlinkedExprOperation.makeUntypedMap:
+ case UnlinkedExprOperation.makeUntypedSet:
intPtr++;
break;
case UnlinkedExprOperation.assignToRef:
@@ -1930,6 +1937,7 @@
refPtr += numTypeArguments;
break;
case UnlinkedExprOperation.makeTypedList:
+ case UnlinkedExprOperation.makeTypedSet:
refPtr++;
intPtr++;
break;
@@ -2221,7 +2229,7 @@
/// Base class for executable elements resynthesized from a summary during
/// linking.
-abstract class ExecutableElementForLink extends Object
+abstract class ExecutableElementForLink
with TypeParameterizedElementMixin, ParameterParentElementForLink
implements ExecutableElementImpl {
/// The unlinked representation of the method in the summary.
@@ -2339,6 +2347,9 @@
}
@override
+ AnalysisSession get session => compilationUnit.session;
+
+ @override
FunctionTypeImpl get type => _type ??= new FunctionTypeImpl(this);
@override
@@ -2722,7 +2733,7 @@
/// Element representing a function-typed parameter resynthesied from a summary
/// during linking.
-class FunctionElementForLink_FunctionTypedParam extends Object
+class FunctionElementForLink_FunctionTypedParam
with ParameterParentElementForLink
implements FunctionElement {
@override
@@ -2775,7 +2786,7 @@
}
/// Element representing the initializer expression of a variable.
-class FunctionElementForLink_Initializer extends Object
+class FunctionElementForLink_Initializer
with ReferenceableElementForLink, TypeParameterizedElementMixin
implements FunctionElementForLink_Local {
/// The variable for which this element is the initializer.
@@ -3086,7 +3097,7 @@
}
/// Element representing a typedef resynthesized from a summary during linking.
-class FunctionTypeAliasElementForLink extends Object
+class FunctionTypeAliasElementForLink
with
TypeParameterizedElementMixin,
ParameterParentElementForLink,
@@ -3147,6 +3158,9 @@
enclosingElement.resolveTypeRef(this, _unlinkedTypedef.returnType);
@override
+ AnalysisSession get session => enclosingElement.session;
+
+ @override
TypeParameterizedElementMixin get typeParameterContext => this;
@override
@@ -3198,7 +3212,7 @@
/// Element representing a generic function resynthesized from a summary during
/// linking.
-class GenericFunctionTypeElementForLink extends Object
+class GenericFunctionTypeElementForLink
with
TypeParameterizedElementMixin,
ParameterParentElementForLink,
@@ -3262,6 +3276,9 @@
_returnType ??= enclosingUnit.resolveTypeRef(this, _unlinkedReturnType);
@override
+ AnalysisSession get session => enclosingElement.session;
+
+ @override
FunctionType get type {
return _type ??= new FunctionTypeImpl(this);
}
@@ -3278,7 +3295,7 @@
/// Element representing a generic typedef resynthesized from a summary during
/// linking.
-class GenericTypeAliasElementForLink extends Object
+class GenericTypeAliasElementForLink
with
TypeParameterizedElementMixin,
ParameterParentElementForLink,
@@ -3342,6 +3359,9 @@
this, _unlinkedTypedef.returnType.syntheticReturnType);
@override
+ AnalysisSession get session => enclosingElement.session;
+
+ @override
TypeParameterizedElementMixin get typeParameterContext => this;
@override
@@ -4075,8 +4095,7 @@
/// Accesses to a chain of non-static members separated by '.' are handled by
/// creating a [NonstaticMemberElementForLink] that points to another
/// [NonstaticMemberElementForLink], to whatever nesting level is necessary.
-class NonstaticMemberElementForLink extends Object
- with ReferenceableElementForLink {
+class NonstaticMemberElementForLink with ReferenceableElementForLink {
/// The [ReferenceableElementForLink] which is the target of the non-static
/// reference.
final ReferenceableElementForLink _target;
@@ -4455,7 +4474,7 @@
/// Specialization of [PropertyAccessorElementForLink] for synthetic accessors
/// implied by the synthetic fields of an enum declaration.
-class PropertyAccessorElementForLink_EnumField extends Object
+class PropertyAccessorElementForLink_EnumField
with ReferenceableElementForLink
implements PropertyAccessorElementForLink {
@override
@@ -4472,6 +4491,9 @@
Element get enclosingElement => variable.enclosingElement;
@override
+ bool get isAbstract => false;
+
+ @override
bool get isGetter => true;
@override
@@ -4592,7 +4614,7 @@
/// Specialization of [PropertyAccessorElementForLink] for synthetic accessors
/// implied by a field or variable declaration.
-class PropertyAccessorElementForLink_Variable extends Object
+class PropertyAccessorElementForLink_Variable
with ReferenceableElementForLink
implements PropertyAccessorElementForLink {
@override
@@ -4710,7 +4732,7 @@
/// Base class representing an element which can be the target of a reference.
/// When used as a mixin, implements the default behavior shared by most
/// elements.
-abstract class ReferenceableElementForLink implements Element {
+mixin ReferenceableElementForLink implements Element {
/// If this element is a class reference, return it. Otherwise return `null`.
ClassElementForLink get asClass => null;
@@ -4989,8 +5011,7 @@
}
/// Element used for references to special types such as `void`.
-class SpecialTypeElementForLink extends Object
- with ReferenceableElementForLink {
+class SpecialTypeElementForLink with ReferenceableElementForLink {
final Linker linker;
final DartType type;
@@ -5178,9 +5199,11 @@
break;
case UnlinkedExprOperation.makeUntypedList:
case UnlinkedExprOperation.makeUntypedMap:
+ case UnlinkedExprOperation.makeUntypedSet:
intPtr++;
break;
case UnlinkedExprOperation.makeTypedList:
+ case UnlinkedExprOperation.makeTypedSet:
refPtr++;
intPtr++;
break;
@@ -5304,9 +5327,12 @@
InterfaceType _iterableType;
InterfaceType _listType;
InterfaceType _mapType;
+ InterfaceType _mapNullNullType;
InterfaceType _nullType;
InterfaceType _numType;
InterfaceType _objectType;
+ InterfaceType _setType;
+ InterfaceType _setNullType;
InterfaceType _stackTraceType;
InterfaceType _streamDynamicType;
InterfaceType _streamType;
@@ -5375,6 +5401,10 @@
_listType ??= _buildInterfaceType(_linker.coreLibrary, 'List');
@override
+ InterfaceType get mapNullNullType =>
+ _mapNullNullType ??= mapType.instantiate(<DartType>[nullType, nullType]);
+
+ @override
InterfaceType get mapType =>
_mapType ??= _buildInterfaceType(_linker.coreLibrary, 'Map');
@@ -5397,6 +5427,14 @@
_objectType ??= _buildInterfaceType(_linker.coreLibrary, 'Object');
@override
+ InterfaceType get setNullType =>
+ _setNullType ??= setType.instantiate(<DartType>[nullType]);
+
+ @override
+ InterfaceType get setType =>
+ _setType ??= _buildInterfaceType(_linker.coreLibrary, 'Set');
+
+ @override
InterfaceType get stackTraceType => _stackTraceType ??=
_buildInterfaceType(_linker.coreLibrary, 'StackTrace');
@@ -5434,7 +5472,7 @@
}
/// Singleton element used for unresolved references.
-class UndefinedElementForLink extends Object with ReferenceableElementForLink {
+class UndefinedElementForLink with ReferenceableElementForLink {
static final UndefinedElementForLink instance =
new UndefinedElementForLink._();
diff --git a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
index 801ab29..dc9e818 100644
--- a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
@@ -1,6 +1,7 @@
import 'dart:io' as io;
import 'dart:math' show min;
+import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/context/cache.dart';
@@ -73,8 +74,9 @@
*/
class InputPackagesResultProvider extends ResynthesizerResultProvider {
InputPackagesResultProvider(
- InternalAnalysisContext context, SummaryDataStore dataStore)
- : super(context, dataStore) {
+ InternalAnalysisContext context, SummaryDataStore dataStore,
+ {AnalysisSession session})
+ : super(context, session, dataStore) {
createResynthesizer();
context.typeProvider = resynthesizer.typeProvider;
resynthesizer.finishCoreAsyncLibraries();
@@ -167,11 +169,12 @@
*/
abstract class ResynthesizerResultProvider extends ResultProvider {
final InternalAnalysisContext context;
+ final AnalysisSession session;
final SummaryDataStore _dataStore;
StoreBasedSummaryResynthesizer _resynthesizer;
- ResynthesizerResultProvider(this.context, this._dataStore);
+ ResynthesizerResultProvider(this.context, this.session, this._dataStore);
SummaryResynthesizer get resynthesizer => _resynthesizer;
@@ -317,7 +320,7 @@
*/
void createResynthesizer() {
_resynthesizer = new StoreBasedSummaryResynthesizer(
- context, context.sourceFactory, true, _dataStore);
+ context, session, context.sourceFactory, true, _dataStore);
}
/**
@@ -334,9 +337,13 @@
class StoreBasedSummaryResynthesizer extends SummaryResynthesizer {
final SummaryDataStore _dataStore;
- StoreBasedSummaryResynthesizer(AnalysisContext context,
- SourceFactory sourceFactory, bool _, this._dataStore)
- : super(context, sourceFactory, true);
+ StoreBasedSummaryResynthesizer(
+ AnalysisContext context,
+ AnalysisSession session,
+ SourceFactory sourceFactory,
+ bool _,
+ this._dataStore)
+ : super(context, session, sourceFactory, true);
@override
LinkedLibrary getLinkedSummary(String uri) {
diff --git a/pkg/analyzer/lib/src/summary/public_namespace_computer.dart b/pkg/analyzer/lib/src/summary/public_namespace_computer.dart
index 4d78177..4c2e4db 100644
--- a/pkg/analyzer/lib/src/summary/public_namespace_computer.dart
+++ b/pkg/analyzer/lib/src/summary/public_namespace_computer.dart
@@ -2,7 +2,8 @@
// 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:analyzer/analyzer.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart
index 2add257..6b7fa39 100644
--- a/pkg/analyzer/lib/src/summary/resynthesize.dart
+++ b/pkg/analyzer/lib/src/summary/resynthesize.dart
@@ -4,6 +4,7 @@
import 'dart:collection';
+import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
@@ -171,8 +172,9 @@
final Map<String, LibraryElement> _resynthesizedLibraries =
<String, LibraryElement>{};
- SummaryResynthesizer(AnalysisContext context, this.sourceFactory, bool _)
- : super(context) {
+ SummaryResynthesizer(AnalysisContext context, AnalysisSession session,
+ this.sourceFactory, bool _)
+ : super(context, session) {
_buildTypeProvider();
}
@@ -327,7 +329,7 @@
Source librarySource = _getSource(uri);
if (serializedLibrary == null) {
LibraryElementImpl libraryElement =
- new LibraryElementImpl(context, '', -1, 0);
+ new LibraryElementImpl(context, session, '', -1, 0);
libraryElement.isSynthetic = true;
CompilationUnitElementImpl unitElement =
new CompilationUnitElementImpl();
@@ -519,7 +521,7 @@
/// [UnitResynthesizerMixin] contains methods useful for implementing the
/// [UnitResynthesizer] interface.
-abstract class UnitResynthesizerMixin implements UnitResynthesizer {
+mixin UnitResynthesizerMixin implements UnitResynthesizer {
@override
DartType createConstructorDefiningType(ElementImpl context,
ReferenceInfo info, List<EntityRef> typeArgumentRefs) {
@@ -579,6 +581,9 @@
@override
ElementLocation get location => actualElement.location;
+
+ @override
+ AnalysisSession get session => enclosingElement.session;
}
/// Specialization of [LibraryResynthesizer] for resynthesis from linked
@@ -698,6 +703,7 @@
bool hasName = unlinkedUnits[0].libraryName.isNotEmpty;
library = new LibraryElementImpl.forSerialized(
summaryResynthesizer.context,
+ summaryResynthesizer.session,
unlinkedUnits[0].libraryName,
hasName ? unlinkedUnits[0].libraryNameOffset : -1,
unlinkedUnits[0].libraryNameLength,
@@ -1242,21 +1248,13 @@
if (constExpr == null) {
// Invalid constant expression.
} else if (constExpr is Identifier) {
- var element = constExpr.staticElement;
ArgumentList arguments = constExpr.getProperty(ExprBuilder.ARGUMENT_LIST);
- if (element is PropertyAccessorElement && arguments == null) {
- elementAnnotation.element = element;
- elementAnnotation.annotationAst = AstTestFactory.annotation(constExpr);
- } else if (element is ConstructorElement && arguments != null) {
- elementAnnotation.element = element;
- elementAnnotation.annotationAst =
- AstTestFactory.annotation2(constExpr, null, arguments);
- } else {
- elementAnnotation.annotationAst = AstTestFactory.annotation(
- AstTestFactory.identifier3(r'#invalidConst'));
- }
- } else if (constExpr is InstanceCreationExpression) {
elementAnnotation.element = constExpr.staticElement;
+ elementAnnotation.annotationAst =
+ AstTestFactory.annotation2(constExpr, null, arguments);
+ } else if (constExpr is InstanceCreationExpression) {
+ var element = constExpr.staticElement;
+ elementAnnotation.element = element;
Identifier typeName = constExpr.constructorName.type.name;
SimpleIdentifier constructorName = constExpr.constructorName.name;
if (typeName is SimpleIdentifier && constructorName != null) {
@@ -1273,20 +1271,10 @@
var propertyName = constExpr.propertyName;
var propertyElement = propertyName.staticElement;
ArgumentList arguments = constExpr.getProperty(ExprBuilder.ARGUMENT_LIST);
- if (propertyElement is PropertyAccessorElement && arguments == null) {
- elementAnnotation.element = propertyElement;
- elementAnnotation.annotationAst =
- AstTestFactory.annotation2(target, propertyName, null)
- ..element = propertyElement;
- } else if (propertyElement is ConstructorElement && arguments != null) {
- elementAnnotation.element = propertyElement;
- elementAnnotation.annotationAst =
- AstTestFactory.annotation2(target, propertyName, arguments)
- ..element = propertyElement;
- } else {
- elementAnnotation.annotationAst = AstTestFactory.annotation(
- AstTestFactory.identifier3(r'#invalidConst'));
- }
+ elementAnnotation.element = propertyElement;
+ elementAnnotation.annotationAst =
+ AstTestFactory.annotation2(target, propertyName, arguments)
+ ..element = propertyElement;
} else {
throw new StateError(
'Unexpected annotation type: ${constExpr.runtimeType}');
diff --git a/pkg/analyzer/lib/src/summary/summarize_const_expr.dart b/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
index 6bb8870..3a1e036 100644
--- a/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -317,6 +317,8 @@
_serializeListLiteral(expr);
} else if (expr is MapLiteral) {
_serializeMapLiteral(expr);
+ } else if (expr is SetLiteral) {
+ _serializeSetLiteral(expr);
} else if (expr is MethodInvocation) {
_serializeMethodInvocation(expr);
} else if (expr is BinaryExpression) {
@@ -621,6 +623,23 @@
}
}
+ void _serializeSetLiteral(SetLiteral expr) {
+ if (forConst || expr.typeArguments == null) {
+ List<Expression> elements = expr.elements;
+ elements.forEach(_serialize);
+ ints.add(elements.length);
+ } else {
+ ints.add(0);
+ }
+ if (expr.typeArguments != null &&
+ expr.typeArguments.arguments.length == 1) {
+ references.add(serializeType(expr.typeArguments.arguments[0]));
+ operations.add(UnlinkedExprOperation.makeTypedSet);
+ } else {
+ operations.add(UnlinkedExprOperation.makeUntypedSet);
+ }
+ }
+
void _serializeString(StringLiteral expr) {
if (expr is AdjacentStrings) {
if (expr.strings.every((string) => string is SimpleStringLiteral)) {
diff --git a/pkg/analyzer/lib/src/summary/summarize_elements.dart b/pkg/analyzer/lib/src/summary/summarize_elements.dart
index 9964703..ba4cc40 100644
--- a/pkg/analyzer/lib/src/summary/summarize_elements.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_elements.dart
@@ -26,7 +26,7 @@
* data that was previously not summarized), this value should be incremented
* by 1.
*/
- static const int currentMinorVersion = 0;
+ static const int currentMinorVersion = 1;
final List<String> _linkedLibraryUris = <String>[];
final List<LinkedLibraryBuilder> _linkedLibraries = <LinkedLibraryBuilder>[];
diff --git a/pkg/analyzer/lib/src/summary/summary_sdk.dart b/pkg/analyzer/lib/src/summary/summary_sdk.dart
index 9fc486b..b60e627 100644
--- a/pkg/analyzer/lib/src/summary/summary_sdk.dart
+++ b/pkg/analyzer/lib/src/summary/summary_sdk.dart
@@ -131,10 +131,13 @@
InterfaceType _iterableType;
InterfaceType _listType;
InterfaceType _mapType;
+ InterfaceType _mapNullNullType;
DartObjectImpl _nullObject;
InterfaceType _nullType;
InterfaceType _numType;
InterfaceType _objectType;
+ InterfaceType _setType;
+ InterfaceType _setNullType;
InterfaceType _stackTraceType;
InterfaceType _streamDynamicType;
InterfaceType _streamType;
@@ -247,6 +250,13 @@
}
@override
+ InterfaceType get mapNullNullType {
+ assert(_coreLibrary != null);
+ return _mapNullNullType ??=
+ mapType.instantiate(<DartType>[nullType, nullType]);
+ }
+
+ @override
InterfaceType get mapType {
assert(_coreLibrary != null);
_mapType ??= _getType(_coreLibrary, "Map");
@@ -283,6 +293,18 @@
}
@override
+ InterfaceType get setNullType {
+ assert(_coreLibrary != null);
+ return _setNullType ??= setType.instantiate(<DartType>[nullType]);
+ }
+
+ @override
+ InterfaceType get setType {
+ assert(_coreLibrary != null);
+ return _setType ??= _getType(_coreLibrary, "Set");
+ }
+
+ @override
InterfaceType get stackTraceType {
assert(_coreLibrary != null);
_stackTraceType ??= _getType(_coreLibrary, "StackTrace");
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index 7e5c4bc..11d6dab 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2015, 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.
@@ -1627,7 +1627,7 @@
//
if (libraryElement == null) {
libraryElement =
- new LibraryElementImpl.forNode(owningContext, libraryNameNode);
+ new LibraryElementImpl.forNode(owningContext, null, libraryNameNode);
libraryElement.isSynthetic = modificationTime < 0;
libraryElement.definingCompilationUnit = definingCompilationUnitElement;
libraryElement.entryPoint = entryPoint;
@@ -3235,7 +3235,7 @@
"${variable.displayName} at $offset in $variableSource");
}
VariableDeclaration declaration =
- node.getAncestor((AstNode ancestor) => ancestor is VariableDeclaration);
+ node.thisOrAncestorOfType<VariableDeclaration>();
if (declaration == null || declaration.name != node) {
Source variableSource = variable.source;
Source unitSource =
@@ -5452,8 +5452,7 @@
CodeChecker checker = new CodeChecker(
typeProvider,
new StrongTypeSystemImpl(typeProvider,
- implicitCasts: options.implicitCasts,
- declarationCasts: options.declarationCasts),
+ implicitCasts: options.implicitCasts),
errorListener,
options);
checker.visitCompilationUnit(unit);
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart
index c1c96b6..1032268 100644
--- a/pkg/analyzer/lib/src/task/options.dart
+++ b/pkg/analyzer/lib/src/task/options.dart
@@ -1,12 +1,15 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2015, 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:collection';
-import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/error/listener.dart';
import 'package:analyzer/source/error_processor.dart';
import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
+import 'package:analyzer/src/analysis_options/error/option_codes.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/source.dart';
@@ -42,6 +45,7 @@
static const String enableSuperMixins = 'enableSuperMixins';
static const String enablePreviewDart2 = 'enablePreviewDart2';
+ static const String enableExperiment = 'enable-experiment';
static const String errors = 'errors';
static const String exclude = 'exclude';
static const String include = 'include';
@@ -69,6 +73,7 @@
/// Supported top-level `analyzer` options.
static const List<String> topLevel = const [
+ enableExperiment,
errors,
exclude,
language,
@@ -94,6 +99,7 @@
new TopLevelAnalyzerOptionsValidator(),
new StrongModeOptionValueValidator(),
new ErrorFilterOptionValidator(),
+ new EnabledExperimentsValidator(),
new LanguageOptionValidator()
]);
}
@@ -109,6 +115,37 @@
validators.forEach((v) => v.validate(reporter, options));
}
+/// Validates `analyzer` language configuration options.
+class EnabledExperimentsValidator extends OptionsValidator {
+ ErrorBuilder builder = new ErrorBuilder(AnalyzerOptions.languageOptions);
+ ErrorBuilder trueOrFalseBuilder = new TrueOrFalseValueErrorBuilder();
+
+ @override
+ void validate(ErrorReporter reporter, YamlMap options) {
+ var analyzer = getValue(options, AnalyzerOptions.analyzer);
+ if (analyzer is YamlMap) {
+ var experimentNames =
+ getValue(analyzer, AnalyzerOptions.enableExperiment);
+ if (experimentNames is YamlList) {
+ for (var node in experimentNames.nodes) {
+ String experimentName = node.toString();
+ if (!Experiments.activeExperimentNames.contains(experimentName)) {
+ reporter.reportErrorForSpan(
+ AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITHOUT_VALUES,
+ node.span,
+ [experimentName, AnalyzerOptions.enableExperiment]);
+ }
+ }
+ } else if (experimentNames != null) {
+ reporter.reportErrorForSpan(
+ AnalysisOptionsWarningCode.INVALID_SECTION_FORMAT,
+ experimentNames.span,
+ [AnalyzerOptions.enableExperiment]);
+ }
+ }
+ }
+}
+
/// Builds error reports with value proposals.
class ErrorBuilder {
String proposal;
@@ -578,10 +615,24 @@
var strongMode = getValue(analyzer, AnalyzerOptions.strong_mode);
_applyStrongOptions(options, strongMode);
- // Set filters.
+ // Process filters.
var filters = getValue(analyzer, AnalyzerOptions.errors);
_applyProcessors(options, filters);
+ // Process enabled experiments.
+ var experimentNames =
+ getValue(analyzer, AnalyzerOptions.enableExperiment);
+ if (experimentNames is YamlList) {
+ List<String> enabledExperiments = <String>[];
+ for (var element in experimentNames.nodes) {
+ String experimentName = _toString(element);
+ if (experimentName != null) {
+ enabledExperiments.add(experimentName);
+ }
+ }
+ options.enabledExperiments = enabledExperiments;
+ }
+
// Process language options.
var language = getValue(analyzer, AnalyzerOptions.language);
_applyLanguageOptions(options, language);
@@ -661,9 +712,6 @@
AnalysisOptionsImpl options, String feature, Object value) {
bool boolValue = toBool(value);
if (boolValue != null) {
- if (feature == AnalyzerOptions.declarationCasts) {
- options.declarationCasts = boolValue;
- }
if (feature == AnalyzerOptions.implicitCasts) {
options.implicitCasts = boolValue;
}
diff --git a/pkg/analyzer/lib/src/task/strong/ast_properties.dart b/pkg/analyzer/lib/src/task/strong/ast_properties.dart
index 7fd42485..d2fea4e 100644
--- a/pkg/analyzer/lib/src/task/strong/ast_properties.dart
+++ b/pkg/analyzer/lib/src/task/strong/ast_properties.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -6,17 +6,37 @@
///
/// These properties are not public, but provided by use of back-ends such as
/// Dart Dev Compiler.
-import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
-const String _hasImplicitCasts = '_hasImplicitCasts';
-const String _implicitOperationCast = '_implicitAssignmentCast';
-const String _implicitCast = '_implicitCast';
-const String _isDynamicInvoke = '_isDynamicInvoke';
const String _classCovariantParameters = '_classCovariantParameters';
-const String _superclassCovariantParameters = '_superclassCovariantParameters';
const String _covariantPrivateMembers = '_covariantPrivateMembers';
+const String _hasImplicitCasts = '_hasImplicitCasts';
+const String _implicitCast = '_implicitCast';
+const String _implicitOperationCast = '_implicitAssignmentCast';
+const String _isDynamicInvoke = '_isDynamicInvoke';
+const String _superclassCovariantParameters = '_superclassCovariantParameters';
+
+/// Returns a list of parameters and method type parameters in this class
+/// declaration that need a check at runtime to ensure soundness.
+Set<Element> getClassCovariantParameters(Declaration node) {
+ return node.getProperty(_classCovariantParameters);
+}
+
+/// Gets the private setters and methods that are accessed unsafely from
+/// this compilation unit.
+///
+/// These members will require a check.
+Set<ExecutableElement> getCovariantPrivateMembers(CompilationUnit node) {
+ return node.getProperty(_covariantPrivateMembers);
+}
+
+/// If this expression has an implicit cast, returns the type it is coerced to,
+/// otherwise returns null.
+DartType getImplicitCast(Expression node) {
+ return node.getProperty<DartType>(_implicitCast);
+}
/// If this expression needs an implicit cast on a subexpression that cannot be
/// expressed anywhere else, returns the type it is coerced to.
@@ -28,10 +48,11 @@
return node.getProperty<DartType>(_implicitOperationCast);
}
-/// If this expression has an implicit cast, returns the type it is coerced to,
-/// otherwise returns null.
-DartType getImplicitCast(Expression node) {
- return node.getProperty<DartType>(_implicitCast);
+/// Returns a list of parameters and method type parameters from mixins and
+/// superclasses of this class that need a stub method to check their type at
+/// runtime for soundness.
+Set<Element> getSuperclassCovariantParameters(Declaration node) {
+ return node.getProperty(_superclassCovariantParameters);
}
/// True if this compilation unit has any implicit casts, otherwise false.
@@ -47,59 +68,38 @@
return node.getProperty<bool>(_isDynamicInvoke) ?? false;
}
+/// Sets [getClassCovariantParameters] property for this class.
+void setClassCovariantParameters(Declaration node, Set<Element> value) {
+ node.setProperty(_classCovariantParameters, value);
+}
+
+/// Sets [getCovariantPrivateMembers] property for this compilation unit.
+void setCovariantPrivateMembers(
+ CompilationUnit node, Set<ExecutableElement> value) {
+ node.setProperty(_covariantPrivateMembers, value);
+}
+
/// Sets [hasImplicitCasts] property for this compilation unit.
void setHasImplicitCasts(CompilationUnit node, bool value) {
node.setProperty(_hasImplicitCasts, value == true ? true : null);
}
-/// Sets the result of [getImplicitOperationCast] for this node.
-void setImplicitOperationCast(Expression node, DartType type) {
- node.setProperty(_implicitOperationCast, type);
-}
-
/// Sets the result of [getImplicitCast] for this node.
void setImplicitCast(Expression node, DartType type) {
node.setProperty(_implicitCast, type);
}
+/// Sets the result of [getImplicitOperationCast] for this node.
+void setImplicitOperationCast(Expression node, DartType type) {
+ node.setProperty(_implicitOperationCast, type);
+}
+
/// Sets [isDynamicInvoke] property for this expression.
void setIsDynamicInvoke(Expression node, bool value) {
node.setProperty(_isDynamicInvoke, value == true ? true : null);
}
-/// Returns a list of parameters and method type parameters in this class
-/// declaration that need a check at runtime to ensure soundness.
-Set<Element> getClassCovariantParameters(Declaration node) {
- return node.getProperty(_classCovariantParameters);
-}
-
-/// Sets [getClassCovariantParameters] property for this class.
-void setClassCovariantParameters(Declaration node, Set<Element> value) {
- node.setProperty(_classCovariantParameters, value);
-}
-
-/// Returns a list of parameters and method type parameters from mixins and
-/// superclasses of this class that need a stub method to check their type at
-/// runtime for soundness.
-Set<Element> getSuperclassCovariantParameters(Declaration node) {
- return node.getProperty(_superclassCovariantParameters);
-}
-
/// Sets [getSuperclassCovariantParameters] property for this class.
void setSuperclassCovariantParameters(Declaration node, Set<Element> value) {
node.setProperty(_superclassCovariantParameters, value);
}
-
-/// Gets the private setters and methods that are accessed unsafely from
-/// this compilation unit.
-///
-/// These members will require a check.
-Set<ExecutableElement> getCovariantPrivateMembers(CompilationUnit node) {
- return node.getProperty(_covariantPrivateMembers);
-}
-
-/// Sets [getCovariantPrivateMembers] property for this compilation unit.
-void setCovariantPrivateMembers(
- CompilationUnit node, Set<ExecutableElement> value) {
- node.setProperty(_covariantPrivateMembers, value);
-}
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index a830600..6dce6f6 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -6,7 +6,6 @@
// refactored to fit into analyzer.
import 'dart:collection';
-import 'package:analyzer/analyzer.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/standard_resolution_map.dart';
import 'package:analyzer/dart/ast/token.dart' show TokenType;
@@ -14,6 +13,8 @@
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/error/listener.dart';
import 'package:analyzer/source/error_processor.dart' show ErrorProcessor;
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/member.dart';
@@ -156,34 +157,17 @@
checkForCast(expr, type);
}
- void checkDeclarationCast(Expression expr, DartType type) {
- checkForCast(expr, type, isDeclarationCast: true);
- }
-
- void checkForCast(Expression expr, DartType type,
- {bool isDeclarationCast = false}) {
- if (expr is ParenthesizedExpression) {
- checkForCast(expr.expression, type);
- } else {
- _checkImplicitCast(expr, type, isDeclarationCast: isDeclarationCast);
- }
- }
-
/// Analyzer checks boolean conversions, but we need to check too, because
/// it uses the default assignability rules that allow `dynamic` and `Object`
/// to be assigned to bool with no message.
void checkBoolean(Expression expr) =>
checkAssignment(expr, typeProvider.boolType);
- void _checkFunctionApplication(InvocationExpression node) {
- var ft = _getTypeAsCaller(node);
-
- if (_isDynamicCall(node, ft)) {
- // If f is Function and this is a method invocation, we should have
- // gotten an analyzer error, so no need to issue another error.
- _recordDynamicInvoke(node, node.function);
+ void checkForCast(Expression expr, DartType type) {
+ if (expr is ParenthesizedExpression) {
+ checkForCast(expr.expression, type);
} else {
- checkArgumentList(node.argumentList, ft);
+ _checkImplicitCast(expr, type);
}
}
@@ -305,7 +289,6 @@
}
}
- // Check invocations
@override
void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
var field = node.fieldName;
@@ -315,6 +298,7 @@
node.visitChildren(this);
}
+ // Check invocations
@override
void visitDefaultFormalParameter(DefaultFormalParameter node) {
// Check that defaults have the proper subtype.
@@ -391,7 +375,7 @@
// Insert a cast from the sequence's element type to the loop variable's
// if needed.
_checkImplicitCast(loopVariable, _getExpressionType(loopVariable),
- from: elementType, isDeclarationCast: true);
+ from: elementType);
}
}
@@ -517,7 +501,9 @@
visitMethodInvocation(MethodInvocation node) {
var target = node.realTarget;
var element = node.methodName.staticElement;
- if (element == null && !typeProvider.isObjectMethod(node.methodName.name)) {
+ if (element == null &&
+ !typeProvider.isObjectMethod(node.methodName.name) &&
+ node.methodName.name != FunctionElement.CALL_METHOD_NAME) {
_recordDynamicInvoke(node, target);
// Mark the tear-off as being dynamic, too. This lets us distinguish
@@ -630,11 +616,11 @@
void visitVariableDeclarationList(VariableDeclarationList node) {
TypeAnnotation type = node.type;
- for (VariableDeclaration variable in node.variables) {
- var initializer = variable.initializer;
- if (initializer != null) {
- if (type != null) {
- checkDeclarationCast(initializer, type.type);
+ if (type != null) {
+ for (VariableDeclaration variable in node.variables) {
+ var initializer = variable.initializer;
+ if (initializer != null) {
+ checkForCast(initializer, type.type);
}
}
}
@@ -702,6 +688,49 @@
node.visitChildren(this);
}
+ void _checkFunctionApplication(InvocationExpression node) {
+ var ft = _getTypeAsCaller(node);
+
+ if (_isDynamicCall(node, ft)) {
+ // If f is Function and this is a method invocation, we should have
+ // gotten an analyzer error, so no need to issue another error.
+ _recordDynamicInvoke(node, node.function);
+ } else {
+ checkArgumentList(node.argumentList, ft);
+ }
+ }
+
+ /// Given an expression [expr] of type [fromType], returns true if an implicit
+ /// downcast is required, false if it is not, or null if the types are
+ /// unrelated.
+ bool _checkFunctionTypeCasts(
+ Expression expr, FunctionType to, DartType fromType) {
+ bool callTearoff = false;
+ FunctionType from;
+ if (fromType is FunctionType) {
+ from = fromType;
+ } else if (fromType is InterfaceType) {
+ from = rules.getCallMethodType(fromType);
+ callTearoff = true;
+ }
+ if (from == null) {
+ return null; // unrelated
+ }
+
+ if (rules.isSubtypeOf(from, to)) {
+ // Sound subtype.
+ // However we may still need cast if we have a call tearoff.
+ return callTearoff;
+ }
+
+ if (rules.isSubtypeOf(to, from)) {
+ // Assignable, but needs cast.
+ return true;
+ }
+
+ return null;
+ }
+
/// Checks if an implicit cast of [expr] from [from] type to [to] type is
/// needed, and if so records it.
///
@@ -710,76 +739,14 @@
/// If [expr] does not require an implicit cast because it is not related to
/// [to] or is already a subtype of it, does nothing.
void _checkImplicitCast(Expression expr, DartType to,
- {DartType from, bool opAssign: false, bool isDeclarationCast: false}) {
+ {DartType from, bool opAssign: false}) {
from ??= _getExpressionType(expr);
- if (_needsImplicitCast(expr, to,
- from: from, isDeclarationCast: isDeclarationCast) ==
- true) {
+ if (_needsImplicitCast(expr, to, from: from) == true) {
_recordImplicitCast(expr, to, from: from, opAssign: opAssign);
}
}
- void _checkReturnOrYield(Expression expression, AstNode node,
- {bool yieldStar: false}) {
- FunctionBody body = node.getAncestor((n) => n is FunctionBody);
- var type = _getExpectedReturnType(body, yieldStar: yieldStar);
- if (type == null) {
- // We have a type mismatch: the async/async*/sync* modifier does
- // not match the return or yield type. We should have already gotten an
- // analyzer error in this case.
- return;
- }
- // TODO(vsm): Enforce void or dynamic (to void?) when expression is null.
- if (expression != null) checkAssignment(expression, type);
- }
-
- void _checkRuntimeTypeCheck(AstNode node, TypeAnnotation annotation) {
- var type = getAnnotatedType(annotation);
- if (!rules.isGroundType(type)) {
- _recordMessage(node, StrongModeCode.NON_GROUND_TYPE_CHECK_INFO, [type]);
- }
- }
-
- void _checkUnary(Expression operand, Token op, MethodElement element) {
- bool isIncrementAssign =
- op.type == TokenType.PLUS_PLUS || op.type == TokenType.MINUS_MINUS;
- if (op.isUserDefinableOperator || isIncrementAssign) {
- if (element == null) {
- _recordDynamicInvoke(operand.parent, operand);
- } else if (isIncrementAssign) {
- // For ++ and --, even if it is not dynamic, we still need to check
- // that the user defined method accepts an `int` as the RHS.
- //
- // We assume Analyzer has done this already (in ErrorVerifier).
- //
- // However, we also need to check the return type.
-
- // Refine the return type.
- var functionType = element.type;
- var rhsType = typeProvider.intType;
- var lhsType = _getExpressionType(operand);
- var returnType = rules.refineBinaryExpressionType(
- lhsType, TokenType.PLUS, rhsType, functionType.returnType);
-
- // Skip the argument check - `int` cannot be downcast.
- //
- // Check the return type for an implicit cast.
- //
- // If needed, mark the assignment to indicate a down cast when we assign
- // back to it. So these two implicit casts are equivalent:
- //
- // y = /*implicit cast*/(y + 1);
- // /*implicit assignment cast*/y++;
- //
- _checkImplicitCast(operand, lhsType, from: returnType, opAssign: true);
- }
- }
- }
-
- DartType _getExpressionType(Expression expr) =>
- getExpressionType(expr, rules, typeProvider);
-
/// If we're calling into [member] through the [target], we may need to
/// insert a caller side check for soundness on the result of the expression
/// [node].
@@ -862,57 +829,61 @@
}
}
- /// Returns true if we can safely skip the covariance checks because [target]
- /// has known type arguments, such as `this` `super` or a non-factory `new`.
- ///
- /// For example:
- ///
- /// class C<T> {
- /// T _t;
- /// }
- /// class D<T> extends C<T> {
- /// method<S extends T>(T t, C<T> c) {
- /// // implicit cast: t as T;
- /// // implicit cast: c as C<T>;
- ///
- /// // These do not need further checks. The type parameter `T` for
- /// // `this` must be the same as our `T`
- /// this._t = t;
- /// super._t = t;
- /// new C<T>()._t = t; // non-factory
- ///
- /// // This needs further checks. The type of `c` could be `C<S>` for
- /// // some `S <: T`.
- /// c._t = t;
- /// // factory statically returns `C<T>`, dynamically returns `C<S>`.
- /// new F<T, S>()._t = t;
- /// }
- /// }
- /// class F<T, S extends T> extends C<T> {
- /// factory F() => new C<S>();
- /// }
- ///
- bool _targetHasKnownGenericTypeArguments(Expression target) {
- return target == null || // implicit this
- target is ThisExpression ||
- target is SuperExpression ||
- target is InstanceCreationExpression &&
- target.staticElement?.isFactory == false;
+ void _checkReturnOrYield(Expression expression, AstNode node,
+ {bool yieldStar: false}) {
+ FunctionBody body = node.thisOrAncestorOfType<FunctionBody>();
+ var type = _getExpectedReturnType(body, yieldStar: yieldStar);
+ if (type == null) {
+ // We have a type mismatch: the async/async*/sync* modifier does
+ // not match the return or yield type. We should have already gotten an
+ // analyzer error in this case.
+ return;
+ }
+ // TODO(vsm): Enforce void or dynamic (to void?) when expression is null.
+ if (expression != null) checkAssignment(expression, type);
}
- bool _isInstanceMember(ExecutableElement e) =>
- !e.isStatic &&
- (e is MethodElement ||
- e is PropertyAccessorElement && e.variable is FieldElement);
+ void _checkRuntimeTypeCheck(AstNode node, TypeAnnotation annotation) {
+ var type = getAnnotatedType(annotation);
+ if (!rules.isGroundType(type)) {
+ _recordMessage(node, StrongModeCode.NON_GROUND_TYPE_CHECK_INFO, [type]);
+ }
+ }
- ExecutableElement _lookUpMember(InterfaceType type, ExecutableElement e) {
- var name = e.name;
- var library = e.library;
- return e is PropertyAccessorElement
- ? (e.isGetter
- ? type.lookUpInheritedGetter(name, library: library)
- : type.lookUpInheritedSetter(name, library: library))
- : type.lookUpInheritedMethod(name, library: library);
+ void _checkUnary(Expression operand, Token op, MethodElement element) {
+ bool isIncrementAssign =
+ op.type == TokenType.PLUS_PLUS || op.type == TokenType.MINUS_MINUS;
+ if (op.isUserDefinableOperator || isIncrementAssign) {
+ if (element == null) {
+ _recordDynamicInvoke(operand.parent, operand);
+ } else if (isIncrementAssign) {
+ // For ++ and --, even if it is not dynamic, we still need to check
+ // that the user defined method accepts an `int` as the RHS.
+ //
+ // We assume Analyzer has done this already (in ErrorVerifier).
+ //
+ // However, we also need to check the return type.
+
+ // Refine the return type.
+ var functionType = element.type;
+ var rhsType = typeProvider.intType;
+ var lhsType = _getExpressionType(operand);
+ var returnType = rules.refineBinaryExpressionType(
+ lhsType, TokenType.PLUS, rhsType, functionType.returnType);
+
+ // Skip the argument check - `int` cannot be downcast.
+ //
+ // Check the return type for an implicit cast.
+ //
+ // If needed, mark the assignment to indicate a down cast when we assign
+ // back to it. So these two implicit casts are equivalent:
+ //
+ // y = /*implicit cast*/(y + 1);
+ // /*implicit assignment cast*/y++;
+ //
+ _checkImplicitCast(operand, lhsType, from: returnType, opAssign: true);
+ }
+ }
}
/// Gets the expected return type of the given function [body], either from
@@ -971,6 +942,9 @@
}
}
+ DartType _getExpressionType(Expression expr) =>
+ getExpressionType(expr, rules, typeProvider);
+
/// Given an expression, return its type assuming it is
/// in the caller position of a call (that is, accounting
/// for the possibility of a call method). Returns null
@@ -991,35 +965,28 @@
return ft == null;
}
- /// Given an expression [expr] of type [fromType], returns true if an implicit
- /// downcast is required, false if it is not, or null if the types are
- /// unrelated.
- bool _checkFunctionTypeCasts(
- Expression expr, FunctionType to, DartType fromType) {
- bool callTearoff = false;
- FunctionType from;
- if (fromType is FunctionType) {
- from = fromType;
- } else if (fromType is InterfaceType) {
- from = rules.getCallMethodType(fromType);
- callTearoff = true;
- }
- if (from == null) {
- return null; // unrelated
- }
+ bool _isInstanceMember(ExecutableElement e) =>
+ !e.isStatic &&
+ (e is MethodElement ||
+ e is PropertyAccessorElement && e.variable is FieldElement);
- if (rules.isSubtypeOf(from, to)) {
- // Sound subtype.
- // However we may still need cast if we have a call tearoff.
- return callTearoff;
- }
+ ExecutableElement _lookUpMember(InterfaceType type, ExecutableElement e) {
+ var name = e.name;
+ var library = e.library;
+ return e is PropertyAccessorElement
+ ? (e.isGetter
+ ? type.lookUpInheritedGetter(name, library: library)
+ : type.lookUpInheritedSetter(name, library: library))
+ : type.lookUpInheritedMethod(name, library: library);
+ }
- if (rules.isSubtypeOf(to, from)) {
- // Assignable, but needs cast.
- return true;
+ void _markImplicitCast(Expression expr, DartType to, {bool opAssign: false}) {
+ if (opAssign) {
+ setImplicitOperationCast(expr, to);
+ } else {
+ setImplicitCast(expr, to);
}
-
- return null;
+ _hasImplicitCasts = true;
}
/// Returns true if we need an implicit cast of [expr] from [from] type to
@@ -1029,8 +996,7 @@
/// downcast implicitly).
///
/// If [from] is omitted, uses the static type of [expr]
- bool _needsImplicitCast(Expression expr, DartType to,
- {DartType from, bool isDeclarationCast: false}) {
+ bool _needsImplicitCast(Expression expr, DartType to, {DartType from}) {
from ??= _getExpressionType(expr);
// Void is considered Top, but may only be *explicitly* cast.
@@ -1047,7 +1013,7 @@
}
// Down cast or legal sideways cast, coercion needed.
- if (rules.isAssignableTo(from, to, isDeclarationCast: isDeclarationCast)) {
+ if (rules.isAssignableTo(from, to)) {
return true;
}
@@ -1074,15 +1040,6 @@
if (target != null) setIsDynamicInvoke(target, true);
}
- void _markImplicitCast(Expression expr, DartType to, {bool opAssign: false}) {
- if (opAssign) {
- setImplicitOperationCast(expr, to);
- } else {
- setImplicitCast(expr, to);
- }
- _hasImplicitCasts = true;
- }
-
/// Records an implicit cast for the [expr] from [from] to [to].
///
/// This will emit the appropriate error/warning/hint message as well as mark
@@ -1109,6 +1066,9 @@
} else if (expr is MapLiteral) {
_recordMessage(
expr, StrongModeCode.INVALID_CAST_LITERAL_MAP, [from, to]);
+ } else if (expr is SetLiteral) {
+ _recordMessage(
+ expr, StrongModeCode.INVALID_CAST_LITERAL_SET, [from, to]);
} else {
_recordMessage(
expr, StrongModeCode.INVALID_CAST_LITERAL, [expr, from, to]);
@@ -1207,6 +1167,44 @@
}
}
+ /// Returns true if we can safely skip the covariance checks because [target]
+ /// has known type arguments, such as `this` `super` or a non-factory `new`.
+ ///
+ /// For example:
+ ///
+ /// class C<T> {
+ /// T _t;
+ /// }
+ /// class D<T> extends C<T> {
+ /// method<S extends T>(T t, C<T> c) {
+ /// // implicit cast: t as T;
+ /// // implicit cast: c as C<T>;
+ ///
+ /// // These do not need further checks. The type parameter `T` for
+ /// // `this` must be the same as our `T`
+ /// this._t = t;
+ /// super._t = t;
+ /// new C<T>()._t = t; // non-factory
+ ///
+ /// // This needs further checks. The type of `c` could be `C<S>` for
+ /// // some `S <: T`.
+ /// c._t = t;
+ /// // factory statically returns `C<T>`, dynamically returns `C<S>`.
+ /// new F<T, S>()._t = t;
+ /// }
+ /// }
+ /// class F<T, S extends T> extends C<T> {
+ /// factory F() => new C<S>();
+ /// }
+ ///
+ bool _targetHasKnownGenericTypeArguments(Expression target) {
+ return target == null || // implicit this
+ target is ThisExpression ||
+ target is SuperExpression ||
+ target is InstanceCreationExpression &&
+ target.staticElement?.isFactory == false;
+ }
+
void _validateTopLevelInitializer(String name, Expression n) {
n.accept(new _TopLevelInitializerValidator(this, name));
}
@@ -1229,6 +1227,36 @@
_checkForCovariantGenerics(node, element);
}
+ /// Visits each member on the class [node] and calls [checkMember] with the
+ /// corresponding instance element and AST node (for error reporting).
+ ///
+ /// See also [_checkTypeMembers], which is used when the class AST node is not
+ /// available.
+ void _checkClassMembers(Declaration node,
+ void checkMember(ExecutableElement member, ClassMember location)) {
+ for (var member in _classMembers(node)) {
+ if (member is FieldDeclaration) {
+ if (member.isStatic) {
+ continue;
+ }
+ for (var variable in member.fields.variables) {
+ var element = variable.declaredElement as PropertyInducingElement;
+ checkMember(element.getter, member);
+ if (!variable.isFinal && !variable.isConst) {
+ checkMember(element.setter, member);
+ }
+ }
+ } else if (member is MethodDeclaration) {
+ if (member.isStatic) {
+ continue;
+ }
+ checkMember(member.declaredElement, member);
+ } else {
+ assert(member is ConstructorDeclaration);
+ }
+ }
+ }
+
/// Finds implicit casts that we need on parameters and type formals to
/// ensure soundness of covariant generics, and records them on the [node].
///
@@ -1273,86 +1301,24 @@
setSuperclassCovariantParameters(node, checks);
}
- /// For each member of this class and non-overridden inherited member, we
- /// check to see if any generic super interface permits an unsound call to the
- /// concrete member. For example:
+ /// Visits the [type] and calls [checkMember] for each instance member.
///
- /// We must check non-overridden inherited members because this class could
- /// contain a new interface that permits unsound access to that member. In
- /// those cases, the class is expected to insert stub that checks the type
- /// before calling `super`. For example:
- ///
- /// class C<T> {
- /// add(T t) {}
- /// }
- /// class D {
- /// add(int t) {}
- /// }
- /// class E extends D implements C<int> {
- /// // C<Object>.add is unsafe, and D.m is marked for a check.
- /// //
- /// // one way to implement this is to generate a stub method:
- /// // add(t) => super.add(t as int);
- /// }
- ///
- Set<Element> _findSuperclassCovariantChecks(ClassElement element,
- Set<ClassElement> allCovariant, HashSet<String> seenConcreteMembers) {
- var visited = new HashSet<ClassElement>()..add(element);
- var superChecks = _createCovariantCheckSet();
- var existingChecks = _createCovariantCheckSet();
-
- void visitImmediateSuper(InterfaceType type) {
- // For members of mixins/supertypes, check them against new interfaces,
- // and also record any existing checks they already had.
- var oldCovariant = _findAllGenericInterfaces(type);
- var newCovariant = allCovariant.difference(oldCovariant);
- if (newCovariant.isEmpty) return;
-
- void visitSuper(InterfaceType type) {
- var element = type.element;
- if (visited.add(element)) {
- var members = _getConcreteMembers(type, seenConcreteMembers);
- _findCovariantChecks(members, newCovariant, superChecks);
- _findCovariantChecks(members, oldCovariant, existingChecks);
- element.mixins.reversed.forEach(visitSuper);
- var s = element.supertype;
- if (s != null) visitSuper(s);
- }
- }
-
- visitSuper(type);
+ /// See also [_checkClassMembers], which should be used when the class AST
+ /// node is available to allow for better error locations
+ void _checkTypeMembers(
+ InterfaceType type, void checkMember(ExecutableElement member)) {
+ void checkHelper(ExecutableElement e) {
+ if (!e.isStatic) checkMember(e);
}
- element.mixins.reversed.forEach(visitImmediateSuper);
- var s = element.supertype;
- if (s != null) visitImmediateSuper(s);
-
- superChecks.removeAll(existingChecks);
- return superChecks;
+ type.methods.forEach(checkHelper);
+ type.accessors.forEach(checkHelper);
}
- /// Gets all concrete instance members declared on this type, skipping already
- /// [seenConcreteMembers] and adding any found ones to it.
- ///
- /// By tracking the set of seen members, we can visit superclasses and mixins
- /// and ultimately collect every most-derived member exposed by a given type.
- static List<ExecutableElement> _getConcreteMembers(
- InterfaceType type, HashSet<String> seenConcreteMembers) {
- var members = <ExecutableElement>[];
- for (var declaredMembers in [type.accessors, type.methods]) {
- for (var member in declaredMembers) {
- // We only visit each most derived concrete member.
- // To avoid visiting an overridden superclass member, we skip members
- // we've seen, and visit starting from the class, then mixins in
- // reverse order, then superclasses.
- if (!member.isStatic &&
- !member.isAbstract &&
- seenConcreteMembers.add(member.name)) {
- members.add(member);
- }
- }
- }
- return members;
+ /// If node is a [ClassDeclaration] returns its members, otherwise if node is
+ /// a [ClassTypeAlias] this returns an empty list.
+ Iterable<ClassMember> _classMembers(Declaration node) {
+ return node is ClassDeclaration ? node.members : [];
}
/// Find all covariance checks on parameters/type parameters needed for
@@ -1453,6 +1419,64 @@
});
}
+ /// For each member of this class and non-overridden inherited member, we
+ /// check to see if any generic super interface permits an unsound call to the
+ /// concrete member. For example:
+ ///
+ /// We must check non-overridden inherited members because this class could
+ /// contain a new interface that permits unsound access to that member. In
+ /// those cases, the class is expected to insert stub that checks the type
+ /// before calling `super`. For example:
+ ///
+ /// class C<T> {
+ /// add(T t) {}
+ /// }
+ /// class D {
+ /// add(int t) {}
+ /// }
+ /// class E extends D implements C<int> {
+ /// // C<Object>.add is unsafe, and D.m is marked for a check.
+ /// //
+ /// // one way to implement this is to generate a stub method:
+ /// // add(t) => super.add(t as int);
+ /// }
+ ///
+ Set<Element> _findSuperclassCovariantChecks(ClassElement element,
+ Set<ClassElement> allCovariant, HashSet<String> seenConcreteMembers) {
+ var visited = new HashSet<ClassElement>()..add(element);
+ var superChecks = _createCovariantCheckSet();
+ var existingChecks = _createCovariantCheckSet();
+
+ void visitImmediateSuper(InterfaceType type) {
+ // For members of mixins/supertypes, check them against new interfaces,
+ // and also record any existing checks they already had.
+ var oldCovariant = _findAllGenericInterfaces(type);
+ var newCovariant = allCovariant.difference(oldCovariant);
+ if (newCovariant.isEmpty) return;
+
+ void visitSuper(InterfaceType type) {
+ var element = type.element;
+ if (visited.add(element)) {
+ var members = _getConcreteMembers(type, seenConcreteMembers);
+ _findCovariantChecks(members, newCovariant, superChecks);
+ _findCovariantChecks(members, oldCovariant, existingChecks);
+ element.mixins.reversed.forEach(visitSuper);
+ var s = element.supertype;
+ if (s != null) visitSuper(s);
+ }
+ }
+
+ visitSuper(type);
+ }
+
+ element.mixins.reversed.forEach(visitImmediateSuper);
+ var s = element.supertype;
+ if (s != null) visitImmediateSuper(s);
+
+ superChecks.removeAll(existingChecks);
+ return superChecks;
+ }
+
static Set<Element> _createCovariantCheckSet() {
return new LinkedHashSet(
equals: _equalMemberElements, hashCode: _hashCodeMemberElements);
@@ -1468,11 +1492,6 @@
return x == y;
}
- static int _hashCodeMemberElements(Element x) {
- x = x is Member ? x.baseElement : x;
- return x.hashCode;
- }
-
/// Find all generic interfaces that are implemented by [type], including
/// [type] itself if it is generic.
///
@@ -1503,54 +1522,33 @@
return genericSupertypes;
}
- /// Visits each member on the class [node] and calls [checkMember] with the
- /// corresponding instance element and AST node (for error reporting).
+ /// Gets all concrete instance members declared on this type, skipping already
+ /// [seenConcreteMembers] and adding any found ones to it.
///
- /// See also [_checkTypeMembers], which is used when the class AST node is not
- /// available.
- void _checkClassMembers(Declaration node,
- void checkMember(ExecutableElement member, ClassMember location)) {
- for (var member in _classMembers(node)) {
- if (member is FieldDeclaration) {
- if (member.isStatic) {
- continue;
+ /// By tracking the set of seen members, we can visit superclasses and mixins
+ /// and ultimately collect every most-derived member exposed by a given type.
+ static List<ExecutableElement> _getConcreteMembers(
+ InterfaceType type, HashSet<String> seenConcreteMembers) {
+ var members = <ExecutableElement>[];
+ for (var declaredMembers in [type.accessors, type.methods]) {
+ for (var member in declaredMembers) {
+ // We only visit each most derived concrete member.
+ // To avoid visiting an overridden superclass member, we skip members
+ // we've seen, and visit starting from the class, then mixins in
+ // reverse order, then superclasses.
+ if (!member.isStatic &&
+ !member.isAbstract &&
+ seenConcreteMembers.add(member.name)) {
+ members.add(member);
}
- for (var variable in member.fields.variables) {
- var element = variable.declaredElement as PropertyInducingElement;
- checkMember(element.getter, member);
- if (!variable.isFinal && !variable.isConst) {
- checkMember(element.setter, member);
- }
- }
- } else if (member is MethodDeclaration) {
- if (member.isStatic) {
- continue;
- }
- checkMember(member.declaredElement, member);
- } else {
- assert(member is ConstructorDeclaration);
}
}
+ return members;
}
- /// Visits the [type] and calls [checkMember] for each instance member.
- ///
- /// See also [_checkClassMembers], which should be used when the class AST
- /// node is available to allow for better error locations
- void _checkTypeMembers(
- InterfaceType type, void checkMember(ExecutableElement member)) {
- void checkHelper(ExecutableElement e) {
- if (!e.isStatic) checkMember(e);
- }
-
- type.methods.forEach(checkHelper);
- type.accessors.forEach(checkHelper);
- }
-
- /// If node is a [ClassDeclaration] returns its members, otherwise if node is
- /// a [ClassTypeAlias] this returns an empty list.
- Iterable<ClassMember> _classMembers(Declaration node) {
- return node is ClassDeclaration ? node.members : [];
+ static int _hashCodeMemberElements(Element x) {
+ x = x is Member ? x.baseElement : x;
+ return x.hashCode;
}
}
diff --git a/pkg/analyzer_plugin/test/support/mock_sdk.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
similarity index 82%
rename from pkg/analyzer_plugin/test/support/mock_sdk.dart
rename to pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
index f76516c4..b48d3c49 100644
--- a/pkg/analyzer_plugin/test/support/mock_sdk.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
@@ -1,9 +1,9 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2018, 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:analyzer/file_system/file_system.dart' as resource;
-import 'package:analyzer/file_system/memory_file_system.dart' as resource;
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/context/context.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine;
@@ -11,6 +11,7 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/summary/idl.dart' show PackageBundle;
import 'package:analyzer/src/summary/summary_file_builder.dart';
+import 'package:meta/meta.dart';
const String librariesContent = r'''
const Map<String, LibraryInfo> libraries = const {
@@ -42,11 +43,10 @@
factory Future.microtask(FutureOr<T> computation()) => null;
factory Future.value([FutureOr<T> result]) => null;
- static Future<List<T>> wait<T>(
- Iterable<Future<T>> futures) => null;
Future<R> then<R>(FutureOr<R> onValue(T value)) => null;
-
Future<T> whenComplete(action());
+
+ static Future<List<T>> wait<T>(Iterable<Future<T>> futures) => null;
}
class FutureOr<T> {}
@@ -60,12 +60,9 @@
bool get isCompleted;
}
-class _StreamIterator<T> implements StreamIterator<T> {}
-class _AsyncStarStreamController {}
-Function _asyncThenWrapperHelper(continuation) {}
-Function _asyncErrorWrapperHelper(continuation) {}
-Future _awaitHelper(
- object, Function thenCallback, Function errorCallback, var awaiter) {}
+abstract class Timer {
+ static void run(void callback()) {}
+}
''', const <String, String>{
'$sdkRoot/lib/async/stream.dart': r'''
part of dart.async;
@@ -108,6 +105,7 @@
library dart.collection;
abstract class HashMap<K, V> implements Map<K, V> {}
+abstract class LinkedHashMap<K, V> implements Map<K, V> {}
''');
const _MockSdkLibrary _LIB_CONVERT = const _MockSdkLibrary(
@@ -124,104 +122,34 @@
const _MockSdkLibrary('dart:core', '$sdkRoot/lib/core/core.dart', '''
library dart.core;
-import 'dart:async';
-import 'dart:_internal';
+import 'dart:async'; // ignore: unused_import
-class Object {
- const Object();
- bool operator ==(other) => identical(this, other);
- String toString() => 'a string';
- int get hashCode => 0;
- Type get runtimeType => null;
- dynamic noSuchMethod(Invocation invocation) => null;
+export 'dart:async' show Future, Stream;
+
+const deprecated = const Deprecated("next release");
+
+const override = const _Override();
+
+const proxy = const _Proxy();
+
+external bool identical(Object a, Object b);
+
+void print(Object object) {}
+
+class bool extends Object {
+ external const factory bool.fromEnvironment(String name,
+ {bool defaultValue: false});
}
-class Function {}
-class StackTrace {}
-
-class Symbol {
- const factory Symbol(String name) = _SymbolImpl;
-}
-
-class _SymbolImpl {
- const _SymbolImpl(String name);
-}
-
-class Type {}
-
abstract class Comparable<T> {
int compareTo(T other);
}
-abstract class Pattern {}
-abstract class String implements Comparable<String>, Pattern {
- external factory String.fromCharCodes(Iterable<int> charCodes,
- [int start = 0, int end]);
- String operator +(String other) => null;
- bool operator ==(Object other);
- bool get isEmpty => false;
- bool get isNotEmpty => false;
- int get length => 0;
- int codeUnitAt(int index);
- String substring(int len) => null;
- String toLowerCase();
- String toUpperCase();
- List<int> get codeUnits;
-}
-abstract class RegExp implements Pattern {
- external factory RegExp(String source);
-}
+class DateTime extends Object {}
-class bool extends Object {
- external const factory bool.fromEnvironment(String name,
- {bool defaultValue: false});
-}
-
-abstract class Invocation {}
-
-abstract class num implements Comparable<num> {
- bool operator ==(Object other);
- bool operator <(num other);
- bool operator <=(num other);
- bool operator >(num other);
- bool operator >=(num other);
- num operator +(num other);
- num operator -(num other);
- num operator *(num other);
- double operator /(num other);
- int operator ^(int other);
- int operator |(int other);
- int operator <<(int other);
- int operator >>(int other);
- int operator ~/(num other);
- num operator %(num other);
- int operator ~();
- num operator -();
- int toInt();
- double toDouble();
- num abs();
- int round();
-}
-abstract class int extends num {
- external const factory int.fromEnvironment(String name, {int defaultValue});
-
- bool get isNegative;
- bool get isEven => false;
-
- int operator &(int other);
- int operator |(int other);
- int operator ^(int other);
- int operator ~();
- int operator <<(int shiftAmount);
- int operator >>(int shiftAmount);
-
- int operator -();
-
- external static int parse(String source,
- { int radix,
- int onError(String source) });
-
- String toString();
+class Deprecated extends Object {
+ final String expires;
+ const Deprecated(this.expires);
}
abstract class double extends num {
@@ -231,89 +159,25 @@
static const double MIN_POSITIVE = 5e-324;
static const double MAX_FINITE = 1.7976931348623157e+308;
- double remainder(num other);
+ double get sign;
+ double operator %(num other);
+ double operator *(num other);
double operator +(num other);
double operator -(num other);
- double operator *(num other);
- double operator %(num other);
- double operator /(num other);
- int operator ~/(num other);
double operator -();
+ double operator /(num other);
double abs();
- double get sign;
- int round();
- int floor();
int ceil();
- int truncate();
- double roundToDouble();
- double floorToDouble();
double ceilToDouble();
+ int floor();
+ double floorToDouble();
+ double remainder(num other);
+ int round();
+ double roundToDouble();
+ int truncate();
double truncateToDouble();
- external static double parse(String source,
- [double onError(String source)]);
-}
-
-class DateTime extends Object {}
-
-class Null extends Object {
- factory Null._uninstantiable() => null;
-}
-
-class Deprecated extends Object {
- final String expires;
- const Deprecated(this.expires);
-}
-const Object deprecated = const Deprecated("next release");
-
-class Iterator<E> {
- bool moveNext();
- E get current;
-}
-
-abstract class Iterable<E> {
- Iterator<E> get iterator;
- bool get isEmpty;
- E get first;
- int get length;
-
- Iterable<R> map<R>(R f(E e));
-
- R fold<R>(R initialValue,
- R combine(R previousValue, E element)) => null;
-
- Iterable<T> expand<T>(Iterable<T> f(E element));
-
- Iterable<E> where(bool test(E element));
-
- void forEach(void f(E element));
-
- List<E> toList();
-}
-
-class List<E> implements Iterable<E> {
- List([int length]);
- factory List.from(Iterable elements, {bool growable: true}) => null;
- void add(E value) {}
- void addAll(Iterable<E> iterable) {}
- E operator [](int index) => null;
- void operator []=(int index, E value) {}
- Iterator<E> get iterator => null;
- void clear() {}
-
- bool get isEmpty => false;
- E get first => null;
- E get last => null;
-
-}
-
-class Map<K, V> extends Object {
- Iterable<K> get keys => null;
- int get length;
- Iterable<V> get values;
- V operator [](K key) => null;
- void operator []=(K key, V value) {}
- Map<RK, RV> cast<RK, RV>();
- bool containsKey(Object key);
+ int operator ~/(num other);
+ external static double parse(String source, [double onError(String source)]);
}
class Duration implements Comparable<Duration> {}
@@ -322,36 +186,166 @@
factory Exception([var message]) => null;
}
-external bool identical(Object a, Object b);
+class Function {}
-void print(Object object) {}
+abstract class int extends num {
+ external const factory int.fromEnvironment(String name, {int defaultValue});
-class _Proxy { const _Proxy(); }
-const Object proxy = const _Proxy();
+ bool get isEven => false;
+ bool get isNegative;
-class _Override { const _Override(); }
-const Object override = const _Override();
+ int operator &(int other);
+ int operator -();
+ int operator <<(int shiftAmount);
+ int operator >>(int shiftAmount);
+ int operator ^(int other);
+ String toString();
-class _CompileTimeError {
- final String _errorMsg;
- _CompileTimeError(this._errorMsg);
+ int operator |(int other);
+
+ int operator ~();
+
+ external static int parse(String source,
+ {int radix, int onError(String source)});
}
-class AbstractClassInstantiationError {
- AbstractClassInstantiationError(String className);
+abstract class Invocation {}
+
+abstract class Iterable<E> {
+ E get first;
+ bool get isEmpty;
+ Iterator<E> get iterator;
+ int get length;
+
+ Iterable<T> expand<T>(Iterable<T> f(E element));
+
+ R fold<R>(R initialValue, R combine(R previousValue, E element)) => null;
+
+ void forEach(void f(E element));
+
+ Iterable<R> map<R>(R f(E e));
+
+ List<E> toList();
+
+ Iterable<E> where(bool test(E element));
}
-class FallThroughError {
- FallThroughError();
- FallThroughError._create(String url, int line);
+abstract class Iterator<E> {
+ E get current;
+ bool moveNext();
}
-abstract class _SyncIterable implements Iterable {}
-class _InvocationMirror {
- _InvocationMirror._withoutType(
- String _functionName, List<Type> _typeArguments,
- List _positionalArguments, Map<Symbol, dynamic>_namedArguments,
- bool _isSuperInvocation);
+class List<E> implements Iterable<E> {
+ List([int length]);
+ factory List.from(Iterable elements, {bool growable: true}) => null;
+
+ E get last => null;
+ E operator [](int index) => null;
+ void operator []=(int index, E value) {}
+
+ void add(E value) {}
+ void addAll(Iterable<E> iterable) {}
+ void clear() {}
+
+ noSuchMethod(Invocation invocation) => null;
+}
+
+class Map<K, V> {
+ Iterable<K> get keys => null;
+ int get length => 0;
+ Iterable<V> get values => null;
+ V operator [](K key) => null;
+ void operator []=(K key, V value) {}
+ Map<RK, RV> cast<RK, RV>() => null;
+ bool containsKey(Object key) => false;
+}
+
+class Null extends Object {
+ factory Null._uninstantiable() => null;
+}
+
+abstract class num implements Comparable<num> {
+ num operator %(num other);
+ num operator *(num other);
+ num operator +(num other);
+ num operator -(num other);
+ num operator -();
+ double operator /(num other);
+ bool operator <(num other);
+ int operator <<(int other);
+ bool operator <=(num other);
+ bool operator ==(Object other);
+ bool operator >(num other);
+ bool operator >=(num other);
+ int operator >>(int other);
+ int operator ^(int other);
+ num abs();
+ int round();
+ double toDouble();
+ int toInt();
+ int operator |(int other);
+ int operator ~();
+ int operator ~/(num other);
+}
+
+class Object {
+ const Object();
+ int get hashCode => 0;
+ Type get runtimeType => null;
+ bool operator ==(other) => identical(this, other);
+ dynamic noSuchMethod(Invocation invocation) => null;
+ String toString() => 'a string';
+}
+
+abstract class Pattern {}
+
+abstract class RegExp implements Pattern {
+ external factory RegExp(String source);
+}
+
+abstract class Set<E> implements Iterable<E> {
+ Set<R> cast<R>();
+}
+
+class StackTrace {}
+
+abstract class String implements Comparable<String>, Pattern {
+ external factory String.fromCharCodes(Iterable<int> charCodes,
+ [int start = 0, int end]);
+ List<int> get codeUnits;
+ bool get isEmpty => false;
+ bool get isNotEmpty => false;
+ int get length => 0;
+ String operator +(String other) => null;
+ bool operator ==(Object other);
+ int codeUnitAt(int index);
+ String substring(int len) => null;
+ String toLowerCase();
+ String toUpperCase();
+}
+
+class Symbol {
+ const factory Symbol(String name) = _SymbolImpl;
+}
+
+class Type {}
+
+class Uri {
+ static List<int> parseIPv6Address(String host, [int start = 0, int end]) {
+ return null;
+ }
+}
+
+class _Override {
+ const _Override();
+}
+
+class _Proxy {
+ const _Proxy();
+}
+
+class _SymbolImpl {
+ const _SymbolImpl(String name);
}
''');
@@ -470,7 +464,7 @@
"dart:math": "$sdkRoot/lib/math/math.dart"
};
- final resource.MemoryResourceProvider provider;
+ final MemoryResourceProvider resourceProvider;
final Map<String, String> uriMap = {};
@@ -487,33 +481,30 @@
*/
PackageBundle _bundle;
- MockSdk(
- {bool generateSummaryFiles: false,
- resource.MemoryResourceProvider resourceProvider})
- : provider = resourceProvider ?? new resource.MemoryResourceProvider() {
+ MockSdk({bool generateSummaryFiles: false, @required this.resourceProvider}) {
_URI_MAP.forEach((uri, path) {
- uriMap[uri] = provider.convertPath(path);
+ uriMap[uri] = resourceProvider.convertPath(path);
});
for (_MockSdkLibrary library in _LIBRARIES) {
- var convertedLibrary = library._toProvider(provider);
+ var convertedLibrary = library._toProvider(resourceProvider);
sdkLibraries.add(convertedLibrary);
}
for (_MockSdkLibrary library in sdkLibraries) {
- provider.newFile(library.path, library.content);
+ resourceProvider.newFile(library.path, library.content);
library.parts.forEach((String path, String content) {
- provider.newFile(path, content);
+ resourceProvider.newFile(path, content);
});
}
- provider.newFile(
- provider.convertPath(
+ resourceProvider.newFile(
+ resourceProvider.convertPath(
'$sdkRoot/lib/_internal/sdk_library_metadata/lib/libraries.dart'),
librariesContent);
if (generateSummaryFiles) {
List<int> bytes = _computeLinkedBundleBytes();
- provider.newFileWithBytes(
- provider.convertPath('/lib/_internal/strong.sum'), bytes);
+ resourceProvider.newFileWithBytes(
+ resourceProvider.convertPath('/lib/_internal/strong.sum'), bytes);
}
}
@@ -536,28 +527,29 @@
@override
Source fromFileUri(Uri uri) {
- String filePath = provider.pathContext.fromUri(uri);
- if (!filePath.startsWith(provider.convertPath('$sdkRoot/lib/'))) {
+ String filePath = resourceProvider.pathContext.fromUri(uri);
+ if (!filePath.startsWith(resourceProvider.convertPath('$sdkRoot/lib/'))) {
return null;
}
for (SdkLibrary library in sdkLibraries) {
String libraryPath = library.path;
if (filePath == libraryPath) {
try {
- resource.File file = provider.getResource(filePath);
+ File file = resourceProvider.getResource(filePath);
Uri dartUri = Uri.parse(library.shortName);
return file.createSource(dartUri);
} catch (exception) {
return null;
}
}
- String libraryRootPath = provider.pathContext.dirname(libraryPath) +
- provider.pathContext.separator;
+ String libraryRootPath =
+ resourceProvider.pathContext.dirname(libraryPath) +
+ resourceProvider.pathContext.separator;
if (filePath.startsWith(libraryRootPath)) {
String pathInLibrary = filePath.substring(libraryRootPath.length);
String uriStr = '${library.shortName}/$pathInLibrary';
try {
- resource.File file = provider.getResource(filePath);
+ File file = resourceProvider.getResource(filePath);
Uri dartUri = Uri.parse(uriStr);
return file.createSource(dartUri);
} catch (exception) {
@@ -571,8 +563,8 @@
@override
PackageBundle getLinkedBundle() {
if (_bundle == null) {
- resource.File summaryFile =
- provider.getFile(provider.convertPath('/lib/_internal/strong.sum'));
+ File summaryFile = resourceProvider
+ .getFile(resourceProvider.convertPath('/lib/_internal/strong.sum'));
List<int> bytes;
if (summaryFile.exists) {
bytes = summaryFile.readAsBytesSync();
@@ -598,7 +590,7 @@
Source mapDartUri(String dartUri) {
String path = uriMap[dartUri];
if (path != null) {
- resource.File file = provider.getResource(path);
+ File file = resourceProvider.getResource(path);
Uri uri = new Uri(scheme: 'dart', path: dartUri.substring(5));
return file.createSource(uri);
}
@@ -619,14 +611,9 @@
}
class _MockSdkLibrary implements SdkLibrary {
- @override
final String shortName;
-
- @override
final String path;
-
final String content;
-
final Map<String, String> parts;
const _MockSdkLibrary(this.shortName, this.path, this.content,
@@ -653,7 +640,7 @@
@override
bool get isVmLibrary => throw new UnimplementedError();
- _MockSdkLibrary _toProvider(resource.MemoryResourceProvider provider) {
+ _MockSdkLibrary _toProvider(MemoryResourceProvider provider) {
return new _MockSdkLibrary(
shortName,
provider.convertPath(path),
diff --git a/pkg/analyzer/lib/src/test_utilities/resource_provider_mixin.dart b/pkg/analyzer/lib/src/test_utilities/resource_provider_mixin.dart
index a24767d..b5f666d2 100644
--- a/pkg/analyzer/lib/src/test_utilities/resource_provider_mixin.dart
+++ b/pkg/analyzer/lib/src/test_utilities/resource_provider_mixin.dart
@@ -13,16 +13,14 @@
* for manipulating the file system. The utility methods all take a posix style
* path and convert it as appropriate for the actual platform.
*/
-class ResourceProviderMixin {
+mixin ResourceProviderMixin {
MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
- String convertPath(String path) => resourceProvider.convertPath(path);
-
/// Convert the given [path] to be a valid import uri for this provider's path context.
/// The URI will use forward slashes on all platforms and absolute paths on Windows
/// will be formatted as /X:/path/file.dart
String convertAbsolutePathToUri(String path) {
- path = resourceProvider.convertPath(path);
+ path = convertPath(path);
// On Windows, absolute import paths are not quite the same as a normal fs path.
// C:\test.dart must be imported as one of:
@@ -38,23 +36,25 @@
return path.replaceAll(r'\', '/');
}
+ String convertPath(String path) => resourceProvider.convertPath(path);
+
void deleteFile(String path) {
- String convertedPath = resourceProvider.convertPath(path);
+ String convertedPath = convertPath(path);
resourceProvider.deleteFile(convertedPath);
}
void deleteFolder(String path) {
- String convertedPath = resourceProvider.convertPath(path);
+ String convertedPath = convertPath(path);
resourceProvider.deleteFolder(convertedPath);
}
File getFile(String path) {
- String convertedPath = resourceProvider.convertPath(path);
+ String convertedPath = convertPath(path);
return resourceProvider.getFile(convertedPath);
}
Folder getFolder(String path) {
- String convertedPath = resourceProvider.convertPath(path);
+ String convertedPath = convertPath(path);
return resourceProvider.getFolder(convertedPath);
}
@@ -70,32 +70,37 @@
.join(part1, part2, part3, part4, part5, part6, part7, part8);
void modifyFile(String path, String content) {
- String convertedPath = resourceProvider.convertPath(path);
+ String convertedPath = convertPath(path);
resourceProvider.modifyFile(convertedPath, content);
}
File newFile(String path, {String content = ''}) {
- String convertedPath = resourceProvider.convertPath(path);
+ String convertedPath = convertPath(path);
return resourceProvider.newFile(convertedPath, content);
}
File newFileWithBytes(String path, List<int> bytes) {
- String convertedPath = resourceProvider.convertPath(path);
+ String convertedPath = convertPath(path);
return resourceProvider.newFileWithBytes(convertedPath, bytes);
}
Folder newFolder(String path) {
- String convertedPath = resourceProvider.convertPath(path);
+ String convertedPath = convertPath(path);
return resourceProvider.newFolder(convertedPath);
}
File newOptionsFile(String directoryPath) {
- return newFile(resourceProvider.pathContext
- .join(directoryPath, ContextLocatorImpl.ANALYSIS_OPTIONS_NAME));
+ String path = join(directoryPath, ContextLocatorImpl.ANALYSIS_OPTIONS_NAME);
+ return newFile(path);
}
File newPackagesFile(String directoryPath) {
- return newFile(resourceProvider.pathContext
- .join(directoryPath, ContextLocatorImpl.PACKAGES_FILE_NAME));
+ String path = join(directoryPath, ContextLocatorImpl.PACKAGES_FILE_NAME);
+ return newFile(path);
+ }
+
+ Uri toUri(String path) {
+ path = convertPath(path);
+ return resourceProvider.pathContext.toUri(path);
}
}
diff --git a/pkg/analyzer/lib/src/workspace/basic.dart b/pkg/analyzer/lib/src/workspace/basic.dart
new file mode 100644
index 0000000..2dfddcf
--- /dev/null
+++ b/pkg/analyzer/lib/src/workspace/basic.dart
@@ -0,0 +1,85 @@
+// 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:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/context/builder.dart';
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/source/package_map_resolver.dart';
+import 'package:analyzer/src/summary/package_bundle_reader.dart';
+import 'package:analyzer/src/workspace/workspace.dart';
+import 'package:package_config/packages.dart';
+import 'package:path/path.dart';
+
+/**
+ * Information about a default Dart workspace.
+ */
+class BasicWorkspace extends Workspace {
+ /**
+ * The [ResourceProvider] by which paths are converted into [Resource]s.
+ */
+ final ResourceProvider provider;
+
+ /**
+ * The absolute workspace root path.
+ */
+ final String root;
+
+ final ContextBuilder _builder;
+
+ Map<String, List<Folder>> _packageMap;
+
+ Packages _packages;
+
+ BasicWorkspace._(this.provider, this.root, this._builder);
+
+ @override
+ Map<String, List<Folder>> get packageMap {
+ _packageMap ??= _builder.convertPackagesToMap(packages);
+ return _packageMap;
+ }
+
+ Packages get packages {
+ _packages ??= _builder.createPackageMap(root);
+ return _packages;
+ }
+
+ @override
+ UriResolver get packageUriResolver =>
+ new PackageMapUriResolver(provider, packageMap);
+
+ @override
+ SourceFactory createSourceFactory(DartSdk sdk, SummaryDataStore summaryData) {
+ if (summaryData != null) {
+ throw new UnsupportedError(
+ 'Summary files are not supported in a basic workspace.');
+ }
+ List<UriResolver> resolvers = <UriResolver>[];
+ if (sdk != null) {
+ resolvers.add(new DartUriResolver(sdk));
+ }
+ resolvers.add(packageUriResolver);
+ resolvers.add(new ResourceUriResolver(provider));
+ return new SourceFactory(resolvers, packages, provider);
+ }
+
+ /**
+ * Find the basic workspace that contains the given [path].
+ */
+ static BasicWorkspace find(
+ ResourceProvider provider, String path, ContextBuilder builder) {
+ Context context = provider.pathContext;
+
+ // Ensure that the path is absolute and normalized.
+ if (!context.isAbsolute(path)) {
+ throw new ArgumentError('not absolute: $path');
+ }
+ path = context.normalize(path);
+ Resource resource = provider.getResource(path);
+ if (resource is File) {
+ path = resource.parent.path;
+ }
+ return new BasicWorkspace._(provider, path, builder);
+ }
+}
diff --git a/pkg/analyzer/lib/src/generated/bazel.dart b/pkg/analyzer/lib/src/workspace/bazel.dart
similarity index 85%
rename from pkg/analyzer/lib/src/generated/bazel.dart
rename to pkg/analyzer/lib/src/workspace/bazel.dart
index 68e19fb..c4e6c21 100644
--- a/pkg/analyzer/lib/src/generated/bazel.dart
+++ b/pkg/analyzer/lib/src/workspace/bazel.dart
@@ -10,9 +10,10 @@
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/generated/workspace.dart';
+import 'package:analyzer/src/summary/package_bundle_reader.dart';
import 'package:analyzer/src/util/uri.dart';
-import 'package:path/path.dart';
+import 'package:analyzer/src/workspace/workspace.dart';
+import 'package:path/path.dart' as path;
/**
* Instances of the class `BazelFileUriResolver` resolve `file` URI's by first
@@ -31,8 +32,8 @@
if (!ResourceUriResolver.isFileUri(uri)) {
return null;
}
- String path = fileUriToNormalizedPath(provider.pathContext, uri);
- File file = workspace.findFile(path);
+ String filePath = fileUriToNormalizedPath(provider.pathContext, uri);
+ File file = workspace.findFile(filePath);
if (file != null) {
return file.createSource(actualUri ?? uri);
}
@@ -45,7 +46,7 @@
*/
class BazelPackageUriResolver extends UriResolver {
final BazelWorkspace _workspace;
- final Context _context;
+ final path.Context _context;
/**
* The cache of absolute [Uri]s to [Source]s mappings.
@@ -75,15 +76,15 @@
String filePath = fileUriPart.replaceAll('/', _context.separator);
if (packageName.indexOf('.') == -1) {
- String path = _context.join(_workspace.root, 'third_party', 'dart',
- packageName, 'lib', filePath);
- File file = _workspace.findFile(path);
+ String fullFilePath = _context.join(_workspace.root, 'third_party',
+ 'dart', packageName, 'lib', filePath);
+ File file = _workspace.findFile(fullFilePath);
return file?.createSource(uri);
} else {
String packagePath = packageName.replaceAll('.', _context.separator);
- String path =
+ String fullFilePath =
_context.join(_workspace.root, packagePath, 'lib', filePath);
- File file = _workspace.findFile(path);
+ File file = _workspace.findFile(fullFilePath);
return file?.createSource(uri);
}
});
@@ -91,12 +92,12 @@
@override
Uri restoreAbsolute(Source source) {
- Context context = _workspace.provider.pathContext;
- String path = source.fullName;
+ path.Context context = _workspace.provider.pathContext;
+ String filePath = source.fullName;
- Uri restore(String root, String path) {
- if (root != null && context.isWithin(root, path)) {
- String relative = context.relative(path, from: root);
+ Uri restore(String root, String filePath) {
+ if (root != null && context.isWithin(root, filePath)) {
+ String relative = context.relative(filePath, from: root);
List<String> components = context.split(relative);
if (components.length > 4 &&
components[0] == 'third_party' &&
@@ -126,7 +127,7 @@
_workspace.readonly,
_workspace.root
]) {
- Uri uri = restore(root, path);
+ Uri uri = restore(root, filePath);
if (uri != null) {
return uri;
}
@@ -185,13 +186,16 @@
UriResolver get packageUriResolver => new BazelPackageUriResolver(this);
@override
- SourceFactory createSourceFactory(DartSdk sdk) {
+ SourceFactory createSourceFactory(DartSdk sdk, SummaryDataStore summaryData) {
List<UriResolver> resolvers = <UriResolver>[];
if (sdk != null) {
resolvers.add(new DartUriResolver(sdk));
}
resolvers.add(packageUriResolver);
resolvers.add(new BazelFileUriResolver(this));
+ if (summaryData != null) {
+ resolvers.add(InSummaryUriResolver(provider, summaryData));
+ }
return new SourceFactory(resolvers, null, provider);
}
@@ -203,7 +207,7 @@
* not in the workspace [root].
*/
File findFile(String absolutePath) {
- Context context = provider.pathContext;
+ path.Context context = provider.pathContext;
try {
String relative = context.relative(absolutePath, from: root);
if (relative == '.') {
@@ -255,16 +259,12 @@
* folder, but there is corresponding folder 'foo' in `READONLY`, i.e. the
* corresponding readonly workspace root.
*/
- static BazelWorkspace find(ResourceProvider provider, String path) {
- Context context = provider.pathContext;
+ static BazelWorkspace find(ResourceProvider provider, String filePath) {
+ path.Context context = provider.pathContext;
+ assert(context.isAbsolute(filePath), 'Not an absolute path: $filePath');
+ filePath = context.normalize(filePath);
- // Ensure that the path is absolute and normalized.
- if (!context.isAbsolute(path)) {
- throw new ArgumentError('not absolute: $path');
- }
- path = context.normalize(path);
-
- Folder folder = provider.getFolder(path);
+ Folder folder = provider.getFolder(filePath);
while (true) {
Folder parent = folder.parent;
if (parent == null) {
@@ -317,7 +317,7 @@
* exists.
*/
static String _findSymlinkPrefix(ResourceProvider provider, String root) {
- Context context = provider.pathContext;
+ path.Context context = provider.pathContext;
if (provider.getFolder(context.join(root, 'blaze-genfiles')).exists) {
return 'blaze';
}
diff --git a/pkg/analyzer/lib/src/generated/gn.dart b/pkg/analyzer/lib/src/workspace/gn.dart
similarity index 78%
rename from pkg/analyzer/lib/src/generated/gn.dart
rename to pkg/analyzer/lib/src/workspace/gn.dart
index abbed00..50731c5 100644
--- a/pkg/analyzer/lib/src/generated/gn.dart
+++ b/pkg/analyzer/lib/src/workspace/gn.dart
@@ -10,13 +10,14 @@
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/generated/workspace.dart';
import 'package:analyzer/src/source/package_map_resolver.dart';
+import 'package:analyzer/src/summary/package_bundle_reader.dart';
import 'package:analyzer/src/util/uri.dart';
+import 'package:analyzer/src/workspace/workspace.dart';
import 'package:package_config/packages.dart';
import 'package:package_config/packages_file.dart';
import 'package:package_config/src/packages_impl.dart';
-import 'package:path/path.dart';
+import 'package:path/path.dart' as path;
/**
* Information about a Gn workspace.
@@ -70,7 +71,11 @@
new PackageMapUriResolver(provider, packageMap);
@override
- SourceFactory createSourceFactory(DartSdk sdk) {
+ SourceFactory createSourceFactory(DartSdk sdk, SummaryDataStore summaryData) {
+ if (summaryData != null) {
+ throw new UnsupportedError(
+ 'Summary files are not supported in a GN workspace.');
+ }
List<UriResolver> resolvers = <UriResolver>[];
if (sdk != null) {
resolvers.add(new DartUriResolver(sdk));
@@ -81,21 +86,6 @@
}
/**
- * Return the file with the given [absolutePath].
- *
- * Return `null` if the given [absolutePath] is not in the workspace [root].
- */
- File findFile(String absolutePath) {
- try {
- File writableFile = provider.getFile(absolutePath);
- if (writableFile.exists) {
- return writableFile;
- }
- } catch (_) {}
- return null;
- }
-
- /**
* Creates an alternate representation for available packages.
*/
Map<String, List<Folder>> _convertPackagesToMap(Packages packages) {
@@ -103,8 +93,8 @@
if (packages != null && packages != Packages.noPackages) {
var pathContext = provider.pathContext;
packages.asMap().forEach((String packageName, Uri uri) {
- String path = fileUriToNormalizedPath(pathContext, uri);
- folderMap[packageName] = [provider.getFolder(path)];
+ String filePath = fileUriToNormalizedPath(pathContext, uri);
+ folderMap[packageName] = [provider.getFolder(filePath)];
});
}
return folderMap;
@@ -114,8 +104,8 @@
* Loads the packages from the .packages file.
*/
Packages _createPackages() {
- Map<String, Uri> map = _packagesFilePaths.map((String path) {
- File configFile = provider.getFile(path);
+ Map<String, Uri> map = _packagesFilePaths.map((String filePath) {
+ File configFile = provider.getFile(filePath);
List<int> bytes = configFile.readAsBytesSync();
return parse(bytes, configFile.toUri());
}).reduce((mapOne, mapTwo) {
@@ -142,10 +132,10 @@
* replacing the values in the map.
*/
void _resolveSymbolicLinks(Map<String, Uri> map) {
- Context pathContext = provider.pathContext;
+ path.Context pathContext = provider.pathContext;
for (String packageName in map.keys) {
- String path = fileUriToNormalizedPath(pathContext, map[packageName]);
- Folder folder = provider.getFolder(path);
+ String filePath = fileUriToNormalizedPath(pathContext, map[packageName]);
+ Folder folder = provider.getFolder(filePath);
String folderPath = _resolveSymbolicLink(folder);
// Add a '.' so that the URI is suitable for resolving relative URI's
// against it.
@@ -155,22 +145,18 @@
}
/**
- * Find the GN workspace that contains the given [path].
+ * Find the GN workspace that contains the given [filePath].
*
* Return `null` if a workspace could not be found. For a workspace to be
* found, both a `.jiri_root` file must be found, and at least one "packages"
- * file must be found in [path]'s output directory.
+ * file must be found in [filePath]'s output directory.
*/
- static GnWorkspace find(ResourceProvider provider, String path) {
- Context context = provider.pathContext;
+ static GnWorkspace find(ResourceProvider provider, String filePath) {
+ path.Context context = provider.pathContext;
+ assert(context.isAbsolute(filePath), 'Not an absolute path: $filePath');
+ filePath = context.normalize(filePath);
- // Ensure that the path is absolute and normalized.
- if (!context.isAbsolute(path)) {
- throw new ArgumentError('Not an absolute path: $path');
- }
- path = context.normalize(path);
-
- Folder folder = provider.getFolder(path);
+ Folder folder = provider.getFolder(filePath);
while (true) {
Folder parent = folder.parent;
if (parent == null) {
@@ -180,7 +166,8 @@
// Found the .jiri_root file, must be a non-git workspace.
if (folder.getChildAssumingFolder(_jiriRootName).exists) {
String root = folder.path;
- List<String> packagesFiles = _findPackagesFile(provider, root, path);
+ List<String> packagesFiles =
+ _findPackagesFile(provider, root, filePath);
if (packagesFiles.isEmpty) {
return null;
}
@@ -204,10 +191,10 @@
static List<String> _findPackagesFile(
ResourceProvider provider,
String root,
- String path,
+ String filePath,
) {
- Context pathContext = provider.pathContext;
- String sourceDirectory = pathContext.relative(path, from: root);
+ path.Context pathContext = provider.pathContext;
+ String sourceDirectory = pathContext.relative(filePath, from: root);
Folder outDirectory = _getOutDirectory(root, provider);
if (outDirectory == null) {
return const <String>[];
@@ -234,7 +221,7 @@
* that file cannot be found, looks for standard output directory locations.
*/
static Folder _getOutDirectory(String root, ResourceProvider provider) {
- Context pathContext = provider.pathContext;
+ path.Context pathContext = provider.pathContext;
File config = provider.getFile(pathContext.join(root, '.config'));
if (config.exists) {
String content = config.readAsStringSync();
@@ -242,11 +229,11 @@
new RegExp(r'^FUCHSIA_BUILD_DIR=["\x27](.+)["\x27]$', multiLine: true)
.firstMatch(content);
if (match != null) {
- String path = match.group(1);
- if (pathContext.isRelative(path)) {
- path = pathContext.join(root, path);
+ String buildDirPath = match.group(1);
+ if (pathContext.isRelative(buildDirPath)) {
+ buildDirPath = pathContext.join(root, buildDirPath);
}
- return provider.getFolder(path);
+ return provider.getFolder(buildDirPath);
}
}
Folder outDirectory = provider.getFolder(pathContext.join(root, 'out'));
diff --git a/pkg/analyzer/lib/src/generated/package_build.dart b/pkg/analyzer/lib/src/workspace/package_build.dart
similarity index 80%
rename from pkg/analyzer/lib/src/generated/package_build.dart
rename to pkg/analyzer/lib/src/workspace/package_build.dart
index 8effaf9..49e0485 100644
--- a/pkg/analyzer/lib/src/generated/package_build.dart
+++ b/pkg/analyzer/lib/src/workspace/package_build.dart
@@ -11,11 +11,12 @@
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/generated/workspace.dart';
import 'package:analyzer/src/source/package_map_resolver.dart';
+import 'package:analyzer/src/summary/package_bundle_reader.dart';
import 'package:analyzer/src/util/uri.dart';
+import 'package:analyzer/src/workspace/workspace.dart';
import 'package:package_config/packages.dart';
-import 'package:path/path.dart';
+import 'package:path/path.dart' as path;
import 'package:yaml/yaml.dart';
/**
@@ -35,8 +36,8 @@
if (!ResourceUriResolver.isFileUri(uri)) {
return null;
}
- String path = fileUriToNormalizedPath(provider.pathContext, uri);
- File file = workspace.findFile(path);
+ String filePath = fileUriToNormalizedPath(provider.pathContext, uri);
+ File file = workspace.findFile(filePath);
if (file != null) {
return file.createSource(actualUri ?? uri);
}
@@ -50,7 +51,7 @@
class PackageBuildPackageUriResolver extends UriResolver {
final PackageBuildWorkspace _workspace;
final UriResolver _normalUriResolver;
- final Context _context;
+ final path.Context _context;
/**
* The cache of absolute [Uri]s to [Source]s mappings.
@@ -98,12 +99,11 @@
@override
Uri restoreAbsolute(Source source) {
- Context context = _workspace.provider.pathContext;
- String path = source.fullName;
+ String filePath = source.fullName;
- if (context.isWithin(_workspace.root, path)) {
- String relative = context.relative(path, from: _workspace.root);
- List<String> components = context.split(relative);
+ if (_context.isWithin(_workspace.root, filePath)) {
+ String relative = _context.relative(filePath, from: _workspace.root);
+ List<String> components = _context.split(relative);
if (components.length > 4 &&
components[0] == 'build' &&
components[1] == 'generated' &&
@@ -205,9 +205,10 @@
if (!packageMap.containsKey(packageName)) {
return null;
}
- String path = context.join(
+ path.Context context = provider.pathContext;
+ String fullBuiltPath = context.join(
root, _dartToolRootName, 'build', 'generated', packageName, builtPath);
- return provider.getFile(path);
+ return provider.getFile(fullBuiltPath);
}
/**
@@ -217,13 +218,18 @@
* `bin/`, `web/`, and `test/` etc can all be built as well. This method
* exists to give a name to that prefix processing step.
*/
- String builtPackageSourcePath(String path) {
- assert(context.isRelative(path));
- return context.join('lib', path);
+ String builtPackageSourcePath(String filePath) {
+ path.Context context = provider.pathContext;
+ assert(context.isRelative(filePath), 'Not a relative path: $filePath');
+ return context.join('lib', filePath);
}
@override
- SourceFactory createSourceFactory(DartSdk sdk) {
+ SourceFactory createSourceFactory(DartSdk sdk, SummaryDataStore summaryData) {
+ if (summaryData != null) {
+ throw new UnsupportedError(
+ 'Summary files are not supported in a package:build workspace.');
+ }
List<UriResolver> resolvers = <UriResolver>[];
if (sdk != null) {
resolvers.add(new DartUriResolver(sdk));
@@ -234,44 +240,40 @@
}
/**
- * Return the file with the given [path], looking first into directories for
+ * Return the file with the given [filePath], looking first into directories for
* source files, and then in the generated directory
* `.dart_tool/build/generated/$projectPackageName/$FILE`. The file in the
* workspace root is returned even if it does not exist. Return `null` if the
- * given [path] is not in the workspace [root].
+ * given [filePath] is not in the workspace [root].
*/
- File findFile(String path) {
- assert(context.isAbsolute(path));
+ File findFile(String filePath) {
+ path.Context context = provider.pathContext;
+ assert(context.isAbsolute(filePath), 'Not an absolute path: $filePath');
try {
- final String builtPath = context.relative(path, from: root);
+ final String builtPath = context.relative(filePath, from: root);
final File file = builtFile(builtPath, projectPackageName);
if (file.exists) {
return file;
}
- return provider.getFile(path);
+ return provider.getFile(filePath);
} catch (_) {
return null;
}
}
/**
- * Find the package:build workspace that contains the given [path].
+ * Find the package:build workspace that contains the given [filePath].
*
- * Return `null` if the path is not in a package:build workspace.
+ * Return `null` if the filePath is not in a package:build workspace.
*/
static PackageBuildWorkspace find(
- ResourceProvider provider, String path, ContextBuilder builder) {
- Context context = provider.pathContext;
-
- // Ensure that the path is absolute and normalized.
- if (!context.isAbsolute(path)) {
- throw new ArgumentError('Not an absolute path: $path');
- }
- path = context.normalize(path);
-
- Folder folder = provider.getFolder(path);
+ ResourceProvider provider, String filePath, ContextBuilder builder) {
+ path.Context context = provider.pathContext;
+ assert(context.isAbsolute(filePath), 'Not an absolute path: $filePath');
+ filePath = context.normalize(filePath);
+ Folder folder = provider.getFolder(filePath);
while (true) {
Folder parent = folder.parent;
if (parent == null) {
diff --git a/pkg/analyzer/lib/src/generated/workspace.dart b/pkg/analyzer/lib/src/workspace/workspace.dart
similarity index 76%
rename from pkg/analyzer/lib/src/generated/workspace.dart
rename to pkg/analyzer/lib/src/workspace/workspace.dart
index c122845..efd55f8 100644
--- a/pkg/analyzer/lib/src/generated/workspace.dart
+++ b/pkg/analyzer/lib/src/workspace/workspace.dart
@@ -5,6 +5,7 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/summary/package_bundle_reader.dart';
/**
* Abstract superclass of classes that provide information about the workspace
@@ -28,8 +29,8 @@
UriResolver get packageUriResolver;
/**
- * Create the [SourceFactory] for resolving Uris to [Source]s.
- * The [sdk] may be `null`.
+ * Create the source factory that should be used to resolve Uris to [Source]s.
+ * The [sdk] may be `null`. The [summaryData] can also be `null`.
*/
- SourceFactory createSourceFactory(DartSdk sdk);
+ SourceFactory createSourceFactory(DartSdk sdk, SummaryDataStore summaryData);
}
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index d6cd53d..62eb471 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
name: analyzer
-version: 0.33.6+1-dev
+version: 0.34.0
author: Dart Team <misc@dartlang.org>
description: Static analyzer for Dart.
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
@@ -11,10 +11,10 @@
collection: ^1.10.1
convert: ^2.0.0
crypto: '>=1.1.1 <3.0.0'
- front_end: 0.1.6+8
+ front_end: 0.1.7
glob: ^1.0.3
html: '>=0.12.0 <1.14.0'
- kernel: 0.3.6+8
+ kernel: 0.3.7
meta: ^1.0.2
package_config: '>=0.1.5 <2.0.0'
path: '>=0.9.0 <2.0.0'
diff --git a/pkg/analyzer/test/dart/ast/visitor_test.dart b/pkg/analyzer/test/dart/ast/visitor_test.dart
index f246a06..94457e0 100644
--- a/pkg/analyzer/test/dart/ast/visitor_test.dart
+++ b/pkg/analyzer/test/dart/ast/visitor_test.dart
@@ -40,7 +40,7 @@
}''';
CompilationUnit unit = parseCompilationUnit(source);
List<AstNode> nodes = new List<AstNode>();
- BreadthFirstVisitor<Object> visitor =
+ _BreadthFirstVisitorTestHelper visitor =
new _BreadthFirstVisitorTestHelper(nodes);
visitor.visitAllNodes(unit);
expect(nodes, hasLength(59));
@@ -64,14 +64,14 @@
* A helper class used to collect the nodes that were visited and to preserve
* the order in which they were visited.
*/
-class _BreadthFirstVisitorTestHelper extends BreadthFirstVisitor<Object> {
+class _BreadthFirstVisitorTestHelper extends BreadthFirstVisitor<void> {
List<AstNode> nodes;
_BreadthFirstVisitorTestHelper(this.nodes) : super();
@override
- Object visitNode(AstNode node) {
+ void visitNode(AstNode node) {
nodes.add(node);
- return super.visitNode(node);
+ super.visitNode(node);
}
}
diff --git a/pkg/analyzer/test/dart/element/builder_test.dart b/pkg/analyzer/test/dart/element/builder_test.dart
index f460cfc..4b6a746 100644
--- a/pkg/analyzer/test/dart/element/builder_test.dart
+++ b/pkg/analyzer/test/dart/element/builder_test.dart
@@ -1207,7 +1207,7 @@
* It is used to test the [ApiElementBuilder] itself, and its usage by
* [ElementBuilder].
*/
-abstract class _ApiElementBuilderTestMixin {
+mixin _ApiElementBuilderTestMixin {
CompilationUnit get compilationUnit;
void set isMixinSupportEnabled(bool value);
diff --git a/pkg/analyzer/test/file_system/resource_uri_resolver_test.dart b/pkg/analyzer/test/file_system/resource_uri_resolver_test.dart
index 4bb689e..4f0a866 100644
--- a/pkg/analyzer/test/file_system/resource_uri_resolver_test.dart
+++ b/pkg/analyzer/test/file_system/resource_uri_resolver_test.dart
@@ -2,9 +2,9 @@
// 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:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -15,36 +15,34 @@
}
@reflectiveTest
-class ResourceUriResolverTest {
- MemoryResourceProvider provider;
+class ResourceUriResolverTest with ResourceProviderMixin {
ResourceUriResolver resolver;
void setUp() {
- provider = new MemoryResourceProvider();
- resolver = new ResourceUriResolver(provider);
- provider.newFile(provider.convertPath('/test.dart'), '');
- provider.newFolder(provider.convertPath('/folder'));
+ resolver = new ResourceUriResolver(resourceProvider);
+ newFile('/test.dart');
+ newFolder('/folder');
}
void test_creation() {
- expect(provider, isNotNull);
+ expect(resourceProvider, isNotNull);
expect(resolver, isNotNull);
}
void test_resolveAbsolute_file() {
- var uri = provider.pathContext.toUri(provider.convertPath('/test.dart'));
+ var uri = toUri('/test.dart');
Source source = resolver.resolveAbsolute(uri);
expect(source, isNotNull);
expect(source.exists(), isTrue);
- expect(source.fullName, provider.convertPath('/test.dart'));
+ expect(source.fullName, convertPath('/test.dart'));
}
void test_resolveAbsolute_folder() {
- var uri = provider.pathContext.toUri(provider.convertPath('/folder'));
+ var uri = toUri('/folder');
Source source = resolver.resolveAbsolute(uri);
expect(source, isNotNull);
expect(source.exists(), isFalse);
- expect(source.fullName, provider.convertPath('/folder'));
+ expect(source.fullName, convertPath('/folder'));
}
void test_resolveAbsolute_notFile_dartUri() {
@@ -60,7 +58,7 @@
}
void test_restoreAbsolute() {
- var uri = provider.pathContext.toUri(provider.convertPath('/test.dart'));
+ var uri = toUri('/test.dart');
Source source = resolver.resolveAbsolute(uri);
expect(source, isNotNull);
expect(resolver.restoreAbsolute(source), uri);
diff --git a/pkg/analyzer/test/generated/all_the_rest_test.dart b/pkg/analyzer/test/generated/all_the_rest_test.dart
index 4ac956a..49a4b02 100644
--- a/pkg/analyzer/test/generated/all_the_rest_test.dart
+++ b/pkg/analyzer/test/generated/all_the_rest_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -150,16 +150,14 @@
void test_restoreAbsolute_library() {
_SourceMock source = new _SourceMock();
- Uri fileUri = resourceProvider.pathContext.toUri(coreCorePath);
- source.uri = fileUri;
+ source.uri = toUri('/sdk/lib/core/core.dart');
Uri dartUri = resolver.restoreAbsolute(source);
expect(dartUri.toString(), 'dart:core');
}
void test_restoreAbsolute_part() {
_SourceMock source = new _SourceMock();
- Uri fileUri = resourceProvider.pathContext.toUri(coreIntPath);
- source.uri = fileUri;
+ source.uri = toUri('/sdk/lib/core/int.dart');
Uri dartUri = resolver.restoreAbsolute(source);
expect(dartUri.toString(), 'dart:core/int.dart');
}
@@ -220,7 +218,7 @@
A.bar() {}
}''');
ConstructorDeclaration declaration =
- id.getAncestor((node) => node is ConstructorDeclaration);
+ id.thisOrAncestorOfType<ConstructorDeclaration>();
Element element = ElementLocator.locate(declaration);
EngineTestCase.assertInstanceOf(
(obj) => obj is ConstructorElement, ConstructorElement, element);
@@ -236,7 +234,7 @@
test_locate_FunctionDeclaration() async {
AstNode id = await _findNodeIn("f", "int f() => 3;");
FunctionDeclaration declaration =
- id.getAncestor((node) => node is FunctionDeclaration);
+ id.thisOrAncestorOfType<FunctionDeclaration>();
Element element = ElementLocator.locate(declaration);
EngineTestCase.assertInstanceOf(
(obj) => obj is FunctionElement, FunctionElement, element);
@@ -397,7 +395,7 @@
void m() {}
}''');
MethodDeclaration declaration =
- id.getAncestor((node) => node is MethodDeclaration);
+ id.thisOrAncestorOfType<MethodDeclaration>();
Element element = ElementLocator.locate(declaration);
EngineTestCase.assertInstanceOf(
(obj) => obj is MethodElement, MethodElement, element);
@@ -425,8 +423,7 @@
CompilationUnit cu = await _resolveContents(code);
int offset = code.indexOf('foo(0)');
AstNode node = new NodeLocator(offset).searchWithin(cu);
- MethodInvocation invocation =
- node.getAncestor((n) => n is MethodInvocation);
+ MethodInvocation invocation = node.thisOrAncestorOfType<MethodInvocation>();
Element element = ElementLocator.locate(invocation);
EngineTestCase.assertInstanceOf(
(obj) => obj is FunctionElement, FunctionElement, element);
@@ -460,7 +457,7 @@
import 'dart:core' as core;
core.int value;''');
PrefixedIdentifier identifier =
- id.getAncestor((node) => node is PrefixedIdentifier);
+ id.thisOrAncestorOfType<PrefixedIdentifier>();
Element element = ElementLocator.locate(identifier);
EngineTestCase.assertInstanceOf(
(obj) => obj is ClassElement, ClassElement, element);
@@ -508,7 +505,7 @@
test_locate_VariableDeclaration() async {
AstNode id = await _findNodeIn("x", "var x = 'abc';");
VariableDeclaration declaration =
- id.getAncestor((node) => node is VariableDeclaration);
+ id.thisOrAncestorOfType<VariableDeclaration>();
Element element = ElementLocator.locate(declaration);
EngineTestCase.assertInstanceOf((obj) => obj is TopLevelVariableElement,
TopLevelVariableElement, element);
@@ -2053,31 +2050,27 @@
}
}
-class _SimpleDartSdkTest extends Object with ResourceProviderMixin {
- String coreCorePath;
- String coreIntPath;
+class _SimpleDartSdkTest with ResourceProviderMixin {
DartSdk sdk;
void setUp() {
- Folder sdkFolder =
- resourceProvider.newFolder(resourceProvider.convertPath('/sdk'));
- resourceProvider.newFile(
- resourceProvider.convertPath(
- '/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart'),
- '''
+ newFile('/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart',
+ content: '''
const Map<String, LibraryInfo> libraries = const {
"core": const LibraryInfo("core/core.dart")
};
''');
- coreCorePath = resourceProvider.convertPath('/sdk/lib/core/core.dart');
- resourceProvider.newFile(coreCorePath, '''
+
+ newFile('/sdk/lib/core/core.dart', content: '''
library dart.core;
part 'int.dart';
''');
- coreIntPath = resourceProvider.convertPath('/sdk/lib/core/int.dart');
- resourceProvider.newFile(coreIntPath, '''
+
+ newFile('/sdk/lib/core/int.dart', content: '''
part of dart.core;
''');
+
+ Folder sdkFolder = newFolder('/sdk');
sdk = new FolderBasedDartSdk(resourceProvider, sdkFolder);
}
}
diff --git a/pkg/analyzer/test/generated/analysis_context_factory.dart b/pkg/analyzer/test/generated/analysis_context_factory.dart
index 0226a04..1185adf 100644
--- a/pkg/analyzer/test/generated/analysis_context_factory.dart
+++ b/pkg/analyzer/test/generated/analysis_context_factory.dart
@@ -130,6 +130,7 @@
objectClassElement,
overrideClassElement,
proxyClassElement,
+ provider.setType.element,
provider.stackTraceType.element,
provider.stringType.element,
provider.symbolType.element,
@@ -173,13 +174,15 @@
proxyTopLevelVariableElt
];
LibraryElementImpl coreLibrary = new LibraryElementImpl.forNode(
- coreContext, AstTestFactory.libraryIdentifier2(["dart", "core"]));
+ coreContext, null, AstTestFactory.libraryIdentifier2(["dart", "core"]));
coreLibrary.definingCompilationUnit = coreUnit;
//
// dart:async
//
LibraryElementImpl asyncLibrary = new LibraryElementImpl.forNode(
- coreContext, AstTestFactory.libraryIdentifier2(["dart", "async"]));
+ coreContext,
+ null,
+ AstTestFactory.libraryIdentifier2(["dart", "async"]));
CompilationUnitElementImpl asyncUnit = new CompilationUnitElementImpl();
Source asyncSource = sourceFactory.forUri(DartSdk.DART_ASYNC);
coreContext.setContents(asyncSource, "");
@@ -329,7 +332,7 @@
htmlUnit.topLevelVariables = <TopLevelVariableElement>[document];
htmlUnit.accessors = <PropertyAccessorElement>[document.getter];
LibraryElementImpl htmlLibrary = new LibraryElementImpl.forNode(coreContext,
- AstTestFactory.libraryIdentifier2(["dart", "dom", "html"]));
+ null, AstTestFactory.libraryIdentifier2(["dart", "dom", "html"]));
htmlLibrary.definingCompilationUnit = htmlUnit;
//
// dart:math
@@ -390,7 +393,7 @@
];
mathUnit.types = <ClassElement>[randomElement];
LibraryElementImpl mathLibrary = new LibraryElementImpl.forNode(
- coreContext, AstTestFactory.libraryIdentifier2(["dart", "math"]));
+ coreContext, null, AstTestFactory.libraryIdentifier2(["dart", "math"]));
mathLibrary.definingCompilationUnit = mathUnit;
//
// Set empty sources for the rest of the libraries.
diff --git a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_driver_test.dart b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_driver_test.dart
index b8d01e9..a21ef51 100644
--- a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_driver_test.dart
+++ b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_driver_test.dart
@@ -17,4 +17,8 @@
extends CheckedModeCompileTimeErrorCodeTest {
@override
bool get enableNewAnalysisDriver => true;
+
+ test_setElementTypeNotAssignable() async {
+ await super.test_setElementTypeNotAssignable();
+ }
}
diff --git a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
index 32623b2..52ed142 100644
--- a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
@@ -28,8 +28,7 @@
var v = const A(3, 2);
''');
await computeAnalysisResult(source);
- assertErrors(
- source, [CheckedModeCompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
verify([source]);
}
@@ -634,8 +633,18 @@
}
var v = const A.a1(0);''');
await computeAnalysisResult(source);
- assertErrors(
- source, [CheckedModeCompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
+ verify([source]);
+ }
+
+ @failingTest
+ test_setElementTypeNotAssignable() async {
+ Source source = addSource("var v = const <String>{42};");
+ await computeAnalysisResult(source);
+ assertErrors(source, [
+ CheckedModeCompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE,
+ StaticWarningCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE
+ ]);
verify([source]);
}
@@ -651,8 +660,7 @@
const f = const D('0.0');
''');
await computeAnalysisResult(source);
- assertErrors(
- source, [CheckedModeCompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
+ assertErrors(source, [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
verify([source]);
}
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_driver_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_driver_test.dart
index e2ad9cf..c8acd25 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_driver_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_driver_test.dart
@@ -31,12 +31,6 @@
@override
@failingTest
- test_genericFunctionTypeArgument_typedef() {
- return super.test_genericFunctionTypeArgument_typedef();
- }
-
- @override
- @failingTest
test_invalidIdentifierInAsync_async() {
return super.test_invalidIdentifierInAsync_async();
}
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
index a04cda9..1a74c98 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
@@ -38,8 +38,32 @@
@override
@failingTest
- test_genericFunctionTypeArgument_typedef() {
- return super.test_genericFunctionTypeArgument_typedef();
+ test_constSetElementTypeImplementsEquals_constField() async {
+ return super.test_constSetElementTypeImplementsEquals_constField();
+ }
+
+ @override
+ @failingTest
+ test_constSetElementTypeImplementsEquals_direct() async {
+ return super.test_constSetElementTypeImplementsEquals_direct();
+ }
+
+ @override
+ @failingTest
+ test_constSetElementTypeImplementsEquals_dynamic() async {
+ return super.test_constSetElementTypeImplementsEquals_dynamic();
+ }
+
+ @override
+ @failingTest
+ test_constSetElementTypeImplementsEquals_factory() async {
+ return super.test_constSetElementTypeImplementsEquals_factory();
+ }
+
+ @override
+ @failingTest
+ test_constSetElementTypeImplementsEquals_super() async {
+ return super.test_constSetElementTypeImplementsEquals_super();
}
@override
@@ -61,6 +85,12 @@
}
@override
+ @failingTest
+ test_invalidTypeArgumentInConstSet() async {
+ return super.test_invalidTypeArgumentInConstSet();
+ }
+
+ @override
@failingTest // Does not work with old task model
test_mixinInference_recursiveSubtypeCheck_new_syntax() {
return super.test_mixinInference_recursiveSubtypeCheck_new_syntax();
@@ -74,6 +104,24 @@
@override
@failingTest
+ test_nonConstSetElement() async {
+ return super.test_nonConstSetElement();
+ }
+
+ @override
+ @failingTest
+ test_nonConstSetElementFromDeferredLibrary() async {
+ return super.test_nonConstSetElementFromDeferredLibrary();
+ }
+
+ @override
+ @failingTest
+ test_nonConstSetElementFromDeferredLibrary_nested() async {
+ return super.test_nonConstSetElementFromDeferredLibrary_nested();
+ }
+
+ @override
+ @failingTest
test_objectCannotExtendAnotherClass() {
return super.test_objectCannotExtendAnotherClass();
}
@@ -1235,9 +1283,9 @@
}
test_constEvalTypeInt_binary() async {
- await _check_constEvalTypeInt_withParameter_binary("p ^ ''");
- await _check_constEvalTypeInt_withParameter_binary("p & ''");
- await _check_constEvalTypeInt_withParameter_binary("p | ''");
+ await _check_constEvalTypeBoolOrInt_withParameter_binary("p ^ ''");
+ await _check_constEvalTypeBoolOrInt_withParameter_binary("p & ''");
+ await _check_constEvalTypeBoolOrInt_withParameter_binary("p | ''");
await _check_constEvalTypeInt_withParameter_binary("p >> ''");
await _check_constEvalTypeInt_withParameter_binary("p << ''");
}
@@ -1439,6 +1487,100 @@
verify([source]);
}
+ test_constSetElementTypeImplementsEquals_constField() async {
+ Source source = addSource(r'''
+class A {
+ static const a = const A();
+ const A();
+ operator ==(other) => false;
+}
+main() {
+ const {A.a};
+}
+''');
+ await computeAnalysisResult(source);
+ assertErrors(source,
+ [CompileTimeErrorCode.CONST_SET_ELEMENT_TYPE_IMPLEMENTS_EQUALS]);
+ verify([source]);
+ }
+
+ test_constSetElementTypeImplementsEquals_direct() async {
+ Source source = addSource(r'''
+class A {
+ const A();
+ operator ==(other) => false;
+}
+main() {
+ const {const A()};
+}
+''');
+ await computeAnalysisResult(source);
+ assertErrors(source,
+ [CompileTimeErrorCode.CONST_SET_ELEMENT_TYPE_IMPLEMENTS_EQUALS]);
+ verify([source]);
+ }
+
+ test_constSetElementTypeImplementsEquals_dynamic() async {
+ // Note: static type of B.a is "dynamic", but actual type of the const
+ // object is A. We need to make sure we examine the actual type when
+ // deciding whether there is a problem with operator==.
+ Source source = addSource(r'''
+class A {
+ const A();
+ operator ==(other) => false;
+}
+class B {
+ static const a = const A();
+}
+main() {
+ const {B.a};
+}
+''');
+ await computeAnalysisResult(source);
+ assertErrors(source,
+ [CompileTimeErrorCode.CONST_SET_ELEMENT_TYPE_IMPLEMENTS_EQUALS]);
+ verify([source]);
+ }
+
+ test_constSetElementTypeImplementsEquals_factory() async {
+ Source source = addSource(r'''
+class A { const factory A() = B; }
+
+class B implements A {
+ const B();
+
+ operator ==(o) => true;
+}
+
+main() {
+ var m = const {const A()};
+}
+''');
+ await computeAnalysisResult(source);
+ assertErrors(source,
+ [CompileTimeErrorCode.CONST_SET_ELEMENT_TYPE_IMPLEMENTS_EQUALS]);
+ verify([source]);
+ }
+
+ test_constSetElementTypeImplementsEquals_super() async {
+ Source source = addSource(r'''
+class A {
+ const A();
+ operator ==(other) => false;
+}
+class B extends A {
+ const B();
+}
+main() {
+ const {const B()};
+}
+''');
+ await computeAnalysisResult(source);
+ assertErrors(source,
+ [CompileTimeErrorCode.CONST_SET_ELEMENT_TYPE_IMPLEMENTS_EQUALS]);
+ verify([source]);
+ }
+
test_constWithInvalidTypeParameters() async {
Source source = addSource(r'''
class A {
@@ -2406,36 +2548,6 @@
verify([source]);
}
- test_genericFunctionTypeArgument_class() async {
- Source source = addSource(r'''
-class C<T> {}
-C<T Function<T>(T)> c;''');
- await computeAnalysisResult(source);
- assertErrors(source,
- [CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT]);
- verify([source]);
- }
-
- test_genericFunctionTypeArgument_function() async {
- Source source = addSource(r'''
-T f<T>(T) => null;
-main() { f<S Function<S>(S)>(null); }''');
- await computeAnalysisResult(source);
- assertErrors(source,
- [CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT]);
- verify([source]);
- }
-
- test_genericFunctionTypeArgument_functionType() async {
- Source source = addSource(r'''
-T Function<T>(T) f;
-main() { f<S Function<S>(S)>(null); }''');
- await computeAnalysisResult(source);
- assertErrors(source,
- [CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT]);
- verify([source]);
- }
-
test_genericFunctionTypeArgument_inference_function() async {
Source source = addSource(r'''
T f<T>(T t) => null;
@@ -2465,29 +2577,6 @@
verify([source]);
}
- test_genericFunctionTypeArgument_method() async {
- Source source = addSource(r'''
-class C {
- T f<T>(T) => null;
-}
-main() { new C().f<S Function<S>(S)>(null); }''');
- await computeAnalysisResult(source);
- assertErrors(source,
- [CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT]);
- verify([source]);
- }
-
- test_genericFunctionTypeArgument_typedef() async {
- // TODO(mfairhurst) diagnose these parse errors to give the correct error
- Source source = addSource(r'''
-typedef T f<T>(T t);
-final T<Function<S>(int)> x = null;''');
- await computeAnalysisResult(source);
- assertErrors(source,
- [CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT]);
- verify([source]);
- }
-
test_genericFunctionTypeAsBound_class() async {
Source source = addSource(r'''
class C<T extends S Function<S>(S)> {
@@ -3670,6 +3759,19 @@
verify([source]);
}
+ test_invalidTypeArgumentInConstSet() async {
+ Source source = addSource(r'''
+class A<E> {
+ m() {
+ return const <E>{};
+ }
+}''');
+ await computeAnalysisResult(source);
+ assertErrors(
+ source, [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_SET]);
+ verify([source]);
+ }
+
test_invalidUri_export() async {
Source source = addSource("export 'ht:';");
await computeAnalysisResult(source);
@@ -4672,6 +4774,48 @@
]);
}
+ test_nonConstSetElement() async {
+ Source source = addSource(r'''
+f(a) {
+ return const {a};
+}''');
+ await computeAnalysisResult(source);
+ assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT]);
+ verify([source]);
+ }
+
+ test_nonConstSetElementFromDeferredLibrary() async {
+ await resolveWithErrors(<String>[
+ r'''
+library lib1;
+const int c = 1;''',
+ r'''
+library root;
+import 'lib1.dart' deferred as a;
+f() {
+ return const {a.c};
+}'''
+ ], [
+ CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT_FROM_DEFERRED_LIBRARY
+ ]);
+ }
+
+ test_nonConstSetElementFromDeferredLibrary_nested() async {
+ await resolveWithErrors(<String>[
+ r'''
+library lib1;
+const int c = 1;''',
+ r'''
+library root;
+import 'lib1.dart' deferred as a;
+f() {
+ return const {a.c + 1};
+}'''
+ ], [
+ CompileTimeErrorCode.NON_CONSTANT_SET_ELEMENT_FROM_DEFERRED_LIBRARY
+ ]);
+ }
+
test_nonConstValueInInitializer_assert_condition() async {
Source source = addSource(r'''
class A {
@@ -4730,7 +4874,7 @@
}''');
await computeAnalysisResult(source);
assertErrors(source, [
- CompileTimeErrorCode.CONST_EVAL_TYPE_INT,
+ CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_INT,
StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
]);
verify([source]);
@@ -5076,23 +5220,6 @@
verify([source]);
}
- test_prefix_conditionalPropertyAccess_call() async {
- addNamedSource('/lib.dart', '''
-library lib;
-g() {}
-''');
- Source source = addSource('''
-import 'lib.dart' as p;
-f() {
- p?.g();
-}
-''');
- await computeAnalysisResult(source);
- assertErrors(
- source, [CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT]);
- verify([source]);
- }
-
test_prefix_conditionalPropertyAccess_call_loadLibrary() async {
addNamedSource('/lib.dart', '''
library lib;
@@ -5175,36 +5302,6 @@
verify([source]);
}
- test_prefix_unqualified_invocation_in_method() async {
- addNamedSource('/lib.dart', 'librarylib;');
- Source source = addSource('''
-import 'lib.dart' as p;
-class C {
- f() {
- p();
- }
-}
-''');
- await computeAnalysisResult(source);
- assertErrors(
- source, [CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT]);
- verify([source]);
- }
-
- test_prefix_unqualified_invocation_not_in_method() async {
- addNamedSource('/lib.dart', 'librarylib;');
- Source source = addSource('''
-import 'lib.dart' as p;
-f() {
- p();
-}
-''');
- await computeAnalysisResult(source);
- assertErrors(
- source, [CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT]);
- verify([source]);
- }
-
test_prefixCollidesWithTopLevelMembers_functionTypeAlias() async {
addNamedSource("/lib.dart", r'''
library lib;
@@ -5423,9 +5520,9 @@
}
test_recursiveCompileTimeConstant_fromMapLiteral() async {
- resourceProvider.newFile(
- resourceProvider.convertPath('/constants.dart'),
- r'''
+ newFile(
+ '/constants.dart',
+ content: r'''
const int x = y;
const int y = x;
''',
@@ -6334,7 +6431,7 @@
assertErrors(test, [HintCode.UNUSED_IMPORT]);
// Remove the overlay in the same way as AnalysisServer.
- resourceProvider.deleteFile(target.fullName);
+ deleteFile(target.fullName);
if (enableNewAnalysisDriver) {
driver.removeFile(target.fullName);
} else {
@@ -6352,7 +6449,7 @@
await computeAnalysisResult(source);
assertErrors(source, [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
- String targetPath = resourceProvider.convertPath('/target.dart');
+ String targetPath = convertPath('/target.dart');
if (enableNewAnalysisDriver) {
// Add an overlay in the same way as AnalysisServer.
fileContentOverlay[targetPath] = '';
@@ -6617,6 +6714,21 @@
verify([source]);
}
+ Future<Null> _check_constEvalTypeBoolOrInt_withParameter_binary(
+ String expr) async {
+ Source source = addSource('''
+class A {
+ final a;
+ const A(int p) : a = $expr;
+}''');
+ await computeAnalysisResult(source);
+ assertErrors(source, [
+ CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_INT,
+ StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ ]);
+ verify([source]);
+ }
+
Future<Null> _check_constEvalTypeInt_withParameter_binary(String expr) async {
Source source = addSource('''
class A {
diff --git a/pkg/analyzer/test/generated/element_resolver_test.dart b/pkg/analyzer/test/generated/element_resolver_test.dart
index 75e534a..e553c30 100644
--- a/pkg/analyzer/test/generated/element_resolver_test.dart
+++ b/pkg/analyzer/test/generated/element_resolver_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -829,31 +829,6 @@
_listener.assertNoErrors();
}
- test_visitMethodInvocation_namedParameter() async {
- ClassElementImpl classA = ElementFactory.classElement2("A");
- String methodName = "m";
- String parameterName = "p";
- MethodElementImpl method = ElementFactory.methodElement(methodName, null);
- ParameterElement parameter = ElementFactory.namedParameter(parameterName);
- method.parameters = <ParameterElement>[parameter];
- classA.methods = <MethodElement>[method];
- SimpleIdentifier left = AstTestFactory.identifier3("i");
- left.staticType = classA.type;
- MethodInvocation invocation = AstTestFactory.methodInvocation(
- left, methodName, [
- AstTestFactory.namedExpression2(parameterName, AstTestFactory.integer(0))
- ]);
- _resolveNode(invocation);
- expect(invocation.methodName.staticElement, same(method));
- expect(
- (invocation.argumentList.arguments[0] as NamedExpression)
- .name
- .label
- .staticElement,
- same(parameter));
- _listener.assertNoErrors();
- }
-
test_visitPostfixExpression() async {
InterfaceType numType = _typeProvider.numType;
SimpleIdentifier operand = AstTestFactory.identifier3("i");
@@ -1290,8 +1265,7 @@
@override
void setUp() {
- AnalysisOptionsImpl options = new AnalysisOptionsImpl()
- ..previewDart2 = true;
+ AnalysisOptionsImpl options = new AnalysisOptionsImpl();
resetWith(options: options);
}
diff --git a/pkg/analyzer/test/generated/hint_code_test.dart b/pkg/analyzer/test/generated/hint_code_test.dart
index bcf3bad..18e26cc 100644
--- a/pkg/analyzer/test/generated/hint_code_test.dart
+++ b/pkg/analyzer/test/generated/hint_code_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -106,11 +106,7 @@
n(void f(int i)) {}
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
- } else {
- assertErrors(source, [HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
- }
+ assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
verify([source]);
}
@@ -129,11 +125,7 @@
}
n(int i) {}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
- } else {
- assertErrors(source, [HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
- }
+ assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
verify([source]);
}
@@ -1099,11 +1091,7 @@
var v = (x / y).toInt();
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertNoErrors(source);
- } else {
- assertErrors(source, [HintCode.DIVISION_OPTIMIZATION]);
- }
+ assertNoErrors(source);
verify([source]);
}
@@ -1395,11 +1383,7 @@
}
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
- } else {
- assertErrors(source, [HintCode.INVALID_ASSIGNMENT]);
- }
+ assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
verify([source]);
}
@@ -1411,11 +1395,7 @@
}
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
- } else {
- assertErrors(source, [HintCode.INVALID_ASSIGNMENT]);
- }
+ assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
verify([source]);
}
@@ -1437,11 +1417,7 @@
}
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
- } else {
- assertErrors(source, [HintCode.INVALID_ASSIGNMENT]);
- }
+ assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
verify([source]);
}
@@ -1461,11 +1437,7 @@
int n = p1 + p2;
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
- } else {
- assertErrors(source, [HintCode.INVALID_ASSIGNMENT]);
- }
+ assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
verify([source]);
}
@@ -3931,11 +3903,7 @@
}
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
- } else {
- assertErrors(source, [HintCode.UNDEFINED_GETTER]);
- }
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
}
test_undefinedIdentifier_exportHide() async {
@@ -3980,38 +3948,6 @@
verify([source]);
}
- test_undefinedMethod() async {
- Source source = addSource(r'''
-f() {
- var a = 'str';
- a.notAMethodOnString();
-}''');
- await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(source, [StaticTypeWarningCode.UNDEFINED_METHOD]);
- } else {
- assertErrors(source, [HintCode.UNDEFINED_METHOD]);
- }
- }
-
- test_undefinedMethod_assignmentExpression() async {
- Source source = addSource(r'''
-class A {}
-class B {
- f(var a, var a2) {
- a = new A();
- a2 = new A();
- a += a2;
- }
-}''');
- await computeAnalysisResult(source);
- if (previewDart2) {
- assertNoErrors(source);
- } else {
- assertErrors(source, [HintCode.UNDEFINED_METHOD]);
- }
- }
-
test_undefinedOperator_binaryExpression() async {
Source source = addSource(r'''
class A {}
@@ -4021,11 +3957,7 @@
}
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
- } else {
- assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
- }
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
test_undefinedOperator_indexBoth() async {
@@ -4037,11 +3969,10 @@
}
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
- } else {
- assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
- }
+ assertErrors(source, [
+ StaticTypeWarningCode.UNDEFINED_OPERATOR,
+ StaticTypeWarningCode.UNDEFINED_OPERATOR,
+ ]);
}
test_undefinedOperator_indexGetter() async {
@@ -4053,11 +3984,7 @@
}
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
- } else {
- assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
- }
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
test_undefinedOperator_indexSetter() async {
@@ -4069,11 +3996,7 @@
}
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
- } else {
- assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
- }
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
test_undefinedOperator_postfixExpression() async {
@@ -4085,11 +4008,7 @@
}
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertNoErrors(source);
- } else {
- assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
- }
+ assertNoErrors(source);
}
test_undefinedOperator_prefixExpression() async {
@@ -4101,11 +4020,7 @@
}
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertNoErrors(source);
- } else {
- assertErrors(source, [HintCode.UNDEFINED_OPERATOR]);
- }
+ assertNoErrors(source);
}
test_undefinedSetter() async {
@@ -4117,11 +4032,7 @@
}
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(source, [StaticTypeWarningCode.UNDEFINED_SETTER]);
- } else {
- assertErrors(source, [HintCode.UNDEFINED_SETTER]);
- }
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_SETTER]);
}
test_unnecessaryCast_type_supertype() async {
diff --git a/pkg/analyzer/test/generated/inheritance_manager_test.dart b/pkg/analyzer/test/generated/inheritance_manager_test.dart
index fa5b0d4..d6def33 100644
--- a/pkg/analyzer/test/generated/inheritance_manager_test.dart
+++ b/pkg/analyzer/test/generated/inheritance_manager_test.dart
@@ -28,7 +28,7 @@
}
@reflectiveTest
-class InheritanceManagerTest extends Object with ResourceProviderMixin {
+class InheritanceManagerTest with ResourceProviderMixin {
/**
* The type provider used to access the types.
*/
diff --git a/pkg/analyzer/test/generated/non_error_resolver_driver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_driver_test.dart
index c524c9c..da8d07c 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_driver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_driver_test.dart
@@ -31,12 +31,6 @@
@override
@failingTest
- test_null_callMethod() {
- return super.test_null_callMethod();
- }
-
- @override
- @failingTest
test_null_callOperator() {
return super.test_null_callOperator();
}
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index 25ce0a7..2b881c0 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -16,7 +16,6 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'resolver_test_case.dart';
-import 'test_support.dart';
main() {
defineReflectiveSuite(() {
@@ -76,12 +75,6 @@
@override
@failingTest
- test_null_callMethod() {
- return super.test_null_callMethod();
- }
-
- @override
- @failingTest
test_null_callOperator() {
return super.test_null_callOperator();
}
@@ -307,7 +300,7 @@
}
test_argumentTypeNotAssignable_optionalNew() async {
- resetWith(options: new AnalysisOptionsImpl()..previewDart2 = true);
+ resetWith(options: new AnalysisOptionsImpl());
Source source = addSource(r'''
class Widget { }
@@ -978,220 +971,6 @@
expect(classC.documentationComment, isNotNull);
}
- test_commentReference_beforeConstructor() async {
- String code = r'''
-abstract class A {
- /// [p]
- A(int p) {}
-}''';
- Source source = addSource(code);
- TestAnalysisResult analysisResult = await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- CompilationUnit unit = analysisResult.unit;
- {
- SimpleIdentifier ref =
- EngineTestCase.findSimpleIdentifier(unit, code, "p]");
- expect(ref.staticElement, new TypeMatcher<ParameterElement>());
- }
- }
-
- test_commentReference_beforeEnum() async {
- String code = r'''
-/// This is the [Samurai] kind.
-enum Samurai {
- /// Use [int].
- WITH_SWORD,
- /// Like [WITH_SWORD], but only without one.
- WITHOUT_SWORD
-}''';
- Source source = addSource(code);
- TestAnalysisResult analysisResult = await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- CompilationUnit unit = analysisResult.unit;
- {
- SimpleIdentifier ref =
- EngineTestCase.findSimpleIdentifier(unit, code, 'Samurai]');
- ClassElement refElement = ref.staticElement;
- expect(refElement, isNotNull);
- expect(refElement.name, 'Samurai');
- }
- {
- SimpleIdentifier ref =
- EngineTestCase.findSimpleIdentifier(unit, code, 'int]');
- ClassElement refElement = ref.staticElement;
- expect(refElement, isNotNull);
- expect(refElement.name, 'int');
- }
- {
- SimpleIdentifier ref =
- EngineTestCase.findSimpleIdentifier(unit, code, 'WITH_SWORD]');
- PropertyAccessorElement refElement = ref.staticElement;
- expect(refElement, isNotNull);
- expect(refElement.name, 'WITH_SWORD');
- }
- }
-
- test_commentReference_beforeFunction_blockBody() async {
- String code = r'''
-/// [p]
-foo(int p) {
-}''';
- Source source = addSource(code);
- TestAnalysisResult analysisResult = await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- CompilationUnit unit = analysisResult.unit;
- SimpleIdentifier ref =
- EngineTestCase.findSimpleIdentifier(unit, code, 'p]');
- expect(ref.staticElement, new TypeMatcher<ParameterElement>());
- }
-
- test_commentReference_beforeFunction_expressionBody() async {
- String code = r'''
-/// [p]
-foo(int p) => null;''';
- Source source = addSource(code);
- TestAnalysisResult analysisResult = await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- CompilationUnit unit = analysisResult.unit;
- SimpleIdentifier ref =
- EngineTestCase.findSimpleIdentifier(unit, code, 'p]');
- expect(ref.staticElement, new TypeMatcher<ParameterElement>());
- }
-
- test_commentReference_beforeFunctionTypeAlias() async {
- String code = r'''
-/// [p]
-typedef Foo(int p);
-''';
- Source source = addSource(code);
- TestAnalysisResult analysisResult = await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- CompilationUnit unit = analysisResult.unit;
- SimpleIdentifier ref =
- EngineTestCase.findSimpleIdentifier(unit, code, 'p]');
- expect(ref.staticElement, new TypeMatcher<ParameterElement>());
- }
-
- test_commentReference_beforeGenericTypeAlias() async {
- String code = r'''
-/// Can resolve [T], [S], and [p].
-typedef Foo<T> = Function<S>(int p);
-''';
- Source source = addSource(code);
- TestAnalysisResult analysisResult = await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- CompilationUnit unit = analysisResult.unit;
-
- Element getElement(String search) {
- return EngineTestCase.findSimpleIdentifier(unit, code, search)
- .staticElement;
- }
-
- expect(getElement('T]'), new TypeMatcher<TypeParameterElement>());
- expect(getElement('S]'), new TypeMatcher<TypeParameterElement>());
- expect(getElement('p]'), new TypeMatcher<ParameterElement>());
- }
-
- test_commentReference_beforeGetter() async {
- String code = r'''
-abstract class A {
- /// [int]
- get g => null;
-}''';
- Source source = addSource(code);
- TestAnalysisResult analysisResult = await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- CompilationUnit unit = analysisResult.unit;
- {
- SimpleIdentifier ref =
- EngineTestCase.findSimpleIdentifier(unit, code, 'int]');
- expect(ref.staticElement, isNotNull);
- }
- }
-
- test_commentReference_beforeMethod() async {
- String code = r'''
-abstract class A {
- /// [p1]
- ma(int p1) {}
- /// [p2]
- mb(int p2);
- /// [p3] and [p4]
- mc(int p3, p4());
- /// [p5]
- md(int p5, {int p6});
-}''';
- Source source = addSource(code);
- TestAnalysisResult analysisResult = await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- CompilationUnit unit = analysisResult.unit;
- assertIsParameter(String search) {
- SimpleIdentifier ref =
- EngineTestCase.findSimpleIdentifier(unit, code, search);
- expect(ref.staticElement, new TypeMatcher<ParameterElement>());
- }
-
- assertIsParameter('p1');
- assertIsParameter('p2');
- assertIsParameter('p3');
- assertIsParameter('p4');
- assertIsParameter('p5');
- assertIsParameter('p6');
- }
-
- test_commentReference_class() async {
- String code = r'''
-/// [foo]
-class A {
- foo() {}
-}''';
- Source source = addSource(code);
- TestAnalysisResult analysisResult = await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- CompilationUnit unit = analysisResult.unit;
- SimpleIdentifier ref =
- EngineTestCase.findSimpleIdentifier(unit, code, 'foo]');
- expect(ref.staticElement, new TypeMatcher<MethodElement>());
- }
-
- test_commentReference_setter() async {
- String code = r'''
-class A {
- /// [x] in A
- mA() {}
- set x(value) {}
-}
-class B extends A {
- /// [x] in B
- mB() {}
-}
-''';
- Source source = addSource(code);
- TestAnalysisResult analysisResult = await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- CompilationUnit unit = analysisResult.unit;
- {
- SimpleIdentifier ref =
- EngineTestCase.findSimpleIdentifier(unit, code, "x] in A");
- expect(ref.staticElement, new TypeMatcher<PropertyAccessorElement>());
- }
- {
- SimpleIdentifier ref =
- EngineTestCase.findSimpleIdentifier(unit, code, 'x] in B');
- expect(ref.staticElement, new TypeMatcher<PropertyAccessorElement>());
- }
- }
-
test_concreteClassWithAbstractMember() async {
Source source = addSource(r'''
abstract class A {
@@ -2864,7 +2643,6 @@
}
test_intLiteralInDoubleContext_const_exact() async {
- // TODO(mfairhurst): get the commented out assertions to pass.
Source source = addSource(r'''
class C {
const C(double x)
@@ -3450,86 +3228,6 @@
verify([source]);
}
- test_invocationOfNonFunction_dynamic() async {
- Source source = addSource(r'''
-class A {
- var f;
-}
-class B extends A {
- g() {
- f();
- }
-}''');
- await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- test_invocationOfNonFunction_functionTypeTypeParameter() async {
- Source source = addSource(r'''
-typedef void Action<T>(T x);
-class C<T, U extends Action<T>> {
- T value;
- U action;
- C(this.value, [this.action]);
- void act() {
- action(value);
- }
-}
-''');
- await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- test_invocationOfNonFunction_getter() async {
- Source source = addSource(r'''
-class A {
- var g;
-}
-f() {
- A a;
- a.g();
-}''');
- await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- test_invocationOfNonFunction_localVariable() async {
- Source source = addSource(r'''
-f() {
- var g;
- g();
-}''');
- await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- test_invocationOfNonFunction_localVariable_dynamic() async {
- Source source = addSource(r'''
-f() {}
-main() {
- var v = f;
- v();
-}''');
- await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- test_invocationOfNonFunction_Object() async {
- Source source = addSource(r'''
-main() {
- Object v = null;
- v();
-}''');
- await computeAnalysisResult(source);
- assertErrors(source, [StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION]);
- verify([source]);
- }
-
Future test_issue32114() async {
addNamedSource('/a.dart', '''
class O {}
@@ -4795,15 +4493,6 @@
verify([source]);
}
- test_null_callMethod() async {
- Source source = addSource(r'''
-main() {
- null.m();
-}''');
- await computeAnalysisResult(source);
- assertErrors(source, [StaticTypeWarningCode.UNDEFINED_METHOD]);
- }
-
test_null_callOperator() async {
Source source = addSource(r'''
main() {
@@ -4819,7 +4508,7 @@
}
test_optionalNew_rewrite() async {
- resetWith(options: new AnalysisOptionsImpl()..previewDart2 = true);
+ resetWith(options: new AnalysisOptionsImpl());
Source source = addSource(r'''
import 'b.dart';
main() {
@@ -4859,7 +4548,7 @@
}
test_optionalNew_rewrite_instantiatesToBounds() async {
- resetWith(options: new AnalysisOptionsImpl()..previewDart2 = true);
+ resetWith(options: new AnalysisOptionsImpl());
Source source = addSource(r'''
import 'b.dart';
@@ -5156,6 +4845,16 @@
verify([source]);
}
+ test_regress34906() async {
+ Source source = addSource(r'''
+typedef G<X, Y extends Function(X)> = X Function(Function(Y));
+G<dynamic, Function(Null)> superBoundedG;
+''');
+ await computeAnalysisResult(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
test_rethrowOutsideCatch() async {
Source source = addSource(r'''
class A {
@@ -6078,20 +5777,6 @@
verify([source]);
}
- test_unqualifiedReferenceToNonLocalStaticMember_fromComment_new() async {
- Source source = addSource(r'''
-class A {
- A() {}
- A.named() {}
-}
-/// [new A] or [new A.named]
-main() {
-}''');
- await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- }
-
test_unusedShownName_unresolved() async {
Source source = addSource(r'''
import 'dart:math' show max, FooBar;
diff --git a/pkg/analyzer/test/generated/non_hint_code_test.dart b/pkg/analyzer/test/generated/non_hint_code_test.dart
index b6053b6..962865a 100644
--- a/pkg/analyzer/test/generated/non_hint_code_test.dart
+++ b/pkg/analyzer/test/generated/non_hint_code_test.dart
@@ -700,14 +700,10 @@
int c;
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(
- source,
- [CompileTimeErrorCode.INVALID_OVERRIDE],
- );
- } else {
- assertNoErrors(source);
- }
+ assertErrors(
+ source,
+ [CompileTimeErrorCode.INVALID_OVERRIDE],
+ );
verify([source]);
}
@@ -727,14 +723,10 @@
int c;
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(
- source,
- [CompileTimeErrorCode.INVALID_OVERRIDE],
- );
- } else {
- assertNoErrors(source);
- }
+ assertErrors(
+ source,
+ [CompileTimeErrorCode.INVALID_OVERRIDE],
+ );
verify([source]);
}
@@ -943,11 +935,7 @@
}
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
- } else {
- assertNoErrors(source);
- }
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
}
test_undefinedMethod_assignmentExpression_inSubtype() async {
@@ -975,24 +963,6 @@
assertNoErrors(source);
}
- test_undefinedMethod_inSubtype() async {
- Source source = addSource(r'''
-class A {}
-class B extends A {
- b() {}
-}
-f() {
- var a = new A();
- a.b();
-}''');
- await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(source, [StaticTypeWarningCode.UNDEFINED_METHOD]);
- } else {
- assertNoErrors(source);
- }
- }
-
test_undefinedMethod_unionType_all() async {
Source source = addSource(r'''
class A {
@@ -1045,11 +1015,7 @@
}
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
- } else {
- assertNoErrors(source);
- }
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
test_undefinedOperator_indexBoth_inSubtype() async {
@@ -1064,11 +1030,10 @@
}
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
- } else {
- assertNoErrors(source);
- }
+ assertErrors(source, [
+ StaticTypeWarningCode.UNDEFINED_OPERATOR,
+ StaticTypeWarningCode.UNDEFINED_OPERATOR,
+ ]);
}
test_undefinedOperator_indexGetter_inSubtype() async {
@@ -1083,11 +1048,7 @@
}
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
- } else {
- assertNoErrors(source);
- }
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
test_undefinedOperator_indexSetter_inSubtype() async {
@@ -1102,11 +1063,7 @@
}
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
- } else {
- assertNoErrors(source);
- }
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
}
test_undefinedOperator_postfixExpression() async {
@@ -1151,11 +1108,7 @@
}
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(source, [StaticTypeWarningCode.UNDEFINED_SETTER]);
- } else {
- assertNoErrors(source);
- }
+ assertErrors(source, [StaticTypeWarningCode.UNDEFINED_SETTER]);
}
test_unnecessaryCast_13855_parameter_A() async {
@@ -1236,7 +1189,7 @@
(c ? f(): new Future.value(0) as Future<int>).then((int value) {});
}''');
await computeAnalysisResult(source);
- if (previewDart2 && enableNewAnalysisDriver) {
+ if (enableNewAnalysisDriver) {
assertErrors(source, [HintCode.UNNECESSARY_CAST]);
} else {
assertNoErrors(source);
diff --git a/pkg/analyzer/test/generated/package_test.dart b/pkg/analyzer/test/generated/package_test.dart
deleted file mode 100644
index 1921f63..0000000
--- a/pkg/analyzer/test/generated/package_test.dart
+++ /dev/null
@@ -1,261 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/exception/exception.dart';
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/package.dart';
-import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:package_config/packages.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../src/context/mock_sdk.dart';
-import 'resolver_test_case.dart';
-
-main() {
- defineReflectiveSuite(() {
- defineReflectiveTests(DependencyFinderTest);
- defineReflectiveTests(PackageDescriptionTest);
- defineReflectiveTests(PackageManagerTest);
- });
-}
-
-/**
- * The name of the pubspec.yaml file.
- */
-const String pubspecName = 'pubspec.yaml';
-
-@reflectiveTest
-class DependencyFinderTest extends ResolverTestCase {
- void test_transitiveDependenciesFor_circularDependencies() {
- var pathContext = resourceProvider.pathContext;
- String packageA = resourceProvider.convertPath('/pub-cache/a-1.0');
- String packageB = resourceProvider.convertPath('/pub-cache/b-1.0');
- String packageC = resourceProvider.convertPath('/pub-cache/c-1.0');
- resourceProvider.newFile(pathContext.join(packageA, pubspecName), '''
- dependencies:
- b: any
- ''');
- resourceProvider.newFile(pathContext.join(packageB, pubspecName), '''
- dependencies:
- c: any
- ''');
- resourceProvider.newFile(pathContext.join(packageC, pubspecName), '''
- dependencies:
- a: any
- ''');
- Map<String, List<Folder>> packageMap = <String, List<Folder>>{
- 'a': <Folder>[resourceProvider.getFolder(packageA)],
- 'b': <Folder>[resourceProvider.getFolder(packageB)],
- 'c': <Folder>[resourceProvider.getFolder(packageC)],
- };
-
- DependencyFinder finder = new DependencyFinder(resourceProvider);
- List<String> result =
- finder.transitiveDependenciesFor(packageMap, packageA);
- expect(result, unorderedEquals([packageB, packageC]));
- }
-
- void test_transitiveDependenciesFor_missingPubspec() {
- String packagePath = resourceProvider.convertPath('/pub-cache/a-1.0');
- Map<String, List<Folder>> packageMap = <String, List<Folder>>{
- 'a': <Folder>[resourceProvider.getFolder(packagePath)]
- };
-
- DependencyFinder finder = new DependencyFinder(resourceProvider);
- expect(() => finder.transitiveDependenciesFor(packageMap, packagePath),
- throwsA(new TypeMatcher<AnalysisException>()));
- }
-
- void test_transitiveDependenciesFor_noDependencies() {
- var pathContext = resourceProvider.pathContext;
- String packagePath = resourceProvider.convertPath('/pub-cache/a-1.0');
- resourceProvider.newFile(pathContext.join(packagePath, pubspecName), '');
- Map<String, List<Folder>> packageMap = <String, List<Folder>>{
- 'a': <Folder>[resourceProvider.getFolder(packagePath)]
- };
-
- DependencyFinder finder = new DependencyFinder(resourceProvider);
- List<String> result =
- finder.transitiveDependenciesFor(packageMap, packagePath);
- expect(result, hasLength(0));
- }
-
- void test_transitiveDependenciesFor_overlappingDependencies() {
- var pathContext = resourceProvider.pathContext;
- String packageA = resourceProvider.convertPath('/pub-cache/a-1.0');
- String packageB = resourceProvider.convertPath('/pub-cache/b-1.0');
- String packageC = resourceProvider.convertPath('/pub-cache/c-1.0');
- String packageD = resourceProvider.convertPath('/pub-cache/d-1.0');
- resourceProvider.newFile(pathContext.join(packageA, pubspecName), '''
- dependencies:
- b: any
- c: any
- ''');
- resourceProvider.newFile(pathContext.join(packageB, pubspecName), '''
- dependencies:
- d: any
- ''');
- resourceProvider.newFile(pathContext.join(packageC, pubspecName), '''
- dependencies:
- d: any
- ''');
- resourceProvider.newFile(pathContext.join(packageD, pubspecName), '');
- Map<String, List<Folder>> packageMap = <String, List<Folder>>{
- 'a': <Folder>[resourceProvider.getFolder(packageA)],
- 'b': <Folder>[resourceProvider.getFolder(packageB)],
- 'c': <Folder>[resourceProvider.getFolder(packageC)],
- 'd': <Folder>[resourceProvider.getFolder(packageD)],
- };
-
- DependencyFinder finder = new DependencyFinder(resourceProvider);
- List<String> result =
- finder.transitiveDependenciesFor(packageMap, packageA);
- expect(result, unorderedEquals([packageB, packageC, packageD]));
- }
-
- void test_transitiveDependenciesFor_simpleDependencies() {
- var pathContext = resourceProvider.pathContext;
- String packageA = resourceProvider.convertPath('/pub-cache/a-1.0');
- String packageB = resourceProvider.convertPath('/pub-cache/b-1.0');
- String packageC = resourceProvider.convertPath('/pub-cache/c-1.0');
- resourceProvider.newFile(pathContext.join(packageA, pubspecName), '''
- dependencies:
- b: any
- c: any
- ''');
- resourceProvider.newFile(pathContext.join(packageB, pubspecName), '');
- resourceProvider.newFile(pathContext.join(packageC, pubspecName), '');
- Map<String, List<Folder>> packageMap = <String, List<Folder>>{
- 'a': <Folder>[resourceProvider.getFolder(packageA)],
- 'b': <Folder>[resourceProvider.getFolder(packageB)],
- 'c': <Folder>[resourceProvider.getFolder(packageC)],
- };
-
- DependencyFinder finder = new DependencyFinder(resourceProvider);
- List<String> result =
- finder.transitiveDependenciesFor(packageMap, packageA);
- expect(result, unorderedEquals([packageB, packageC]));
- }
-}
-
-@reflectiveTest
-class PackageDescriptionTest extends ResolverTestCase {
- void test_equal_false_differentOptions() {
- String packageId = 'path1;path2';
- DartSdk sdk = new MockSdk();
- AnalysisOptionsImpl options1 = new AnalysisOptionsImpl();
- AnalysisOptionsImpl options2 = new AnalysisOptionsImpl();
- options2.enableLazyAssignmentOperators =
- !options1.enableLazyAssignmentOperators;
- PackageDescription first = new PackageDescription(packageId, sdk, options1);
- PackageDescription second =
- new PackageDescription(packageId, sdk, options2);
- expect(first == second, isFalse);
- }
-
- void test_equal_false_differentPaths() {
- String packageId1 = 'path1;path2';
- String packageId2 = 'path1;path3';
- DartSdk sdk = new MockSdk();
- AnalysisOptions options = new AnalysisOptionsImpl();
- PackageDescription first = new PackageDescription(packageId1, sdk, options);
- PackageDescription second =
- new PackageDescription(packageId2, sdk, options);
- expect(first == second, isFalse);
- }
-
- void test_equal_false_differentSdks() {
- String packageId = 'path1;path2';
- DartSdk sdk1 = new MockSdk();
- DartSdk sdk2 = new MockSdk();
- AnalysisOptions options = new AnalysisOptionsImpl();
- PackageDescription first = new PackageDescription(packageId, sdk1, options);
- PackageDescription second =
- new PackageDescription(packageId, sdk2, options);
- expect(first == second, isFalse);
- }
-
- void test_equal_true() {
- String packageId = 'path1;path2';
- DartSdk sdk = new MockSdk();
- AnalysisOptions options = new AnalysisOptionsImpl();
- PackageDescription first = new PackageDescription(packageId, sdk, options);
- PackageDescription second = new PackageDescription(packageId, sdk, options);
- expect(first == second, isTrue);
- }
-}
-
-@reflectiveTest
-class PackageManagerTest extends ResolverTestCase {
- void test_getContext() {
- var pathContext = resourceProvider.pathContext;
- String packageA = resourceProvider.convertPath('/pub-cache/a-1.0');
- String packageB1 = resourceProvider.convertPath('/pub-cache/b-1.0');
- String packageB2 = resourceProvider.convertPath('/pub-cache/b-2.0');
- String packageC = resourceProvider.convertPath('/pub-cache/c-1.0');
- resourceProvider.newFile(pathContext.join(packageA, pubspecName), '''
- dependencies:
- b: any
- c: any
- ''');
- resourceProvider.newFile(pathContext.join(packageB1, pubspecName), '');
- resourceProvider.newFile(pathContext.join(packageB2, pubspecName), '');
- resourceProvider.newFile(pathContext.join(packageC, pubspecName), '');
-
- Packages packages1 = new _MockPackages(<String, Uri>{
- 'a': pathContext.toUri(packageA),
- 'b': pathContext.toUri(packageB1),
- 'c': pathContext.toUri(packageC),
- });
- DartUriResolver resolver = new DartUriResolver(new MockSdk());
- AnalysisOptions options = new AnalysisOptionsImpl();
- //
- // Verify that we can compute a context for a package.
- //
- PackageManager manager = new PackageManager(resourceProvider);
- AnalysisContext context1 =
- manager.getContext(packageA, packages1, resolver, options);
- expect(context1, isNotNull);
- //
- // Verify that if we have the same package map we get the same context.
- //
- AnalysisContext context2 =
- manager.getContext(packageA, packages1, resolver, options);
- expect(context2, same(context1));
- //
- // Verify that if we have a different package map we get a different context.
- //
- Packages packages3 = new _MockPackages(<String, Uri>{
- 'a': pathContext.toUri(packageA),
- 'b': pathContext.toUri(packageB2),
- 'c': pathContext.toUri(packageC),
- });
- AnalysisContext context3 =
- manager.getContext(packageA, packages3, resolver, options);
- expect(context3, isNot(same(context1)));
- }
-}
-
-/**
- * An implementation of [Packages] used for testing.
- */
-class _MockPackages implements Packages {
- final Map<String, Uri> map;
-
- _MockPackages(this.map);
-
- @override
- Iterable<String> get packages => map.keys;
-
- @override
- Map<String, Uri> asMap() => map;
-
- @override
- Uri resolve(Uri packageUri, {Uri notFound(Uri packageUri)}) {
- fail('Unexpected invocation of resolve');
- }
-}
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index 2e121cc..055692f 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// 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.
@@ -14,9 +14,9 @@
import 'package:analyzer/src/generated/parser.dart' as analyzer;
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/string_source.dart';
+import 'package:front_end/src/fasta/parser/parser.dart' as fasta;
import 'package:front_end/src/fasta/scanner.dart'
show ScannerResult, scanString;
-import 'package:front_end/src/fasta/parser/parser.dart' as fasta;
import 'package:front_end/src/fasta/scanner/error_token.dart' show ErrorToken;
import 'package:front_end/src/fasta/scanner/string_scanner.dart';
import 'package:front_end/src/scanner/errors.dart' show translateErrorToken;
@@ -190,13 +190,140 @@
// Actual: TokenType:<MINUS_MINUS>
super.test_parseUnaryExpression_decrement_super_withComment();
}
+
+ void test_mapLiteral() {
+ MapLiteral map = parseExpression('{3: 6}', parseSetLiterals: true);
+ expect(map.constKeyword, isNull);
+ expect(map.typeArguments, isNull);
+ expect(map.entries, hasLength(1));
+ MapLiteralEntry entry = map.entries[0];
+ IntegerLiteral key = entry.key;
+ expect(key.value, 3);
+ IntegerLiteral value = entry.value;
+ expect(value.value, 6);
+ }
+
+ void test_mapLiteral_const() {
+ MapLiteral map = parseExpression('const {3: 6}', parseSetLiterals: true);
+ expect(map.constKeyword, isNotNull);
+ expect(map.typeArguments, isNull);
+ expect(map.entries, hasLength(1));
+ MapLiteralEntry entry = map.entries[0];
+ IntegerLiteral key = entry.key;
+ expect(key.value, 3);
+ IntegerLiteral value = entry.value;
+ expect(value.value, 6);
+ }
+
+ void test_setLiteral() {
+ SetLiteral set = parseExpression('{3}', parseSetLiterals: true);
+ expect(set.constKeyword, isNull);
+ expect(set.typeArguments, isNull);
+ expect(set.elements, hasLength(1));
+ IntegerLiteral value = set.elements[0];
+ expect(value.value, 3);
+ }
+
+ void test_setLiteral_const() {
+ SetLiteral set = parseExpression('const {3, 6}', parseSetLiterals: true);
+ expect(set.constKeyword, isNotNull);
+ expect(set.typeArguments, isNull);
+ expect(set.elements, hasLength(2));
+ IntegerLiteral value1 = set.elements[0];
+ expect(value1.value, 3);
+ IntegerLiteral value2 = set.elements[1];
+ expect(value2.value, 6);
+ }
+
+ void test_setLiteral_const_typeArgument() {
+ SetLiteral set = parseExpression('const <int>{3}', parseSetLiterals: true);
+ expect(set.constKeyword, isNotNull);
+ expect(set.typeArguments.arguments, hasLength(1));
+ NamedType typeArg = set.typeArguments.arguments[0];
+ expect(typeArg.name.name, 'int');
+ expect(set.elements.length, 1);
+ IntegerLiteral value = set.elements[0];
+ expect(value.value, 3);
+ }
+
+ void test_setLiteral_invalid_map_entry() {
+ parseExpression('<int>{1: 1}', parseSetLiterals: true, errors: [
+ expectedError(ParserErrorCode.EXPECTED_TOKEN, 7, 1),
+ ]);
+ }
+
+ @failingTest
+ void test_setLiteral_invalid_too_many_type_arguments1() {
+ parseExpression('<int, int, int>{}', parseSetLiterals: true, errors: [
+ // TODO(danrubel): Currently the resolver reports invalid number of
+ // type arguments, but the parser could report this.
+ expectedError(
+ /* ParserErrorCode.EXPECTED_ONE_TYPE_VARIABLE */
+ ParserErrorCode.EXPECTED_TOKEN,
+ 15,
+ 1),
+ ]);
+ }
+
+ @failingTest
+ void test_setLiteral_invalid_too_many_type_arguments2() {
+ parseExpression('<int, int, int>{1}', parseSetLiterals: true, errors: [
+ // TODO(danrubel): Currently the resolver reports invalid number of
+ // type arguments, but the parser could report this.
+ expectedError(
+ /* ParserErrorCode.EXPECTED_ONE_TYPE_VARIABLE */
+ ParserErrorCode.EXPECTED_TOKEN,
+ 15,
+ 1),
+ ]);
+ }
+
+ @failingTest
+ void test_setLiteral_invalid_too_many_type_arguments3() {
+ parseExpression('<int, int>{1}', parseSetLiterals: true, errors: [
+ // TODO(danrubel): Currently the resolver reports invalid number of
+ // type arguments, but the parser could report this.
+ expectedError(
+ /* ParserErrorCode.EXPECTED_ONE_TYPE_VARIABLE */
+ ParserErrorCode.EXPECTED_TOKEN,
+ 10,
+ 1),
+ ]);
+ }
+
+ void test_setLiteral_nested_typeArgument() {
+ SetLiteral set = parseExpression('<Set<int>>{{3}}', parseSetLiterals: true);
+ expect(set.constKeyword, isNull);
+ expect(set.typeArguments.arguments, hasLength(1));
+ NamedType typeArg1 = set.typeArguments.arguments[0];
+ expect(typeArg1.name.name, 'Set');
+ expect(typeArg1.typeArguments.arguments, hasLength(1));
+ NamedType typeArg2 = typeArg1.typeArguments.arguments[0];
+ expect(typeArg2.name.name, 'int');
+ expect(set.elements.length, 1);
+ SetLiteral intSet = set.elements[0];
+ expect(intSet.elements, hasLength(1));
+ IntegerLiteral value = intSet.elements[0];
+ expect(value.value, 3);
+ }
+
+ void test_setLiteral_typeArgument() {
+ SetLiteral set = parseExpression('<int>{3}', parseSetLiterals: true);
+ expect(set.constKeyword, isNull);
+ expect(set.typeArguments.arguments, hasLength(1));
+ NamedType typeArg = set.typeArguments.arguments[0];
+ expect(typeArg.name.name, 'int');
+ expect(set.elements.length, 1);
+ IntegerLiteral value = set.elements[0];
+ expect(value.value, 3);
+ }
}
/**
* Implementation of [AbstractParserTestCase] specialized for testing the
* Fasta parser.
*/
-class FastaParserTestCase extends Object
+class FastaParserTestCase
with ParserTestHelpers
implements AbstractParserTestCase {
static final List<ErrorCode> NO_ERROR_COMPARISON = <ErrorCode>[];
@@ -446,8 +573,10 @@
Expression parseExpression(String source,
{List<ErrorCode> codes,
List<ExpectedError> errors,
- int expectedEndOffset}) {
+ int expectedEndOffset,
+ bool parseSetLiterals = false}) {
createParser(source, expectedEndOffset: expectedEndOffset);
+ _parserProxy.fastaParser.parseSetLiterals = parseSetLiterals;
Expression result = _parserProxy.parseExpression2();
assertErrors(codes: codes, errors: errors);
return result;
@@ -900,6 +1029,15 @@
@reflectiveTest
class RecoveryParserTest_Fasta extends FastaParserTestCase
with RecoveryParserTestMixin {
+ @override
+ void test_equalityExpression_precedence_relational_right() {
+ parseExpression("== is", codes: [
+ ParserErrorCode.EXPECTED_TYPE_NAME,
+ ParserErrorCode.MISSING_IDENTIFIER,
+ ParserErrorCode.MISSING_IDENTIFIER
+ ]);
+ }
+
void test_invalidTypeParameters_super() {
parseCompilationUnit('class C<X super Y> {}', errors: [
// TODO(danrubel): Improve recovery.
@@ -916,15 +1054,6 @@
}
@override
- void test_equalityExpression_precedence_relational_right() {
- parseExpression("== is", codes: [
- ParserErrorCode.EXPECTED_TYPE_NAME,
- ParserErrorCode.MISSING_IDENTIFIER,
- ParserErrorCode.MISSING_IDENTIFIER
- ]);
- }
-
- @override
void test_relationalExpression_missing_LHS_RHS() {
parseExpression("is", codes: [
ParserErrorCode.EXPECTED_TYPE_NAME,
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index db03ec1..2c4ce93 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -251,7 +251,7 @@
* Instances of the class `AstValidator` are used to validate the correct construction of an
* AST structure.
*/
-class AstValidator extends UnifyingAstVisitor<Object> {
+class AstValidator extends UnifyingAstVisitor<void> {
/**
* A list containing the errors found while traversing the AST structure.
*/
@@ -274,9 +274,9 @@
}
@override
- Object visitNode(AstNode node) {
+ void visitNode(AstNode node) {
_validate(node);
- return super.visitNode(node);
+ super.visitNode(node);
}
/**
@@ -335,7 +335,7 @@
/**
* Tests which exercise the parser using a class member.
*/
-abstract class ClassMemberParserTestMixin implements AbstractParserTestCase {
+mixin ClassMemberParserTestMixin implements AbstractParserTestCase {
void test_parseAwaitExpression_asStatement_inAsync() {
createParser('m() async { await x; }');
ClassMember member = parser.parseClassMember('C');
@@ -1771,7 +1771,7 @@
*
* Simpler tests should be defined in the class [SimpleParserTest].
*/
-abstract class ComplexParserTestMixin implements AbstractParserTestCase {
+mixin ComplexParserTestMixin implements AbstractParserTestCase {
void test_additiveExpression_normal() {
BinaryExpression expression = parseExpression("x + y - z");
EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
@@ -2260,7 +2260,7 @@
}
}
-abstract class ErrorParserTestMixin implements AbstractParserTestCase {
+mixin ErrorParserTestMixin implements AbstractParserTestCase {
void test_abstractClassMember_constructor() {
createParser('abstract C.c();');
ClassMember member = parser.parseClassMember('C');
@@ -5733,7 +5733,7 @@
class ExpressionParserTest extends ParserTestCase
with ExpressionParserTestMixin {}
-abstract class ExpressionParserTestMixin implements AbstractParserTestCase {
+mixin ExpressionParserTestMixin implements AbstractParserTestCase {
void test_namedArgument() {
var invocation = parseExpression('m(a: 1, b: 2)') as MethodInvocation;
List<Expression> arguments = invocation.argumentList.arguments;
@@ -8048,8 +8048,7 @@
* The class [FormalParameterParserTestMixin] defines parser tests that test
* the parsing of formal parameters.
*/
-abstract class FormalParameterParserTestMixin
- implements AbstractParserTestCase {
+mixin FormalParameterParserTestMixin implements AbstractParserTestCase {
void test_parseConstructorParameter_this() {
parseCompilationUnit('''
class C {
@@ -9943,7 +9942,7 @@
*
* Intended to be mixed in to parser test case classes.
*/
-class ParserTestHelpers {
+mixin ParserTestHelpers {
void expectCommentText(Comment comment, String expectedText) {
expect(comment.beginToken, same(comment.endToken));
expect(comment.beginToken.lexeme, expectedText);
@@ -9972,7 +9971,7 @@
* invalid code sequences to ensure that the correct recovery steps are taken in
* the parser.
*/
-abstract class RecoveryParserTestMixin implements AbstractParserTestCase {
+mixin RecoveryParserTestMixin implements AbstractParserTestCase {
void test_additiveExpression_missing_LHS() {
BinaryExpression expression =
parseExpression("+ y", codes: [ParserErrorCode.MISSING_IDENTIFIER]);
@@ -12540,7 +12539,7 @@
*
* More complex tests should be defined in the class [ComplexParserTest].
*/
-abstract class SimpleParserTestMixin implements AbstractParserTestCase {
+mixin SimpleParserTestMixin implements AbstractParserTestCase {
ConstructorName parseConstructorName(String name) {
createParser('new $name();');
Statement statement = parser.parseStatement2();
@@ -14494,7 +14493,7 @@
* The class [FormalParameterParserTestMixin] defines parser tests that test
* the parsing statements.
*/
-abstract class StatementParserTestMixin implements AbstractParserTestCase {
+mixin StatementParserTestMixin implements AbstractParserTestCase {
void test_invalid_typeParamAnnotation() {
parseCompilationUnit('main() { C<@Foo T> v; }',
errors: usingFastaParser
@@ -15870,7 +15869,7 @@
* Tests which exercise the parser using a complete compilation unit or
* compilation unit member.
*/
-abstract class TopLevelParserTestMixin implements AbstractParserTestCase {
+mixin TopLevelParserTestMixin implements AbstractParserTestCase {
void test_function_literal_allowed_at_toplevel() {
parseCompilationUnit("var x = () {};");
}
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index 2c0bdfd..0558400 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -413,7 +413,7 @@
* Instances of the class `StaticTypeVerifier` verify that all of the nodes in an AST
* structure that should have a static type associated with them do have a static type.
*/
-class StaticTypeVerifier extends GeneralizingAstVisitor<Object> {
+class StaticTypeVerifier extends GeneralizingAstVisitor<void> {
/**
* A list containing all of the AST Expression nodes that were not resolved.
*/
@@ -479,19 +479,19 @@
}
@override
- Object visitBreakStatement(BreakStatement node) => null;
+ void visitBreakStatement(BreakStatement node) {}
@override
- Object visitCommentReference(CommentReference node) => null;
+ void visitCommentReference(CommentReference node) {}
@override
- Object visitContinueStatement(ContinueStatement node) => null;
+ void visitContinueStatement(ContinueStatement node) {}
@override
- Object visitExportDirective(ExportDirective node) => null;
+ void visitExportDirective(ExportDirective node) {}
@override
- Object visitExpression(Expression node) {
+ void visitExpression(Expression node) {
node.visitChildren(this);
DartType staticType = node.staticType;
if (staticType == null) {
@@ -499,66 +499,65 @@
} else {
_resolvedExpressionCount++;
}
- return null;
}
@override
- Object visitImportDirective(ImportDirective node) => null;
+ void visitImportDirective(ImportDirective node) {}
@override
- Object visitLabel(Label node) => null;
+ void visitLabel(Label node) {}
@override
- Object visitLibraryIdentifier(LibraryIdentifier node) => null;
+ void visitLibraryIdentifier(LibraryIdentifier node) {}
@override
- Object visitPrefixedIdentifier(PrefixedIdentifier node) {
+ void visitPrefixedIdentifier(PrefixedIdentifier node) {
// In cases where we have a prefixed identifier where the prefix is dynamic,
// we don't want to assert that the node will have a type.
if (node.staticType == null &&
resolutionMap.staticTypeForExpression(node.prefix).isDynamic) {
- return null;
+ return;
}
- return super.visitPrefixedIdentifier(node);
+ super.visitPrefixedIdentifier(node);
}
@override
- Object visitSimpleIdentifier(SimpleIdentifier node) {
+ void visitSimpleIdentifier(SimpleIdentifier node) {
// In cases where identifiers are being used for something other than an
// expressions, then they can be ignored.
AstNode parent = node.parent;
if (parent is MethodInvocation && identical(node, parent.methodName)) {
- return null;
+ return;
} else if (parent is RedirectingConstructorInvocation &&
identical(node, parent.constructorName)) {
- return null;
+ return;
} else if (parent is SuperConstructorInvocation &&
identical(node, parent.constructorName)) {
- return null;
+ return;
} else if (parent is ConstructorName && identical(node, parent.name)) {
- return null;
+ return;
} else if (parent is ConstructorFieldInitializer &&
identical(node, parent.fieldName)) {
- return null;
+ return;
} else if (node.staticElement is PrefixElement) {
// Prefixes don't have a type.
- return null;
+ return;
}
- return super.visitSimpleIdentifier(node);
+ super.visitSimpleIdentifier(node);
}
@override
- Object visitTypeAnnotation(TypeAnnotation node) {
+ void visitTypeAnnotation(TypeAnnotation node) {
if (node.type == null) {
_unresolvedTypes.add(node);
} else {
_resolvedTypeCount++;
}
- return super.visitTypeAnnotation(node);
+ super.visitTypeAnnotation(node);
}
@override
- Object visitTypeName(TypeName node) {
+ void visitTypeName(TypeName node) {
// Note: do not visit children from this node, the child SimpleIdentifier in
// TypeName (i.e. "String") does not have a static type defined.
// TODO(brianwilkerson) Not visiting the children means that we won't catch
@@ -568,7 +567,6 @@
} else {
_resolvedTypeCount++;
}
- return null;
}
String _getFileName(AstNode node) {
@@ -856,77 +854,6 @@
}
}
- test_functionExpression_asInvocationArgument() async {
- if (previewDart2) {
- return;
- }
- String code = r'''
-class MyMap<K, V> {
- forEach(f(K key, V value)) {}
-}
-f(MyMap<int, String> m) {
- m.forEach((k, v) {
- k;
- v;
- });
-}''';
- Source source = addSource(code);
- CompilationUnit unit = await _computeResolvedUnit(source);
- // k
- SimpleIdentifier kIdentifier = EngineTestCase.findNode(
- unit, code, "k;", (node) => node is SimpleIdentifier);
- expect(kIdentifier.staticType, typeProvider.dynamicType);
- // v
- SimpleIdentifier vIdentifier = EngineTestCase.findNode(
- unit, code, "v;", (node) => node is SimpleIdentifier);
- expect(vIdentifier.staticType, typeProvider.dynamicType);
- }
-
- test_functionExpression_asInvocationArgument_functionExpressionInvocation() async {
- if (previewDart2) {
- return;
- }
- String code = r'''
-main() {
- (f(String value)) {} ((v) {
- v;
- });
-}''';
- Source source = addSource(code);
- CompilationUnit unit = await _computeResolvedUnit(source);
- // v
- FormalParameter vParameter = EngineTestCase.findNode(
- unit, code, "v)", (node) => node is FormalParameter);
- expect(vParameter.identifier.staticType, typeProvider.dynamicType);
- SimpleIdentifier vIdentifier = EngineTestCase.findNode(
- unit, code, "v;", (node) => node is SimpleIdentifier);
- expect(vIdentifier.staticType, typeProvider.dynamicType);
- }
-
- test_functionExpression_asInvocationArgument_keepIfLessSpecific() async {
- if (previewDart2) {
- return;
- }
- String code = r'''
-class MyList {
- forEach(f(Object value)) {}
-}
-f(MyList list) {
- list.forEach((int v) {
- v;
- });
-}''';
- Source source = addSource(code);
- CompilationUnit unit = await _computeResolvedUnit(source);
- // v
- FormalParameter vParameter = EngineTestCase.findNode(
- unit, code, "v)", (node) => node is SimpleFormalParameter);
- expect(vParameter.identifier.staticType, typeProvider.intType);
- SimpleIdentifier vIdentifier = EngineTestCase.findNode(
- unit, code, "v;", (node) => node is SimpleIdentifier);
- expect(vIdentifier.staticType, typeProvider.intType);
- }
-
test_functionExpression_asInvocationArgument_notSubtypeOfStaticType() async {
String code = r'''
class A {
@@ -946,50 +873,6 @@
same(0));
}
- test_functionExpression_asInvocationArgument_replaceIfMoreSpecific() async {
- if (previewDart2) {
- return;
- }
- String code = r'''
-class MyList<E> {
- forEach(f(E value)) {}
-}
-f(MyList<String> list) {
- list.forEach((Object v) {
- v;
- });
-}''';
- Source source = addSource(code);
- CompilationUnit unit = await _computeResolvedUnit(source);
- // v
- FormalParameter vParameter = EngineTestCase.findNode(
- unit, code, "v)", (node) => node is SimpleFormalParameter);
- expect(vParameter.identifier.staticType, typeProvider.objectType);
- }
-
- test_initializer() async {
- if (previewDart2) {
- return;
- }
- Source source = addSource(r'''
-f() {
- var v = 0;
- return v;
-}''');
- CompilationUnit unit = await _computeResolvedUnit(source);
- FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
- BlockFunctionBody body =
- function.functionExpression.body as BlockFunctionBody;
- NodeList<Statement> statements = body.block.statements;
- // Type of 'v' in declaration.
- {
- VariableDeclarationStatement statement =
- statements[0] as VariableDeclarationStatement;
- SimpleIdentifier variableName = statement.variables.variables[0].name;
- expect(variableName.staticType, typeProvider.dynamicType);
- }
- }
-
test_initializer_hasStaticType() async {
Source source = addSource(r'''
f() {
@@ -1168,23 +1051,6 @@
expect(getter.staticType, typeProvider.dynamicType);
}
- test_objectAccessInference_enabled_for_cascades() async {
- if (previewDart2) {
- return;
- }
- String name = 'hashCode';
- String code = '''
-main() {
- dynamic obj;
- obj..$name..$name; // marker
-}''';
- CompilationUnit unit = await resolveSource(code);
- PropertyAccess access =
- findMarkedIdentifier(code, unit, "; // marker").parent;
- expect(access.staticType, typeProvider.dynamicType);
- expect(access.realTarget.staticType, typeProvider.dynamicType);
- }
-
test_objectMethodInference_disabled_for_library_prefix() async {
String name = 'toString';
addNamedSource('/helper.dart', '''
@@ -1223,38 +1089,6 @@
expect(methodInvoke.staticType, typeProvider.dynamicType);
}
- test_objectMethodInference_enabled_for_cascades() async {
- if (previewDart2) {
- return;
- }
- String name = 'toString';
- String code = '''
-main() {
- dynamic obj;
- obj..$name()..$name(); // marker
-}''';
- CompilationUnit unit = await resolveSource(code);
- SimpleIdentifier methodName =
- findMarkedIdentifier(code, unit, "(); // marker");
- MethodInvocation methodInvoke = methodName.parent;
-
- expect(methodInvoke.staticType, typeProvider.dynamicType);
- expect(methodInvoke.realTarget.staticType, typeProvider.dynamicType);
- }
-
- test_propagatedReturnType_localFunction() async {
- if (previewDart2) {
- return;
- }
- String code = r'''
-main() {
- f() => 42;
- var v = f();
-}''';
- CompilationUnit unit = await resolveSource(code);
- assertAssignedType(code, unit, typeProvider.dynamicType);
- }
-
/**
* Return the resolved unit for the given [source].
*
@@ -1293,6 +1127,7 @@
_classElement("Iterable", objectType, ["T"]).type;
InterfaceType listType = _classElement("List", objectType, ["E"]).type;
InterfaceType mapType = _classElement("Map", objectType, ["K", "V"]).type;
+ InterfaceType setType = _classElement("Set", objectType, ["E"]).type;
InterfaceType stackTraceType = _classElement("StackTrace", objectType).type;
InterfaceType streamType = _classElement("Stream", objectType, ["T"]).type;
InterfaceType stringType = _classElement("String", objectType).type;
@@ -1307,24 +1142,28 @@
iterableType.element,
listType.element,
mapType.element,
+ setType.element,
objectType.element,
stackTraceType.element,
stringType.element,
symbolType.element,
typeType.element
];
+ coreUnit.source = new TestSource('dart:core');
+ coreUnit.librarySource = coreUnit.source;
CompilationUnitElementImpl asyncUnit = new CompilationUnitElementImpl();
asyncUnit.types = <ClassElement>[
futureType.element,
futureOrType.element,
streamType.element
];
- AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
+ asyncUnit.source = new TestSource('dart:async');
+ asyncUnit.librarySource = asyncUnit.source;
LibraryElementImpl coreLibrary = new LibraryElementImpl.forNode(
- context, AstTestFactory.libraryIdentifier2(["dart.core"]));
+ null, null, AstTestFactory.libraryIdentifier2(["dart.core"]));
coreLibrary.definingCompilationUnit = coreUnit;
LibraryElementImpl asyncLibrary = new LibraryElementImpl.forNode(
- context, AstTestFactory.libraryIdentifier2(["dart.async"]));
+ null, null, AstTestFactory.libraryIdentifier2(["dart.async"]));
asyncLibrary.definingCompilationUnit = asyncUnit;
//
// Create a type provider and ensure that it can return the expected types.
@@ -1425,7 +1264,7 @@
resourceProvider: resourceProvider);
Source librarySource = new FileSource(getFile("/lib.dart"));
LibraryElementImpl element = new LibraryElementImpl.forNode(
- context, AstTestFactory.libraryIdentifier2(["lib"]));
+ context, null, AstTestFactory.libraryIdentifier2(["lib"]));
element.definingCompilationUnit = new CompilationUnitElementImpl();
_typeProvider = new TestTypeProvider();
libraryScope = new LibraryScope(element);
@@ -1462,7 +1301,7 @@
InternalAnalysisContext context = AnalysisContextFactory.contextWithCore(
resourceProvider: resourceProvider);
var source = getFile('/test.dart').createSource();
- var libraryElement = new LibraryElementImpl.forNode(context, null)
+ var libraryElement = new LibraryElementImpl.forNode(context, null, null)
..definingCompilationUnit = unitElement;
var libraryScope = new LibraryScope(libraryElement);
var visitor = new TypeResolverVisitor(
@@ -2332,7 +2171,7 @@
InternalAnalysisContext context = AnalysisContextFactory.contextWithCore(
resourceProvider: resourceProvider);
var source = getFile('/test.dart').createSource();
- var libraryElement = new LibraryElementImpl.forNode(context, null)
+ var libraryElement = new LibraryElementImpl.forNode(context, null, null)
..definingCompilationUnit = unitElement;
libraryScope = new LibraryScope(libraryElement);
visitor = new TypeResolverVisitor(
diff --git a/pkg/analyzer/test/generated/resolver_test_case.dart b/pkg/analyzer/test/generated/resolver_test_case.dart
index d7a954d..2c68db3 100644
--- a/pkg/analyzer/test/generated/resolver_test_case.dart
+++ b/pkg/analyzer/test/generated/resolver_test_case.dart
@@ -1,9 +1,10 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/standard_resolution_map.dart';
import 'package:analyzer/dart/ast/visitor.dart';
@@ -11,9 +12,11 @@
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
+import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/error/codes.dart';
@@ -26,11 +29,10 @@
import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
import 'package:analyzer/src/generated/testing/element_factory.dart';
import 'package:analyzer/src/source/package_map_resolver.dart';
-import 'package:analyzer/src/dart/analysis/byte_store.dart';
-import 'package:analyzer/src/dart/analysis/performance_logger.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:test/test.dart';
-import '../src/context/mock_sdk.dart';
import 'analysis_context_factory.dart';
import 'test_support.dart';
@@ -38,7 +40,7 @@
* An AST visitor used to verify that all of the nodes in an AST structure that
* should have been resolved were resolved.
*/
-class ResolutionVerifier extends RecursiveAstVisitor<Object> {
+class ResolutionVerifier extends RecursiveAstVisitor<void> {
/**
* A set containing nodes that are known to not be resolvable and should
* therefore not cause the test to fail.
@@ -88,7 +90,7 @@
}
@override
- Object visitAnnotation(Annotation node) {
+ void visitAnnotation(Annotation node) {
node.visitChildren(this);
ElementAnnotation elementAnnotation = node.elementAnnotation;
if (elementAnnotation == null) {
@@ -98,154 +100,153 @@
} else if (elementAnnotation is! ElementAnnotation) {
_wrongTypedNodes.add(node);
}
- return null;
}
@override
- Object visitBinaryExpression(BinaryExpression node) {
+ void visitBinaryExpression(BinaryExpression node) {
node.visitChildren(this);
if (!node.operator.isUserDefinableOperator) {
- return null;
+ return;
}
DartType operandType = node.leftOperand.staticType;
if (operandType == null || operandType.isDynamic) {
- return null;
+ return;
}
- return _checkResolved(
- node, node.staticElement, (node) => node is MethodElement);
+ _checkResolved(node, node.staticElement, (node) => node is MethodElement);
}
@override
- Object visitCommentReference(CommentReference node) => null;
+ void visitCommentReference(CommentReference node) {}
@override
- Object visitCompilationUnit(CompilationUnit node) {
+ void visitCompilationUnit(CompilationUnit node) {
node.visitChildren(this);
- return _checkResolved(
+ _checkResolved(
node, node.declaredElement, (node) => node is CompilationUnitElement);
}
@override
- Object visitExportDirective(ExportDirective node) =>
- _checkResolved(node, node.element, (node) => node is ExportElement);
+ void visitExportDirective(ExportDirective node) {
+ _checkResolved(node, node.element, (node) => node is ExportElement);
+ }
@override
- Object visitFunctionDeclaration(FunctionDeclaration node) {
+ void visitFunctionDeclaration(FunctionDeclaration node) {
node.visitChildren(this);
if (node.declaredElement is LibraryElement) {
_wrongTypedNodes.add(node);
}
- return null;
}
@override
- Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+ void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
node.visitChildren(this);
// TODO(brianwilkerson) If we start resolving function expressions, then
// conditionally check to see whether the node was resolved correctly.
- return null;
//checkResolved(node, node.getElement(), FunctionElement.class);
}
@override
- Object visitImportDirective(ImportDirective node) {
+ void visitImportDirective(ImportDirective node) {
// Not sure how to test the combinators given that it isn't an error if the
// names are not defined.
_checkResolved(node, node.element, (node) => node is ImportElement);
SimpleIdentifier prefix = node.prefix;
if (prefix == null) {
- return null;
+ return;
}
- return _checkResolved(
+ _checkResolved(
prefix, prefix.staticElement, (node) => node is PrefixElement);
}
@override
- Object visitIndexExpression(IndexExpression node) {
+ void visitIndexExpression(IndexExpression node) {
node.visitChildren(this);
DartType targetType = node.realTarget.staticType;
if (targetType == null || targetType.isDynamic) {
- return null;
+ return;
}
- return _checkResolved(
- node, node.staticElement, (node) => node is MethodElement);
+ _checkResolved(node, node.staticElement, (node) => node is MethodElement);
}
@override
- Object visitLibraryDirective(LibraryDirective node) =>
- _checkResolved(node, node.element, (node) => node is LibraryElement);
+ void visitLibraryDirective(LibraryDirective node) {
+ _checkResolved(node, node.element, (node) => node is LibraryElement);
+ }
@override
- Object visitNamedExpression(NamedExpression node) =>
- node.expression.accept(this);
+ void visitNamedExpression(NamedExpression node) {
+ node.expression.accept(this);
+ }
@override
- Object visitPartDirective(PartDirective node) => _checkResolved(
- node, node.element, (node) => node is CompilationUnitElement);
+ void visitPartDirective(PartDirective node) {
+ _checkResolved(
+ node, node.element, (node) => node is CompilationUnitElement);
+ }
@override
- Object visitPartOfDirective(PartOfDirective node) =>
- _checkResolved(node, node.element, (node) => node is LibraryElement);
+ void visitPartOfDirective(PartOfDirective node) {
+ _checkResolved(node, node.element, (node) => node is LibraryElement);
+ }
@override
- Object visitPostfixExpression(PostfixExpression node) {
+ void visitPostfixExpression(PostfixExpression node) {
node.visitChildren(this);
if (!node.operator.isUserDefinableOperator) {
- return null;
+ return;
}
DartType operandType = node.operand.staticType;
if (operandType == null || operandType.isDynamic) {
- return null;
+ return;
}
- return _checkResolved(
- node, node.staticElement, (node) => node is MethodElement);
+ _checkResolved(node, node.staticElement, (node) => node is MethodElement);
}
@override
- Object visitPrefixedIdentifier(PrefixedIdentifier node) {
+ void visitPrefixedIdentifier(PrefixedIdentifier node) {
SimpleIdentifier prefix = node.prefix;
prefix.accept(this);
DartType prefixType = prefix.staticType;
if (prefixType == null || prefixType.isDynamic) {
- return null;
+ return;
}
- return _checkResolved(node, node.staticElement, null);
+ _checkResolved(node, node.staticElement, null);
}
@override
- Object visitPrefixExpression(PrefixExpression node) {
+ void visitPrefixExpression(PrefixExpression node) {
node.visitChildren(this);
if (!node.operator.isUserDefinableOperator) {
- return null;
+ return;
}
DartType operandType = node.operand.staticType;
if (operandType == null || operandType.isDynamic) {
- return null;
+ return;
}
- return _checkResolved(
- node, node.staticElement, (node) => node is MethodElement);
+ _checkResolved(node, node.staticElement, (node) => node is MethodElement);
}
@override
- Object visitPropertyAccess(PropertyAccess node) {
+ void visitPropertyAccess(PropertyAccess node) {
Expression target = node.realTarget;
target.accept(this);
DartType targetType = target.staticType;
if (targetType == null || targetType.isDynamic) {
- return null;
+ return;
}
- return node.propertyName.accept(this);
+ node.propertyName.accept(this);
}
@override
- Object visitSimpleIdentifier(SimpleIdentifier node) {
+ void visitSimpleIdentifier(SimpleIdentifier node) {
if (node.name == "void") {
- return null;
+ return;
}
if (resolutionMap.staticTypeForExpression(node) != null &&
resolutionMap.staticTypeForExpression(node).isDynamic &&
node.staticElement == null) {
- return null;
+ return;
}
AstNode parent = node.parent;
if (parent is MethodInvocation) {
@@ -254,14 +255,14 @@
Expression target = invocation.realTarget;
DartType targetType = target == null ? null : target.staticType;
if (targetType == null || targetType.isDynamic) {
- return null;
+ return;
}
}
}
- return _checkResolved(node, node.staticElement, null);
+ _checkResolved(node, node.staticElement, null);
}
- Object _checkResolved(
+ void _checkResolved(
AstNode node, Element element, Predicate<Element> predicate) {
if (element == null) {
if (_knownExceptions == null || !_knownExceptions.contains(node)) {
@@ -272,7 +273,6 @@
_wrongTypedNodes.add(node);
}
}
- return null;
}
String _getFileName(AstNode node) {
@@ -310,12 +310,7 @@
}
}
-class ResolverTestCase extends EngineTestCase {
- /**
- * The resource provider used by the test case.
- */
- MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
-
+class ResolverTestCase extends EngineTestCase with ResourceProviderMixin {
/**
* The analysis context used to parse the compilation units being resolved.
*/
@@ -350,9 +345,6 @@
bool get enableNewAnalysisDriver => false;
- /// TODO(brianwilkerson) Remove this getter.
- bool get previewDart2 => true;
-
/**
* Return a type provider that can be used to test the results of resolution.
*
@@ -384,8 +376,8 @@
* set in the content provider. Return the source representing the added file.
*/
Source addNamedSource(String filePath, String contents) {
- filePath = resourceProvider.convertPath(filePath);
- File file = resourceProvider.newFile(filePath, contents);
+ filePath = convertPath(filePath);
+ File file = newFile(filePath, content: contents);
Source source = file.createSource();
if (enableNewAnalysisDriver) {
driver.addFile(filePath);
@@ -529,7 +521,7 @@
Future<TestAnalysisResult> computeAnalysisResult(Source source) async {
TestAnalysisResult analysisResult;
if (enableNewAnalysisDriver) {
- AnalysisResult result = await driver.getResult(source.fullName);
+ ResolvedUnitResult result = await driver.getResult(source.fullName);
analysisResult =
new TestAnalysisResult(source, result.unit, result.errors);
} else {
@@ -570,7 +562,7 @@
* give it an empty content. Return the source that was created.
*/
Source createNamedSource(String fileName) {
- Source source = resourceProvider.getFile(fileName).createSource();
+ Source source = getFile(fileName).createSource();
analysisContext2.setContents(source, '');
return source;
}
@@ -585,7 +577,7 @@
LibraryElementImpl createTestLibrary(
AnalysisContext context, String libraryName,
[List<String> typeNames]) {
- String fileName = resourceProvider.convertPath("/test/$libraryName.dart");
+ String fileName = convertPath("/test/$libraryName.dart");
Source definingCompilationUnitSource = createNamedSource(fileName);
List<CompilationUnitElement> sourcedCompilationUnits;
if (typeNames == null) {
@@ -611,7 +603,9 @@
compilationUnit.librarySource =
compilationUnit.source = definingCompilationUnitSource;
LibraryElementImpl library = new LibraryElementImpl.forNode(
- context, AstTestFactory.libraryIdentifier2([libraryName]));
+ context,
+ driver?.currentSession,
+ AstTestFactory.libraryIdentifier2([libraryName]));
library.definingCompilationUnit = compilationUnit;
library.parts = sourcedCompilationUnits;
return library;
@@ -662,6 +656,10 @@
fail('Only packages or options can be specified.');
}
options ??= defaultAnalysisOptions;
+ (options as AnalysisOptionsImpl).enabledExperiments = [
+ Experiments.constantUpdate2018Name,
+ Experiments.setLiteralName
+ ];
if (enableNewAnalysisDriver) {
DartSdk sdk = new MockSdk(resourceProvider: resourceProvider)
..context.analysisOptions = options;
@@ -674,10 +672,8 @@
var packageMap = <String, List<Folder>>{};
packages.forEach((args) {
String name = args[0];
- String path =
- resourceProvider.convertPath('/packages/$name/$name.dart');
String content = args[1];
- File file = resourceProvider.newFile(path, content);
+ File file = newFile('/packages/$name/$name.dart', content: content);
packageMap[name] = <Folder>[file.parent];
});
resolvers.add(new PackageMapUriResolver(resourceProvider, packageMap));
@@ -832,6 +828,19 @@
CompilationUnit testUnit;
/**
+ * Find the expression that starts at the offset of [search] and validate its
+ * that its static type matches the given [type].
+ *
+ * If [type] is a string, validates that the expression's static type
+ * stringifies to that text. Otherwise, [type] is used directly a [Matcher]
+ * to match the type.
+ */
+ void expectExpressionType(String search, type) {
+ Expression expression = findExpression(search);
+ _expectType(expression.staticType, type);
+ }
+
+ /**
* Looks up the identifier with [name] and validates that its type type
* stringifies to [type] and that its generics match the given stringified
* output.
@@ -889,15 +898,19 @@
void expectInitializerType(String name, type) {
SimpleIdentifier identifier = findIdentifier(name);
VariableDeclaration declaration =
- identifier.getAncestor((node) => node is VariableDeclaration);
+ identifier.thisOrAncestorOfType<VariableDeclaration>();
Expression initializer = declaration.initializer;
_expectType(initializer.staticType, type);
}
+ Expression findExpression(String search) {
+ return EngineTestCase.findNode(
+ testUnit, testCode, search, (node) => node is Expression);
+ }
+
SimpleIdentifier findIdentifier(String search) {
- SimpleIdentifier identifier = EngineTestCase.findNode(
+ return EngineTestCase.findNode(
testUnit, testCode, search, (node) => node is SimpleIdentifier);
- return identifier;
}
Future<Null> resolveTestUnit(String code, {bool noErrors: true}) async {
diff --git a/pkg/analyzer/test/generated/sdk_test.dart b/pkg/analyzer/test/generated/sdk_test.dart
index f311ea9..6dae63b 100644
--- a/pkg/analyzer/test/generated/sdk_test.dart
+++ b/pkg/analyzer/test/generated/sdk_test.dart
@@ -4,10 +4,11 @@
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../src/context/mock_sdk.dart';
import 'test_support.dart';
main() {
@@ -18,14 +19,14 @@
}
@reflectiveTest
-class DartSdkManagerTest extends EngineTestCase {
+class DartSdkManagerTest extends EngineTestCase with ResourceProviderMixin {
void test_anySdk() {
DartSdkManager manager = new DartSdkManager('/a/b/c', false);
expect(manager.anySdk, isNull);
AnalysisOptions options = new AnalysisOptionsImpl();
SdkDescription description = new SdkDescription(<String>['/c/d'], options);
- DartSdk sdk = new MockSdk();
+ DartSdk sdk = new MockSdk(resourceProvider: resourceProvider);
manager.getSdk(description, () => sdk);
expect(manager.anySdk, same(sdk));
}
@@ -34,11 +35,11 @@
DartSdkManager manager = new DartSdkManager('/a/b/c', false);
AnalysisOptions options = new AnalysisOptionsImpl();
SdkDescription description1 = new SdkDescription(<String>['/c/d'], options);
- DartSdk sdk1 = new MockSdk();
+ DartSdk sdk1 = new MockSdk(resourceProvider: resourceProvider);
DartSdk result1 = manager.getSdk(description1, () => sdk1);
expect(result1, same(sdk1));
SdkDescription description2 = new SdkDescription(<String>['/e/f'], options);
- DartSdk sdk2 = new MockSdk();
+ DartSdk sdk2 = new MockSdk(resourceProvider: resourceProvider);
DartSdk result2 = manager.getSdk(description2, () => sdk2);
expect(result2, same(sdk2));
@@ -50,7 +51,7 @@
DartSdkManager manager = new DartSdkManager('/a/b/c', false);
AnalysisOptions options = new AnalysisOptionsImpl();
SdkDescription description = new SdkDescription(<String>['/c/d'], options);
- DartSdk sdk = new MockSdk();
+ DartSdk sdk = new MockSdk(resourceProvider: resourceProvider);
DartSdk result = manager.getSdk(description, () => sdk);
expect(result, same(sdk));
manager.getSdk(description, _failIfAbsent);
diff --git a/pkg/analyzer/test/generated/simple_resolver_test.dart b/pkg/analyzer/test/generated/simple_resolver_test.dart
index 3d64b48..55d92dd 100644
--- a/pkg/analyzer/test/generated/simple_resolver_test.dart
+++ b/pkg/analyzer/test/generated/simple_resolver_test.dart
@@ -142,7 +142,7 @@
}
// get parameter
Expression rhs = assignment.rightHandSide;
- expect(rhs.staticParameterElement, previewDart2 ? isNotNull : isNull);
+ expect(rhs.staticParameterElement, isNotNull);
}
test_argumentResolution_setter_propagated_propertyAccess() async {
@@ -166,7 +166,7 @@
}
// get parameter
Expression rhs = assignment.rightHandSide;
- expect(rhs.staticParameterElement, previewDart2 ? isNotNull : isNull);
+ expect(rhs.staticParameterElement, isNotNull);
}
test_argumentResolution_setter_static() async {
@@ -376,42 +376,6 @@
verify([source]);
}
- test_commentReference_class() async {
- Source source = addSource(r'''
-f() {}
-/** [A] [new A] [A.n] [new A.n] [m] [f] */
-class A {
- A() {}
- A.n() {}
- m() {}
-}''');
- await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- test_commentReference_parameter() async {
- Source source = addSource(r'''
-class A {
- A() {}
- A.n() {}
- /** [e] [f] */
- m(e, f()) {}
-}''');
- await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- }
-
- test_commentReference_singleLine() async {
- Source source = addSource(r'''
-/// [A]
-class A {}''');
- await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- }
-
test_continueTarget_labeled() async {
// Verify that the target of the label is correctly found and is recorded
// as the unlabeled portion of the statement.
@@ -1717,7 +1681,7 @@
}
class _SimpleResolverTest_localVariable_types_invoked
- extends RecursiveAstVisitor<Object> {
+ extends RecursiveAstVisitor<void> {
final SimpleResolverTest test;
List<bool> found;
@@ -1729,25 +1693,20 @@
: super();
@override
- Object visitSimpleIdentifier(SimpleIdentifier node) {
+ void visitSimpleIdentifier(SimpleIdentifier node) {
if (node.name == "myVar" && node.parent is MethodInvocation) {
try {
found[0] = true;
// check static type
DartType staticType = node.staticType;
- if (test.previewDart2) {
- expect(staticType is FunctionType, isTrue);
- FunctionType functionType = staticType;
- expect(
- functionType.parameters[0].type, same(test.typeProvider.intType));
- expect(functionType.returnType, same(test.typeProvider.stringType));
- } else {
- expect(staticType, same(test.typeProvider.dynamicType));
- }
+ expect(staticType is FunctionType, isTrue);
+ FunctionType functionType = staticType;
+ expect(
+ functionType.parameters[0].type, same(test.typeProvider.intType));
+ expect(functionType.returnType, same(test.typeProvider.stringType));
} on AnalysisException catch (e, stackTrace) {
thrownException[0] = new CaughtException(e, stackTrace);
}
}
- return null;
}
}
diff --git a/pkg/analyzer/test/generated/source_factory_test.dart b/pkg/analyzer/test/generated/source_factory_test.dart
index 09a3c10..767de68 100644
--- a/pkg/analyzer/test/generated/source_factory_test.dart
+++ b/pkg/analyzer/test/generated/source_factory_test.dart
@@ -13,6 +13,7 @@
import 'package:analyzer/src/generated/utilities_dart.dart' as utils;
import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer/src/source/source_resource.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:package_config/packages.dart';
import 'package:package_config/packages_file.dart' as pkgfile show parse;
import 'package:package_config/src/packages_impl.dart';
@@ -217,9 +218,7 @@
}
@reflectiveTest
-class SourceFactoryTest {
- MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
-
+class SourceFactoryTest with ResourceProviderMixin {
void test_creation() {
expect(new SourceFactory([]), isNotNull);
}
@@ -252,12 +251,11 @@
void test_resolveUri_nonAbsolute_absolute() {
SourceFactory factory =
new SourceFactory([new AbsoluteUriResolver(resourceProvider)]);
- String sourcePath = resourceProvider.convertPath('/does/not/exist.dart');
+ String sourcePath = convertPath('/does/not/exist.dart');
String targetRawPath = '/does/not/matter.dart';
- String targetPath = resourceProvider.convertPath(targetRawPath);
- String targetUri =
- resourceProvider.pathContext.toUri(targetRawPath).toString();
- Source sourceSource = new FileSource(resourceProvider.getFile(sourcePath));
+ String targetPath = convertPath(targetRawPath);
+ String targetUri = toUri(targetRawPath).toString();
+ Source sourceSource = new FileSource(getFile(sourcePath));
Source result = factory.resolveUri(sourceSource, targetUri);
expect(result.fullName, targetPath);
}
@@ -265,10 +263,9 @@
void test_resolveUri_nonAbsolute_relative() {
SourceFactory factory =
new SourceFactory([new AbsoluteUriResolver(resourceProvider)]);
- String path = _p('/does/not/have.dart');
- Source containingSource = new FileSource(resourceProvider.getFile(path));
+ Source containingSource = new FileSource(getFile('/does/not/have.dart'));
Source result = factory.resolveUri(containingSource, 'exist.dart');
- expect(result.fullName, _p('/does/not/exist.dart'));
+ expect(result.fullName, convertPath('/does/not/exist.dart'));
}
void test_resolveUri_nonAbsolute_relative_package() {
@@ -301,8 +298,8 @@
}
void test_restoreUri() {
- File file1 = resourceProvider.getFile(_p("/some/file1.dart"));
- File file2 = resourceProvider.getFile(_p("/some/file2.dart"));
+ File file1 = getFile("/some/file1.dart");
+ File file2 = getFile("/some/file2.dart");
Source source1 = new FileSource(file1);
Source source2 = new FileSource(file2);
Uri expected1 = Uri.parse("file:///my_file.dart");
@@ -311,11 +308,6 @@
expect(factory.restoreUri(source1), same(expected1));
expect(factory.restoreUri(source2), same(null));
}
-
- /**
- * Return the [resourceProvider] specific path for the given Posix [path].
- */
- String _p(String path) => resourceProvider.convertPath(path);
}
class UriResolver_absolute extends UriResolver {
diff --git a/pkg/analyzer/test/generated/static_type_analyzer_test.dart b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
index 8995879..6657e81 100644
--- a/pkg/analyzer/test/generated/static_type_analyzer_test.dart
+++ b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -33,6 +33,7 @@
defineReflectiveSuite(() {
defineReflectiveTests(StaticTypeAnalyzerTest);
defineReflectiveTests(StaticTypeAnalyzer2Test);
+ defineReflectiveTests(StaticTypeAnalyzer3Test);
});
}
@@ -57,7 +58,7 @@
}
''';
await resolveTestUnit(code);
- expectInitializerType('foo', previewDart2 ? 'int' : 'dynamic');
+ expectInitializerType('foo', 'int');
}
test_FunctionExpressionInvocation_curried() async {
@@ -117,11 +118,7 @@
}
""";
await resolveTestUnit(code);
- if (previewDart2) {
- expectIdentifierType("p()", '() → dynamic');
- } else {
- expectIdentifierType("p()", DynamicTypeImpl.instance);
- }
+ expectIdentifierType("p()", '() → dynamic');
}
test_staticMethods_classTypeParameters() async {
@@ -156,7 +153,7 @@
FunctionTypeImpl type = expectFunctionType('m);', '<S>(S) → void',
elementTypeParams: '[S]',
typeFormals: '[S]',
- identifierType: previewDart2 ? '<S>(S) → void' : '(dynamic) → void');
+ identifierType: '<S>(S) → void');
typeS = type.typeFormals[0].type;
type = type.instantiate([DynamicTypeImpl.instance]);
@@ -172,8 +169,7 @@
typeParams: '[S]',
typeArgs: '[S]',
typeFormals: '[U]',
- identifierType:
- previewDart2 ? '<U>(S, U) → void' : '(S, dynamic) → void');
+ identifierType: '<U>(S, U) → void');
type = type.instantiate([DynamicTypeImpl.instance]);
expect(type.toString(), '(S, dynamic) → void');
@@ -184,6 +180,48 @@
}
}
+/**
+ * End-to-end tests of the static type analyzer that use the new driver.
+ */
+@reflectiveTest
+class StaticTypeAnalyzer3Test extends StaticTypeAnalyzer2TestShared {
+ bool get enableNewAnalysisDriver => true;
+
+ test_emptyMapLiteral_inContext() async {
+ String code = r'''
+main() {
+ useMap({});
+}
+void useMap(Map<int, int> m) {
+}
+''';
+ await resolveTestUnit(code);
+ expectExpressionType('{}', 'Map<int, int>');
+ }
+
+ test_emptyMapLiteral_notInContext() async {
+ String code = r'''
+main() {
+ var v = {};
+}
+''';
+ await resolveTestUnit(code);
+ expectExpressionType('{}', 'Map<dynamic, dynamic>');
+ }
+
+ test_emptySetLiteral_inContext() async {
+ String code = r'''
+main() {
+ useSet({});
+}
+void useSet(Set<int> s) {
+}
+''';
+ await resolveTestUnit(code);
+ expectExpressionType('{}', 'Set<int>');
+ }
+}
+
@reflectiveTest
class StaticTypeAnalyzerTest extends EngineTestCase with ResourceProviderMixin {
/**
@@ -206,9 +244,6 @@
*/
TypeProvider _typeProvider;
- /// TODO(brianwilkerson) Remove this getter.
- bool get previewDart2 => true;
-
/**
* The type system used to analyze the test cases.
*/
@@ -661,8 +696,6 @@
void test_visitFunctionExpression_async_expression() {
// () async => e, where e has type int
InterfaceType intType = _typeProvider.intType;
- InterfaceType futureIntType =
- _typeProvider.futureType.instantiate(<DartType>[intType]);
Expression expression = _resolvedVariable(intType, 'e');
ExpressionFunctionBody body =
AstTestFactory.expressionFunctionBody(expression);
@@ -670,17 +703,13 @@
FunctionExpression node = _resolvedFunctionExpression(
AstTestFactory.formalParameterList([]), body);
DartType resultType = _analyze(node);
- if (previewDart2) {
- _assertFunctionType(
- _typeProvider.futureType
- .instantiate(<DartType>[_typeProvider.dynamicType]),
- null,
- null,
- null,
- resultType);
- } else {
- _assertFunctionType(futureIntType, null, null, null, resultType);
- }
+ _assertFunctionType(
+ _typeProvider.futureType
+ .instantiate(<DartType>[_typeProvider.dynamicType]),
+ null,
+ null,
+ null,
+ resultType);
_listener.assertNoErrors();
}
@@ -696,17 +725,13 @@
FunctionExpression node = _resolvedFunctionExpression(
AstTestFactory.formalParameterList([]), body);
DartType resultType = _analyze(node);
- if (previewDart2) {
- _assertFunctionType(
- _typeProvider.futureType
- .instantiate(<DartType>[_typeProvider.dynamicType]),
- null,
- null,
- null,
- resultType);
- } else {
- _assertFunctionType(futureIntType, null, null, null, resultType);
- }
+ _assertFunctionType(
+ _typeProvider.futureType
+ .instantiate(<DartType>[_typeProvider.dynamicType]),
+ null,
+ null,
+ null,
+ resultType);
_listener.assertNoErrors();
}
@@ -724,17 +749,13 @@
FunctionExpression node = _resolvedFunctionExpression(
AstTestFactory.formalParameterList([]), body);
DartType resultType = _analyze(node);
- if (previewDart2) {
- _assertFunctionType(
- _typeProvider.futureType
- .instantiate(<DartType>[_typeProvider.dynamicType]),
- null,
- null,
- null,
- resultType);
- } else {
- _assertFunctionType(futureIntType, null, null, null, resultType);
- }
+ _assertFunctionType(
+ _typeProvider.futureType
+ .instantiate(<DartType>[_typeProvider.dynamicType]),
+ null,
+ null,
+ null,
+ resultType);
_listener.assertNoErrors();
}
@@ -800,13 +821,8 @@
DartType resultType = _analyze(node);
Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>();
expectedNamedTypes["p"] = dynamicType;
- if (previewDart2) {
- _assertFunctionType(
- dynamicType, null, null, expectedNamedTypes, resultType);
- } else {
- _assertFunctionType(
- _typeProvider.intType, null, null, expectedNamedTypes, resultType);
- }
+ _assertFunctionType(
+ dynamicType, null, null, expectedNamedTypes, resultType);
_listener.assertNoErrors();
}
@@ -838,13 +854,8 @@
AstTestFactory.expressionFunctionBody(_resolvedInteger(0)));
_analyze5(p);
DartType resultType = _analyze(node);
- if (previewDart2) {
- _assertFunctionType(
- dynamicType, <DartType>[dynamicType], null, null, resultType);
- } else {
- _assertFunctionType(_typeProvider.intType, <DartType>[dynamicType], null,
- null, resultType);
- }
+ _assertFunctionType(
+ dynamicType, <DartType>[dynamicType], null, null, resultType);
_listener.assertNoErrors();
}
@@ -883,13 +894,8 @@
DartType resultType = _analyze(node);
Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>();
expectedNamedTypes["p2"] = dynamicType;
- if (previewDart2) {
- _assertFunctionType(dynamicType, <DartType>[dynamicType], null,
- expectedNamedTypes, resultType);
- } else {
- _assertFunctionType(_typeProvider.intType, <DartType>[dynamicType], null,
- expectedNamedTypes, resultType);
- }
+ _assertFunctionType(dynamicType, <DartType>[dynamicType], null,
+ expectedNamedTypes, resultType);
_listener.assertNoErrors();
}
@@ -926,13 +932,8 @@
_analyze5(p1);
_analyze5(p2);
DartType resultType = _analyze(node);
- if (previewDart2) {
- _assertFunctionType(dynamicType, <DartType>[dynamicType],
- <DartType>[dynamicType], null, resultType);
- } else {
- _assertFunctionType(_typeProvider.intType, <DartType>[dynamicType],
- <DartType>[dynamicType], null, resultType);
- }
+ _assertFunctionType(dynamicType, <DartType>[dynamicType],
+ <DartType>[dynamicType], null, resultType);
_listener.assertNoErrors();
}
@@ -967,13 +968,8 @@
AstTestFactory.expressionFunctionBody(_resolvedInteger(0)));
_analyze5(p);
DartType resultType = _analyze(node);
- if (previewDart2) {
- _assertFunctionType(
- dynamicType, null, <DartType>[dynamicType], null, resultType);
- } else {
- _assertFunctionType(_typeProvider.intType, null, <DartType>[dynamicType],
- null, resultType);
- }
+ _assertFunctionType(
+ dynamicType, null, <DartType>[dynamicType], null, resultType);
_listener.assertNoErrors();
}
@@ -1139,16 +1135,9 @@
// [0]
Expression node = AstTestFactory.listLiteral([_resolvedInteger(0)]);
DartType resultType = _analyze(node);
- if (previewDart2) {
- _assertType2(
- _typeProvider.listType.instantiate(<DartType>[_typeProvider.intType]),
- resultType);
- } else {
- _assertType2(
- _typeProvider.listType
- .instantiate(<DartType>[_typeProvider.dynamicType]),
- resultType);
- }
+ _assertType2(
+ _typeProvider.listType.instantiate(<DartType>[_typeProvider.intType]),
+ resultType);
_listener.assertNoErrors();
}
@@ -1194,17 +1183,10 @@
Expression node = AstTestFactory.mapLiteral2(
[AstTestFactory.mapLiteralEntry("k", _resolvedInteger(0))]);
DartType resultType = _analyze(node);
- if (previewDart2) {
- _assertType2(
- _typeProvider.mapType.instantiate(
- <DartType>[_typeProvider.dynamicType, _typeProvider.intType]),
- resultType);
- } else {
- _assertType2(
- _typeProvider.mapType.instantiate(
- <DartType>[_typeProvider.dynamicType, _typeProvider.dynamicType]),
- resultType);
- }
+ _assertType2(
+ _typeProvider.mapType.instantiate(
+ <DartType>[_typeProvider.dynamicType, _typeProvider.intType]),
+ resultType);
_listener.assertNoErrors();
}
@@ -1545,7 +1527,7 @@
definingCompilationUnit.librarySource =
definingCompilationUnit.source = source;
LibraryElementImpl definingLibrary =
- new LibraryElementImpl.forNode(context, null);
+ new LibraryElementImpl.forNode(context, null, null);
definingLibrary.definingCompilationUnit = definingCompilationUnit;
_typeProvider = context.typeProvider;
_visitor = new ResolverVisitor(
diff --git a/pkg/analyzer/test/generated/static_type_warning_code_test.dart b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
index e4f9e69..283d077 100644
--- a/pkg/analyzer/test/generated/static_type_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
@@ -2,12 +2,9 @@
// 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:analyzer/error/error.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/java_core.dart' show formatList;
import 'package:analyzer/src/generated/source_io.dart';
-import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'resolver_test_case.dart';
@@ -30,21 +27,6 @@
}''', [StaticTypeWarningCode.UNDEFINED_ENUM_CONSTANT]);
}
- test_ambiguousImport_function() async {
- Source source = addSource(r'''
-import 'lib1.dart';
-import 'lib2.dart';
-g() { return f(); }''');
- addNamedSource("/lib1.dart", r'''
-library lib1;
-f() {}''');
- addNamedSource("/lib2.dart", r'''
-library lib2;
-f() {}''');
- await computeAnalysisResult(source);
- assertErrors(source, [StaticWarningCode.AMBIGUOUS_IMPORT]);
- }
-
test_assert_message_suppresses_type_promotion() async {
// If a variable is assigned to inside the expression for an assert
// message, type promotion should be suppressed, just as it would be if the
@@ -218,11 +200,12 @@
}''', [StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS]);
}
- test_expectedTwoMapTypeArguments_one() async {
+ @failingTest
+ test_expectedOneSetTypeArgument() async {
await assertErrorsInCode(r'''
main() {
- <int> {};
-}''', [StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS]);
+ <int, int>{2, 3};
+}''', [StaticTypeWarningCode.EXPECTED_ONE_SET_TYPE_ARGUMENTS]);
}
test_expectedTwoMapTypeArguments_three() async {
@@ -457,16 +440,6 @@
''', [StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE]);
}
- test_instanceAccessToStaticMember_method_invocation() async {
- await assertErrorsInCode(r'''
-class A {
- static m() {}
-}
-main(A a) {
- a.m();
-}''', [StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER]);
- }
-
test_instanceAccessToStaticMember_method_reference() async {
await assertErrorsInCode(r'''
class A {
@@ -617,85 +590,6 @@
}''', [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
}
- test_invocationOfNonFunction_class() async {
- await assertErrorsInCode(r'''
-class A {
- void m() {
- A();
- }
-}''', previewDart2 ? [] : [StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION]);
- }
-
- test_invocationOfNonFunction_dynamic() async {
- await assertErrorsInCode(r'''
-main() {
- dynamic d;
- d.hashCode();
-}
-''', [StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION]);
- }
-
- test_invocationOfNonFunction_localGenericFunction() async {
- // Invoking `.call` on a `Function` type works similarly to invoking it on
- // `dynamic`--the invocation is accepted at compile time, and all type
- // checking is deferred until runtime.
- await assertErrorsInCode('''
-f(Function f) {
- return f();
-}''', []);
- }
-
- test_invocationOfNonFunction_localObject() async {
- await assertErrorsInCode('''
-f(Object o) {
- return o();
-}''', [StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION]);
- }
-
- test_invocationOfNonFunction_localVariable() async {
- await assertErrorsInCode(r'''
-f() {
- int x;
- return x();
-}''', [StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION]);
- }
-
- test_invocationOfNonFunction_ordinaryInvocation() async {
- await assertErrorsInCode(r'''
-class A {
- static int x;
-}
-class B {
- m() {
- A.x();
- }
-}''', [StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION]);
- // A call to verify(source) fails as A.x() cannot be resolved.
- }
-
- test_invocationOfNonFunction_staticInvocation() async {
- await assertErrorsInCode(r'''
-class A {
- static int get g => 0;
- f() {
- A.g();
- }
-}''', [StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION]);
- // A call to verify(source) fails as g() cannot be resolved.
- }
-
- test_invocationOfNonFunction_superExpression() async {
- await assertErrorsInCode(r'''
-class A {
- int get g => 0;
-}
-class B extends A {
- m() {
- var v = super.g();
- }
-}''', [StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION]);
- }
-
test_invocationOfNonFunctionExpression_literal() async {
await assertErrorsInCode(r'''
f() {
@@ -1348,34 +1242,6 @@
}''', [StaticTypeWarningCode.UNDEFINED_GETTER]);
}
- test_undefinedFunction() async {
- await assertErrorsInCode(r'''
-void f() {
- g();
-}''', [StaticTypeWarningCode.UNDEFINED_FUNCTION]);
- }
-
- test_undefinedFunction_inCatch() async {
- await assertErrorsInCode(r'''
-void f() {
- try {
- } on Object {
- g();
- }
-}''', [StaticTypeWarningCode.UNDEFINED_FUNCTION]);
- }
-
- test_undefinedFunction_inImportedLib() async {
- Source source = addSource(r'''
-import 'lib.dart' as f;
-main() { return f.g(); }''');
- addNamedSource("/lib.dart", r'''
-library lib;
-h() {}''');
- await computeAnalysisResult(source);
- assertErrors(source, [StaticTypeWarningCode.UNDEFINED_FUNCTION]);
- }
-
test_undefinedGetter() async {
await assertErrorsInUnverifiedCode(r'''
class T {}
@@ -1433,12 +1299,11 @@
test_undefinedGetter_typeLiteral_conditionalAccess() async {
// When applied to a type literal, the conditional access operator '?.'
// cannot be used to access instance getters of Type.
- // TODO(brianwilkerson) We cannot verify in previewDart2 because hashCode
- // isn't resolved.
+ // TODO(brianwilkerson) We cannot verify because hashCode isn't resolved.
await assertErrorsInCode('''
class A {}
f() => A?.hashCode;
-''', [StaticTypeWarningCode.UNDEFINED_GETTER], verify: !previewDart2);
+''', [StaticTypeWarningCode.UNDEFINED_GETTER], verify: false);
}
test_undefinedGetter_wrongNumberOfTypeArguments_tooLittle() async {
@@ -1471,15 +1336,6 @@
}''', [StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT]);
}
- test_undefinedMethod() async {
- await assertErrorsInCode(r'''
-class A {
- void m() {
- n();
- }
-}''', [StaticTypeWarningCode.UNDEFINED_METHOD]);
- }
-
test_undefinedMethod_assignmentExpression() async {
await assertErrorsInCode(r'''
class A {}
@@ -1491,17 +1347,6 @@
}''', [StaticTypeWarningCode.UNDEFINED_METHOD]);
}
- test_undefinedMethod_generic_function_call() async {
- // Invoking `.call` on a `Function` type works similarly to invoking it on
- // `dynamic`--the invocation is accepted at compile time, and all type
- // checking is deferred until runtime.
- await assertErrorsInCode('''
-f(Function f) {
- f.call();
-}
-''', []);
- }
-
test_undefinedMethod_ignoreTypePropagation() async {
await assertErrorsInCode(r'''
class A {}
@@ -1521,14 +1366,6 @@
[StaticTypeWarningCode.UNDEFINED_METHOD]);
}
- test_undefinedMethod_object_call() async {
- await assertErrorsInCode('''
-f(Object o) {
- o.call();
-}
-''', [StaticTypeWarningCode.UNDEFINED_METHOD]);
- }
-
test_undefinedMethod_ofNull() async {
// TODO(scheglov) Track https://github.com/dart-lang/sdk/issues/28430 to
// decide whether a warning should be reported here.
@@ -1540,69 +1377,15 @@
''', [StaticTypeWarningCode.UNDEFINED_METHOD]);
}
- test_undefinedMethod_private() async {
- addNamedSource("/lib.dart", r'''
-library lib;
-class A {
- _foo() {}
-}''');
- await assertErrorsInCode(r'''
-import 'lib.dart';
-class B extends A {
- test() {
- _foo();
- }
-}''', [StaticTypeWarningCode.UNDEFINED_METHOD]);
- }
-
- test_undefinedMethod_proxy_annotation_fakeProxy() async {
- await assertErrorsInCode(r'''
-library L;
-class Fake {
- const Fake();
-}
-const proxy = const Fake();
-@proxy class PrefixProxy {}
-main() {
- new PrefixProxy().foo();
-}''', [StaticTypeWarningCode.UNDEFINED_METHOD]);
- }
-
- test_undefinedMethod_typeLiteral_cascadeTarget() async {
- await assertErrorsInCode('''
-class T {
- static void foo() {}
-}
-main() {
- T..foo();
-}
-''', [StaticTypeWarningCode.UNDEFINED_METHOD]);
- }
-
- test_undefinedMethod_typeLiteral_conditionalAccess() async {
- // When applied to a type literal, the conditional access operator '?.'
- // cannot be used to access instance methods of Type.
- await assertErrorsInCode('''
-class A {}
-f() => A?.toString();
-''', [StaticTypeWarningCode.UNDEFINED_METHOD]);
- }
-
test_undefinedMethodWithConstructor() async {
- // TODO(brianwilkerson) We cannot verify in previewDart2 because 'C' could
- // not be resolved.
- await assertErrorsInCode(
- r'''
+ // TODO(brianwilkerson) We cannot verify because 'C' could not be resolved.
+ await assertErrorsInCode(r'''
class C {
C.m();
}
f() {
C c = C.m();
-}''',
- previewDart2
- ? []
- : [StaticTypeWarningCode.UNDEFINED_METHOD_WITH_CONSTRUCTOR],
- verify: !previewDart2);
+}''', [], verify: false);
}
test_undefinedOperator_indexBoth() async {
@@ -1610,7 +1393,10 @@
class A {}
f(A a) {
a[0]++;
-}''', [StaticTypeWarningCode.UNDEFINED_OPERATOR]);
+}''', [
+ StaticTypeWarningCode.UNDEFINED_OPERATOR,
+ StaticTypeWarningCode.UNDEFINED_OPERATOR,
+ ]);
}
test_undefinedOperator_indexGetter() async {
@@ -1701,18 +1487,6 @@
''', [StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER]);
}
- test_unqualifiedReferenceToNonLocalStaticMember_method() async {
- await assertErrorsInCode(r'''
-class A {
- static void a() {}
-}
-class B extends A {
- void b() {
- a();
- }
-}''', [StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER]);
- }
-
test_unqualifiedReferenceToNonLocalStaticMember_setter() async {
await assertErrorsInCode(r'''
class A {
@@ -1883,26 +1657,6 @@
resetWith(options: options);
}
- test_genericMethodWrongNumberOfTypeArguments() async {
- Source source = addSource('''
-f() {}
-main() {
- f<int>();
-}
-''');
- TestAnalysisResult analysisResult = await computeAnalysisResult(source);
- assertErrors(
- source, [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD]);
- for (AnalysisError error in analysisResult.errors) {
- if (error.errorCode ==
- StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS) {
- expect(error.message,
- formatList(error.errorCode.message, ['() → dynamic', 0, 1]));
- }
- }
- verify([source]);
- }
-
test_legalAsyncGeneratorReturnType_function_supertypeOfStream() async {
await assertErrorsInCode('''
import 'dart:async';
diff --git a/pkg/analyzer/test/generated/static_warning_code_driver_test.dart b/pkg/analyzer/test/generated/static_warning_code_driver_test.dart
index adf005d..699954f 100644
--- a/pkg/analyzer/test/generated/static_warning_code_driver_test.dart
+++ b/pkg/analyzer/test/generated/static_warning_code_driver_test.dart
@@ -16,4 +16,8 @@
class StaticWarningCodeTest_Driver extends StaticWarningCodeTest {
@override
bool get enableNewAnalysisDriver => true;
+
+ test_setElementTypeNotAssignable() async {
+ return super.test_setElementTypeNotAssignable();
+ }
}
diff --git a/pkg/analyzer/test/generated/static_warning_code_test.dart b/pkg/analyzer/test/generated/static_warning_code_test.dart
index 4b7068e..07f6d2f 100644
--- a/pkg/analyzer/test/generated/static_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_warning_code_test.dart
@@ -274,24 +274,6 @@
assertErrors(source, [StaticWarningCode.AMBIGUOUS_IMPORT]);
}
- test_ambiguousImport_withPrefix() async {
- Source source = addSource(r'''
-library test;
-import 'lib1.dart' as p;
-import 'lib2.dart' as p;
-main() {
- p.f();
-}''');
- addNamedSource("/lib1.dart", r'''
-library lib1;
-f() {}''');
- addNamedSource("/lib2.dart", r'''
-library lib2;
-f() {}''');
- await computeAnalysisResult(source);
- assertErrors(source, [StaticWarningCode.AMBIGUOUS_IMPORT]);
- }
-
test_argumentTypeNotAssignable_ambiguousClassName() async {
// See dartbug.com/19624
Source source = addNamedSource("/lib1.dart", r'''
@@ -315,10 +297,6 @@
expect(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, error.errorCode);
String message = error.message;
expect(message.indexOf("_A") != -1, isTrue);
- if (!previewDart2) {
- expect(message.indexOf("lib1.dart") != -1, isTrue);
- expect(message.indexOf("lib2.dart") != -1, isTrue);
- }
}
test_argumentTypeNotAssignable_annotation_namedConstructor() async {
@@ -501,11 +479,7 @@
acceptFunNumOptBool(funNumBool);
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(source, [StrongModeCode.INVALID_CAST_FUNCTION]);
- } else {
- assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
- }
+ assertErrors(source, [StrongModeCode.INVALID_CAST_FUNCTION]);
verify([source]);
}
@@ -1111,15 +1085,10 @@
A(String this.x) {}
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(source, [
- StaticWarningCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE,
- StrongModeCode.INVALID_PARAMETER_DECLARATION
- ]);
- } else {
- assertErrors(
- source, [StaticWarningCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE]);
- }
+ assertErrors(source, [
+ StaticWarningCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE,
+ StrongModeCode.INVALID_PARAMETER_DECLARATION
+ ]);
verify([source]);
}
@@ -1356,11 +1325,7 @@
}
''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertNoErrors(source);
- } else {
- assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
- }
+ assertNoErrors(source);
}
test_generalizedVoid_interpolateVoidValueError() async {
@@ -1374,51 +1339,6 @@
assertErrors(source, [StaticWarningCode.USE_OF_VOID_RESULT]);
}
- test_generalizedVoid_invocationOfVoidFieldError() async {
- Source source = addSource(r'''
-class Container<T>{
- T value;
-}
-void main(Container<void> voidContainer) {
- voidContainer.value();
-}
-''');
- await computeAnalysisResult(source);
- assertErrors(source, [StaticWarningCode.USE_OF_VOID_RESULT]);
- }
-
- test_generalizedVoid_invocationOfVoidLocalError() async {
- Source source = addSource(r'''
-void main() {
- void x;
- x();
-}
-''');
- await computeAnalysisResult(source);
- assertErrors(source, [StaticWarningCode.USE_OF_VOID_RESULT]);
- }
-
- test_generalizedVoid_invocationOfVoidResultError() async {
- Source source = addSource(r'''
-void main() {
- main()();
-}
-''');
- await computeAnalysisResult(source);
- assertErrors(source, [StaticWarningCode.USE_OF_VOID_RESULT]);
- }
-
- test_generalizedVoid_invocationOfVoidToplevelError() async {
- Source source = addSource(r'''
-void x;
-void main() {
- x();
-}
-''');
- await computeAnalysisResult(source);
- assertErrors(source, [StaticWarningCode.USE_OF_VOID_RESULT]);
- }
-
test_generalizedVoid_negateVoidValueError() async {
Source source = addSource(r'''
void main() {
@@ -1533,28 +1453,6 @@
assertErrors(source, [StaticWarningCode.USE_OF_VOID_RESULT]);
}
- test_generalizedVoid_useOfVoidCallMethodError() async {
- Source source = addSource(r'''
-void main() {
- void x;
- x.toString();
-}
-''');
- await computeAnalysisResult(source);
- assertErrors(source, [StaticWarningCode.USE_OF_VOID_RESULT]);
- }
-
- test_generalizedVoid_useOfVoidCallMethodWithNullError() async {
- Source source = addSource(r'''
-void main() {
- void x;
- x?.toString();
-}
-''');
- await computeAnalysisResult(source);
- assertErrors(source, [StaticWarningCode.USE_OF_VOID_RESULT]);
- }
-
test_generalizedVoid_useOfVoidCallSetterError() async {
Source source = addSource(r'''
void main() {
@@ -1566,17 +1464,6 @@
assertErrors(source, [StaticWarningCode.USE_OF_VOID_RESULT]);
}
- test_generalizedVoid_useOfVoidCascadeError() async {
- Source source = addSource(r'''
-void main() {
- void x;
- x..toString();
-}
-''');
- await computeAnalysisResult(source);
- assertErrors(source, [StaticWarningCode.USE_OF_VOID_RESULT]);
- }
-
test_generalizedVoid_useOfVoidCastsOk() async {
Source source = addSource(r'''
void use(dynamic x) { }
@@ -2257,13 +2144,7 @@
}
''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertNoErrors(source);
- } else {
- assertErrors(source, [
- StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL
- ]);
- }
+ assertNoErrors(source);
verify([source]);
}
@@ -2280,12 +2161,7 @@
}
''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertNoErrors(source);
- } else {
- assertErrors(source,
- [StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED]);
- }
+ assertNoErrors(source);
verify([source]);
}
@@ -2368,12 +2244,7 @@
m({int p : 1}) {}
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertNoErrors(source);
- } else {
- assertErrors(source,
- [StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED]);
- }
+ assertNoErrors(source);
verify([source]);
}
@@ -2386,13 +2257,7 @@
m([int p = 1]) {}
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertNoErrors(source);
- } else {
- assertErrors(source, [
- StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL
- ]);
- }
+ assertNoErrors(source);
verify([source]);
}
@@ -2405,11 +2270,7 @@
m({a}) {}
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]);
- } else {
- assertErrors(source, [StaticWarningCode.INVALID_OVERRIDE_NAMED]);
- }
+ assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]);
verify([source]);
}
@@ -2422,11 +2283,7 @@
m({a, c}) {}
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]);
- } else {
- assertErrors(source, [StaticWarningCode.INVALID_OVERRIDE_NAMED]);
- }
+ assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]);
verify([source]);
}
@@ -2439,11 +2296,7 @@
m([a]) {}
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]);
- } else {
- assertErrors(source, [StaticWarningCode.INVALID_OVERRIDE_POSITIONAL]);
- }
+ assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]);
verify([source]);
}
@@ -2456,11 +2309,7 @@
m(a, b, [c]) {}
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]);
- } else {
- assertErrors(source, [StaticWarningCode.INVALID_OVERRIDE_POSITIONAL]);
- }
+ assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]);
verify([source]);
}
@@ -2473,11 +2322,7 @@
m(a, [c, d]) {}
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]);
- } else {
- assertErrors(source, [StaticWarningCode.INVALID_OVERRIDE_POSITIONAL]);
- }
+ assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]);
verify([source]);
}
@@ -2490,11 +2335,7 @@
m(a, b) {}
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]);
- } else {
- assertErrors(source, [StaticWarningCode.INVALID_OVERRIDE_REQUIRED]);
- }
+ assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]);
verify([source]);
}
@@ -2507,12 +2348,7 @@
void set s(String v) {}
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]);
- } else {
- assertErrors(source,
- [StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE]);
- }
+ assertErrors(source, [CompileTimeErrorCode.INVALID_OVERRIDE]);
verify([source]);
}
@@ -2529,15 +2365,10 @@
set setter14(String _) => null;
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(source, [
- CompileTimeErrorCode.INVALID_OVERRIDE,
- CompileTimeErrorCode.INVALID_OVERRIDE,
- ]);
- } else {
- assertErrors(source,
- [StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE]);
- }
+ assertErrors(source, [
+ CompileTimeErrorCode.INVALID_OVERRIDE,
+ CompileTimeErrorCode.INVALID_OVERRIDE,
+ ]);
verify([source]);
}
@@ -2555,15 +2386,10 @@
set setter14(String _) => null;
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(source, [
- CompileTimeErrorCode.INVALID_OVERRIDE,
- CompileTimeErrorCode.INVALID_OVERRIDE
- ]);
- } else {
- assertErrors(source,
- [StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE]);
- }
+ assertErrors(source, [
+ CompileTimeErrorCode.INVALID_OVERRIDE,
+ CompileTimeErrorCode.INVALID_OVERRIDE
+ ]);
verify([source]);
}
@@ -2579,15 +2405,10 @@
set s(double d) {}
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(source, [
- CompileTimeErrorCode.INVALID_OVERRIDE,
- CompileTimeErrorCode.INVALID_OVERRIDE
- ]);
- } else {
- assertErrors(source,
- [StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE]);
- }
+ assertErrors(source, [
+ CompileTimeErrorCode.INVALID_OVERRIDE,
+ CompileTimeErrorCode.INVALID_OVERRIDE
+ ]);
verify([source]);
}
@@ -2653,14 +2474,7 @@
}
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertErrors(source, [StaticWarningCode.RETURN_WITHOUT_VALUE]);
- } else {
- assertErrors(source, [
- StaticWarningCode.MIXED_RETURN_TYPES,
- StaticWarningCode.MIXED_RETURN_TYPES
- ]);
- }
+ assertErrors(source, [StaticWarningCode.RETURN_WITHOUT_VALUE]);
verify([source]);
}
@@ -3451,11 +3265,15 @@
Null f() {return;}
''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertNoErrors(source);
- } else {
- assertErrors(source, [StaticWarningCode.RETURN_WITHOUT_VALUE]);
- }
+ assertNoErrors(source);
+ }
+
+ @failingTest
+ test_setElementTypeNotAssignable() async {
+ Source source = addSource("var v = <String>{42};");
+ await computeAnalysisResult(source);
+ assertErrors(source, [StaticWarningCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE]);
+ verify([source]);
}
test_staticAccessToInstanceMember_method_invocation() async {
@@ -3813,11 +3631,7 @@
}
}''');
await computeAnalysisResult(source);
- if (previewDart2) {
- assertNoErrors(source);
- } else {
- assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
- }
+ assertNoErrors(source);
}
test_typeTestNonType() async {
@@ -3974,29 +3788,6 @@
assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
}
- test_undefinedStaticMethodOrGetter_method() async {
- Source source = addSource(r'''
-class C {}
-f(var p) {
- f(C.m());
-}''');
- await computeAnalysisResult(source);
- assertErrors(source, [StaticTypeWarningCode.UNDEFINED_METHOD]);
- }
-
- test_undefinedStaticMethodOrGetter_method_inSuperclass() async {
- Source source = addSource(r'''
-class S {
- static m() {}
-}
-class C extends S {}
-f(var p) {
- f(C.m());
-}''');
- await computeAnalysisResult(source);
- assertErrors(source, [StaticTypeWarningCode.UNDEFINED_METHOD]);
- }
-
test_undefinedStaticMethodOrGetter_setter_inSuperclass() async {
Source source = addSource(r'''
class S {
diff --git a/pkg/analyzer/test/generated/strong_mode_test.dart b/pkg/analyzer/test/generated/strong_mode_test.dart
index 70a60b6..6b9af7e 100644
--- a/pkg/analyzer/test/generated/strong_mode_test.dart
+++ b/pkg/analyzer/test/generated/strong_mode_test.dart
@@ -2909,7 +2909,7 @@
}
/// Test cases for [StrongModeStaticTypeAnalyzer2Test]
-abstract class StrongModeStaticTypeAnalyzer2TestCases
+mixin StrongModeStaticTypeAnalyzer2TestCases
implements StaticTypeAnalyzer2TestShared {
void expectStaticInvokeType(String search, String type) {
var invocation = findIdentifier(search).parent as MethodInvocation;
@@ -2927,17 +2927,6 @@
expectInitializerType('foo', 'int');
}
- test_dynamicObjectMethod_toString() async {
- String code = r'''
-main() {
- dynamic a = null;
- var foo = a.toString();
-}
-''';
- await resolveTestUnit(code);
- expectInitializerType('foo', 'String');
- }
-
test_futureOr_promotion1() async {
// Test that promotion from FutureOr<T> to T works for concrete types
String code = r'''
@@ -3612,22 +3601,6 @@
verify([source]);
}
- test_genericMethod_partiallyAppliedErrorWithBound() async {
- await resolveTestUnit(r'''
-void f<X extends List, Y>() => null;
-
-void test() {
- f<int>();
-}
-''', noErrors: false);
- assertErrors(testSource, [
- // Make sure to catch both the missing parameter:
- StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD,
- // And the incorrect parameter:
- StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
- ]);
- }
-
test_genericMethod_propagatedType_promotion() async {
// Regression test for:
// https://github.com/dart-lang/sdk/issues/25340
diff --git a/pkg/analyzer/test/generated/test_all.dart b/pkg/analyzer/test/generated/test_all.dart
index 3b976b4..ac07574 100644
--- a/pkg/analyzer/test/generated/test_all.dart
+++ b/pkg/analyzer/test/generated/test_all.dart
@@ -5,7 +5,6 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'all_the_rest_test.dart' as all_the_rest;
-import 'bazel_test.dart' as bazel_test;
import 'checked_mode_compile_time_error_code_driver_test.dart'
as checked_mode_compile_time_error_code_driver_test;
import 'checked_mode_compile_time_error_code_test.dart'
@@ -19,7 +18,6 @@
import 'engine_test.dart' as engine_test;
import 'error_suppression_driver_test.dart' as error_suppression_driver_test;
import 'error_suppression_test.dart' as error_suppression_test;
-import 'gn_test.dart' as gn_test;
import 'hint_code_driver_test.dart' as hint_code_driver_test;
import 'hint_code_test.dart' as hint_code_test;
import 'inheritance_manager_test.dart' as inheritance_manager_test;
@@ -31,8 +29,6 @@
import 'non_error_resolver_test.dart' as non_error_resolver_test;
import 'non_hint_code_driver_test.dart' as non_hint_code_driver_test;
import 'non_hint_code_test.dart' as non_hint_code_test;
-import 'package_build_test.dart' as package_build_test;
-import 'package_test.dart' as package_test;
import 'parser_fasta_test.dart' as parser_fasta_test;
import 'parser_test.dart' as parser_test;
import 'resolver_driver_test.dart' as resolver_driver_test;
@@ -59,7 +55,6 @@
main() {
defineReflectiveSuite(() {
all_the_rest.main();
- bazel_test.main();
checked_mode_compile_time_error_code_driver_test.main();
checked_mode_compile_time_error_code_test.main();
compile_time_error_code_driver_test.main();
@@ -70,7 +65,6 @@
engine_test.main();
error_suppression_driver_test.main();
error_suppression_test.main();
- gn_test.main();
hint_code_driver_test.main();
hint_code_test.main();
inheritance_manager_test.main();
@@ -82,8 +76,6 @@
non_error_resolver_test.main();
non_hint_code_driver_test.main();
non_hint_code_test.main();
- package_build_test.main();
- package_test.main();
parser_fasta_test.main();
parser_test.main();
resolver_driver_test.main();
diff --git a/pkg/analyzer/test/generated/test_support.dart b/pkg/analyzer/test/generated/test_support.dart
index 8a6e9d4..e44dd22 100644
--- a/pkg/analyzer/test/generated/test_support.dart
+++ b/pkg/analyzer/test/generated/test_support.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -133,7 +133,7 @@
throw new ArgumentError("Not found '$prefix'.");
}
AstNode node = new NodeLocator(offset).searchWithin(root);
- return node.getAncestor(predicate);
+ return node.thisOrAncestorMatching(predicate);
}
/**
diff --git a/pkg/analyzer/test/generated/type_system_test.dart b/pkg/analyzer/test/generated/type_system_test.dart
index 67110dd..b682c79 100644
--- a/pkg/analyzer/test/generated/type_system_test.dart
+++ b/pkg/analyzer/test/generated/type_system_test.dart
@@ -1,25 +1,26 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2015, 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.
// Tests related to the [TypeSystem] class.
-import 'package:analyzer/analyzer.dart'
- show ErrorReporter, ParameterKind, StrongModeCode;
import 'package:analyzer/dart/ast/standard_ast_factory.dart' show astFactory;
import 'package:analyzer/dart/ast/token.dart' show Keyword;
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/error/listener.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/dart/ast/token.dart' show KeywordToken;
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source.dart'
show NonExistingSource, UriKind;
import 'package:analyzer/src/generated/testing/element_factory.dart';
import 'package:analyzer/src/generated/testing/test_type_provider.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:path/path.dart' show toUri;
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analyzer/test/parse_compilation_unit_test.dart b/pkg/analyzer/test/parse_compilation_unit_test.dart
index a916d00..74a0179 100644
--- a/pkg/analyzer/test/parse_compilation_unit_test.dart
+++ b/pkg/analyzer/test/parse_compilation_unit_test.dart
@@ -2,6 +2,7 @@
// 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.
+// ignore: deprecated_member_use
import 'package:analyzer/analyzer.dart';
import 'package:test/test.dart';
diff --git a/pkg/analyzer/test/source/sdk_ext_test.dart b/pkg/analyzer/test/source/sdk_ext_test.dart
index b09c36b..4f542d1 100644
--- a/pkg/analyzer/test/source/sdk_ext_test.dart
+++ b/pkg/analyzer/test/source/sdk_ext_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/source/sdk_ext.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -15,9 +15,7 @@
}
@reflectiveTest
-class SdkExtUriResolverTest {
- MemoryResourceProvider resourceProvider;
-
+class SdkExtUriResolverTest with ResourceProviderMixin {
void setUp() {
String joinAndEscape(List<String> components) {
return resourceProvider.pathContext
@@ -25,10 +23,9 @@
.replaceAll(r'\', r'\\');
}
- resourceProvider = new MemoryResourceProvider();
- resourceProvider.newFolder(resourceProvider.convertPath('/empty'));
- resourceProvider.newFolder(resourceProvider.convertPath('/tmp'));
- resourceProvider.newFile(resourceProvider.convertPath('/tmp/_sdkext'), '''
+ newFolder('/empty');
+ newFolder('/tmp');
+ newFile('/tmp/_sdkext', content: '''
{
"dart:fox": "slippy.dart",
"dart:bear": "grizzly.dart",
@@ -41,47 +38,37 @@
test_create_badJSON() {
var resolver = new SdkExtUriResolver(null);
resolver.addSdkExt(r'''{{{,{{}}},}}''', null);
- expect(resolver.length, equals(0));
+ expect(resolver.length, 0);
}
test_create_noSdkExtPackageMap() {
var resolver = new SdkExtUriResolver({
- 'fox': <Folder>[
- resourceProvider.getFolder(resourceProvider.convertPath('/empty'))
- ]
+ 'fox': <Folder>[getFolder('/empty')]
});
- expect(resolver.length, equals(0));
+ expect(resolver.length, 0);
}
test_create_nullPackageMap() {
var resolver = new SdkExtUriResolver(null);
- expect(resolver.length, equals(0));
+ expect(resolver.length, 0);
}
test_create_sdkExtPackageMap() {
var resolver = new SdkExtUriResolver({
- 'fox': <Folder>[
- resourceProvider.newFolder(resourceProvider.convertPath('/tmp'))
- ]
+ 'fox': <Folder>[newFolder('/tmp')]
});
// We have four mappings.
- expect(resolver.length, equals(4));
+ expect(resolver.length, 4);
// Check that they map to the correct paths.
- expect(resolver['dart:fox'],
- equals(resourceProvider.convertPath('/tmp/slippy.dart')));
- expect(resolver['dart:bear'],
- equals(resourceProvider.convertPath('/tmp/grizzly.dart')));
- expect(resolver['dart:relative'],
- equals(resourceProvider.convertPath('/relative.dart')));
- expect(resolver['dart:deep'],
- equals(resourceProvider.convertPath('/tmp/deep/directory/file.dart')));
+ expect(resolver['dart:fox'], convertPath('/tmp/slippy.dart'));
+ expect(resolver['dart:bear'], convertPath('/tmp/grizzly.dart'));
+ expect(resolver['dart:relative'], convertPath('/relative.dart'));
+ expect(resolver['dart:deep'], convertPath('/tmp/deep/directory/file.dart'));
}
test_restoreAbsolute() {
var resolver = new SdkExtUriResolver({
- 'fox': <Folder>[
- resourceProvider.newFolder(resourceProvider.convertPath('/tmp'))
- ]
+ 'fox': <Folder>[newFolder('/tmp')]
});
var source = resolver.resolveAbsolute(Uri.parse('dart:fox'));
expect(source, isNotNull);
@@ -89,8 +76,8 @@
var restoreUri = resolver.restoreAbsolute(source);
expect(restoreUri, isNotNull);
// Verify that it is 'dart:fox'.
- expect(restoreUri.toString(), equals('dart:fox'));
- expect(restoreUri.scheme, equals('dart'));
- expect(restoreUri.path, equals('fox'));
+ expect(restoreUri.toString(), 'dart:fox');
+ expect(restoreUri.scheme, 'dart');
+ expect(restoreUri.path, 'fox');
}
}
diff --git a/pkg/analyzer/test/src/abstract_single_unit.dart b/pkg/analyzer/test/src/abstract_single_unit.dart
index f8fbb79..164b2f5 100644
--- a/pkg/analyzer/test/src/abstract_single_unit.dart
+++ b/pkg/analyzer/test/src/abstract_single_unit.dart
@@ -51,7 +51,7 @@
AstNode findNodeAtOffset(int offset, [Predicate<AstNode> predicate]) {
AstNode result = new NodeLocator(offset).searchWithin(testUnit);
if (result != null && predicate != null) {
- result = result.getAncestor(predicate);
+ result = result.thisOrAncestorMatching(predicate);
}
return result;
}
diff --git a/pkg/analyzer/test/src/command_line/arguments_test.dart b/pkg/analyzer/test/src/command_line/arguments_test.dart
index c612c12..3662f70 100644
--- a/pkg/analyzer/test/src/command_line/arguments_test.dart
+++ b/pkg/analyzer/test/src/command_line/arguments_test.dart
@@ -2,12 +2,12 @@
// 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:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/command_line/arguments.dart';
import 'package:analyzer/src/context/builder.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:args/args.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -19,27 +19,25 @@
}
@reflectiveTest
-class ArgumentsTest {
+class ArgumentsTest with ResourceProviderMixin {
void test_createContextBuilderOptions_all() {
String dartSdkSummaryPath = 'a';
String defaultAnalysisOptionsFilePath = 'b';
String defaultPackageFilePath = 'c';
String defaultPackagesDirectoryPath = 'd';
- MemoryResourceProvider provider = new MemoryResourceProvider();
ArgParser parser = new ArgParser();
defineAnalysisArguments(parser);
List<String> args = [
'--dart-sdk-summary=$dartSdkSummaryPath',
'-Dfoo=1',
'-Dbar=2',
- '--no-declaration-casts',
'--no-implicit-casts',
'--no-implicit-dynamic',
'--options=$defaultAnalysisOptionsFilePath',
'--packages=$defaultPackageFilePath',
'--package-root=$defaultPackagesDirectoryPath',
];
- ArgResults result = parse(provider, parser, args);
+ ArgResults result = parse(resourceProvider, parser, args);
ContextBuilderOptions options = createContextBuilderOptions(result);
expect(options, isNotNull);
expect(options.dartSdkSummaryPath, dartSdkSummaryPath);
@@ -54,17 +52,15 @@
AnalysisOptionsImpl defaultOptions = options.defaultOptions;
expect(defaultOptions, isNotNull);
expect(defaultOptions.strongMode, true);
- expect(defaultOptions.declarationCasts, false);
expect(defaultOptions.implicitCasts, false);
expect(defaultOptions.implicitDynamic, false);
}
void test_createContextBuilderOptions_none() {
- MemoryResourceProvider provider = new MemoryResourceProvider();
ArgParser parser = new ArgParser();
defineAnalysisArguments(parser);
List<String> args = [];
- ArgResults result = parse(provider, parser, args);
+ ArgResults result = parse(resourceProvider, parser, args);
ContextBuilderOptions options = createContextBuilderOptions(result);
expect(options, isNotNull);
expect(options.dartSdkSummaryPath, isNull);
@@ -74,79 +70,61 @@
expect(options.defaultPackagesDirectoryPath, isNull);
AnalysisOptionsImpl defaultOptions = options.defaultOptions;
expect(defaultOptions, isNotNull);
- expect(defaultOptions.strongMode, defaultOptions.previewDart2);
- expect(defaultOptions.declarationCasts, true);
+ expect(defaultOptions.strongMode, true);
expect(defaultOptions.implicitCasts, true);
expect(defaultOptions.implicitDynamic, true);
}
void test_createDartSdkManager_noPath_noSummaries() {
- MemoryResourceProvider provider = new MemoryResourceProvider();
ArgParser parser = new ArgParser();
defineAnalysisArguments(parser);
List<String> args = [];
- ArgResults result = parse(provider, parser, args);
- DartSdkManager manager = createDartSdkManager(provider, false, result);
+ ArgResults result = parse(resourceProvider, parser, args);
+ DartSdkManager manager =
+ createDartSdkManager(resourceProvider, false, result);
expect(manager, isNotNull);
expect(manager.defaultSdkDirectory,
- FolderBasedDartSdk.defaultSdkDirectory(provider));
+ FolderBasedDartSdk.defaultSdkDirectory(resourceProvider));
expect(manager.canUseSummaries, false);
}
void test_createDartSdkManager_noPath_summaries() {
- MemoryResourceProvider provider = new MemoryResourceProvider();
ArgParser parser = new ArgParser();
defineAnalysisArguments(parser);
List<String> args = [];
- ArgResults result = parse(provider, parser, args);
- DartSdkManager manager = createDartSdkManager(provider, true, result);
+ ArgResults result = parse(resourceProvider, parser, args);
+ DartSdkManager manager =
+ createDartSdkManager(resourceProvider, true, result);
expect(manager, isNotNull);
expect(manager.defaultSdkDirectory,
- FolderBasedDartSdk.defaultSdkDirectory(provider));
+ FolderBasedDartSdk.defaultSdkDirectory(resourceProvider));
expect(manager.canUseSummaries, true);
}
void test_createDartSdkManager_path_noSummaries() {
- MemoryResourceProvider provider = new MemoryResourceProvider();
ArgParser parser = new ArgParser();
defineAnalysisArguments(parser);
List<String> args = ['--dart-sdk=x'];
- ArgResults result = parse(provider, parser, args);
- DartSdkManager manager = createDartSdkManager(provider, false, result);
+ ArgResults result = parse(resourceProvider, parser, args);
+ DartSdkManager manager =
+ createDartSdkManager(resourceProvider, false, result);
expect(manager, isNotNull);
expect(manager.defaultSdkDirectory, 'x');
expect(manager.canUseSummaries, false);
}
void test_createDartSdkManager_path_summaries() {
- MemoryResourceProvider provider = new MemoryResourceProvider();
ArgParser parser = new ArgParser();
defineAnalysisArguments(parser);
List<String> args = ['--dart-sdk=y'];
- ArgResults result = parse(provider, parser, args);
- DartSdkManager manager = createDartSdkManager(provider, true, result);
+ ArgResults result = parse(resourceProvider, parser, args);
+ DartSdkManager manager =
+ createDartSdkManager(resourceProvider, true, result);
expect(manager, isNotNull);
expect(manager.defaultSdkDirectory, 'y');
expect(manager.canUseSummaries, true);
}
- void test_declarationCast_noImplicitCast() {
- MemoryResourceProvider provider = new MemoryResourceProvider();
- ArgParser parser = new ArgParser();
- defineAnalysisArguments(parser);
- List<String> args = [
- '--declaration-casts',
- '--no-implicit-casts',
- ];
- ArgResults result = parse(provider, parser, args);
- ContextBuilderOptions options = createContextBuilderOptions(result);
- expect(options, isNotNull);
- AnalysisOptionsImpl defaultOptions = options.defaultOptions;
- expect(defaultOptions, isNotNull);
- expect(defaultOptions.declarationCasts, true);
- expect(defaultOptions.implicitCasts, false);
- }
-
void test_defineAnalysisArguments() {
ArgParser parser = new ArgParser();
defineAnalysisArguments(parser);
@@ -179,62 +157,40 @@
expect(result, orderedEquals(['--a', '--c=0', '-e=2', '-f', 'bar']));
}
- void test_noAssignmentCast() {
- MemoryResourceProvider provider = new MemoryResourceProvider();
+ void test_implicitCast() {
ArgParser parser = new ArgParser();
defineAnalysisArguments(parser);
List<String> args = [
- '--no-declaration-casts',
- ];
- ArgResults result = parse(provider, parser, args);
- ContextBuilderOptions options = createContextBuilderOptions(result);
- expect(options, isNotNull);
- AnalysisOptionsImpl defaultOptions = options.defaultOptions;
- expect(defaultOptions, isNotNull);
- expect(defaultOptions.declarationCasts, false);
- expect(defaultOptions.implicitCasts, true);
- }
-
- void test_noAssignmentCast_implicitCast() {
- MemoryResourceProvider provider = new MemoryResourceProvider();
- ArgParser parser = new ArgParser();
- defineAnalysisArguments(parser);
- List<String> args = [
- '--no-declaration-casts',
'--implicit-casts',
];
- ArgResults result = parse(provider, parser, args);
+ ArgResults result = parse(resourceProvider, parser, args);
ContextBuilderOptions options = createContextBuilderOptions(result);
expect(options, isNotNull);
AnalysisOptionsImpl defaultOptions = options.defaultOptions;
expect(defaultOptions, isNotNull);
- expect(defaultOptions.declarationCasts, false);
expect(defaultOptions.implicitCasts, true);
}
void test_noImplicitCast() {
- MemoryResourceProvider provider = new MemoryResourceProvider();
ArgParser parser = new ArgParser();
defineAnalysisArguments(parser);
List<String> args = [
'--no-implicit-casts',
];
- ArgResults result = parse(provider, parser, args);
+ ArgResults result = parse(resourceProvider, parser, args);
ContextBuilderOptions options = createContextBuilderOptions(result);
expect(options, isNotNull);
AnalysisOptionsImpl defaultOptions = options.defaultOptions;
expect(defaultOptions, isNotNull);
- expect(defaultOptions.declarationCasts, false);
expect(defaultOptions.implicitCasts, false);
}
void test_parse_noReplacement_noIgnored() {
- MemoryResourceProvider provider = new MemoryResourceProvider();
ArgParser parser = new ArgParser();
parser.addFlag('xx');
parser.addOption('yy');
List<String> args = ['--xx', '--yy=abc', 'foo', 'bar'];
- ArgResults result = parse(provider, parser, args);
+ ArgResults result = parse(resourceProvider, parser, args);
expect(result, isNotNull);
expect(result['xx'], true);
expect(result['yy'], 'abc');
@@ -242,17 +198,15 @@
}
void test_preprocessArgs_noReplacement() {
- MemoryResourceProvider provider = new MemoryResourceProvider();
List<String> original = ['--xx' '--yy' 'baz'];
- List<String> result = preprocessArgs(provider, original);
+ List<String> result = preprocessArgs(resourceProvider, original);
expect(result, orderedEquals(original));
expect(identical(original, result), isFalse);
}
void test_preprocessArgs_replacement_exists() {
- MemoryResourceProvider provider = new MemoryResourceProvider();
- String filePath = provider.convertPath('/args.txt');
- provider.newFile(filePath, '''
+ String filePath = convertPath('/args.txt');
+ newFile(filePath, content: '''
-a
--xx
@@ -260,16 +214,15 @@
bar
''');
List<String> result =
- preprocessArgs(provider, ['--preserved', '@$filePath']);
+ preprocessArgs(resourceProvider, ['--preserved', '@$filePath']);
expect(result, orderedEquals(['--preserved', '-a', '--xx', 'foo', 'bar']));
}
void test_preprocessArgs_replacement_nonexistent() {
- MemoryResourceProvider provider = new MemoryResourceProvider();
- String filePath = provider.convertPath('/args.txt');
+ String filePath = convertPath('/args.txt');
List<String> args = ['ignored', '@$filePath'];
try {
- preprocessArgs(provider, args);
+ preprocessArgs(resourceProvider, args);
fail('Expect exception');
} on Exception catch (e) {
expect(e.toString(), contains('Failed to read file'));
@@ -278,10 +231,9 @@
}
void test_preprocessArgs_replacement_notLast() {
- MemoryResourceProvider provider = new MemoryResourceProvider();
- String filePath = provider.convertPath('/args.txt');
+ String filePath = convertPath('/args.txt');
List<String> args = ['a', '@$filePath', 'b'];
- List<String> result = preprocessArgs(provider, args);
+ List<String> result = preprocessArgs(resourceProvider, args);
expect(result, orderedEquals(args));
}
}
diff --git a/pkg/analyzer/test/src/context/abstract_context.dart b/pkg/analyzer/test/src/context/abstract_context.dart
index eb77d7e..131646e 100644
--- a/pkg/analyzer/test/src/context/abstract_context.dart
+++ b/pkg/analyzer/test/src/context/abstract_context.dart
@@ -6,7 +6,6 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/visitor.dart';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/context/context.dart';
import 'package:analyzer/src/file_system/file_system.dart';
@@ -15,12 +14,12 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/driver.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:plugin/manager.dart';
import 'package:plugin/plugin.dart';
import 'package:test/test.dart';
-import 'mock_sdk.dart';
-
/**
* Finds an [Element] with the given [name].
*/
@@ -43,12 +42,7 @@
*/
typedef void _ElementVisitorFunction(Element element);
-class AbstractContextTest {
- static final MockSdk SHARED_MOCK_SDK = new MockSdk();
- static final MockSdk SHARED_STRONG_MOCK_SDK = new MockSdk();
-
- MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
-
+class AbstractContextTest with ResourceProviderMixin {
DartSdk sdk;
SourceFactory sourceFactory;
AnalysisContextImpl context;
@@ -125,8 +119,7 @@
DartSdk createDartSdk() => new MockSdk(resourceProvider: resourceProvider);
Source newSource(String path, [String content = '']) {
- File file =
- resourceProvider.newFile(resourceProvider.convertPath(path), content);
+ File file = newFile(path, content: content);
return file.createSource();
}
diff --git a/pkg/analyzer/test/src/context/builder_test.dart b/pkg/analyzer/test/src/context/builder_test.dart
index 45d21f0..3594512 100644
--- a/pkg/analyzer/test/src/context/builder_test.dart
+++ b/pkg/analyzer/test/src/context/builder_test.dart
@@ -1,15 +1,13 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/command_line/arguments.dart';
import 'package:analyzer/src/context/builder.dart';
import 'package:analyzer/src/context/context_root.dart';
import 'package:analyzer/src/context/source.dart';
import 'package:analyzer/src/file_system/file_system.dart';
-import 'package:analyzer/src/generated/bazel.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
@@ -17,6 +15,9 @@
import 'package:analyzer/src/lint/registry.dart';
import 'package:analyzer/src/services/lint.dart';
import 'package:analyzer/src/source/package_map_resolver.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:analyzer/src/workspace/bazel.dart';
import 'package:args/args.dart';
import 'package:package_config/packages.dart';
import 'package:package_config/src/packages_impl.dart';
@@ -26,7 +27,6 @@
import '../../embedder_tests.dart';
import '../../generated/test_support.dart';
-import 'mock_sdk.dart';
main() {
defineReflectiveSuite(() {
@@ -36,17 +36,7 @@
}
@reflectiveTest
-class ContextBuilderTest extends EngineTestCase {
- /**
- * The resource provider to be used by tests.
- */
- MemoryResourceProvider resourceProvider;
-
- /**
- * The path context used to manipulate file paths.
- */
- path.Context pathContext;
-
+class ContextBuilderTest extends EngineTestCase with ResourceProviderMixin {
/**
* The SDK manager used by the tests;
*/
@@ -79,15 +69,15 @@
_MockLintRule _mockPublicMemberApiDocs;
Uri convertedDirectoryUri(String directoryPath) {
- return new Uri.directory(resourceProvider.convertPath(directoryPath),
- windows: pathContext.style == path.windows.style);
+ return new Uri.directory(convertPath(directoryPath),
+ windows: resourceProvider.pathContext.style == path.windows.style);
}
void createDefaultSdk(Folder sdkDir) {
- defaultSdkPath = pathContext.join(sdkDir.path, 'default', 'sdk');
- String librariesFilePath = pathContext.join(defaultSdkPath, 'lib',
- '_internal', 'sdk_library_metadata', 'lib', 'libraries.dart');
- resourceProvider.newFile(librariesFilePath, r'''
+ defaultSdkPath = join(sdkDir.path, 'default', 'sdk');
+ String librariesFilePath = join(defaultSdkPath, 'lib', '_internal',
+ 'sdk_library_metadata', 'lib', 'libraries.dart');
+ newFile(librariesFilePath, content: r'''
const Map<String, LibraryInfo> libraries = const {
"async": const LibraryInfo("async/async.dart"),
"core": const LibraryInfo("core/core.dart"),
@@ -98,20 +88,17 @@
options: builderOptions);
}
- void createFile(String path, String content) {
- resourceProvider.newFile(path, content);
- }
-
@override
void setUp() {
- resourceProvider = new MemoryResourceProvider();
- pathContext = resourceProvider.pathContext;
new MockSdk(resourceProvider: resourceProvider);
- sdkManager =
- new DartSdkManager(resourceProvider.convertPath('/sdk'), false);
+ sdkManager = new DartSdkManager(convertPath('/sdk'), false);
contentCache = new ContentCache();
- builder = new ContextBuilder(resourceProvider, sdkManager, contentCache,
- options: builderOptions);
+ builder = new ContextBuilder(
+ resourceProvider,
+ sdkManager,
+ contentCache,
+ options: builderOptions,
+ );
}
@failingTest
@@ -131,11 +118,9 @@
expected.lint = true;
expected.lintRules = Registry.ruleRegistry.defaultRules;
- String path = resourceProvider.convertPath('/some/directory/path');
- String filePath =
- pathContext.join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
- resourceProvider.newFile(filePath, '''
-''');
+ String path = convertPath('/some/directory/path');
+ String filePath = join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
+ newFile(filePath);
AnalysisOptions options = builder.getAnalysisOptions(path);
_expectEqualOptions(options, expected);
@@ -155,10 +140,9 @@
Registry.ruleRegistry['mock_lint_rule'],
];
- String path = resourceProvider.convertPath('/some/directory/path');
- String filePath =
- pathContext.join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
- resourceProvider.newFile(filePath, '''
+ String path = convertPath('/some/directory/path');
+ String filePath = join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
+ newFile(filePath, content: '''
linter:
rules:
- mock_lint_rule
@@ -181,10 +165,9 @@
Registry.ruleRegistry['mock_lint_rule'],
];
- String path = resourceProvider.convertPath('/some/directory/path');
- String filePath =
- pathContext.join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
- resourceProvider.newFile(filePath, '''
+ String path = convertPath('/some/directory/path');
+ String filePath = join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
+ newFile(filePath, content: '''
linter:
rules:
- mock_lint_rule
@@ -207,10 +190,9 @@
Registry.ruleRegistry['mock_lint_rule'],
];
- String path = resourceProvider.convertPath('/some/directory/path');
- String filePath =
- pathContext.join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
- resourceProvider.newFile(filePath, '''
+ String path = convertPath('/some/directory/path');
+ String filePath = join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
+ newFile(filePath, content: '''
linter:
rules:
- mock_lint_rule
@@ -231,10 +213,9 @@
expected.lint = false;
expected.lintRules = <LintRule>[];
- String path = resourceProvider.convertPath('/some/directory/path');
- String filePath =
- pathContext.join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
- resourceProvider.newFile(filePath, '''
+ String path = convertPath('/some/directory/path');
+ String filePath = join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
+ newFile(filePath, content: '''
''');
AnalysisOptions options = builder.getAnalysisOptions(path);
@@ -251,15 +232,15 @@
// options: createContextBuilderOptions(argResults));
//
// AnalysisOptionsImpl expected = new AnalysisOptionsImpl();
-// expected.previewDart2 = true;
+// expected.option = true;
//
// String path = resourceProvider.convertPath('/some/directory/path');
// String filePath =
-// pathContext.join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
+// join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
// resourceProvider.newFile(filePath, '''
//analyzer:
// language:
-// enablePreviewDart2: true
+// option: true
//''');
//
// AnalysisOptions options = builder.getAnalysisOptions(path);
@@ -276,11 +257,11 @@
void test_convertPackagesToMap_packages() {
String fooName = 'foo';
- String fooPath = resourceProvider.convertPath('/pkg/foo');
- Uri fooUri = pathContext.toUri(fooPath);
+ String fooPath = convertPath('/pkg/foo');
+ Uri fooUri = resourceProvider.pathContext.toUri(fooPath);
String barName = 'bar';
- String barPath = resourceProvider.convertPath('/pkg/bar');
- Uri barUri = pathContext.toUri(barPath);
+ String barPath = convertPath('/pkg/bar');
+ Uri barUri = resourceProvider.pathContext.toUri(barPath);
MapPackages packages = new MapPackages({fooName: fooUri, barName: barUri});
Map<String, List<Folder>> result = builder.convertPackagesToMap(packages);
@@ -311,16 +292,16 @@
void test_createPackageMap_fromPackageDirectory_explicit() {
// Use a package directory that is outside the project directory.
- String rootPath = resourceProvider.convertPath('/root');
- String projectPath = pathContext.join(rootPath, 'project');
- String packageDirPath = pathContext.join(rootPath, 'packages');
+ String rootPath = convertPath('/root');
+ String projectPath = join(rootPath, 'project');
+ String packageDirPath = join(rootPath, 'packages');
String fooName = 'foo';
- String fooPath = pathContext.join(packageDirPath, fooName);
+ String fooPath = join(packageDirPath, fooName);
String barName = 'bar';
- String barPath = pathContext.join(packageDirPath, barName);
- resourceProvider.newFolder(projectPath);
- resourceProvider.newFolder(fooPath);
- resourceProvider.newFolder(barPath);
+ String barPath = join(packageDirPath, barName);
+ newFolder(projectPath);
+ newFolder(fooPath);
+ newFolder(barPath);
builderOptions.defaultPackagesDirectoryPath = packageDirPath;
@@ -334,14 +315,14 @@
void test_createPackageMap_fromPackageDirectory_inRoot() {
// Use a package directory that is inside the project directory.
- String projectPath = resourceProvider.convertPath('/root/project');
- String packageDirPath = pathContext.join(projectPath, 'packages');
+ String projectPath = convertPath('/root/project');
+ String packageDirPath = join(projectPath, 'packages');
String fooName = 'foo';
- String fooPath = pathContext.join(packageDirPath, fooName);
+ String fooPath = join(packageDirPath, fooName);
String barName = 'bar';
- String barPath = pathContext.join(packageDirPath, barName);
- resourceProvider.newFolder(fooPath);
- resourceProvider.newFolder(barPath);
+ String barPath = join(packageDirPath, barName);
+ newFolder(fooPath);
+ newFolder(barPath);
Packages packages = builder.createPackageMap(projectPath);
expect(packages, isNotNull);
@@ -353,13 +334,13 @@
void test_createPackageMap_fromPackageFile_explicit() {
// Use a package file that is outside the project directory's hierarchy.
- String rootPath = resourceProvider.convertPath('/root');
- String projectPath = pathContext.join(rootPath, 'project');
- String packageFilePath = pathContext.join(rootPath, 'child', '.packages');
- resourceProvider.newFolder(projectPath);
+ String rootPath = convertPath('/root');
+ String projectPath = join(rootPath, 'project');
+ String packageFilePath = join(rootPath, 'child', '.packages');
+ newFolder(projectPath);
Uri fooUri = convertedDirectoryUri('/pkg/foo');
Uri barUri = convertedDirectoryUri('/pkg/bar');
- createFile(packageFilePath, '''
+ newFile(packageFilePath, content: '''
foo:$fooUri
bar:$barUri
''');
@@ -375,13 +356,13 @@
void test_createPackageMap_fromPackageFile_inParentOfRoot() {
// Use a package file that is inside the parent of the project directory.
- String rootPath = resourceProvider.convertPath('/root');
- String projectPath = pathContext.join(rootPath, 'project');
- String packageFilePath = pathContext.join(rootPath, '.packages');
- resourceProvider.newFolder(projectPath);
+ String rootPath = convertPath('/root');
+ String projectPath = join(rootPath, 'project');
+ String packageFilePath = join(rootPath, '.packages');
+ newFolder(projectPath);
Uri fooUri = convertedDirectoryUri('/pkg/foo');
Uri barUri = convertedDirectoryUri('/pkg/bar');
- createFile(packageFilePath, '''
+ newFile(packageFilePath, content: '''
foo:$fooUri
bar:$barUri
''');
@@ -396,13 +377,13 @@
void test_createPackageMap_fromPackageFile_inRoot() {
// Use a package file that is inside the project directory.
- String rootPath = resourceProvider.convertPath('/root');
- String projectPath = pathContext.join(rootPath, 'project');
- String packageFilePath = pathContext.join(projectPath, '.packages');
- resourceProvider.newFolder(projectPath);
+ String rootPath = convertPath('/root');
+ String projectPath = join(rootPath, 'project');
+ String packageFilePath = join(projectPath, '.packages');
+ newFolder(projectPath);
Uri fooUri = convertedDirectoryUri('/pkg/foo');
Uri barUri = convertedDirectoryUri('/pkg/bar');
- createFile(packageFilePath, '''
+ newFile(packageFilePath, content: '''
foo:$fooUri
bar:$barUri
''');
@@ -416,26 +397,24 @@
}
void test_createPackageMap_none() {
- String rootPath = resourceProvider.convertPath('/root');
- resourceProvider.newFolder(rootPath);
+ String rootPath = convertPath('/root');
+ newFolder(rootPath);
Packages packages = builder.createPackageMap(rootPath);
expect(packages, same(Packages.noPackages));
}
void test_createPackageMap_rootDoesNotExist() {
- String rootPath = resourceProvider.convertPath('/root');
+ String rootPath = convertPath('/root');
Packages packages = builder.createPackageMap(rootPath);
expect(packages, same(Packages.noPackages));
}
void test_createSourceFactory_bazelWorkspace_fileProvider() {
- String _p(String path) => resourceProvider.convertPath(path);
-
- String projectPath = _p('/workspace/my/module');
- resourceProvider.newFile(_p('/workspace/WORKSPACE'), '');
- resourceProvider.newFolder(_p('/workspace/bazel-bin'));
- resourceProvider.newFolder(_p('/workspace/bazel-genfiles'));
- resourceProvider.newFolder(projectPath);
+ String projectPath = convertPath('/workspace/my/module');
+ newFile('/workspace/WORKSPACE');
+ newFolder('/workspace/bazel-bin');
+ newFolder('/workspace/bazel-genfiles');
+ newFolder(projectPath);
AnalysisOptionsImpl options = new AnalysisOptionsImpl();
SourceFactoryImpl factory =
@@ -447,14 +426,12 @@
}
void test_createSourceFactory_bazelWorkspace_withPackagesFile() {
- String _p(String path) => resourceProvider.convertPath(path);
-
- String projectPath = _p('/workspace/my/module');
- resourceProvider.newFile(_p('/workspace/WORKSPACE'), '');
- resourceProvider.newFolder(_p('/workspace/bazel-bin'));
- resourceProvider.newFolder(_p('/workspace/bazel-genfiles'));
- resourceProvider.newFolder(projectPath);
- resourceProvider.newFile(_p(path.join(projectPath, '.packages')), '');
+ String projectPath = convertPath('/workspace/my/module');
+ newFile('/workspace/WORKSPACE');
+ newFolder('/workspace/bazel-bin');
+ newFolder('/workspace/bazel-genfiles');
+ newFolder(projectPath);
+ newFile(join(projectPath, '.packages'));
AnalysisOptionsImpl options = new AnalysisOptionsImpl();
SourceFactoryImpl factory =
@@ -466,28 +443,28 @@
}
void test_createSourceFactory_noProvider_packages_embedder_extensions() {
- String rootPath = resourceProvider.convertPath('/root');
- Folder rootFolder = resourceProvider.getFolder(rootPath);
+ String rootPath = convertPath('/root');
+ Folder rootFolder = getFolder(rootPath);
createDefaultSdk(rootFolder);
- String projectPath = pathContext.join(rootPath, 'project');
- String packageFilePath = pathContext.join(projectPath, '.packages');
- String packageA = pathContext.join(rootPath, 'pkgs', 'a');
- String embedderPath = pathContext.join(packageA, '_embedder.yaml');
- String packageB = pathContext.join(rootPath, 'pkgs', 'b');
- String extensionPath = pathContext.join(packageB, '_sdkext');
- createFile(packageFilePath, '''
-a:${pathContext.toUri(packageA)}
-b:${pathContext.toUri(packageB)}
+ String projectPath = join(rootPath, 'project');
+ String packageFilePath = join(projectPath, '.packages');
+ String packageA = join(rootPath, 'pkgs', 'a');
+ String embedderPath = join(packageA, '_embedder.yaml');
+ String packageB = join(rootPath, 'pkgs', 'b');
+ String extensionPath = join(packageB, '_sdkext');
+ newFile(packageFilePath, content: '''
+a:${resourceProvider.pathContext.toUri(packageA)}
+b:${resourceProvider.pathContext.toUri(packageB)}
''');
- String asyncPath = pathContext.join(packageA, 'sdk', 'async.dart');
- String corePath = pathContext.join(packageA, 'sdk', 'core.dart');
- createFile(embedderPath, '''
+ String asyncPath = join(packageA, 'sdk', 'async.dart');
+ String corePath = join(packageA, 'sdk', 'core.dart');
+ newFile(embedderPath, content: '''
embedded_libs:
"dart:async": ${_relativeUri(asyncPath, from: packageA)}
"dart:core": ${_relativeUri(corePath, from: packageA)}
''');
- String fooPath = pathContext.join(packageB, 'ext', 'foo.dart');
- createFile(extensionPath, '''{
+ String fooPath = join(packageB, 'ext', 'foo.dart');
+ newFile(extensionPath, content: '''{
"dart:foo": "${_relativeUri(fooPath, from: packageB)}"
}''');
AnalysisOptionsImpl options = new AnalysisOptionsImpl();
@@ -504,25 +481,25 @@
Source packageSource = factory.forUri('package:b/b.dart');
expect(packageSource, isNotNull);
- expect(packageSource.fullName, pathContext.join(packageB, 'b.dart'));
+ expect(packageSource.fullName, join(packageB, 'b.dart'));
}
void test_createSourceFactory_noProvider_packages_embedder_noExtensions() {
- String rootPath = resourceProvider.convertPath('/root');
- Folder rootFolder = resourceProvider.getFolder(rootPath);
+ String rootPath = convertPath('/root');
+ Folder rootFolder = getFolder(rootPath);
createDefaultSdk(rootFolder);
- String projectPath = pathContext.join(rootPath, 'project');
- String packageFilePath = pathContext.join(projectPath, '.packages');
- String packageA = pathContext.join(rootPath, 'pkgs', 'a');
- String embedderPath = pathContext.join(packageA, '_embedder.yaml');
- String packageB = pathContext.join(rootPath, 'pkgs', 'b');
- createFile(packageFilePath, '''
-a:${pathContext.toUri(packageA)}
-b:${pathContext.toUri(packageB)}
+ String projectPath = join(rootPath, 'project');
+ String packageFilePath = join(projectPath, '.packages');
+ String packageA = join(rootPath, 'pkgs', 'a');
+ String embedderPath = join(packageA, '_embedder.yaml');
+ String packageB = join(rootPath, 'pkgs', 'b');
+ newFile(packageFilePath, content: '''
+a:${resourceProvider.pathContext.toUri(packageA)}
+b:${resourceProvider.pathContext.toUri(packageB)}
''');
- String asyncPath = pathContext.join(packageA, 'sdk', 'async.dart');
- String corePath = pathContext.join(packageA, 'sdk', 'core.dart');
- createFile(embedderPath, '''
+ String asyncPath = join(packageA, 'sdk', 'async.dart');
+ String corePath = join(packageA, 'sdk', 'core.dart');
+ newFile(embedderPath, content: '''
embedded_libs:
"dart:async": ${_relativeUri(asyncPath, from: packageA)}
"dart:core": ${_relativeUri(corePath, from: packageA)}
@@ -537,7 +514,7 @@
Source packageSource = factory.forUri('package:b/b.dart');
expect(packageSource, isNotNull);
- expect(packageSource.fullName, pathContext.join(packageB, 'b.dart'));
+ expect(packageSource.fullName, join(packageB, 'b.dart'));
}
@failingTest
@@ -546,16 +523,16 @@
}
void test_createSourceFactory_noProvider_packages_noEmbedder_noExtensions() {
- String rootPath = resourceProvider.convertPath('/root');
- Folder rootFolder = resourceProvider.getFolder(rootPath);
+ String rootPath = convertPath('/root');
+ Folder rootFolder = getFolder(rootPath);
createDefaultSdk(rootFolder);
- String projectPath = pathContext.join(rootPath, 'project');
- String packageFilePath = pathContext.join(projectPath, '.packages');
- String packageA = pathContext.join(rootPath, 'pkgs', 'a');
- String packageB = pathContext.join(rootPath, 'pkgs', 'b');
- createFile(packageFilePath, '''
-a:${pathContext.toUri(packageA)}
-b:${pathContext.toUri(packageB)}
+ String projectPath = join(rootPath, 'project');
+ String packageFilePath = join(projectPath, '.packages');
+ String packageA = join(rootPath, 'pkgs', 'a');
+ String packageB = join(rootPath, 'pkgs', 'b');
+ newFile(packageFilePath, content: '''
+a:${resourceProvider.pathContext.toUri(packageA)}
+b:${resourceProvider.pathContext.toUri(packageB)}
''');
AnalysisOptionsImpl options = new AnalysisOptionsImpl();
@@ -563,12 +540,12 @@
Source dartSource = factory.forUri('dart:core');
expect(dartSource, isNotNull);
- expect(dartSource.fullName,
- pathContext.join(defaultSdkPath, 'lib', 'core', 'core.dart'));
+ expect(
+ dartSource.fullName, join(defaultSdkPath, 'lib', 'core', 'core.dart'));
Source packageSource = factory.forUri('package:a/a.dart');
expect(packageSource, isNotNull);
- expect(packageSource.fullName, pathContext.join(packageA, 'a.dart'));
+ expect(packageSource.fullName, join(packageA, 'a.dart'));
}
void test_declareVariables_emptyMap() {
@@ -633,10 +610,8 @@
DartSdk sdk = builder.findSdk(null, new AnalysisOptionsImpl());
expect(sdk, isNotNull);
Source htmlSource = sdk.mapDartUri('dart:html');
- expect(
- htmlSource.fullName,
- resourceProvider
- .convertPath('/sdk/lib/html/dart2js/html_dart2js.dart'));
+ expect(htmlSource.fullName,
+ convertPath('/sdk/lib/html/dart2js/html_dart2js.dart'));
expect(htmlSource.exists(), isTrue);
}
@@ -647,25 +622,19 @@
AnalysisOptionsImpl expected = new AnalysisOptionsImpl();
expected.lint = true;
expected.lintRules = <Linter>[_mockLintRule];
- createFile(resourceProvider.convertPath('/root/WORKSPACE'), '');
- createFile(
- resourceProvider
- .convertPath('/root/dart/analysis_options/lib/default.yaml'),
- '''
+ newFile('/root/WORKSPACE');
+ newFile('/root/dart/analysis_options/lib/default.yaml', content: '''
linter:
rules:
- mock_lint_rule
''');
- createFile(
- resourceProvider
- .convertPath('/root/dart/analysis_options/lib/flutter.yaml'),
- '''
+ newFile('/root/dart/analysis_options/lib/flutter.yaml', content: '''
linter:
rules:
- mock_lint_rule2
''');
- AnalysisOptions options = builder
- .getAnalysisOptions(resourceProvider.convertPath('/root/some/path'));
+ AnalysisOptions options =
+ builder.getAnalysisOptions(convertPath('/root/some/path'));
_expectEqualOptions(options, expected);
}
@@ -676,18 +645,15 @@
AnalysisOptionsImpl expected = new AnalysisOptionsImpl();
expected.lint = true;
expected.lintRules = <Linter>[_mockLintRule];
- String packagesFilePath =
- resourceProvider.convertPath('/some/directory/path/.packages');
- createFile(packagesFilePath, 'flutter:/pkg/flutter/lib/');
- String optionsFilePath = resourceProvider
- .convertPath('/pkg/flutter/lib/analysis_options_user.yaml');
- createFile(optionsFilePath, '''
+ String packagesFilePath = convertPath('/some/directory/path/.packages');
+ newFile(packagesFilePath, content: 'flutter:/pkg/flutter/lib/');
+ newFile('/pkg/flutter/lib/analysis_options_user.yaml', content: '''
linter:
rules:
- mock_lint_rule
''');
- String projPath = resourceProvider.convertPath('/some/directory/path');
- AnalysisOptions options = builder.getAnalysisOptions(projPath);
+ String projectPath = convertPath('/some/directory/path');
+ AnalysisOptions options = builder.getAnalysisOptions(projectPath);
_expectEqualOptions(options, expected);
}
@@ -697,10 +663,9 @@
builderOptions.defaultOptions = defaultOptions;
AnalysisOptionsImpl expected = new AnalysisOptionsImpl();
expected.enableLazyAssignmentOperators = true;
- String path = resourceProvider.convertPath('/some/directory/path');
- String filePath =
- pathContext.join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
- resourceProvider.newFile(filePath, '''
+ String path = convertPath('/some/directory/path');
+ String filePath = join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
+ newFile(filePath, content: '''
linter:
rules:
- empty_constructor_bodies
@@ -716,10 +681,9 @@
builderOptions.defaultOptions = defaultOptions;
AnalysisOptionsImpl expected = new AnalysisOptionsImpl();
expected.implicitDynamic = false;
- String path = resourceProvider.convertPath('/some/directory/path');
- String filePath =
- pathContext.join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
- resourceProvider.newFile(filePath, '''
+ String path = convertPath('/some/directory/path');
+ String filePath = join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
+ newFile(filePath, content: '''
analyzer:
strong-mode:
implicit-dynamic: false
@@ -730,13 +694,12 @@
}
void test_getAnalysisOptions_gnWorkspace() {
- String _p(String path) => resourceProvider.convertPath(path);
+ String _p(String path) => convertPath(path);
String projectPath = _p('/workspace/some/path');
- resourceProvider.newFolder(_p('/workspace/.jiri_root'));
- resourceProvider.newFile(
- _p('/workspace/out/debug/gen/dart.sources/foo_pkg'),
- _p('/workspace/foo_pkg/lib'));
- resourceProvider.newFolder(projectPath);
+ newFolder('/workspace/.jiri_root');
+ newFile('/workspace/out/debug/gen/dart.sources/foo_pkg',
+ content: _p('/workspace/foo_pkg/lib'));
+ newFolder(projectPath);
ArgParser argParser = new ArgParser();
defineAnalysisArguments(argParser);
ArgResults argResults = argParser.parse([]);
@@ -759,25 +722,23 @@
_mockLintRule2,
_mockLintRule3
];
- resourceProvider.newFile(
- resourceProvider.convertPath('/mypkgs/somepkg/lib/here.yaml'), '''
+ newFile('/mypkgs/somepkg/lib/here.yaml', content: '''
linter:
rules:
- mock_lint_rule3
''');
- String path = resourceProvider.convertPath('/some/directory/path');
- resourceProvider.newFile(pathContext.join(path, '.packages'), '''
+ String path = convertPath('/some/directory/path');
+ newFile(join(path, '.packages'), content: '''
somepkg:../../../mypkgs/somepkg/lib
''');
- resourceProvider.newFile(pathContext.join(path, 'bar.yaml'), '''
+ newFile(join(path, 'bar.yaml'), content: '''
include: package:somepkg/here.yaml
linter:
rules:
- mock_lint_rule2
''');
- String filePath =
- pathContext.join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
- resourceProvider.newFile(filePath, '''
+ String filePath = join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
+ newFile(filePath, content: '''
include: bar.yaml
linter:
rules:
@@ -789,20 +750,18 @@
}
void test_getAnalysisOptions_invalid() {
- String path = resourceProvider.convertPath('/some/directory/path');
- String filePath =
- pathContext.join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
- resourceProvider.newFile(filePath, ';');
+ String path = convertPath('/some/directory/path');
+ String filePath = join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
+ newFile(filePath, content: ';');
AnalysisOptions options = builder.getAnalysisOptions(path);
expect(options, isNotNull);
}
void test_getAnalysisOptions_noDefault_noOverrides() {
- String path = resourceProvider.convertPath('/some/directory/path');
- String filePath =
- pathContext.join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
- resourceProvider.newFile(filePath, '''
+ String path = convertPath('/some/directory/path');
+ String filePath = join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
+ newFile(filePath, content: '''
linter:
rules:
- empty_constructor_bodies
@@ -815,10 +774,9 @@
void test_getAnalysisOptions_noDefault_overrides() {
AnalysisOptionsImpl expected = new AnalysisOptionsImpl();
expected.implicitDynamic = false;
- String path = resourceProvider.convertPath('/some/directory/path');
- String filePath =
- pathContext.join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
- resourceProvider.newFile(filePath, '''
+ String path = convertPath('/some/directory/path');
+ String filePath = join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
+ newFile(filePath, content: '''
analyzer:
strong-mode:
implicit-dynamic: false
@@ -829,24 +787,41 @@
}
void test_getAnalysisOptions_optionsPath() {
- String path = resourceProvider.convertPath('/some/directory/path');
- String filePath =
- pathContext.join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
- resourceProvider.newFile(filePath, '''
+ String path = convertPath('/some/directory/path');
+ String filePath = join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
+ newFile(filePath, content: '''
linter:
rules:
- empty_constructor_bodies
''');
- ContextRoot root = new ContextRoot(path, [], pathContext: pathContext);
+ ContextRoot root =
+ new ContextRoot(path, [], pathContext: resourceProvider.pathContext);
builder.getAnalysisOptions(path, contextRoot: root);
expect(root.optionsFilePath, equals(filePath));
}
+ void test_getAnalysisOptions_sdkVersionConstraint() {
+ var projectPath = convertPath('/test');
+ newFile(join(projectPath, AnalysisEngine.PUBSPEC_YAML_FILE), content: '''
+environment:
+ sdk: ^2.1.0
+''');
+
+ var options = builder.getAnalysisOptions(projectPath);
+ expect(options.sdkVersionConstraint.toString(), '^2.1.0');
+ }
+
+ void test_getAnalysisOptions_sdkVersionConstraint_any_noOptionsFile() {
+ var projectPath = convertPath('/test');
+ var options = builder.getAnalysisOptions(projectPath);
+ expect(options.sdkVersionConstraint, isNull);
+ }
+
void test_getOptionsFile_explicit() {
- String path = resourceProvider.convertPath('/some/directory/path');
- String filePath = resourceProvider.convertPath('/options/analysis.yaml');
- resourceProvider.newFile(filePath, '');
+ String path = convertPath('/some/directory/path');
+ String filePath = convertPath('/options/analysis.yaml');
+ newFile(filePath);
builderOptions.defaultAnalysisOptionsFilePath = filePath;
File result = builder.getOptionsFile(path);
@@ -855,11 +830,11 @@
}
void test_getOptionsFile_inParentOfRoot_new() {
- String parentPath = resourceProvider.convertPath('/some/directory');
- String path = pathContext.join(parentPath, 'path');
+ String parentPath = convertPath('/some/directory');
+ String path = join(parentPath, 'path');
String filePath =
- pathContext.join(parentPath, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
- resourceProvider.newFile(filePath, '');
+ join(parentPath, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
+ newFile(filePath);
File result = builder.getOptionsFile(path);
expect(result, isNotNull);
@@ -867,11 +842,10 @@
}
void test_getOptionsFile_inParentOfRoot_old() {
- String parentPath = resourceProvider.convertPath('/some/directory');
- String path = pathContext.join(parentPath, 'path');
- String filePath =
- pathContext.join(parentPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE);
- resourceProvider.newFile(filePath, '');
+ String parentPath = convertPath('/some/directory');
+ String path = join(parentPath, 'path');
+ String filePath = join(parentPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE);
+ newFile(filePath);
File result = builder.getOptionsFile(path);
expect(result, isNotNull);
@@ -879,10 +853,9 @@
}
void test_getOptionsFile_inRoot_new() {
- String path = resourceProvider.convertPath('/some/directory/path');
- String filePath =
- pathContext.join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
- resourceProvider.newFile(filePath, '');
+ String path = convertPath('/some/directory/path');
+ String filePath = join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
+ newFile(filePath);
File result = builder.getOptionsFile(path);
expect(result, isNotNull);
@@ -890,10 +863,9 @@
}
void test_getOptionsFile_inRoot_old() {
- String path = resourceProvider.convertPath('/some/directory/path');
- String filePath =
- pathContext.join(path, AnalysisEngine.ANALYSIS_OPTIONS_FILE);
- resourceProvider.newFile(filePath, '');
+ String path = convertPath('/some/directory/path');
+ String filePath = join(path, AnalysisEngine.ANALYSIS_OPTIONS_FILE);
+ newFile(filePath);
File result = builder.getOptionsFile(path);
expect(result, isNotNull);
@@ -931,7 +903,6 @@
expect(actual.preserveComments, expected.preserveComments);
expect(actual.strongMode, expected.strongMode);
expect(actual.strongModeHints, expected.strongModeHints);
- expect(actual.declarationCasts, expected.declarationCasts);
expect(actual.implicitCasts, expected.implicitCasts);
expect(actual.implicitDynamic, expected.implicitDynamic);
expect(actual.trackCacheDependencies, expected.trackCacheDependencies);
@@ -939,6 +910,7 @@
}
Uri _relativeUri(String path, {String from}) {
+ var pathContext = resourceProvider.pathContext;
String relativePath = pathContext.relative(path, from: from);
return pathContext.toUri(relativePath);
}
diff --git a/pkg/analyzer/test/src/context/cache_test.dart b/pkg/analyzer/test/src/context/cache_test.dart
index fbd0736..2b42c7d9 100644
--- a/pkg/analyzer/test/src/context/cache_test.dart
+++ b/pkg/analyzer/test/src/context/cache_test.dart
@@ -4,7 +4,6 @@
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
@@ -14,6 +13,7 @@
import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/model.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -1162,13 +1162,12 @@
}
@reflectiveTest
-class PackageCachePartitionTest extends CachePartitionTest {
- MemoryResourceProvider resourceProvider;
+class PackageCachePartitionTest extends CachePartitionTest
+ with ResourceProviderMixin {
Folder rootFolder;
CachePartition createPartition() {
- resourceProvider = new MemoryResourceProvider();
- rootFolder = resourceProvider.newFolder('/package/root');
+ rootFolder = newFolder('/package/root');
return new PackageCachePartition(null, rootFolder);
}
diff --git a/pkg/analyzer/test/src/context/context_test.dart b/pkg/analyzer/test/src/context/context_test.dart
index b33ce36..9ebd97f 100644
--- a/pkg/analyzer/test/src/context/context_test.dart
+++ b/pkg/analyzer/test/src/context/context_test.dart
@@ -2686,7 +2686,7 @@
void test_validateCacheConsistency_deletedFile() {
String pathA = '/a.dart';
String pathB = '/b.dart';
- var fileA = newFile(pathA, content: "");
+ var fileA = newFile(pathA);
var fileB = newFile(pathB, content: "import 'a.dart';");
Source sourceA = fileA.createSource();
Source sourceB = fileB.createSource();
diff --git a/pkg/analyzer/test/src/context/mock_sdk.dart b/pkg/analyzer/test/src/context/mock_sdk.dart
deleted file mode 100644
index ba87ba5..0000000
--- a/pkg/analyzer/test/src/context/mock_sdk.dart
+++ /dev/null
@@ -1,686 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/file_system/file_system.dart' as resource;
-import 'package:analyzer/file_system/memory_file_system.dart' as resource;
-import 'package:analyzer/src/context/cache.dart';
-import 'package:analyzer/src/context/context.dart';
-import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine;
-import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/summary/idl.dart' show PackageBundle;
-import 'package:analyzer/src/summary/summary_file_builder.dart';
-
-const String librariesContent = r'''
-const Map<String, LibraryInfo> libraries = const {
- "async": const LibraryInfo("async/async.dart"),
- "collection": const LibraryInfo("collection/collection.dart"),
- "convert": const LibraryInfo("convert/convert.dart"),
- "core": const LibraryInfo("core/core.dart"),
- "html": const LibraryInfo(
- "html/dartium/html_dartium.dart",
- dart2jsPath: "html/dart2js/html_dart2js.dart"),
- "math": const LibraryInfo("math/math.dart"),
- "_foreign_helper": const LibraryInfo("_internal/js_runtime/lib/foreign_helper.dart"),
-};
-''';
-
-const String sdkRoot = '/sdk';
-
-const _MockSdkLibrary _LIB_ASYNC =
- const _MockSdkLibrary('dart:async', '$sdkRoot/lib/async/async.dart', '''
-library dart.async;
-
-import 'dart:math';
-
-part 'stream.dart';
-
-class Future<T> {
- factory Future(computation()) => null;
- factory Future.delayed(Duration duration, [T computation()]) => null;
- factory Future.microtask(FutureOr<T> computation()) => null;
- factory Future.value([FutureOr<T> result]) => null;
-
- static Future<List<T>> wait<T>(
- Iterable<Future<T>> futures) => null;
- Future<R> then<R>(FutureOr<R> onValue(T value)) => null;
-
- Future<T> whenComplete(action());
-}
-
-class FutureOr<T> {}
-
-abstract class Completer<T> {
- factory Completer() => null;
- factory Completer.sync() => null;
- Future<T> get future;
- void complete([value]);
- void completeError(Object error, [StackTrace stackTrace]);
- bool get isCompleted;
-}
-
-abstract class Timer {
- static void run(void callback()) {}
-}
-
-class _StreamIterator<T> implements StreamIterator<T> {}
-class _AsyncStarStreamController {}
-Function _asyncThenWrapperHelper(continuation) {}
-Function _asyncErrorWrapperHelper(continuation) {}
-Future _awaitHelper(
- object, Function thenCallback, Function errorCallback, var awaiter) {}
-''', const <String, String>{
- '$sdkRoot/lib/async/stream.dart': r'''
-part of dart.async;
-abstract class Stream<T> {
- Future<T> get first;
- StreamSubscription<T> listen(void onData(T event),
- { Function onError,
- void onDone(),
- bool cancelOnError});
- Stream();
- factory Stream.fromIterable(Iterable<T> data) => null;
-}
-
-abstract class StreamIterator<T> {}
-
-abstract class StreamSubscription<T> {
- Future cancel();
- void onData(void handleData(T data));
- void onError(Function handleError);
- void onDone(void handleDone());
- void pause([Future resumeSignal]);
- void resume();
- bool get isPaused;
- Future<E> asFuture<E>([E futureValue]);
-}
-
-abstract class StreamTransformer<S, T> {}
-'''
-});
-
-const _MockSdkLibrary _LIB_ASYNC2 =
- const _MockSdkLibrary('dart:async2', '$sdkRoot/lib/async2/async2.dart', '''
-library dart.async2;
-
-class Future {}
-''');
-
-const _MockSdkLibrary _LIB_COLLECTION = const _MockSdkLibrary(
- 'dart:collection', '$sdkRoot/lib/collection/collection.dart', '''
-library dart.collection;
-
-abstract class HashMap<K, V> implements Map<K, V> {}
-''');
-
-const _MockSdkLibrary _LIB_CONVERT = const _MockSdkLibrary(
- 'dart:convert', '$sdkRoot/lib/convert/convert.dart', '''
-library dart.convert;
-
-import 'dart:async';
-
-abstract class Converter<S, T> implements StreamTransformer {}
-class JsonDecoder extends Converter<String, Object> {}
-''');
-
-const _MockSdkLibrary _LIB_CORE =
- const _MockSdkLibrary('dart:core', '$sdkRoot/lib/core/core.dart', '''
-library dart.core;
-
-import 'dart:async';
-import 'dart:_internal';
-
-export 'dart:async' show Future, Stream;
-
-class Object {
- const Object();
- bool operator ==(other) => identical(this, other);
- String toString() => 'a string';
- int get hashCode => 0;
- Type get runtimeType => null;
- dynamic noSuchMethod(Invocation invocation) => null;
-}
-
-class Function {}
-class StackTrace {}
-
-class Symbol {
- const factory Symbol(String name) = _SymbolImpl;
-}
-
-class _SymbolImpl {
- const _SymbolImpl(String name);
-}
-
-class Type {}
-
-abstract class Comparable<T> {
- int compareTo(T other);
-}
-
-abstract class Pattern {}
-abstract class String implements Comparable<String>, Pattern {
- external factory String.fromCharCodes(Iterable<int> charCodes,
- [int start = 0, int end]);
- String operator +(String other) => null;
- bool operator ==(Object other);
- bool get isEmpty => false;
- bool get isNotEmpty => false;
- int get length => 0;
- int codeUnitAt(int index);
- String substring(int len) => null;
- String toLowerCase();
- String toUpperCase();
- List<int> get codeUnits;
-}
-abstract class RegExp implements Pattern {
- external factory RegExp(String source);
-}
-
-class bool extends Object {
- external const factory bool.fromEnvironment(String name,
- {bool defaultValue: false});
-}
-
-abstract class Invocation {}
-
-abstract class num implements Comparable<num> {
- bool operator ==(Object other);
- bool operator <(num other);
- bool operator <=(num other);
- bool operator >(num other);
- bool operator >=(num other);
- num operator +(num other);
- num operator -(num other);
- num operator *(num other);
- double operator /(num other);
- int operator ^(int other);
- int operator |(int other);
- int operator <<(int other);
- int operator >>(int other);
- int operator ~/(num other);
- num operator %(num other);
- int operator ~();
- num operator -();
- int toInt();
- double toDouble();
- num abs();
- int round();
-}
-abstract class int extends num {
- external const factory int.fromEnvironment(String name, {int defaultValue});
-
- bool get isNegative;
- bool get isEven => false;
-
- int operator &(int other);
- int operator |(int other);
- int operator ^(int other);
- int operator ~();
- int operator <<(int shiftAmount);
- int operator >>(int shiftAmount);
-
- int operator -();
-
- external static int parse(String source,
- { int radix,
- int onError(String source) });
-
- String toString();
-}
-
-abstract class double extends num {
- static const double NAN = 0.0 / 0.0;
- static const double INFINITY = 1.0 / 0.0;
- static const double NEGATIVE_INFINITY = -INFINITY;
- static const double MIN_POSITIVE = 5e-324;
- static const double MAX_FINITE = 1.7976931348623157e+308;
-
- double remainder(num other);
- double operator +(num other);
- double operator -(num other);
- double operator *(num other);
- double operator %(num other);
- double operator /(num other);
- int operator ~/(num other);
- double operator -();
- double abs();
- double get sign;
- int round();
- int floor();
- int ceil();
- int truncate();
- double roundToDouble();
- double floorToDouble();
- double ceilToDouble();
- double truncateToDouble();
- external static double parse(String source,
- [double onError(String source)]);
-}
-
-class DateTime extends Object {}
-
-class Null extends Object {
- factory Null._uninstantiable() => null;
-}
-
-class Deprecated extends Object {
- final String expires;
- const Deprecated(this.expires);
-}
-const Object deprecated = const Deprecated("next release");
-
-class Iterator<E> {
- bool moveNext();
- E get current;
-}
-
-abstract class Iterable<E> {
- Iterator<E> get iterator;
- bool get isEmpty;
- E get first;
- int get length;
-
- Iterable<R> map<R>(R f(E e));
-
- R fold<R>(R initialValue,
- R combine(R previousValue, E element)) => null;
-
- Iterable<T> expand<T>(Iterable<T> f(E element));
-
- Iterable<E> where(bool test(E element));
-
- void forEach(void f(E element));
-
- List<E> toList();
-}
-
-class List<E> implements Iterable<E> {
- List([int length]);
- factory List.from(Iterable elements, {bool growable: true}) => null;
- void add(E value) {}
- void addAll(Iterable<E> iterable) {}
- E operator [](int index) => null;
- void operator []=(int index, E value) {}
- Iterator<E> get iterator => null;
- void clear() {}
-
- bool get isEmpty => false;
- E get first => null;
- E get last => null;
-
-}
-
-class Map<K, V> extends Object {
- Iterable<K> get keys => null;
- int get length;
- Iterable<V> get values;
- V operator [](K key) => null;
- void operator []=(K key, V value) {}
- Map<RK, RV> cast<RK, RV>();
- bool containsKey(Object key);
-}
-
-class Duration implements Comparable<Duration> {}
-
-class Exception {
- factory Exception([var message]) => null;
-}
-
-external bool identical(Object a, Object b);
-
-void print(Object object) {}
-
-class _Proxy { const _Proxy(); }
-const Object proxy = const _Proxy();
-
-class _Override { const _Override(); }
-const Object override = const _Override();
-
-class _CompileTimeError {
- final String _errorMsg;
- _CompileTimeError(this._errorMsg);
-}
-
-class AbstractClassInstantiationError {
- AbstractClassInstantiationError(String className);
-}
-
-class FallThroughError {
- FallThroughError();
- FallThroughError._create(String url, int line);
-}
-
-abstract class _SyncIterable implements Iterable {}
-class _InvocationMirror {
- _InvocationMirror._withoutType(
- String _functionName, List<Type> _typeArguments,
- List _positionalArguments, Map<Symbol, dynamic>_namedArguments,
- bool _isSuperInvocation);
-}
-''');
-
-const _MockSdkLibrary _LIB_FOREIGN_HELPER = const _MockSdkLibrary(
- 'dart:_foreign_helper',
- '$sdkRoot/lib/_foreign_helper/_foreign_helper.dart', '''
-library dart._foreign_helper;
-
-JS(String typeDescription, String codeTemplate,
- [arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11])
-{}
-''');
-
-const _MockSdkLibrary _LIB_HTML_DART2JS = const _MockSdkLibrary(
- 'dart:html', '$sdkRoot/lib/html/dart2js/html_dart2js.dart', '''
-library dart.html;
-class HtmlElement {}
-''');
-
-const _MockSdkLibrary _LIB_HTML_DARTIUM = const _MockSdkLibrary(
- 'dart:html', '$sdkRoot/lib/html/dartium/html_dartium.dart', '''
-library dart.dom.html;
-
-final HtmlDocument document;
-
-abstract class Element {}
-
-abstract class HtmlDocument {
- Element query(String relativeSelectors) => null;
-}
-
-abstract class HtmlElement extends Element {}
-
-abstract class AnchorElement extends HtmlElement {}
-abstract class BodyElement extends HtmlElement {}
-abstract class ButtonElement extends HtmlElement {}
-abstract class DivElement extends HtmlElement {}
-abstract class InputElement extends HtmlElement {}
-abstract class SelectElement extends HtmlElement {}
-
-
-abstract class CanvasElement extends HtmlElement {
- Object getContext(String contextId, [Map attributes]);
- CanvasRenderingContext2D get context2D;
-}
-
-abstract class CanvasRenderingContext2D {}
-
-Element query(String relativeSelectors) => null;
-''');
-
-const _MockSdkLibrary _LIB_INTERCEPTORS = const _MockSdkLibrary(
- 'dart:_interceptors',
- '$sdkRoot/lib/_internal/js_runtime/lib/interceptors.dart', '''
-library dart._interceptors;
-''');
-
-const _MockSdkLibrary _LIB_INTERNAL = const _MockSdkLibrary(
- 'dart:_internal', '$sdkRoot/lib/_internal/internal.dart', '''
-library dart._internal;
-class Symbol {}
-class ExternalName {
- final String name;
- const ExternalName(this.name);
-}
-''');
-
-const _MockSdkLibrary _LIB_MATH =
- const _MockSdkLibrary('dart:math', '$sdkRoot/lib/math/math.dart', '''
-library dart.math;
-
-const double E = 2.718281828459045;
-const double PI = 3.1415926535897932;
-const double LN10 = 2.302585092994046;
-
-T min<T extends num>(T a, T b) => null;
-T max<T extends num>(T a, T b) => null;
-
-external double cos(num radians);
-external double sin(num radians);
-external double sqrt(num radians);
-class Random {
- bool nextBool() => true;
- double nextDouble() => 2.0;
- int nextInt() => 1;
-}
-''');
-
-const List<SdkLibrary> _LIBRARIES = const [
- _LIB_CORE,
- _LIB_ASYNC,
- _LIB_ASYNC2,
- _LIB_COLLECTION,
- _LIB_CONVERT,
- _LIB_FOREIGN_HELPER,
- _LIB_MATH,
- _LIB_HTML_DART2JS,
- _LIB_HTML_DARTIUM,
- _LIB_INTERCEPTORS,
- _LIB_INTERNAL,
-];
-
-class MockSdk implements DartSdk {
- static const Map<String, String> _URI_MAP = const {
- "dart:core": "$sdkRoot/lib/core/core.dart",
- "dart:html": "$sdkRoot/lib/html/dartium/html_dartium.dart",
- "dart:async": "$sdkRoot/lib/async/async.dart",
- "dart:async2": "$sdkRoot/lib/async2/async2.dart",
- "dart:async/stream.dart": "$sdkRoot/lib/async/stream.dart",
- "dart:collection": "$sdkRoot/lib/collection/collection.dart",
- "dart:convert": "$sdkRoot/lib/convert/convert.dart",
- "dart:_foreign_helper": "$sdkRoot/lib/_foreign_helper/_foreign_helper.dart",
- "dart:_interceptors":
- "$sdkRoot/lib/_internal/js_runtime/lib/interceptors.dart",
- "dart:_internal": "$sdkRoot/lib/_internal/internal.dart",
- "dart:math": "$sdkRoot/lib/math/math.dart"
- };
-
- final resource.MemoryResourceProvider provider;
-
- final Map<String, String> uriMap = {};
-
- /**
- * The [AnalysisContextImpl] which is used for all of the sources.
- */
- AnalysisContextImpl _analysisContext;
-
- @override
- final List<SdkLibrary> sdkLibraries = [];
-
- /**
- * The cached linked bundle of the SDK.
- */
- PackageBundle _bundle;
-
- MockSdk(
- {bool generateSummaryFiles: false,
- resource.MemoryResourceProvider resourceProvider})
- : provider = resourceProvider ?? new resource.MemoryResourceProvider() {
- _URI_MAP.forEach((uri, path) {
- uriMap[uri] = provider.convertPath(path);
- });
-
- for (_MockSdkLibrary library in _LIBRARIES) {
- var convertedLibrary = library._toProvider(provider);
- sdkLibraries.add(convertedLibrary);
- }
-
- for (_MockSdkLibrary library in sdkLibraries) {
- provider.newFile(library.path, library.content);
- library.parts.forEach((String path, String content) {
- provider.newFile(path, content);
- });
- }
- provider.newFile(
- provider.convertPath(
- '$sdkRoot/lib/_internal/sdk_library_metadata/lib/libraries.dart'),
- librariesContent);
- if (generateSummaryFiles) {
- List<int> bytes = _computeLinkedBundleBytes();
- provider.newFileWithBytes(
- provider.convertPath('/lib/_internal/strong.sum'), bytes);
- }
- }
-
- @override
- AnalysisContextImpl get context {
- if (_analysisContext == null) {
- _analysisContext = new _SdkAnalysisContext(this);
- SourceFactory factory = new SourceFactory([new DartUriResolver(this)]);
- _analysisContext.sourceFactory = factory;
- }
- return _analysisContext;
- }
-
- @override
- String get sdkVersion => throw new UnimplementedError();
-
- @override
- List<String> get uris =>
- sdkLibraries.map((SdkLibrary library) => library.shortName).toList();
-
- @override
- Source fromFileUri(Uri uri) {
- String filePath = provider.pathContext.fromUri(uri);
- if (!filePath.startsWith(provider.convertPath('$sdkRoot/lib/'))) {
- return null;
- }
- for (SdkLibrary library in sdkLibraries) {
- String libraryPath = library.path;
- if (filePath == libraryPath) {
- try {
- resource.File file = provider.getResource(filePath);
- Uri dartUri = Uri.parse(library.shortName);
- return file.createSource(dartUri);
- } catch (exception) {
- return null;
- }
- }
- String libraryRootPath = provider.pathContext.dirname(libraryPath) +
- provider.pathContext.separator;
- if (filePath.startsWith(libraryRootPath)) {
- String pathInLibrary = filePath.substring(libraryRootPath.length);
- String uriStr = '${library.shortName}/$pathInLibrary';
- try {
- resource.File file = provider.getResource(filePath);
- Uri dartUri = Uri.parse(uriStr);
- return file.createSource(dartUri);
- } catch (exception) {
- return null;
- }
- }
- }
- return null;
- }
-
- @override
- PackageBundle getLinkedBundle() {
- if (_bundle == null) {
- resource.File summaryFile =
- provider.getFile(provider.convertPath('/lib/_internal/strong.sum'));
- List<int> bytes;
- if (summaryFile.exists) {
- bytes = summaryFile.readAsBytesSync();
- } else {
- bytes = _computeLinkedBundleBytes();
- }
- _bundle = new PackageBundle.fromBuffer(bytes);
- }
- return _bundle;
- }
-
- @override
- SdkLibrary getSdkLibrary(String dartUri) {
- for (SdkLibrary library in _LIBRARIES) {
- if (library.shortName == dartUri) {
- return library;
- }
- }
- return null;
- }
-
- @override
- Source mapDartUri(String dartUri) {
- String path = uriMap[dartUri];
- if (path != null) {
- resource.File file = provider.getResource(path);
- Uri uri = new Uri(scheme: 'dart', path: dartUri.substring(5));
- return file.createSource(uri);
- }
- // If we reach here then we tried to use a dartUri that's not in the
- // table above.
- return null;
- }
-
- /**
- * Compute the bytes of the linked bundle associated with this SDK.
- */
- List<int> _computeLinkedBundleBytes() {
- List<Source> librarySources = sdkLibraries
- .map((SdkLibrary library) => mapDartUri(library.shortName))
- .toList();
- return new SummaryBuilder(librarySources, context).build();
- }
-}
-
-class _MockSdkLibrary implements SdkLibrary {
- final String shortName;
- final String path;
- final String content;
- final Map<String, String> parts;
-
- const _MockSdkLibrary(this.shortName, this.path, this.content,
- [this.parts = const <String, String>{}]);
-
- @override
- String get category => throw new UnimplementedError();
-
- @override
- bool get isDart2JsLibrary => throw new UnimplementedError();
-
- @override
- bool get isDocumented => throw new UnimplementedError();
-
- @override
- bool get isImplementation => throw new UnimplementedError();
-
- @override
- bool get isInternal => shortName.startsWith('dart:_');
-
- @override
- bool get isShared => throw new UnimplementedError();
-
- @override
- bool get isVmLibrary => throw new UnimplementedError();
-
- _MockSdkLibrary _toProvider(resource.MemoryResourceProvider provider) {
- return new _MockSdkLibrary(
- shortName,
- provider.convertPath(path),
- content,
- parts.map((path, content) {
- var convertedPath = provider.convertPath(path);
- return new MapEntry(convertedPath, content);
- }),
- );
- }
-}
-
-/**
- * An [AnalysisContextImpl] that only contains sources for a Dart SDK.
- */
-class _SdkAnalysisContext extends AnalysisContextImpl {
- final DartSdk sdk;
-
- _SdkAnalysisContext(this.sdk);
-
- @override
- AnalysisCache createCacheFromSourceFactory(SourceFactory factory) {
- if (factory == null) {
- return super.createCacheFromSourceFactory(factory);
- }
- return new AnalysisCache(
- <CachePartition>[AnalysisEngine.instance.partitionManager.forSdk(sdk)]);
- }
-}
diff --git a/pkg/analyzer/test/src/context/source_test.dart b/pkg/analyzer/test/src/context/source_test.dart
index 18cc9b8..45a5ffc 100644
--- a/pkg/analyzer/test/src/context/source_test.dart
+++ b/pkg/analyzer/test/src/context/source_test.dart
@@ -20,8 +20,8 @@
@reflectiveTest
class SourceFactoryImplTest extends AbstractContextTest {
void test_restoreUri() {
- String libPath = resourceProvider.convertPath('/pkgs/somepkg/lib');
- Uri libUri = resourceProvider.getFolder(libPath).toUri();
+ String libPath = convertPath('/pkgs/somepkg/lib');
+ Uri libUri = getFolder(libPath).toUri();
Map<String, Uri> packageUriMap = <String, Uri>{'foo': libUri};
SourceFactoryImpl sourceFactory = new SourceFactoryImpl(
<UriResolver>[new ResourceUriResolver(resourceProvider)],
diff --git a/pkg/analyzer/test/src/dart/analysis/analysis_context_collection_test.dart b/pkg/analyzer/test/src/dart/analysis/analysis_context_collection_test.dart
index 0afd0b0..b2870e7 100644
--- a/pkg/analyzer/test/src/dart/analysis/analysis_context_collection_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/analysis_context_collection_test.dart
@@ -1,15 +1,14 @@
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2018, 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:analyzer/src/dart/analysis/analysis_context_collection.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:meta/meta.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../context/mock_sdk.dart';
-
main() {
defineReflectiveSuite(() {
defineReflectiveTests(AnalysisContextCollectionTest);
@@ -17,7 +16,7 @@
}
@reflectiveTest
-class AnalysisContextCollectionTest extends Object with ResourceProviderMixin {
+class AnalysisContextCollectionTest with ResourceProviderMixin {
void setUp() {
new MockSdk(resourceProvider: resourceProvider);
}
diff --git a/pkg/analyzer/test/src/dart/analysis/base.dart b/pkg/analyzer/test/src/dart/analysis/base.dart
index e9f6eaa..8f6daf9 100644
--- a/pkg/analyzer/test/src/dart/analysis/base.dart
+++ b/pkg/analyzer/test/src/dart/analysis/base.dart
@@ -2,12 +2,14 @@
// 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:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/visitor.dart';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
+import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/dart/analysis/status.dart';
import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
@@ -16,12 +18,10 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer/src/summary/package_bundle_reader.dart';
-import 'package:analyzer/src/dart/analysis/byte_store.dart';
-import 'package:analyzer/src/dart/analysis/performance_logger.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:test/test.dart';
-import '../../context/mock_sdk.dart';
-
/**
* Finds an [Element] with the given [name].
*/
@@ -46,8 +46,7 @@
*/
typedef void _ElementVisitorFunction(Element element);
-class BaseAnalysisDriverTest {
- final MemoryResourceProvider provider = new MemoryResourceProvider();
+class BaseAnalysisDriverTest with ResourceProviderMixin {
DartSdk sdk;
final ByteStore byteStore = new MemoryByteStore();
final FileContentOverlay contentOverlay = new FileContentOverlay();
@@ -60,7 +59,7 @@
AnalysisDriverScheduler scheduler;
AnalysisDriver driver;
final List<AnalysisStatus> allStatuses = <AnalysisStatus>[];
- final List<AnalysisResult> allResults = <AnalysisResult>[];
+ final List<ResolvedUnitResult> allResults = <ResolvedUnitResult>[];
final List<ExceptionResult> allExceptions = <ExceptionResult>[];
String testProject;
@@ -71,7 +70,7 @@
void addTestFile(String content, {bool priority: false}) {
testCode = content;
- provider.newFile(testFile, content);
+ newFile(testFile, content: content);
driver.addFile(testFile);
if (priority) {
driver.priorityFiles = [testFile];
@@ -82,25 +81,26 @@
{Map<String, List<Folder>> packageMap,
SummaryDataStore externalSummaries}) {
packageMap ??= <String, List<Folder>>{
- 'test': [provider.getFolder(testProject)],
- 'aaa': [provider.getFolder(_p('/aaa/lib'))],
- 'bbb': [provider.getFolder(_p('/bbb/lib'))],
+ 'test': [getFolder(testProject)],
+ 'aaa': [getFolder('/aaa/lib')],
+ 'bbb': [getFolder('/bbb/lib')],
};
return new AnalysisDriver(
scheduler,
logger,
- provider,
+ resourceProvider,
byteStore,
contentOverlay,
null,
new SourceFactory([
new DartUriResolver(sdk),
generatedUriResolver,
- new PackageMapUriResolver(provider, packageMap),
- new ResourceUriResolver(provider)
- ], null, provider),
+ new PackageMapUriResolver(resourceProvider, packageMap),
+ new ResourceUriResolver(resourceProvider)
+ ], null, resourceProvider),
createAnalysisOptions(),
disableChangesAndCacheAllResults: disableChangesAndCacheAllResults,
+ enableIndex: true,
externalSummaries: externalSummaries);
}
@@ -137,9 +137,9 @@
}
void setUp() {
- sdk = new MockSdk(resourceProvider: provider);
- testProject = _p('/test/lib');
- testFile = _p('/test/lib/test.dart');
+ sdk = new MockSdk(resourceProvider: resourceProvider);
+ testProject = convertPath('/test/lib');
+ testFile = convertPath('/test/lib/test.dart');
logger = new PerformanceLog(logBuffer);
scheduler = new AnalysisDriverScheduler(logger);
driver = createAnalysisDriver();
@@ -150,8 +150,6 @@
}
void tearDown() {}
-
- String _p(String path) => provider.convertPath(path);
}
/**
diff --git a/pkg/analyzer/test/src/dart/analysis/context_builder_test.dart b/pkg/analyzer/test/src/dart/analysis/context_builder_test.dart
index 86c3094..c98351b 100644
--- a/pkg/analyzer/test/src/dart/analysis/context_builder_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/context_builder_test.dart
@@ -7,16 +7,14 @@
import 'package:analyzer/dart/analysis/analysis_context.dart';
import 'package:analyzer/dart/analysis/context_root.dart';
import 'package:analyzer/dart/analysis/declared_variables.dart';
-import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/analysis/context_builder.dart';
import 'package:analyzer/src/dart/analysis/context_root.dart';
import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../context/mock_sdk.dart';
-
main() {
defineReflectiveSuite(() {
defineReflectiveTests(ContextBuilderImplTest);
@@ -24,7 +22,7 @@
}
@reflectiveTest
-class ContextBuilderImplTest extends Object with ResourceProviderMixin {
+class ContextBuilderImplTest with ResourceProviderMixin {
ContextBuilderImpl contextBuilder;
ContextRoot contextRoot;
@@ -38,11 +36,9 @@
}
void setUp() {
- resourceProvider.newFolder(resourceProvider.pathContext.dirname(
- resourceProvider.pathContext.dirname(io.Platform.resolvedExecutable)));
+ newFile(io.Platform.resolvedExecutable); // create folders
+ var folder = newFolder('/home/test');
contextBuilder = new ContextBuilderImpl(resourceProvider: resourceProvider);
- String path = resourceProvider.convertPath('/temp/root');
- Folder folder = resourceProvider.newFolder(path);
contextRoot = new ContextRootImpl(resourceProvider, folder);
}
diff --git a/pkg/analyzer/test/src/dart/analysis/context_locator_test.dart b/pkg/analyzer/test/src/dart/analysis/context_locator_test.dart
index 388be9b..03db7aa 100644
--- a/pkg/analyzer/test/src/dart/analysis/context_locator_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/context_locator_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2018, 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.
@@ -16,7 +16,7 @@
}
@reflectiveTest
-class ContextLocatorImplTest extends Object with ResourceProviderMixin {
+class ContextLocatorImplTest with ResourceProviderMixin {
ContextLocatorImpl contextLocator;
ContextRoot findRoot(List<ContextRoot> roots, Resource rootFolder) {
diff --git a/pkg/analyzer/test/src/dart/analysis/context_root_test.dart b/pkg/analyzer/test/src/dart/analysis/context_root_test.dart
index 9b6324d..6edc6d2 100644
--- a/pkg/analyzer/test/src/dart/analysis/context_root_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/context_root_test.dart
@@ -3,8 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/dart/analysis/context_root.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -15,50 +15,48 @@
}
@reflectiveTest
-class ContextRootTest {
- MemoryResourceProvider provider = new MemoryResourceProvider();
+class ContextRootTest with ResourceProviderMixin {
String rootPath;
Folder rootFolder;
ContextRootImpl contextRoot;
void setUp() {
- rootPath = provider.convertPath('/test/root');
- rootFolder = provider.newFolder(rootPath);
- contextRoot = new ContextRootImpl(provider, rootFolder);
+ rootPath = convertPath('/test/root');
+ rootFolder = newFolder(rootPath);
+ contextRoot = new ContextRootImpl(resourceProvider, rootFolder);
contextRoot.included.add(rootFolder);
}
test_analyzedFiles() {
- String optionsPath =
- provider.convertPath('/test/root/analysis_options.yaml');
- String readmePath = provider.convertPath('/test/root/README.md');
- String aPath = provider.convertPath('/test/root/lib/a.dart');
- String bPath = provider.convertPath('/test/root/lib/src/b.dart');
- String excludePath = provider.convertPath('/test/root/exclude');
- String cPath = provider.convertPath('/test/root/exclude/c.dart');
+ String optionsPath = convertPath('/test/root/analysis_options.yaml');
+ String readmePath = convertPath('/test/root/README.md');
+ String aPath = convertPath('/test/root/lib/a.dart');
+ String bPath = convertPath('/test/root/lib/src/b.dart');
+ String excludePath = convertPath('/test/root/exclude');
+ String cPath = convertPath('/test/root/exclude/c.dart');
- provider.newFile(optionsPath, '');
- provider.newFile(readmePath, '');
- provider.newFile(aPath, '');
- provider.newFile(bPath, '');
- provider.newFile(cPath, '');
- contextRoot.excluded.add(provider.newFolder(excludePath));
+ newFile(optionsPath);
+ newFile(readmePath);
+ newFile(aPath);
+ newFile(bPath);
+ newFile(cPath);
+ contextRoot.excluded.add(newFolder(excludePath));
expect(contextRoot.analyzedFiles(),
unorderedEquals([optionsPath, readmePath, aPath, bPath]));
}
test_isAnalyzed_explicitlyExcluded() {
- String excludePath = provider.convertPath('/test/root/exclude');
- String filePath = provider.convertPath('/test/root/exclude/root.dart');
- contextRoot.excluded.add(provider.newFolder(excludePath));
+ String excludePath = convertPath('/test/root/exclude');
+ String filePath = convertPath('/test/root/exclude/root.dart');
+ contextRoot.excluded.add(newFolder(excludePath));
expect(contextRoot.isAnalyzed(filePath), isFalse);
}
test_isAnalyzed_explicitlyExcluded_same() {
- String aPath = provider.convertPath('/test/root/lib/a.dart');
- String bPath = provider.convertPath('/test/root/lib/b.dart');
- File aFile = provider.getFile(aPath);
+ String aPath = convertPath('/test/root/lib/a.dart');
+ String bPath = convertPath('/test/root/lib/b.dart');
+ File aFile = getFile(aPath);
contextRoot.excluded.add(aFile);
@@ -67,26 +65,26 @@
}
test_isAnalyzed_implicitlyExcluded_dot_analysisOptions() {
- String filePath = provider.convertPath('/test/root/lib/.analysis_options');
+ String filePath = convertPath('/test/root/lib/.analysis_options');
expect(contextRoot.isAnalyzed(filePath), isFalse);
}
test_isAnalyzed_implicitlyExcluded_dot_packages() {
- String filePath = provider.convertPath('/test/root/lib/.packages');
+ String filePath = convertPath('/test/root/lib/.packages');
expect(contextRoot.isAnalyzed(filePath), isFalse);
}
test_isAnalyzed_included() {
- String filePath = provider.convertPath('/test/root/lib/root.dart');
+ String filePath = convertPath('/test/root/lib/root.dart');
expect(contextRoot.isAnalyzed(filePath), isTrue);
}
test_isAnalyzed_included_same() {
- String aPath = provider.convertPath('/test/root/lib/a.dart');
- String bPath = provider.convertPath('/test/root/lib/b.dart');
- File aFile = provider.getFile(aPath);
+ String aPath = convertPath('/test/root/lib/a.dart');
+ String bPath = convertPath('/test/root/lib/b.dart');
+ File aFile = getFile(aPath);
- contextRoot = new ContextRootImpl(provider, rootFolder);
+ contextRoot = new ContextRootImpl(resourceProvider, rootFolder);
contextRoot.included.add(aFile);
expect(contextRoot.isAnalyzed(aPath), isTrue);
@@ -94,8 +92,8 @@
}
test_isAnalyzed_packagesDirectory_analyzed() {
- String folderPath = provider.convertPath('/test/root/lib/packages');
- provider.newFolder(folderPath);
+ String folderPath = convertPath('/test/root/lib/packages');
+ newFolder(folderPath);
expect(contextRoot.isAnalyzed(folderPath), isTrue);
}
}
diff --git a/pkg/analyzer/test/src/dart/analysis/dependency/base.dart b/pkg/analyzer/test/src/dart/analysis/dependency/base.dart
new file mode 100644
index 0000000..8df8a047
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/analysis/dependency/base.dart
@@ -0,0 +1,184 @@
+// Copyright (c) 2018, 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:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/analysis/dependency/library_builder.dart';
+import 'package:analyzer/src/dart/analysis/dependency/node.dart';
+import 'package:meta/meta.dart';
+import 'package:test/test.dart';
+
+import '../../resolution/driver_resolution.dart';
+
+class BaseDependencyTest extends DriverResolutionTest {
+// DependencyTracker tracker;
+ String a;
+ String b;
+ String c;
+ Uri aUri;
+ Uri bUri;
+ Uri cUri;
+
+ bool hasDartCore = false;
+
+ void assertNodes(
+ List<DependencyNode> actualNodes,
+ List<ExpectedNode> expectedNodes,
+ ) {
+ expect(actualNodes, hasLength(expectedNodes.length));
+ for (var expectedNode in expectedNodes) {
+ var topNode = _getNode(
+ actualNodes,
+ uri: expectedNode.uri,
+ name: expectedNode.name,
+ kind: expectedNode.kind,
+ );
+
+ if (expectedNode.classMembers != null) {
+ assertNodes(topNode.classMembers, expectedNode.classMembers);
+ } else {
+ expect(topNode.classMembers, isNull);
+ }
+
+ if (expectedNode.classTypeParameters != null) {
+ assertNodes(
+ topNode.classTypeParameters,
+ expectedNode.classTypeParameters,
+ );
+ } else {
+ expect(topNode.classTypeParameters, isNull);
+ }
+ }
+ }
+
+ Future<Library> buildTestLibrary(String path, String content) async {
+// if (!hasDartCore) {
+// hasDartCore = true;
+// await _addLibraryByUri('dart:core');
+// await _addLibraryByUri('dart:async');
+// await _addLibraryByUri('dart:math');
+// await _addLibraryByUri('dart:_internal');
+// }
+
+ newFile(path, content: content);
+ driver.changeFile(path);
+
+ var units = await _resolveLibrary(path);
+ var uri = units.first.declaredElement.source.uri;
+
+ return buildLibrary(uri, units, _ReferenceCollector());
+
+// tracker.addLibrary(uri, units);
+//
+// var library = tracker.libraries[uri];
+// expect(library, isNotNull);
+//
+// return library;
+ }
+
+ DependencyNode getNode(Library library,
+ {@required Uri uri,
+ @required String name,
+ DependencyNodeKind kind,
+ String memberOf,
+ String typeParameterOf}) {
+ var nodes = library.declaredNodes;
+ if (memberOf != null) {
+ var class_ = _getNode(nodes, uri: aUri, name: memberOf);
+ expect(class_.kind,
+ anyOf(DependencyNodeKind.CLASS, DependencyNodeKind.MIXIN));
+ nodes = class_.classMembers;
+ } else if (typeParameterOf != null) {
+ var class_ = _getNode(nodes, uri: aUri, name: typeParameterOf);
+ expect(class_.kind,
+ anyOf(DependencyNodeKind.CLASS, DependencyNodeKind.MIXIN));
+ nodes = class_.classTypeParameters;
+ }
+ return _getNode(nodes, uri: aUri, name: name, kind: kind);
+ }
+
+ @override
+ void setUp() {
+ super.setUp();
+// var logger = PerformanceLog(null);
+// tracker = DependencyTracker(logger);
+ a = convertPath('/test/lib/a.dart');
+ b = convertPath('/test/lib/b.dart');
+ c = convertPath('/test/lib/c.dart');
+ aUri = Uri.parse('package:test/a.dart');
+ bUri = Uri.parse('package:test/b.dart');
+ cUri = Uri.parse('package:test/c.dart');
+ }
+
+// Future _addLibraryByUri(String uri) async {
+// var path = driver.sourceFactory.forUri(uri).fullName;
+// var unitResult = await driver.getUnitElement(path);
+//
+// var signature = ApiSignature();
+// signature.addString(unitResult.signature);
+// var signatureBytes = signature.toByteList();
+//
+// tracker.addLibraryElement(unitResult.element.library, signatureBytes);
+// }
+
+ DependencyNode _getNode(List<DependencyNode> nodes,
+ {@required Uri uri, @required String name, DependencyNodeKind kind}) {
+ var nameObj = DependencyName(uri, name);
+ for (var node in nodes) {
+ if (node.name == nameObj) {
+ if (kind != null && node.kind != kind) {
+ fail('Expected $kind "$name", found ${node.kind}');
+ }
+ return node;
+ }
+ }
+ fail('Expected to find $uri::$name in:\n ${nodes.join('\n ')}');
+ }
+
+ Future<List<CompilationUnit>> _resolveLibrary(String libraryPath) async {
+ var resolvedLibrary = await driver.getResolvedLibrary(libraryPath);
+ return resolvedLibrary.units.map((ru) => ru.unit).toList();
+ }
+}
+
+class ExpectedNode {
+ final Uri uri;
+ final String name;
+ final DependencyNodeKind kind;
+ final List<ExpectedNode> classMembers;
+ final List<ExpectedNode> classTypeParameters;
+
+ ExpectedNode(
+ this.uri,
+ this.name,
+ this.kind, {
+ this.classMembers,
+ this.classTypeParameters,
+ });
+}
+
+/// TODO(scheglov) remove it once we get actual implementation
+class _ReferenceCollector implements ReferenceCollector {
+ @override
+ Uri get libraryUri => null;
+
+ @override
+ void addImportPrefix(String name) {}
+
+ @override
+ void appendExpression(Expression node) {}
+
+ @override
+ void appendFormalParameters(FormalParameterList formalParameterList) {}
+
+ @override
+ void appendFunctionBody(FunctionBody node) {}
+
+ @override
+ void appendTypeAnnotation(TypeAnnotation node) {}
+
+ @override
+ DependencyNodeDependencies finish(List<int> tokenSignature) {
+ return DependencyNodeDependencies(tokenSignature, [], [], [], []);
+ }
+}
diff --git a/pkg/analyzer/test/src/dart/analysis/dependency/declared_nodes_test.dart b/pkg/analyzer/test/src/dart/analysis/dependency/declared_nodes_test.dart
new file mode 100644
index 0000000..fec1f34
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/analysis/dependency/declared_nodes_test.dart
@@ -0,0 +1,1709 @@
+// Copyright (c) 2018, 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:analyzer/src/dart/analysis/dependency/library_builder.dart'
+ hide buildLibrary;
+import 'package:analyzer/src/dart/analysis/dependency/node.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'base.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(DeclaredNodesTest);
+ });
+}
+
+@reflectiveTest
+class DeclaredNodesTest extends BaseDependencyTest {
+ test_class_constructor() async {
+ var library = await buildTestLibrary(a, r'''
+class C {
+ C();
+ C.named();
+}
+''');
+ assertNodes(library.declaredNodes, [
+ ExpectedNode(
+ aUri,
+ 'C',
+ DependencyNodeKind.CLASS,
+ classMembers: [
+ ExpectedNode(aUri, '', DependencyNodeKind.CONSTRUCTOR),
+ ExpectedNode(aUri, 'named', DependencyNodeKind.CONSTRUCTOR),
+ ],
+ ),
+ ]);
+ }
+
+ test_class_constructor_api_tokens_notSame_annotation() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.CONSTRUCTOR,
+ 'class X { X.foo(); }',
+ 'class X { @deprecated X.foo(); }',
+ memberOf: 'X',
+ );
+ }
+
+ test_class_constructor_api_tokens_notSame_parameter_add() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.CONSTRUCTOR,
+ 'class X { X.foo(); }',
+ 'class X { X.foo(int a); }',
+ memberOf: 'X',
+ );
+ }
+
+ test_class_constructor_api_tokens_notSame_parameter_name_edit_named() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.CONSTRUCTOR,
+ 'class X { X.foo({int a}); }',
+ 'class X { X.foo({int b}); }',
+ memberOf: 'X',
+ );
+ }
+
+ test_class_constructor_api_tokens_notSame_parameter_type() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.CONSTRUCTOR,
+ 'class X { X.foo(int a); }',
+ 'class X { X.foo(double a); }',
+ memberOf: 'X',
+ );
+ }
+
+ test_class_constructor_api_tokens_same_body() async {
+ await _assertApiTokenSignatureSame(
+ 'foo',
+ DependencyNodeKind.CONSTRUCTOR,
+ 'class X { X.foo() { print(1); } }',
+ 'class X { X.foo() { print(2); } }',
+ memberOf: 'X',
+ );
+ }
+
+ test_class_constructor_api_tokens_same_body_add() async {
+ await _assertApiTokenSignatureSame(
+ 'foo',
+ DependencyNodeKind.CONSTRUCTOR,
+ 'class X { X.foo(); }',
+ 'class X { X.foo() {} }',
+ memberOf: 'X',
+ );
+ }
+
+ test_class_constructor_api_tokens_same_parameter_name_edit_required() async {
+ await _assertApiTokenSignatureSame(
+ 'foo',
+ DependencyNodeKind.CONSTRUCTOR,
+ 'class X { X.foo(int a); }',
+ 'class X { X.foo(int b); }',
+ memberOf: 'X',
+ );
+ }
+
+ test_class_constructor_default() async {
+ var library = await buildTestLibrary(a, r'''
+class C {}
+''');
+ assertNodes(library.declaredNodes, [
+ ExpectedNode(
+ aUri,
+ 'C',
+ DependencyNodeKind.CLASS,
+ classMembers: [
+ ExpectedNode(aUri, '', DependencyNodeKind.CONSTRUCTOR),
+ ],
+ ),
+ ]);
+ }
+
+ test_class_field() async {
+ var library = await buildTestLibrary(a, r'''
+class C {
+ int a = 1;
+ int b = 2, c = 3;
+}
+''');
+ assertNodes(library.declaredNodes, [
+ ExpectedNode(
+ aUri,
+ 'C',
+ DependencyNodeKind.CLASS,
+ classMembers: [
+ ExpectedNode(aUri, '', DependencyNodeKind.CONSTRUCTOR),
+ ExpectedNode(aUri, 'a', DependencyNodeKind.GETTER),
+ ExpectedNode(aUri, 'b', DependencyNodeKind.GETTER),
+ ExpectedNode(aUri, 'c', DependencyNodeKind.GETTER),
+ ExpectedNode(aUri, 'a=', DependencyNodeKind.SETTER),
+ ExpectedNode(aUri, 'b=', DependencyNodeKind.SETTER),
+ ExpectedNode(aUri, 'c=', DependencyNodeKind.SETTER),
+ ],
+ ),
+ ]);
+ }
+
+ test_class_field_api_tokens_notSame_annotation() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.GETTER,
+ 'class X { int foo = 0; }',
+ 'class X { @deprecated int foo = 0; }',
+ memberOf: 'X',
+ );
+ }
+
+ test_class_field_api_tokens_notSame_const() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.GETTER,
+ 'class X { int foo = 0; }',
+ 'class X { const int foo = 0; }',
+ memberOf: 'X',
+ );
+ }
+
+ test_class_field_api_tokens_same_final() async {
+ await _assertApiTokenSignatureSame(
+ 'foo',
+ DependencyNodeKind.GETTER,
+ 'class X { int foo = 0; }',
+ 'class X { final int foo = 0; }',
+ memberOf: 'X',
+ );
+ }
+
+ test_class_field_api_tokens_typed_notSame_type() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.GETTER,
+ 'class X { int foo = 0; }',
+ 'class X { num foo = 1; }',
+ memberOf: 'X',
+ );
+ }
+
+ test_class_field_api_tokens_typed_same_initializer() async {
+ await _assertApiTokenSignatureSame(
+ 'foo',
+ DependencyNodeKind.GETTER,
+ 'class X { int foo = 0; }',
+ 'class X { int foo = 1; }',
+ memberOf: 'X',
+ );
+ }
+
+ test_class_field_api_tokens_untyped_notSame_initializer() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.GETTER,
+ 'class X { var foo = 0; }',
+ 'class X { var foo = 1.0; }',
+ memberOf: 'X',
+ );
+ }
+
+ test_class_field_const() async {
+ var library = await buildTestLibrary(a, r'''
+class X {
+ const foo = 1;
+ const bar = 2;
+}
+''');
+ assertNodes(library.declaredNodes, [
+ ExpectedNode(
+ aUri,
+ 'X',
+ DependencyNodeKind.CLASS,
+ classMembers: [
+ ExpectedNode(aUri, '', DependencyNodeKind.CONSTRUCTOR),
+ ExpectedNode(aUri, 'foo', DependencyNodeKind.GETTER),
+ ExpectedNode(aUri, 'bar', DependencyNodeKind.GETTER),
+ ],
+ ),
+ ]);
+ }
+
+ test_class_field_const_api_tokens_typed_notSame_initializer() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.GETTER,
+ 'class X { const int foo = 0; }',
+ 'class X { const int foo = 1; }',
+ memberOf: 'X',
+ );
+ }
+
+ test_class_field_final() async {
+ var library = await buildTestLibrary(a, r'''
+class X {
+ final foo = 1;
+ final bar = 2;
+}
+''');
+ assertNodes(library.declaredNodes, [
+ ExpectedNode(
+ aUri,
+ 'X',
+ DependencyNodeKind.CLASS,
+ classMembers: [
+ ExpectedNode(aUri, '', DependencyNodeKind.CONSTRUCTOR),
+ ExpectedNode(aUri, 'foo', DependencyNodeKind.GETTER),
+ ExpectedNode(aUri, 'bar', DependencyNodeKind.GETTER),
+ ],
+ ),
+ ]);
+ }
+
+ test_class_field_final_api_tokens_typed_notSame_initializer_constClass() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.GETTER,
+ 'class X { final int foo = 0; const X(); }',
+ 'class X { final int foo = 1; const X(); }',
+ memberOf: 'X',
+ );
+ }
+
+ test_class_field_final_api_tokens_typed_same_initializer() async {
+ await _assertApiTokenSignatureSame(
+ 'foo',
+ DependencyNodeKind.GETTER,
+ 'class X { final int foo = 0; }',
+ 'class X { final int foo = 1; }',
+ memberOf: 'X',
+ );
+ }
+
+ test_class_field_final_api_tokens_untyped_notSame_initializer() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.GETTER,
+ 'class X { final foo = 0; }',
+ 'class X { final foo = 1.0; }',
+ memberOf: 'X',
+ );
+ }
+
+ test_class_getter() async {
+ var library = await buildTestLibrary(a, r'''
+class C {
+ int get foo => 0;
+ int get bar => 0;
+}
+''');
+ assertNodes(library.declaredNodes, [
+ ExpectedNode(
+ aUri,
+ 'C',
+ DependencyNodeKind.CLASS,
+ classMembers: [
+ ExpectedNode(aUri, '', DependencyNodeKind.CONSTRUCTOR),
+ ExpectedNode(aUri, 'foo', DependencyNodeKind.GETTER),
+ ExpectedNode(aUri, 'bar', DependencyNodeKind.GETTER),
+ ],
+ ),
+ ]);
+ }
+
+ test_class_getter_api_tokens_notSame_returnType() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.GETTER,
+ 'class X { int get foo => null; }',
+ 'class X { double get foo => null; }',
+ memberOf: 'X',
+ );
+ }
+
+ test_class_method() async {
+ var library = await buildTestLibrary(a, r'''
+class C {
+ void foo() {}
+ void bar() {}
+}
+''');
+ assertNodes(library.declaredNodes, [
+ ExpectedNode(
+ aUri,
+ 'C',
+ DependencyNodeKind.CLASS,
+ classMembers: [
+ ExpectedNode(aUri, '', DependencyNodeKind.CONSTRUCTOR),
+ ExpectedNode(aUri, 'foo', DependencyNodeKind.METHOD),
+ ExpectedNode(aUri, 'bar', DependencyNodeKind.METHOD),
+ ],
+ ),
+ ]);
+ }
+
+ test_class_method_api_tokens_notSame_annotation() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.METHOD,
+ 'class X { void foo() {} }',
+ 'class X { @deprecated void foo() {} }',
+ memberOf: 'X',
+ );
+ }
+
+ test_class_method_api_tokens_notSame_parameter_add() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.METHOD,
+ 'class X { void foo() {} }',
+ 'class X { void foo(int a) {} }',
+ memberOf: 'X',
+ );
+ }
+
+ test_class_method_api_tokens_notSame_parameter_name_edit_named() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.METHOD,
+ 'class X { void foo({int a}) {} }',
+ 'class X { void foo({int b}) {} }',
+ memberOf: 'X',
+ );
+ }
+
+ test_class_method_api_tokens_notSame_parameter_type() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.METHOD,
+ 'class X { void foo(int a) {} }',
+ 'class X { void foo(double a) {} }',
+ memberOf: 'X',
+ );
+ }
+
+ test_class_method_api_tokens_notSame_returnType() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.METHOD,
+ 'class X { int foo() {} }',
+ 'class X { double foo() {} }',
+ memberOf: 'X',
+ );
+ }
+
+ test_class_method_api_tokens_notSame_typeParameter_add() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.METHOD,
+ 'class X { void foo() {} }',
+ 'class X { void foo<T>() {} }',
+ memberOf: 'X',
+ );
+ }
+
+ test_class_method_api_tokens_notSame_typeParameter_bound_add() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.METHOD,
+ 'class X { void foo<T>() {} }',
+ 'class X { void foo<T extends num>() {} }',
+ memberOf: 'X',
+ );
+ }
+
+ test_class_method_api_tokens_same_async_add() async {
+ await _assertApiTokenSignatureSame(
+ 'foo',
+ DependencyNodeKind.METHOD,
+ 'class X { foo() {} }',
+ 'class X { foo() async {} }',
+ memberOf: 'X',
+ );
+ }
+
+ test_class_method_api_tokens_same_body() async {
+ await _assertApiTokenSignatureSame(
+ 'foo',
+ DependencyNodeKind.METHOD,
+ 'class X { void foo() { print(1); } }',
+ 'class X { void foo() { print(2); } }',
+ memberOf: 'X',
+ );
+ }
+
+ test_class_method_api_tokens_same_parameter_name_edit_required() async {
+ await _assertApiTokenSignatureSame(
+ 'foo',
+ DependencyNodeKind.METHOD,
+ 'class X { void foo(int a) {} }',
+ 'class X { void foo(int b) {} }',
+ memberOf: 'X',
+ );
+ }
+
+ test_class_setter() async {
+ var library = await buildTestLibrary(a, r'''
+class C {
+ set foo(_) {}
+ set bar(_) {}
+}
+''');
+ assertNodes(library.declaredNodes, [
+ ExpectedNode(
+ aUri,
+ 'C',
+ DependencyNodeKind.CLASS,
+ classMembers: [
+ ExpectedNode(aUri, '', DependencyNodeKind.CONSTRUCTOR),
+ ExpectedNode(aUri, 'foo', DependencyNodeKind.SETTER),
+ ExpectedNode(aUri, 'bar', DependencyNodeKind.SETTER),
+ ],
+ ),
+ ]);
+ }
+
+ test_class_setter_api_tokens_notSame_returnType() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.SETTER,
+ 'class X { set foo(int a) {} }',
+ 'class X { set foo(double a) {} }',
+ memberOf: 'X',
+ );
+ }
+
+ test_class_setter_api_tokens_same_parameter_name() async {
+ await _assertApiTokenSignatureSame(
+ 'foo',
+ DependencyNodeKind.SETTER,
+ 'class X { set foo(int a) {} }',
+ 'class X { set foo(int b) {} }',
+ memberOf: 'X',
+ );
+ }
+
+ test_class_typeParameter() async {
+ var library = await buildTestLibrary(a, r'''
+class A<T> {}
+class B<T, U> {}
+''');
+ assertNodes(library.declaredNodes, [
+ ExpectedNode(
+ aUri,
+ 'A',
+ DependencyNodeKind.CLASS,
+ classMembers: [
+ ExpectedNode(aUri, '', DependencyNodeKind.CONSTRUCTOR),
+ ],
+ classTypeParameters: [
+ ExpectedNode(aUri, 'T', DependencyNodeKind.TYPE_PARAMETER),
+ ],
+ ),
+ ExpectedNode(
+ aUri,
+ 'B',
+ DependencyNodeKind.CLASS,
+ classMembers: [
+ ExpectedNode(aUri, '', DependencyNodeKind.CONSTRUCTOR),
+ ],
+ classTypeParameters: [
+ ExpectedNode(aUri, 'T', DependencyNodeKind.TYPE_PARAMETER),
+ ExpectedNode(aUri, 'U', DependencyNodeKind.TYPE_PARAMETER),
+ ],
+ ),
+ ]);
+ }
+
+ test_class_typeParameter_api_tokens_notSame_annotation() async {
+ await _assertApiTokenSignatureNotSame(
+ 'T',
+ DependencyNodeKind.TYPE_PARAMETER,
+ 'class X<T> {}',
+ 'class X<@deprecate T> {}',
+ typeParameterOf: 'X',
+ );
+ }
+
+ test_class_typeParameter_api_tokens_notSame_bound_add() async {
+ await _assertApiTokenSignatureNotSame(
+ 'T',
+ DependencyNodeKind.TYPE_PARAMETER,
+ 'class X<T> {}',
+ 'class X<T extends num> {}',
+ typeParameterOf: 'X',
+ );
+ }
+
+ test_class_typeParameter_api_tokens_notSame_bound_edit() async {
+ await _assertApiTokenSignatureNotSame(
+ 'T',
+ DependencyNodeKind.TYPE_PARAMETER,
+ 'class X<T extends num> {}',
+ 'class X<T extends int> {}',
+ typeParameterOf: 'X',
+ );
+ }
+
+ test_library_export() async {
+ var library = await buildTestLibrary(a, r'''
+export 'dart:math';
+export 'package:aaa/aaa.dart';
+export 'package:bbb/bbb.dart' show b1, b2 hide b3;
+''');
+ _assertExports(library, [
+ Export(Uri.parse('dart:math'), []),
+ Export(Uri.parse('package:aaa/aaa.dart'), []),
+ Export(Uri.parse('package:bbb/bbb.dart'), [
+ Combinator(true, ['b1', 'b2']),
+ Combinator(false, ['b3']),
+ ]),
+ ]);
+ }
+
+ test_library_import() async {
+ var library = await buildTestLibrary(a, r'''
+import 'dart:math';
+import 'package:aaa/aaa.dart';
+import 'package:bbb/bbb.dart' as b;
+import 'package:ccc/ccc.dart' show c1, c2 hide c3;
+''');
+ _assertImports(library, [
+ Import(Uri.parse('dart:math'), null, []),
+ Import(Uri.parse('package:aaa/aaa.dart'), null, []),
+ Import(Uri.parse('package:bbb/bbb.dart'), 'b', []),
+ Import(Uri.parse('package:ccc/ccc.dart'), null, [
+ Combinator(true, ['c1', 'c2']),
+ Combinator(false, ['c3']),
+ ]),
+ Import(Uri.parse('dart:core'), null, []),
+ ]);
+ }
+
+ test_library_import_core_explicit() async {
+ var library = await buildTestLibrary(a, r'''
+import 'dart:core' hide List;
+''');
+ _assertImports(library, [
+ Import(Uri.parse('dart:core'), null, [
+ Combinator(false, ['List']),
+ ]),
+ ]);
+ }
+
+ test_library_import_core_implicit() async {
+ var library = await buildTestLibrary(a, '');
+ _assertImports(library, [
+ Import(Uri.parse('dart:core'), null, []),
+ ]);
+ }
+
+ test_unit_class() async {
+ var library = await buildTestLibrary(a, r'''
+class Foo {}
+class Bar {}
+''');
+ assertNodes(library.declaredNodes, [
+ ExpectedNode(aUri, 'Foo', DependencyNodeKind.CLASS, classMembers: [
+ ExpectedNode(aUri, '', DependencyNodeKind.CONSTRUCTOR),
+ ]),
+ ExpectedNode(aUri, 'Bar', DependencyNodeKind.CLASS, classMembers: [
+ ExpectedNode(aUri, '', DependencyNodeKind.CONSTRUCTOR),
+ ]),
+ ]);
+ }
+
+ test_unit_class_api_tokens_notSame_annotation() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.CLASS,
+ 'class X {}',
+ '@deprecated class X {}',
+ );
+ }
+
+ test_unit_class_api_tokens_notSame_extends_add() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.CLASS,
+ 'class X {}',
+ 'class X extends A {}',
+ );
+ }
+
+ test_unit_class_api_tokens_notSame_extends_edit() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.CLASS,
+ 'class X extends A {}',
+ 'class X extends B {}',
+ );
+ }
+
+ test_unit_class_api_tokens_notSame_extends_replace() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.CLASS,
+ 'class X extends A {}',
+ 'class X implements A {}',
+ );
+ }
+
+ test_unit_class_api_tokens_notSame_extends_typeArgument() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.CLASS,
+ 'class X extends A {}',
+ 'class X extends A<int> {}',
+ );
+ }
+
+ test_unit_class_api_tokens_notSame_implements_add() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.CLASS,
+ 'class X {}',
+ 'class X implements A {}',
+ );
+ }
+
+ test_unit_class_api_tokens_notSame_implements_edit() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.CLASS,
+ 'class X implements A {}',
+ 'class X implements B {}',
+ );
+ }
+
+ test_unit_class_api_tokens_notSame_implements_remove() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.CLASS,
+ 'class X implements A {}',
+ 'class X {}',
+ );
+ }
+
+ test_unit_class_api_tokens_notSame_implements_remove2() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.CLASS,
+ 'class X implements A, B {}',
+ 'class X implements B {}',
+ );
+ }
+
+ test_unit_class_api_tokens_notSame_implements_typeArgument() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.CLASS,
+ 'class X implements A {}',
+ 'class X implements A<int> {}',
+ );
+ }
+
+ test_unit_class_api_tokens_notSame_typeParameter_add() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.CLASS,
+ 'class X {}',
+ 'class X<T> {}',
+ );
+ }
+
+ test_unit_class_api_tokens_notSame_typeParameter_add2() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.CLASS,
+ 'class X<T> {}',
+ 'class X<T, U> {}',
+ );
+ }
+
+ test_unit_class_api_tokens_notSame_typeParameter_bound_add() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.CLASS,
+ 'class X<T> {}',
+ 'class X<T extends num> {}',
+ );
+ }
+
+ test_unit_class_api_tokens_notSame_with_add() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.CLASS,
+ 'class X extends A {}',
+ 'class X extends A with B {}',
+ );
+ }
+
+ test_unit_class_api_tokens_notSame_with_edit() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.CLASS,
+ 'class X extends A with B {}',
+ 'class X extends A with C {}',
+ );
+ }
+
+ test_unit_class_api_tokens_notSame_with_typeArgument() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.CLASS,
+ 'class X extends A with B {}',
+ 'class X extends A with B<int> {}',
+ );
+ }
+
+ test_unit_class_api_tokens_same_body() async {
+ await _assertApiTokenSignatureSame(
+ 'X',
+ DependencyNodeKind.CLASS,
+ 'class X { }',
+ 'class X { void foo() {} }',
+ );
+ }
+
+ test_unit_classTypeAlias() async {
+ var library = await buildTestLibrary(a, r'''
+class X = Object with M;
+''');
+ assertNodes(library.declaredNodes, [
+ ExpectedNode(aUri, 'X', DependencyNodeKind.CLASS_TYPE_ALIAS),
+ ]);
+ }
+
+ test_unit_classTypeAlias_api_tokens_notSame_implements_add() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.CLASS_TYPE_ALIAS,
+ 'class X = A with M;',
+ 'class X = A with M implements I;',
+ );
+ }
+
+ test_unit_classTypeAlias_api_tokens_notSame_implements_edit() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.CLASS_TYPE_ALIAS,
+ 'class X = A with M implements I;',
+ 'class X = A with M implements J;',
+ );
+ }
+
+ test_unit_classTypeAlias_api_tokens_notSame_implements_remove() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.CLASS_TYPE_ALIAS,
+ 'class X = A with M implements I;',
+ 'class X = A with M;',
+ );
+ }
+
+ test_unit_classTypeAlias_api_tokens_notSame_implements_typeArgument() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.CLASS_TYPE_ALIAS,
+ 'class X = A with M implements I;',
+ 'class X = A with M implements I<int>;',
+ );
+ }
+
+ test_unit_classTypeAlias_api_tokens_notSame_super() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.CLASS_TYPE_ALIAS,
+ 'class X = A with M;',
+ 'class X = B with M;',
+ );
+ }
+
+ test_unit_classTypeAlias_api_tokens_notSame_super_typeArgument() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.CLASS_TYPE_ALIAS,
+ 'class X = A with M;',
+ 'class X = A<int> with M;',
+ );
+ }
+
+ test_unit_classTypeAlias_api_tokens_notSame_typeParameter_add() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.CLASS_TYPE_ALIAS,
+ 'class X = A with M;',
+ 'class X<T> = A with M;',
+ );
+ }
+
+ test_unit_classTypeAlias_api_tokens_notSame_typeParameter_add2() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.CLASS_TYPE_ALIAS,
+ 'class X<T> = A with M;',
+ 'class X<T, U> = A with M;',
+ );
+ }
+
+ test_unit_classTypeAlias_api_tokens_notSame_typeParameter_bound_add() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.CLASS_TYPE_ALIAS,
+ 'class X<T> = A with M;',
+ 'class X<T extends num> = A with M;',
+ );
+ }
+
+ test_unit_classTypeAlias_api_tokens_notSame_with_add() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.CLASS_TYPE_ALIAS,
+ 'class X = A with M;',
+ 'class X = A with M, N;',
+ );
+ }
+
+ test_unit_classTypeAlias_api_tokens_notSame_with_edit() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.CLASS_TYPE_ALIAS,
+ 'class X = A with M;',
+ 'class X = A with N;',
+ );
+ }
+
+ test_unit_classTypeAlias_api_tokens_notSame_with_typeArgument() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.CLASS_TYPE_ALIAS,
+ 'class X = A with M;',
+ 'class X = A with M<int>;',
+ );
+ }
+
+ test_unit_enumDeclaration() async {
+ var library = await buildTestLibrary(a, r'''
+enum Foo {a, b, c}
+enum Bar {d, e, f}
+''');
+ assertNodes(library.declaredNodes, [
+ ExpectedNode(
+ aUri,
+ 'Foo',
+ DependencyNodeKind.ENUM,
+ classMembers: [
+ ExpectedNode(aUri, 'a', DependencyNodeKind.GETTER),
+ ExpectedNode(aUri, 'b', DependencyNodeKind.GETTER),
+ ExpectedNode(aUri, 'c', DependencyNodeKind.GETTER),
+ ExpectedNode(aUri, 'index', DependencyNodeKind.GETTER),
+ ExpectedNode(aUri, 'values', DependencyNodeKind.GETTER),
+ ],
+ ),
+ ExpectedNode(
+ aUri,
+ 'Bar',
+ DependencyNodeKind.ENUM,
+ classMembers: [
+ ExpectedNode(aUri, 'd', DependencyNodeKind.GETTER),
+ ExpectedNode(aUri, 'e', DependencyNodeKind.GETTER),
+ ExpectedNode(aUri, 'f', DependencyNodeKind.GETTER),
+ ExpectedNode(aUri, 'index', DependencyNodeKind.GETTER),
+ ExpectedNode(aUri, 'values', DependencyNodeKind.GETTER),
+ ],
+ ),
+ ]);
+ }
+
+ test_unit_function() async {
+ var library = await buildTestLibrary(a, r'''
+void foo() {}
+void bar() {}
+''');
+ assertNodes(library.declaredNodes, [
+ ExpectedNode(aUri, 'foo', DependencyNodeKind.FUNCTION),
+ ExpectedNode(aUri, 'bar', DependencyNodeKind.FUNCTION),
+ ]);
+ }
+
+ test_unit_function_api_tokens_notSame_annotation() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.FUNCTION,
+ 'void foo() {}',
+ '@deprecated void foo() {}',
+ );
+ }
+
+ test_unit_function_api_tokens_notSame_parameter_add() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.FUNCTION,
+ 'void foo() {}',
+ 'void foo(int a) {}',
+ );
+ }
+
+ test_unit_function_api_tokens_notSame_parameter_name_edit_named() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.FUNCTION,
+ 'void foo({int a}) {}',
+ 'void foo({int b}) {}',
+ );
+ }
+
+ test_unit_function_api_tokens_notSame_parameter_type() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.FUNCTION,
+ 'void foo(int a) {}',
+ 'void foo(double a) {}',
+ );
+ }
+
+ test_unit_function_api_tokens_notSame_returnType() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.FUNCTION,
+ 'int foo() {}',
+ 'num foo() {}',
+ );
+ }
+
+ test_unit_function_api_tokens_notSame_typeParameter_add() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.FUNCTION,
+ 'void foo() {}',
+ 'void foo<T>() {}',
+ );
+ }
+
+ test_unit_function_api_tokens_notSame_typeParameter_bound_add() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.FUNCTION,
+ 'void foo<T>() {}',
+ 'void foo<T extends num>() {}',
+ );
+ }
+
+ test_unit_function_api_tokens_same_async_add() async {
+ await _assertApiTokenSignatureSame(
+ 'foo',
+ DependencyNodeKind.FUNCTION,
+ 'foo() {}',
+ 'foo() async {}',
+ );
+ }
+
+ test_unit_function_api_tokens_same_body() async {
+ await _assertApiTokenSignatureSame(
+ 'foo',
+ DependencyNodeKind.FUNCTION,
+ 'void foo() { print(1); }',
+ 'void foo() { print(2); }',
+ );
+ }
+
+ test_unit_function_api_tokens_same_parameter_name_edit_required() async {
+ await _assertApiTokenSignatureSame(
+ 'foo',
+ DependencyNodeKind.FUNCTION,
+ 'void foo(int a) {}',
+ 'void foo(int b) {}',
+ );
+ }
+
+ test_unit_function_api_tokens_same_syncStar_add() async {
+ await _assertApiTokenSignatureSame(
+ 'foo',
+ DependencyNodeKind.FUNCTION,
+ 'foo() {}',
+ 'foo() sync* {}',
+ );
+ }
+
+ test_unit_functionTypeAlias() async {
+ var library = await buildTestLibrary(a, r'''
+typedef void Foo();
+typedef void Bar();
+''');
+ assertNodes(library.declaredNodes, [
+ ExpectedNode(aUri, 'Foo', DependencyNodeKind.FUNCTION_TYPE_ALIAS),
+ ExpectedNode(aUri, 'Bar', DependencyNodeKind.FUNCTION_TYPE_ALIAS),
+ ]);
+ }
+
+ test_unit_functionTypeAlias_api_tokens_notSame_annotation() async {
+ await _assertApiTokenSignatureNotSame(
+ 'Foo',
+ DependencyNodeKind.FUNCTION_TYPE_ALIAS,
+ 'typedef void Foo();',
+ '@deprecated typedef void Foo();',
+ );
+ }
+
+ test_unit_functionTypeAlias_api_tokens_notSame_parameter_add() async {
+ await _assertApiTokenSignatureNotSame(
+ 'Foo',
+ DependencyNodeKind.FUNCTION_TYPE_ALIAS,
+ 'typedef void Foo();',
+ 'typedef void Foo(int a);',
+ );
+ }
+
+ test_unit_functionTypeAlias_api_tokens_notSame_parameter_name_edit_named() async {
+ await _assertApiTokenSignatureNotSame(
+ 'Foo',
+ DependencyNodeKind.FUNCTION_TYPE_ALIAS,
+ 'typedef void Foo({int a});',
+ 'typedef void Foo({int b});',
+ );
+ }
+
+ test_unit_functionTypeAlias_api_tokens_notSame_parameter_type() async {
+ await _assertApiTokenSignatureNotSame(
+ 'Foo',
+ DependencyNodeKind.FUNCTION_TYPE_ALIAS,
+ 'typedef void Foo(int a);',
+ 'typedef void Foo(double a);',
+ );
+ }
+
+ test_unit_functionTypeAlias_api_tokens_notSame_returnType() async {
+ await _assertApiTokenSignatureNotSame(
+ 'Foo',
+ DependencyNodeKind.FUNCTION_TYPE_ALIAS,
+ 'typedef int Foo();',
+ 'typedef num Foo();',
+ );
+ }
+
+ test_unit_functionTypeAlias_api_tokens_notSame_typeParameter_add() async {
+ await _assertApiTokenSignatureNotSame(
+ 'Foo',
+ DependencyNodeKind.FUNCTION_TYPE_ALIAS,
+ 'typedef void Foo();',
+ 'typedef void Foo<T>();',
+ );
+ }
+
+ test_unit_functionTypeAlias_api_tokens_notSame_typeParameter_bound_add() async {
+ await _assertApiTokenSignatureNotSame(
+ 'Foo',
+ DependencyNodeKind.FUNCTION_TYPE_ALIAS,
+ 'typedef void Foo<T>();',
+ 'typedef void Foo<T extends num>();',
+ );
+ }
+
+ test_unit_functionTypeAlias_api_tokens_same_comment() async {
+ await _assertApiTokenSignatureSame(
+ 'Foo',
+ DependencyNodeKind.FUNCTION_TYPE_ALIAS,
+ 'typedef int Foo();',
+ '/* text */ typedef int Foo();',
+ );
+ }
+
+ test_unit_functionTypeAlias_api_tokens_same_parameter_name_edit_required() async {
+ await _assertApiTokenSignatureSame(
+ 'Foo',
+ DependencyNodeKind.FUNCTION_TYPE_ALIAS,
+ 'typedef void Foo(int a);',
+ 'typedef void Foo(int b);',
+ );
+ }
+
+ test_unit_genericTypeAlias() async {
+ var library = await buildTestLibrary(a, r'''
+typedef Foo = void Function();
+typedef Bar = void Function();
+''');
+ assertNodes(library.declaredNodes, [
+ ExpectedNode(aUri, 'Foo', DependencyNodeKind.GENERIC_TYPE_ALIAS),
+ ExpectedNode(aUri, 'Bar', DependencyNodeKind.GENERIC_TYPE_ALIAS),
+ ]);
+ }
+
+ test_unit_genericTypeAlias_api_tokens_notSame_annotation() async {
+ await _assertApiTokenSignatureNotSame(
+ 'Foo',
+ DependencyNodeKind.GENERIC_TYPE_ALIAS,
+ 'typedef Foo = void Function();',
+ '@deprecated typedef Foo = void Function();',
+ );
+ }
+
+ test_unit_genericTypeAlias_api_tokens_notSame_parameter_add() async {
+ await _assertApiTokenSignatureNotSame(
+ 'Foo',
+ DependencyNodeKind.GENERIC_TYPE_ALIAS,
+ 'typedef Foo = void Function();',
+ 'typedef Foo = void Function(int);',
+ );
+ }
+
+ test_unit_genericTypeAlias_api_tokens_notSame_parameter_kind() async {
+ await _assertApiTokenSignatureNotSame(
+ 'Foo',
+ DependencyNodeKind.GENERIC_TYPE_ALIAS,
+ 'typedef Foo = void Function(int a);',
+ 'typedef Foo = void Function([int a]);',
+ );
+ }
+
+ test_unit_genericTypeAlias_api_tokens_notSame_parameter_name_add_positional() async {
+ await _assertApiTokenSignatureNotSame(
+ 'Foo',
+ DependencyNodeKind.GENERIC_TYPE_ALIAS,
+ 'typedef Foo = void Function([int]);',
+ 'typedef Foo = void Function([int a]);',
+ );
+ }
+
+ test_unit_genericTypeAlias_api_tokens_notSame_parameter_name_edit_named() async {
+ await _assertApiTokenSignatureNotSame(
+ 'Foo',
+ DependencyNodeKind.GENERIC_TYPE_ALIAS,
+ 'typedef Foo = void Function({int a});',
+ 'typedef Foo = void Function({int b});',
+ );
+ }
+
+ test_unit_genericTypeAlias_api_tokens_notSame_parameter_name_edit_positional() async {
+ await _assertApiTokenSignatureNotSame(
+ 'Foo',
+ DependencyNodeKind.GENERIC_TYPE_ALIAS,
+ 'typedef Foo = void Function([int]);',
+ 'typedef Foo = void Function([int a]);',
+ );
+ }
+
+ test_unit_genericTypeAlias_api_tokens_notSame_returnType() async {
+ await _assertApiTokenSignatureNotSame(
+ 'Foo',
+ DependencyNodeKind.GENERIC_TYPE_ALIAS,
+ 'typedef Foo = int Function();',
+ 'typedef Foo = double Function();',
+ );
+ }
+
+ test_unit_genericTypeAlias_api_tokens_notSame_typeParameter2_add() async {
+ await _assertApiTokenSignatureNotSame(
+ 'Foo',
+ DependencyNodeKind.GENERIC_TYPE_ALIAS,
+ 'typedef Foo = void Function();',
+ 'typedef Foo = void Function<T>();',
+ );
+ }
+
+ test_unit_genericTypeAlias_api_tokens_notSame_typeParameter2_bound_add() async {
+ await _assertApiTokenSignatureNotSame(
+ 'Foo',
+ DependencyNodeKind.GENERIC_TYPE_ALIAS,
+ 'typedef Foo = void Function<T>();',
+ 'typedef Foo = void Function<T extends num>();',
+ );
+ }
+
+ test_unit_genericTypeAlias_api_tokens_notSame_typeParameter_add() async {
+ await _assertApiTokenSignatureNotSame(
+ 'Foo',
+ DependencyNodeKind.GENERIC_TYPE_ALIAS,
+ 'typedef Foo = void Function();',
+ 'typedef Foo<T> = void Function();',
+ );
+ }
+
+ test_unit_genericTypeAlias_api_tokens_notSame_typeParameter_bound_add() async {
+ await _assertApiTokenSignatureNotSame(
+ 'Foo',
+ DependencyNodeKind.GENERIC_TYPE_ALIAS,
+ 'typedef Foo<T> = void Function();',
+ 'typedef Foo<T extends num> = void Function();',
+ );
+ }
+
+ test_unit_genericTypeAlias_api_tokens_same_parameter_name_add_required() async {
+ await _assertApiTokenSignatureSame(
+ 'Foo',
+ DependencyNodeKind.GENERIC_TYPE_ALIAS,
+ 'typedef Foo = void Function(int);',
+ 'typedef Foo = void Function(int a);',
+ );
+ }
+
+ test_unit_genericTypeAlias_api_tokens_same_parameter_name_edit_required() async {
+ await _assertApiTokenSignatureSame(
+ 'Foo',
+ DependencyNodeKind.GENERIC_TYPE_ALIAS,
+ 'typedef Foo = void Function(int a);',
+ 'typedef Foo = void Function(int b);',
+ );
+ }
+
+ test_unit_getter() async {
+ var library = await buildTestLibrary(a, r'''
+int get foo => 0;
+int get bar => 0;
+''');
+ assertNodes(library.declaredNodes, [
+ ExpectedNode(aUri, 'foo', DependencyNodeKind.GETTER),
+ ExpectedNode(aUri, 'bar', DependencyNodeKind.GETTER),
+ ]);
+ }
+
+ test_unit_getter_api_tokens_notSame_annotation() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.GETTER,
+ 'int get foo => 0;',
+ '@deprecated int get foo => 0;',
+ );
+ }
+
+ test_unit_getter_api_tokens_notSame_returnType() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.GETTER,
+ 'int get foo => 0;',
+ 'num get foo => 0;',
+ );
+ }
+
+ test_unit_getter_api_tokens_same_body() async {
+ await _assertApiTokenSignatureSame(
+ 'foo',
+ DependencyNodeKind.GETTER,
+ 'int get foo => 0;',
+ 'int get foo => 1;',
+ );
+ }
+
+ test_unit_mixin() async {
+ var library = await buildTestLibrary(a, r'''
+mixin Foo {}
+mixin Bar {}
+''');
+ assertNodes(library.declaredNodes, [
+ ExpectedNode(aUri, 'Foo', DependencyNodeKind.MIXIN,
+ classMembers: const []),
+ ExpectedNode(aUri, 'Bar', DependencyNodeKind.MIXIN,
+ classMembers: const []),
+ ]);
+ }
+
+ test_unit_mixin_api_tokens_notSame_annotation() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.MIXIN,
+ 'mixin X {}',
+ '@deprecated mixin X {}',
+ );
+ }
+
+ test_unit_mixin_api_tokens_notSame_implements_add() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.MIXIN,
+ 'mixin X {}',
+ 'mixin X implements A {}',
+ );
+ }
+
+ test_unit_mixin_api_tokens_notSame_implements_edit() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.MIXIN,
+ 'mixin X implements A {}',
+ 'mixin X implements B {}',
+ );
+ }
+
+ test_unit_mixin_api_tokens_notSame_implements_remove() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.MIXIN,
+ 'mixin X implements A {}',
+ 'mixin X {}',
+ );
+ }
+
+ test_unit_mixin_api_tokens_notSame_implements_remove2() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.MIXIN,
+ 'mixin X implements A, B {}',
+ 'mixin X implements B {}',
+ );
+ }
+
+ test_unit_mixin_api_tokens_notSame_implements_typeArgument() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.MIXIN,
+ 'mixin X implements A {}',
+ 'mixin X implements A<int> {}',
+ );
+ }
+
+ test_unit_mixin_api_tokens_notSame_on_add() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.MIXIN,
+ 'mixin X {}',
+ 'mixin X on A {}',
+ );
+ }
+
+ test_unit_mixin_api_tokens_notSame_on_add2() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.MIXIN,
+ 'mixin X on A {}',
+ 'mixin X on A, B {}',
+ );
+ }
+
+ test_unit_mixin_api_tokens_notSame_on_edit() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.MIXIN,
+ 'mixin X on A {}',
+ 'mixin X on B {}',
+ );
+ }
+
+ test_unit_mixin_api_tokens_notSame_on_replace() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.MIXIN,
+ 'mixin X on A {}',
+ 'mixin X implements A {}',
+ );
+ }
+
+ test_unit_mixin_api_tokens_notSame_on_typeArgument() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.MIXIN,
+ 'mixin X on A {}',
+ 'mixin X on A<int> {}',
+ );
+ }
+
+ test_unit_mixin_api_tokens_notSame_typeParameter_add() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.MIXIN,
+ 'mixin X {}',
+ 'mixin X<T> {}',
+ );
+ }
+
+ test_unit_mixin_api_tokens_notSame_typeParameter_add2() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.MIXIN,
+ 'mixin X<T> {}',
+ 'mixin X<T, U> {}',
+ );
+ }
+
+ test_unit_mixin_api_tokens_notSame_typeParameter_bound_add() async {
+ await _assertApiTokenSignatureNotSame(
+ 'X',
+ DependencyNodeKind.MIXIN,
+ 'mixin X<T> {}',
+ 'mixin X<T extends num> {}',
+ );
+ }
+
+ test_unit_mixin_api_tokens_same_body() async {
+ await _assertApiTokenSignatureSame(
+ 'X',
+ DependencyNodeKind.MIXIN,
+ 'mixin X { }',
+ 'mixin X { void foo() {} }',
+ );
+ }
+
+ test_unit_setter() async {
+ var library = await buildTestLibrary(a, r'''
+void set foo(_) {}
+void set bar(_) {}
+''');
+ assertNodes(library.declaredNodes, [
+ ExpectedNode(aUri, 'foo=', DependencyNodeKind.SETTER),
+ ExpectedNode(aUri, 'bar=', DependencyNodeKind.SETTER),
+ ]);
+ }
+
+ test_unit_setter_api_tokens_notSame_annotation() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo=',
+ DependencyNodeKind.SETTER,
+ 'set foo(int a) {}',
+ '@deprecated set foo(int a) {}',
+ );
+ }
+
+ test_unit_setter_api_tokens_notSame_parameter_type() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo=',
+ DependencyNodeKind.SETTER,
+ 'set foo(int a) {}',
+ 'set foo(num a) {}',
+ );
+ }
+
+ test_unit_setter_api_tokens_same_body() async {
+ await _assertApiTokenSignatureSame(
+ 'foo=',
+ DependencyNodeKind.SETTER,
+ 'set foo(int a) { print(0); }',
+ 'set foo(int a) { print(1); }',
+ );
+ }
+
+ test_unit_variable() async {
+ var library = await buildTestLibrary(a, r'''
+int a = 1;
+int b = 2, c = 3;
+''');
+ assertNodes(library.declaredNodes, [
+ ExpectedNode(aUri, 'a', DependencyNodeKind.GETTER),
+ ExpectedNode(aUri, 'b', DependencyNodeKind.GETTER),
+ ExpectedNode(aUri, 'c', DependencyNodeKind.GETTER),
+ ExpectedNode(aUri, 'a=', DependencyNodeKind.SETTER),
+ ExpectedNode(aUri, 'b=', DependencyNodeKind.SETTER),
+ ExpectedNode(aUri, 'c=', DependencyNodeKind.SETTER),
+ ]);
+ }
+
+ test_unit_variable_api_tokens_notSame_annotation() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.GETTER,
+ 'int foo = 0;',
+ '@deprecated int foo = 0;',
+ );
+ }
+
+ test_unit_variable_api_tokens_notSame_const() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.GETTER,
+ 'int foo = 0;',
+ 'const int foo = 0;',
+ );
+ }
+
+ test_unit_variable_api_tokens_same_final() async {
+ await _assertApiTokenSignatureSame(
+ 'foo',
+ DependencyNodeKind.GETTER,
+ 'int foo = 0;',
+ 'final int foo = 0;',
+ );
+ }
+
+ test_unit_variable_api_tokens_typed_notSame_type() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.GETTER,
+ 'int foo = 0;',
+ 'num foo = 1;',
+ );
+ }
+
+ test_unit_variable_api_tokens_typed_same_initializer() async {
+ await _assertApiTokenSignatureSame(
+ 'foo',
+ DependencyNodeKind.GETTER,
+ 'int foo = 0;',
+ 'int foo = 1;',
+ );
+ }
+
+ test_unit_variable_api_tokens_untyped_notSame_initializer() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.GETTER,
+ 'var foo = 0;',
+ 'var foo = 1.0;',
+ );
+ }
+
+ test_unit_variable_const() async {
+ var library = await buildTestLibrary(a, r'''
+const foo = 1;
+const bar = 2;
+''');
+ assertNodes(library.declaredNodes, [
+ ExpectedNode(aUri, 'foo', DependencyNodeKind.GETTER),
+ ExpectedNode(aUri, 'bar', DependencyNodeKind.GETTER),
+ ]);
+ }
+
+ test_unit_variable_const_api_tokens_typed_notSame_initializer() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.GETTER,
+ 'const int foo = 0;',
+ 'const int foo = 1;',
+ );
+ }
+
+ test_unit_variable_final() async {
+ var library = await buildTestLibrary(a, r'''
+final foo = 1;
+final bar = 2;
+''');
+ assertNodes(library.declaredNodes, [
+ ExpectedNode(aUri, 'foo', DependencyNodeKind.GETTER),
+ ExpectedNode(aUri, 'bar', DependencyNodeKind.GETTER),
+ ]);
+ }
+
+ test_unit_variable_final_api_tokens_typed_same_initializer() async {
+ await _assertApiTokenSignatureSame(
+ 'foo',
+ DependencyNodeKind.GETTER,
+ 'final int foo = 0;',
+ 'final int foo = 1;',
+ );
+ }
+
+ test_unit_variable_final_api_tokens_untyped_notSame_initializer() async {
+ await _assertApiTokenSignatureNotSame(
+ 'foo',
+ DependencyNodeKind.GETTER,
+ 'final foo = 0;',
+ 'final foo = 1.0;',
+ );
+ }
+
+ test_unit_variable_final_withoutValue() async {
+ var library = await buildTestLibrary(a, r'''
+final foo;
+final bar;
+''');
+ assertNodes(library.declaredNodes, [
+ ExpectedNode(aUri, 'foo', DependencyNodeKind.GETTER),
+ ExpectedNode(aUri, 'bar', DependencyNodeKind.GETTER),
+ ]);
+ }
+
+ Future<void> _assertApiTokenSignatureNotSame(
+ String name, DependencyNodeKind kind, String codeBefore, String codeAfter,
+ {String memberOf, String typeParameterOf}) async {
+ DependencyNode getNodeA(Library library) {
+ return getNode(
+ library,
+ uri: aUri,
+ name: name,
+ kind: kind,
+ memberOf: memberOf,
+ typeParameterOf: typeParameterOf,
+ );
+ }
+
+ var libraryBefore = await buildTestLibrary(a, codeBefore);
+ var nodeBefore = getNodeA(libraryBefore);
+
+ var libraryAfter = await buildTestLibrary(a, codeAfter);
+ var nodeAfter = getNodeA(libraryAfter);
+
+ expect(
+ nodeAfter.api.tokenSignatureHex,
+ isNot(nodeBefore.api.tokenSignatureHex),
+ );
+ }
+
+ Future<void> _assertApiTokenSignatureSame(
+ String name, DependencyNodeKind kind, String codeBefore, String codeAfter,
+ {String memberOf, String typeParameterOf}) async {
+ DependencyNode getNodeA(Library library) {
+ return getNode(
+ library,
+ uri: aUri,
+ name: name,
+ kind: kind,
+ memberOf: memberOf,
+ typeParameterOf: typeParameterOf,
+ );
+ }
+
+ var libraryBefore = await buildTestLibrary(a, codeBefore);
+ var nodeBefore = getNodeA(libraryBefore);
+
+ var libraryAfter = await buildTestLibrary(a, codeAfter);
+ var nodeAfter = getNodeA(libraryAfter);
+
+ expect(
+ nodeAfter.api.tokenSignatureHex,
+ nodeBefore.api.tokenSignatureHex,
+ );
+ }
+
+ static void _assertExports(Library library, List<Export> expectedExports) {
+ var actualExports = library.exports;
+ expect(actualExports, hasLength(expectedExports.length));
+ for (var i = 0; i < actualExports.length; ++i) {
+ var actual = actualExports[i];
+ var expected = expectedExports[i];
+ if (actual.uri != expected.uri ||
+ !_equalCombinators(actual.combinators, expected.combinators)) {
+ fail('Expected: $expected\nActual: $actual');
+ }
+ }
+ }
+
+ static void _assertImports(Library library, List<Import> expectedImports) {
+ var actualImports = library.imports;
+ expect(actualImports, hasLength(expectedImports.length));
+ for (var i = 0; i < actualImports.length; ++i) {
+ var actual = actualImports[i];
+ var expected = expectedImports[i];
+ if (actual.uri != expected.uri ||
+ actual.prefix != expected.prefix ||
+ !_equalCombinators(actual.combinators, expected.combinators)) {
+ fail('Expected: $expected\nActual: $actual');
+ }
+ }
+ }
+
+ static bool _equalCombinators(List<Combinator> actualCombinators,
+ List<Combinator> expectedCombinators) {
+ if (actualCombinators.length != expectedCombinators.length) {
+ return false;
+ }
+
+ for (var i = 0; i < actualCombinators.length; i++) {
+ var actualCombinator = actualCombinators[i];
+ var expectedCombinator = expectedCombinators[i];
+ if (actualCombinator.isShow != expectedCombinator.isShow) {
+ return false;
+ }
+
+ var actualNames = actualCombinator.names;
+ var expectedNames = expectedCombinator.names;
+ if (actualNames.length != expectedNames.length) {
+ return false;
+ }
+ for (var j = 0; j < actualNames.length; j++) {
+ if (actualNames[j] != expectedNames[j]) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
index 7841c96..2ca7531 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
@@ -1,17 +1,19 @@
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2018, 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:analyzer/dart/analysis/results.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';
-import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/member.dart';
import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:test/test.dart';
@@ -25,6 +27,7 @@
main() {
defineReflectiveSuite(() {
defineReflectiveTests(AnalysisDriverResolutionTest);
+ defineReflectiveTests(DriverResolutionWithExperimentsTest);
});
}
@@ -41,7 +44,7 @@
*/
@reflectiveTest
class AnalysisDriverResolutionTest extends BaseAnalysisDriverTest {
- AnalysisResult result;
+ ResolvedUnitResult result;
FindNode findNode;
FindElement findElement;
@@ -376,7 +379,7 @@
}
test_annotation_onDirective_part() async {
- provider.newFile(_p('/test/lib/a.dart'), r'''
+ newFile('/test/lib/a.dart', content: r'''
part of 'test.dart';
''');
addTestFile(r'''
@@ -399,8 +402,7 @@
}
test_annotation_onDirective_partOf() async {
- var a = _p('/test/lib/a.dart');
- provider.newFile(a, r'''
+ newFile('/test/lib/a.dart', content: r'''
part 'test.dart';
''');
addTestFile(r'''
@@ -409,7 +411,6 @@
const a = 1;
''');
- driver.addFile(a);
await resolveTestFile();
var directive = findNode.partOf('a.dart');
@@ -522,8 +523,7 @@
}
test_annotation_prefixed_classField() async {
- var a = _p('/test/lib/a.dart');
- provider.newFile(a, r'''
+ newFile('/test/lib/a.dart', content: r'''
class A {
static const a = 1;
}
@@ -563,8 +563,7 @@
}
test_annotation_prefixed_constructor() async {
- var a = _p('/test/lib/a.dart');
- provider.newFile(a, r'''
+ newFile('/test/lib/a.dart', content: r'''
class A {
const A(int a, {int b});
}
@@ -605,8 +604,7 @@
}
test_annotation_prefixed_constructor_named() async {
- var a = _p('/test/lib/a.dart');
- provider.newFile(a, r'''
+ newFile('/test/lib/a.dart', content: r'''
class A {
const A.named(int a, {int b});
}
@@ -649,8 +647,7 @@
}
test_annotation_prefixed_topLevelVariable() async {
- var a = _p('/test/lib/a.dart');
- provider.newFile(a, r'''
+ newFile('/test/lib/a.dart', content: r'''
const topAnnotation = 1;
''');
addTestFile(r'''
@@ -1538,8 +1535,7 @@
@failingTest
test_deferredImport_loadLibrary_invocation() async {
- var a = _p('/test/lib/a.dart');
- provider.newFile(a, '');
+ newFile('/test/lib/a.dart');
addTestFile(r'''
import 'a.dart' deferred as a;
main() {
@@ -1564,8 +1560,7 @@
@failingTest
test_deferredImport_loadLibrary_invocation_argument() async {
- var a = _p('/test/lib/a.dart');
- provider.newFile(a, '');
+ newFile('/test/lib/a.dart');
addTestFile(r'''
import 'a.dart' deferred as a;
var b = 1;
@@ -1599,8 +1594,7 @@
}
test_deferredImport_loadLibrary_tearOff() async {
- var a = _p('/test/lib/a.dart');
- provider.newFile(a, '');
+ newFile('/test/lib/a.dart');
addTestFile(r'''
import 'a.dart' deferred as a;
main() {
@@ -1623,8 +1617,7 @@
}
test_deferredImport_variable() async {
- var a = _p('/test/lib/a.dart');
- provider.newFile(a, 'var v = 0;');
+ newFile('/test/lib/a.dart', content: 'var v = 0;');
addTestFile(r'''
import 'a.dart' deferred as a;
main() async {
@@ -1664,8 +1657,7 @@
}
test_directive_export() async {
- var a = _p('/test/lib/a.dart');
- provider.newFile(a, r'''
+ newFile('/test/lib/a.dart', content: r'''
class MyClass {}
int myVar;
int get myGetter => 0;
@@ -1713,8 +1705,7 @@
}
test_directive_import_hide() async {
- var a = _p('/test/lib/a.dart');
- provider.newFile(a, r'''
+ newFile('/test/lib/a.dart', content: r'''
class MyClass {}
int myVar;
int get myGetter => 0;
@@ -1762,8 +1753,7 @@
}
test_directive_import_show() async {
- var a = _p('/test/lib/a.dart');
- provider.newFile(a, r'''
+ newFile('/test/lib/a.dart', content: r'''
class MyClass {}
int myVar;
int get myGetter => 0;
@@ -2325,8 +2315,7 @@
}
test_instanceCreation_prefixed() async {
- var a = _p('/test/lib/a.dart');
- provider.newFile(a, r'''
+ newFile('/test/lib/a.dart', content: r'''
class C<T> {
C(T p);
C.named(T p);
@@ -3567,7 +3556,6 @@
assertType(aRef, 'int');
}
- @failingTest
test_invalid_methodInvocation_simpleIdentifier() async {
addTestFile(r'''
int foo = 0;
@@ -3720,8 +3708,7 @@
@failingTest
test_invalid_nonTypeAsType_topLevelFunction_prefixed() async {
- var a = _p('/test/lib/a.dart');
- provider.newFile(a, r'''
+ newFile('/test/lib/a.dart', content: r'''
int T() => 0;
''');
addTestFile(r'''
@@ -3789,8 +3776,7 @@
@failingTest
test_invalid_nonTypeAsType_topLevelVariable_prefixed() async {
- var a = _p('/test/lib/a.dart');
- provider.newFile(a, r'''
+ newFile('/test/lib/a.dart', content: r'''
int T;
''');
addTestFile(r'''
@@ -5388,8 +5374,8 @@
expect(target.staticType.toString(), '(int) → double');
SimpleIdentifier methodName = invocation.methodName;
- expect(methodName.staticElement, same(parameter));
- expect(methodName.staticType, parameter.type);
+ expect(methodName.staticElement, isNull);
+ expect(methodName.staticType, dynamicType);
}
test_methodInvocation_instanceMethod_forwardingStub() async {
@@ -5899,7 +5885,7 @@
@failingTest
test_optionalConst_prefixed() async {
- provider.newFile(_p('/test/lib/a.dart'), r'''
+ newFile('/test/lib/a.dart', content: r'''
class C {
const C();
const C.named();
@@ -6426,8 +6412,7 @@
}
test_prefixedIdentifier_importPrefix_className() async {
- var libPath = _p('/test/lib/lib.dart');
- provider.newFile(libPath, '''
+ newFile('/test/lib/lib.dart', content: '''
class MyClass {}
typedef void MyFunctionTypeAlias();
int myTopVariable;
@@ -8019,12 +8004,9 @@
}
test_typeAnnotation_prefixed() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
- var c = _p('/test/lib/c.dart');
- provider.newFile(a, 'class A {}');
- provider.newFile(b, "export 'a.dart';");
- provider.newFile(c, "export 'a.dart';");
+ newFile('/test/lib/a.dart', content: 'class A {}');
+ newFile('/test/lib/b.dart', content: "export 'a.dart';");
+ newFile('/test/lib/c.dart', content: "export 'a.dart';");
addTestFile(r'''
import 'b.dart' as b;
import 'c.dart' as c;
@@ -8737,69 +8719,6 @@
expect(identifier.staticType, isDynamicType);
}
- test_unresolved_static_call() async {
- addTestFile('''
-class C {
- static f() => C.g();
-}
-''');
- await resolveTestFile();
- expect(result.errors, isNotEmpty);
-
- var g = findNode.simple('g()');
- assertElementNull(g);
- assertTypeDynamic(g);
- var invocation = g.parent as MethodInvocation;
- assertTypeDynamic(invocation);
- expect(invocation.staticInvokeType, isDynamicType);
- }
-
- test_unresolved_static_call_arguments() async {
- addTestFile('''
-int x;
-class C {
- static f() => C.g(x);
-}
-''');
- await resolveTestFile();
- expect(result.errors, isNotEmpty);
-
- var x = findNode.simple('x)');
- assertElement(x, findElement.topGet('x'));
- assertType(x, 'int');
- }
-
- test_unresolved_static_call_same_name_as_type_param() async {
- addTestFile('''
-class C<T> {
- static f() => C.T();
-}
-''');
- await resolveTestFile();
- expect(result.errors, isNotEmpty);
-
- var t = findNode.simple('T()');
- assertElementNull(t);
- assertTypeDynamic(t);
- var invocation = t.parent as MethodInvocation;
- assertTypeDynamic(invocation);
- expect(invocation.staticInvokeType, isDynamicType);
- }
-
- test_unresolved_static_call_type_arguments() async {
- addTestFile('''
-class C {
- static f() => C.g<int>();
-}
-''');
- await resolveTestFile();
- expect(result.errors, isNotEmpty);
-
- var intRef = findNode.simple('int>');
- assertElement(intRef, intType.element);
- assertType(intRef, 'int');
- }
-
/// Assert that the [argument] is associated with the [expected]. If the
/// [argument] is a [NamedExpression], the name must be resolved to the
/// parameter.
@@ -8910,7 +8829,7 @@
expect(identifier.staticType, type);
}
- List<Statement> _getMainStatements(AnalysisResult result) {
+ List<Statement> _getMainStatements(ResolvedUnitResult result) {
for (var declaration in result.unit.declarations) {
if (declaration is FunctionDeclaration &&
declaration.name.name == 'main') {
@@ -8922,7 +8841,7 @@
}
TopLevelVariableElement _getTopLevelVariable(
- AnalysisResult result, String name) {
+ ResolvedUnitResult result, String name) {
for (var variable in result.unit.declaredElement.topLevelVariables) {
if (variable.name == name) {
return variable;
@@ -8931,8 +8850,39 @@
fail('Not found $name');
}
- /**
- * Return the [provider] specific path for the given Posix [path].
- */
- String _p(String path) => provider.convertPath(path);
+// String _p(String path) => convertPath(path);
+}
+
+/**
+ * Resolution tests that are run with all of the experiments enabled.
+ */
+@reflectiveTest
+class DriverResolutionWithExperimentsTest extends BaseAnalysisDriverTest {
+ AnalysisOptionsImpl createAnalysisOptions() => super.createAnalysisOptions()
+ ..enabledExperiments = Experiments.activeExperimentNames;
+
+ test_binaryExpression_gtGtGt() async {
+ addTestFile('''
+class A {
+ A operator >>>(int amount) => this;
+}
+f(A a) {
+ a >>> 3;
+}
+''');
+ var result = await driver.getResult(testFile);
+ CompilationUnit unit = result.unit;
+ MethodDeclaration declaration =
+ (unit.declarations[0] as ClassDeclaration).members[0];
+ ExecutableElement operatorElement = declaration.declaredElement;
+ expect(operatorElement.name, '>>>');
+ ExpressionStatement statement =
+ ((unit.declarations[1] as FunctionDeclaration).functionExpression.body
+ as BlockFunctionBody)
+ .block
+ .statements[0];
+ BinaryExpression binary = statement.expression;
+ expect(binary.operator.type, TokenType.GT_GT_GT);
+ expect(binary.staticElement, operatorElement);
+ }
}
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index 0345738..50b6094 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -1,16 +1,15 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
-import 'package:analyzer/dart/analysis/results.dart' as results;
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/standard_resolution_map.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/error.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
@@ -27,11 +26,12 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/package_bundle_reader.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../../../utils.dart';
-import '../../context/mock_sdk.dart';
import 'base.dart';
main() {
@@ -57,8 +57,7 @@
}
@reflectiveTest
-class AnalysisDriverSchedulerTest {
- final MemoryResourceProvider provider = new MemoryResourceProvider();
+class AnalysisDriverSchedulerTest with ResourceProviderMixin {
DartSdk sdk;
final ByteStore byteStore = new MemoryByteStore();
final FileContentOverlay contentOverlay = new FileContentOverlay();
@@ -68,28 +67,28 @@
AnalysisDriverScheduler scheduler;
- List<AnalysisResult> allResults = [];
+ List<ResolvedUnitResult> allResults = [];
AnalysisDriver newDriver() {
- sdk = new MockSdk(resourceProvider: provider);
+ sdk = new MockSdk(resourceProvider: resourceProvider);
AnalysisDriver driver = new AnalysisDriver(
scheduler,
logger,
- provider,
+ resourceProvider,
byteStore,
contentOverlay,
null,
- new SourceFactory(
- [new DartUriResolver(sdk), new ResourceUriResolver(provider)],
- null,
- provider),
+ new SourceFactory([
+ new DartUriResolver(sdk),
+ new ResourceUriResolver(resourceProvider)
+ ], null, resourceProvider),
new AnalysisOptionsImpl());
driver.results.forEach(allResults.add);
return driver;
}
void setUp() {
- sdk = new MockSdk(resourceProvider: provider);
+ sdk = new MockSdk(resourceProvider: resourceProvider);
logger = new PerformanceLog(logBuffer);
scheduler = new AnalysisDriverScheduler(logger);
scheduler.start();
@@ -99,14 +98,14 @@
AnalysisDriver driver1 = newDriver();
AnalysisDriver driver2 = newDriver();
- String a = _p('/a.dart');
- String b = _p('/b.dart');
- String c = _p('/c.dart');
- String d = _p('/d.dart');
- provider.newFile(a, 'class A {}');
- provider.newFile(b, "import 'a.dart';");
- provider.newFile(c, 'class C {}');
- provider.newFile(d, "import 'c.dart';");
+ String a = convertPath('/a.dart');
+ String b = convertPath('/b.dart');
+ String c = convertPath('/c.dart');
+ String d = convertPath('/d.dart');
+ newFile(a, content: 'class A {}');
+ newFile(b, content: "import 'a.dart';");
+ newFile(c, content: 'class C {}');
+ newFile(d, content: "import 'c.dart';");
driver1.addFile(a);
driver1.addFile(b);
driver2.addFile(c);
@@ -115,8 +114,8 @@
await scheduler.waitForIdle();
allResults.clear();
- provider.updateFile(a, 'class A2 {}');
- provider.updateFile(c, 'class C2 {}');
+ modifyFile(a, 'class A2 {}');
+ modifyFile(c, 'class C2 {}');
driver1.changeFile(a);
driver1.changeFile(c);
driver2.changeFile(a);
@@ -132,12 +131,12 @@
AnalysisDriver driver1 = newDriver();
AnalysisDriver driver2 = newDriver();
- String a = _p('/a.dart');
- String b = _p('/b.dart');
- String c = _p('/c.dart');
- provider.newFile(a, "import 'c.dart';");
- provider.newFile(b, 'class B {}');
- provider.newFile(c, "import 'b.dart';");
+ String a = convertPath('/a.dart');
+ String b = convertPath('/b.dart');
+ String c = convertPath('/c.dart');
+ newFile(a, content: "import 'c.dart';");
+ newFile(b, content: 'class B {}');
+ newFile(c, content: "import 'b.dart';");
driver1.addFile(a);
driver1.addFile(b);
driver2.addFile(c);
@@ -145,7 +144,7 @@
await scheduler.waitForIdle();
allResults.clear();
- provider.updateFile(b, 'class B2 {}');
+ modifyFile(b, 'class B2 {}');
driver1.changeFile(b);
driver2.changeFile(b);
@@ -159,14 +158,14 @@
AnalysisDriver driver1 = newDriver();
AnalysisDriver driver2 = newDriver();
- String a = _p('/a.dart');
- String b = _p('/b.dart');
- String c = _p('/c.dart');
- String d = _p('/d.dart');
- provider.newFile(a, 'class A {}');
- provider.newFile(b, "export 'a.dart';");
- provider.newFile(c, "import 'b.dart';");
- provider.newFile(d, "import 'b.dart'; class D extends X {}");
+ String a = convertPath('/a.dart');
+ String b = convertPath('/b.dart');
+ String c = convertPath('/c.dart');
+ String d = convertPath('/d.dart');
+ newFile(a, content: 'class A {}');
+ newFile(b, content: "export 'a.dart';");
+ newFile(c, content: "import 'b.dart';");
+ newFile(d, content: "import 'b.dart'; class D extends X {}");
driver1.addFile(a);
driver1.addFile(b);
driver2.addFile(c);
@@ -175,7 +174,7 @@
await scheduler.waitForIdle();
allResults.clear();
- provider.updateFile(a, 'class A2 {}');
+ modifyFile(a, 'class A2 {}');
driver1.changeFile(a);
driver2.changeFile(a);
@@ -189,19 +188,19 @@
AnalysisDriver driver1 = newDriver();
AnalysisDriver driver2 = newDriver();
- String a = _p('/a.dart');
- String b = _p('/b.dart');
- String c = _p('/c.dart');
- provider.newFile(a, 'class A {}');
- provider.newFile(b, 'class B {}');
- provider.newFile(c, 'class C {}');
+ String a = convertPath('/a.dart');
+ String b = convertPath('/b.dart');
+ String c = convertPath('/c.dart');
+ newFile(a, content: 'class A {}');
+ newFile(b, content: 'class B {}');
+ newFile(c, content: 'class C {}');
driver1.addFile(a);
driver2.addFile(b);
driver2.addFile(c);
driver1.priorityFiles = [a];
driver2.priorityFiles = [a];
- AnalysisResult result = await driver2.getResult(b);
+ ResolvedUnitResult result = await driver2.getResult(b);
expect(result.path, b);
await scheduler.status.firstWhere((status) => status.isIdle);
@@ -216,10 +215,10 @@
AnalysisDriver driver1 = newDriver();
AnalysisDriver driver2 = newDriver();
- String a = _p('/a.dart');
- String b = _p('/b.dart');
- provider.newFile(a, 'class A {}');
- provider.newFile(b, 'class B {}');
+ String a = convertPath('/a.dart');
+ String b = convertPath('/b.dart');
+ newFile(a, content: 'class A {}');
+ newFile(b, content: 'class B {}');
driver1.addFile(a);
driver2.addFile(b);
driver1.priorityFiles = [a];
@@ -236,10 +235,10 @@
AnalysisDriver driver1 = newDriver();
AnalysisDriver driver2 = newDriver();
- String a = _p('/a.dart');
- String b = _p('/b.dart');
- provider.newFile(a, 'class A {}');
- provider.newFile(b, 'class B {}');
+ String a = convertPath('/a.dart');
+ String b = convertPath('/b.dart');
+ newFile(a, content: 'class A {}');
+ newFile(b, content: 'class B {}');
driver1.addFile(a);
driver2.addFile(b);
driver1.priorityFiles = [b];
@@ -256,12 +255,12 @@
AnalysisDriver driver1 = newDriver();
AnalysisDriver driver2 = newDriver();
- String a = _p('/a.dart');
- String b = _p('/b.dart');
- String c = _p('/c.dart');
- provider.newFile(a, 'class A {}');
- provider.newFile(b, 'class B {}');
- provider.newFile(c, 'class C {}');
+ String a = convertPath('/a.dart');
+ String b = convertPath('/b.dart');
+ String c = convertPath('/c.dart');
+ newFile(a, content: 'class A {}');
+ newFile(b, content: 'class B {}');
+ newFile(c, content: 'class C {}');
driver1.addFile(a);
driver1.addFile(b);
driver2.addFile(c);
@@ -280,12 +279,12 @@
AnalysisDriver driver1 = newDriver();
AnalysisDriver driver2 = newDriver();
- String a = _p('/a.dart');
- String b = _p('/b.dart');
- String c = _p('/c.dart');
- provider.newFile(a, 'class A {}');
- provider.newFile(b, 'class B {}');
- provider.newFile(c, 'class C {}');
+ String a = convertPath('/a.dart');
+ String b = convertPath('/b.dart');
+ String c = convertPath('/c.dart');
+ newFile(a, content: 'class A {}');
+ newFile(b, content: 'class B {}');
+ newFile(c, content: 'class C {}');
driver1.addFile(a);
driver2.addFile(b);
driver2.addFile(c);
@@ -312,10 +311,10 @@
AnalysisDriver driver1 = newDriver();
AnalysisDriver driver2 = newDriver();
- String a = _p('/a.dart');
- String b = _p('/b.dart');
- provider.newFile(a, 'class A {}');
- provider.newFile(b, 'class B {}');
+ String a = convertPath('/a.dart');
+ String b = convertPath('/b.dart');
+ newFile(a, content: 'class A {}');
+ newFile(b, content: 'class B {}');
driver1.addFile(a);
driver2.addFile(b);
@@ -339,21 +338,18 @@
await driver1.getFilesReferencingName('X');
expect(allStatuses, isEmpty);
}
-
- String _p(String path) => provider.convertPath(path);
}
@reflectiveTest
class AnalysisDriverTest extends BaseAnalysisDriverTest {
void configurePreviewDart2() {
driver.configure(
- analysisOptions: new AnalysisOptionsImpl.from(driver.analysisOptions)
- ..previewDart2 = true);
+ analysisOptions: new AnalysisOptionsImpl.from(driver.analysisOptions));
}
test_addedFiles() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
driver.addFile(a);
expect(driver.addedFiles, contains(a));
@@ -372,11 +368,11 @@
}
test_addFile_shouldRefresh() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
- provider.newFile(a, 'class A {}');
- provider.newFile(b, r'''
+ newFile(a, content: 'class A {}');
+ newFile(b, content: r'''
import 'a.dart';
''');
@@ -394,7 +390,7 @@
assertNumberOfErrorsInB(1);
// Update 'b' to use 'a', no more hints.
- provider.newFile(b, r'''
+ newFile(b, content: r'''
import 'a.dart';
main() {
print(A);
@@ -407,7 +403,7 @@
// Change 'b' content so that it has a hint.
// Remove 'b' and add it again.
// The file 'b' must be refreshed, and the hint must be reported.
- provider.newFile(b, r'''
+ newFile(b, content: r'''
import 'a.dart';
''');
driver.removeFile(b);
@@ -417,10 +413,10 @@
}
test_addFile_thenRemove() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
- provider.newFile(a, 'class A {}');
- provider.newFile(b, 'class B {}');
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
+ newFile(a, content: 'class A {}');
+ newFile(b, content: 'class B {}');
driver.addFile(a);
driver.addFile(b);
@@ -435,24 +431,24 @@
}
test_analyze_resolveDirectives() async {
- var lib = _p('/test/lib.dart');
- var part1 = _p('/test/part1.dart');
- var part2 = _p('/test/part2.dart');
- provider.newFile(lib, '''
+ var lib = convertPath('/test/lib.dart');
+ var part1 = convertPath('/test/part1.dart');
+ var part2 = convertPath('/test/part2.dart');
+ newFile(lib, content: '''
library lib;
part 'part1.dart';
part 'part2.dart';
''');
- provider.newFile(part1, '''
+ newFile(part1, content: '''
part of lib;
''');
- provider.newFile(part2, '''
+ newFile(part2, content: '''
part of 'lib.dart';
''');
- AnalysisResult libResult = await driver.getResult(lib);
- AnalysisResult partResult1 = await driver.getResult(part1);
- AnalysisResult partResult2 = await driver.getResult(part2);
+ ResolvedUnitResult libResult = await driver.getResult(lib);
+ ResolvedUnitResult partResult1 = await driver.getResult(part1);
+ ResolvedUnitResult partResult2 = await driver.getResult(part2);
CompilationUnit libUnit = libResult.unit;
CompilationUnit partUnit1 = partResult1.unit;
@@ -486,189 +482,87 @@
}
test_analyze_resolveDirectives_error_missingLibraryDirective() async {
- var lib = _p('/test/lib.dart');
- var part = _p('/test/part.dart');
- provider.newFile(lib, '''
+ var lib = convertPath('/test/lib.dart');
+ var part = convertPath('/test/part.dart');
+ newFile(lib, content: '''
part 'part.dart';
''');
- provider.newFile(part, '''
+ newFile(part, content: '''
part of lib;
''');
driver.addFile(lib);
- AnalysisResult libResult = await driver.getResult(lib);
+ ResolvedUnitResult libResult = await driver.getResult(lib);
List<AnalysisError> errors = libResult.errors;
expect(errors, hasLength(1));
expect(errors[0].errorCode, ResolverErrorCode.PART_OF_UNNAMED_LIBRARY);
}
test_analyze_resolveDirectives_error_partOfDifferentLibrary_byName() async {
- var lib = _p('/test/lib.dart');
- var part = _p('/test/part.dart');
- provider.newFile(lib, '''
+ var lib = convertPath('/test/lib.dart');
+ var part = convertPath('/test/part.dart');
+ newFile(lib, content: '''
library lib;
part 'part.dart';
''');
- provider.newFile(part, '''
+ newFile(part, content: '''
part of someOtherLib;
''');
driver.addFile(lib);
- AnalysisResult libResult = await driver.getResult(lib);
+ ResolvedUnitResult libResult = await driver.getResult(lib);
List<AnalysisError> errors = libResult.errors;
expect(errors, hasLength(1));
expect(errors[0].errorCode, StaticWarningCode.PART_OF_DIFFERENT_LIBRARY);
}
test_analyze_resolveDirectives_error_partOfDifferentLibrary_byUri() async {
- var lib = _p('/test/lib.dart');
- var part = _p('/test/part.dart');
- provider.newFile(lib, '''
+ var lib = convertPath('/test/lib.dart');
+ var part = convertPath('/test/part.dart');
+ newFile(lib, content: '''
library lib;
part 'part.dart';
''');
- provider.newFile(part, '''
+ newFile(part, content: '''
part of 'other_lib.dart';
''');
driver.addFile(lib);
- AnalysisResult libResult = await driver.getResult(lib);
+ ResolvedUnitResult libResult = await driver.getResult(lib);
List<AnalysisError> errors = libResult.errors;
expect(errors, hasLength(1));
expect(errors[0].errorCode, StaticWarningCode.PART_OF_DIFFERENT_LIBRARY);
}
test_analyze_resolveDirectives_error_partOfNonPart() async {
- var lib = _p('/test/lib.dart');
- var part = _p('/test/part.dart');
- provider.newFile(lib, '''
+ var lib = convertPath('/test/lib.dart');
+ var part = convertPath('/test/part.dart');
+ newFile(lib, content: '''
library lib;
part 'part.dart';
''');
- provider.newFile(part, '''
+ newFile(part, content: '''
// no part of directive
''');
driver.addFile(lib);
- AnalysisResult libResult = await driver.getResult(lib);
+ ResolvedUnitResult libResult = await driver.getResult(lib);
List<AnalysisError> errors = libResult.errors;
expect(errors, hasLength(1));
expect(errors[0].errorCode, CompileTimeErrorCode.PART_OF_NON_PART);
}
- test_asyncChangesDuringAnalysis_getErrors() async {
- var path = _p('/test/lib/test.dart');
- provider.newFile(path, 'class A {}');
- driver.addFile(path);
-
- // Compute and cache errors.
- await driver.getErrors(path);
- await waitForIdleWithoutExceptions();
-
- // Simulate a change that happens during reading the cached errors.
- bool asyncWorkExecuted = false;
- driver.test.workToWaitAfterComputingResult = (path) async {
- await new Future.value(); // the rest will be executed asynchronously
- provider.updateFile(path, 'class B');
- driver.changeFile(path);
- asyncWorkExecuted = true;
- };
-
- ErrorsResult result = await driver.getErrors(testFile);
- expect(asyncWorkExecuted, isTrue);
- expect(result.errors, isNotEmpty);
- }
-
- test_asyncChangesDuringAnalysis_getResult() async {
- var path = _p('/test/lib/test.dart');
- provider.newFile(path, 'class A {}');
- driver.addFile(path);
-
- // Schedule the result to be computed.
- Future<AnalysisResult> future1 = driver.getResult(testFile);
-
- // Simulate a change that happens during computing the result.
- // We also request a new result, which must include the change.
- Future<AnalysisResult> future2;
- bool asyncWorkExecuted = false;
- driver.test.workToWaitAfterComputingResult = (path) async {
- provider.updateFile(path, 'class B {}');
- driver.changeFile(path);
- future2 = driver.getResult(testFile);
- asyncWorkExecuted = true;
- };
-
- // Both futures complete, with the same result.
- // The result must be with the new changes.
- //
- // It would not be wrong to have "class A {}" in result1, and "class B {}"
- // in result2, but we test here the actual implementation behaviour.
- AnalysisResult result1 = await future1;
- AnalysisResult result2 = await future2;
- expect(asyncWorkExecuted, isTrue);
- expect(result2, same(result1));
- expect(result1.path, testFile);
- expect(result1.unit, isNotNull);
- expect((result1.unit.declarations[0] as ClassDeclaration).name.name, 'B');
- }
-
- test_asyncChangesDuringAnalysis_resultsStream() async {
- var path = _p('/test/lib/test.dart');
- provider.newFile(path, 'class A {}');
- driver.addFile(path);
-
- // Simulate a change that happens during computing the result.
- bool asyncWorkExecuted = false;
- driver.test.workToWaitAfterComputingResult = (p) async {
- if (p == path && !asyncWorkExecuted) {
- provider.updateFile(path, 'class B');
- driver.changeFile(path);
- asyncWorkExecuted = true;
- }
- };
-
- await waitForIdleWithoutExceptions();
- expect(asyncWorkExecuted, isTrue);
-
- // The last result must have an error.
- expect(allResults.last.errors, isNotEmpty);
- }
-
- test_asyncChangesDuringAnalysis_resultsStream_priority() async {
- var path = _p('/test/lib/test.dart');
- provider.newFile(path, 'class A {}');
- driver.addFile(path);
- driver.priorityFiles = [path];
-
- // Simulate a change that happens during computing the result.
- bool asyncWorkExecuted = false;
- driver.test.workToWaitAfterComputingResult = (p) async {
- if (p == path && !asyncWorkExecuted) {
- provider.updateFile(path, 'class B {}');
- driver.changeFile(path);
- asyncWorkExecuted = true;
- }
- };
-
- await waitForIdleWithoutExceptions();
- expect(asyncWorkExecuted, isTrue);
-
- // The last unit must have "class B {}".
- var lastUnit = allResults.last.unit;
- expect((lastUnit.declarations[0] as ClassDeclaration).name.name, 'B');
- }
-
test_cachedPriorityResults() async {
- var a = _p('/test/bin/a.dart');
- provider.newFile(a, 'var a = 1;');
+ var a = convertPath('/test/bin/a.dart');
+ newFile(a, content: 'var a = 1;');
driver.priorityFiles = [a];
- AnalysisResult result1 = await driver.getResult(a);
+ ResolvedUnitResult result1 = await driver.getResult(a);
expect(driver.test.priorityResults, containsPair(a, result1));
await waitForIdleWithoutExceptions();
@@ -676,14 +570,14 @@
// Get the (cached) result, not reported to the stream.
{
- AnalysisResult result2 = await driver.getResult(a);
+ ResolvedUnitResult result2 = await driver.getResult(a);
expect(result2, same(result1));
expect(allResults, isEmpty);
}
// Get the (cached) result, reported to the stream.
{
- AnalysisResult result2 =
+ ResolvedUnitResult result2 =
await driver.getResult(a, sendCachedToStream: true);
expect(result2, same(result1));
@@ -693,28 +587,28 @@
}
test_cachedPriorityResults_flush_onAnyFileChange() async {
- var a = _p('/test/bin/a.dart');
- var b = _p('/test/bin/b.dart');
- provider.newFile(a, 'var a = 1;');
- provider.newFile(a, 'var b = 2;');
+ var a = convertPath('/test/bin/a.dart');
+ var b = convertPath('/test/bin/b.dart');
+ newFile(a, content: 'var a = 1;');
+ newFile(a, content: 'var b = 2;');
driver.priorityFiles = [a];
- AnalysisResult result1 = await driver.getResult(a);
+ ResolvedUnitResult result1 = await driver.getResult(a);
expect(driver.test.priorityResults, containsPair(a, result1));
// Change a file.
// The cache is flushed.
driver.changeFile(a);
expect(driver.test.priorityResults, isEmpty);
- AnalysisResult result2 = await driver.getResult(a);
+ ResolvedUnitResult result2 = await driver.getResult(a);
expect(driver.test.priorityResults, containsPair(a, result2));
// Add a file.
// The cache is flushed.
driver.addFile(b);
expect(driver.test.priorityResults, isEmpty);
- AnalysisResult result3 = await driver.getResult(a);
+ ResolvedUnitResult result3 = await driver.getResult(a);
expect(driver.test.priorityResults, containsPair(a, result3));
// Remove a file.
@@ -724,14 +618,14 @@
}
test_cachedPriorityResults_flush_onPrioritySetChange() async {
- var a = _p('/test/bin/a.dart');
- var b = _p('/test/bin/b.dart');
- provider.newFile(a, 'var a = 1;');
- provider.newFile(b, 'var b = 2;');
+ var a = convertPath('/test/bin/a.dart');
+ var b = convertPath('/test/bin/b.dart');
+ newFile(a, content: 'var a = 1;');
+ newFile(b, content: 'var b = 2;');
driver.priorityFiles = [a];
- AnalysisResult result1 = await driver.getResult(a);
+ ResolvedUnitResult result1 = await driver.getResult(a);
expect(driver.test.priorityResults, hasLength(1));
expect(driver.test.priorityResults, containsPair(a, result1));
@@ -742,7 +636,7 @@
expect(driver.test.priorityResults, containsPair(a, result1));
// Get the result for "b".
- AnalysisResult result2 = await driver.getResult(b);
+ ResolvedUnitResult result2 = await driver.getResult(b);
expect(driver.test.priorityResults, hasLength(2));
expect(driver.test.priorityResults, containsPair(a, result1));
expect(driver.test.priorityResults, containsPair(b, result2));
@@ -755,25 +649,25 @@
}
test_cachedPriorityResults_notPriority() async {
- var a = _p('/test/bin/a.dart');
- provider.newFile(a, 'var a = 1;');
+ var a = convertPath('/test/bin/a.dart');
+ newFile(a, content: 'var a = 1;');
- AnalysisResult result1 = await driver.getResult(a);
+ ResolvedUnitResult result1 = await driver.getResult(a);
expect(driver.test.priorityResults, isEmpty);
// The file is not priority, so its result is not cached.
- AnalysisResult result2 = await driver.getResult(a);
+ ResolvedUnitResult result2 = await driver.getResult(a);
expect(result2, isNot(same(result1)));
}
test_changeFile_implicitlyAnalyzed() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
- provider.newFile(a, r'''
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
+ newFile(a, content: r'''
import 'b.dart';
var A = B;
''');
- provider.newFile(b, 'var B = 1;');
+ newFile(b, content: 'var B = 1;');
driver.priorityFiles = [a];
driver.addFile(a);
@@ -782,13 +676,13 @@
await waitForIdleWithoutExceptions();
expect(allResults, hasLength(1));
{
- AnalysisResult ar = allResults.firstWhere((r) => r.path == a);
+ ResolvedUnitResult ar = allResults.firstWhere((r) => r.path == a);
expect(_getTopLevelVarType(ar.unit, 'A'), 'int');
}
allResults.clear();
// Change "b" and notify.
- provider.updateFile(b, 'var B = 1.2;');
+ modifyFile(b, 'var B = 1.2;');
driver.changeFile(b);
// "b" is not an added file, so it is not scheduled for analysis.
@@ -799,7 +693,7 @@
await waitForIdleWithoutExceptions();
expect(allResults, hasLength(1));
{
- AnalysisResult ar = allResults.firstWhere((r) => r.path == a);
+ ResolvedUnitResult ar = allResults.firstWhere((r) => r.path == a);
expect(_getTopLevelVarType(ar.unit, 'A'), 'double');
}
}
@@ -812,10 +706,10 @@
}
test_changeFile_notUsed() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/other/b.dart');
- provider.newFile(a, '');
- provider.newFile(b, 'class B1 {}');
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/other/b.dart');
+ newFile(a);
+ newFile(b, content: 'class B1 {}');
driver.addFile(a);
@@ -824,7 +718,7 @@
// Change "b" and notify.
// Nothing depends on "b", so nothing is analyzed.
- provider.updateFile(b, 'class B2 {}');
+ modifyFile(b, 'class B2 {}');
driver.changeFile(b);
await waitForIdleWithoutExceptions();
expect(allResults, isEmpty);
@@ -834,14 +728,14 @@
}
test_changeFile_selfConsistent() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
- provider.newFile(a, r'''
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
+ newFile(a, content: r'''
import 'b.dart';
var A1 = 1;
var A2 = B1;
''');
- provider.newFile(b, r'''
+ newFile(b, content: r'''
import 'a.dart';
var B1 = A1;
''');
@@ -854,18 +748,18 @@
// We have results for both "a" and "b".
expect(allResults, hasLength(2));
{
- AnalysisResult ar = allResults.firstWhere((r) => r.path == a);
+ ResolvedUnitResult ar = allResults.firstWhere((r) => r.path == a);
expect(_getTopLevelVarType(ar.unit, 'A1'), 'int');
expect(_getTopLevelVarType(ar.unit, 'A2'), 'int');
}
{
- AnalysisResult br = allResults.firstWhere((r) => r.path == b);
+ ResolvedUnitResult br = allResults.firstWhere((r) => r.path == b);
expect(_getTopLevelVarType(br.unit, 'B1'), 'int');
}
// Clear the results and update "a".
allResults.clear();
- provider.updateFile(a, r'''
+ modifyFile(a, r'''
import 'b.dart';
var A1 = 1.2;
var A2 = B1;
@@ -877,12 +771,12 @@
await waitForIdleWithoutExceptions();
expect(allResults, hasLength(2));
{
- AnalysisResult ar = allResults.firstWhere((r) => r.path == a);
+ ResolvedUnitResult ar = allResults.firstWhere((r) => r.path == a);
expect(_getTopLevelVarType(ar.unit, 'A1'), 'double');
expect(_getTopLevelVarType(ar.unit, 'A2'), 'double');
}
{
- AnalysisResult br = allResults.firstWhere((r) => r.path == b);
+ ResolvedUnitResult br = allResults.firstWhere((r) => r.path == b);
expect(_getTopLevelVarType(br.unit, 'B1'), 'double');
}
}
@@ -894,14 +788,14 @@
{
await waitForIdleWithoutExceptions();
expect(allResults, hasLength(1));
- AnalysisResult result = allResults[0];
+ ResolvedUnitResult result = allResults[0];
expect(result.path, testFile);
expect(_getTopLevelVarType(result.unit, 'V'), 'int');
}
// Update the file, but don't notify the driver.
allResults.clear();
- provider.updateFile(testFile, 'var V = 1.2;');
+ modifyFile(testFile, 'var V = 1.2;');
// No new results.
await pumpEventQueue();
@@ -917,7 +811,7 @@
{
await waitForIdleWithoutExceptions();
expect(allResults, hasLength(1));
- AnalysisResult result = allResults[0];
+ ResolvedUnitResult result = allResults[0];
expect(result.path, testFile);
expect(_getTopLevelVarType(result.unit, 'V'), 'double');
}
@@ -1013,15 +907,15 @@
test_const_implicitCreation() async {
configurePreviewDart2();
- var a = _p('/test/bin/a.dart');
- var b = _p('/test/bin/b.dart');
- provider.newFile(a, r'''
+ var a = convertPath('/test/bin/a.dart');
+ var b = convertPath('/test/bin/b.dart');
+ newFile(a, content: r'''
class C {
const C();
static const C WARNING = C();
}
''');
- provider.newFile(b, r'''
+ newFile(b, content: r'''
import 'a.dart';
class D {
@@ -1032,16 +926,16 @@
const c = C.WARNING;
const d = D.WARNING;
''');
- AnalysisResult result = await driver.getResult(b);
+ ResolvedUnitResult result = await driver.getResult(b);
expect(result.errors, isEmpty);
}
test_const_implicitCreation_rewrite() async {
configurePreviewDart2();
- var a = _p('/test/bin/a.dart');
- var b = _p('/test/bin/b.dart');
- provider.newFile(a, r'''
+ var a = convertPath('/test/bin/a.dart');
+ var b = convertPath('/test/bin/b.dart');
+ newFile(a, content: r'''
class A {
const A();
}
@@ -1056,14 +950,14 @@
const C();
}
''');
- provider.newFile(b, r'''
+ newFile(b, content: r'''
import 'a.dart';
main() {
const C();
}
''');
- AnalysisResult result = await driver.getResult(b);
+ ResolvedUnitResult result = await driver.getResult(b);
expect(result.errors, isEmpty);
}
@@ -1090,15 +984,15 @@
}
test_currentSession() async {
- var a = _p('/a.dart');
+ var a = convertPath('/a.dart');
- provider.newFile(a, 'var V = 1;');
+ newFile(a, content: 'var V = 1;');
await driver.getResult(a);
var session1 = driver.currentSession;
expect(session1, isNotNull);
- provider.updateFile(a, 'var V = 2;');
+ modifyFile(a, 'var V = 2;');
driver.changeFile(a);
await driver.getResult(a);
@@ -1110,19 +1004,19 @@
}
test_discoverAvailableFiles_packages() async {
- var t = _p('/test/lib/test.dart');
- var a1 = _p('/aaa/lib/a1.dart');
- var a2 = _p('/aaa/lib/src/a2.dart');
- var a3 = _p('/aaa/lib/a3.txt');
- var b = _p('/bbb/lib/b.dart');
- var c = _p('/ccc/lib/c.dart');
+ var t = convertPath('/test/lib/test.dart');
+ var a1 = convertPath('/aaa/lib/a1.dart');
+ var a2 = convertPath('/aaa/lib/src/a2.dart');
+ var a3 = convertPath('/aaa/lib/a3.txt');
+ var b = convertPath('/bbb/lib/b.dart');
+ var c = convertPath('/ccc/lib/c.dart');
- provider.newFile(t, 'class T {}');
- provider.newFile(a1, 'class A1 {}');
- provider.newFile(a2, 'class A2 {}');
- provider.newFile(a3, 'text');
- provider.newFile(b, 'class B {}');
- provider.newFile(c, 'class C {}');
+ newFile(t, content: 'class T {}');
+ newFile(a1, content: 'class A1 {}');
+ newFile(a2, content: 'class A2 {}');
+ newFile(a3, content: 'text');
+ newFile(b, content: 'class B {}');
+ newFile(c, content: 'class C {}');
driver.addFile(t);
// Don't add a1.dart, a2.dart, or b.dart - they should be discovered.
@@ -1161,7 +1055,7 @@
export 'foo.dart';
''');
- AnalysisResult result = await driver.getResult(testFile);
+ ResolvedUnitResult result = await driver.getResult(testFile);
List<AnalysisError> errors = result.errors;
expect(errors, hasLength(1));
expect(errors[0].errorCode, CompileTimeErrorCode.URI_DOES_NOT_EXIST);
@@ -1172,7 +1066,7 @@
import 'foo.dart';
''');
- AnalysisResult result = await driver.getResult(testFile);
+ ResolvedUnitResult result = await driver.getResult(testFile);
List<AnalysisError> errors = result.errors;
expect(errors, hasLength(1));
expect(errors[0].errorCode, CompileTimeErrorCode.URI_DOES_NOT_EXIST);
@@ -1186,7 +1080,7 @@
}
''', priority: true);
- AnalysisResult result = await driver.getResult(testFile);
+ ResolvedUnitResult result = await driver.getResult(testFile);
List<AnalysisError> errors = result.errors;
expect(errors, hasLength(1));
expect(errors[0].errorCode, CompileTimeErrorCode.URI_DOES_NOT_EXIST);
@@ -1198,19 +1092,19 @@
part 'foo.dart';
''');
- AnalysisResult result = await driver.getResult(testFile);
+ ResolvedUnitResult result = await driver.getResult(testFile);
List<AnalysisError> errors = result.errors;
expect(errors, hasLength(1));
expect(errors[0].errorCode, CompileTimeErrorCode.URI_DOES_NOT_EXIST);
}
test_externalSummaries() async {
- var a = _p('/a.dart');
- var b = _p('/b.dart');
- provider.newFile(a, r'''
+ var a = convertPath('/a.dart');
+ var b = convertPath('/b.dart');
+ newFile(a, content: r'''
class A {}
''');
- provider.newFile(b, r'''
+ newFile(b, content: r'''
import 'a.dart';
var a = new A();
''');
@@ -1220,37 +1114,37 @@
await createAnalysisDriver().test.getSummaryStore(a);
// There are at least a.dart and dart:core libraries.
- String aUri = provider.pathContext.toUri(a).toString();
+ String aUri = toUri(a).toString();
expect(summaryStore.unlinkedMap.keys, contains(aUri));
expect(summaryStore.linkedMap.keys, contains(aUri));
expect(summaryStore.unlinkedMap.keys, contains('dart:core'));
expect(summaryStore.linkedMap.keys, contains('dart:core'));
// Remove a.dart from the file system.
- provider.deleteFile(a);
+ deleteFile(a);
// We don't need a.dart file when we analyze with the summary store.
// Still no analysis errors.
AnalysisDriver driver =
createAnalysisDriver(externalSummaries: summaryStore);
- AnalysisResult result = await driver.getResult(b);
+ ResolvedUnitResult result = await driver.getResult(b);
expect(result.errors, isEmpty);
}
test_externalSummaries_partReuse() async {
- var a = _p('/a.dart');
- var b = _p('/b.dart');
- var c = _p('/c.dart');
- provider.newFile(a, r'''
+ var a = convertPath('/a.dart');
+ var b = convertPath('/b.dart');
+ var c = convertPath('/c.dart');
+ newFile(a, content: r'''
library a;
part 'b.dart';
class A {}
''');
- provider.newFile(b, r'''
+ newFile(b, content: r'''
part of a;
class _B {}
''');
- provider.newFile(c, r'''
+ newFile(c, content: r'''
library a;
import 'a.dart';
part 'b.dart';
@@ -1262,8 +1156,8 @@
SummaryDataStore summaryStore =
await createAnalysisDriver().test.getSummaryStore(a);
- String aUri = provider.pathContext.toUri(a).toString();
- String bUri = provider.pathContext.toUri(b).toString();
+ String aUri = toUri(a).toString();
+ String bUri = toUri(b).toString();
// There are unlinked units for a.dart and b.dart files.
expect(summaryStore.hasUnlinkedUnit(aUri), isTrue);
expect(summaryStore.hasUnlinkedUnit(bUri), isTrue);
@@ -1273,28 +1167,28 @@
// Remove a.dart from the file system.
// Keep b.dart, because we (re)use it as a part.
- provider.deleteFile(a);
+ deleteFile(a);
// We don't need a.dart file when we analyze with the summary store.
// We can instantiate the class A the library a.dart.
// We can instantiate the class _A the part b.dart.
AnalysisDriver driver =
createAnalysisDriver(externalSummaries: summaryStore);
- AnalysisResult result = await driver.getResult(c);
+ ResolvedUnitResult result = await driver.getResult(c);
expect(result.errors, isEmpty);
}
test_generatedFile() async {
Uri uri = Uri.parse('package:aaa/foo.dart');
- String templatePath = _p('/aaa/lib/foo.dart');
- String generatedPath = _p('/generated/aaa/lib/foo.dart');
+ String templatePath = convertPath('/aaa/lib/foo.dart');
+ String generatedPath = convertPath('/generated/aaa/lib/foo.dart');
- provider.newFile(templatePath, r'''
+ newFile(templatePath, content: r'''
a() {}
b() {}
''');
- provider.newFile(generatedPath, r'''
+ newFile(generatedPath, content: r'''
aaa() {}
bbb() {}
''');
@@ -1338,13 +1232,13 @@
}
test_getCachedResult() async {
- var a = _p('/test/bin/a.dart');
- provider.newFile(a, 'var a = 1;');
+ var a = convertPath('/test/bin/a.dart');
+ newFile(a, content: 'var a = 1;');
expect(driver.getCachedResult(a), isNull);
driver.priorityFiles = [a];
- AnalysisResult result = await driver.getResult(a);
+ ResolvedUnitResult result = await driver.getResult(a);
expect(driver.getCachedResult(a), same(result));
}
@@ -1367,15 +1261,15 @@
}
test_getFilesDefiningClassMemberName_class() async {
- var a = _p('/test/bin/a.dart');
- var b = _p('/test/bin/b.dart');
- var c = _p('/test/bin/c.dart');
- var d = _p('/test/bin/d.dart');
+ var a = convertPath('/test/bin/a.dart');
+ var b = convertPath('/test/bin/b.dart');
+ var c = convertPath('/test/bin/c.dart');
+ var d = convertPath('/test/bin/d.dart');
- provider.newFile(a, 'class A { m1() {} }');
- provider.newFile(b, 'class B { m2() {} }');
- provider.newFile(c, 'class C { m2() {} }');
- provider.newFile(d, 'class D { m3() {} }');
+ newFile(a, content: 'class A { m1() {} }');
+ newFile(b, content: 'class B { m2() {} }');
+ newFile(c, content: 'class C { m2() {} }');
+ newFile(d, content: 'class D { m3() {} }');
driver.addFile(a);
driver.addFile(b);
@@ -1393,15 +1287,15 @@
}
test_getFilesDefiningClassMemberName_mixin() async {
- var a = _p('/test/bin/a.dart');
- var b = _p('/test/bin/b.dart');
- var c = _p('/test/bin/c.dart');
- var d = _p('/test/bin/d.dart');
+ var a = convertPath('/test/bin/a.dart');
+ var b = convertPath('/test/bin/b.dart');
+ var c = convertPath('/test/bin/c.dart');
+ var d = convertPath('/test/bin/d.dart');
- provider.newFile(a, 'mixin A { m1() {} }');
- provider.newFile(b, 'mixin B { m2() {} }');
- provider.newFile(c, 'mixin C { m2() {} }');
- provider.newFile(d, 'mixin D { m3() {} }');
+ newFile(a, content: 'mixin A { m1() {} }');
+ newFile(b, content: 'mixin B { m2() {} }');
+ newFile(c, content: 'mixin C { m2() {} }');
+ newFile(d, content: 'mixin D { m3() {} }');
driver.addFile(a);
driver.addFile(b);
@@ -1419,17 +1313,17 @@
}
test_getFilesReferencingName() async {
- var a = _p('/test/bin/a.dart');
- var b = _p('/test/bin/b.dart');
- var c = _p('/test/bin/c.dart');
- var d = _p('/test/bin/d.dart');
- var e = _p('/test/bin/e.dart');
+ var a = convertPath('/test/bin/a.dart');
+ var b = convertPath('/test/bin/b.dart');
+ var c = convertPath('/test/bin/c.dart');
+ var d = convertPath('/test/bin/d.dart');
+ var e = convertPath('/test/bin/e.dart');
- provider.newFile(a, 'class A {}');
- provider.newFile(b, "import 'a.dart'; A a;");
- provider.newFile(c, "import 'a.dart'; var a = new A();");
- provider.newFile(d, "class A{} A a;");
- provider.newFile(e, "import 'a.dart'; main() {}");
+ newFile(a, content: 'class A {}');
+ newFile(b, content: "import 'a.dart'; A a;");
+ newFile(c, content: "import 'a.dart'; var a = new A();");
+ newFile(d, content: "class A{} A a;");
+ newFile(e, content: "import 'a.dart'; main() {}");
driver.addFile(a);
driver.addFile(b);
@@ -1450,15 +1344,15 @@
}
test_getFilesReferencingName_discover() async {
- var t = _p('/test/lib/test.dart');
- var a = _p('/aaa/lib/a.dart');
- var b = _p('/bbb/lib/b.dart');
- var c = _p('/ccc/lib/c.dart');
+ var t = convertPath('/test/lib/test.dart');
+ var a = convertPath('/aaa/lib/a.dart');
+ var b = convertPath('/bbb/lib/b.dart');
+ var c = convertPath('/ccc/lib/c.dart');
- provider.newFile(t, 'int t;');
- provider.newFile(a, 'int a;');
- provider.newFile(b, 'int b;');
- provider.newFile(c, 'int c;');
+ newFile(t, content: 'int t;');
+ newFile(a, content: 'int a;');
+ newFile(b, content: 'int b;');
+ newFile(c, content: 'int c;');
driver.addFile(t);
@@ -1470,8 +1364,8 @@
}
test_getFileSync_library() async {
- var path = _p('/test/lib/a.dart');
- provider.newFile(path, '');
+ var path = convertPath('/test/lib/a.dart');
+ newFile(path);
var file = driver.getFileSync(path);
expect(file.path, path);
expect(file.uri.toString(), 'package:test/a.dart');
@@ -1486,8 +1380,8 @@
}
test_getFileSync_part() async {
- var path = _p('/test/lib/a.dart');
- provider.newFile(path, 'part of lib;');
+ var path = convertPath('/test/lib/a.dart');
+ newFile(path, content: 'part of lib;');
var file = driver.getFileSync(path);
expect(file.path, path);
expect(file.uri.toString(), 'package:test/a.dart');
@@ -1518,29 +1412,86 @@
} on ArgumentError {}
}
- test_getLibraryByUri_external_resynthesize() async {
- provider.newFile(testFile, r'''
-class Test {}
+ test_getLibraryByUri() async {
+ var a = '/test/lib/a.dart';
+ var b = '/test/lib/b.dart';
+
+ String aUriStr = 'package:test/a.dart';
+ String bUriStr = 'package:test/b.dart';
+
+ newFile(a, content: r'''
+part 'b.dart';
+
+class A {}
+''');
+
+ newFile(b, content: r'''
+part of 'a.dart';
+
+class B {}
+''');
+
+ var library = await driver.getLibraryByUri(aUriStr);
+ expect(library.getType('A'), isNotNull);
+ expect(library.getType('B'), isNotNull);
+
+ // It is an error to ask for a library when we know that it is a part.
+ expect(() async {
+ await driver.getLibraryByUri(bUriStr);
+ }, throwsArgumentError);
+ }
+
+ test_getLibraryByUri_external() async {
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
+
+ String aUriStr = 'package:test/a.dart';
+ String bUriStr = 'package:test/b.dart';
+
+ newFile(a, content: r'''
+part 'b.dart';
+
+class A {}
+''');
+
+ newFile(b, content: r'''
+part of 'a.dart';
+
+class B {}
''');
// Prepare the store with package:test/test.dart URI.
- SummaryDataStore summaryStore =
- await createAnalysisDriver().test.getSummaryStore(testFile);
+ var store = await createAnalysisDriver().test.getSummaryStore(a);
// package:test/test.dart is in the store.
- String uri = 'package:test/test.dart';
- expect(summaryStore.unlinkedMap.keys, contains(uri));
- expect(summaryStore.linkedMap.keys, contains(uri));
+ expect(store.unlinkedMap.keys, contains(aUriStr));
+ expect(store.unlinkedMap.keys, contains(bUriStr));
+ expect(store.linkedMap.keys, contains(aUriStr));
+ expect(store.linkedMap.keys, isNot(contains(bUriStr)));
- // Remove the file from the file system.
- provider.deleteFile(testFile);
+ // Remove the files from the file system.
+ deleteFile(a);
+ deleteFile(b);
- // We can resynthesize the library from the store without reading the file.
- AnalysisDriver driver =
- createAnalysisDriver(externalSummaries: summaryStore);
- expect(driver.test.numOfCreatedLibraryContexts, 0);
- LibraryElement library = await driver.getLibraryByUri(uri);
- expect(library.getType('Test'), isNotNull);
+ // We can resynthesize the library from the store.
+ var driver = createAnalysisDriver(externalSummaries: store);
+
+ // Ask by URI, so we get the "external" FileState.
+ var aUri = Uri.parse(aUriStr);
+ var aFile = driver.fsState.getFileForUri(aUri);
+ expect(aFile.uri, aUri);
+ expect(aFile.path, isNull);
+
+ // We still can resynthesize the library.
+ // The URI is known to be external, so we don't talk to the file.
+ var library = await driver.getLibraryByUri(aUriStr);
+ expect(library.getType('A'), isNotNull);
+ expect(library.getType('B'), isNotNull);
+
+ // It is an error to ask for a library when we know that it is a part.
+ expect(() async {
+ await driver.getLibraryByUri(bUriStr);
+ }, throwsArgumentError);
}
test_getLibraryByUri_sdk_analyze() async {
@@ -1551,11 +1502,9 @@
}
test_getLibraryByUri_sdk_resynthesize() async {
- SummaryDataStore sdkStore;
- {
- String corePath = sdk.mapDartUri('dart:core').fullName;
- sdkStore = await createAnalysisDriver().test.getSummaryStore(corePath);
- }
+ String corePath = sdk.mapDartUri('dart:core').fullName;
+ String asyncPath = sdk.mapDartUri('dart:async').fullName;
+ var sdkStore = await createAnalysisDriver().test.getSummaryStore(corePath);
// There are dart:core and dart:async in the store.
expect(sdkStore.unlinkedMap.keys, contains('dart:core'));
@@ -1563,25 +1512,109 @@
expect(sdkStore.linkedMap.keys, contains('dart:core'));
expect(sdkStore.linkedMap.keys, contains('dart:async'));
- // We don't create new library context (so, don't parse, summarize and
- // link) for dart:core. The library is resynthesized from the provided
- // external store.
+ // Remove dart:core and dart:async.
+ // So, the new driver below cannot parse and summarize them.
+ deleteFile(corePath);
+ deleteFile(asyncPath);
+
+ // We still get get dart:core library element.
AnalysisDriver driver = createAnalysisDriver(externalSummaries: sdkStore);
LibraryElement coreLibrary = await driver.getLibraryByUri('dart:core');
- expect(driver.test.numOfCreatedLibraryContexts, 0);
expect(coreLibrary, isNotNull);
expect(coreLibrary.getType('Object'), isNotNull);
}
- test_getResolvedLibrary_external() async {
- var a1 = _p('/aaa/lib/a1.dart');
- var a2 = _p('/aaa/lib/a2.dart');
+ test_getParsedLibrary_external() async {
+ var a1 = convertPath('/aaa/lib/a1.dart');
+ var a2 = convertPath('/aaa/lib/a2.dart');
var a1UriStr = 'package:aaa/a1.dart';
var a2UriStr = 'package:aaa/a2.dart';
- provider.newFile(a1, "part 'a2.dart'; class A {}");
- provider.newFile(a2, "part of 'a1.dart';");
+ newFile(a1, content: "part 'a2.dart'; class A {}");
+ newFile(a2, content: "part of 'a1.dart';");
+
+ // Build the store with the library.
+ var store = await createAnalysisDriver().test.getSummaryStore(a1);
+ expect(store.unlinkedMap.keys, contains(a1UriStr));
+ expect(store.unlinkedMap.keys, contains(a2UriStr));
+ expect(store.linkedMap.keys, contains(a1UriStr));
+
+ var driver = createAnalysisDriver(externalSummaries: store);
+ var libraryElement = await driver.getLibraryByUri(a1UriStr);
+ var classA = libraryElement.library.getType('A');
+
+ var parsedLibrary = driver.getParsedLibrary(a1);
+ expect(parsedLibrary, isNotNull);
+ expect(parsedLibrary.state, ResultState.NOT_A_FILE);
+ expect(() {
+ parsedLibrary.getElementDeclaration(classA);
+ }, throwsStateError);
+
+ // It is an error to ask for a library when we know that it is a part.
+ expect(() {
+ driver.getParsedLibrary(a2);
+ }, throwsArgumentError);
+ }
+
+ test_getParsedLibraryByUri_external() async {
+ var a1 = convertPath('/aaa/lib/a1.dart');
+ var a2 = convertPath('/aaa/lib/a2.dart');
+
+ var a1UriStr = 'package:aaa/a1.dart';
+ var a2UriStr = 'package:aaa/a2.dart';
+
+ var a1Uri = Uri.parse(a1UriStr);
+ var a2Uri = Uri.parse(a2UriStr);
+
+ newFile(a1, content: "part 'a2.dart'; class A {}");
+ newFile(a2, content: "part of 'a1.dart';");
+
+ // Build the store with the library.
+ var store = await createAnalysisDriver().test.getSummaryStore(a1);
+ expect(store.unlinkedMap.keys, contains(a1UriStr));
+ expect(store.unlinkedMap.keys, contains(a2UriStr));
+ expect(store.linkedMap.keys, contains(a1UriStr));
+
+ var driver = createAnalysisDriver(externalSummaries: store);
+ var libraryElement = await driver.getLibraryByUri(a1UriStr);
+ var classA = libraryElement.library.getType('A');
+
+ {
+ var parsedLibrary = driver.getParsedLibraryByUri(a1Uri);
+ expect(parsedLibrary, isNotNull);
+ expect(parsedLibrary.state, ResultState.NOT_A_FILE);
+ expect(() {
+ parsedLibrary.getElementDeclaration(classA);
+ }, throwsStateError);
+ }
+
+ // We can also get the result from the session.
+ {
+ var session = driver.currentSession;
+ var parsedLibrary = session.getParsedLibraryByElement(libraryElement);
+ expect(parsedLibrary, isNotNull);
+ expect(parsedLibrary.state, ResultState.NOT_A_FILE);
+ expect(() {
+ parsedLibrary.getElementDeclaration(classA);
+ }, throwsStateError);
+ }
+
+ // It is an error to ask for a library when we know that it is a part.
+ expect(() {
+ driver.getParsedLibraryByUri(a2Uri);
+ }, throwsArgumentError);
+ }
+
+ test_getResolvedLibrary_external() async {
+ var a1 = convertPath('/aaa/lib/a1.dart');
+ var a2 = convertPath('/aaa/lib/a2.dart');
+
+ var a1UriStr = 'package:aaa/a1.dart';
+ var a2UriStr = 'package:aaa/a2.dart';
+
+ newFile(a1, content: "part 'a2.dart'; class A {}");
+ newFile(a2, content: "part of 'a1.dart';");
// Build the store with the library.
var store = await createAnalysisDriver().test.getSummaryStore(a1);
@@ -1595,7 +1628,7 @@
var resolvedLibrary = await driver.getResolvedLibrary(a1);
expect(resolvedLibrary, isNotNull);
- expect(resolvedLibrary.state, results.ResultState.NOT_A_FILE);
+ expect(resolvedLibrary.state, ResultState.NOT_A_FILE);
expect(() {
resolvedLibrary.getElementDeclaration(classA);
}, throwsStateError);
@@ -1607,8 +1640,8 @@
}
test_getResolvedLibraryByUri_external() async {
- var a1 = _p('/aaa/lib/a1.dart');
- var a2 = _p('/aaa/lib/a2.dart');
+ var a1 = convertPath('/aaa/lib/a1.dart');
+ var a2 = convertPath('/aaa/lib/a2.dart');
var a1UriStr = 'package:aaa/a1.dart';
var a2UriStr = 'package:aaa/a2.dart';
@@ -1616,8 +1649,8 @@
var a1Uri = Uri.parse(a1UriStr);
var a2Uri = Uri.parse(a2UriStr);
- provider.newFile(a1, "part 'a2.dart'; class A {}");
- provider.newFile(a2, "part of 'a1.dart';");
+ newFile(a1, content: "part 'a2.dart'; class A {}");
+ newFile(a2, content: "part of 'a1.dart';");
// Build the store with the library.
var store = await createAnalysisDriver().test.getSummaryStore(a1);
@@ -1632,7 +1665,7 @@
{
var resolvedLibrary = await driver.getResolvedLibraryByUri(a1Uri);
expect(resolvedLibrary, isNotNull);
- expect(resolvedLibrary.state, results.ResultState.NOT_A_FILE);
+ expect(resolvedLibrary.state, ResultState.NOT_A_FILE);
expect(() {
resolvedLibrary.getElementDeclaration(classA);
}, throwsStateError);
@@ -1644,7 +1677,7 @@
var resolvedLibrary =
await session.getResolvedLibraryByElement(libraryElement);
expect(resolvedLibrary, isNotNull);
- expect(resolvedLibrary.state, results.ResultState.NOT_A_FILE);
+ expect(resolvedLibrary.state, ResultState.NOT_A_FILE);
expect(() {
resolvedLibrary.getElementDeclaration(classA);
}, throwsStateError);
@@ -1660,10 +1693,10 @@
String content = 'int f() => 42;';
addTestFile(content, priority: true);
- AnalysisResult result = await driver.getResult(testFile);
+ ResolvedUnitResult result = await driver.getResult(testFile);
expect(result.path, testFile);
expect(result.uri.toString(), 'package:test/test.dart');
- expect(result.exists, isTrue);
+ expect(result.state, ResultState.VALID);
expect(result.content, content);
expect(result.unit, isNotNull);
expect(result.errors, hasLength(0));
@@ -1678,10 +1711,10 @@
}
test_getResult_constants_defaultParameterValue_localFunction() async {
- var a = _p('/test/bin/a.dart');
- var b = _p('/test/bin/b.dart');
- provider.newFile(a, 'const C = 42;');
- provider.newFile(b, r'''
+ var a = convertPath('/test/bin/a.dart');
+ var b = convertPath('/test/bin/b.dart');
+ newFile(a, content: 'const C = 42;');
+ newFile(b, content: r'''
import 'a.dart';
main() {
foo({int p: C}) {}
@@ -1692,17 +1725,17 @@
driver.addFile(b);
await waitForIdleWithoutExceptions();
- AnalysisResult result = await driver.getResult(b);
+ ResolvedUnitResult result = await driver.getResult(b);
expect(result.errors, isEmpty);
}
test_getResult_doesNotExist() async {
- var a = _p('/test/lib/a.dart');
+ var a = convertPath('/test/lib/a.dart');
- AnalysisResult result = await driver.getResult(a);
+ ResolvedUnitResult result = await driver.getResult(a);
expect(result.path, a);
expect(result.uri.toString(), 'package:test/a.dart');
- expect(result.exists, isFalse);
+ expect(result.state, ResultState.NOT_A_FILE);
expect(result.content, '');
}
@@ -1710,7 +1743,7 @@
String content = 'main() { int vv; }';
addTestFile(content, priority: true);
- AnalysisResult result = await driver.getResult(testFile);
+ ResolvedUnitResult result = await driver.getResult(testFile);
expect(result.path, testFile);
expect(result.errors, hasLength(1));
{
@@ -1723,23 +1756,6 @@
}
}
- test_getResult_fileContentOverlay_throughAnalysisContext() async {
- var a = _p('/test/bin/a.dart');
- var b = _p('/test/bin/b.dart');
-
- provider.newFile(a, 'import "b.dart";');
- provider.newFile(b, 'var v = 1;');
- contentOverlay[b] = 'var v = 2;';
-
- var result = await driver.getResult(a);
-
- // The content that was set into the overlay for "b" should be visible
- // through the AnalysisContext that was used to analyze "a".
- CompilationUnitElement unitA = result.unit.declaredElement;
- Source sourceB = unitA.library.imports[0].importedLibrary.source;
- expect(unitA.context.getContents(sourceB).data, 'var v = 2;');
- }
-
test_getResult_functionTypeFormalParameter_withTypeParameter() async {
// This was code crashing because of incomplete implementation.
// Consider (re)moving after fixing dartbug.com/28515
@@ -1750,7 +1766,7 @@
class B {}
''');
- AnalysisResult result = await driver.getResult(testFile);
+ ResolvedUnitResult result = await driver.getResult(testFile);
expect(result.path, testFile);
}
@@ -1767,10 +1783,10 @@
}
test_getResult_importLibrary_thenRemoveIt() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
- provider.newFile(a, 'class A {}');
- provider.newFile(b, r'''
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
+ newFile(a, content: 'class A {}');
+ newFile(b, content: r'''
import 'a.dart';
class B extends A {}
''');
@@ -1781,17 +1797,17 @@
// No errors in b.dart
{
- AnalysisResult result = await driver.getResult(b);
+ ResolvedUnitResult result = await driver.getResult(b);
expect(result.errors, isEmpty);
}
// Remove a.dart and reanalyze.
- provider.deleteFile(a);
+ deleteFile(a);
driver.removeFile(a);
// The unresolved URI error must be reported.
{
- AnalysisResult result = await driver.getResult(b);
+ ResolvedUnitResult result = await driver.getResult(b);
expect(
result.errors,
contains(predicate((AnalysisError e) =>
@@ -1799,12 +1815,12 @@
}
// Restore a.dart and reanalyze.
- provider.newFile(a, 'class A {}');
+ newFile(a, content: 'class A {}');
driver.addFile(a);
// No errors in b.dart again.
{
- AnalysisResult result = await driver.getResult(b);
+ ResolvedUnitResult result = await driver.getResult(b);
expect(result.errors, isEmpty);
}
}
@@ -1817,7 +1833,7 @@
''', priority: true);
await waitForIdleWithoutExceptions();
- AnalysisResult result = await driver.getResult(testFile);
+ ResolvedUnitResult result = await driver.getResult(testFile);
expect(_getClassFieldType(result.unit, 'C', 'f'), 'int');
}
@@ -1832,7 +1848,7 @@
''', priority: true);
await waitForIdleWithoutExceptions();
- AnalysisResult result = await driver.getResult(testFile);
+ ResolvedUnitResult result = await driver.getResult(testFile);
expect(_getClassMethodReturnType(result.unit, 'A', 'm'), 'int');
expect(_getClassMethodReturnType(result.unit, 'B', 'm'), 'int');
}
@@ -1845,7 +1861,7 @@
class C {}
''', priority: true);
- AnalysisResult result = await driver.getResult(testFile);
+ ResolvedUnitResult result = await driver.getResult(testFile);
ClassDeclaration c = result.unit.declarations[1] as ClassDeclaration;
Annotation a = c.metadata[0];
expect(a.name.name, 'fff');
@@ -1872,7 +1888,7 @@
''';
addTestFile(content);
- AnalysisResult result = await driver.getResult(testFile);
+ ResolvedUnitResult result = await driver.getResult(testFile);
expect(result.path, testFile);
}
@@ -1884,7 +1900,7 @@
''';
addTestFile(content, priority: true);
- AnalysisResult result = await driver.getResult(testFile);
+ ResolvedUnitResult result = await driver.getResult(testFile);
expect(result.path, testFile);
// Has only exports for valid URIs.
List<ExportElement> imports = resolutionMap
@@ -1904,7 +1920,7 @@
''';
addTestFile(content, priority: true);
- AnalysisResult result = await driver.getResult(testFile);
+ ResolvedUnitResult result = await driver.getResult(testFile);
expect(result.path, testFile);
// Has only imports for valid URIs.
List<ImportElement> imports = resolutionMap
@@ -1932,23 +1948,23 @@
}
test_getResult_mix_fileAndPackageUris() async {
- var a = _p('/test/bin/a.dart');
- var b = _p('/test/bin/b.dart');
- var c = _p('/test/lib/c.dart');
- var d = _p('/test/test/d.dart');
- provider.newFile(a, r'''
+ var a = convertPath('/test/bin/a.dart');
+ var b = convertPath('/test/bin/b.dart');
+ var c = convertPath('/test/lib/c.dart');
+ var d = convertPath('/test/test/d.dart');
+ newFile(a, content: r'''
import 'package:test/c.dart';
int x = y;
''');
- provider.newFile(b, r'''
+ newFile(b, content: r'''
import '../lib/c.dart';
int x = y;
''');
- provider.newFile(c, r'''
+ newFile(c, content: r'''
import '../test/d.dart';
var y = z;
''');
- provider.newFile(d, r'''
+ newFile(d, content: r'''
String z = "string";
''');
@@ -1962,7 +1978,7 @@
// package:my_pkg/c.dart's import is erroneous, causing y's reference to z
// to be unresolved (and therefore have type dynamic).
{
- AnalysisResult result = await driver.getResult(a);
+ ResolvedUnitResult result = await driver.getResult(a);
expect(result.errors, isEmpty);
}
@@ -1972,7 +1988,7 @@
// successfully imports file:///my_pkg/test/d.dart, causing y to have an
// inferred type of String.
{
- AnalysisResult result = await driver.getResult(b);
+ ResolvedUnitResult result = await driver.getResult(b);
List<AnalysisError> errors = result.errors;
expect(errors, hasLength(1));
expect(errors[0].errorCode, StaticTypeWarningCode.INVALID_ASSIGNMENT);
@@ -2011,10 +2027,10 @@
}
test_getResult_notDartFile() async {
- var path = _p('/test/lib/test.txt');
- provider.newFile(path, 'class A {}');
+ var path = convertPath('/test/lib/test.txt');
+ newFile(path, content: 'class A {}');
- AnalysisResult result = await driver.getResult(path);
+ ResolvedUnitResult result = await driver.getResult(path);
expect(result, isNotNull);
expect(result.unit.declaredElement.types.map((e) => e.name), ['A']);
}
@@ -2030,15 +2046,15 @@
}
test_getResult_sameFile_twoUris() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
- var c = _p('/test/test/c.dart');
- provider.newFile(a, 'class A<T> {}');
- provider.newFile(b, r'''
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
+ var c = convertPath('/test/test/c.dart');
+ newFile(a, content: 'class A<T> {}');
+ newFile(b, content: r'''
import 'a.dart';
var VB = new A<int>();
''');
- provider.newFile(c, r'''
+ newFile(c, content: r'''
import '../lib/a.dart';
var VC = new A<double>();
''');
@@ -2048,29 +2064,31 @@
await waitForIdleWithoutExceptions();
{
- AnalysisResult result = await driver.getResult(b);
+ ResolvedUnitResult result = await driver.getResult(b);
expect(_getImportSource(result.unit, 0).uri.toString(),
'package:test/a.dart');
expect(_getTopLevelVarType(result.unit, 'VB'), 'A<int>');
}
{
- AnalysisResult result = await driver.getResult(c);
- expect(_getImportSource(result.unit, 0).uri,
- provider.pathContext.toUri(_p('/test/lib/a.dart')));
+ ResolvedUnitResult result = await driver.getResult(c);
+ expect(
+ _getImportSource(result.unit, 0).uri,
+ toUri(convertPath('/test/lib/a.dart')),
+ );
expect(_getTopLevelVarType(result.unit, 'VC'), 'A<double>');
}
}
test_getResult_selfConsistent() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
- provider.newFile(a, r'''
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
+ newFile(a, content: r'''
import 'b.dart';
var A1 = 1;
var A2 = B1;
''');
- provider.newFile(b, r'''
+ newFile(b, content: r'''
import 'a.dart';
var B1 = A1;
''');
@@ -2080,7 +2098,7 @@
await waitForIdleWithoutExceptions();
{
- AnalysisResult result = await driver.getResult(a);
+ ResolvedUnitResult result = await driver.getResult(a);
expect(_getTopLevelVarType(result.unit, 'A1'), 'int');
expect(_getTopLevelVarType(result.unit, 'A2'), 'int');
}
@@ -2092,7 +2110,7 @@
// That's because we check for "a" API signature consistency, and because
// it has changed, we invalidated the dependency cache, relinked libraries
// and recomputed types.
- provider.updateFile(a, r'''
+ modifyFile(a, r'''
import 'b.dart';
var A1 = 1.2;
var A2 = B1;
@@ -2100,7 +2118,7 @@
driver.changeFile(a);
{
- AnalysisResult result = await driver.getResult(a);
+ ResolvedUnitResult result = await driver.getResult(a);
expect(_getTopLevelVarType(result.unit, 'A1'), 'double');
expect(_getTopLevelVarType(result.unit, 'A2'), 'double');
}
@@ -2109,10 +2127,10 @@
test_getResult_thenRemove() async {
addTestFile('main() {}', priority: true);
- Future<AnalysisResult> resultFuture = driver.getResult(testFile);
+ Future<ResolvedUnitResult> resultFuture = driver.getResult(testFile);
driver.removeFile(testFile);
- AnalysisResult result = await resultFuture;
+ ResolvedUnitResult result = await resultFuture;
expect(result, isNotNull);
expect(result.path, testFile);
expect(result.unit, isNotNull);
@@ -2122,20 +2140,20 @@
String content = 'main() {}';
addTestFile(content, priority: true);
- Future<AnalysisResult> future1 = driver.getResult(testFile);
- Future<AnalysisResult> future2 = driver.getResult(testFile);
+ Future<ResolvedUnitResult> future1 = driver.getResult(testFile);
+ Future<ResolvedUnitResult> future2 = driver.getResult(testFile);
// Both futures complete, with the same result.
- AnalysisResult result1 = await future1;
- AnalysisResult result2 = await future2;
+ ResolvedUnitResult result1 = await future1;
+ ResolvedUnitResult result2 = await future2;
expect(result2, same(result1));
expect(result1.path, testFile);
expect(result1.unit, isNotNull);
}
test_getSourceKind_library() async {
- var path = _p('/test/lib/test.dart');
- provider.newFile(path, 'class A {}');
+ var path = convertPath('/test/lib/test.dart');
+ newFile(path, content: 'class A {}');
expect(await driver.getSourceKind(path), SourceKind.LIBRARY);
}
@@ -2147,27 +2165,27 @@
}
test_getSourceKind_notDartFile() async {
- var path = _p('/test/lib/test.txt');
- provider.newFile(path, 'class A {}');
+ var path = convertPath('/test/lib/test.txt');
+ newFile(path, content: 'class A {}');
expect(await driver.getSourceKind(path), isNull);
}
test_getSourceKind_part() async {
- var path = _p('/test/lib/test.dart');
- provider.newFile(path, 'part of lib; class A {}');
+ var path = convertPath('/test/lib/test.dart');
+ newFile(path, content: 'part of lib; class A {}');
expect(await driver.getSourceKind(path), SourceKind.PART);
}
test_getTopLevelNameDeclarations() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
- var c = _p('/test/lib/c.dart');
- var d = _p('/test/lib/d.dart');
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
+ var c = convertPath('/test/lib/c.dart');
+ var d = convertPath('/test/lib/d.dart');
- provider.newFile(a, 'class A {}');
- provider.newFile(b, 'export "a.dart"; class B {}');
- provider.newFile(c, 'import "d.dart"; class C {}');
- provider.newFile(d, 'class D {}');
+ newFile(a, content: 'class A {}');
+ newFile(b, content: 'export "a.dart"; class B {}');
+ newFile(c, content: 'import "d.dart"; class C {}');
+ newFile(d, content: 'class D {}');
driver.addFile(a);
driver.addFile(b);
@@ -2191,17 +2209,17 @@
}
test_getTopLevelNameDeclarations_discover() async {
- var t = _p('/test/lib/test.dart');
- var a1 = _p('/aaa/lib/a1.dart');
- var a2 = _p('/aaa/lib/src/a2.dart');
- var b = _p('/bbb/lib/b.dart');
- var c = _p('/ccc/lib/c.dart');
+ var t = convertPath('/test/lib/test.dart');
+ var a1 = convertPath('/aaa/lib/a1.dart');
+ var a2 = convertPath('/aaa/lib/src/a2.dart');
+ var b = convertPath('/bbb/lib/b.dart');
+ var c = convertPath('/ccc/lib/c.dart');
- provider.newFile(t, 'class T {}');
- provider.newFile(a1, 'class A1 {}');
- provider.newFile(a2, 'class A2 {}');
- provider.newFile(b, 'class B {}');
- provider.newFile(c, 'class C {}');
+ newFile(t, content: 'class T {}');
+ newFile(a1, content: 'class A1 {}');
+ newFile(a2, content: 'class A2 {}');
+ newFile(b, content: 'class B {}');
+ newFile(c, content: 'class C {}');
driver.addFile(t);
// Don't add a1.dart, a2.dart, or b.dart - they should be discovered.
@@ -2224,18 +2242,18 @@
}
test_getTopLevelNameDeclarations_parts() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
- var c = _p('/test/lib/c.dart');
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
+ var c = convertPath('/test/lib/c.dart');
- provider.newFile(a, r'''
+ newFile(a, content: r'''
library lib;
part 'b.dart';
part 'c.dart';
class A {}
''');
- provider.newFile(b, 'part of lib; class B {}');
- provider.newFile(c, 'part of lib; class C {}');
+ newFile(b, content: 'part of lib; class B {}');
+ newFile(c, content: 'part of lib; class C {}');
driver.addFile(a);
driver.addFile(b);
@@ -2279,17 +2297,17 @@
}
test_getUnitElement_notDart() async {
- var path = _p('/test.txt');
- provider.newFile(path, 'class A {}');
+ var path = convertPath('/test.txt');
+ newFile(path, content: 'class A {}');
UnitElementResult unitResult = await driver.getUnitElement(path);
expect(unitResult, isNotNull);
expect(unitResult.element.types.map((e) => e.name), ['A']);
}
test_getUnitElementSignature() async {
- var a = _p('/test/lib/a.dart');
+ var a = convertPath('/test/lib/a.dart');
- provider.newFile(a, 'foo() {}');
+ newFile(a, content: 'foo() {}');
String signature = await driver.getUnitElementSignature(a);
expect(signature, isNotNull);
@@ -2298,7 +2316,7 @@
expect(unitResult.path, a);
expect(unitResult.signature, signature);
- provider.updateFile(a, 'bar() {}');
+ modifyFile(a, 'bar() {}');
driver.changeFile(a);
String signature2 = await driver.getUnitElementSignature(a);
@@ -2307,11 +2325,19 @@
}
test_hasFilesToAnalyze() async {
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
+ var c = convertPath('/test/lib/c.dart');
+
// No files yet, nothing to analyze.
expect(driver.hasFilesToAnalyze, isFalse);
// Add a new file, it should be analyzed.
- addTestFile('main() {}', priority: false);
+ newFile(a, content: r'''
+import 'b.dart';
+main() {}
+''');
+ driver.addFile(a);
expect(driver.hasFilesToAnalyze, isTrue);
// Wait for idle, nothing to do.
@@ -2319,36 +2345,42 @@
expect(driver.hasFilesToAnalyze, isFalse);
// Ask to analyze the file, so there is a file to analyze.
- Future<AnalysisResult> future = driver.getResult(testFile);
+ Future<ResolvedUnitResult> future = driver.getResult(a);
expect(driver.hasFilesToAnalyze, isTrue);
// Once analysis is done, there is nothing to analyze.
await future;
expect(driver.hasFilesToAnalyze, isFalse);
- // Change a file, even if not added, it still might affect analysis.
- driver.changeFile(_p('/not/added.dart'));
+ // Change a file that is not added, but referenced, so known.
+ driver.changeFile(b);
expect(driver.hasFilesToAnalyze, isTrue);
await waitForIdleWithoutExceptions();
expect(driver.hasFilesToAnalyze, isFalse);
+ // Change a file that is not known - neither added, nor referenced.
+ driver.changeFile(c);
+ expect(driver.hasFilesToAnalyze, isFalse);
+ await waitForIdleWithoutExceptions();
+ expect(driver.hasFilesToAnalyze, isFalse);
+
// Request of referenced names is not analysis of a file.
driver.getFilesReferencingName('X');
expect(driver.hasFilesToAnalyze, isFalse);
}
test_hermetic_modifyLibraryFile_resolvePart() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
- provider.newFile(a, r'''
+ newFile(a, content: r'''
library a;
part 'b.dart';
class C {
int foo;
}
''');
- provider.newFile(b, r'''
+ newFile(b, content: r'''
part of a;
var c = new C();
''');
@@ -2360,7 +2392,7 @@
// Modify the library, but don't notify the driver.
// The driver should use the previous library content and elements.
- provider.newFile(a, r'''
+ newFile(a, content: r'''
library a;
part 'b.dart';
class C {
@@ -2377,8 +2409,8 @@
}
test_hermetic_overlayOnly_part() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
contentOverlay[a] = r'''
library a;
part 'b.dart';
@@ -2390,14 +2422,14 @@
driver.addFile(a);
driver.addFile(b);
- AnalysisResult result = await driver.getResult(a);
+ ResolvedUnitResult result = await driver.getResult(a);
expect(result.errors, isEmpty);
expect(_getTopLevelVarType(result.unit, 'b'), 'B');
}
test_instantiateToBounds_invalid() async {
- var a = _p('/test/lib/a.dart');
- provider.newFile(a, r'''
+ var a = convertPath('/test/lib/a.dart');
+ newFile(a, content: r'''
class A<T extends B> {}
class B<T extends A<B>> {}
''');
@@ -2407,30 +2439,31 @@
}
test_isLibraryByUri() async {
- var a1 = _p('/aaa/lib/a1.dart');
- var a2 = _p('/aaa/lib/a2.dart');
- var b1 = _p('/bbb/lib/b1.dart');
- var b2 = _p('/bbb/lib/b2.dart');
+ var a1 = '/aaa/lib/a1.dart';
+ var a2 = '/aaa/lib/a2.dart';
+ var b1 = '/bbb/lib/b1.dart';
+ var b2 = '/bbb/lib/b2.dart';
String a1UriStr = 'package:aaa/a1.dart';
String a2UriStr = 'package:aaa/a2.dart';
String b1UriStr = 'package:bbb/b1.dart';
String b2UriStr = 'package:bbb/b2.dart';
- provider.newFile(a1, "part 'a2.dart';");
- provider.newFile(a2, "part of 'a1.dart';");
- provider.newFile(b1, "part 'b2.dart';");
- provider.newFile(b2, "part of 'b1.dart';");
+ newFile(a1, content: "part 'a2.dart';");
+ newFile(a2, content: "part of 'a1.dart';");
+ newFile(b1, content: "part 'b2.dart';");
+ newFile(b2, content: "part of 'b1.dart';");
// Build the store with the library.
- var store = await createAnalysisDriver().test.getSummaryStore(a1);
+ var store =
+ await createAnalysisDriver().test.getSummaryStore(convertPath(a1));
expect(store.unlinkedMap.keys, contains(a1UriStr));
expect(store.unlinkedMap.keys, contains(a2UriStr));
expect(store.linkedMap.keys, contains(a1UriStr));
// Remove the stored files from the file system.
- provider.deleteFile(a1);
- provider.deleteFile(a2);
+ deleteFile(a1);
+ deleteFile(a2);
// We can ask isLibraryByUri() for both external and local units.
AnalysisDriver driver = createAnalysisDriver(externalSummaries: store);
@@ -2451,8 +2484,8 @@
}
test_issue34619() async {
- var a = _p('/test/lib/a.dart');
- provider.newFile(a, r'''
+ var a = convertPath('/test/lib/a.dart');
+ newFile(a, content: r'''
class C {
final Set<String> f = new Set<String>();
@@ -2465,7 +2498,7 @@
await waitForIdleWithoutExceptions();
// Update the file in a
- provider.updateFile(a, r'''
+ modifyFile(a, r'''
class C {
final Set<String> f = a + b + c;
@@ -2478,15 +2511,15 @@
}
test_knownFiles() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
- var c = _p('/test/lib/c.dart');
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
+ var c = convertPath('/test/lib/c.dart');
- provider.newFile(a, r'''
+ newFile(a, content: r'''
import 'b.dart';
''');
- provider.newFile(b, '');
- provider.newFile(c, '');
+ newFile(b);
+ newFile(c);
driver.addFile(a);
driver.addFile(c);
@@ -2506,10 +2539,10 @@
}
test_knownFiles_beforeAnalysis() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
- provider.newFile(a, '');
+ newFile(a);
// 'a.dart' is added, but not processed yet.
// So, the set of known files is empty yet.
@@ -2526,7 +2559,7 @@
test_missingDartLibrary_async() async {
var asyncPath = sdk.mapDartUri('dart:async').fullName;
- provider.getFile(asyncPath).delete();
+ getFile(asyncPath).delete();
addTestFile('class C {}');
ErrorsResult result = await driver.getErrors(testFile);
@@ -2538,7 +2571,7 @@
test_missingDartLibrary_core() async {
var corePath = sdk.mapDartUri('dart:core').fullName;
- provider.getFile(corePath).delete();
+ getFile(corePath).delete();
addTestFile('class C {}');
ErrorsResult result = await driver.getErrors(testFile);
@@ -2556,27 +2589,27 @@
}
test_parseFile_notDart() async {
- var p = _p('/test/bin/a.txt');
- provider.newFile(p, 'class A {}');
+ var p = convertPath('/test/bin/a.txt');
+ newFile(p, content: 'class A {}');
- ParseResult parseResult = await driver.parseFile(p);
+ ParsedUnitResult parseResult = await driver.parseFile(p);
expect(parseResult, isNotNull);
expect(driver.knownFiles, contains(p));
}
test_parseFile_shouldRefresh() async {
- var p = _p('/test/bin/a.dart');
+ var p = convertPath('/test/bin/a.dart');
- provider.newFile(p, 'class A {}');
+ newFile(p, content: 'class A {}');
driver.addFile(p);
// Get the result, so force the file reading.
await driver.getResult(p);
// Update the file.
- provider.newFile(p, 'class A2 {}');
+ newFile(p, content: 'class A2 {}');
- ParseResult parseResult = await driver.parseFile(p);
+ ParsedUnitResult parseResult = await driver.parseFile(p);
var clazz = parseResult.unit.declarations[0] as ClassDeclaration;
expect(clazz.name.name, 'A2');
}
@@ -2589,44 +2622,44 @@
}
test_parseFileSync_notDart() {
- var p = _p('/test/bin/a.txt');
- provider.newFile(p, 'class A {}');
+ var p = convertPath('/test/bin/a.txt');
+ newFile(p, content: 'class A {}');
- ParseResult parseResult = driver.parseFileSync(p);
+ ParsedUnitResult parseResult = driver.parseFileSync(p);
expect(parseResult, isNotNull);
expect(driver.knownFiles, contains(p));
}
test_parseFileSync_shouldRefresh() async {
- var p = _p('/test/bin/a.dart');
+ var p = convertPath('/test/bin/a.dart');
- provider.newFile(p, 'class A {}');
+ newFile(p, content: 'class A {}');
driver.addFile(p);
// Get the result, so force the file reading.
await driver.getResult(p);
// Update the file.
- provider.newFile(p, 'class A2 {}');
+ newFile(p, content: 'class A2 {}');
- ParseResult parseResult = driver.parseFileSync(p);
+ ParsedUnitResult parseResult = driver.parseFileSync(p);
var clazz = parseResult.unit.declarations[0] as ClassDeclaration;
expect(clazz.name.name, 'A2');
}
test_part_getErrors_afterLibrary() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
- var c = _p('/test/lib/c.dart');
- provider.newFile(a, r'''
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
+ var c = convertPath('/test/lib/c.dart');
+ newFile(a, content: r'''
library a;
import 'b.dart';
part 'c.dart';
class A {}
var c = new C();
''');
- provider.newFile(b, 'class B {}');
- provider.newFile(c, r'''
+ newFile(b, content: 'class B {}');
+ newFile(c, content: r'''
part of a;
class C {}
var a = new A();
@@ -2651,18 +2684,18 @@
}
test_part_getErrors_beforeLibrary() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
- var c = _p('/test/lib/c.dart');
- provider.newFile(a, r'''
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
+ var c = convertPath('/test/lib/c.dart');
+ newFile(a, content: r'''
library a;
import 'b.dart';
part 'c.dart';
class A {}
var c = new C();
''');
- provider.newFile(b, 'class B {}');
- provider.newFile(c, r'''
+ newFile(b, content: 'class B {}');
+ newFile(c, content: r'''
part of a;
class C {}
var a = new A();
@@ -2681,18 +2714,18 @@
}
test_part_getResult_afterLibrary() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
- var c = _p('/test/lib/c.dart');
- provider.newFile(a, r'''
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
+ var c = convertPath('/test/lib/c.dart');
+ newFile(a, content: r'''
library a;
import 'b.dart';
part 'c.dart';
class A {}
var c = new C();
''');
- provider.newFile(b, 'class B {}');
- provider.newFile(c, r'''
+ newFile(b, content: 'class B {}');
+ newFile(c, content: r'''
part of a;
class C {}
var a = new A();
@@ -2705,14 +2738,14 @@
// Process a.dart so that we know that it's a library for c.dart later.
{
- AnalysisResult result = await driver.getResult(a);
+ ResolvedUnitResult result = await driver.getResult(a);
expect(result.errors, isEmpty);
expect(_getTopLevelVarType(result.unit, 'c'), 'C');
}
// Now c.dart can be resolved without errors in the context of a.dart
{
- AnalysisResult result = await driver.getResult(c);
+ ResolvedUnitResult result = await driver.getResult(c);
expect(result.errors, isEmpty);
expect(_getTopLevelVarType(result.unit, 'a'), 'A');
expect(_getTopLevelVarType(result.unit, 'b'), 'B');
@@ -2720,18 +2753,18 @@
}
test_part_getResult_beforeLibrary() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
- var c = _p('/test/lib/c.dart');
- provider.newFile(a, r'''
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
+ var c = convertPath('/test/lib/c.dart');
+ newFile(a, content: r'''
library a;
import 'b.dart';
part 'c.dart';
class A {}
var c = new C();
''');
- provider.newFile(b, 'class B {}');
- provider.newFile(c, r'''
+ newFile(b, content: 'class B {}');
+ newFile(c, content: r'''
part of a;
class C {}
var a = new A();
@@ -2744,15 +2777,15 @@
// b.dart will be analyzed after a.dart is analyzed.
// So, A and B references are resolved.
- AnalysisResult result = await driver.getResult(c);
+ ResolvedUnitResult result = await driver.getResult(c);
expect(result.errors, isEmpty);
expect(_getTopLevelVarType(result.unit, 'a'), 'A');
expect(_getTopLevelVarType(result.unit, 'b'), 'B');
}
test_part_getResult_noLibrary() async {
- var c = _p('/test/lib/c.dart');
- provider.newFile(c, r'''
+ var c = convertPath('/test/lib/c.dart');
+ newFile(c, content: r'''
part of a;
class C {}
var a = new A();
@@ -2763,24 +2796,24 @@
// There is no library which c.dart is a part of, so it has unresolved
// A and B references.
- AnalysisResult result = await driver.getResult(c);
+ ResolvedUnitResult result = await driver.getResult(c);
expect(result.errors, isNotEmpty);
expect(result.unit, isNotNull);
}
test_part_getUnitElement_afterLibrary() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
- var c = _p('/test/lib/c.dart');
- provider.newFile(a, r'''
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
+ var c = convertPath('/test/lib/c.dart');
+ newFile(a, content: r'''
library a;
import 'b.dart';
part 'c.dart';
class A {}
var c = new C();
''');
- provider.newFile(b, 'class B {}');
- provider.newFile(c, r'''
+ newFile(b, content: 'class B {}');
+ newFile(c, content: r'''
part of a;
class C {}
var a = new A();
@@ -2808,18 +2841,18 @@
}
test_part_getUnitElement_beforeLibrary() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
- var c = _p('/test/lib/c.dart');
- provider.newFile(a, r'''
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
+ var c = convertPath('/test/lib/c.dart');
+ newFile(a, content: r'''
library a;
import 'b.dart';
part 'c.dart';
class A {}
var c = new C();
''');
- provider.newFile(b, 'class B {}');
- provider.newFile(c, r'''
+ newFile(b, content: 'class B {}');
+ newFile(c, content: r'''
part of a;
class C {}
var a = new A();
@@ -2844,8 +2877,8 @@
}
test_part_getUnitElement_noLibrary() async {
- var c = _p('/test/lib/c.dart');
- provider.newFile(c, r'''
+ var c = convertPath('/test/lib/c.dart');
+ newFile(c, content: r'''
part of a;
var a = new A();
var b = new B();
@@ -2868,18 +2901,18 @@
}
test_part_getUnitElementSignature() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
- var c = _p('/test/lib/c.dart');
- provider.newFile(a, r'''
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
+ var c = convertPath('/test/lib/c.dart');
+ newFile(a, content: r'''
library a;
import 'b.dart';
part 'c.dart';
class A {}
var c = new C();
''');
- provider.newFile(b, 'class B {}');
- provider.newFile(c, r'''
+ newFile(b, content: 'class B {}');
+ newFile(c, content: r'''
part of a;
class C {}
var a = new A();
@@ -2902,18 +2935,18 @@
}
test_part_results_afterLibrary() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
- var c = _p('/test/lib/c.dart');
- provider.newFile(a, r'''
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
+ var c = convertPath('/test/lib/c.dart');
+ newFile(a, content: r'''
library a;
import 'b.dart';
part 'c.dart';
class A {}
var c = new C();
''');
- provider.newFile(b, 'class B {}');
- provider.newFile(c, r'''
+ newFile(b, content: 'class B {}');
+ newFile(c, content: r'''
part of a;
class C {}
var a = new A();
@@ -2930,38 +2963,38 @@
// c.dart was added after a.dart, so it is analyzed after a.dart,
// so we know that a.dart is the library of c.dart, so no errors.
- AnalysisResult result = allResults.lastWhere((r) => r.path == c);
+ ResolvedUnitResult result = allResults.lastWhere((r) => r.path == c);
expect(result.errors, isEmpty);
expect(result.unit, isNull);
}
// Update a.dart so that c.dart is not a part.
{
- provider.updateFile(a, '// does not use c.dart anymore');
+ modifyFile(a, '// does not use c.dart anymore');
driver.changeFile(a);
await waitForIdleWithoutExceptions();
// Now c.dart does not have a library context, so A and B cannot be
// resolved, so there are errors.
- AnalysisResult result = allResults.lastWhere((r) => r.path == c);
+ ResolvedUnitResult result = allResults.lastWhere((r) => r.path == c);
expect(result.errors, isNotEmpty);
expect(result.unit, isNull);
}
}
test_part_results_beforeLibrary() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
- var c = _p('/test/lib/c.dart');
- provider.newFile(a, r'''
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
+ var c = convertPath('/test/lib/c.dart');
+ newFile(a, content: r'''
library a;
import 'b.dart';
part 'c.dart';
class A {}
var c = new C();
''');
- provider.newFile(b, 'class B {}');
- provider.newFile(c, r'''
+ newFile(b, content: 'class B {}');
+ newFile(c, content: r'''
part of a;
class C {}
var a = new A();
@@ -2979,14 +3012,14 @@
// a.dart, but we cannot find the library for it, so we delay analysis
// until all other files are analyzed, including a.dart, after which we
// analyze the delayed parts.
- AnalysisResult result = allResults.lastWhere((r) => r.path == c);
+ ResolvedUnitResult result = allResults.lastWhere((r) => r.path == c);
expect(result.errors, isEmpty);
expect(result.unit, isNull);
}
test_part_results_noLibrary() async {
- var c = _p('/test/lib/c.dart');
- provider.newFile(c, r'''
+ var c = convertPath('/test/lib/c.dart');
+ newFile(c, content: r'''
part of a;
class C {}
var a = new A();
@@ -2999,24 +3032,24 @@
// There is no library which c.dart is a part of, so it has unresolved
// A and B references.
- AnalysisResult result = allResults.lastWhere((r) => r.path == c);
+ ResolvedUnitResult result = allResults.lastWhere((r) => r.path == c);
expect(result.errors, isNotEmpty);
expect(result.unit, isNull);
}
test_part_results_priority_beforeLibrary() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
- var c = _p('/test/lib/c.dart');
- provider.newFile(a, r'''
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
+ var c = convertPath('/test/lib/c.dart');
+ newFile(a, content: r'''
library a;
import 'b.dart';
part 'c.dart';
class A {}
var c = new C();
''');
- provider.newFile(b, 'class B {}');
- provider.newFile(c, r'''
+ newFile(b, content: 'class B {}');
+ newFile(c, content: r'''
part of a;
class C {}
var a = new A();
@@ -3035,19 +3068,19 @@
// a.dart, but we cannot find the library for it, so we delay analysis
// until all other files are analyzed, including a.dart, after which we
// analyze the delayed parts.
- AnalysisResult result = allResults.lastWhere((r) => r.path == c);
+ ResolvedUnitResult result = allResults.lastWhere((r) => r.path == c);
expect(result.errors, isEmpty);
expect(result.unit, isNotNull);
}
test_removeFile_changeFile_implicitlyAnalyzed() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
- provider.newFile(a, r'''
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
+ newFile(a, content: r'''
import 'b.dart';
var A = B;
''');
- provider.newFile(b, 'var B = 1;');
+ newFile(b, content: 'var B = 1;');
driver.priorityFiles = [a, b];
driver.addFile(a);
@@ -3057,17 +3090,17 @@
await waitForIdleWithoutExceptions();
expect(allResults, hasLength(2));
{
- AnalysisResult ar = allResults.firstWhere((r) => r.path == a);
+ ResolvedUnitResult ar = allResults.firstWhere((r) => r.path == a);
expect(_getTopLevelVarType(ar.unit, 'A'), 'int');
}
{
- AnalysisResult br = allResults.firstWhere((r) => r.path == b);
+ ResolvedUnitResult br = allResults.firstWhere((r) => r.path == b);
expect(_getTopLevelVarType(br.unit, 'B'), 'int');
}
allResults.clear();
// Remove "b" and send the change notification.
- provider.updateFile(b, 'var B = 1.2;');
+ modifyFile(b, 'var B = 1.2;');
driver.removeFile(b);
driver.changeFile(b);
@@ -3077,7 +3110,7 @@
await waitForIdleWithoutExceptions();
expect(allResults, hasLength(1));
{
- AnalysisResult ar = allResults.firstWhere((r) => r.path == a);
+ ResolvedUnitResult ar = allResults.firstWhere((r) => r.path == a);
expect(_getTopLevelVarType(ar.unit, 'A'), 'double');
}
}
@@ -3102,11 +3135,11 @@
}
test_removeFile_invalidate_importers() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
- provider.newFile(a, 'class A {}');
- provider.newFile(b, "import 'a.dart'; var a = new A();");
+ newFile(a, content: 'class A {}');
+ newFile(b, content: "import 'a.dart'; var a = new A();");
driver.addFile(a);
driver.addFile(b);
@@ -3117,7 +3150,7 @@
allResults.clear();
// Remove a.dart, now b.dart should be reanalyzed and has an error.
- provider.deleteFile(a);
+ deleteFile(a);
driver.removeFile(a);
await waitForIdleWithoutExceptions();
expect(allResults.singleWhere((r) => r.path == b).errors, hasLength(2));
@@ -3132,26 +3165,26 @@
}
test_results_order() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
- var c = _p('/test/lib/c.dart');
- var d = _p('/test/lib/d.dart');
- var e = _p('/test/lib/e.dart');
- var f = _p('/test/lib/f.dart');
- provider.newFile(a, r'''
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
+ var c = convertPath('/test/lib/c.dart');
+ var d = convertPath('/test/lib/d.dart');
+ var e = convertPath('/test/lib/e.dart');
+ var f = convertPath('/test/lib/f.dart');
+ newFile(a, content: r'''
import 'd.dart';
''');
- provider.newFile(b, '');
- provider.newFile(c, r'''
+ newFile(b);
+ newFile(c, content: r'''
import 'd.dart';
''');
- provider.newFile(d, r'''
+ newFile(d, content: r'''
import 'b.dart';
''');
- provider.newFile(e, r'''
+ newFile(e, content: r'''
export 'b.dart';
''');
- provider.newFile(f, r'''
+ newFile(f, content: r'''
import 'e.dart';
class F extends X {}
''');
@@ -3171,7 +3204,7 @@
allResults.clear();
// Update a.dart with changing its API signature.
- provider.updateFile(b, 'class A {}');
+ modifyFile(b, 'class A {}');
driver.changeFile(b);
await waitForIdleWithoutExceptions();
@@ -3188,16 +3221,16 @@
}
test_results_order_allChangedFirst_thenImports() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
- var c = _p('/test/lib/c.dart');
- var d = _p('/test/lib/d.dart');
- var e = _p('/test/lib/e.dart');
- provider.newFile(a, 'class A {}');
- provider.newFile(b, 'class B {}');
- provider.newFile(c, '');
- provider.newFile(d, "import 'a.dart';");
- provider.newFile(e, "import 'b.dart';");
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
+ var c = convertPath('/test/lib/c.dart');
+ var d = convertPath('/test/lib/d.dart');
+ var e = convertPath('/test/lib/e.dart');
+ newFile(a, content: 'class A {}');
+ newFile(b, content: 'class B {}');
+ newFile(c);
+ newFile(d, content: "import 'a.dart';");
+ newFile(e, content: "import 'b.dart';");
driver.addFile(a);
driver.addFile(b);
@@ -3211,8 +3244,8 @@
// Change b.dart and then a.dart files.
// So, a.dart and b.dart should be analyzed first.
// Then d.dart and e.dart because they import a.dart and b.dart files.
- provider.updateFile(a, 'class A2 {}');
- provider.updateFile(b, 'class B2 {}');
+ modifyFile(a, 'class A2 {}');
+ modifyFile(b, 'class B2 {}');
driver.changeFile(b);
driver.changeFile(a);
await waitForIdleWithoutExceptions();
@@ -3235,7 +3268,7 @@
await waitForIdleWithoutExceptions();
expect(allResults, hasLength(1));
- AnalysisResult result = allResults.single;
+ ResolvedUnitResult result = allResults.single;
expect(result.path, testFile);
expect(result.uri.toString(), 'package:test/test.dart');
expect(result.content, content);
@@ -3248,12 +3281,12 @@
}
test_results_priorityFirst() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
- var c = _p('/test/lib/c.dart');
- provider.newFile(a, 'class A {}');
- provider.newFile(b, 'class B {}');
- provider.newFile(c, 'class C {}');
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
+ var c = convertPath('/test/lib/c.dart');
+ newFile(a, content: 'class A {}');
+ newFile(b, content: 'class B {}');
+ newFile(c, content: 'class C {}');
driver.addFile(a);
driver.addFile(b);
@@ -3262,7 +3295,7 @@
await waitForIdleWithoutExceptions();
expect(allResults, hasLength(3));
- AnalysisResult result = allResults[0];
+ ResolvedUnitResult result = allResults[0];
expect(result.path, b);
expect(result.unit, isNotNull);
expect(result.errors, hasLength(0));
@@ -3274,7 +3307,7 @@
await waitForIdleWithoutExceptions();
expect(allResults, hasLength(1));
- AnalysisResult result = allResults.single;
+ ResolvedUnitResult result = allResults.single;
expect(result.path, testFile);
expect(result.uri.toString(), 'package:test/test.dart');
expect(result.content, isNull);
@@ -3283,10 +3316,10 @@
}
test_results_skipNotAffected() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
- provider.newFile(a, 'class A {}');
- provider.newFile(b, 'class B {}');
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
+ newFile(a, content: 'class A {}');
+ newFile(b, content: 'class B {}');
driver.addFile(a);
driver.addFile(b);
@@ -3296,7 +3329,7 @@
allResults.clear();
// Update a.dart and notify.
- provider.updateFile(a, 'class A2 {}');
+ modifyFile(a, 'class A2 {}');
driver.changeFile(a);
// Only result for a.dart should be produced, b.dart is not affected.
@@ -3451,11 +3484,6 @@
.type
.toString();
}
-
- /**
- * Return the [provider] specific path for the given Posix [path].
- */
- String _p(String path) => provider.convertPath(path);
}
@reflectiveTest
@@ -3463,31 +3491,31 @@
bool get disableChangesAndCacheAllResults => true;
test_addFile() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
driver.addFile(a);
driver.addFile(b);
}
test_changeFile() async {
- var path = _p('/test.dart');
+ var path = convertPath('/test.dart');
expect(() {
driver.changeFile(path);
}, throwsStateError);
}
test_getResult_libraryUnits() async {
- var lib = _p('/lib.dart');
- var part1 = _p('/part1.dart');
- var part2 = _p('/part2.dart');
+ var lib = convertPath('/lib.dart');
+ var part1 = convertPath('/part1.dart');
+ var part2 = convertPath('/part2.dart');
- provider.newFile(lib, r'''
+ newFile(lib, content: r'''
library test;
part 'part1.dart';
part 'part2.dart';
''');
- provider.newFile(part1, 'part of test; class A {}');
- provider.newFile(part2, 'part of test; class B {}');
+ newFile(part1, content: 'part of test; class A {}');
+ newFile(part2, content: 'part of test; class B {}');
driver.addFile(lib);
driver.addFile(part1);
@@ -3496,9 +3524,9 @@
// No analyzed libraries initially.
expect(driver.test.numOfAnalyzedLibraries, 0);
- AnalysisResult libResult = await driver.getResult(lib);
- AnalysisResult partResult1 = await driver.getResult(part1);
- AnalysisResult partResult2 = await driver.getResult(part2);
+ ResolvedUnitResult libResult = await driver.getResult(lib);
+ ResolvedUnitResult partResult1 = await driver.getResult(part1);
+ ResolvedUnitResult partResult2 = await driver.getResult(part2);
// Just one library was analyzed, results for parts are cached.
expect(driver.test.numOfAnalyzedLibraries, 1);
@@ -3520,11 +3548,11 @@
}
test_getResult_singleFile() async {
- var path = _p('/test.dart');
- provider.newFile(path, 'main() {}');
+ var path = convertPath('/test.dart');
+ newFile(path, content: 'main() {}');
driver.addFile(path);
- AnalysisResult result1 = await driver.getResult(path);
+ ResolvedUnitResult result1 = await driver.getResult(path);
expect(driver.test.numOfAnalyzedLibraries, 1);
var unit1 = result1.unit;
var unitElement1 = unit1.declaredElement;
@@ -3532,7 +3560,7 @@
expect(unit1, isNotNull);
expect(unitElement1, isNotNull);
- AnalysisResult result2 = await driver.getResult(path);
+ ResolvedUnitResult result2 = await driver.getResult(path);
expect(driver.test.numOfAnalyzedLibraries, 1);
expect(result2.path, path);
expect(result2.unit, same(unit1));
@@ -3540,13 +3568,11 @@
}
test_removeFile() async {
- var path = _p('/test.dart');
+ var path = convertPath('/test.dart');
expect(() {
driver.removeFile(path);
}, throwsStateError);
}
-
- String _p(String path) => provider.convertPath(path);
}
class _SourceMock implements Source {
diff --git a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
index aeb0e75..119f2b3 100644
--- a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
@@ -6,9 +6,9 @@
import 'dart:typed_data';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
+import 'package:analyzer/src/dart/analysis/library_graph.dart';
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/dart/analysis/top_level_declaration.dart';
import 'package:analyzer/src/file_system/file_system.dart';
@@ -16,13 +16,13 @@
show AnalysisOptions, AnalysisOptionsImpl;
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/source/package_map_resolver.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:convert/convert.dart';
import 'package:crypto/crypto.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../context/mock_sdk.dart';
-
main() {
defineReflectiveSuite(() {
defineReflectiveTests(FileSystemStateTest);
@@ -30,8 +30,7 @@
}
@reflectiveTest
-class FileSystemStateTest {
- final MemoryResourceProvider provider = new MemoryResourceProvider();
+class FileSystemStateTest with ResourceProviderMixin {
MockSdk sdk;
final ByteStore byteStore = new MemoryByteStore();
@@ -47,22 +46,22 @@
void setUp() {
logger = new PerformanceLog(logBuffer);
- sdk = new MockSdk(resourceProvider: provider);
+ sdk = new MockSdk(resourceProvider: resourceProvider);
sourceFactory = new SourceFactory([
new DartUriResolver(sdk),
generatedUriResolver,
- new PackageMapUriResolver(provider, <String, List<Folder>>{
- 'aaa': [provider.getFolder(_p('/aaa/lib'))],
- 'bbb': [provider.getFolder(_p('/bbb/lib'))],
+ new PackageMapUriResolver(resourceProvider, <String, List<Folder>>{
+ 'aaa': [getFolder('/aaa/lib')],
+ 'bbb': [getFolder('/bbb/lib')],
}),
- new ResourceUriResolver(provider)
- ], null, provider);
+ new ResourceUriResolver(resourceProvider)
+ ], null, resourceProvider);
AnalysisOptions analysisOptions = new AnalysisOptionsImpl();
fileSystemState = new FileSystemState(
logger,
byteStore,
contentOverlay,
- provider,
+ resourceProvider,
sourceFactory,
analysisOptions,
new Uint32List(0),
@@ -70,8 +69,8 @@
}
test_definedClassMemberNames() {
- String path = _p('/aaa/lib/a.dart');
- provider.newFile(path, r'''
+ String path = convertPath('/aaa/lib/a.dart');
+ newFile(path, content: r'''
class A {
int a, b;
A();
@@ -90,8 +89,8 @@
}
test_definedTopLevelNames() {
- String path = _p('/aaa/lib/a.dart');
- provider.newFile(path, r'''
+ String path = convertPath('/aaa/lib/a.dart');
+ newFile(path, content: r'''
class A {}
class B = Object with A;
typedef C();
@@ -106,18 +105,18 @@
}
test_exportedTopLevelDeclarations_cycle() {
- String a = _p('/aaa/lib/a.dart');
- String b = _p('/aaa/lib/b.dart');
- String c = _p('/aaa/lib/c.dart');
- provider.newFile(a, r'''
+ String a = convertPath('/aaa/lib/a.dart');
+ String b = convertPath('/aaa/lib/b.dart');
+ String c = convertPath('/aaa/lib/c.dart');
+ newFile(a, content: r'''
export 'b.dart';
class A {}
''');
- provider.newFile(b, r'''
+ newFile(b, content: r'''
export 'c.dart';
class B {}
''');
- provider.newFile(c, r'''
+ newFile(c, content: r'''
export 'a.dart';
class C {}
''');
@@ -130,24 +129,24 @@
}
test_exportedTopLevelDeclarations_cycle_anotherOutsideCycle() {
- String a = _p('/aaa/lib/a.dart');
- String b = _p('/aaa/lib/b.dart');
- String c = _p('/aaa/lib/c.dart');
- String d = _p('/aaa/lib/d.dart');
- provider.newFile(a, r'''
+ String a = convertPath('/aaa/lib/a.dart');
+ String b = convertPath('/aaa/lib/b.dart');
+ String c = convertPath('/aaa/lib/c.dart');
+ String d = convertPath('/aaa/lib/d.dart');
+ newFile(a, content: r'''
export 'b.dart';
class A {}
''');
- provider.newFile(b, r'''
+ newFile(b, content: r'''
export 'c.dart';
class B {}
''');
- provider.newFile(c, r'''
+ newFile(c, content: r'''
export 'b.dart';
export 'd.dart';
class C {}
''');
- provider.newFile(d, r'''
+ newFile(d, content: r'''
class D {}
''');
_assertExportedTopLevelDeclarations(a, ['A', 'B', 'C', 'D']);
@@ -159,28 +158,28 @@
}
test_exportedTopLevelDeclarations_cycle_onSequence() {
- String a = _p('/aaa/lib/a.dart');
- String b = _p('/aaa/lib/b.dart');
- String c = _p('/aaa/lib/c.dart');
- String d = _p('/aaa/lib/d.dart');
- String e = _p('/aaa/lib/e.dart');
- provider.newFile(a, r'''
+ String a = convertPath('/aaa/lib/a.dart');
+ String b = convertPath('/aaa/lib/b.dart');
+ String c = convertPath('/aaa/lib/c.dart');
+ String d = convertPath('/aaa/lib/d.dart');
+ String e = convertPath('/aaa/lib/e.dart');
+ newFile(a, content: r'''
export 'b.dart';
class A {}
''');
- provider.newFile(b, r'''
+ newFile(b, content: r'''
export 'c.dart';
class B {}
''');
- provider.newFile(c, r'''
+ newFile(c, content: r'''
export 'd.dart';
class C {}
''');
- provider.newFile(d, r'''
+ newFile(d, content: r'''
export 'e.dart';
class D {}
''');
- provider.newFile(e, r'''
+ newFile(e, content: r'''
export 'c.dart';
class E {}
''');
@@ -197,12 +196,12 @@
}
test_exportedTopLevelDeclarations_export() {
- String a = _p('/aaa/lib/a.dart');
- String b = _p('/aaa/lib/b.dart');
- provider.newFile(a, r'''
+ String a = convertPath('/aaa/lib/a.dart');
+ String b = convertPath('/aaa/lib/b.dart');
+ newFile(a, content: r'''
class A {}
''');
- provider.newFile(b, r'''
+ newFile(b, content: r'''
export 'a.dart';
class B {}
''');
@@ -211,20 +210,20 @@
}
test_exportedTopLevelDeclarations_export2_show() {
- String a = _p('/aaa/lib/a.dart');
- String b = _p('/aaa/lib/b.dart');
- String c = _p('/aaa/lib/c.dart');
- provider.newFile(a, r'''
+ String a = convertPath('/aaa/lib/a.dart');
+ String b = convertPath('/aaa/lib/b.dart');
+ String c = convertPath('/aaa/lib/c.dart');
+ newFile(a, content: r'''
class A1 {}
class A2 {}
class A3 {}
''');
- provider.newFile(b, r'''
+ newFile(b, content: r'''
export 'a.dart' show A1, A2;
class B1 {}
class B2 {}
''');
- provider.newFile(c, r'''
+ newFile(c, content: r'''
export 'b.dart' show A2, A3, B1;
class C {}
''');
@@ -233,12 +232,12 @@
}
test_exportedTopLevelDeclarations_export_flushOnChange() {
- String a = _p('/aaa/lib/a.dart');
- String b = _p('/aaa/lib/b.dart');
- provider.newFile(a, r'''
+ String a = convertPath('/aaa/lib/a.dart');
+ String b = convertPath('/aaa/lib/b.dart');
+ newFile(a, content: r'''
class A {}
''');
- provider.newFile(b, r'''
+ newFile(b, content: r'''
export 'a.dart';
class B {}
''');
@@ -247,20 +246,20 @@
_assertExportedTopLevelDeclarations(b, ['A', 'B']);
// Update a.dart, so a.dart and b.dart exported declarations are flushed.
- provider.newFile(a, 'class A {} class A2 {}');
+ newFile(a, content: 'class A {} class A2 {}');
fileSystemState.getFileForPath(a).refresh();
_assertExportedTopLevelDeclarations(b, ['A', 'A2', 'B']);
}
test_exportedTopLevelDeclarations_export_hide() {
- String a = _p('/aaa/lib/a.dart');
- String b = _p('/aaa/lib/b.dart');
- provider.newFile(a, r'''
+ String a = convertPath('/aaa/lib/a.dart');
+ String b = convertPath('/aaa/lib/b.dart');
+ newFile(a, content: r'''
class A1 {}
class A2 {}
class A3 {}
''');
- provider.newFile(b, r'''
+ newFile(b, content: r'''
export 'a.dart' hide A2;
class B {}
''');
@@ -268,12 +267,12 @@
}
test_exportedTopLevelDeclarations_export_preferLocal() {
- String a = _p('/aaa/lib/a.dart');
- String b = _p('/aaa/lib/b.dart');
- provider.newFile(a, r'''
+ String a = convertPath('/aaa/lib/a.dart');
+ String b = convertPath('/aaa/lib/b.dart');
+ newFile(a, content: r'''
class V {}
''');
- provider.newFile(b, r'''
+ newFile(b, content: r'''
export 'a.dart';
int V;
''');
@@ -285,13 +284,13 @@
}
test_exportedTopLevelDeclarations_export_show() {
- String a = _p('/aaa/lib/a.dart');
- String b = _p('/aaa/lib/b.dart');
- provider.newFile(a, r'''
+ String a = convertPath('/aaa/lib/a.dart');
+ String b = convertPath('/aaa/lib/b.dart');
+ newFile(a, content: r'''
class A1 {}
class A2 {}
''');
- provider.newFile(b, r'''
+ newFile(b, content: r'''
export 'a.dart' show A2;
class B {}
''');
@@ -299,21 +298,21 @@
}
test_exportedTopLevelDeclarations_export_show2() {
- String a = _p('/aaa/lib/a.dart');
- String b = _p('/aaa/lib/b.dart');
- String c = _p('/aaa/lib/c.dart');
- String d = _p('/aaa/lib/d.dart');
- provider.newFile(a, r'''
+ String a = convertPath('/aaa/lib/a.dart');
+ String b = convertPath('/aaa/lib/b.dart');
+ String c = convertPath('/aaa/lib/c.dart');
+ String d = convertPath('/aaa/lib/d.dart');
+ newFile(a, content: r'''
export 'b.dart' show Foo;
export 'c.dart' show Bar;
''');
- provider.newFile(b, r'''
+ newFile(b, content: r'''
export 'd.dart';
''');
- provider.newFile(c, r'''
+ newFile(c, content: r'''
export 'd.dart';
''');
- provider.newFile(d, r'''
+ newFile(d, content: r'''
class Foo {}
class Bar {}
''');
@@ -321,12 +320,12 @@
}
test_exportedTopLevelDeclarations_import() {
- String a = _p('/aaa/lib/a.dart');
- String b = _p('/aaa/lib/b.dart');
- provider.newFile(a, r'''
+ String a = convertPath('/aaa/lib/a.dart');
+ String b = convertPath('/aaa/lib/b.dart');
+ newFile(a, content: r'''
class A {}
''');
- provider.newFile(b, r'''
+ newFile(b, content: r'''
import 'a.dart';
class B {}
''');
@@ -334,14 +333,14 @@
}
test_exportedTopLevelDeclarations_parts() {
- String a = _p('/aaa/lib/a.dart');
- String a2 = _p('/aaa/lib/a2.dart');
- provider.newFile(a, r'''
+ String a = convertPath('/aaa/lib/a.dart');
+ String a2 = convertPath('/aaa/lib/a2.dart');
+ newFile(a, content: r'''
library lib;
part 'a2.dart';
class A1 {}
''');
- provider.newFile(a2, r'''
+ newFile(a2, content: r'''
part of lib;
class A2 {}
''');
@@ -349,7 +348,7 @@
}
test_getFileForPath_doesNotExist() {
- String path = _p('/aaa/lib/a.dart');
+ String path = convertPath('/aaa/lib/a.dart');
FileState file = fileSystemState.getFileForPath(path);
expect(file.path, path);
expect(file.uri, Uri.parse('package:aaa/a.dart'));
@@ -367,8 +366,8 @@
}
test_getFileForPath_emptyUri() {
- String path = _p('/test.dart');
- provider.newFile(path, r'''
+ String path = convertPath('/test.dart');
+ newFile(path, content: r'''
import '';
export '';
part '';
@@ -381,8 +380,8 @@
}
test_getFileForPath_hasLibraryDirective_hasPartOfDirective() {
- String a = _p('/test/lib/a.dart');
- provider.newFile(a, r'''
+ String a = convertPath('/test/lib/a.dart');
+ newFile(a, content: r'''
library L;
part of L;
''');
@@ -391,10 +390,10 @@
}
test_getFileForPath_invalidUri() {
- String a = _p('/aaa/lib/a.dart');
- String a1 = _p('/aaa/lib/a1.dart');
- String a2 = _p('/aaa/lib/a2.dart');
- String a3 = _p('/aaa/lib/a3.dart');
+ String a = convertPath('/aaa/lib/a.dart');
+ String a1 = convertPath('/aaa/lib/a1.dart');
+ String a2 = convertPath('/aaa/lib/a2.dart');
+ String a3 = convertPath('/aaa/lib/a3.dart');
String content_a1 = r'''
import 'package:aaa/a1.dart';
import ':[invalid uri]';
@@ -405,7 +404,7 @@
part 'a3.dart';
part ':[invalid uri]';
''';
- provider.newFile(a, content_a1);
+ newFile(a, content: content_a1);
FileState file = fileSystemState.getFileForPath(a);
@@ -429,12 +428,12 @@
}
test_getFileForPath_library() {
- String a1 = _p('/aaa/lib/a1.dart');
- String a2 = _p('/aaa/lib/a2.dart');
- String a3 = _p('/aaa/lib/a3.dart');
- String a4 = _p('/aaa/lib/a4.dart');
- String b1 = _p('/bbb/lib/b1.dart');
- String b2 = _p('/bbb/lib/b2.dart');
+ String a1 = convertPath('/aaa/lib/a1.dart');
+ String a2 = convertPath('/aaa/lib/a2.dart');
+ String a3 = convertPath('/aaa/lib/a3.dart');
+ String a4 = convertPath('/aaa/lib/a4.dart');
+ String b1 = convertPath('/bbb/lib/b1.dart');
+ String b2 = convertPath('/bbb/lib/b2.dart');
String content_a1 = r'''
import 'package:aaa/a2.dart';
import 'package:bbb/b1.dart';
@@ -444,7 +443,7 @@
class A1 {}
''';
- provider.newFile(a1, content_a1);
+ newFile(a1, content: content_a1);
FileState file = fileSystemState.getFileForPath(a1);
expect(file.path, a1);
@@ -485,12 +484,12 @@
}
test_getFileForPath_onlyDartFiles() {
- String not_dart = _p('/test/lib/not_dart.txt');
- String a = _p('/test/lib/a.dart');
- String b = _p('/test/lib/b.dart');
- String c = _p('/test/lib/c.dart');
- String d = _p('/test/lib/d.dart');
- provider.newFile(a, r'''
+ String not_dart = convertPath('/test/lib/not_dart.txt');
+ String a = convertPath('/test/lib/a.dart');
+ String b = convertPath('/test/lib/b.dart');
+ String c = convertPath('/test/lib/c.dart');
+ String d = convertPath('/test/lib/d.dart');
+ newFile(a, content: r'''
library lib;
import 'dart:math';
import 'b.dart';
@@ -511,13 +510,13 @@
}
test_getFileForPath_part() {
- String a1 = _p('/aaa/lib/a1.dart');
- String a2 = _p('/aaa/lib/a2.dart');
- provider.newFile(a1, r'''
+ String a1 = convertPath('/aaa/lib/a1.dart');
+ String a2 = convertPath('/aaa/lib/a2.dart');
+ newFile(a1, content: r'''
library a1;
part 'a2.dart';
''');
- provider.newFile(a2, r'''
+ newFile(a2, content: r'''
part of a1;
class A2 {}
''');
@@ -552,7 +551,7 @@
// Now update the library, and refresh its file.
// The 'a2.dart' is not referenced anymore.
// So the part file does not have the library anymore.
- provider.newFile(a1, r'''
+ newFile(a1, content: r'''
library a1;
part 'not-a2.dart';
''');
@@ -561,7 +560,7 @@
}
test_getFileForPath_samePath() {
- String path = _p('/aaa/lib/a.dart');
+ String path = convertPath('/aaa/lib/a.dart');
FileState file1 = fileSystemState.getFileForPath(path);
FileState file2 = fileSystemState.getFileForPath(path);
expect(file2, same(file1));
@@ -577,9 +576,9 @@
}
test_getFileForUri_packageVsFileUri() {
- String path = _p('/aaa/lib/a.dart');
+ String path = convertPath('/aaa/lib/a.dart');
var packageUri = Uri.parse('package:aaa/a.dart');
- var fileUri = provider.pathContext.toUri(path);
+ var fileUri = toUri(path);
// The files with `package:` and `file:` URIs are different.
FileState filePackageUri = fileSystemState.getFileForUri(packageUri);
@@ -598,14 +597,14 @@
}
test_getFilesSubtypingName() {
- String a = _p('/a.dart');
- String b = _p('/b.dart');
+ String a = convertPath('/a.dart');
+ String b = convertPath('/b.dart');
- provider.newFile(a, r'''
+ newFile(a, content: r'''
class A {}
class B extends A {}
''');
- provider.newFile(b, r'''
+ newFile(b, content: r'''
class A {}
class D implements A {}
''');
@@ -619,7 +618,7 @@
);
// Change b.dart so that it does not subtype A.
- provider.newFile(b, r'''
+ newFile(b, content: r'''
class C {}
class D implements C {}
''');
@@ -636,8 +635,8 @@
test_hasUri() {
Uri uri = Uri.parse('package:aaa/foo.dart');
- String templatePath = _p('/aaa/lib/foo.dart');
- String generatedPath = _p('/generated/aaa/lib/foo.dart');
+ String templatePath = convertPath('/aaa/lib/foo.dart');
+ String generatedPath = convertPath('/generated/aaa/lib/foo.dart');
Source generatedSource = new _SourceMock(generatedPath, uri);
@@ -648,9 +647,87 @@
expect(fileSystemState.hasUri(generatedPath), isTrue);
}
+ test_libraryCycle() {
+ String pa = convertPath('/aaa/lib/a.dart');
+ String pb = convertPath('/aaa/lib/b.dart');
+ String pc = convertPath('/aaa/lib/c.dart');
+ String pd = convertPath('/aaa/lib/d.dart');
+
+ FileState fa = fileSystemState.getFileForPath(pa);
+ FileState fb = fileSystemState.getFileForPath(pb);
+ FileState fc = fileSystemState.getFileForPath(pc);
+ FileState fd = fileSystemState.getFileForPath(pd);
+
+ // Compute library cycles for all files.
+ fa.libraryCycle;
+ fb.libraryCycle;
+ fc.libraryCycle;
+ fd.libraryCycle;
+ _assertFilesWithoutLibraryCycle([]);
+
+ // No imports, so just a single file.
+ newFile(pa);
+ _assertLibraryCycle(fa, [fa], []);
+
+ // Import b.dart into a.dart, two files now.
+ newFile(pa, content: "import 'b.dart';");
+ fa.refresh();
+ _assertFilesWithoutLibraryCycle([fa]);
+ _assertLibraryCycle(fa, [fa], [fb.libraryCycle]);
+
+ // Update b.dart so that it imports c.dart now.
+ newFile(pb, content: "import 'c.dart';");
+ fb.refresh();
+ _assertFilesWithoutLibraryCycle([fa, fb]);
+ _assertLibraryCycle(fa, [fa], [fb.libraryCycle]);
+ _assertLibraryCycle(fb, [fb], [fc.libraryCycle]);
+ _assertFilesWithoutLibraryCycle([]);
+
+ // Update b.dart so that it exports d.dart instead.
+ newFile(pb, content: "export 'd.dart';");
+ fb.refresh();
+ _assertFilesWithoutLibraryCycle([fa, fb]);
+ _assertLibraryCycle(fa, [fa], [fb.libraryCycle]);
+ _assertLibraryCycle(fb, [fb], [fd.libraryCycle]);
+ _assertFilesWithoutLibraryCycle([]);
+
+ // Update a.dart so that it does not import b.dart anymore.
+ newFile(pa);
+ fa.refresh();
+ _assertFilesWithoutLibraryCycle([fa]);
+ _assertLibraryCycle(fa, [fa], []);
+ }
+
+ test_libraryCycle_cycle() {
+ String pa = convertPath('/aaa/lib/a.dart');
+ String pb = convertPath('/aaa/lib/b.dart');
+
+ newFile(pa, content: "import 'b.dart';");
+ newFile(pb, content: "import 'a.dart';");
+
+ FileState fa = fileSystemState.getFileForPath(pa);
+ FileState fb = fileSystemState.getFileForPath(pb);
+
+ // Compute library cycles for all files.
+ fa.libraryCycle;
+ fb.libraryCycle;
+ _assertFilesWithoutLibraryCycle([]);
+
+ // It's a cycle.
+ _assertLibraryCycle(fa, [fa, fb], []);
+ _assertLibraryCycle(fb, [fa, fb], []);
+
+ // Update a.dart so that it does not import b.dart anymore.
+ newFile(pa);
+ fa.refresh();
+ _assertFilesWithoutLibraryCycle([fa, fb]);
+ _assertLibraryCycle(fa, [fa], []);
+ _assertLibraryCycle(fb, [fb], [fa.libraryCycle]);
+ }
+
test_referencedNames() {
- String path = _p('/aaa/lib/a.dart');
- provider.newFile(path, r'''
+ String path = convertPath('/aaa/lib/a.dart');
+ newFile(path, content: r'''
A foo(B p) {
foo(null);
C c = new C(p);
@@ -662,8 +739,8 @@
}
test_refresh_differentApiSignature() {
- String path = _p('/aaa/lib/a.dart');
- provider.newFile(path, r'''
+ String path = convertPath('/aaa/lib/a.dart');
+ newFile(path, content: r'''
class A {}
''');
FileState file = fileSystemState.getFileForPath(path);
@@ -671,7 +748,7 @@
List<int> signature = file.apiSignature;
// Update the resource and refresh the file state.
- provider.newFile(path, r'''
+ newFile(path, content: r'''
class B {}
''');
bool apiSignatureChanged = file.refresh();
@@ -682,8 +759,8 @@
}
test_refresh_sameApiSignature() {
- String path = _p('/aaa/lib/a.dart');
- provider.newFile(path, r'''
+ String path = convertPath('/aaa/lib/a.dart');
+ newFile(path, content: r'''
class C {
foo() {
print(111);
@@ -694,7 +771,7 @@
List<int> signature = file.apiSignature;
// Update the resource and refresh the file state.
- provider.newFile(path, r'''
+ newFile(path, content: r'''
class C {
foo() {
print(222);
@@ -708,8 +785,8 @@
}
test_store_zeroLengthUnlinked() {
- String path = _p('/test.dart');
- provider.newFile(path, 'class A {}');
+ String path = convertPath('/test.dart');
+ newFile(path, content: 'class A {}');
// Get the file, prepare unlinked.
FileState file = fileSystemState.getFileForPath(path);
@@ -724,8 +801,8 @@
}
test_subtypedNames() {
- String path = _p('/test.dart');
- provider.newFile(path, r'''
+ String path = convertPath('/test.dart');
+ newFile(path, content: r'''
class X extends A {}
class Y extends A with B {}
class Z implements C, D {}
@@ -735,8 +812,8 @@
}
test_topLevelDeclarations() {
- String path = _p('/aaa/lib/a.dart');
- provider.newFile(path, r'''
+ String path = convertPath('/aaa/lib/a.dart');
+ newFile(path, content: r'''
class C {}
typedef F();
enum E {E1, E2}
@@ -775,95 +852,16 @@
assertHas('V4', TopLevelDeclarationKind.variable);
}
- test_transitiveFiles() {
- String pa = _p('/aaa/lib/a.dart');
- String pb = _p('/aaa/lib/b.dart');
- String pc = _p('/aaa/lib/c.dart');
- String pd = _p('/aaa/lib/d.dart');
-
- FileState fa = fileSystemState.getFileForPath(pa);
- FileState fb = fileSystemState.getFileForPath(pb);
- FileState fc = fileSystemState.getFileForPath(pc);
- FileState fd = fileSystemState.getFileForPath(pd);
-
- // Compute transitive closures for all files.
- fa.transitiveFiles;
- fb.transitiveFiles;
- fc.transitiveFiles;
- fd.transitiveFiles;
- expect(
- _excludeSdk(fileSystemState.test.filesWithoutTransitiveFiles), isEmpty);
-
- // No imports, so just a single file.
- provider.newFile(pa, "");
- _assertTransitiveFiles(fa, [fa]);
-
- // Import b.dart into a.dart, two files now.
- provider.newFile(pa, "import 'b.dart';");
- fa.refresh();
- _assertFilesWithoutTransitiveFiles([fa]);
- _assertTransitiveFiles(fa, [fa, fb]);
-
- // Update b.dart so that it imports c.dart now.
- provider.newFile(pb, "import 'c.dart';");
- fb.refresh();
- _assertFilesWithoutTransitiveFiles([fa, fb]);
- _assertTransitiveFiles(fa, [fa, fb, fc]);
- _assertTransitiveFiles(fb, [fb, fc]);
- _assertFilesWithoutTransitiveFiles([]);
-
- // Update b.dart so that it exports d.dart instead.
- provider.newFile(pb, "export 'd.dart';");
- fb.refresh();
- _assertFilesWithoutTransitiveFiles([fa, fb]);
- _assertTransitiveFiles(fa, [fa, fb, fd]);
- _assertTransitiveFiles(fb, [fb, fd]);
- _assertFilesWithoutTransitiveFiles([]);
-
- // Update a.dart so that it does not import b.dart anymore.
- provider.newFile(pa, "");
- fa.refresh();
- _assertFilesWithoutTransitiveFiles([fa]);
- _assertTransitiveFiles(fa, [fa]);
- }
-
- test_transitiveFiles_cycle() {
- String pa = _p('/aaa/lib/a.dart');
- String pb = _p('/aaa/lib/b.dart');
-
- provider.newFile(pa, "import 'b.dart';");
- provider.newFile(pb, "import 'a.dart';");
-
- FileState fa = fileSystemState.getFileForPath(pa);
- FileState fb = fileSystemState.getFileForPath(pb);
-
- // Compute transitive closures for all files.
- fa.transitiveFiles;
- fb.transitiveFiles;
- _assertFilesWithoutTransitiveFiles([]);
-
- // It's a cycle.
- _assertTransitiveFiles(fa, [fa, fb]);
- _assertTransitiveFiles(fb, [fa, fb]);
-
- // Update a.dart so that it does not import b.dart anymore.
- provider.newFile(pa, "");
- fa.refresh();
- _assertFilesWithoutTransitiveFiles([fa, fb]);
- _assertTransitiveFiles(fa, [fa]);
- _assertTransitiveFiles(fb, [fa, fb]);
- }
-
test_transitiveSignature() {
- String pa = _p('/aaa/lib/a.dart');
- String pb = _p('/aaa/lib/b.dart');
- String pc = _p('/aaa/lib/c.dart');
- String pd = _p('/aaa/lib/d.dart');
+ String pa = convertPath('/aaa/lib/a.dart');
+ String pb = convertPath('/aaa/lib/b.dart');
+ String pc = convertPath('/aaa/lib/c.dart');
+ String pd = convertPath('/aaa/lib/d.dart');
- provider.newFile(pa, "class A {}");
- provider.newFile(pb, "import 'a.dart';");
- provider.newFile(pc, "import 'b.dart';");
- provider.newFile(pd, "class D {}");
+ newFile(pa, content: "class A {}");
+ newFile(pb, content: "import 'a.dart';");
+ newFile(pc, content: "import 'b.dart';");
+ newFile(pd, content: "class D {}");
FileState fa = fileSystemState.getFileForPath(pa);
FileState fb = fileSystemState.getFileForPath(pb);
@@ -871,25 +869,24 @@
FileState fd = fileSystemState.getFileForPath(pd);
// Compute transitive closures for all files.
+ // This implicitly computes library cycles.
expect(fa.transitiveSignature, isNotNull);
expect(fb.transitiveSignature, isNotNull);
expect(fc.transitiveSignature, isNotNull);
expect(fd.transitiveSignature, isNotNull);
- expect(
- _excludeSdk(fileSystemState.test.filesWithoutTransitiveFiles), isEmpty);
+ _assertFilesWithoutLibraryCycle([]);
// Make an update to a.dart that does not change its API signature.
- // All transitive signatures are still valid.
- provider.newFile(pa, "class A {} // the same API signature");
+ // All library cycles are still valid.
+ newFile(pa, content: "class A {} // the same API signature");
fa.refresh();
- expect(
- _excludeSdk(fileSystemState.test.filesWithoutTransitiveFiles), isEmpty);
+ _assertFilesWithoutLibraryCycle([]);
- // Change a.dart API signature, also flush signatures of b.dart and c.dart,
- // but d.dart is still OK.
- provider.newFile(pa, "class A2 {}");
+ // Change a.dart API signature.
+ // This flushes signatures of b.dart and c.dart, but d.dart is still OK.
+ newFile(pa, content: "class A2 {}");
fa.refresh();
- _assertFilesWithoutTransitiveSignatures([fa, fb, fc]);
+ _assertFilesWithoutLibraryCycle([fa, fb, fc]);
}
void _assertExportedTopLevelDeclarations(String path, List<String> expected) {
@@ -899,13 +896,8 @@
expect(declarations.keys, unorderedEquals(expected));
}
- void _assertFilesWithoutTransitiveFiles(List<FileState> expected) {
- var actual = fileSystemState.test.filesWithoutTransitiveFiles;
- expect(_excludeSdk(actual), unorderedEquals(expected));
- }
-
- void _assertFilesWithoutTransitiveSignatures(List<FileState> expected) {
- var actual = fileSystemState.test.filesWithoutTransitiveSignature;
+ void _assertFilesWithoutLibraryCycle(List<FileState> expected) {
+ var actual = fileSystemState.test.filesWithoutLibraryCycle;
expect(_excludeSdk(actual), unorderedEquals(expected));
}
@@ -921,22 +913,30 @@
expect(file.source, isNull);
}
- void _assertTransitiveFiles(FileState file, List<FileState> expected) {
- expect(_excludeSdk(file.transitiveFiles), unorderedEquals(expected));
+ void _assertLibraryCycle(
+ FileState file,
+ List<FileState> expectedLibraries,
+ List<LibraryCycle> expectedDirectDependencies,
+ ) {
+ expect(file.libraryCycle.libraries, unorderedEquals(expectedLibraries));
+ expect(
+ _excludeSdk(file.libraryCycle.directDependencies),
+ unorderedEquals(expectedDirectDependencies),
+ );
}
List<T> _excludeSdk<T>(Iterable<T> files) {
return files.where((Object file) {
- if (file is FileState) {
+ if (file is LibraryCycle) {
+ return !file.libraries.any((file) => file.uri.isScheme('dart'));
+ } else if (file is FileState) {
return file.uri?.scheme != 'dart';
} else {
- return !(file as String).startsWith(_p('/sdk'));
+ return !(file as String).startsWith(convertPath('/sdk'));
}
}).toList();
}
- String _p(String path) => provider.convertPath(path);
-
static String _md5(String content) {
return hex.encode(md5.convert(utf8.encode(content)).bytes);
}
diff --git a/pkg/analyzer/test/src/dart/analysis/index_test.dart b/pkg/analyzer/test/src/dart/analysis/index_test.dart
index e3106d1..94fbd94 100644
--- a/pkg/analyzer/test/src/dart/analysis/index_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/index_test.dart
@@ -5,9 +5,9 @@
import 'dart:async';
import 'dart:convert';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/index.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
@@ -134,7 +134,7 @@
}
test_isExtendedBy_ClassDeclaration_isQualified() async {
- provider.newFile(_p('$testProject/lib.dart'), '''
+ newFile('$testProject/lib.dart', content: '''
class A {}
''');
await _indexTestUnit('''
@@ -167,7 +167,7 @@
}
test_isExtendedBy_ClassTypeAlias_isQualified() async {
- provider.newFile(_p('$testProject/lib.dart'), '''
+ newFile('$testProject/lib.dart', content: '''
class A {}
''');
await _indexTestUnit('''
@@ -193,7 +193,7 @@
}
test_isImplementedBy_ClassDeclaration_isQualified() async {
- provider.newFile(_p('$testProject/lib.dart'), '''
+ newFile('$testProject/lib.dart', content: '''
class A {}
''');
await _indexTestUnit('''
@@ -256,7 +256,7 @@
}
test_isInvokedBy_FunctionElement() async {
- provider.newFile(_p('$testProject/lib.dart'), '''
+ newFile('$testProject/lib.dart', content: '''
library lib;
foo() {}
''');
@@ -393,7 +393,7 @@
}
test_isMixedInBy_ClassDeclaration_isQualified() async {
- provider.newFile(_p('$testProject/lib.dart'), '''
+ newFile('$testProject/lib.dart', content: '''
class A {}
''');
await _indexTestUnit('''
@@ -465,7 +465,7 @@
}
test_isReferencedBy_ClassElement_invocation_isQualified() async {
- provider.newFile(_p('$testProject/lib.dart'), '''
+ newFile('$testProject/lib.dart', content: '''
class A {}
''');
await _indexTestUnit('''
@@ -504,7 +504,7 @@
}
test_isReferencedBy_CompilationUnitElement_export() async {
- provider.newFile(_p('$testProject/lib.dart'), '''
+ newFile('$testProject/lib.dart', content: '''
library lib;
''');
await _indexTestUnit('''
@@ -515,7 +515,7 @@
}
test_isReferencedBy_CompilationUnitElement_import() async {
- provider.newFile(_p('$testProject/lib.dart'), '''
+ newFile('$testProject/lib.dart', content: '''
library lib;
''');
await _indexTestUnit('''
@@ -526,7 +526,7 @@
}
test_isReferencedBy_CompilationUnitElement_part() async {
- provider.newFile(_p('$testProject/my_unit.dart'), 'part of my_lib;');
+ newFile('$testProject/my_unit.dart', content: 'part of my_lib;');
await _indexTestUnit('''
library my_lib;
part 'my_unit.dart';
@@ -536,8 +536,8 @@
}
test_isReferencedBy_CompilationUnitElement_part_inPart() async {
- provider.newFile(_p('$testProject/a.dart'), 'part of lib;');
- provider.newFile(_p('$testProject/b.dart'), '''
+ newFile('$testProject/a.dart', content: 'part of lib;');
+ newFile('$testProject/b.dart', content: '''
library lib;
part 'a.dart';
''');
@@ -803,7 +803,7 @@
}
test_isReferencedBy_FunctionElement_with_LibraryElement() async {
- provider.newFile(_p('$testProject/foo.dart'), r'''
+ newFile('$testProject/foo.dart', content: r'''
bar() {}
''');
await _indexTestUnit('''
@@ -863,8 +863,8 @@
}
test_isReferencedBy_MultiplyDefinedElement() async {
- provider.newFile(_p('$testProject/a1.dart'), 'class A {}');
- provider.newFile(_p('$testProject/a2.dart'), 'class A {}');
+ newFile('$testProject/a1.dart', content: 'class A {}');
+ newFile('$testProject/a2.dart', content: 'class A {}');
await _indexTestUnit('''
import 'a1.dart';
import 'a2.dart';
@@ -911,7 +911,7 @@
}
test_isReferencedBy_TopLevelVariableElement() async {
- provider.newFile(_p('$testProject/lib.dart'), '''
+ newFile('$testProject/lib.dart', content: '''
library lib;
var V;
''');
@@ -935,7 +935,7 @@
}
test_isReferencedBy_TopLevelVariableElement_synthetic_hasGetterSetter() async {
- provider.newFile(_p('$testProject/lib.dart'), '''
+ newFile('$testProject/lib.dart', content: '''
int get V => 0;
void set V(_) {}
''');
@@ -947,7 +947,7 @@
}
test_isReferencedBy_TopLevelVariableElement_synthetic_hasSetter() async {
- provider.newFile(_p('$testProject/lib.dart'), '''
+ newFile('$testProject/lib.dart', content: '''
void set V(_) {}
''');
await _indexTestUnit('''
@@ -982,7 +982,7 @@
test_subtypes_classDeclaration() async {
String libP = 'package:test/lib.dart;package:test/lib.dart';
- provider.newFile(_p('$testProject/lib.dart'), '''
+ newFile('$testProject/lib.dart', content: '''
class A {}
class B {}
class C {}
@@ -1032,7 +1032,7 @@
test_subtypes_classTypeAlias() async {
String libP = 'package:test/lib.dart;package:test/lib.dart';
- provider.newFile(_p('$testProject/lib.dart'), '''
+ newFile('$testProject/lib.dart', content: '''
class A {}
class B {}
class C {}
@@ -1070,7 +1070,7 @@
test_subtypes_mixinDeclaration() async {
String libP = 'package:test/lib.dart;package:test/lib.dart';
- provider.newFile(_p('$testProject/lib.dart'), '''
+ newFile('$testProject/lib.dart', content: '''
class A {}
class B {}
class C {}
@@ -1339,7 +1339,7 @@
Future<Null> _indexTestUnit(String code) async {
addTestFile(code);
- AnalysisResult result = await driver.getResult(testFile);
+ ResolvedUnitResult result = await driver.getResult(testFile);
testUnit = result.unit;
testUnitElement = testUnit.declaredElement;
testLibraryElement = testUnitElement.library;
@@ -1348,8 +1348,6 @@
List<int> indexBytes = indexBuilder.toBuffer();
index = new AnalysisDriverUnitIndex.fromBuffer(indexBytes);
}
-
- String _p(String path) => provider.convertPath(path);
}
class _ElementIndexAssert {
diff --git a/pkg/analyzer/test/src/dart/analysis/search_test.dart b/pkg/analyzer/test/src/dart/analysis/search_test.dart
index ad2bc6e..2d67389 100644
--- a/pkg/analyzer/test/src/dart/analysis/search_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/search_test.dart
@@ -5,10 +5,10 @@
import 'dart:async';
import 'dart:collection';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart' hide Declaration;
import 'package:analyzer/dart/ast/standard_resolution_map.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/search.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/dart/element/member.dart';
@@ -149,15 +149,15 @@
}
test_declarations_discover() async {
- var t = _p('/test/lib/t.dart');
- var a = _p('/aaa/lib/a.dart');
- var b = _p('/bbb/lib/b.dart');
- var c = _p('/ccc/lib/c.dart');
+ var t = convertPath('/test/lib/t.dart');
+ var a = convertPath('/aaa/lib/a.dart');
+ var b = convertPath('/bbb/lib/b.dart');
+ var c = convertPath('/ccc/lib/c.dart');
- provider.newFile(t, 'class T {}');
- provider.newFile(a, 'class A {}');
- provider.newFile(b, 'class B {}');
- provider.newFile(c, 'class C {}');
+ newFile(t, content: 'class T {}');
+ newFile(a, content: 'class A {}');
+ newFile(b, content: 'class B {}');
+ newFile(c, content: 'class C {}');
driver.addFile(t);
@@ -170,11 +170,11 @@
}
test_declarations_duplicateFile() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
- provider.newFile(a, 'class A {}');
- provider.newFile(b, 'class B {}');
+ newFile(a, content: 'class A {}');
+ newFile(b, content: 'class B {}');
driver.addFile(a);
driver.addFile(b);
@@ -243,10 +243,10 @@
}
test_declarations_onlyForFile() async {
- var a = _p('/test/lib/a.dart');
- var b = _p('/test/lib/b.dart');
- provider.newFile(a, 'class A {}');
- provider.newFile(b, 'class B {}');
+ var a = convertPath('/test/lib/a.dart');
+ var b = convertPath('/test/lib/b.dart');
+ newFile(a, content: 'class A {}');
+ newFile(b, content: 'class B {}');
driver.addFile(a);
driver.addFile(b);
@@ -423,15 +423,15 @@
}
test_references_discover() async {
- var t = _p('/test/lib/t.dart');
- var a = _p('/aaa/lib/a.dart');
- var b = _p('/bbb/lib/b.dart');
- var c = _p('/ccc/lib/c.dart');
+ var t = convertPath('/test/lib/t.dart');
+ var a = convertPath('/aaa/lib/a.dart');
+ var b = convertPath('/bbb/lib/b.dart');
+ var c = convertPath('/ccc/lib/c.dart');
- provider.newFile(t, 'List t;');
- provider.newFile(a, 'List a;');
- provider.newFile(b, 'List b;');
- provider.newFile(c, 'List c;');
+ newFile(t, content: 'List t;');
+ newFile(a, content: 'List a;');
+ newFile(b, content: 'List b;');
+ newFile(c, content: 'List c;');
driver.addFile(t);
@@ -456,13 +456,13 @@
}
test_references_discover_onlyOwned() async {
- var t = _p('/test/lib/t.dart');
- var a = _p('/aaa/lib/a.dart');
- var b = _p('/bbb/lib/b.dart');
+ var t = convertPath('/test/lib/t.dart');
+ var a = convertPath('/aaa/lib/a.dart');
+ var b = convertPath('/bbb/lib/b.dart');
- provider.newFile(t, 'List t;');
- provider.newFile(a, 'List a;');
- provider.newFile(b, 'List b;');
+ newFile(t, content: 'List t;');
+ newFile(a, content: 'List a;');
+ newFile(b, content: 'List b;');
driver.addFile(t);
driver.addFile(a);
@@ -492,11 +492,11 @@
}
test_references_discover_onlyOwned_samePath() async {
- var p = _p('/test/lib/t.dart');
- provider.newFile(p, 'int t;');
+ var p = convertPath('/test/lib/t.dart');
+ newFile(p, content: 'int t;');
var driver1 = createAnalysisDriver(packageMap: {
- 'test': [provider.newFolder(_p('/test/lib'))]
+ 'test': [newFolder('/test/lib')]
});
var driver2 = createAnalysisDriver(packageMap: {});
@@ -512,17 +512,17 @@
}
test_references_discover_onlyOwned_sameUri() async {
- var a = _p('/aaa/lib/t.dart');
- var b = _p('/bbb/lib/t.dart');
+ var a = convertPath('/aaa/lib/t.dart');
+ var b = convertPath('/bbb/lib/t.dart');
- provider.newFile(a, 'int t;');
- provider.newFile(b, 'double t;');
+ newFile(a, content: 'int t;');
+ newFile(b, content: 'double t;');
var driver1 = createAnalysisDriver(packageMap: {
- 'ttt': [provider.newFolder(_p('/aaa/lib'))]
+ 'ttt': [newFolder('/aaa/lib')]
});
var driver2 = createAnalysisDriver(packageMap: {
- 'ttt': [provider.newFolder(_p('/bbb/lib'))]
+ 'ttt': [newFolder('/bbb/lib')]
});
// driver1 owns `/aaa/lib/t.dart` with `package:ttt/t.dart`.
@@ -620,7 +620,7 @@
ClassElement randomElement;
{
String randomPath = sdk.mapDartUri('dart:math').fullName;
- AnalysisResult result = await driver.getResult(randomPath);
+ ResolvedUnitResult result = await driver.getResult(randomPath);
randomElement = result.unit.declaredElement.getType('Random');
}
@@ -680,7 +680,7 @@
}
test_searchReferences_ClassElement_definedOutside() async {
- provider.newFile(_p('$testProject/lib.dart'), r'''
+ newFile('$testProject/lib.dart', content: r'''
class A {};
''');
await _resolveTestUnit('''
@@ -713,7 +713,7 @@
}
test_searchReferences_CompilationUnitElement() async {
- provider.newFile(_p('$testProject/foo.dart'), '');
+ newFile('$testProject/foo.dart');
await _resolveTestUnit('''
import 'foo.dart'; // import
export 'foo.dart'; // export
@@ -750,14 +750,14 @@
}
test_searchReferences_ConstructorElement_default_otherFile() async {
- String other = _p('$testProject/other.dart');
+ String other = convertPath('$testProject/other.dart');
String otherCode = '''
import 'test.dart';
main() {
new A(); // in other
}
''';
- provider.newFile(other, otherCode);
+ newFile(other, content: otherCode);
driver.addFile(other);
await _resolveTestUnit('''
@@ -962,7 +962,7 @@
}
test_searchReferences_ImportElement_noPrefix_inPackage() async {
- testFile = _p('/aaa/lib/a.dart');
+ testFile = convertPath('/aaa/lib/a.dart');
await _resolveTestUnit('''
import 'dart:math' show max, PI, Random hide min;
export 'dart:math' show max, PI, Random hide min;
@@ -1063,8 +1063,8 @@
test_searchReferences_LibraryElement() async {
var codeA = 'part of lib; // A';
var codeB = 'part of lib; // B';
- provider.newFile(_p('$testProject/unitA.dart'), codeA);
- provider.newFile(_p('$testProject/unitB.dart'), codeB);
+ newFile('$testProject/unitA.dart', content: codeA);
+ newFile('$testProject/unitB.dart', content: codeB);
await _resolveTestUnit('''
library lib;
part 'unitA.dart';
@@ -1083,14 +1083,14 @@
}
test_searchReferences_LibraryElement_inPackage() async {
- testFile = _p('/aaa/lib/a.dart');
- var partPathA = _p('/aaa/lib/unitA.dart');
- var partPathB = _p('/aaa/lib/unitB.dart');
+ testFile = convertPath('/aaa/lib/a.dart');
+ var partPathA = convertPath('/aaa/lib/unitA.dart');
+ var partPathB = convertPath('/aaa/lib/unitB.dart');
var codeA = 'part of lib; // A';
var codeB = 'part of lib; // B';
- provider.newFile(partPathA, codeA);
- provider.newFile(partPathB, codeB);
+ newFile(partPathA, content: codeA);
+ newFile(partPathB, content: codeB);
await _resolveTestUnit('''
library lib;
part 'unitA.dart';
@@ -1152,7 +1152,7 @@
}
test_searchReferences_LocalVariableElement_inPackage() async {
- testFile = _p('/aaa/lib/a.dart');
+ testFile = convertPath('/aaa/lib/a.dart');
await _resolveTestUnit('''
main() {
@@ -1370,7 +1370,7 @@
part of my_lib;
ppp.Future c;
''';
- provider.newFile(_p('$testProject/my_part.dart'), partCode);
+ newFile('$testProject/my_part.dart', content: partCode);
await _resolveTestUnit('''
library my_lib;
import 'dart:async' as ppp;
@@ -1393,14 +1393,14 @@
}
test_searchReferences_PrefixElement_inPackage() async {
- testFile = _p('/aaa/lib/a.dart');
- var partPath = _p('/aaa/lib/my_part.dart');
+ testFile = convertPath('/aaa/lib/a.dart');
+ var partPath = convertPath('/aaa/lib/my_part.dart');
String partCode = r'''
part of my_lib;
ppp.Future c;
''';
- provider.newFile(partPath, partCode);
+ newFile(partPath, content: partCode);
await _resolveTestUnit('''
library my_lib;
import 'dart:async' as ppp;
@@ -1423,14 +1423,14 @@
}
test_searchReferences_private_declaredInDefiningUnit() async {
- String p1 = _p('$testProject/part1.dart');
- String p2 = _p('$testProject/part2.dart');
- String p3 = _p('$testProject/part3.dart');
+ String p1 = convertPath('$testProject/part1.dart');
+ String p2 = convertPath('$testProject/part2.dart');
+ String p3 = convertPath('$testProject/part3.dart');
String code1 = 'part of lib; _C v1;';
String code2 = 'part of lib; _C v2;';
- provider.newFile(p1, code1);
- provider.newFile(p2, code2);
- provider.newFile(p3, 'part of lib; int v3;');
+ newFile(p1, content: code1);
+ newFile(p2, content: code2);
+ newFile(p3, content: 'part of lib; int v3;');
driver.addFile(p1);
driver.addFile(p2);
@@ -1459,9 +1459,9 @@
}
test_searchReferences_private_declaredInPart() async {
- String p = _p('$testProject/lib.dart');
- String p1 = _p('$testProject/part1.dart');
- String p2 = _p('$testProject/part2.dart');
+ String p = convertPath('$testProject/lib.dart');
+ String p1 = convertPath('$testProject/part1.dart');
+ String p2 = convertPath('$testProject/part2.dart');
var code = '''
library lib;
@@ -1476,15 +1476,15 @@
''';
String code2 = 'part of lib; _C v2;';
- provider.newFile(p, code);
- provider.newFile(p1, code1);
- provider.newFile(p2, code2);
+ newFile(p, content: code);
+ newFile(p1, content: code1);
+ newFile(p2, content: code2);
driver.addFile(p);
driver.addFile(p1);
driver.addFile(p2);
- AnalysisResult result = await driver.getResult(p);
+ ResolvedUnitResult result = await driver.getResult(p);
testUnit = result.unit;
testUnitElement = testUnit.declaredElement;
testLibraryElement = testUnitElement.library;
@@ -1505,15 +1505,15 @@
}
test_searchReferences_private_inPackage() async {
- testFile = _p('/aaa/lib/a.dart');
- var p1 = _p('/aaa/lib/part1.dart');
- var p2 = _p('/aaa/lib/part2.dart');
+ testFile = convertPath('/aaa/lib/a.dart');
+ var p1 = convertPath('/aaa/lib/part1.dart');
+ var p2 = convertPath('/aaa/lib/part2.dart');
String code1 = 'part of lib; _C v1;';
String code2 = 'part of lib; _C v2;';
- provider.newFile(p1, code1);
- provider.newFile(p2, code2);
+ newFile(p1, content: code1);
+ newFile(p2, content: code2);
await _resolveTestUnit('''
library lib;
@@ -1581,7 +1581,7 @@
}
test_searchReferences_TopLevelVariableElement() async {
- provider.newFile(_p('$testProject/lib.dart'), '''
+ newFile('$testProject/lib.dart', content: '''
library lib;
var V;
''');
@@ -1768,15 +1768,15 @@
}
test_subtypes_discover() async {
- var pathT = _p('/test/lib/t.dart');
- var pathA = _p('/aaa/lib/a.dart');
- var pathB = _p('/bbb/lib/b.dart');
+ var pathT = convertPath('/test/lib/t.dart');
+ var pathA = convertPath('/aaa/lib/a.dart');
+ var pathB = convertPath('/bbb/lib/b.dart');
var tUri = 'package:test/t.dart';
var aUri = 'package:aaa/a.dart';
var bUri = 'package:bbb/b.dart';
- provider.newFile(pathT, r'''
+ newFile(pathT, content: r'''
import 'package:aaa/a.dart';
class T1 extends A {
@@ -1788,7 +1788,7 @@
}
''');
- provider.newFile(pathB, r'''
+ newFile(pathB, content: r'''
import 'package:aaa/a.dart';
class B extends A {
@@ -1796,7 +1796,7 @@
}
''');
- provider.newFile(pathA, r'''
+ newFile(pathA, content: r'''
class A {
void method1() {}
void method2() {}
@@ -1830,15 +1830,15 @@
}
test_subTypes_discover() async {
- var t = _p('/test/lib/t.dart');
- var a = _p('/aaa/lib/a.dart');
- var b = _p('/bbb/lib/b.dart');
- var c = _p('/ccc/lib/c.dart');
+ var t = convertPath('/test/lib/t.dart');
+ var a = convertPath('/aaa/lib/a.dart');
+ var b = convertPath('/bbb/lib/b.dart');
+ var c = convertPath('/ccc/lib/c.dart');
- provider.newFile(t, 'class T implements List {}');
- provider.newFile(a, 'class A implements List {}');
- provider.newFile(b, 'class B implements List {}');
- provider.newFile(c, 'class C implements List {}');
+ newFile(t, content: 'class T implements List {}');
+ newFile(a, content: 'class A implements List {}');
+ newFile(b, content: 'class B implements List {}');
+ newFile(c, content: 'class C implements List {}');
driver.addFile(t);
@@ -1863,13 +1863,13 @@
}
test_subtypes_files() async {
- String pathB = _p('$testProject/b.dart');
- String pathC = _p('$testProject/c.dart');
- provider.newFile(pathB, r'''
+ String pathB = convertPath('$testProject/b.dart');
+ String pathC = convertPath('$testProject/c.dart');
+ newFile(pathB, content: r'''
import 'test.dart';
class B extends A {}
''');
- provider.newFile(pathC, r'''
+ newFile(pathC, content: r'''
import 'test.dart';
class C extends A {}
class D {}
@@ -2016,17 +2016,15 @@
return ElementLocator.locate(node);
}
- String _p(String path) => provider.convertPath(path);
-
Future<Null> _resolveTestUnit(String code, {bool addToDriver: true}) async {
if (addToDriver) {
addTestFile(code);
} else {
testCode = code;
- provider.newFile(testFile, testCode);
+ newFile(testFile, content: testCode);
}
if (testUnit == null) {
- AnalysisResult result = await driver.getResult(testFile);
+ ResolvedUnitResult result = await driver.getResult(testFile);
testUnit = result.unit;
testUnitElement = testUnit.declaredElement;
testLibraryElement = testUnitElement.library;
diff --git a/pkg/analyzer/test/src/dart/analysis/session_helper_test.dart b/pkg/analyzer/test/src/dart/analysis/session_helper_test.dart
index 81e7cbb..f815fbc 100644
--- a/pkg/analyzer/test/src/dart/analysis/session_helper_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/session_helper_test.dart
@@ -2,12 +2,13 @@
// 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:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/analysis/session_helper.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'base.dart';
+import '../resolution/driver_resolution.dart';
main() {
defineReflectiveSuite(() {
@@ -16,163 +17,408 @@
}
@reflectiveTest
-class AnalysisSessionHelperTest extends BaseAnalysisDriverTest {
- AnalysisSessionHelper sessionHelper;
+class AnalysisSessionHelperTest extends DriverResolutionTest {
+ AnalysisSessionHelper helper;
@override
void setUp() {
super.setUp();
- sessionHelper = new AnalysisSessionHelper(driver.currentSession);
+ helper = new AnalysisSessionHelper(driver.currentSession);
}
test_getClass_defined() async {
- var path = _p('/c.dart');
- var file = provider.newFile(path, r'''
+ var file = newFile('/test/lib/c.dart', content: r'''
class C {}
int v = 0;
''');
String uri = file.toUri().toString();
- var element = await sessionHelper.getClass(uri, 'C');
+ var element = await helper.getClass(uri, 'C');
expect(element, isNotNull);
expect(element.displayName, 'C');
}
test_getClass_defined_notClass() async {
- var path = _p('/c.dart');
- var file = provider.newFile(path, r'''
+ var file = newFile('/test/lib/c.dart', content: r'''
int v = 0;
''');
String uri = file.toUri().toString();
- var element = await sessionHelper.getClass(uri, 'v');
+ var element = await helper.getClass(uri, 'v');
expect(element, isNull);
}
test_getClass_exported() async {
- var a = _p('/a.dart');
- var b = _p('/b.dart');
- provider.newFile(a, r'''
+ newFile('/test/lib/a.dart', content: r'''
class A {}
''');
- var bFile = provider.newFile(b, r'''
+ var bFile = newFile('/test/lib/b.dart', content: r'''
export 'a.dart';
''');
String bUri = bFile.toUri().toString();
- var element = await sessionHelper.getClass(bUri, 'A');
+ var element = await helper.getClass(bUri, 'A');
expect(element, isNotNull);
expect(element.displayName, 'A');
}
test_getClass_imported() async {
- var a = _p('/a.dart');
- var b = _p('/b.dart');
- provider.newFile(a, r'''
+ newFile('/test/lib/a.dart', content: r'''
class A {}
''');
- var bFile = provider.newFile(b, r'''
+ var bFile = newFile('/test/lib/b.dart', content: r'''
import 'a.dart';
''');
String bUri = bFile.toUri().toString();
- var element = await sessionHelper.getClass(bUri, 'A');
+ var element = await helper.getClass(bUri, 'A');
expect(element, isNull);
}
+ test_getElementDeclaration_class() async {
+ newFile('/test/lib/test.dart', content: r'''
+class A {}
+''');
+ await resolveTestFile();
+
+ var element = findNode.classDeclaration('A').declaredElement;
+ var result = await helper.getElementDeclaration(element);
+ ClassDeclaration node = result.node;
+ expect(node.name.name, 'A');
+ }
+
+ test_getElementDeclaration_class_duplicate() async {
+ newFile('/test/lib/test.dart', content: r'''
+class A {} // 1
+class A {} // 2
+''');
+ await resolveTestFile();
+
+ {
+ var element = findNode.classDeclaration('A {} // 1').declaredElement;
+ var result = await helper.getElementDeclaration(element);
+ ClassDeclaration node = result.node;
+ expect(node.name.name, 'A');
+ expect(
+ node.name.offset,
+ this.result.content.indexOf('A {} // 1'),
+ );
+ }
+
+ {
+ var element = findNode.classDeclaration('A {} // 2').declaredElement;
+ var result = await helper.getElementDeclaration(element);
+ ClassDeclaration node = result.node;
+ expect(node.name.name, 'A');
+ expect(
+ node.name.offset,
+ this.result.content.indexOf('A {} // 2'),
+ );
+ }
+ }
+
+ test_getElementDeclaration_class_inPart() async {
+ newFile('/test/lib/a.dart', content: r'''
+part of 'test.dart';
+class A {}
+''');
+ newFile('/test/lib/test.dart', content: r'''
+part 'a.dart';
+''');
+ await resolveTestFile();
+
+ var library = this.result.unit.declaredElement.library;
+ var element = library.getType('A');
+ var result = await helper.getElementDeclaration(element);
+ ClassDeclaration node = result.node;
+ expect(node.name.name, 'A');
+ }
+
+ test_getElementDeclaration_constructor() async {
+ newFile('/test/lib/test.dart', content: r'''
+class A {
+ A();
+ A.named();
+}
+''');
+ await resolveTestFile();
+
+ {
+ var unnamed = findNode.constructor('A();').declaredElement;
+ var result = await helper.getElementDeclaration(unnamed);
+ ConstructorDeclaration node = result.node;
+ expect(node.name, isNull);
+ }
+
+ {
+ var named = findNode.constructor('A.named();').declaredElement;
+ var result = await helper.getElementDeclaration(named);
+ ConstructorDeclaration node = result.node;
+ expect(node.name.name, 'named');
+ }
+ }
+
+ test_getElementDeclaration_constructor_duplicate_named() async {
+ newFile('/test/lib/test.dart', content: r'''
+class A {
+ A.named(); // 1
+ A.named(); // 2
+}
+''');
+ await resolveTestFile();
+
+ {
+ var element = findNode.constructor('A.named(); // 1').declaredElement;
+ var result = await helper.getElementDeclaration(element);
+ ConstructorDeclaration node = result.node;
+ expect(node.name.name, 'named');
+ expect(
+ node.name.offset,
+ this.result.content.indexOf('named(); // 1'),
+ );
+ }
+
+ {
+ var element = findNode.constructor('A.named(); // 2').declaredElement;
+ var result = await helper.getElementDeclaration(element);
+ ConstructorDeclaration node = result.node;
+ expect(node.name.name, 'named');
+ expect(
+ node.name.offset,
+ this.result.content.indexOf('named(); // 2'),
+ );
+ }
+ }
+
+ test_getElementDeclaration_constructor_duplicate_unnamed() async {
+ newFile('/test/lib/test.dart', content: r'''
+class A {
+ A(); // 1
+ A(); // 2
+}
+''');
+ await resolveTestFile();
+
+ {
+ var element = findNode.constructor('A(); // 1').declaredElement;
+ var result = await helper.getElementDeclaration(element);
+ ConstructorDeclaration node = result.node;
+ expect(node.name, isNull);
+ expect(
+ node.returnType.offset,
+ this.result.content.indexOf('A(); // 1'),
+ );
+ }
+
+ {
+ var element = findNode.constructor('A(); // 2').declaredElement;
+ var result = await helper.getElementDeclaration(element);
+ ConstructorDeclaration node = result.node;
+ expect(node.name, isNull);
+ expect(
+ node.returnType.offset,
+ this.result.content.indexOf('A(); // 2'),
+ );
+ }
+ }
+
+ test_getElementDeclaration_constructor_synthetic() async {
+ newFile('/test/lib/test.dart', content: r'''
+class A {}
+''');
+ await resolveTestFile();
+
+ var element = findElement.class_('A').unnamedConstructor;
+ expect(element.isSynthetic, isTrue);
+
+ var result = await helper.getElementDeclaration(element);
+ expect(result, isNull);
+ }
+
+ test_getElementDeclaration_field() async {
+ newFile('/test/lib/test.dart', content: r'''
+class C {
+ int foo;
+}
+''');
+ await resolveTestFile();
+
+ var element = findElement.field('foo');
+ var result = await helper.getElementDeclaration(element);
+ VariableDeclaration node = result.node;
+ expect(node.name.name, 'foo');
+ }
+
+ test_getElementDeclaration_functionDeclaration_local() async {
+ newFile('/test/lib/test.dart', content: r'''
+main() {
+ void foo() {}
+}
+''');
+ await resolveTestFile();
+
+ var element = findElement.localFunction('foo');
+ var result = await helper.getElementDeclaration(element);
+ FunctionDeclaration node = result.node;
+ expect(node.name.name, 'foo');
+ }
+
+ test_getElementDeclaration_functionDeclaration_top() async {
+ newFile('/test/lib/test.dart', content: r'''
+void foo() {}
+''');
+ await resolveTestFile();
+
+ var element = findElement.topFunction('foo');
+ var result = await helper.getElementDeclaration(element);
+ FunctionDeclaration node = result.node;
+ expect(node.name.name, 'foo');
+ }
+
+ test_getElementDeclaration_localVariable() async {
+ newFile('/test/lib/test.dart', content: r'''
+main() {
+ int foo;
+}
+''');
+ await resolveTestFile();
+
+ var element = findElement.localVar('foo');
+ var result = await helper.getElementDeclaration(element);
+ VariableDeclaration node = result.node;
+ expect(node.name.name, 'foo');
+ }
+
+ test_getElementDeclaration_method() async {
+ newFile('/test/lib/test.dart', content: r'''
+class C {
+ void foo() {}
+}
+''');
+ await resolveTestFile();
+
+ var element = findElement.method('foo');
+ var result = await helper.getElementDeclaration(element);
+ MethodDeclaration node = result.node;
+ expect(node.name.name, 'foo');
+ }
+
+ test_getElementDeclaration_topLevelVariable() async {
+ newFile('/test/lib/test.dart', content: r'''
+int foo;
+''');
+ await resolveTestFile();
+
+ var element = findElement.topVar('foo');
+ var result = await helper.getElementDeclaration(element);
+ VariableDeclaration node = result.node;
+ expect(node.name.name, 'foo');
+ }
+
+ test_getElementDeclaration_topLevelVariable_synthetic() async {
+ newFile('/test/lib/test.dart', content: r'''
+int get foo => 0;
+''');
+ await resolveTestFile();
+
+ var element = findElement.topVar('foo');
+ var result = await helper.getElementDeclaration(element);
+ expect(result, isNull);
+ }
+
+ test_getResolvedUnitByElement() async {
+ newFile('/test/lib/test.dart', content: r'''
+class A {}
+class B {}
+''');
+ await resolveTestFile();
+
+ var element = findNode.classDeclaration('A').declaredElement;
+ var resolvedUnit = await helper.getResolvedUnitByElement(element);
+ expect(resolvedUnit.unit.declarations, hasLength(2));
+ }
+
test_getTopLevelPropertyAccessor_defined_getter() async {
- var path = _p('/test.dart');
- var file = provider.newFile(path, r'''
+ var file = newFile('/test/lib/test.dart', content: r'''
int get a => 0;
''');
String uri = file.toUri().toString();
- var element = await sessionHelper.getTopLevelPropertyAccessor(uri, 'a');
+ var element = await helper.getTopLevelPropertyAccessor(uri, 'a');
expect(element, isNotNull);
expect(element.kind, ElementKind.GETTER);
expect(element.displayName, 'a');
}
test_getTopLevelPropertyAccessor_defined_setter() async {
- var path = _p('/test.dart');
- var file = provider.newFile(path, r'''
+ var file = newFile('/test/lib/test.dart', content: r'''
set a(_) {}
''');
String uri = file.toUri().toString();
- var element = await sessionHelper.getTopLevelPropertyAccessor(uri, 'a=');
+ var element = await helper.getTopLevelPropertyAccessor(uri, 'a=');
expect(element, isNotNull);
expect(element.kind, ElementKind.SETTER);
expect(element.displayName, 'a');
}
test_getTopLevelPropertyAccessor_defined_variable() async {
- var path = _p('/test.dart');
- var file = provider.newFile(path, r'''
+ var file = newFile('/test/lib/test.dart', content: r'''
int a;
''');
String uri = file.toUri().toString();
- var element = await sessionHelper.getTopLevelPropertyAccessor(uri, 'a');
+ var element = await helper.getTopLevelPropertyAccessor(uri, 'a');
expect(element, isNotNull);
expect(element.kind, ElementKind.GETTER);
expect(element.displayName, 'a');
}
test_getTopLevelPropertyAccessor_exported() async {
- var a = _p('/a.dart');
- var b = _p('/b.dart');
- provider.newFile(a, r'''
+ newFile('/test/lib/a.dart', content: r'''
int a;
''');
- var bFile = provider.newFile(b, r'''
+ var bFile = newFile('/test/lib/b.dart', content: r'''
export 'a.dart';
''');
String bUri = bFile.toUri().toString();
- var element = await sessionHelper.getTopLevelPropertyAccessor(bUri, 'a');
+ var element = await helper.getTopLevelPropertyAccessor(bUri, 'a');
expect(element, isNotNull);
expect(element.kind, ElementKind.GETTER);
expect(element.displayName, 'a');
}
test_getTopLevelPropertyAccessor_imported() async {
- var a = _p('/a.dart');
- var b = _p('/b.dart');
- provider.newFile(a, r'''
+ newFile('/test/lib/a.dart', content: r'''
int a;
''');
- var bFile = provider.newFile(b, r'''
+ var bFile = newFile('/test/lib/b.dart', content: r'''
import 'a.dart';
''');
String bUri = bFile.toUri().toString();
- var element = await sessionHelper.getTopLevelPropertyAccessor(bUri, 'a');
+ var element = await helper.getTopLevelPropertyAccessor(bUri, 'a');
expect(element, isNull);
}
test_getTopLevelPropertyAccessor_notDefined() async {
- var path = _p('/test.dart');
- var file = provider.newFile(path, r'''
+ var file = newFile('/test/lib/test.dart', content: r'''
int a;
''');
String uri = file.toUri().toString();
- var element = await sessionHelper.getTopLevelPropertyAccessor(uri, 'b');
+ var element = await helper.getTopLevelPropertyAccessor(uri, 'b');
expect(element, isNull);
}
test_getTopLevelPropertyAccessor_notPropertyAccessor() async {
- var path = _p('/test.dart');
- var file = provider.newFile(path, r'''
+ var file = newFile('/test/lib/test.dart', content: r'''
int a() {}
''');
String uri = file.toUri().toString();
- var element = await sessionHelper.getTopLevelPropertyAccessor(uri, 'a');
+ var element = await helper.getTopLevelPropertyAccessor(uri, 'a');
expect(element, isNull);
}
-
- /// Return the [provider] specific path for the given Posix [path].
- String _p(String path) => provider.convertPath(path);
}
diff --git a/pkg/analyzer/test/src/dart/analysis/session_test.dart b/pkg/analyzer/test/src/dart/analysis/session_test.dart
index a5b9b87..555c2ec 100644
--- a/pkg/analyzer/test/src/dart/analysis/session_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/session_test.dart
@@ -8,12 +8,11 @@
import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
import 'package:analyzer/src/dart/analysis/session.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../context/mock_sdk.dart';
-
main() {
defineReflectiveSuite(() {
defineReflectiveTests(AnalysisSessionImplTest);
@@ -74,32 +73,207 @@
expect(library.getType('C'), isNull);
}
- test_getParsedAstSync() async {
+ test_getParsedLibrary() async {
newFile(testPath, content: r'''
class A {}
class B {}
''');
- var unitResult = session.getParsedAstSync(testPath);
- expect(unitResult.session, session);
- expect(unitResult.path, testPath);
- expect(unitResult.uri, Uri.parse('package:test/test.dart'));
- expect(unitResult.unit.declarations, hasLength(2));
+ var parsedLibrary = session.getParsedLibrary(testPath);
+ expect(parsedLibrary.session, session);
+ expect(parsedLibrary.path, testPath);
+ expect(parsedLibrary.uri, Uri.parse('package:test/test.dart'));
+
+ expect(parsedLibrary.units, hasLength(1));
+ {
+ var parsedUnit = parsedLibrary.units[0];
+ expect(parsedUnit.session, session);
+ expect(parsedUnit.path, testPath);
+ expect(parsedUnit.uri, Uri.parse('package:test/test.dart'));
+ expect(parsedUnit.unit.declarations, hasLength(2));
+ }
}
- test_getResolvedAst() async {
+ test_getParsedLibrary_getElementDeclaration_class() async {
newFile(testPath, content: r'''
class A {}
class B {}
''');
- var unitResult = await session.getResolvedAst(testPath);
+ var library = await session.getLibraryByUri('package:test/test.dart');
+ var parsedLibrary = session.getParsedLibrary(testPath);
+
+ var element = library.getType('A');
+ var declaration = parsedLibrary.getElementDeclaration(element);
+ ClassDeclaration node = declaration.node;
+ expect(node.name.name, 'A');
+ expect(node.offset, 0);
+ expect(node.length, 10);
+ }
+
+ test_getParsedLibrary_getElementDeclaration_notThisLibrary() async {
+ newFile(testPath, content: '');
+
+ var parsedLibrary = await session.getParsedLibrary(testPath);
+
+ var typeProvider = await session.typeProvider;
+ var intClass = typeProvider.intType.element;
+
+ expect(() {
+ parsedLibrary.getElementDeclaration(intClass);
+ }, throwsArgumentError);
+ }
+
+ test_getParsedLibrary_getElementDeclaration_synthetic() async {
+ newFile(testPath, content: r'''
+int foo = 0;
+''');
+
+ var parsedLibrary = session.getParsedLibrary(testPath);
+
+ var unitElement = (await session.getUnitElement(testPath)).element;
+ var fooElement = unitElement.topLevelVariables[0];
+ expect(fooElement.name, 'foo');
+
+ // We can get the variable element declaration.
+ var fooDeclaration = parsedLibrary.getElementDeclaration(fooElement);
+ VariableDeclaration fooNode = fooDeclaration.node;
+ expect(fooNode.name.name, 'foo');
+ expect(fooNode.offset, 4);
+ expect(fooNode.length, 7);
+ expect(fooNode.name.staticElement, isNull);
+
+ // Synthetic elements don't have nodes.
+ expect(parsedLibrary.getElementDeclaration(fooElement.getter), isNull);
+ expect(parsedLibrary.getElementDeclaration(fooElement.setter), isNull);
+ }
+
+ test_getParsedLibrary_invalidPartUri() async {
+ newFile(testPath, content: r'''
+part 'a.dart';
+part ':[invalid uri].dart';
+part 'c.dart';
+''');
+
+ var parsedLibrary = session.getParsedLibrary(testPath);
+
+ expect(parsedLibrary.units, hasLength(3));
+ expect(
+ parsedLibrary.units[0].path,
+ convertPath('/home/test/lib/test.dart'),
+ );
+ expect(
+ parsedLibrary.units[1].path,
+ convertPath('/home/test/lib/a.dart'),
+ );
+ expect(
+ parsedLibrary.units[2].path,
+ convertPath('/home/test/lib/c.dart'),
+ );
+ }
+
+ test_getParsedLibrary_notLibrary() async {
+ newFile(testPath, content: 'part of "a.dart";');
+
+ expect(() {
+ session.getParsedLibrary(testPath);
+ }, throwsArgumentError);
+ }
+
+ test_getParsedLibrary_parts() async {
+ var a = convertPath('/home/test/lib/a.dart');
+ var b = convertPath('/home/test/lib/b.dart');
+ var c = convertPath('/home/test/lib/c.dart');
+
+ var aContent = r'''
+part 'b.dart';
+part 'c.dart';
+
+class A {}
+''';
+
+ var bContent = r'''
+part of 'a.dart';
+
+class B1 {}
+class B2 {}
+''';
+
+ var cContent = r'''
+part of 'a.dart';
+
+class C1 {}
+class C2 {}
+class C3 {}
+''';
+
+ newFile(a, content: aContent);
+ newFile(b, content: bContent);
+ newFile(c, content: cContent);
+
+ var parsedLibrary = session.getParsedLibrary(a);
+ expect(parsedLibrary.path, a);
+ expect(parsedLibrary.uri, Uri.parse('package:test/a.dart'));
+ expect(parsedLibrary.units, hasLength(3));
+
+ {
+ var aUnit = parsedLibrary.units[0];
+ expect(aUnit.path, a);
+ expect(aUnit.uri, Uri.parse('package:test/a.dart'));
+ expect(aUnit.unit.declarations, hasLength(1));
+ }
+
+ {
+ var bUnit = parsedLibrary.units[1];
+ expect(bUnit.path, b);
+ expect(bUnit.uri, Uri.parse('package:test/b.dart'));
+ expect(bUnit.unit.declarations, hasLength(2));
+ }
+
+ {
+ var cUnit = parsedLibrary.units[2];
+ expect(cUnit.path, c);
+ expect(cUnit.uri, Uri.parse('package:test/c.dart'));
+ expect(cUnit.unit.declarations, hasLength(3));
+ }
+ }
+
+ test_getParsedLibraryByElement() async {
+ newFile(testPath, content: '');
+
+ var element = await session.getLibraryByUri('package:test/test.dart');
+
+ var parsedLibrary = session.getParsedLibraryByElement(element);
+ expect(parsedLibrary.session, session);
+ expect(parsedLibrary.path, testPath);
+ expect(parsedLibrary.uri, Uri.parse('package:test/test.dart'));
+ expect(parsedLibrary.units, hasLength(1));
+ }
+
+ test_getParsedLibraryByElement_differentSession() async {
+ newFile(testPath, content: '');
+
+ var element = await session.getLibraryByUri('package:test/test.dart');
+
+ var aaaSession =
+ contextCollection.contextFor(aaaContextPath).currentSession;
+
+ expect(() {
+ aaaSession.getParsedLibraryByElement(element);
+ }, throwsArgumentError);
+ }
+
+ test_getParsedUnit() async {
+ newFile(testPath, content: r'''
+class A {}
+class B {}
+''');
+
+ var unitResult = session.getParsedUnit(testPath);
expect(unitResult.session, session);
expect(unitResult.path, testPath);
expect(unitResult.uri, Uri.parse('package:test/test.dart'));
expect(unitResult.unit.declarations, hasLength(2));
- expect(unitResult.typeProvider, isNotNull);
- expect(unitResult.libraryElement, isNotNull);
}
test_getResolvedLibrary() async {
@@ -251,6 +425,34 @@
expect(resolvedLibrary.units[0].unit.declaredElement, isNotNull);
}
+ test_getResolvedLibraryByElement_differentSession() async {
+ newFile(testPath, content: '');
+
+ var element = await session.getLibraryByUri('package:test/test.dart');
+
+ var aaaSession =
+ contextCollection.contextFor(aaaContextPath).currentSession;
+
+ expect(() async {
+ await aaaSession.getResolvedLibraryByElement(element);
+ }, throwsArgumentError);
+ }
+
+ test_getResolvedUnit() async {
+ newFile(testPath, content: r'''
+class A {}
+class B {}
+''');
+
+ var unitResult = await session.getResolvedUnit(testPath);
+ expect(unitResult.session, session);
+ expect(unitResult.path, testPath);
+ expect(unitResult.uri, Uri.parse('package:test/test.dart'));
+ expect(unitResult.unit.declarations, hasLength(2));
+ expect(unitResult.typeProvider, isNotNull);
+ expect(unitResult.libraryElement, isNotNull);
+ }
+
test_getSourceKind() async {
newFile(testPath, content: 'class C {}');
diff --git a/pkg/analyzer/test/src/dart/analysis/uri_converter_test.dart b/pkg/analyzer/test/src/dart/analysis/uri_converter_test.dart
index f400cee..c7e291e 100644
--- a/pkg/analyzer/test/src/dart/analysis/uri_converter_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/uri_converter_test.dart
@@ -3,18 +3,16 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/context/context_root.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/uri_converter.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/source/package_map_resolver.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../context/mock_sdk.dart';
-
main() {
defineReflectiveSuite(() {
defineReflectiveTests(DriverBasedUriConverterTest);
@@ -22,12 +20,10 @@
}
@reflectiveTest
-class DriverBasedUriConverterTest extends Object with ResourceProviderMixin {
+class DriverBasedUriConverterTest with ResourceProviderMixin {
DriverBasedUriConverter uriConverter;
void setUp() {
- resourceProvider = new MemoryResourceProvider();
-
Folder barFolder = newFolder('/packages/bar/lib');
Folder fooFolder = newFolder('/packages/foo/lib');
diff --git a/pkg/analyzer/test/src/dart/ast/ast_test.dart b/pkg/analyzer/test/src/dart/ast/ast_test.dart
index 1bbecda..f0a6265 100644
--- a/pkg/analyzer/test/src/dart/ast/ast_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/ast_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// 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.
@@ -6,7 +6,6 @@
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
-import 'package:analyzer/src/generated/engine.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -472,102 +471,24 @@
bool get enableNewAnalysisDriver => true;
- void assertCanBeConst(String snippet, bool expectedResult) {
- int index = testSource.indexOf(snippet);
- expect(index >= 0, isTrue);
- NodeLocator visitor = new NodeLocator(index);
- AstNodeImpl node = visitor.searchWithin(testUnit);
- node = node.getAncestor((node) => node is InstanceCreationExpressionImpl);
- expect(node, isNotNull);
- expect((node as InstanceCreationExpressionImpl).canBeConst(),
- expectedResult ? isTrue : isFalse);
- }
-
void assertIsConst(String snippet, bool expectedResult) {
int index = testSource.indexOf(snippet);
expect(index >= 0, isTrue);
NodeLocator visitor = new NodeLocator(index);
AstNodeImpl node = visitor.searchWithin(testUnit);
- node = node.getAncestor((node) => node is InstanceCreationExpressionImpl);
+ node = node.thisOrAncestorOfType<InstanceCreationExpressionImpl>();
expect(node, isNotNull);
expect((node as InstanceCreationExpressionImpl).isConst,
expectedResult ? isTrue : isFalse);
}
- void enablePreviewDart2() {
- resetWith(options: new AnalysisOptionsImpl()..previewDart2 = true);
- }
-
Future<void> resolve(String source) async {
testSource = source;
testUnit = await resolveSource2('/test.dart', source);
}
- void test_canBeConst_false_argument_invocation() async {
- enablePreviewDart2();
- await resolve('''
-class A {}
-class B {
- const B(A a);
-}
-A f() => A();
-B g() => B(f());
-''');
- assertCanBeConst("B(f", false);
- }
-
- void test_canBeConst_false_argument_invocationInList() async {
- enablePreviewDart2();
- await resolve('''
-class A {}
-class B {
- const B(a);
-}
-A f() => A();
-B g() => B([f()]);
-''');
- assertCanBeConst("B([", false);
- }
-
- void test_canBeConst_false_argument_nonConstConstructor() async {
- enablePreviewDart2();
- await resolve('''
-class A {}
-class B {
- const B(A a);
-}
-B f() => B(A());
-''');
- assertCanBeConst("B(A(", false);
- }
-
- void test_canBeConst_false_nonConstConstructor() async {
- enablePreviewDart2();
- await resolve('''
-class A {}
-A f() => A();
-''');
- assertCanBeConst("A(", false);
- }
-
- @failingTest
- void test_canBeConst_true_argument_constConstructor() async {
- enablePreviewDart2();
- await resolve('''
-class A {
- const A();
-}
-class B {
- const B(A a);
-}
-B f() => B(A());
-''');
- assertCanBeConst("B(A(", true);
- }
-
void
test_isConst_notInContext_constructor_const_constParam_identifier() async {
- enablePreviewDart2();
await resolve('''
var v = C(C.a);
class C {
@@ -580,7 +501,6 @@
}
void test_isConst_notInContext_constructor_const_constParam_named() async {
- enablePreviewDart2();
await resolve('''
var v = C(c: C());
class C {
@@ -592,7 +512,6 @@
void
test_isConst_notInContext_constructor_const_constParam_named_parens() async {
- enablePreviewDart2();
await resolve('''
var v = C(c: (C()));
class C {
@@ -603,7 +522,6 @@
}
void test_isConst_notInContext_constructor_const_constParam_parens() async {
- enablePreviewDart2();
await resolve('''
var v = C( (C.c()) );
class C {
@@ -615,7 +533,6 @@
}
void test_isConst_notInContext_constructor_const_generic_named() async {
- enablePreviewDart2();
await resolve('''
f() => <Object>[C<int>.n()];
class C<E> {
@@ -627,7 +544,6 @@
void
test_isConst_notInContext_constructor_const_generic_named_prefixed() async {
- enablePreviewDart2();
addNamedSource('/c.dart', '''
class C<E> {
const C.n();
@@ -641,7 +557,6 @@
}
void test_isConst_notInContext_constructor_const_generic_unnamed() async {
- enablePreviewDart2();
await resolve('''
f() => <Object>[C<int>()];
class C<E> {
@@ -653,7 +568,6 @@
void
test_isConst_notInContext_constructor_const_generic_unnamed_prefixed() async {
- enablePreviewDart2();
addNamedSource('/c.dart', '''
class C<E> {
const C();
@@ -668,7 +582,6 @@
void
test_isConst_notInContext_constructor_const_nonConstParam_constructor() async {
- enablePreviewDart2();
await resolve('''
f() {
return A(B());
@@ -687,7 +600,6 @@
void
test_isConst_notInContext_constructor_const_nonConstParam_variable() async {
- enablePreviewDart2();
await resolve('''
f(int i) => <Object>[C(i)];
class C {
@@ -699,7 +611,6 @@
}
void test_isConst_notInContext_constructor_const_nonGeneric_named() async {
- enablePreviewDart2();
await resolve('''
f() => <Object>[C.n()];
class C<E> {
@@ -711,7 +622,6 @@
void
test_isConst_notInContext_constructor_const_nonGeneric_named_prefixed() async {
- enablePreviewDart2();
addNamedSource('/c.dart', '''
class C {
const C.n();
@@ -725,7 +635,6 @@
}
void test_isConst_notInContext_constructor_const_nonGeneric_unnamed() async {
- enablePreviewDart2();
await resolve('''
f() => <Object>[C()];
class C {
@@ -737,7 +646,6 @@
void
test_isConst_notInContext_constructor_const_nonGeneric_unnamed_prefixed() async {
- enablePreviewDart2();
addNamedSource('/c.dart', '''
class C {
const C();
@@ -751,7 +659,6 @@
}
void test_isConst_notInContext_constructor_nonConst() async {
- enablePreviewDart2();
await resolve('''
f() => <Object>[C()];
class C {
diff --git a/pkg/analyzer/test/src/dart/ast/utilities_test.dart b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
index de28384..795c3da 100644
--- a/pkg/analyzer/test/src/dart/ast/utilities_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
@@ -805,7 +805,7 @@
void test_visitPartDirective() {
PartDirective fromNode = AstTestFactory.partDirective2("part.dart");
LibraryElement element = new LibraryElementImpl.forNode(
- null, AstTestFactory.libraryIdentifier2(["lib"]));
+ null, null, AstTestFactory.libraryIdentifier2(["lib"]));
fromNode.element = element;
PartDirective toNode = AstTestFactory.partDirective2("part.dart");
ResolutionCopier.copyResolutionData(fromNode, toNode);
@@ -816,7 +816,7 @@
PartOfDirective fromNode = AstTestFactory.partOfDirective(
AstTestFactory.libraryIdentifier2(["lib"]));
LibraryElement element = new LibraryElementImpl.forNode(
- null, AstTestFactory.libraryIdentifier2(["lib"]));
+ null, null, AstTestFactory.libraryIdentifier2(["lib"]));
fromNode.element = element;
PartOfDirective toNode = AstTestFactory.partOfDirective(
AstTestFactory.libraryIdentifier2(["lib"]));
diff --git a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
index 0a08cae..5fce676 100644
--- a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -6,9 +6,12 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/standard_resolution_map.dart';
import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/constant.dart';
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
@@ -29,7 +32,139 @@
@reflectiveTest
class ConstantVisitorTest extends ResolverTestCase {
- test_visitBinaryExpression_questionQuestion_notNull_notNull() async {
+ test_visitAsExpression_instanceOfSameClass() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const a = const A();
+const b = a as A;
+class A {
+ const A();
+}
+''');
+ DartObjectImpl resultA = _evaluateConstant(compilationUnit, 'a',
+ experiments: [Experiments.constantUpdate2018Name]);
+ DartObjectImpl resultB = _evaluateConstant(compilationUnit, 'b',
+ experiments: [Experiments.constantUpdate2018Name]);
+ expect(resultB, resultA);
+ }
+
+ test_visitAsExpression_instanceOfSubclass() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const a = const B();
+const b = a as A;
+class A {
+ const A();
+}
+class B extends A {
+ const B();
+}
+''');
+ DartObjectImpl resultA = _evaluateConstant(compilationUnit, 'a',
+ experiments: [Experiments.constantUpdate2018Name]);
+ DartObjectImpl resultB = _evaluateConstant(compilationUnit, 'b',
+ experiments: [Experiments.constantUpdate2018Name]);
+ expect(resultB, resultA);
+ }
+
+ test_visitAsExpression_instanceOfSuperclass() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const a = const A();
+const b = a as B;
+class A {
+ const A();
+}
+class B extends A {
+ const B();
+}
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'b',
+ errorCodes: [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION],
+ experiments: [Experiments.constantUpdate2018Name]);
+ expect(result, isNull);
+ }
+
+ test_visitAsExpression_instanceOfUnrelatedClass() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const a = const A();
+const b = a as B;
+class A {
+ const A();
+}
+class B {
+ const B();
+}
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'b',
+ errorCodes: [CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION],
+ experiments: [Experiments.constantUpdate2018Name]);
+ expect(result, isNull);
+ }
+
+ test_visitAsExpression_null() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const a = null;
+const b = a as A;
+class A {}
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'b',
+ experiments: [Experiments.constantUpdate2018Name]);
+ expect(result.type, typeProvider.nullType);
+ }
+
+ test_visitBinaryExpression_and_bool() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const c = false & true;
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
+ experiments: [Experiments.constantUpdate2018Name]);
+ expect(result.type, typeProvider.boolType);
+ }
+
+ test_visitBinaryExpression_and_int() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const c = 3 & 5;
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
+ experiments: [Experiments.constantUpdate2018Name]);
+ expect(result.type, typeProvider.intType);
+ }
+
+ test_visitBinaryExpression_and_mixed() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const c = 3 & false;
+''');
+ _evaluateConstant(compilationUnit, 'c',
+ errorCodes: [CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_INT],
+ experiments: [Experiments.constantUpdate2018Name]);
+ }
+
+ test_visitBinaryExpression_or_bool() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const c = false | true;
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
+ experiments: [Experiments.constantUpdate2018Name]);
+ expect(result.type, typeProvider.boolType);
+ }
+
+ test_visitBinaryExpression_or_int() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const c = 3 | 5;
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
+ experiments: [Experiments.constantUpdate2018Name]);
+ expect(result.type, typeProvider.intType);
+ }
+
+ test_visitBinaryExpression_or_mixed() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const c = 3 | false;
+''');
+ _evaluateConstant(compilationUnit, 'c',
+ errorCodes: [CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_INT],
+ experiments: [Experiments.constantUpdate2018Name]);
+ }
+
+ test_visitBinaryExpression_questionQuestion_eager_notNull_notNull() async {
Expression left = AstTestFactory.string2('a');
Expression right = AstTestFactory.string2('b');
Expression expression = AstTestFactory.binaryExpression(
@@ -45,7 +180,7 @@
errorListener.assertNoErrors();
}
- test_visitBinaryExpression_questionQuestion_null_notNull() async {
+ test_visitBinaryExpression_questionQuestion_eager_null_notNull() async {
Expression left = AstTestFactory.nullLiteral();
Expression right = AstTestFactory.string2('b');
Expression expression = AstTestFactory.binaryExpression(
@@ -61,7 +196,7 @@
errorListener.assertNoErrors();
}
- test_visitBinaryExpression_questionQuestion_null_null() async {
+ test_visitBinaryExpression_questionQuestion_eager_null_null() async {
Expression left = AstTestFactory.nullLiteral();
Expression right = AstTestFactory.nullLiteral();
Expression expression = AstTestFactory.binaryExpression(
@@ -76,7 +211,84 @@
errorListener.assertNoErrors();
}
- test_visitConditionalExpression_false() async {
+ test_visitBinaryExpression_questionQuestion_lazy_notNull_invalid() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const c = 'a' ?? new C();
+class C {}
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
+ experiments: [Experiments.constantUpdate2018Name]);
+ expect(result.type, typeProvider.stringType);
+ expect(result.toStringValue(), 'a');
+ }
+
+ test_visitBinaryExpression_questionQuestion_lazy_notNull_notNull() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const c = 'a' ?? 'b';
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
+ experiments: [Experiments.constantUpdate2018Name]);
+ expect(result.type, typeProvider.stringType);
+ expect(result.toStringValue(), 'a');
+ }
+
+ test_visitBinaryExpression_questionQuestion_lazy_null_invalid() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const c = null ?? new C();
+class C {}
+''');
+ _evaluateConstant(compilationUnit, 'c',
+ errorCodes: [CompileTimeErrorCode.INVALID_CONSTANT],
+ experiments: [Experiments.constantUpdate2018Name]);
+ }
+
+ test_visitBinaryExpression_questionQuestion_lazy_null_notNull() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const c = null ?? 'b';
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
+ experiments: [Experiments.constantUpdate2018Name]);
+ expect(result.type, typeProvider.stringType);
+ expect(result.toStringValue(), 'b');
+ }
+
+ test_visitBinaryExpression_questionQuestion_lazy_null_null() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const c = null ?? null;
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
+ experiments: [Experiments.constantUpdate2018Name]);
+ expect(result.isNull, isTrue);
+ }
+
+ test_visitBinaryExpression_xor_bool() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const c = false ^ true;
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
+ experiments: [Experiments.constantUpdate2018Name]);
+ expect(result.type, typeProvider.boolType);
+ }
+
+ test_visitBinaryExpression_xor_int() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const c = 3 ^ 5;
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
+ experiments: [Experiments.constantUpdate2018Name]);
+ expect(result.type, typeProvider.intType);
+ }
+
+ test_visitBinaryExpression_xor_mixed() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const c = 3 ^ false;
+''');
+ _evaluateConstant(compilationUnit, 'c',
+ errorCodes: [CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_INT],
+ experiments: [Experiments.constantUpdate2018Name]);
+ }
+
+ test_visitConditionalExpression_eager_false_int_int() async {
Expression thenExpression = AstTestFactory.integer(1);
Expression elseExpression = AstTestFactory.integer(0);
ConditionalExpression expression = AstTestFactory.conditionalExpression(
@@ -88,7 +300,7 @@
errorListener.assertNoErrors();
}
- test_visitConditionalExpression_nonBooleanCondition() async {
+ test_visitConditionalExpression_eager_invalid_int_int() async {
Expression thenExpression = AstTestFactory.integer(1);
Expression elseExpression = AstTestFactory.integer(0);
NullLiteral conditionExpression = AstTestFactory.nullLiteral();
@@ -103,7 +315,19 @@
.assertErrorsWithCodes([CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL]);
}
- test_visitConditionalExpression_nonConstantElse() async {
+ test_visitConditionalExpression_eager_true_int_int() async {
+ Expression thenExpression = AstTestFactory.integer(1);
+ Expression elseExpression = AstTestFactory.integer(0);
+ ConditionalExpression expression = AstTestFactory.conditionalExpression(
+ AstTestFactory.booleanLiteral(true), thenExpression, elseExpression);
+ GatheringErrorListener errorListener = new GatheringErrorListener();
+ ErrorReporter errorReporter =
+ new ErrorReporter(errorListener, _dummySource());
+ _assertValue(1, _evaluate(expression, errorReporter));
+ errorListener.assertNoErrors();
+ }
+
+ test_visitConditionalExpression_eager_true_int_invalid() async {
Expression thenExpression = AstTestFactory.integer(1);
Expression elseExpression = AstTestFactory.identifier3("x");
ConditionalExpression expression = AstTestFactory.conditionalExpression(
@@ -117,7 +341,7 @@
.assertErrorsWithCodes([CompileTimeErrorCode.INVALID_CONSTANT]);
}
- test_visitConditionalExpression_nonConstantThen() async {
+ test_visitConditionalExpression_eager_true_invalid_int() async {
Expression thenExpression = AstTestFactory.identifier3("x");
Expression elseExpression = AstTestFactory.integer(0);
ConditionalExpression expression = AstTestFactory.conditionalExpression(
@@ -131,16 +355,263 @@
.assertErrorsWithCodes([CompileTimeErrorCode.INVALID_CONSTANT]);
}
- test_visitConditionalExpression_true() async {
- Expression thenExpression = AstTestFactory.integer(1);
- Expression elseExpression = AstTestFactory.integer(0);
- ConditionalExpression expression = AstTestFactory.conditionalExpression(
- AstTestFactory.booleanLiteral(true), thenExpression, elseExpression);
- GatheringErrorListener errorListener = new GatheringErrorListener();
- ErrorReporter errorReporter =
- new ErrorReporter(errorListener, _dummySource());
- _assertValue(1, _evaluate(expression, errorReporter));
- errorListener.assertNoErrors();
+ test_visitConditionalExpression_lazy_false_int_int() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const c = false ? 1 : 0;
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
+ experiments: [Experiments.constantUpdate2018Name]);
+ expect(result.type, typeProvider.intType);
+ expect(result.toIntValue(), 0);
+ }
+
+ test_visitConditionalExpression_lazy_false_int_invalid() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const c = false ? 1 : new C();
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
+ errorCodes: [CompileTimeErrorCode.INVALID_CONSTANT],
+ experiments: [Experiments.constantUpdate2018Name]);
+ }
+
+ test_visitConditionalExpression_lazy_false_invalid_int() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const c = false ? new C() : 0;
+class C {}
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
+ experiments: [Experiments.constantUpdate2018Name]);
+ expect(result.type, typeProvider.intType);
+ expect(result.toIntValue(), 0);
+ }
+
+ test_visitConditionalExpression_lazy_invalid_int_int() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const c = 3 ? 1 : 0;
+''');
+ _evaluateConstant(compilationUnit, 'c',
+ errorCodes: [CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL],
+ experiments: [Experiments.constantUpdate2018Name]);
+ }
+
+ test_visitConditionalExpression_lazy_true_int_int() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const c = true ? 1 : 0;
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
+ experiments: [Experiments.constantUpdate2018Name]);
+ expect(result.type, typeProvider.intType);
+ expect(result.toIntValue(), 1);
+ }
+
+ test_visitConditionalExpression_lazy_true_int_invalid() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const c = true ? 1 : new C();
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'c',
+ experiments: [Experiments.constantUpdate2018Name]);
+ expect(result.type, typeProvider.intType);
+ expect(result.toIntValue(), 1);
+ }
+
+ test_visitConditionalExpression_lazy_true_invalid_int() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const c = true ? new C() : 0;
+class C {}
+''');
+ _evaluateConstant(compilationUnit, 'c',
+ errorCodes: [CompileTimeErrorCode.INVALID_CONSTANT],
+ experiments: [Experiments.constantUpdate2018Name]);
+ }
+
+ test_visitIsExpression_is_instanceOfSameClass() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const a = const A();
+const b = a is A;
+class A {
+ const A();
+}
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'b',
+ experiments: [Experiments.constantUpdate2018Name]);
+ expect(result.type, typeProvider.boolType);
+ expect(result.toBoolValue(), true);
+ }
+
+ test_visitIsExpression_is_instanceOfSubclass() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const a = const B();
+const b = a is A;
+class A {
+ const A();
+}
+class B extends A {
+ const B();
+}
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'b',
+ experiments: [Experiments.constantUpdate2018Name]);
+ expect(result.type, typeProvider.boolType);
+ expect(result.toBoolValue(), true);
+ }
+
+ test_visitIsExpression_is_instanceOfSuperclass() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const a = const A();
+const b = a is B;
+class A {
+ const A();
+}
+class B extends A {
+ const B();
+}
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'b',
+ experiments: [Experiments.constantUpdate2018Name]);
+ expect(result.type, typeProvider.boolType);
+ expect(result.toBoolValue(), false);
+ }
+
+ test_visitIsExpression_is_instanceOfUnrelatedClass() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const a = const A();
+const b = a is B;
+class A {
+ const A();
+}
+class B {
+ const B();
+}
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'b',
+ experiments: [Experiments.constantUpdate2018Name]);
+ expect(result.type, typeProvider.boolType);
+ expect(result.toBoolValue(), false);
+ }
+
+ test_visitIsExpression_is_null() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const a = null;
+const b = a is A;
+class A {}
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'b',
+ experiments: [Experiments.constantUpdate2018Name]);
+ expect(result.type, typeProvider.boolType);
+ expect(result.toBoolValue(), false);
+ }
+
+ test_visitIsExpression_is_null_dynamic() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const a = null;
+const b = a is dynamic;
+class A {}
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'b',
+ experiments: [Experiments.constantUpdate2018Name]);
+ expect(result.type, typeProvider.boolType);
+ expect(result.toBoolValue(), true);
+ }
+
+ test_visitIsExpression_is_null_null() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const a = null;
+const b = a is Null;
+class A {}
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'b',
+ experiments: [Experiments.constantUpdate2018Name]);
+ expect(result.type, typeProvider.boolType);
+ expect(result.toBoolValue(), true);
+ }
+
+ test_visitIsExpression_is_null_object() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const a = null;
+const b = a is Object;
+class A {}
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'b',
+ experiments: [Experiments.constantUpdate2018Name]);
+ expect(result.type, typeProvider.boolType);
+ expect(result.toBoolValue(), true);
+ }
+
+ test_visitIsExpression_isNot_instanceOfSameClass() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const a = const A();
+const b = a is! A;
+class A {
+ const A();
+}
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'b',
+ experiments: [Experiments.constantUpdate2018Name]);
+ expect(result.type, typeProvider.boolType);
+ expect(result.toBoolValue(), false);
+ }
+
+ test_visitIsExpression_isNot_instanceOfSubclass() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const a = const B();
+const b = a is! A;
+class A {
+ const A();
+}
+class B extends A {
+ const B();
+}
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'b',
+ experiments: [Experiments.constantUpdate2018Name]);
+ expect(result.type, typeProvider.boolType);
+ expect(result.toBoolValue(), false);
+ }
+
+ test_visitIsExpression_isNot_instanceOfSuperclass() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const a = const A();
+const b = a is! B;
+class A {
+ const A();
+}
+class B extends A {
+ const B();
+}
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'b',
+ experiments: [Experiments.constantUpdate2018Name]);
+ expect(result.type, typeProvider.boolType);
+ expect(result.toBoolValue(), true);
+ }
+
+ test_visitIsExpression_isNot_instanceOfUnrelatedClass() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const a = const A();
+const b = a is! B;
+class A {
+ const A();
+}
+class B {
+ const B();
+}
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'b',
+ experiments: [Experiments.constantUpdate2018Name]);
+ expect(result.type, typeProvider.boolType);
+ expect(result.toBoolValue(), true);
+ }
+
+ test_visitIsExpression_isNot_null() async {
+ CompilationUnit compilationUnit = await resolveSource('''
+const a = null;
+const b = a is! A;
+class A {}
+''');
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'b',
+ experiments: [Experiments.constantUpdate2018Name]);
+ expect(result.type, typeProvider.boolType);
+ expect(result.toBoolValue(), true);
}
test_visitSimpleIdentifier_className() async {
@@ -148,7 +619,7 @@
const a = C;
class C {}
''');
- DartObjectImpl result = _evaluateConstant(compilationUnit, 'a', null);
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'a');
expect(result.type, typeProvider.typeType);
expect(result.toTypeValue().name, 'C');
}
@@ -157,7 +628,7 @@
CompilationUnit compilationUnit = await resolveSource('''
const a = dynamic;
''');
- DartObjectImpl result = _evaluateConstant(compilationUnit, 'a', null);
+ DartObjectImpl result = _evaluateConstant(compilationUnit, 'a');
expect(result.type, typeProvider.typeType);
expect(result.toTypeValue(), typeProvider.dynamicType);
}
@@ -170,7 +641,10 @@
DartObjectImpl six =
new DartObjectImpl(typeProvider.intType, new IntState(6));
environment["b"] = six;
- _assertValue(6, _evaluateConstant(compilationUnit, "a", environment));
+ _assertValue(
+ 6,
+ _evaluateConstant(compilationUnit, "a",
+ lexicalEnvironment: environment));
}
test_visitSimpleIdentifier_notInEnvironment() async {
@@ -181,14 +655,17 @@
DartObjectImpl six =
new DartObjectImpl(typeProvider.intType, new IntState(6));
environment["c"] = six;
- _assertValue(3, _evaluateConstant(compilationUnit, "a", environment));
+ _assertValue(
+ 3,
+ _evaluateConstant(compilationUnit, "a",
+ lexicalEnvironment: environment));
}
test_visitSimpleIdentifier_withoutEnvironment() async {
CompilationUnit compilationUnit = await resolveSource(r'''
const a = b;
const b = 3;''');
- _assertValue(3, _evaluateConstant(compilationUnit, "a", null));
+ _assertValue(3, _evaluateConstant(compilationUnit, "a"));
}
void _assertValue(int expectedValue, DartObjectImpl result) {
@@ -211,19 +688,32 @@
}
DartObjectImpl _evaluateConstant(CompilationUnit compilationUnit, String name,
- Map<String, DartObjectImpl> lexicalEnvironment) {
+ {List<ErrorCode> errorCodes,
+ List<String> experiments,
+ Map<String, DartObjectImpl> lexicalEnvironment}) {
Source source =
resolutionMap.elementDeclaredByCompilationUnit(compilationUnit).source;
Expression expression =
findTopLevelConstantExpression(compilationUnit, name);
+
+ AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+ if (experiments != null) {
+ options..enabledExperiments = experiments;
+ }
+
GatheringErrorListener errorListener = new GatheringErrorListener();
ErrorReporter errorReporter = new ErrorReporter(errorListener, source);
+
DartObjectImpl result = expression.accept(new ConstantVisitor(
new ConstantEvaluationEngine(typeProvider, new DeclaredVariables(),
- typeSystem: typeSystem),
+ experiments: new Experiments(options), typeSystem: typeSystem),
errorReporter,
lexicalEnvironment: lexicalEnvironment));
- errorListener.assertNoErrors();
+ if (errorCodes == null) {
+ errorListener.assertNoErrors();
+ } else {
+ errorListener.assertErrorsWithCodes(errorCodes);
+ }
return result;
}
}
diff --git a/pkg/analyzer/test/src/dart/constant/value_test.dart b/pkg/analyzer/test/src/dart/constant/value_test.dart
index 1883704..6825e19 100644
--- a/pkg/analyzer/test/src/dart/constant/value_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/value_test.dart
@@ -94,27 +94,27 @@
}
void test_bitAnd_knownInt_knownInt() {
- _assertBitAnd(_intValue(2), _intValue(6), _intValue(3));
+ _assertEagerAnd(_intValue(2), _intValue(6), _intValue(3));
}
void test_bitAnd_knownInt_knownString() {
- _assertBitAnd(null, _intValue(6), _stringValue("3"));
+ _assertEagerAnd(null, _intValue(6), _stringValue("3"));
}
void test_bitAnd_knownInt_unknownInt() {
- _assertBitAnd(_intValue(null), _intValue(6), _intValue(null));
+ _assertEagerAnd(_intValue(null), _intValue(6), _intValue(null));
}
void test_bitAnd_knownString_knownInt() {
- _assertBitAnd(null, _stringValue("6"), _intValue(3));
+ _assertEagerAnd(null, _stringValue("6"), _intValue(3));
}
void test_bitAnd_unknownInt_knownInt() {
- _assertBitAnd(_intValue(null), _intValue(null), _intValue(3));
+ _assertEagerAnd(_intValue(null), _intValue(null), _intValue(3));
}
void test_bitAnd_unknownInt_unknownInt() {
- _assertBitAnd(_intValue(null), _intValue(null), _intValue(null));
+ _assertEagerAnd(_intValue(null), _intValue(null), _intValue(null));
}
void test_bitNot_knownInt() {
@@ -130,51 +130,51 @@
}
void test_bitOr_knownInt_knownInt() {
- _assertBitOr(_intValue(7), _intValue(6), _intValue(3));
+ _assertEagerOr(_intValue(7), _intValue(6), _intValue(3));
}
void test_bitOr_knownInt_knownString() {
- _assertBitOr(null, _intValue(6), _stringValue("3"));
+ _assertEagerOr(null, _intValue(6), _stringValue("3"));
}
void test_bitOr_knownInt_unknownInt() {
- _assertBitOr(_intValue(null), _intValue(6), _intValue(null));
+ _assertEagerOr(_intValue(null), _intValue(6), _intValue(null));
}
void test_bitOr_knownString_knownInt() {
- _assertBitOr(null, _stringValue("6"), _intValue(3));
+ _assertEagerOr(null, _stringValue("6"), _intValue(3));
}
void test_bitOr_unknownInt_knownInt() {
- _assertBitOr(_intValue(null), _intValue(null), _intValue(3));
+ _assertEagerOr(_intValue(null), _intValue(null), _intValue(3));
}
void test_bitOr_unknownInt_unknownInt() {
- _assertBitOr(_intValue(null), _intValue(null), _intValue(null));
+ _assertEagerOr(_intValue(null), _intValue(null), _intValue(null));
}
void test_bitXor_knownInt_knownInt() {
- _assertBitXor(_intValue(5), _intValue(6), _intValue(3));
+ _assertEagerXor(_intValue(5), _intValue(6), _intValue(3));
}
void test_bitXor_knownInt_knownString() {
- _assertBitXor(null, _intValue(6), _stringValue("3"));
+ _assertEagerXor(null, _intValue(6), _stringValue("3"));
}
void test_bitXor_knownInt_unknownInt() {
- _assertBitXor(_intValue(null), _intValue(6), _intValue(null));
+ _assertEagerXor(_intValue(null), _intValue(6), _intValue(null));
}
void test_bitXor_knownString_knownInt() {
- _assertBitXor(null, _stringValue("6"), _intValue(3));
+ _assertEagerXor(null, _stringValue("6"), _intValue(3));
}
void test_bitXor_unknownInt_knownInt() {
- _assertBitXor(_intValue(null), _intValue(null), _intValue(3));
+ _assertEagerXor(_intValue(null), _intValue(null), _intValue(3));
}
void test_bitXor_unknownInt_unknownInt() {
- _assertBitXor(_intValue(null), _intValue(null), _intValue(null));
+ _assertEagerXor(_intValue(null), _intValue(null), _intValue(null));
}
void test_concatenate_knownInt_knownString() {
@@ -418,6 +418,20 @@
expect(_nullValue().isNull, isTrue);
}
+ void test_getValue_set_empty() {
+ Object result = _setValue().toSetValue();
+ _assertInstanceOfObjectArray(result);
+ Set<Object> set = result as Set<Object>;
+ expect(set, hasLength(0));
+ }
+
+ void test_getValue_set_valid() {
+ Object result = _setValue(new Set.from([_intValue(23)])).toSetValue();
+ _assertInstanceOfObjectArray(result);
+ Set<Object> set = result as Set<Object>;
+ expect(set, hasLength(1));
+ }
+
void test_getValue_string_known() {
String value = "twenty-three";
expect(_stringValue(value).toStringValue(), value);
@@ -958,65 +972,63 @@
}
void test_logicalAnd_false_false() {
- _assertLogicalAnd(_boolValue(false), _boolValue(false), _boolValue(false));
+ _assertLazyAnd(_boolValue(false), _boolValue(false), _boolValue(false));
}
void test_logicalAnd_false_null() {
- _assertLogicalAnd(_boolValue(false), _boolValue(false), _nullValue());
+ _assertLazyAnd(_boolValue(false), _boolValue(false), _nullValue());
}
void test_logicalAnd_false_string() {
- _assertLogicalAnd(
- _boolValue(false), _boolValue(false), _stringValue("false"));
+ _assertLazyAnd(_boolValue(false), _boolValue(false), _stringValue("false"));
}
void test_logicalAnd_false_true() {
- _assertLogicalAnd(_boolValue(false), _boolValue(false), _boolValue(true));
+ _assertLazyAnd(_boolValue(false), _boolValue(false), _boolValue(true));
}
void test_logicalAnd_null_false() {
expect(() {
- _assertLogicalAnd(_boolValue(false), _nullValue(), _boolValue(false));
+ _assertLazyAnd(_boolValue(false), _nullValue(), _boolValue(false));
}, throwsEvaluationException);
}
void test_logicalAnd_null_true() {
expect(() {
- _assertLogicalAnd(_boolValue(false), _nullValue(), _boolValue(true));
+ _assertLazyAnd(_boolValue(false), _nullValue(), _boolValue(true));
}, throwsEvaluationException);
}
void test_logicalAnd_string_false() {
expect(() {
- _assertLogicalAnd(
+ _assertLazyAnd(
_boolValue(false), _stringValue("true"), _boolValue(false));
}, throwsEvaluationException);
}
void test_logicalAnd_string_true() {
expect(() {
- _assertLogicalAnd(
+ _assertLazyAnd(
_boolValue(false), _stringValue("false"), _boolValue(true));
}, throwsEvaluationException);
}
void test_logicalAnd_true_false() {
- _assertLogicalAnd(_boolValue(false), _boolValue(true), _boolValue(false));
+ _assertLazyAnd(_boolValue(false), _boolValue(true), _boolValue(false));
}
void test_logicalAnd_true_null() {
- _assertLogicalAnd(null, _boolValue(true), _nullValue());
+ _assertLazyAnd(null, _boolValue(true), _nullValue());
}
void test_logicalAnd_true_string() {
expect(() {
- _assertLogicalAnd(
- _boolValue(false), _boolValue(true), _stringValue("true"));
+ _assertLazyAnd(_boolValue(false), _boolValue(true), _stringValue("true"));
}, throwsEvaluationException);
}
void test_logicalAnd_true_true() {
- _assertLogicalAnd(_boolValue(true), _boolValue(true), _boolValue(true));
+ _assertLazyAnd(_boolValue(true), _boolValue(true), _boolValue(true));
}
void test_logicalNot_false() {
@@ -1042,64 +1054,62 @@
}
void test_logicalOr_false_false() {
- _assertLogicalOr(_boolValue(false), _boolValue(false), _boolValue(false));
+ _assertLazyOr(_boolValue(false), _boolValue(false), _boolValue(false));
}
void test_logicalOr_false_null() {
- _assertLogicalOr(null, _boolValue(false), _nullValue());
+ _assertLazyOr(null, _boolValue(false), _nullValue());
}
void test_logicalOr_false_string() {
expect(() {
- _assertLogicalOr(
+ _assertLazyOr(
_boolValue(false), _boolValue(false), _stringValue("false"));
}, throwsEvaluationException);
}
void test_logicalOr_false_true() {
- _assertLogicalOr(_boolValue(true), _boolValue(false), _boolValue(true));
+ _assertLazyOr(_boolValue(true), _boolValue(false), _boolValue(true));
}
void test_logicalOr_null_false() {
expect(() {
- _assertLogicalOr(_boolValue(false), _nullValue(), _boolValue(false));
+ _assertLazyOr(_boolValue(false), _nullValue(), _boolValue(false));
}, throwsEvaluationException);
}
void test_logicalOr_null_true() {
expect(() {
- _assertLogicalOr(_boolValue(true), _nullValue(), _boolValue(true));
+ _assertLazyOr(_boolValue(true), _nullValue(), _boolValue(true));
}, throwsEvaluationException);
}
void test_logicalOr_string_false() {
expect(() {
- _assertLogicalOr(
- _boolValue(false), _stringValue("true"), _boolValue(false));
+ _assertLazyOr(_boolValue(false), _stringValue("true"), _boolValue(false));
}, throwsEvaluationException);
}
void test_logicalOr_string_true() {
expect(() {
- _assertLogicalOr(
- _boolValue(true), _stringValue("false"), _boolValue(true));
+ _assertLazyOr(_boolValue(true), _stringValue("false"), _boolValue(true));
}, throwsEvaluationException);
}
void test_logicalOr_true_false() {
- _assertLogicalOr(_boolValue(true), _boolValue(true), _boolValue(false));
+ _assertLazyOr(_boolValue(true), _boolValue(true), _boolValue(false));
}
void test_logicalOr_true_null() {
- _assertLogicalOr(_boolValue(true), _boolValue(true), _nullValue());
+ _assertLazyOr(_boolValue(true), _boolValue(true), _nullValue());
}
void test_logicalOr_true_string() {
- _assertLogicalOr(_boolValue(true), _boolValue(true), _stringValue("true"));
+ _assertLazyOr(_boolValue(true), _boolValue(true), _stringValue("true"));
}
void test_logicalOr_true_true() {
- _assertLogicalOr(_boolValue(true), _boolValue(true), _boolValue(true));
+ _assertLazyOr(_boolValue(true), _boolValue(true), _boolValue(true));
}
void test_minus_knownDouble_knownDouble() {
@@ -1480,24 +1490,6 @@
}
/**
- * Assert that the result of bit-anding the [left] and [right] operands is the
- * [expected] value, or that the operation throws an exception if the expected
- * value is `null`.
- */
- void _assertBitAnd(
- DartObjectImpl expected, DartObjectImpl left, DartObjectImpl right) {
- if (expected == null) {
- expect(() {
- left.bitAnd(_typeProvider, right);
- }, throwsEvaluationException);
- } else {
- DartObjectImpl result = left.bitAnd(_typeProvider, right);
- expect(result, isNotNull);
- expect(result, expected);
- }
- }
-
- /**
* Assert that the bit-not of the [operand] is the [expected] value, or that
* the operation throws an exception if the expected value is `null`.
*/
@@ -1514,42 +1506,6 @@
}
/**
- * Assert that the result of bit-oring the [left] and [right] operands is the
- * [expected] value, or that the operation throws an exception if the expected
- * value is `null`.
- */
- void _assertBitOr(
- DartObjectImpl expected, DartObjectImpl left, DartObjectImpl right) {
- if (expected == null) {
- expect(() {
- left.bitOr(_typeProvider, right);
- }, throwsEvaluationException);
- } else {
- DartObjectImpl result = left.bitOr(_typeProvider, right);
- expect(result, isNotNull);
- expect(result, expected);
- }
- }
-
- /**
- * Assert that the result of bit-xoring the [left] and [right] operands is the
- * [expected] value, or that the operation throws an exception if the expected
- * value is `null`.
- */
- void _assertBitXor(
- DartObjectImpl expected, DartObjectImpl left, DartObjectImpl right) {
- if (expected == null) {
- expect(() {
- left.bitXor(_typeProvider, right);
- }, throwsEvaluationException);
- } else {
- DartObjectImpl result = left.bitXor(_typeProvider, right);
- expect(result, isNotNull);
- expect(result, expected);
- }
- }
-
- /**
* Assert that the result of concatenating the [left] and [right] operands is
* the [expected] value, or that the operation throws an exception if the
* expected value is `null`.
@@ -1586,6 +1542,60 @@
}
/**
+ * Assert that the result of bit-anding the [left] and [right] operands is the
+ * [expected] value, or that the operation throws an exception if the expected
+ * value is `null`.
+ */
+ void _assertEagerAnd(
+ DartObjectImpl expected, DartObjectImpl left, DartObjectImpl right) {
+ if (expected == null) {
+ expect(() {
+ left.eagerAnd(_typeProvider, right, false);
+ }, throwsEvaluationException);
+ } else {
+ DartObjectImpl result = left.eagerAnd(_typeProvider, right, false);
+ expect(result, isNotNull);
+ expect(result, expected);
+ }
+ }
+
+ /**
+ * Assert that the result of bit-oring the [left] and [right] operands is the
+ * [expected] value, or that the operation throws an exception if the expected
+ * value is `null`.
+ */
+ void _assertEagerOr(
+ DartObjectImpl expected, DartObjectImpl left, DartObjectImpl right) {
+ if (expected == null) {
+ expect(() {
+ left.eagerOr(_typeProvider, right, false);
+ }, throwsEvaluationException);
+ } else {
+ DartObjectImpl result = left.eagerOr(_typeProvider, right, false);
+ expect(result, isNotNull);
+ expect(result, expected);
+ }
+ }
+
+ /**
+ * Assert that the result of bit-xoring the [left] and [right] operands is the
+ * [expected] value, or that the operation throws an exception if the expected
+ * value is `null`.
+ */
+ void _assertEagerXor(
+ DartObjectImpl expected, DartObjectImpl left, DartObjectImpl right) {
+ if (expected == null) {
+ expect(() {
+ left.eagerXor(_typeProvider, right, false);
+ }, throwsEvaluationException);
+ } else {
+ DartObjectImpl result = left.eagerXor(_typeProvider, right, false);
+ expect(result, isNotNull);
+ expect(result, expected);
+ }
+ }
+
+ /**
* Assert that the result of comparing the [left] and [right] operands for
* equality is the [expected] value, or that the operation throws an exception
* if the expected value is `null`.
@@ -1673,6 +1683,42 @@
}
/**
+ * Assert that the result of logical-anding the [left] and [right] operands is
+ * the [expected] value, or that the operation throws an exception if the
+ * expected value is `null`.
+ */
+ void _assertLazyAnd(
+ DartObjectImpl expected, DartObjectImpl left, DartObjectImpl right) {
+ if (expected == null) {
+ expect(() {
+ left.lazyAnd(_typeProvider, () => right);
+ }, throwsEvaluationException);
+ } else {
+ DartObjectImpl result = left.lazyAnd(_typeProvider, () => right);
+ expect(result, isNotNull);
+ expect(result, expected);
+ }
+ }
+
+ /**
+ * Assert that the result of logical-oring the [left] and [right] operands is
+ * the [expected] value, or that the operation throws an exception if the
+ * expected value is `null`.
+ */
+ void _assertLazyOr(
+ DartObjectImpl expected, DartObjectImpl left, DartObjectImpl right) {
+ if (expected == null) {
+ expect(() {
+ left.lazyOr(_typeProvider, () => right);
+ }, throwsEvaluationException);
+ } else {
+ DartObjectImpl result = left.lazyOr(_typeProvider, () => right);
+ expect(result, isNotNull);
+ expect(result, expected);
+ }
+ }
+
+ /**
* Assert that the result of comparing the [left] and [right] operands is the
* [expected] value, or that the operation throws an exception if the expected
* value is `null`.
@@ -1709,24 +1755,6 @@
}
/**
- * Assert that the result of logical-anding the [left] and [right] operands is
- * the [expected] value, or that the operation throws an exception if the
- * expected value is `null`.
- */
- void _assertLogicalAnd(
- DartObjectImpl expected, DartObjectImpl left, DartObjectImpl right) {
- if (expected == null) {
- expect(() {
- left.logicalAnd(_typeProvider, () => right);
- }, throwsEvaluationException);
- } else {
- DartObjectImpl result = left.logicalAnd(_typeProvider, () => right);
- expect(result, isNotNull);
- expect(result, expected);
- }
- }
-
- /**
* Assert that the logical-not of the [operand] is the [expected] value, or
* that the operation throws an exception if the expected value is `null`.
*/
@@ -1743,24 +1771,6 @@
}
/**
- * Assert that the result of logical-oring the [left] and [right] operands is
- * the [expected] value, or that the operation throws an exception if the
- * expected value is `null`.
- */
- void _assertLogicalOr(
- DartObjectImpl expected, DartObjectImpl left, DartObjectImpl right) {
- if (expected == null) {
- expect(() {
- left.logicalOr(_typeProvider, () => right);
- }, throwsEvaluationException);
- } else {
- DartObjectImpl result = left.logicalOr(_typeProvider, () => right);
- expect(result, isNotNull);
- expect(result, expected);
- }
- }
-
- /**
* Assert that the result of subtracting the [left] and [right] operands is
* the [expected] value, or that the operation throws an exception if the
* expected value is `null`.
@@ -1975,6 +1985,11 @@
return new DartObjectImpl(_typeProvider.nullType, NumState.UNKNOWN_VALUE);
}
+ DartObjectImpl _setValue([Set<DartObjectImpl> elements]) {
+ return new DartObjectImpl(_typeProvider.setType,
+ new SetState(elements ?? new Set<DartObjectImpl>()));
+ }
+
DartObjectImpl _stringValue(String value) {
if (value == null) {
return new DartObjectImpl(
diff --git a/pkg/analyzer/test/src/dart/element/element_test.dart b/pkg/analyzer/test/src/dart/element/element_test.dart
index 3a0bc36..dbebb31 100644
--- a/pkg/analyzer/test/src/dart/element/element_test.dart
+++ b/pkg/analyzer/test/src/dart/element/element_test.dart
@@ -47,6 +47,7 @@
@reflectiveTest
class ClassElementImplTest extends EngineTestCase {
+ @deprecated
void test_computeNode_ClassDeclaration() {
AnalysisContextHelper contextHelper = new AnalysisContextHelper();
AnalysisContext context = contextHelper.context;
@@ -100,6 +101,7 @@
}
}
+ @deprecated
void test_computeNode_ClassTypeAlias() {
AnalysisContextHelper contextHelper = new AnalysisContextHelper();
AnalysisContext context = contextHelper.context;
@@ -130,8 +132,8 @@
new TestElementResynthesizer(context, {location: classA});
ClassElementHandle classAHandle =
new ClassElementHandle(resynthesizer, location);
- ClassElementImpl classB =
- ElementFactory.classElement("B", new InterfaceTypeImpl(classAHandle));
+ ClassElementImpl classB = new ClassElementImpl('B', 0)
+ ..supertype = new InterfaceTypeImpl(classAHandle);
classB.mixinApplication = true;
expect(classB.constructors, hasLength(1));
@@ -1194,6 +1196,7 @@
@reflectiveTest
class FieldElementImplTest extends EngineTestCase {
+ @deprecated
void test_computeNode() {
AnalysisContextHelper contextHelper = new AnalysisContextHelper();
AnalysisContext context = contextHelper.context;
@@ -3692,8 +3695,8 @@
class LibraryElementImplTest extends EngineTestCase {
void test_creation() {
expect(
- new LibraryElementImpl.forNode(
- createAnalysisContext(), AstTestFactory.libraryIdentifier2(["l"])),
+ new LibraryElementImpl.forNode(createAnalysisContext(), null,
+ AstTestFactory.libraryIdentifier2(["l"])),
isNotNull);
}
@@ -3780,7 +3783,7 @@
void test_setImports() {
AnalysisContext context = createAnalysisContext();
LibraryElementImpl library = new LibraryElementImpl.forNode(
- context, AstTestFactory.libraryIdentifier2(["l1"]));
+ context, null, AstTestFactory.libraryIdentifier2(["l1"]));
List<ImportElementImpl> expectedImports = [
ElementFactory.importFor(ElementFactory.library(context, "l2"), null),
ElementFactory.importFor(ElementFactory.library(context, "l3"), null)
@@ -3799,6 +3802,7 @@
@reflectiveTest
class MethodElementImplTest extends EngineTestCase {
+ @deprecated
void test_computeNode() {
AnalysisContextHelper contextHelper = new AnalysisContextHelper();
AnalysisContext context = contextHelper.context;
@@ -3829,6 +3833,7 @@
}
}
+ @deprecated
void test_computeNode_withoutFunctionBody() {
AnalysisOptionsImpl options = new AnalysisOptionsImpl();
options.analyzeFunctionBodies = false;
@@ -3908,6 +3913,7 @@
@reflectiveTest
class ParameterElementImplTest extends EngineTestCase {
+ @deprecated
void test_computeNode_DefaultFormalParameter() {
AnalysisContextHelper contextHelper = new AnalysisContextHelper();
AnalysisContext context = contextHelper.context;
@@ -3927,6 +3933,7 @@
}
}
+ @deprecated
void test_computeNode_FieldFormalParameter() {
AnalysisContextHelper contextHelper = new AnalysisContextHelper();
AnalysisContext context = contextHelper.context;
@@ -3951,6 +3958,7 @@
}
}
+ @deprecated
void test_computeNode_FunctionTypedFormalParameter() {
AnalysisContextHelper contextHelper = new AnalysisContextHelper();
AnalysisContext context = contextHelper.context;
@@ -3970,6 +3978,7 @@
}
}
+ @deprecated
void test_computeNode_SimpleFormalParameter() {
AnalysisContextHelper contextHelper = new AnalysisContextHelper();
AnalysisContext context = contextHelper.context;
@@ -4027,7 +4036,7 @@
Map<ElementLocation, Element> locationMap;
TestElementResynthesizer(AnalysisContext context, this.locationMap)
- : super(context);
+ : super(context, null);
@override
Element getElement(ElementLocation location) {
diff --git a/pkg/analyzer/test/src/dart/element/function_type_test.dart b/pkg/analyzer/test/src/dart/element/function_type_test.dart
index 16b9189..975952b 100644
--- a/pkg/analyzer/test/src/dart/element/function_type_test.dart
+++ b/pkg/analyzer/test/src/dart/element/function_type_test.dart
@@ -1,13 +1,13 @@
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2018, 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:analyzer/analyzer.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/member.dart';
import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analyzer/test/src/dart/resolution/assignment_test.dart b/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
index c07703f..ba409b4 100644
--- a/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/assignment_test.dart
@@ -22,7 +22,7 @@
class AssignmentDriverResolutionTest extends DriverResolutionTest
with AssignmentResolutionMixin {}
-abstract class AssignmentResolutionMixin implements ResolutionTest {
+mixin AssignmentResolutionMixin implements ResolutionTest {
test_compound_indexExpression() async {
addTestFile(r'''
main() {
diff --git a/pkg/analyzer/test/src/dart/resolution/class_alias_test.dart b/pkg/analyzer/test/src/dart/resolution/class_alias_test.dart
index aea7e0f..6a6388a 100644
--- a/pkg/analyzer/test/src/dart/resolution/class_alias_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/class_alias_test.dart
@@ -19,7 +19,7 @@
class ClassAliasDriverResolutionTest extends DriverResolutionTest
with ClassAliasResolutionMixin {}
-abstract class ClassAliasResolutionMixin implements ResolutionTest {
+mixin ClassAliasResolutionMixin implements ResolutionTest {
test_defaultConstructor() async {
addTestFile(r'''
class A {}
diff --git a/pkg/analyzer/test/src/dart/resolution/class_test.dart b/pkg/analyzer/test/src/dart/resolution/class_test.dart
index f825033..0fecf73 100644
--- a/pkg/analyzer/test/src/dart/resolution/class_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/class_test.dart
@@ -21,7 +21,7 @@
class ClassDriverResolutionTest extends DriverResolutionTest
with ClassResolutionMixin {}
-abstract class ClassResolutionMixin implements ResolutionTest {
+mixin ClassResolutionMixin implements ResolutionTest {
test_abstractSuperMemberReference_getter() async {
addTestFile(r'''
abstract class A {
@@ -55,28 +55,7 @@
assertTestErrors([CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
assertElement(
findNode.simple('foo; // ref'),
- findElement.getter('foo', className: 'Foo'),
- );
- }
-
- test_abstractSuperMemberReference_method_invocation() async {
- addTestFile(r'''
-abstract class A {
- foo();
-}
-abstract class B extends A {
- bar() {
- super.foo(); // ref
- }
-
- foo() {} // does not matter
-}
-''');
- await resolveTestFile();
- assertTestErrors([CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
- assertElement(
- findNode.simple('foo(); // ref'),
- findElement.method('foo', of: 'A'),
+ findElement.getter('foo', of: 'Foo'),
);
}
@@ -96,31 +75,6 @@
assertElement(findNode.simple('foo; // ref'), findElement.method('foo'));
}
- test_abstractSuperMemberReference_OK_mixinHasConcrete2_method() async {
- addTestFile('''
-class A {
-}
-
-class M {
- void foo() {}
-}
-
-class B = A with M;
-
-class C extends B {
- void bar() {
- super.foo(); // ref
- }
-}
-''');
- await resolveTestFile();
- assertNoTestErrors();
- assertElement(
- findNode.simple('foo(); // ref'),
- findElement.method('foo', of: 'M'),
- );
- }
-
test_abstractSuperMemberReference_OK_superHasConcrete_mixinHasAbstract_method() async {
addTestFile('''
class A {
@@ -163,31 +117,7 @@
assertNoTestErrors();
assertElement(
findNode.simple('foo; // ref'),
- findElement.getter('foo', className: 'A'),
- );
- }
-
- test_abstractSuperMemberReference_OK_superSuperHasConcrete_method() async {
- addTestFile('''
-abstract class A {
- void foo() {}
-}
-
-abstract class B extends A {
- void foo();
-}
-
-class C extends B {
- void bar() {
- super.foo(); // ref
- }
-}
-''');
- await resolveTestFile();
- assertNoTestErrors();
- assertElement(
- findNode.simple('foo(); // ref'),
- findElement.method('foo', of: 'A'),
+ findElement.getter('foo', of: 'A'),
);
}
@@ -1371,6 +1301,32 @@
assertNoTestErrors();
}
+ test_error_mismatchedGetterAndSetterTypes_OK_setterParameter_0() async {
+ addTestFile(r'''
+class C {
+ int get foo => 0;
+ set foo() {}
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER,
+ ]);
+ }
+
+ test_error_mismatchedGetterAndSetterTypes_OK_setterParameter_2() async {
+ addTestFile(r'''
+class C {
+ int get foo => 0;
+ set foo(String p1, String p2) {}
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER,
+ ]);
+ }
+
test_error_mismatchedGetterAndSetterTypes_superGetter() async {
addTestFile(r'''
class A {
@@ -1483,6 +1439,22 @@
]);
}
+ test_issue32815() async {
+ addTestFile(r'''
+class A<T> extends B<T> {}
+class B<T> extends A<T> {}
+class C<T> extends B<T> implements I<T> {}
+
+abstract class I<T> {}
+
+main() {
+ Iterable<I<int>> x = [new C()];
+}
+''');
+ await resolveTestFile();
+ assertHasTestErrors();
+ }
+
test_recursiveInterfaceInheritance_extends() async {
addTestFile(r'''
class A extends B {}
@@ -1670,7 +1642,10 @@
}
}''');
await resolveTestFile();
- assertTestErrors([StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR]);
+ assertTestErrors([
+ StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR,
+ StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR,
+ ]);
}
test_undefinedSuperOperator_indexGetter() async {
diff --git a/pkg/analyzer/test/src/dart/resolution/comment_test.dart b/pkg/analyzer/test/src/dart/resolution/comment_test.dart
new file mode 100644
index 0000000..8a4d787
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/comment_test.dart
@@ -0,0 +1,261 @@
+// Copyright (c) 2018, 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:test_reflective_loader/test_reflective_loader.dart';
+
+import 'driver_resolution.dart';
+import 'resolution.dart';
+import 'task_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(CommentDriverResolutionTest);
+ defineReflectiveTests(CommentTaskResolutionTest);
+ });
+}
+
+@reflectiveTest
+class CommentDriverResolutionTest extends DriverResolutionTest
+ with ClassAliasResolutionMixin {}
+
+mixin ClassAliasResolutionMixin implements ResolutionTest {
+ test_error_unqualifiedReferenceToNonLocalStaticMember() async {
+ addTestFile(r'''
+class A {
+ static void foo() {}
+}
+
+/// [foo]
+class B extends A {}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ assertElement(
+ findNode.simple('foo]'),
+ findElement.method('foo', of: 'A'),
+ );
+ }
+
+ test_new() async {
+ addTestFile(r'''
+class A {
+ A();
+ A.named();
+}
+
+/// [new A] or [new A.named]
+main() {}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ assertElement(
+ findNode.simple('A]'),
+ findElement.unnamedConstructor('A'),
+ );
+ assertElement(
+ findNode.simple('A.named]'),
+ findElement.class_('A'),
+ );
+ assertElement(
+ findNode.simple('named]'),
+ findElement.constructor('named', className: 'A'),
+ );
+ }
+
+ test_identifier_beforeConstructor() async {
+ addTestFile(r'''
+class A {
+ /// [p]
+ A(int p);
+}''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ assertElement(
+ findNode.simple('p]'),
+ findElement.parameter('p'),
+ );
+ }
+
+ test_identifier_beforeEnum() async {
+ addTestFile(r'''
+/// This is the [Samurai] kind.
+enum Samurai {
+ /// Use [int].
+ WITH_SWORD,
+ /// Like [WITH_SWORD], but only without one.
+ WITHOUT_SWORD
+}''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ assertElement(
+ findNode.simple('Samurai]'),
+ findElement.enum_('Samurai'),
+ );
+ assertElement(
+ findNode.simple('int]'),
+ intElement,
+ );
+ assertElement(
+ findNode.simple('WITH_SWORD]'),
+ findElement.getter('WITH_SWORD'),
+ );
+ }
+
+ test_identifier_beforeFunction_blockBody() async {
+ addTestFile(r'''
+/// [p]
+foo(int p) {}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ assertElement(
+ findNode.simple('p]'),
+ findElement.parameter('p'),
+ );
+ }
+
+ test_identifier_parameter_functionTyped() async {
+ addTestFile(r'''
+/// [bar]
+foo(int bar()) {}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ assertElement(
+ findNode.simple('bar]'),
+ findElement.parameter('bar'),
+ );
+ }
+
+ test_identifier_beforeFunction_expressionBody() async {
+ addTestFile(r'''
+/// [p]
+foo(int p) => null;
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ assertElement(
+ findNode.simple('p]'),
+ findElement.parameter('p'),
+ );
+ }
+
+ test_identifier_beforeFunctionTypeAlias() async {
+ addTestFile(r'''
+/// [p]
+typedef Foo(int p);
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ assertElement(
+ findNode.simple('p]'),
+ findElement.parameter('p'),
+ );
+ }
+
+ test_identifier_beforeGenericTypeAlias() async {
+ addTestFile(r'''
+/// Can resolve [T], [S], and [p].
+typedef Foo<T> = Function<S>(int p);
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ assertElement(
+ findNode.simple('T]'),
+ findElement.typeParameter('T'),
+ );
+ assertElement(findNode.simple('S]'), findElement.typeParameter('S'));
+ assertElement(
+ findNode.simple('p]'),
+ findElement.parameter('p'),
+ );
+ }
+
+ test_identifier_beforeGetter() async {
+ addTestFile(r'''
+/// [int]
+get g => null;
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ assertElement(findNode.simple('int]'), intElement);
+ }
+
+ test_identifier_beforeMethod() async {
+ addTestFile(r'''
+abstract class A {
+ /// [p1]
+ ma(int p1);
+
+ /// [p2]
+ mb(int p2);
+
+ /// [p3] and [p4]
+ mc(int p3, p4());
+
+ /// [p5]
+ md(int p5, {int p6});
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ assertElement(findNode.simple('p1]'), findElement.parameter('p1'));
+ assertElement(findNode.simple('p2]'), findElement.parameter('p2'));
+ assertElement(findNode.simple('p3]'), findElement.parameter('p3'));
+ assertElement(findNode.simple('p4]'), findElement.parameter('p4'));
+ assertElement(findNode.simple('p5]'), findElement.parameter('p5'));
+ }
+
+ test_identifier_beforeClass() async {
+ addTestFile(r'''
+/// [foo]
+class A {
+ foo() {}
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ assertElement(
+ findNode.simple('foo]'),
+ findElement.method('foo'),
+ );
+ }
+
+ test_identifier_setter() async {
+ addTestFile(r'''
+class A {
+ /// [x] in A
+ mA() {}
+ set x(value) {}
+}
+
+class B extends A {
+ /// [x] in B
+ mB() {}
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var x = findElement.setter('x', className: 'A');
+ assertElement(findNode.simple('x] in A'), x);
+ assertElement(findNode.simple('x] in B'), x);
+ }
+}
+
+@reflectiveTest
+class CommentTaskResolutionTest extends TaskResolutionTest
+ with ClassAliasResolutionMixin {}
diff --git a/pkg/analyzer/test/src/dart/resolution/constant_test.dart b/pkg/analyzer/test/src/dart/resolution/constant_test.dart
index 53a5c74..4ba17ed 100644
--- a/pkg/analyzer/test/src/dart/resolution/constant_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/constant_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/error/codes.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -20,7 +21,67 @@
@reflectiveTest
class ConstantDriverTest extends DriverResolutionTest with ConstantMixin {}
-abstract class ConstantMixin implements ResolutionTest {
+mixin ConstantMixin implements ResolutionTest {
+ test_annotation_constructor_named() async {
+ newFile('/test/lib/a.dart', content: r'''
+class A {
+ final int f;
+ const A.named(this.f);
+}
+''');
+
+ newFile('/test/lib/b.dart', content: r'''
+import 'a.dart';
+
+@A.named(42)
+class B {}
+''');
+
+ addTestFile(r'''
+import 'b.dart';
+
+B b;
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var classB = findNode.typeName('B b;').name.staticElement;
+ var annotation = classB.metadata.single;
+ var value = annotation.computeConstantValue();
+ expect(value, isNotNull);
+ expect(value.getField('f').toIntValue(), 42);
+ }
+
+ test_annotation_constructor_unnamed() async {
+ newFile('/test/lib/a.dart', content: r'''
+class A {
+ final int f;
+ const A(this.f);
+}
+''');
+
+ newFile('/test/lib/b.dart', content: r'''
+import 'a.dart';
+
+@A(42)
+class B {}
+''');
+
+ addTestFile(r'''
+import 'b.dart';
+
+B b;
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var classB = findNode.typeName('B b;').name.staticElement;
+ var annotation = classB.metadata.single;
+ var value = annotation.computeConstantValue();
+ expect(value, isNotNull);
+ expect(value.getField('f').toIntValue(), 42);
+ }
+
test_constantValue_defaultParameter_noDefaultValue() async {
newFile('/test/lib/a.dart', content: r'''
class A {
@@ -70,6 +131,25 @@
var value = node.elementAnnotation.constantValue;
expect(value.getField('(super)').getField('f').toIntValue(), 42);
}
+
+ test_constNotInitialized() async {
+ addTestFile(r'''
+class B {
+ const B(_);
+}
+
+class C extends B {
+ static const a;
+ const C() : super(a);
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER,
+ CompileTimeErrorCode.CONST_NOT_INITIALIZED,
+ CompileTimeErrorCode.CONST_NOT_INITIALIZED,
+ ]);
+ }
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/dart/resolution/driver_resolution.dart b/pkg/analyzer/test/src/dart/resolution/driver_resolution.dart
index fb034da..e5315a5 100644
--- a/pkg/analyzer/test/src/dart/resolution/driver_resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/driver_resolution.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2018, 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.
@@ -13,14 +13,13 @@
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/source/package_map_resolver.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
-import '../../context/mock_sdk.dart';
import 'resolution.dart';
/// [AnalysisDriver] based implementation of [ResolutionTest].
-class DriverResolutionTest extends Object
- with ResourceProviderMixin, ResolutionTest {
+class DriverResolutionTest with ResourceProviderMixin, ResolutionTest {
final ByteStore byteStore = new MemoryByteStore();
final StringBuffer logBuffer = new StringBuffer();
@@ -32,7 +31,7 @@
@override
Future<TestAnalysisResult> resolveFile(String path) async {
- AnalysisResult result = await driver.getResult(path);
+ var result = await driver.getResult(path);
return new TestAnalysisResult(
path,
result.content,
diff --git a/pkg/analyzer/test/src/dart/resolution/enum_test.dart b/pkg/analyzer/test/src/dart/resolution/enum_test.dart
index 930ab7c..ff350fb 100644
--- a/pkg/analyzer/test/src/dart/resolution/enum_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/enum_test.dart
@@ -21,7 +21,7 @@
class EnumDriverResolutionTest extends DriverResolutionTest
with EnumResolutionMixin {}
-abstract class EnumResolutionMixin implements ResolutionTest {
+mixin EnumResolutionMixin implements ResolutionTest {
test_error_conflictingStaticAndInstance_index() async {
addTestFile(r'''
enum E {
diff --git a/pkg/analyzer/test/src/dart/resolution/find_element.dart b/pkg/analyzer/test/src/dart/resolution/find_element.dart
index 4eadf43..d408980 100644
--- a/pkg/analyzer/test/src/dart/resolution/find_element.dart
+++ b/pkg/analyzer/test/src/dart/resolution/find_element.dart
@@ -115,9 +115,16 @@
fail('Not found generic type alias: $name');
}
- PropertyAccessorElement getter(String name, {String className}) {
+ PropertyAccessorElement getter(String name, {String of}) {
+ for (var enum_ in unitElement.enums) {
+ for (var accessor in enum_.accessors) {
+ if (accessor.isGetter && accessor.displayName == name) {
+ return accessor;
+ }
+ }
+ }
for (var class_ in unitElement.types) {
- if (className != null && class_.name != className) {
+ if (of != null && class_.name != of) {
continue;
}
for (var accessor in class_.accessors) {
@@ -150,6 +157,25 @@
return class_(name).type;
}
+ FunctionElement localFunction(String name) {
+ FunctionElement result;
+ unit.accept(new FunctionAstVisitor(
+ functionDeclarationStatement: (node) {
+ var element = node.functionDeclaration.declaredElement;
+ if (element is FunctionElement) {
+ if (result != null) {
+ throw new StateError('Local function name $name is not unique.');
+ }
+ result = element;
+ }
+ },
+ ));
+ if (result == null) {
+ fail('Not found local function: $name');
+ }
+ return result;
+ }
+
LocalVariableElement localVar(String name) {
LocalVariableElement result;
unit.accept(new FunctionAstVisitor(
@@ -318,6 +344,9 @@
for (var type in unitElement.functionTypeAliases) {
type.typeParameters.forEach(consider);
+ if (type is GenericTypeAliasElement) {
+ type.function.typeParameters.forEach(consider);
+ }
}
for (var type in unitElement.types) {
type.typeParameters.forEach(consider);
diff --git a/pkg/analyzer/test/src/dart/resolution/find_node.dart b/pkg/analyzer/test/src/dart/resolution/find_node.dart
index 67271af..08de2f9 100644
--- a/pkg/analyzer/test/src/dart/resolution/find_node.dart
+++ b/pkg/analyzer/test/src/dart/resolution/find_node.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2018, 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.
@@ -28,6 +28,10 @@
return _node(search, (n) => n is CascadeExpression);
}
+ ClassDeclaration classDeclaration(String search) {
+ return _node(search, (n) => n is ClassDeclaration);
+ }
+
CommentReference commentReference(String search) {
return _node(search, (n) => n is CommentReference);
}
@@ -158,7 +162,7 @@
var node = new NodeLocator2(index).searchWithin(unit);
expect(node, isNotNull);
- var result = node.getAncestor(predicate);
+ var result = node.thisOrAncestorMatching(predicate);
expect(result, isNotNull);
return result;
}
diff --git a/pkg/analyzer/test/src/dart/resolution/for_in_test.dart b/pkg/analyzer/test/src/dart/resolution/for_in_test.dart
index fdbdd76..7ec1a40 100644
--- a/pkg/analyzer/test/src/dart/resolution/for_in_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/for_in_test.dart
@@ -20,7 +20,7 @@
class ForInDriverResolutionTest extends DriverResolutionTest
with ForInResolutionMixin {}
-abstract class ForInResolutionMixin implements ResolutionTest {
+mixin ForInResolutionMixin implements ResolutionTest {
test_importPrefix_asIterable() async {
// TODO(scheglov) Remove this test (already tested as import prefix).
// TODO(scheglov) Move other for-in tests here.
diff --git a/pkg/analyzer/test/src/dart/resolution/function_ast_visitor.dart b/pkg/analyzer/test/src/dart/resolution/function_ast_visitor.dart
index 82ae780..f3c951b 100644
--- a/pkg/analyzer/test/src/dart/resolution/function_ast_visitor.dart
+++ b/pkg/analyzer/test/src/dart/resolution/function_ast_visitor.dart
@@ -7,10 +7,23 @@
/// [RecursiveAstVisitor] that delegates visit methods to functions.
class FunctionAstVisitor extends RecursiveAstVisitor<void> {
+ final void Function(FunctionDeclarationStatement)
+ functionDeclarationStatement;
final void Function(SimpleIdentifier) simpleIdentifier;
final void Function(VariableDeclaration) variableDeclaration;
- FunctionAstVisitor({this.simpleIdentifier, this.variableDeclaration});
+ FunctionAstVisitor(
+ {this.functionDeclarationStatement,
+ this.simpleIdentifier,
+ this.variableDeclaration});
+
+ @override
+ void visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
+ if (functionDeclarationStatement != null) {
+ functionDeclarationStatement(node);
+ }
+ super.visitFunctionDeclarationStatement(node);
+ }
@override
void visitSimpleIdentifier(SimpleIdentifier node) {
diff --git a/pkg/analyzer/test/src/dart/resolution/generic_type_alias_test.dart b/pkg/analyzer/test/src/dart/resolution/generic_type_alias_test.dart
index 7f24421a..2e64644 100644
--- a/pkg/analyzer/test/src/dart/resolution/generic_type_alias_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/generic_type_alias_test.dart
@@ -2,6 +2,7 @@
// 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:analyzer/src/error/codes.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -20,7 +21,111 @@
class GenericTypeAliasDriverResolutionTest extends DriverResolutionTest
with GenericTypeAliasResolutionMixin {}
-abstract class GenericTypeAliasResolutionMixin implements ResolutionTest {
+mixin GenericTypeAliasResolutionMixin implements ResolutionTest {
+ test_genericFunctionTypeCannotBeTypeArgument_def_class() async {
+ addTestFile(r'''
+class C<T> {}
+
+typedef G = Function<S>();
+
+C<G> x;
+''');
+ await resolveTestFile();
+ assertTestErrors(
+ [CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT],
+ );
+ }
+
+ test_genericFunctionTypeCannotBeTypeArgument_literal_class() async {
+ addTestFile(r'''
+class C<T> {}
+
+C<Function<S>()> x;
+''');
+ await resolveTestFile();
+ assertTestErrors(
+ [CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT],
+ );
+ }
+
+ test_genericFunctionTypeCannotBeTypeArgument_literal_function() async {
+ addTestFile(r'''
+T f<T>(T) => null;
+
+main() {
+ f<Function<S>()>(null);
+}
+''');
+ await resolveTestFile();
+ assertTestErrors(
+ [CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT],
+ );
+ }
+
+ test_genericFunctionTypeCannotBeTypeArgument_literal_functionType() async {
+ addTestFile(r'''
+T Function<T>(T) f;
+
+main() {
+ f<Function<S>()>(null);
+}
+''');
+ await resolveTestFile();
+ assertTestErrors(
+ [CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT],
+ );
+ }
+
+ test_genericFunctionTypeCannotBeTypeArgument_literal_method() async {
+ addTestFile(r'''
+class C {
+ T f<T>(T) => null;
+}
+
+main() {
+ new C().f<Function<S>()>(null);
+}
+''');
+ await resolveTestFile();
+ assertTestErrors(
+ [CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT],
+ );
+ }
+
+ test_genericFunctionTypeCannotBeTypeArgument_literal_typedef() async {
+ addTestFile(r'''
+typedef T F<T>(T t);
+
+F<Function<S>()> x;
+''');
+ await resolveTestFile();
+ assertTestErrors(
+ [CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT],
+ );
+ }
+
+ test_genericFunctionTypeCannotBeTypeArgument_OK_def_class() async {
+ addTestFile(r'''
+class C<T> {}
+
+typedef G = Function();
+
+C<G> x;
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+ }
+
+ test_genericFunctionTypeCannotBeTypeArgument_OK_literal_class() async {
+ addTestFile(r'''
+class C<T> {}
+
+C<Function()> x;
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+ }
+
test_typeParameters() async {
addTestFile(r'''
class A {}
diff --git a/pkg/analyzer/test/src/dart/resolution/import_prefix_test.dart b/pkg/analyzer/test/src/dart/resolution/import_prefix_test.dart
index a269e79..b13db90 100644
--- a/pkg/analyzer/test/src/dart/resolution/import_prefix_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/import_prefix_test.dart
@@ -21,7 +21,7 @@
class ImportPrefixDriverResolutionTest extends DriverResolutionTest
with ImportPrefixResolutionMixin {}
-abstract class ImportPrefixResolutionMixin implements ResolutionTest {
+mixin ImportPrefixResolutionMixin implements ResolutionTest {
test_asExpression_expressionStatement() async {
addTestFile(r'''
import 'dart:async' as p;
diff --git a/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart b/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
index 9594336..302d84b 100644
--- a/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart
@@ -20,7 +20,7 @@
class InstanceCreationDriverResolutionTest extends DriverResolutionTest
with InstanceCreationResolutionMixin {}
-abstract class InstanceCreationResolutionMixin implements ResolutionTest {
+mixin InstanceCreationResolutionMixin implements ResolutionTest {
test_error_wrongNumberOfTypeArgumentsConstructor_explicitNew() async {
addTestFile(r'''
class Foo<X> {
@@ -47,6 +47,24 @@
// );
}
+ test_error_newWithInvalidTypeParameters_implicitNew_inference_top() async {
+ addTestFile(r'''
+final foo = Map<int>();
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticWarningCode.NEW_WITH_INVALID_TYPE_PARAMETERS,
+ ]);
+
+ var creation = findNode.instanceCreation('Map<int>');
+ assertInstanceCreation(
+ creation,
+ mapElement,
+ 'Map<dynamic, dynamic>',
+ expectedConstructorMember: true,
+ );
+ }
+
test_error_wrongNumberOfTypeArgumentsConstructor_explicitNew_prefix() async {
newFile('/test/lib/a.dart', content: '''
class Foo<X> {
@@ -137,4 +155,10 @@
@reflectiveTest
class InstanceCreationTaskResolutionTest extends TaskResolutionTest
- with InstanceCreationResolutionMixin {}
+ with InstanceCreationResolutionMixin {
+ @FailingTest(reason: 'Does not report the error.')
+ test_error_newWithInvalidTypeParameters_implicitNew_inference_top() {
+ return super
+ .test_error_newWithInvalidTypeParameters_implicitNew_inference_top();
+ }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/instance_member_inference_class_test.dart b/pkg/analyzer/test/src/dart/resolution/instance_member_inference_class_test.dart
index 1218643..ad4b765 100644
--- a/pkg/analyzer/test/src/dart/resolution/instance_member_inference_class_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/instance_member_inference_class_test.dart
@@ -19,7 +19,7 @@
class InstanceMemberInferenceClassDriverResolutionTest
extends DriverResolutionTest with InstanceMemberInferenceClassMixin {}
-abstract class InstanceMemberInferenceClassMixin implements ResolutionTest {
+mixin InstanceMemberInferenceClassMixin implements ResolutionTest {
test_invalid_inheritanceCycle() async {
addTestFile('''
class A extends C {}
diff --git a/pkg/analyzer/test/src/dart/resolution/instance_member_inference_mixin_test.dart b/pkg/analyzer/test/src/dart/resolution/instance_member_inference_mixin_test.dart
index 387e166..36db4b0 100644
--- a/pkg/analyzer/test/src/dart/resolution/instance_member_inference_mixin_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/instance_member_inference_mixin_test.dart
@@ -19,7 +19,7 @@
class InstanceMemberInferenceMixinDriverResolutionTest
extends DriverResolutionTest with InstanceMemberInferenceMixinMixin {}
-abstract class InstanceMemberInferenceMixinMixin implements ResolutionTest {
+mixin InstanceMemberInferenceMixinMixin implements ResolutionTest {
test_invalid_inheritanceCycle() async {
addTestFile('''
mixin A on C {}
diff --git a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
new file mode 100644
index 0000000..811228a
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
@@ -0,0 +1,1720 @@
+// Copyright (c) 2018, 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:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'driver_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(MethodInvocationResolutionTest);
+ });
+}
+
+@reflectiveTest
+class MethodInvocationResolutionTest extends DriverResolutionTest {
+ test_error_abstractSuperMemberReference() async {
+ addTestFile(r'''
+abstract class A {
+ void foo(int _);
+}
+abstract class B extends A {
+ void bar() {
+ super.foo(0);
+ }
+
+ void foo(int _) {} // does not matter
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
+
+ var invocation = findNode.methodInvocation('foo(0)');
+ assertMethodInvocation(
+ invocation,
+ findElement.method('foo', of: 'A'),
+ '(int) → void',
+ );
+ assertSuperExpression(invocation.target);
+ }
+
+ test_error_abstractSuperMemberReference_mixinHasNoSuchMethod() async {
+ addTestFile('''
+class A {
+ int foo();
+ noSuchMethod(im) => 42;
+}
+
+class B extends Object with A {
+ foo() => super.foo(); // ref
+ noSuchMethod(im) => 87;
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
+
+ var invocation = findNode.methodInvocation('foo(); // ref');
+ assertMethodInvocation(
+ invocation,
+ findElement.method('foo', of: 'A'),
+ '() → int',
+ );
+ assertSuperExpression(invocation.target);
+ }
+
+ test_error_abstractSuperMemberReference_OK_mixinHasConcrete() async {
+ addTestFile('''
+class A {}
+
+class M {
+ void foo(int _) {}
+}
+
+class B = A with M;
+
+class C extends B {
+ void bar() {
+ super.foo(0);
+ }
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var invocation = findNode.methodInvocation('foo(0)');
+ assertMethodInvocation(
+ invocation,
+ findElement.method('foo', of: 'M'),
+ '(int) → void',
+ );
+ assertSuperExpression(invocation.target);
+ }
+
+ test_error_abstractSuperMemberReference_OK_superHasNoSuchMethod() async {
+ addTestFile(r'''
+class A {
+ int foo();
+ noSuchMethod(im) => 42;
+}
+
+class B extends A {
+ int foo() => super.foo(); // ref
+ noSuchMethod(im) => 87;
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var invocation = findNode.methodInvocation('super.foo(); // ref');
+ assertMethodInvocation(
+ invocation,
+ findElement.method('foo', of: 'A'),
+ '() → int',
+ );
+ assertSuperExpression(invocation.target);
+ }
+
+ test_error_abstractSuperMemberReference_OK_superSuperHasConcrete() async {
+ addTestFile('''
+abstract class A {
+ void foo(int _) {}
+}
+
+abstract class B extends A {
+ void foo(int _);
+}
+
+class C extends B {
+ void bar() {
+ super.foo(0);
+ }
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var invocation = findNode.methodInvocation('foo(0)');
+ assertMethodInvocation(
+ invocation,
+ findElement.method('foo', of: 'A'),
+ '(int) → void',
+ );
+ assertSuperExpression(invocation.target);
+ }
+
+ test_error_ambiguousImport_topFunction() async {
+ newFile('/test/lib/a.dart', content: r'''
+void foo(int _) {}
+''');
+ newFile('/test/lib/b.dart', content: r'''
+void foo(int _) {}
+''');
+
+ addTestFile(r'''
+import 'a.dart';
+import 'b.dart';
+
+main() {
+ foo(0);
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticWarningCode.AMBIGUOUS_IMPORT,
+ ]);
+
+ var invocation = findNode.methodInvocation('foo(0)');
+ assertInvokeType(invocation, '(int) → void');
+ assertType(invocation, 'void');
+ }
+
+ test_error_ambiguousImport_topFunction_prefixed() async {
+ newFile('/test/lib/a.dart', content: r'''
+void foo(int _) {}
+''');
+ newFile('/test/lib/b.dart', content: r'''
+void foo(int _) {}
+''');
+
+ addTestFile(r'''
+import 'a.dart' as p;
+import 'b.dart' as p;
+
+main() {
+ p.foo(0);
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticWarningCode.AMBIGUOUS_IMPORT,
+ ]);
+
+ var invocation = findNode.methodInvocation('foo(0)');
+ assertInvokeType(invocation, '(int) → void');
+ assertType(invocation, 'void');
+ }
+
+ test_error_instanceAccessToStaticMember_method() async {
+ addTestFile(r'''
+class A {
+ static void foo(int _) {}
+}
+
+main(A a) {
+ a.foo(0);
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER,
+ ]);
+ _assertInvalidInvocation(
+ 'a.foo(0)',
+ findElement.method('foo'),
+ expectedNameType: '(int) → void',
+ );
+ }
+
+ test_error_invocationOfNonFunction_interface_hasCall_field() async {
+ addTestFile(r'''
+class C {
+ void Function() call;
+}
+
+main(C c) {
+ c();
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION,
+ ]);
+ _assertInvalidInvocation(
+ 'c()',
+ findElement.parameter('c'),
+ );
+ }
+
+ test_error_invocationOfNonFunction_localVariable() async {
+ addTestFile(r'''
+main() {
+ Object foo;
+ foo();
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION,
+ ]);
+ _assertInvalidInvocation(
+ 'foo()',
+ findElement.localVar('foo'),
+ expectedNameType: 'Object',
+ );
+ }
+
+ test_error_invocationOfNonFunction_OK_dynamic_localVariable() async {
+ addTestFile(r'''
+main() {
+ var foo;
+ foo();
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+ _assertInvalidInvocation('foo();', findElement.localVar('foo'));
+ }
+
+ test_error_invocationOfNonFunction_OK_dynamicGetter_instance() async {
+ addTestFile(r'''
+class C {
+ var foo;
+}
+
+main(C c) {
+ c.foo();
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+ _assertInvalidInvocation('c.foo();', findElement.getter('foo'));
+ }
+
+ test_error_invocationOfNonFunction_OK_dynamicGetter_superClass() async {
+ addTestFile(r'''
+class A {
+ var foo;
+}
+
+class B extends A {
+ main() {
+ foo();
+ }
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+ _assertInvalidInvocation('foo();', findElement.getter('foo'));
+ }
+
+ test_error_invocationOfNonFunction_OK_dynamicGetter_thisClass() async {
+ addTestFile(r'''
+class C {
+ var foo;
+
+ main() {
+ foo();
+ }
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+ _assertInvalidInvocation('foo();', findElement.getter('foo'));
+ }
+
+ test_error_invocationOfNonFunction_OK_Function() async {
+ addTestFile(r'''
+f(Function foo) {
+ foo(1, 2);
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+ _assertInvalidInvocation('foo(1, 2);', findElement.parameter('foo'));
+ }
+
+ test_error_invocationOfNonFunction_OK_functionTypeTypeParameter() async {
+ addTestFile(r'''
+typedef MyFunction = double Function(int _);
+
+class C<T extends MyFunction> {
+ T foo;
+
+ main() {
+ foo(0);
+ }
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+ assertMethodInvocation(
+ findNode.methodInvocation('foo(0)'),
+ findElement.getter('foo'),
+ '(int) → double',
+ );
+ }
+
+ test_error_invocationOfNonFunction_static_hasTarget() async {
+ addTestFile(r'''
+class C {
+ static int foo;
+}
+
+main() {
+ C.foo();
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION,
+ ]);
+ _assertInvalidInvocation(
+ 'foo()',
+ findElement.getter('foo'),
+ );
+ }
+
+ test_error_invocationOfNonFunction_static_noTarget() async {
+ addTestFile(r'''
+class C {
+ static int foo;
+
+ main() {
+ foo();
+ }
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION,
+ ]);
+ _assertInvalidInvocation(
+ 'foo()',
+ findElement.getter('foo'),
+ );
+ }
+
+ test_error_invocationOfNonFunction_super_getter() async {
+ addTestFile(r'''
+class A {
+ int get foo => 0;
+}
+
+class B extends A {
+ main() {
+ super.foo();
+ }
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION,
+ ]);
+ _assertInvalidInvocation(
+ 'foo()',
+ findElement.getter('foo'),
+ );
+ }
+
+ test_error_prefixIdentifierNotFollowedByDot() async {
+ newFile('/test/lib/a.dart', content: r'''
+void foo() {}
+''');
+
+ addTestFile(r'''
+import 'a.dart' as prefix;
+
+main() {
+ prefix?.foo();
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
+ ]);
+
+ var import = _importFinder('package:test/a.dart');
+
+ var invocation = findNode.methodInvocation('foo();');
+ assertMethodInvocation(
+ invocation,
+ import.topFunction('foo'),
+ '() → void',
+ );
+ assertImportPrefix(invocation.target, import.prefix);
+ }
+
+ test_error_prefixIdentifierNotFollowedByDot_deferred() async {
+ addTestFile(r'''
+import 'dart:math' deferred as math;
+
+main() {
+ math?.loadLibrary();
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
+ ]);
+
+ var import = _importFinder('dart:math');
+
+ var invocation = findNode.methodInvocation('loadLibrary()');
+ assertMethodInvocation(
+ invocation,
+ import.importedLibrary.loadLibraryFunction,
+ '() → Future<dynamic>',
+ );
+ assertImportPrefix(invocation.target, import.prefix);
+ }
+
+ test_error_prefixIdentifierNotFollowedByDot_invoke() async {
+ addTestFile(r'''
+import 'dart:math' as foo;
+
+main() {
+ foo();
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
+ ]);
+ _assertInvalidInvocation(
+ 'foo()',
+ findElement.import('dart:math').prefix,
+ dynamicNameType: true,
+ );
+ }
+
+ test_error_undefinedFunction() async {
+ addTestFile(r'''
+main() {
+ foo(0);
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticTypeWarningCode.UNDEFINED_FUNCTION,
+ ]);
+ _assertUnresolvedMethodInvocation('foo(0)');
+ }
+
+ test_error_undefinedFunction_hasTarget_importPrefix() async {
+ addTestFile(r'''
+import 'dart:math' as math;
+
+main() {
+ math.foo(0);
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticTypeWarningCode.UNDEFINED_FUNCTION,
+ ]);
+ _assertUnresolvedMethodInvocation('foo(0);');
+ }
+
+ test_error_undefinedIdentifier_target() async {
+ addTestFile(r'''
+main() {
+ bar.foo(0);
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticWarningCode.UNDEFINED_IDENTIFIER,
+ ]);
+ _assertUnresolvedMethodInvocation('foo(0);');
+ }
+
+ test_error_undefinedMethod_hasTarget_class() async {
+ addTestFile(r'''
+class C {}
+main() {
+ C.foo(0);
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticTypeWarningCode.UNDEFINED_METHOD,
+ ]);
+ _assertUnresolvedMethodInvocation('foo(0);');
+ }
+
+ test_error_undefinedMethod_hasTarget_class_arguments() async {
+ addTestFile(r'''
+class C {}
+
+int x;
+main() {
+ C.foo(x);
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticTypeWarningCode.UNDEFINED_METHOD,
+ ]);
+
+ _assertUnresolvedMethodInvocation('foo(x);');
+ assertTopGetRef('x)', 'x');
+ }
+
+ test_error_undefinedMethod_hasTarget_class_inSuperclass() async {
+ addTestFile(r'''
+class S {
+ static void foo(int _) {}
+}
+
+class C extends S {}
+
+main() {
+ C.foo(0);
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticTypeWarningCode.UNDEFINED_METHOD,
+ ]);
+ _assertUnresolvedMethodInvocation('foo(0);');
+ }
+
+ test_error_undefinedMethod_hasTarget_class_typeArguments() async {
+ addTestFile(r'''
+class C {}
+
+main() {
+ C.foo<int>();
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticTypeWarningCode.UNDEFINED_METHOD,
+ ]);
+
+ _assertUnresolvedMethodInvocation('foo<int>();');
+ assertTypeName(findNode.typeName('int>'), intElement, 'int');
+ }
+
+ test_error_undefinedMethod_hasTarget_class_typeParameter() async {
+ addTestFile(r'''
+class C<T> {
+ static main() => C.T();
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticTypeWarningCode.UNDEFINED_METHOD,
+ ]);
+ _assertUnresolvedMethodInvocation('C.T();');
+ }
+
+ test_error_undefinedMethod_hasTarget_instance() async {
+ addTestFile(r'''
+main() {
+ 42.foo(0);
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticTypeWarningCode.UNDEFINED_METHOD,
+ ]);
+ _assertUnresolvedMethodInvocation('foo(0);');
+ }
+
+ test_error_undefinedMethod_hasTarget_localVariable_function() async {
+ addTestFile(r'''
+main() {
+ var v = () {};
+ v.foo(0);
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticTypeWarningCode.UNDEFINED_METHOD,
+ ]);
+ _assertUnresolvedMethodInvocation('foo(0);');
+ }
+
+ test_error_undefinedMethod_noTarget() async {
+ addTestFile(r'''
+class C {
+ main() {
+ foo(0);
+ }
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticTypeWarningCode.UNDEFINED_METHOD,
+ ]);
+ _assertUnresolvedMethodInvocation('foo(0);');
+ }
+
+ test_error_undefinedMethod_object_call() async {
+ addTestFile(r'''
+main(Object o) {
+ o.call();
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticTypeWarningCode.UNDEFINED_METHOD,
+ ]);
+ }
+
+ test_error_undefinedMethod_OK_null() async {
+ addTestFile(r'''
+main() {
+ null.foo();
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+ _assertUnresolvedMethodInvocation('foo();');
+ }
+
+ test_error_undefinedMethod_private() async {
+ newFile('/test/lib/a.dart', content: r'''
+class A {
+ void _foo(int _) {}
+}
+''');
+ addTestFile(r'''
+import 'a.dart';
+
+class B extends A {
+ main() {
+ _foo(0);
+ }
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticTypeWarningCode.UNDEFINED_METHOD,
+ ]);
+ _assertUnresolvedMethodInvocation('_foo(0);');
+ }
+
+ test_error_undefinedMethod_typeLiteral_cascadeTarget() async {
+ addTestFile(r'''
+class C {
+ static void foo() {}
+}
+
+main() {
+ C..foo();
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticTypeWarningCode.UNDEFINED_METHOD,
+ ]);
+ }
+
+ test_error_undefinedMethod_typeLiteral_conditional() async {
+ // When applied to a type literal, the conditional access operator '?.'
+ // cannot be used to access instance methods of Type.
+ addTestFile(r'''
+class A {}
+main() {
+ A?.toString();
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticTypeWarningCode.UNDEFINED_METHOD,
+ ]);
+ }
+
+ test_error_undefinedSuperMethod() async {
+ addTestFile(r'''
+class A {}
+
+class B extends A {
+ void foo(int _) {
+ super.foo(0);
+ }
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticTypeWarningCode.UNDEFINED_SUPER_METHOD,
+ ]);
+ _assertUnresolvedMethodInvocation('foo(0);');
+ assertSuperExpression(findNode.super_('super.foo'));
+ }
+
+ test_error_unqualifiedReferenceToNonLocalStaticMember_method() async {
+ addTestFile(r'''
+class A {
+ static void foo() {}
+}
+
+class B extends A {
+ main() {
+ foo(0);
+ }
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER,
+ ]);
+
+ _assertInvalidInvocation(
+ 'foo(0)',
+ findElement.method('foo'),
+ expectedNameType: '(int) → void',
+ );
+ }
+
+ /// The primary purpose of this test is to ensure that we are only getting a
+ /// single error generated when the only problem is that an imported file
+ /// does not exist.
+ test_error_uriDoesNotExist_prefixed() async {
+ addTestFile(r'''
+import 'missing.dart' as p;
+
+main() {
+ p.foo(1);
+ p.bar(2);
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ CompileTimeErrorCode.URI_DOES_NOT_EXIST,
+ ]);
+ _assertUnresolvedMethodInvocation('foo(1);');
+ _assertUnresolvedMethodInvocation('bar(2);');
+ }
+
+ /// The primary purpose of this test is to ensure that we are only getting a
+ /// single error generated when the only problem is that an imported file
+ /// does not exist.
+ test_error_uriDoesNotExist_show() async {
+ addTestFile(r'''
+import 'missing.dart' show foo, bar;
+
+main() {
+ foo(1);
+ bar(2);
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ CompileTimeErrorCode.URI_DOES_NOT_EXIST,
+ ]);
+ _assertUnresolvedMethodInvocation('foo(1);');
+ _assertUnresolvedMethodInvocation('bar(2);');
+ }
+
+ test_error_useOfVoidResult_name_getter() async {
+ addTestFile(r'''
+class C<T>{
+ T foo;
+}
+
+main(C<void> c) {
+ c.foo();
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticWarningCode.USE_OF_VOID_RESULT,
+ ]);
+ _assertInvalidInvocation(
+ 'c.foo()',
+ findElement.getter('foo'),
+ expectedNameType: 'void',
+ );
+ }
+
+ test_error_useOfVoidResult_name_localVariable() async {
+ addTestFile(r'''
+main() {
+ void foo;
+ foo();
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticWarningCode.USE_OF_VOID_RESULT,
+ ]);
+ _assertInvalidInvocation(
+ 'foo()',
+ findElement.localVar('foo'),
+ expectedNameType: 'void',
+ );
+ }
+
+ test_error_useOfVoidResult_name_topFunction() async {
+ addTestFile(r'''
+void foo() {}
+
+main() {
+ foo()();
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticWarningCode.USE_OF_VOID_RESULT,
+ ]);
+ assertMethodInvocation(
+ findNode.methodInvocation('foo()()'),
+ findElement.topFunction('foo'),
+ '() → void',
+ );
+ }
+
+ test_error_useOfVoidResult_name_topVariable() async {
+ addTestFile(r'''
+void foo;
+
+main() {
+ foo();
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticWarningCode.USE_OF_VOID_RESULT,
+ ]);
+ _assertInvalidInvocation(
+ 'foo()',
+ findElement.topGet('foo'),
+ expectedNameType: 'void',
+ );
+ }
+
+ test_error_useOfVoidResult_receiver() async {
+ addTestFile(r'''
+main() {
+ void foo;
+ foo.toString();
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticWarningCode.USE_OF_VOID_RESULT,
+ ]);
+ // TODO(scheglov) Resolve fully, or don't resolve at all.
+ assertMethodInvocation(
+ findNode.methodInvocation('toString()'),
+ null,
+ '() → String',
+ );
+ }
+
+ test_error_useOfVoidResult_receiver_cascade() async {
+ addTestFile(r'''
+main() {
+ void foo;
+ foo..toString();
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticWarningCode.USE_OF_VOID_RESULT,
+ ]);
+ // TODO(scheglov) Resolve fully, or don't resolve at all.
+ assertMethodInvocation(
+ findNode.methodInvocation('toString()'),
+ null,
+ '() → String',
+ );
+ }
+
+ test_error_useOfVoidResult_receiver_withNull() async {
+ addTestFile(r'''
+main() {
+ void foo;
+ foo?.toString();
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticWarningCode.USE_OF_VOID_RESULT,
+ ]);
+ // TODO(scheglov) Resolve fully, or don't resolve at all.
+ assertMethodInvocation(
+ findNode.methodInvocation('toString()'),
+ null,
+ '() → String',
+ );
+ }
+
+ test_error_wrongNumberOfTypeArgumentsMethod_01() async {
+ addTestFile(r'''
+void foo() {}
+
+main() {
+ foo<int>();
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD,
+ ]);
+ assertMethodInvocation(
+ findNode.methodInvocation('foo<int>()'),
+ findElement.topFunction('foo'),
+ '() → void',
+ );
+ assertTypeName(findNode.typeName('int>'), intElement, 'int');
+ }
+
+ test_error_wrongNumberOfTypeArgumentsMethod_21() async {
+ addTestFile(r'''
+Map<T, U> foo<T extends num, U>() => null;
+
+main() {
+ foo<int>();
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD,
+ ]);
+ assertMethodInvocation(
+ findNode.methodInvocation('foo<int>()'),
+ findElement.topFunction('foo'),
+ '() → Map<num, dynamic>',
+ );
+ assertTypeName(findNode.typeName('int>'), intElement, 'int');
+ }
+
+ test_hasReceiver_class_staticGetter() async {
+ addTestFile(r'''
+class C {
+ static double Function(int) get foo => null;
+}
+
+main() {
+ C.foo(0);
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var invocation = findNode.methodInvocation('foo(0);');
+ assertMethodInvocation(
+ invocation,
+ findElement.getter('foo'),
+ '(int) → double',
+ );
+ assertClassRef(invocation.target, findElement.class_('C'));
+ }
+
+ test_hasReceiver_class_staticMethod() async {
+ addTestFile(r'''
+class C {
+ static void foo(int _) {}
+}
+
+main() {
+ C.foo(0);
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var invocation = findNode.methodInvocation('foo(0);');
+ assertMethodInvocation(
+ invocation,
+ findElement.method('foo'),
+ '(int) → void',
+ );
+ assertClassRef(invocation.target, findElement.class_('C'));
+ }
+
+ test_hasReceiver_deferredImportPrefix_loadLibrary() async {
+ addTestFile(r'''
+import 'dart:math' deferred as math;
+
+main() {
+ math.loadLibrary();
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var import = _importFinder('dart:math');
+
+ var invocation = findNode.methodInvocation('loadLibrary()');
+ assertMethodInvocation(
+ invocation,
+ import.importedLibrary.loadLibraryFunction,
+ '() → Future<dynamic>',
+ );
+ assertImportPrefix(invocation.target, import.prefix);
+ }
+
+ test_hasReceiver_functionTyped_call() async {
+ addTestFile(r'''
+void foo(int _) {}
+
+main() {
+ foo.call(0);
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var invocation = findNode.methodInvocation('call(0)');
+ assertMethodInvocation(
+ invocation,
+ null,
+ '(int) → void',
+ );
+ assertElement(invocation.target, findElement.topFunction('foo'));
+ assertType(invocation.target, '(int) → void');
+ }
+
+ test_hasReceiver_importPrefix_topFunction() async {
+ newFile('/test/lib/a.dart', content: r'''
+T foo<T extends num>(T a, T b) => a;
+''');
+
+ addTestFile(r'''
+import 'a.dart' as prefix;
+
+main() {
+ prefix.foo(1, 2);
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var import = _importFinder('package:test/a.dart');
+
+ var invocation = findNode.methodInvocation('foo(1, 2)');
+ assertMethodInvocation(
+ invocation,
+ import.topFunction('foo'),
+ '(int, int) → int',
+ );
+ assertImportPrefix(invocation.target, import.prefix);
+ }
+
+ test_hasReceiver_importPrefix_topGetter() async {
+ newFile('/test/lib/a.dart', content: r'''
+T Function<T>(T a, T b) get foo => null;
+''');
+
+ addTestFile(r'''
+import 'a.dart' as prefix;
+
+main() {
+ prefix.foo(1, 2);
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var import = _importFinder('package:test/a.dart');
+
+ var invocation = findNode.methodInvocation('foo(1, 2)');
+ assertMethodInvocation(
+ invocation,
+ import.topGetter('foo'),
+ '(int, int) → int',
+ );
+ assertImportPrefix(invocation.target, import.prefix);
+ }
+
+ test_hasReceiver_instance_Function_call_localVariable() async {
+ addTestFile(r'''
+void main() {
+ Function foo;
+
+ foo.call(0);
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+ _assertInvalidInvocation('call(0)', null);
+ }
+
+ test_hasReceiver_instance_Function_call_topVariable() async {
+ addTestFile(r'''
+Function foo;
+
+void main() {
+ foo.call(0);
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+ _assertInvalidInvocation('call(0)', null);
+ }
+
+ test_hasReceiver_instance_getter() async {
+ addTestFile(r'''
+class C {
+ double Function(int) get foo => null;
+}
+
+main(C c) {
+ c.foo(0);
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var invocation = findNode.methodInvocation('foo(0);');
+ assertMethodInvocation(
+ invocation,
+ findElement.getter('foo'),
+ '(int) → double',
+ );
+ }
+
+ test_hasReceiver_instance_method() async {
+ addTestFile(r'''
+class C {
+ void foo(int _) {}
+}
+
+main(C c) {
+ c.foo(0);
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var invocation = findNode.methodInvocation('foo(0);');
+ assertMethodInvocation(
+ invocation,
+ findElement.method('foo'),
+ '(int) → void',
+ );
+ }
+
+ test_hasReceiver_instance_method_issue30552() async {
+ addTestFile(r'''
+abstract class I1 {
+ void foo(int i);
+}
+
+abstract class I2 {
+ void foo(Object o);
+}
+
+abstract class C implements I1, I2 {}
+
+class D extends C {
+ void foo(Object o) {}
+}
+
+void main(C c) {
+ c.foo('hi');
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var invocation = findNode.methodInvocation("foo('hi')");
+ assertMethodInvocation(
+ invocation,
+ findElement.method('foo', of: 'I2'),
+ '(Object) → void',
+ );
+ }
+
+ test_hasReceiver_instance_typeParameter() async {
+ addTestFile(r'''
+class A {
+ void foo(int _) {}
+}
+
+class C<T extends A> {
+ T a;
+
+ main() {
+ a.foo(0);
+ }
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var invocation = findNode.methodInvocation('foo(0);');
+ assertMethodInvocation(
+ invocation,
+ findElement.method('foo'),
+ '(int) → void',
+ );
+ }
+
+ test_hasReceiver_prefixed_class_staticGetter() async {
+ newFile('/test/lib/a.dart', content: r'''
+class C {
+ static double Function(int) get foo => null;
+}
+''');
+
+ addTestFile(r'''
+import 'a.dart' as prefix;
+
+main() {
+ prefix.C.foo(0);
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var import = _importFinder('package:test/a.dart');
+
+ var invocation = findNode.methodInvocation('foo(0)');
+ assertMethodInvocation(
+ invocation,
+ import.class_('C').getGetter('foo'),
+ '(int) → double',
+ );
+
+ PrefixedIdentifier target = invocation.target;
+ assertImportPrefix(target.prefix, import.prefix);
+ assertClassRef(target.identifier, import.class_('C'));
+ }
+
+ test_hasReceiver_prefixed_class_staticMethod() async {
+ newFile('/test/lib/a.dart', content: r'''
+class C {
+ static void foo(int _) => null;
+}
+''');
+
+ addTestFile(r'''
+import 'a.dart' as prefix;
+
+main() {
+ prefix.C.foo(0);
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var import = _importFinder('package:test/a.dart');
+
+ var invocation = findNode.methodInvocation('foo(0)');
+ assertMethodInvocation(
+ invocation,
+ import.class_('C').getMethod('foo'),
+ '(int) → void',
+ );
+
+ PrefixedIdentifier target = invocation.target;
+ assertImportPrefix(target.prefix, import.prefix);
+ assertClassRef(target.identifier, import.class_('C'));
+ }
+
+ test_hasReceiver_super_getter() async {
+ addTestFile(r'''
+class A {
+ double Function(int) get foo => null;
+}
+
+class B extends A {
+ void bar() {
+ super.foo(0);
+ }
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var invocation = findNode.methodInvocation('foo(0);');
+ assertMethodInvocation(
+ invocation,
+ findElement.getter('foo', of: 'A'),
+ '(int) → double',
+ );
+ assertSuperExpression(invocation.target);
+ }
+
+ test_hasReceiver_super_method() async {
+ addTestFile(r'''
+class A {
+ void foo(int _) {}
+}
+
+class B extends A {
+ void foo(int _) {
+ super.foo(0);
+ }
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var invocation = findNode.methodInvocation('foo(0);');
+ assertMethodInvocation(
+ invocation,
+ findElement.method('foo', of: 'A'),
+ '(int) → void',
+ );
+ assertSuperExpression(invocation.target);
+ }
+
+ test_namedArgument() async {
+ addTestFile(r'''
+void foo({int a, bool b}) {}
+
+main() {
+ foo(b: false, a: 0);
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var invocation = findNode.methodInvocation('foo(b:');
+ assertMethodInvocation(
+ invocation,
+ findElement.topFunction('foo'),
+ '({a: int, b: bool}) → void',
+ );
+ assertNamedParameterRef('b: false', 'b');
+ assertNamedParameterRef('a: 0', 'a');
+ }
+
+ test_noReceiver_getter_superClass() async {
+ addTestFile(r'''
+class A {
+ double Function(int) get foo => null;
+}
+
+class B extends A {
+ void bar() {
+ foo(0);
+ }
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var invocation = findNode.methodInvocation('foo(0)');
+ assertMethodInvocation(
+ invocation,
+ findElement.getter('foo'),
+ '(int) → double',
+ );
+ }
+
+ test_noReceiver_getter_thisClass() async {
+ addTestFile(r'''
+class C {
+ double Function(int) get foo => null;
+
+ void bar() {
+ foo(0);
+ }
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var invocation = findNode.methodInvocation('foo(0)');
+ assertMethodInvocation(
+ invocation,
+ findElement.getter('foo'),
+ '(int) → double',
+ );
+ }
+
+ test_noReceiver_importPrefix() async {
+ addTestFile(r'''
+import 'dart:math' as math;
+
+main() {
+ math();
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
+ ]);
+ assertElement(findNode.simple('math()'), findElement.prefix('math'));
+ }
+
+ test_noReceiver_localFunction() async {
+ addTestFile(r'''
+main() {
+ void foo(int _) {}
+
+ foo(0);
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var invocation = findNode.methodInvocation('foo(0)');
+ assertMethodInvocation(
+ invocation,
+ findElement.localFunction('foo'),
+ '(int) → void',
+ );
+ }
+
+ test_noReceiver_localVariable() async {
+ addTestFile(r'''
+main() {
+ void Function(int) foo;
+
+ foo(0);
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var invocation = findNode.methodInvocation('foo(0)');
+ assertMethodInvocation(
+ invocation,
+ findElement.localVar('foo'),
+ '(int) → void',
+ );
+ }
+
+ test_noReceiver_localVariable_call() async {
+ addTestFile(r'''
+class C {
+ void call(int _) {}
+}
+
+main(C c) {
+ c(0);
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var invocation = findNode.methodInvocation('c(0);');
+ assertMethodInvocation(
+ invocation,
+ findElement.parameter('c'),
+ '(int) → void',
+ );
+ }
+
+ test_noReceiver_localVariable_promoted() async {
+ addTestFile(r'''
+main() {
+ var foo;
+ if (foo is void Function(int)) {
+ foo(0);
+ }
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var invocation = findNode.methodInvocation('foo(0)');
+ assertMethodInvocation(
+ invocation,
+ findElement.localVar('foo'),
+ '(int) → void',
+ );
+ }
+
+ test_noReceiver_method_superClass() async {
+ addTestFile(r'''
+class A {
+ void foo(int _) {}
+}
+
+class B extends A {
+ void bar() {
+ foo(0);
+ }
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var invocation = findNode.methodInvocation('foo(0)');
+ assertMethodInvocation(
+ invocation,
+ findElement.method('foo'),
+ '(int) → void',
+ );
+ }
+
+ test_noReceiver_method_thisClass() async {
+ addTestFile(r'''
+class C {
+ void foo(int _) {}
+
+ void bar() {
+ foo(0);
+ }
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var invocation = findNode.methodInvocation('foo(0)');
+ assertMethodInvocation(
+ invocation,
+ findElement.method('foo'),
+ '(int) → void',
+ );
+ }
+
+ test_noReceiver_topFunction() async {
+ addTestFile(r'''
+void foo(int _) {}
+
+main() {
+ foo(0);
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var invocation = findNode.methodInvocation('foo(0)');
+ assertMethodInvocation(
+ invocation,
+ findElement.topFunction('foo'),
+ '(int) → void',
+ );
+ }
+
+ test_noReceiver_topGetter() async {
+ addTestFile(r'''
+double Function(int) get foo => null;
+
+main() {
+ foo(0);
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var invocation = findNode.methodInvocation('foo(0)');
+ assertMethodInvocation(
+ invocation,
+ findElement.topGet('foo'),
+ '(int) → double',
+ );
+ }
+
+ test_noReceiver_topVariable() async {
+ addTestFile(r'''
+void Function(int) foo;
+
+main() {
+ foo(0);
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var invocation = findNode.methodInvocation('foo(0)');
+ assertMethodInvocation(
+ invocation,
+ findElement.topGet('foo'),
+ '(int) → void',
+ );
+ }
+
+ test_objectMethodOnDynamic() async {
+ addTestFile(r'''
+main() {
+ var v;
+ v.toString(42);
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+ _assertUnresolvedMethodInvocation('toString(42);');
+ }
+
+ test_objectMethodOnFunction() async {
+ addTestFile(r'''
+void f() {}
+
+main() {
+ f.toString();
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var invocation = findNode.methodInvocation('toString();');
+ assertMethodInvocation(
+ invocation,
+ typeProvider.objectType.getMethod('toString'),
+ '() → String',
+ );
+ }
+
+ void _assertInvalidInvocation(String search, Element expectedElement,
+ {String expectedNameType, bool dynamicNameType: false}) {
+ var invocation = findNode.methodInvocation(search);
+ if (dynamicNameType) {
+ assertTypeDynamic(invocation.methodName);
+ }
+ // TODO(scheglov) I think `invokeType` should be `null`.
+ assertMethodInvocation(
+ invocation,
+ expectedElement,
+ 'dynamic',
+ expectedNameType: expectedNameType,
+ expectedType: 'dynamic',
+ );
+ }
+
+ void _assertUnresolvedMethodInvocation(String search) {
+ // TODO(scheglov) clean up
+ _assertInvalidInvocation(search, null);
+// var invocation = findNode.methodInvocation(search);
+// assertTypeDynamic(invocation.methodName);
+// // TODO(scheglov) I think `invokeType` should be `null`.
+// assertMethodInvocation(
+// invocation,
+// null,
+// 'dynamic',
+// expectedType: 'dynamic',
+// );
+ }
+
+ _ImportElementFinder _importFinder(String targetUri) {
+ var import = findElement.import(targetUri);
+ return _ImportElementFinder(import);
+ }
+}
+
+class _ImportElementFinder {
+ final ImportElement import;
+
+ _ImportElementFinder(this.import);
+
+ CompilationUnitElement get definingUnit {
+ return importedLibrary.definingCompilationUnit;
+ }
+
+ LibraryElement get importedLibrary => import.importedLibrary;
+
+ PrefixElement get prefix => import.prefix;
+
+ ClassElement class_(String name) {
+ for (var class_ in definingUnit.types) {
+ if (class_.name == name) {
+ return class_;
+ }
+ }
+ fail('Not found class: $name');
+ }
+
+ FunctionElement topFunction(String name) {
+ for (var function in definingUnit.functions) {
+ if (function.name == name) {
+ return function;
+ }
+ }
+ fail('Not found top-level function: $name');
+ }
+
+ PropertyAccessorElement topGetter(String name) {
+ for (var accessor in definingUnit.accessors) {
+ if (accessor.name == name && accessor.isGetter) {
+ return accessor;
+ }
+ }
+ fail('Not found top-level getter: $name');
+ }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/mixin_test.dart b/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
index 40ae57a..bc792f0 100644
--- a/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
@@ -23,7 +23,7 @@
class MixinDriverResolutionTest extends DriverResolutionTest
with MixinResolutionMixin {}
-abstract class MixinResolutionMixin implements ResolutionTest {
+mixin MixinResolutionMixin implements ResolutionTest {
test_accessor_getter() async {
addTestFile(r'''
mixin M {
@@ -1004,6 +1004,28 @@
]);
}
+ test_error_mixinApplicationNoConcreteSuperInvokedMember_OK_hasNSM() async {
+ addTestFile(r'''
+abstract class A {
+ void foo();
+}
+
+mixin M on A {
+ void bar() {
+ super.foo();
+ }
+}
+
+class C implements A {
+ noSuchMethod(_) {}
+}
+
+class X extends C with M {}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+ }
+
test_error_mixinApplicationNoConcreteSuperInvokedMember_OK_inPreviousMixin() async {
addTestFile(r'''
abstract class A {
@@ -1134,6 +1156,30 @@
]);
}
+ test_error_mixinApplicationNotImplementedInterface_noMemberErrors() async {
+ addTestFile(r'''
+class A {
+ void foo() {}
+}
+
+mixin M on A {
+ void bar() {
+ super.foo();
+ }
+}
+
+class C {
+ noSuchMethod(_) {}
+}
+
+class X = C with M;
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ CompileTimeErrorCode.MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE,
+ ]);
+ }
+
test_error_mixinApplicationNotImplementedInterface_OK_0() async {
addTestFile(r'''
mixin M {}
@@ -1268,6 +1314,24 @@
assertInstanceCreation(creation, m, 'M', constructorName: 'named');
}
+ test_error_mixinInstantiate_undefined() async {
+ addTestFile(r'''
+mixin M {}
+
+main() {
+ new M.named();
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ CompileTimeErrorCode.MIXIN_INSTANTIATE,
+ ]);
+
+ var creation = findNode.instanceCreation('M.named();');
+ var m = findElement.mixin('M');
+ assertElement(creation.constructorName.type.name, m);
+ }
+
test_error_onClause_deferredClass() async {
addTestFile(r'''
import 'dart:math' deferred as math;
diff --git a/pkg/analyzer/test/src/dart/resolution/optional_const_test.dart b/pkg/analyzer/test/src/dart/resolution/optional_const_test.dart
index 6b9d107..df32638 100644
--- a/pkg/analyzer/test/src/dart/resolution/optional_const_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/optional_const_test.dart
@@ -22,7 +22,7 @@
class OptionalConstDriverResolutionTest extends DriverResolutionTest
with OptionalConstMixin {}
-abstract class OptionalConstMixin implements ResolutionTest {
+mixin OptionalConstMixin implements ResolutionTest {
Map<String, LibraryElement> libraries = {};
LibraryElement get libraryA => libraries['package:test/a.dart'];
diff --git a/pkg/analyzer/test/src/dart/resolution/property_access_test.dart b/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
new file mode 100644
index 0000000..15dfcee
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/property_access_test.dart
@@ -0,0 +1,105 @@
+// Copyright (c) 2018, 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:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'driver_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(PropertyAccessResolutionTest);
+ });
+}
+
+@reflectiveTest
+class PropertyAccessResolutionTest extends DriverResolutionTest {
+ test_get_error_abstractSuperMemberReference_mixinHasNoSuchMethod() async {
+ addTestFile('''
+class A {
+ int get foo;
+ noSuchMethod(im) => 1;
+}
+
+class B extends Object with A {
+ get foo => super.foo; // ref
+ noSuchMethod(im) => 2;
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
+
+ var access = findNode.propertyAccess('foo; // ref');
+ assertPropertyAccess(access, findElement.getter('foo', of: 'A'), 'int');
+ assertSuperExpression(access.target);
+ }
+
+ test_get_error_abstractSuperMemberReference_OK_superHasNoSuchMethod() async {
+ addTestFile(r'''
+class A {
+ int get foo;
+ noSuchMethod(im) => 1;
+}
+
+class B extends A {
+ get foo => super.foo; // ref
+ noSuchMethod(im) => 2;
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var access = findNode.propertyAccess('super.foo; // ref');
+ assertPropertyAccess(access, findElement.getter('foo', of: 'A'), 'int');
+ assertSuperExpression(access.target);
+ }
+
+ test_set_error_abstractSuperMemberReference_mixinHasNoSuchMethod() async {
+ addTestFile('''
+class A {
+ set foo(int a);
+ noSuchMethod(im) {}
+}
+
+class B extends Object with A {
+ set foo(v) => super.foo = v; // ref
+ noSuchMethod(im) {}
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
+
+ var access = findNode.propertyAccess('foo = v; // ref');
+ assertPropertyAccess(
+ access,
+ findElement.setter('foo', className: 'A'),
+ 'int',
+ );
+ assertSuperExpression(access.target);
+ }
+
+ test_set_error_abstractSuperMemberReference_OK_superHasNoSuchMethod() async {
+ addTestFile(r'''
+class A {
+ set foo(int a);
+ noSuchMethod(im) => 1;
+}
+
+class B extends A {
+ set foo(v) => super.foo = v; // ref
+ noSuchMethod(im) => 2;
+}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+
+ var access = findNode.propertyAccess('foo = v; // ref');
+ assertPropertyAccess(
+ access,
+ findElement.setter('foo', className: 'A'),
+ 'int',
+ );
+ assertSuperExpression(access.target);
+ }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/resolution.dart b/pkg/analyzer/test/src/dart/resolution/resolution.dart
index f6fdc6f..a762eb6 100644
--- a/pkg/analyzer/test/src/dart/resolution/resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/resolution.dart
@@ -29,7 +29,7 @@
final isVoidType = new TypeMatcher<VoidTypeImpl>();
/// Base for resolution tests.
-abstract class ResolutionTest implements ResourceProviderMixin {
+mixin ResolutionTest implements ResourceProviderMixin {
TestAnalysisResult result;
FindNode findNode;
FindElement findElement;
@@ -61,6 +61,16 @@
newFile('/test/lib/test.dart', content: content);
}
+ /// Assert that the given [identifier] is a reference to a class, in the
+ /// form that is not a separate expression, e.g. in a static method
+ /// invocation like `C.staticMethod()`, or a type annotation `C c = null`.
+ void assertClassRef(
+ SimpleIdentifier identifier, ClassElement expectedElement) {
+ assertElement(identifier, expectedElement);
+ // TODO(scheglov) Enforce this.
+// assertTypeNull(identifier);
+ }
+
void assertConstructorElement(
ConstructorElement expected, ConstructorElement actual) {
if (expected is ConstructorMember && actual is ConstructorMember) {
@@ -168,6 +178,11 @@
assertType(ref, type);
}
+ void assertImportPrefix(SimpleIdentifier identifier, PrefixElement element) {
+ assertElement(identifier, element);
+ assertTypeNull(identifier);
+ }
+
void assertInstanceCreation(InstanceCreationExpression creation,
ClassElement expectedClassElement, String expectedType,
{String constructorName,
@@ -232,10 +247,60 @@
expect(actual.baseElement, same(expectedBase));
}
+ void assertMethodInvocation(MethodInvocation invocation,
+ Element expectedElement, String expectedInvokeType,
+ {String expectedNameType, String expectedType}) {
+ // TODO(scheglov) Check for Member.
+ var element = invocation.methodName.staticElement;
+ if (element is Member) {
+ element = (element as Member).baseElement;
+ expect(element, same(expectedElement));
+ } else {
+ assertElement(invocation.methodName, expectedElement);
+ }
+
+ // TODO(scheglov) Should we enforce this?
+// if (expectedNameType == null) {
+// if (expectedElement is ExecutableElement) {
+// expectedNameType = expectedElement.type.displayName;
+// } else if (expectedElement is VariableElement) {
+// expectedNameType = expectedElement.type.displayName;
+// }
+// }
+// assertType(invocation.methodName, expectedNameType);
+
+ assertInvokeType(invocation, expectedInvokeType);
+
+ expectedType ??= _extractReturnType(expectedInvokeType);
+ assertType(invocation, expectedType);
+ }
+
+ void assertPropertyAccess(
+ PropertyAccess access,
+ Element expectedElement,
+ String expectedType,
+ ) {
+ assertElement(access.propertyName, expectedElement);
+ assertType(access, expectedType);
+ }
+
+ void assertNamedParameterRef(String search, String name) {
+ var ref = findNode.simple(search);
+ assertElement(ref, findElement.parameter(name));
+ assertTypeNull(ref);
+ }
+
void assertNoTestErrors() {
assertTestErrors(const <ErrorCode>[]);
}
+ void assertSuperExpression(SuperExpression superExpression) {
+ // TODO(scheglov) I think `super` does not have type itself.
+ // It is just a signal to look for implemented method in the supertype.
+ // With mixins there isn't a type anyway.
+// assertTypeNull(superExpression);
+ }
+
void assertTestErrors(List<ErrorCode> expected) {
assertErrors(result.errors, expected);
}
@@ -332,6 +397,12 @@
}
return element;
}
+
+ static String _extractReturnType(String invokeType) {
+ int arrowIndex = invokeType.indexOf('→');
+ expect(arrowIndex, isNonNegative);
+ return invokeType.substring(arrowIndex + 1).trim();
+ }
}
class TestAnalysisResult {
diff --git a/pkg/analyzer/test/src/dart/resolution/task_resolution.dart b/pkg/analyzer/test/src/dart/resolution/task_resolution.dart
index 7e02ab4..7c84ed2 100644
--- a/pkg/analyzer/test/src/dart/resolution/task_resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/task_resolution.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2018, 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.
@@ -9,15 +9,14 @@
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/source/package_map_resolver.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import '../../../generated/analysis_context_factory.dart';
-import '../../context/mock_sdk.dart';
import 'resolution.dart';
/// Task model based implementation of [ResolutionTest].
-class TaskResolutionTest extends Object
- with ResourceProviderMixin, ResolutionTest {
+class TaskResolutionTest with ResourceProviderMixin, ResolutionTest {
DartSdk sdk;
SourceFactory sourceFactory;
diff --git a/pkg/analyzer/test/src/dart/resolution/test_all.dart b/pkg/analyzer/test/src/dart/resolution/test_all.dart
index f0c2ee6..c52454e 100644
--- a/pkg/analyzer/test/src/dart/resolution/test_all.dart
+++ b/pkg/analyzer/test/src/dart/resolution/test_all.dart
@@ -6,7 +6,8 @@
import 'assignment_test.dart' as assignment_test;
import 'class_test.dart' as class_test;
-import 'optional_const_test.dart' as optional_const_test;
+import 'comment_test.dart' as comment_test;
+import 'constant_test.dart' as constant_test;
import 'enum_test.dart' as enum_test;
import 'for_in_test.dart' as for_in_test;
import 'generic_type_alias_test.dart' as generic_type_alias_test;
@@ -16,13 +17,18 @@
as instance_member_inference_class_test;
import 'instance_member_inference_mixin_test.dart'
as instance_member_inference_mixin_test;
+import 'method_invocation_test.dart' as method_invocation_test;
import 'mixin_test.dart' as mixin_test;
+import 'optional_const_test.dart' as optional_const_test;
+import 'property_access_test.dart' as property_access_test;
import 'top_type_inference_test.dart' as top_type_inference_test;
main() {
defineReflectiveSuite(() {
assignment_test.main();
class_test.main();
+ comment_test.main();
+ constant_test.main();
enum_test.main();
for_in_test.main();
generic_type_alias_test.main();
@@ -30,8 +36,10 @@
instance_creation_test.main();
instance_member_inference_class_test.main();
instance_member_inference_mixin_test.main();
+ method_invocation_test.main();
mixin_test.main();
optional_const_test.main();
+ property_access_test.main();
top_type_inference_test.main();
}, name: 'resolution');
}
diff --git a/pkg/analyzer/test/src/dart/resolution/top_type_inference_test.dart b/pkg/analyzer/test/src/dart/resolution/top_type_inference_test.dart
index 3b6eb93..3c3defe 100644
--- a/pkg/analyzer/test/src/dart/resolution/top_type_inference_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/top_type_inference_test.dart
@@ -24,7 +24,7 @@
class TopTypeInferenceTaskResolutionTest extends TaskResolutionTest
with TopTypeInstanceMixin {}
-abstract class TopTypeInstanceMixin implements ResolutionTest {
+mixin TopTypeInstanceMixin implements ResolutionTest {
test_referenceInstanceVariable_withDeclaredType() async {
addTestFile(r'''
class A {
diff --git a/pkg/analyzer/test/src/dart/sdk/patch_test.dart b/pkg/analyzer/test/src/dart/sdk/patch_test.dart
index 6ffbf04..dd57aa6 100644
--- a/pkg/analyzer/test/src/dart/sdk/patch_test.dart
+++ b/pkg/analyzer/test/src/dart/sdk/patch_test.dart
@@ -5,11 +5,11 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/dart/sdk/patch.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -20,8 +20,7 @@
}
@reflectiveTest
-class SdkPatcherTest {
- MemoryResourceProvider provider = new MemoryResourceProvider();
+class SdkPatcherTest with ResourceProviderMixin {
Folder sdkFolder;
FolderBasedDartSdk sdk;
@@ -29,7 +28,7 @@
RecordingErrorListener listener = new RecordingErrorListener();
void setUp() {
- sdkFolder = provider.getFolder(_p('/sdk'));
+ sdkFolder = getFolder('/sdk');
}
test_class_constructor_append_fail_notPrivate_named() {
@@ -717,12 +716,12 @@
};''');
_createSdk();
var patchPaths = {
- 'dart:test': [_p('/sdk/lib/does_not_exist.dart')]
+ 'dart:test': [convertPath('/sdk/lib/does_not_exist.dart')]
};
- File file = provider.newFile(_p('/sdk/lib/test/test.dart'), '');
+ File file = newFile('/sdk/lib/test/test.dart');
Source source = file.createSource(Uri.parse('dart:test'));
CompilationUnit unit = SdkPatcher.parse(source, listener);
- patcher.patch(provider, patchPaths, listener, source, unit);
+ patcher.patch(resourceProvider, patchPaths, listener, source, unit);
}, throwsArgumentError);
}
@@ -733,16 +732,16 @@
'internal/internal.dart'),
};''');
var patchPaths = {
- 'dart:_internal': [_p('/sdk/lib/internal/internal_patch.dart')]
+ 'dart:_internal': [convertPath('/sdk/lib/internal/internal_patch.dart')]
};
- File file = provider.newFile(_p('/sdk/lib/internal/internal.dart'), r'''
+ File file = newFile('/sdk/lib/internal/internal.dart', content: r'''
library dart._internal;
class A {}
class B {
B();
}
''');
- provider.newFile(_p('/sdk/lib/internal/internal_patch.dart'), r'''
+ newFile(convertPath('/sdk/lib/internal/internal_patch.dart'), content: r'''
@patch
class B {
int newField;
@@ -757,7 +756,7 @@
Source source = file.createSource(Uri.parse('dart:_internal'));
CompilationUnit unit = SdkPatcher.parse(source, listener);
- patcher.patch(provider, patchPaths, listener, source, unit);
+ patcher.patch(resourceProvider, patchPaths, listener, source, unit);
_assertUnitCode(
unit,
'library dart._internal; class A {} '
@@ -782,12 +781,12 @@
patches: {VM_PLATFORM: ['test/test_patch.dart']}),
};''');
var patchPaths = {
- 'dart:test': [_p('/sdk/lib/test/test_patch.dart')]
+ 'dart:test': [convertPath('/sdk/lib/test/test_patch.dart')]
};
- File fileLib = provider.newFile(_p('/sdk/lib/test/test.dart'), baseLibCode);
+ File fileLib = newFile('/sdk/lib/test/test.dart', content: baseLibCode);
File filePart =
- provider.newFile(_p('/sdk/lib/test/test_part.dart'), basePartCode);
- provider.newFile(_p('/sdk/lib/test/test_patch.dart'), r'''
+ newFile('/sdk/lib/test/test_part.dart', content: basePartCode);
+ newFile('/sdk/lib/test/test_patch.dart', content: r'''
import 'foo.dart';
@patch
@@ -809,7 +808,7 @@
Uri uri = Uri.parse('dart:test');
Source source = fileLib.createSource(uri);
CompilationUnit unit = SdkPatcher.parse(source, listener);
- patcher.patch(provider, patchPaths, listener, source, unit);
+ patcher.patch(resourceProvider, patchPaths, listener, source, unit);
_assertUnitCode(
unit,
"library test; part 'test_part.dart'; import 'foo.dart'; "
@@ -820,7 +819,7 @@
Uri uri = Uri.parse('dart:test/test_part.dart');
Source source = filePart.createSource(uri);
CompilationUnit unit = SdkPatcher.parse(source, listener);
- patcher.patch(provider, patchPaths, listener, source, unit);
+ patcher.patch(resourceProvider, patchPaths, listener, source, unit);
_assertUnitCode(unit, "part of test; class B {int _b() => 1;}");
}
}
@@ -1053,7 +1052,7 @@
}
void _createSdk() {
- sdk = new FolderBasedDartSdk(provider, sdkFolder);
+ sdk = new FolderBasedDartSdk(resourceProvider, sdkFolder);
sdk.analysisOptions = new AnalysisOptionsImpl();
}
@@ -1064,24 +1063,24 @@
'test/test.dart'),
};''');
var patchPaths = {
- 'dart:test': [_p('/sdk/lib/test/test_patch.dart')]
+ 'dart:test': [convertPath('/sdk/lib/test/test_patch.dart')]
};
- File file = provider.newFile(_p('/sdk/lib/test/test.dart'), baseCode);
- provider.newFile(_p('/sdk/lib/test/test_patch.dart'), patchCode);
+ File file = newFile('/sdk/lib/test/test.dart', content: baseCode);
+ newFile('/sdk/lib/test/test_patch.dart', content: patchCode);
_createSdk();
Source source = file.createSource(Uri.parse('dart:test'));
CompilationUnit unit = SdkPatcher.parse(source, listener);
- patcher.patch(provider, patchPaths, listener, source, unit);
+ patcher.patch(resourceProvider, patchPaths, listener, source, unit);
return unit;
}
- String _p(String path) => provider.convertPath(path);
-
void _setSdkLibraries(String code) {
- provider.newFile(
- _p('/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart'), code);
+ newFile(
+ '/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart',
+ content: code,
+ );
}
static void _assertPrevNextToken(Token prev, Token next) {
diff --git a/pkg/analyzer/test/src/dart/sdk/sdk_test.dart b/pkg/analyzer/test/src/dart/sdk/sdk_test.dart
index cfc0540..b795f9d 100644
--- a/pkg/analyzer/test/src/dart/sdk/sdk_test.dart
+++ b/pkg/analyzer/test/src/dart/sdk/sdk_test.dart
@@ -110,7 +110,7 @@
}
@reflectiveTest
-class FolderBasedDartSdkTest extends Object with ResourceProviderMixin {
+class FolderBasedDartSdkTest with ResourceProviderMixin {
void test_addExtensions() {
FolderBasedDartSdk sdk = _createDartSdk();
String uri = 'dart:my.internal';
@@ -315,7 +315,7 @@
}
@reflectiveTest
-class SdkExtensionFinderTest extends Object with ResourceProviderMixin {
+class SdkExtensionFinderTest with ResourceProviderMixin {
void setUp() {
newFile('/tmp/_sdkext', content: r'''
{
diff --git a/pkg/analyzer/test/src/fasta/recovery/code_order_test.dart b/pkg/analyzer/test/src/fasta/recovery/code_order_test.dart
index 17b4d06..0958f78 100644
--- a/pkg/analyzer/test/src/fasta/recovery/code_order_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/code_order_test.dart
@@ -1,8 +1,8 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// 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:analyzer/analyzer.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/src/dart/error/syntactic_errors.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -341,14 +341,6 @@
''');
}
- void test_multipleOn() {
- testRecovery('''
-mixin A on B on C {}
-''', [ParserErrorCode.MULTIPLE_ON_CLAUSES], '''
-mixin A on B, C {}
-''');
- }
-
void test_multipleImplements() {
testRecovery('''
mixin A implements B implements C, D {}
@@ -357,6 +349,14 @@
''');
}
+ void test_multipleOn() {
+ testRecovery('''
+mixin A on B on C {}
+''', [ParserErrorCode.MULTIPLE_ON_CLAUSES], '''
+mixin A on B, C {}
+''');
+ }
+
@failingTest
void test_typing_implements() {
testRecovery('''
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/annotation_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/annotation_test.dart
index 06105e3..4087738 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/annotation_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/annotation_test.dart
@@ -41,7 +41,13 @@
[
new TestDescriptor(
'ampersand', '@', [ParserErrorCode.MISSING_IDENTIFIER], '@_s_',
- failing: ['typedef', 'functionNonVoid', 'getter', 'setter']),
+ failing: [
+ 'typedef',
+ 'functionNonVoid',
+ 'getter',
+ 'mixin',
+ 'setter'
+ ]),
new TestDescriptor(
'leftParen', '@a(', [ScannerErrorCode.EXPECTED_TOKEN], '@a()',
allFailing: true),
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart
index e932751..372ed73 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart
@@ -36,7 +36,7 @@
],
'class A extend _s_ {}',
expectedErrorsInValidCode: [ParserErrorCode.EXPECTED_INSTEAD],
- failing: ['functionVoid', 'functionNonVoid', 'getter']),
+ failing: ['functionVoid', 'functionNonVoid', 'getter', 'mixin']),
new TestDescriptor(
'extends',
'class A extends',
@@ -45,7 +45,7 @@
ParserErrorCode.MISSING_CLASS_BODY
],
'class A extends _s_ {}',
- failing: ['functionVoid', 'functionNonVoid', 'getter']),
+ failing: ['functionVoid', 'functionNonVoid', 'getter', 'mixin']),
new TestDescriptor(
'on',
'class A on',
@@ -56,7 +56,7 @@
],
'class A on _s_ {}',
expectedErrorsInValidCode: [ParserErrorCode.EXPECTED_INSTEAD],
- failing: ['functionVoid', 'functionNonVoid', 'getter']),
+ failing: ['functionVoid', 'functionNonVoid', 'getter', 'mixin']),
new TestDescriptor('extendsBody', 'class A extends {}',
[ParserErrorCode.EXPECTED_TYPE_NAME], 'class A extends _s_ {}'),
new TestDescriptor(
@@ -78,7 +78,7 @@
ParserErrorCode.MISSING_CLASS_BODY
],
'class A extends B with _s_ {}',
- failing: ['functionVoid', 'functionNonVoid', 'getter']),
+ failing: ['functionVoid', 'functionNonVoid', 'getter', 'mixin']),
new TestDescriptor(
'extendsNameWithBody',
'class A extends B with {}',
@@ -92,7 +92,7 @@
ParserErrorCode.MISSING_CLASS_BODY
],
'class A extends B implements _s_ {}',
- failing: ['functionVoid', 'functionNonVoid', 'getter']),
+ failing: ['functionVoid', 'functionNonVoid', 'getter', 'mixin']),
new TestDescriptor(
'extendsNameImplementsBody',
'class A extends B implements {}',
@@ -106,7 +106,7 @@
ParserErrorCode.MISSING_CLASS_BODY
],
'class A extends B with C implements _s_ {}',
- failing: ['functionVoid', 'functionNonVoid', 'getter']),
+ failing: ['functionVoid', 'functionNonVoid', 'getter', 'mixin']),
new TestDescriptor(
'extendsNameWithNameImplementsBody',
'class A extends B with C implements {}',
@@ -120,7 +120,7 @@
ParserErrorCode.MISSING_CLASS_BODY
],
'class A implements _s_ {}',
- failing: ['functionVoid', 'functionNonVoid', 'getter']),
+ failing: ['functionVoid', 'functionNonVoid', 'getter', 'mixin']),
new TestDescriptor(
'implementsBody',
'class A implements {}',
@@ -134,7 +134,7 @@
ParserErrorCode.MISSING_CLASS_BODY
],
'class A implements B, _s_ {}',
- failing: ['functionVoid', 'functionNonVoid', 'getter']),
+ failing: ['functionVoid', 'functionNonVoid', 'getter', 'mixin']),
new TestDescriptor(
'implementsNameCommaBody',
'class A implements B, {}',
@@ -149,7 +149,7 @@
ParserErrorCode.EXPECTED_TOKEN
],
'class A = _s_ with _s_;',
- failing: ['functionVoid', 'functionNonVoid', 'getter']),
+ failing: ['functionVoid', 'functionNonVoid', 'getter', 'mixin']),
new TestDescriptor(
'equalsName',
'class A = B',
@@ -164,7 +164,7 @@
ParserErrorCode.EXPECTED_TOKEN
],
'class A = B with _s_;',
- failing: ['functionVoid', 'functionNonVoid', 'getter']),
+ failing: ['functionVoid', 'functionNonVoid', 'getter', 'mixin']),
new TestDescriptor(
'equalsNameName',
'class A = B C',
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/constructor_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/constructor_test.dart
index 3f834fd..d5a265d 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/constructor_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/constructor_test.dart
@@ -1,4 +1,8 @@
-import 'package:analyzer/analyzer.dart';
+// Copyright (c) 2018, 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:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/src/dart/error/syntactic_errors.dart';
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/enum_declaration_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/enum_declaration_test.dart
index 167587a..4f9ccd9 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/enum_declaration_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/enum_declaration_test.dart
@@ -50,6 +50,7 @@
'typedef',
'functionNonVoid',
'getter',
+ 'mixin',
'setter'
]),
new TestDescriptor(
@@ -66,6 +67,7 @@
'typedef',
'functionNonVoid',
'getter',
+ 'mixin',
'setter'
]),
new TestDescriptor('value', 'enum E {a',
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/mixin_declaration_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/mixin_declaration_test.dart
index 33fe03f..f962b3f 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/mixin_declaration_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/mixin_declaration_test.dart
@@ -34,7 +34,7 @@
ParserErrorCode.MISSING_CLASS_BODY
],
'mixin A on _s_ {}',
- failing: ['functionVoid', 'functionNonVoid', 'getter']),
+ failing: ['functionVoid', 'functionNonVoid', 'getter', 'mixin']),
new TestDescriptor(
'extend',
'mixin A extend',
@@ -45,7 +45,7 @@
],
'mixin A extend _s_ {}',
expectedErrorsInValidCode: [ParserErrorCode.EXPECTED_INSTEAD],
- failing: ['functionVoid', 'functionNonVoid', 'getter']),
+ failing: ['functionVoid', 'functionNonVoid', 'getter', 'mixin']),
new TestDescriptor(
'extends',
'mixin A extends',
@@ -56,7 +56,7 @@
],
'mixin A extends _s_ {}',
expectedErrorsInValidCode: [ParserErrorCode.EXPECTED_INSTEAD],
- failing: ['functionVoid', 'functionNonVoid', 'getter']),
+ failing: ['functionVoid', 'functionNonVoid', 'getter', 'mixin']),
new TestDescriptor('onBody', 'mixin A on {}',
[ParserErrorCode.EXPECTED_TYPE_NAME], 'mixin A on _s_ {}'),
new TestDescriptor(
@@ -67,7 +67,7 @@
ParserErrorCode.MISSING_CLASS_BODY
],
'mixin A on B, _s_ {}',
- failing: ['functionVoid', 'functionNonVoid', 'getter']),
+ failing: ['functionVoid', 'functionNonVoid', 'getter', 'mixin']),
new TestDescriptor('onNameCommaBody', 'mixin A on B, {}',
[ParserErrorCode.EXPECTED_TYPE_NAME], 'mixin A on B, _s_ {}'),
new TestDescriptor(
@@ -84,9 +84,9 @@
ParserErrorCode.MISSING_CLASS_BODY
],
'mixin A on B implements _s_ {}',
- failing: ['functionVoid', 'functionNonVoid', 'getter']),
+ failing: ['functionVoid', 'functionNonVoid', 'getter', 'mixin']),
new TestDescriptor(
- 'onNameImplements',
+ 'onNameImplementsBody',
'mixin A on B implements {}',
[ParserErrorCode.EXPECTED_TYPE_NAME],
'mixin A on B implements _s_ {}'),
@@ -98,7 +98,7 @@
ParserErrorCode.MISSING_CLASS_BODY
],
'mixin A implements _s_ {}',
- failing: ['functionVoid', 'functionNonVoid', 'getter']),
+ failing: ['functionVoid', 'functionNonVoid', 'getter', 'mixin']),
new TestDescriptor(
'implementsBody',
'mixin A implements {}',
@@ -112,7 +112,7 @@
ParserErrorCode.MISSING_CLASS_BODY
],
'mixin A implements B, _s_ {}',
- failing: ['functionVoid', 'functionNonVoid', 'getter']),
+ failing: ['functionVoid', 'functionNonVoid', 'getter', 'mixin']),
new TestDescriptor(
'implementsNameCommaBody',
'mixin A implements B, {}',
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/part_of_directive_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/part_of_directive_test.dart
index 17da7bc..680886f 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/part_of_directive_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/part_of_directive_test.dart
@@ -34,7 +34,8 @@
ParserErrorCode.EXPECTED_STRING_LITERAL,
ParserErrorCode.EXPECTED_TOKEN
],
- 'part of "";'),
+ 'part of "";',
+ failing: ['mixin']),
],
nonIdentifierSuffixes);
buildTests(
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/partial_code_support.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/partial_code_support.dart
index 62a722f..8634b8f 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/partial_code_support.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/partial_code_support.dart
@@ -1,8 +1,8 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// 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:analyzer/analyzer.dart';
+import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/src/dart/error/syntactic_errors.dart';
import 'package:test/test.dart';
@@ -46,6 +46,8 @@
*/
static final List<TestSuffix> declarationSuffixes = <TestSuffix>[
new TestSuffix('class', 'class A {}'),
+ new TestSuffix('enum', 'enum E { v }'),
+ new TestSuffix('mixin', 'mixin M {}'),
new TestSuffix('typedef', 'typedef A = B Function(C, D);'),
new TestSuffix('functionVoid', 'void f() {}'),
new TestSuffix('functionNonVoid', 'int f() {}'),
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/top_level_variable_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/top_level_variable_test.dart
index e4cfd56..046e36c 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/top_level_variable_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/top_level_variable_test.dart
@@ -43,7 +43,7 @@
CompileTimeErrorCode.CONST_NOT_INITIALIZED
],
"const a;",
- failing: ['functionNonVoid', 'getter', 'setter'],
+ failing: ['functionNonVoid', 'getter', 'setter', 'mixin'],
expectedErrorsInValidCode: [
CompileTimeErrorCode.CONST_NOT_INITIALIZED
],
@@ -145,7 +145,7 @@
StaticWarningCode.FINAL_NOT_INITIALIZED
],
"final a;",
- failing: ['functionNonVoid', 'getter', 'setter'],
+ failing: ['functionNonVoid', 'getter', 'setter', 'mixin'],
expectedErrorsInValidCode: [
StaticWarningCode.FINAL_NOT_INITIALIZED
],
@@ -193,7 +193,7 @@
'var a',
[ParserErrorCode.EXPECTED_TOKEN],
"var a;",
- failing: ['functionNonVoid', 'getter', 'setter'],
+ failing: ['functionNonVoid', 'getter', 'mixin', 'setter'],
),
new TestDescriptor(
'varNameEquals',
@@ -209,7 +209,9 @@
'functionVoid',
'functionNonVoid',
'const',
+ 'enum',
'getter',
+ 'mixin',
'setter'
],
),
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/typedef_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/typedef_test.dart
index 95f261e..9466494 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/typedef_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/typedef_test.dart
@@ -33,7 +33,7 @@
ParserErrorCode.EXPECTED_TOKEN
],
"typedef T();",
- failing: ['functionNonVoid', 'getter', 'setter']),
+ failing: ['functionNonVoid', 'getter', 'mixin', 'setter']),
new TestDescriptor(
'keywordEquals',
'typedef =',
@@ -56,7 +56,7 @@
expectedErrorsInValidCode: [
ParserErrorCode.INVALID_GENERIC_FUNCTION_TYPE
],
- failing: ['functionVoid', 'functionNonVoid', 'getter']),
+ failing: ['functionVoid', 'functionNonVoid', 'getter', 'mixin']),
],
PartialCodeTest.declarationSuffixes);
}
diff --git a/pkg/analyzer/test/src/hint/sdk_constraint_verifier.dart b/pkg/analyzer/test/src/hint/sdk_constraint_verifier.dart
index ee9f466..ad910f0 100644
--- a/pkg/analyzer/test/src/hint/sdk_constraint_verifier.dart
+++ b/pkg/analyzer/test/src/hint/sdk_constraint_verifier.dart
@@ -3,7 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/error/error.dart';
-import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
+import 'package:pub_semver/pub_semver.dart';
import '../../generated/resolver_test_case.dart';
import '../../generated/test_support.dart';
@@ -15,10 +16,10 @@
verifyVersion(String version, String source,
{List<ErrorCode> errorCodes}) async {
- newFile('/pubspec.yaml', content: '''
-environment:
- sdk: ^$version
-''');
+ driver.configure(
+ analysisOptions: AnalysisOptionsImpl()
+ ..sdkVersionConstraint = VersionConstraint.parse(version));
+
TestAnalysisResult result = await computeTestAnalysisResult(source);
GatheringErrorListener listener = new GatheringErrorListener();
listener.addAll(result.errors);
@@ -28,11 +29,4 @@
listener.assertErrorsWithCodes(errorCodes);
}
}
-
- File newFile(String path, {String content = ''}) {
- // Copied from ResourceProviderMixin because ResolverTestCase does not apply
- // that mixin on this branch.
- String convertedPath = resourceProvider.convertPath(path);
- return resourceProvider.newFile(convertedPath, content);
- }
}
diff --git a/pkg/analyzer/test/src/hint/sdk_version_async_exported_from_core_test.dart b/pkg/analyzer/test/src/hint/sdk_version_async_exported_from_core_test.dart
index 38bf64b..a9f42b6 100644
--- a/pkg/analyzer/test/src/hint/sdk_version_async_exported_from_core_test.dart
+++ b/pkg/analyzer/test/src/hint/sdk_version_async_exported_from_core_test.dart
@@ -69,7 +69,7 @@
test_lessThan_explicitImportOfCore() async {
await verifyVersion('2.0.0', '''
-import 'dart:core';
+import 'dart:core' show Future, int;
Future<int> zero() async => 0;
''', errorCodes: [HintCode.SDK_VERSION_ASYNC_EXPORTED_FROM_CORE]);
@@ -102,4 +102,28 @@
Future<int> zero() async => 0;
''', errorCodes: [HintCode.SDK_VERSION_ASYNC_EXPORTED_FROM_CORE]);
}
+
+ test_lessThan_onlyReferencedInExport_hide() async {
+ await verifyVersion('2.0.0', '''
+export 'dart:async' hide Future;
+''');
+ }
+
+ test_lessThan_onlyReferencedInExport_show() async {
+ await verifyVersion('2.0.0', '''
+export 'dart:async' show Future;
+''');
+ }
+
+ test_lessThan_onlyReferencedInImport_hide() async {
+ await verifyVersion('2.0.0', '''
+import 'dart:core' hide Future;
+''');
+ }
+
+ test_lessThan_onlyReferencedInImport_show() async {
+ await verifyVersion('2.0.0', '''
+import 'dart:core' show Future;
+''');
+ }
}
diff --git a/pkg/analyzer/test/src/lint/linter/linter_context_impl_test.dart b/pkg/analyzer/test/src/lint/linter/linter_context_impl_test.dart
new file mode 100644
index 0000000..49e4be9
--- /dev/null
+++ b/pkg/analyzer/test/src/lint/linter/linter_context_impl_test.dart
@@ -0,0 +1,121 @@
+// Copyright (c) 2018, 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:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/lint/linter.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../../generated/resolver_test_case.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(LinterContextImplTest);
+ });
+}
+
+@reflectiveTest
+class LinterContextImplTest extends ResolverTestCase {
+ String testSource;
+ CompilationUnitImpl testUnit;
+ LinterContextImpl context;
+
+ bool get enableNewAnalysisDriver => true;
+
+ void assertCanBeConst(String snippet, bool expectedResult) {
+ int index = testSource.indexOf(snippet);
+ expect(index >= 0, isTrue);
+ NodeLocator visitor = new NodeLocator(index);
+ AstNodeImpl node = visitor.searchWithin(testUnit);
+ node = node.thisOrAncestorOfType<InstanceCreationExpressionImpl>();
+ expect(node, isNotNull);
+ expect(context.canBeConst(node as InstanceCreationExpressionImpl),
+ expectedResult ? isTrue : isFalse);
+ }
+
+ Future<void> resolve(String sourceText) async {
+ testSource = sourceText;
+ Source source = addNamedSource('/test.dart', sourceText);
+ ResolvedUnitResult analysisResult = await driver.getResult(source.fullName);
+ testUnit = analysisResult.unit;
+ LinterContextUnit contextUnit = new LinterContextUnit(sourceText, testUnit);
+ context = new LinterContextImpl(
+ [contextUnit],
+ contextUnit,
+ analysisResult.session.declaredVariables,
+ analysisResult.typeProvider,
+ analysisResult.typeSystem);
+ }
+
+ void test_canBeConst_false_argument_invocation() async {
+ await resolve('''
+class A {}
+class B {
+ const B(A a);
+}
+A f() => A();
+B g() => B(f());
+''');
+ assertCanBeConst("B(f", false);
+ }
+
+ void test_canBeConst_false_argument_invocationInList() async {
+ await resolve('''
+class A {}
+class B {
+ const B(a);
+}
+A f() => A();
+B g() => B([f()]);
+''');
+ assertCanBeConst("B([", false);
+ }
+
+ void test_canBeConst_false_argument_nonConstConstructor() async {
+ await resolve('''
+class A {}
+class B {
+ const B(A a);
+}
+B f() => B(A());
+''');
+ assertCanBeConst("B(A(", false);
+ }
+
+ void test_canBeConst_false_nonConstConstructor() async {
+ await resolve('''
+class A {}
+A f() => A();
+''');
+ assertCanBeConst("A(", false);
+ }
+
+ void test_canBeConst_true_constConstructorArg() async {
+ await resolve('''
+class A {
+ const A();
+}
+class B {
+ const B(A a);
+}
+B f() => B(A());
+''');
+ assertCanBeConst("B(A(", true);
+ }
+
+ void test_canBeConst_true_constListArg() async {
+ await resolve('''
+class A {
+ const A(List<int> l);
+}
+A f() => A([1, 2, 3]);
+''');
+ assertCanBeConst("A([", true);
+ }
+}
diff --git a/pkg/analyzer/test/src/lint/linter/test_all.dart b/pkg/analyzer/test/src/lint/linter/test_all.dart
new file mode 100644
index 0000000..101588b
--- /dev/null
+++ b/pkg/analyzer/test/src/lint/linter/test_all.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2018, 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:test_reflective_loader/test_reflective_loader.dart';
+
+import 'linter_context_impl_test.dart' as linter_context_impl;
+
+main() {
+ defineReflectiveSuite(() {
+ linter_context_impl.main();
+ }, name: 'linter');
+}
diff --git a/pkg/analyzer/test/src/lint/test_all.dart b/pkg/analyzer/test/src/lint/test_all.dart
index 60555a3..47596f2 100644
--- a/pkg/analyzer/test/src/lint/test_all.dart
+++ b/pkg/analyzer/test/src/lint/test_all.dart
@@ -1,20 +1,21 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'config_test.dart' as config_test;
-import 'io_test.dart' as io_test;
-import 'project_test.dart' as project_test;
-import 'pub_test.dart' as pub_test;
+import 'config_test.dart' as config;
+import 'io_test.dart' as io;
+import 'linter/test_all.dart' as linter;
+import 'project_test.dart' as project;
+import 'pub_test.dart' as pub;
-/// Utility for manually running all tests.
main() {
defineReflectiveSuite(() {
- config_test.main();
- io_test.main();
- project_test.main();
- pub_test.main();
+ config.main();
+ io.main();
+ linter.main();
+ project.main();
+ pub.main();
}, name: 'lint');
}
diff --git a/pkg/analyzer/test/src/options/options_rule_validator_test.dart b/pkg/analyzer/test/src/options/options_rule_validator_test.dart
new file mode 100644
index 0000000..fad56f3
--- /dev/null
+++ b/pkg/analyzer/test/src/options/options_rule_validator_test.dart
@@ -0,0 +1,76 @@
+// Copyright (c) 2018, 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:analyzer/error/error.dart';
+import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/src/lint/linter.dart';
+import 'package:analyzer/src/lint/options_rule_validator.dart';
+import 'package:analyzer/src/string_source.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:yaml/yaml.dart';
+
+import '../../generated/test_support.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(OptionsRuleValidatorTest);
+ });
+}
+
+class DeprecatedLint extends LintRule {
+ DeprecatedLint()
+ : super(
+ name: 'deprecated_lint',
+ group: Group.style,
+ maturity: Maturity.deprecated);
+}
+
+class StableLint extends LintRule {
+ StableLint()
+ : super(
+ name: 'stable_lint', group: Group.style, maturity: Maturity.stable);
+}
+
+@reflectiveTest
+class OptionsRuleValidatorTest extends Object with ResourceProviderMixin {
+ LinterRuleOptionsValidator validator = new LinterRuleOptionsValidator(
+ provider: () => [new DeprecatedLint(), new StableLint()]);
+
+/**
+ * Assert that when the validator is used on the given [content] the
+ * [expectedErrorCodes] are produced.
+ */
+ void assertErrors(String content, List<ErrorCode> expectedErrorCodes) {
+ GatheringErrorListener listener = new GatheringErrorListener();
+ ErrorReporter reporter = new ErrorReporter(
+ listener, new StringSource(content, 'analysis_options.yaml'));
+ validator.validate(reporter, loadYamlNode(content));
+ listener.assertErrorsWithCodes(expectedErrorCodes);
+ }
+
+ test_deprecated_rule() {
+ assertErrors('''
+linter:
+ rules:
+ - deprecated_lint
+ ''', [DEPRECATED_LINT_HINT]);
+ }
+
+ test_stable_rule() {
+ assertErrors('''
+linter:
+ rules:
+ - stable_lint
+ ''', []);
+ }
+
+ test_undefined_rule() {
+ assertErrors('''
+linter:
+ rules:
+ - this_rule_does_not_exist
+ ''', [UNDEFINED_LINT_WARNING]);
+ }
+}
diff --git a/pkg/analyzer/test/src/options/test_all.dart b/pkg/analyzer/test/src/options/test_all.dart
new file mode 100644
index 0000000..e38e167
--- /dev/null
+++ b/pkg/analyzer/test/src/options/test_all.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2018, 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:test_reflective_loader/test_reflective_loader.dart';
+
+import 'options_rule_validator_test.dart' as options_rule_validator;
+
+main() {
+ defineReflectiveSuite(() {
+ options_rule_validator.main();
+ }, name: 'options');
+}
diff --git a/pkg/analyzer/test/src/pubspec/pubspec_validator_test.dart b/pkg/analyzer/test/src/pubspec/pubspec_validator_test.dart
index f841d78..ef1cc99 100644
--- a/pkg/analyzer/test/src/pubspec/pubspec_validator_test.dart
+++ b/pkg/analyzer/test/src/pubspec/pubspec_validator_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// 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.
@@ -20,7 +20,7 @@
}
@reflectiveTest
-class PubspecValidatorTest extends Object with ResourceProviderMixin {
+class PubspecValidatorTest with ResourceProviderMixin {
PubspecValidator validator;
/**
diff --git a/pkg/analyzer/test/src/source/source_resource_test.dart b/pkg/analyzer/test/src/source/source_resource_test.dart
index abf46f6..863117b 100644
--- a/pkg/analyzer/test/src/source/source_resource_test.dart
+++ b/pkg/analyzer/test/src/source/source_resource_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -10,12 +10,11 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/source/source_resource.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../context/mock_sdk.dart';
-
main() {
defineReflectiveSuite(() {
defineReflectiveTests(FileSourceTest);
@@ -23,7 +22,7 @@
}
@reflectiveTest
-class FileSourceTest extends Object with ResourceProviderMixin {
+class FileSourceTest with ResourceProviderMixin {
void test_equals_false_differentFiles() {
File file1 = getFile("/does/not/exist1.dart");
File file2 = getFile("/does/not/exist2.dart");
diff --git a/pkg/analyzer/test/src/summary/expr_builder_test.dart b/pkg/analyzer/test/src/summary/expr_builder_test.dart
index c17d7f8..c7d69df 100644
--- a/pkg/analyzer/test/src/summary/expr_builder_test.dart
+++ b/pkg/analyzer/test/src/summary/expr_builder_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2018, 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.
@@ -27,7 +27,7 @@
/// Mixin containing test cases exercising the [ExprBuilder]. Intended to be
/// applied to a class implementing [ResynthesizeTestStrategy], along with the
/// mixin [ExprBuilderTestHelpers].
-abstract class ExprBuilderTestCases implements ExprBuilderTestHelpers {
+mixin ExprBuilderTestCases implements ExprBuilderTestHelpers {
void test_add() {
checkSimpleExpression('0 + 1');
}
@@ -360,7 +360,7 @@
@failingTest
void test_pushLocalFunctionReference_nested() {
- prepareAnalysisContext(new AnalysisOptionsImpl()..previewDart2 = false);
+ prepareAnalysisContext(new AnalysisOptionsImpl());
var expr =
checkSimpleExpression('(x) => (y) => x + y') as FunctionExpression;
var outerFunctionElement = expr.declaredElement;
@@ -383,7 +383,7 @@
@failingTest
void test_pushLocalFunctionReference_paramReference() {
- prepareAnalysisContext(new AnalysisOptionsImpl()..previewDart2 = false);
+ prepareAnalysisContext(new AnalysisOptionsImpl());
var expr = checkSimpleExpression('(x, y) => x + y') as FunctionExpression;
var localFunctionElement = expr.declaredElement;
var xElement = localFunctionElement.parameters[0];
@@ -478,9 +478,9 @@
}
}
-/// Mixin containing helper methods for testing the [ExprBuilder]. Intended to
+/// Mixin containing helper methods for testing the [ExprBuilder]. Intended to
/// be applied to a class implementing [ResynthesizeTestStrategy].
-abstract class ExprBuilderTestHelpers implements ResynthesizeTestStrategy {
+mixin ExprBuilderTestHelpers implements ResynthesizeTestStrategy {
Expression buildConstructorInitializer(String sourceText,
{String className: 'C',
String initializerName: 'x',
diff --git a/pkg/analyzer/test/src/summary/linker_test.dart b/pkg/analyzer/test/src/summary/linker_test.dart
index 4a6136f..96d7b4d 100644
--- a/pkg/analyzer/test/src/summary/linker_test.dart
+++ b/pkg/analyzer/test/src/summary/linker_test.dart
@@ -26,7 +26,7 @@
/// These test cases may be mixed into any class derived from
/// [SummaryLinkerTestStrategy], allowing the linker to be unit-tested in a
/// variety of ways.
-abstract class LinkerUnitTestCases implements SummaryLinkerTestStrategy {
+mixin LinkerUnitTestCases implements SummaryLinkerTestStrategy {
Matcher get isUndefined => const TypeMatcher<UndefinedElementForLink>();
LibraryElementForLink getLibrary(String uri) {
diff --git a/pkg/analyzer/test/src/summary/package_bundle_reader_test.dart b/pkg/analyzer/test/src/summary/package_bundle_reader_test.dart
index 0709a95..1061dba 100644
--- a/pkg/analyzer/test/src/summary/package_bundle_reader_test.dart
+++ b/pkg/analyzer/test/src/summary/package_bundle_reader_test.dart
@@ -368,7 +368,7 @@
_TestResynthesizerResultProvider(
InternalAnalysisContext context, SummaryDataStore dataStore)
- : super(context, dataStore);
+ : super(context, null, dataStore);
@override
bool hasResultsForSource(Source source) {
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index adbbdba..4995afb 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -25,12 +25,12 @@
import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/resynthesize.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../../generated/test_support.dart';
import '../abstract_single_unit.dart';
-import '../context/abstract_context.dart';
import 'element_text.dart';
import 'test_strategies.dart';
@@ -100,7 +100,7 @@
}
}
- DartSdk createDartSdk() => AbstractContextTest.SHARED_MOCK_SDK;
+ DartSdk createDartSdk() => new MockSdk(resourceProvider: resourceProvider);
/**
* Create the analysis options that should be used for this test.
@@ -117,7 +117,7 @@
/// Mixin containing test cases exercising summary resynthesis. Intended to be
/// applied to a class implementing [ResynthesizeTestStrategy], along with the
/// mixin [ResynthesizeTestHelpers].
-abstract class ResynthesizeTestCases implements ResynthesizeTestHelpers {
+mixin ResynthesizeTestCases implements ResynthesizeTestHelpers {
test_class_abstract() async {
var library = await checkLibrary('abstract class C {}');
checkElementText(library, r'''
@@ -2152,7 +2152,9 @@
checkElementText(library, r'''
class C {
}
-const dynamic V = #invalidConst;
+const dynamic V = const
+ C/*location: test.dart;C*/.
+ named/*location: null*/();
''');
}
@@ -2162,7 +2164,9 @@
const V = const C.named();
''', allowErrors: true);
checkElementText(library, r'''
-const dynamic V = #invalidConst;
+const dynamic V = const
+ C/*location: null*/.
+ named/*location: null*/();
''');
}
@@ -2178,7 +2182,10 @@
''', allowErrors: true);
checkElementText(library, r'''
import 'a.dart' as p;
-const dynamic V = #invalidConst;
+const dynamic V = const
+ p/*location: test.dart;p*/.
+ C/*location: a.dart;C*/.
+ named/*location: null*/();
''');
}
@@ -2191,7 +2198,10 @@
''', allowErrors: true);
checkElementText(library, r'''
import 'a.dart' as p;
-const dynamic V = #invalidConst;
+const dynamic V = const
+ p/*location: test.dart;p*/.
+ C/*location: null*/.
+ named/*location: null*/();
''');
}
@@ -2201,7 +2211,10 @@
const V = const p.C.named();
''', allowErrors: true);
checkElementText(library, r'''
-const dynamic V = #invalidConst;
+const dynamic V = const
+ p/*location: null*/.
+ C/*location: null*/.
+ named/*location: null*/();
''');
}
@@ -2214,7 +2227,9 @@
checkElementText(library, r'''
class C<T> {
}
-const dynamic V = #invalidConst;
+const dynamic V = const
+ C/*location: test.dart;C*/.
+ named/*location: null*/();
''');
}
@@ -2274,7 +2289,8 @@
const V = const C();
''', allowErrors: true);
checkElementText(library, r'''
-const dynamic V = #invalidConst;
+const dynamic V = const
+ C/*location: null*/();
''');
}
@@ -2287,7 +2303,9 @@
''', allowErrors: true);
checkElementText(library, r'''
import 'a.dart' as p;
-const dynamic V = #invalidConst;
+const dynamic V = const
+ p/*location: test.dart;p*/.
+ C/*location: null*/();
''');
}
@@ -2297,7 +2315,9 @@
const V = const p.C();
''', allowErrors: true);
checkElementText(library, r'''
-const dynamic V = #invalidConst;
+const dynamic V = const
+ p/*location: null*/.
+ C/*location: null*/();
''');
}
@@ -2863,7 +2883,8 @@
const V = foo;
''', allowErrors: true);
checkElementText(library, r'''
-const dynamic V = #invalidConst;
+const dynamic V =
+ foo/*location: null*/;
''');
}
@@ -2876,7 +2897,9 @@
checkElementText(library, r'''
class C {
}
-const dynamic V = #invalidConst;
+const dynamic V =
+ C/*location: test.dart;C*/.
+ foo/*location: null*/;
''');
}
@@ -2891,7 +2914,10 @@
''', allowErrors: true);
checkElementText(library, r'''
import 'foo.dart' as p;
-const dynamic V = #invalidConst;
+const dynamic V =
+ p/*location: test.dart;p*/.
+ C/*location: foo.dart;C*/.
+ foo/*location: null*/;
''');
}
@@ -3029,7 +3055,7 @@
const vSuper = super;
''');
checkElementText(library, r'''
-const dynamic vSuper = #invalidConst;
+const dynamic vSuper = super;
''');
}
@@ -3039,7 +3065,7 @@
const vThis = this;
''');
checkElementText(library, r'''
-const dynamic vThis = #invalidConst;
+const dynamic vThis = this;
''');
}
@@ -5145,7 +5171,8 @@
import '';
''');
checkElementText(library, r'''
-@#invalidConst
+@
+ foo/*location: null*/
import '<unresolved>';
''');
}
@@ -5894,7 +5921,10 @@
''');
checkElementText(library, r'''
import 'a.dart' as a;
-@#invalidConst
+@
+ a/*location: test.dart;a*/.
+ C/*location: a.dart;C*/.
+ named/*location: a.dart;C;named*/
class D {
}
''');
@@ -5914,7 +5944,9 @@
''');
checkElementText(library, r'''
import 'a.dart';
-@#invalidConst
+@
+ C/*location: a.dart;C*/.
+ named/*location: a.dart;C;named*/
class D {
}
''');
@@ -5948,7 +5980,8 @@
checkElementText(library, r'''
import 'a.dart';
import 'b.dart';
-dynamic foo([dynamic p = #invalidConst]) {}
+dynamic foo([dynamic p =
+ V/*location: null*/]) {}
''');
}
@@ -5967,7 +6000,8 @@
''');
checkElementText(library, r'''
import 'c.dart';
-dynamic foo([dynamic p = #invalidConst]) {}
+dynamic foo([dynamic p =
+ V/*location: null*/]) {}
''');
}
@@ -5981,7 +6015,8 @@
''');
checkElementText(library, r'''
dynamic V;
-dynamic foo([dynamic p = #invalidConst]) {}
+dynamic foo([dynamic p =
+ V/*location: null*/]) {}
dynamic V() {}
''');
}
@@ -6662,7 +6697,8 @@
shouldCompareLibraryElements = false;
var library = await checkLibrary('f(_) {} @f(42) class C {}');
checkElementText(library, r'''
-@#invalidConst
+@
+ __unresolved__/*location: null*/
class C {
}
dynamic f(dynamic _) {}
@@ -8323,7 +8359,8 @@
class A {
const A(dynamic _);
}
-@#invalidConst
+@
+ A/*location: test.dart;A*/(this)
class C {
}
''');
@@ -8334,7 +8371,9 @@
var library =
await checkLibrary('@foo.bar() class C {}', allowErrors: true);
checkElementText(library, r'''
-@#invalidConst
+@
+ foo/*location: null*/.
+ bar/*location: null*/()
class C {
}
''');
@@ -8345,7 +8384,9 @@
var library =
await checkLibrary('@String.foo() class C {}', allowErrors: true);
checkElementText(library, r'''
-@#invalidConst
+@
+ String/*location: dart:core;String*/.
+ foo/*location: null*/()
class C {
}
''');
@@ -8355,7 +8396,9 @@
shouldCompareLibraryElements = false;
var library = await checkLibrary('@foo.bar class C {}', allowErrors: true);
checkElementText(library, r'''
-@#invalidConst
+@
+ foo/*location: null*/.
+ bar/*location: null*/
class C {
}
''');
@@ -8368,7 +8411,9 @@
allowErrors: true);
checkElementText(library, r'''
import 'dart:async' as foo;
-@#invalidConst
+@
+ foo/*location: test.dart;foo*/.
+ bar/*location: null*/
class C {
}
''');
@@ -8379,7 +8424,10 @@
var library =
await checkLibrary('@foo.bar.baz() class C {}', allowErrors: true);
checkElementText(library, r'''
-@#invalidConst
+@
+ foo/*location: null*/.
+ bar/*location: null*/.
+ baz/*location: null*/()
class C {
}
''');
@@ -8392,7 +8440,10 @@
allowErrors: true);
checkElementText(library, r'''
import 'dart:async' as foo;
-@#invalidConst
+@
+ foo/*location: test.dart;foo*/.
+ bar/*location: null*/.
+ baz/*location: null*/()
class C {
}
''');
@@ -8405,7 +8456,10 @@
allowErrors: true);
checkElementText(library, r'''
import 'dart:async' as foo;
-@#invalidConst
+@
+ foo/*location: test.dart;foo*/.
+ Future/*location: dart:async;Future*/.
+ bar/*location: null*/()
class C {
}
''');
@@ -8416,7 +8470,9 @@
var library =
await checkLibrary('@foo.bar() class C {}', allowErrors: true);
checkElementText(library, r'''
-@#invalidConst
+@
+ foo/*location: null*/.
+ bar/*location: null*/()
class C {
}
''');
@@ -8429,7 +8485,9 @@
allowErrors: true);
checkElementText(library, r'''
import 'dart:async' as foo;
-@#invalidConst
+@
+ foo/*location: test.dart;foo*/.
+ bar/*location: null*/()
class C {
}
''');
@@ -8439,7 +8497,8 @@
shouldCompareLibraryElements = false;
var library = await checkLibrary('@foo class C {}', allowErrors: true);
checkElementText(library, r'''
-@#invalidConst
+@
+ foo/*location: null*/
class C {
}
''');
@@ -8449,7 +8508,8 @@
shouldCompareLibraryElements = false;
var library = await checkLibrary('@foo() class C {}', allowErrors: true);
checkElementText(library, r'''
-@#invalidConst
+@
+ foo/*location: null*/()
class C {
}
''');
@@ -8746,7 +8806,7 @@
/// Mixin containing helper methods for testing summary resynthesis. Intended
/// to be applied to a class implementing [ResynthesizeTestStrategy].
-abstract class ResynthesizeTestHelpers implements ResynthesizeTestStrategy {
+mixin ResynthesizeTestHelpers implements ResynthesizeTestStrategy {
/**
* Names of variables which have initializers that are not valid constants,
* so they are not resynthesized.
@@ -10012,7 +10072,7 @@
TestSummaryResynthesizer(AnalysisContext context, this.unlinkedSummaries,
this.linkedSummaries, this.allowMissingFiles)
- : super(context, context.sourceFactory, true) {
+ : super(context, null, context.sourceFactory, true) {
// Clear after resynthesizing TypeProvider in super().
unlinkedSummariesRequested.clear();
linkedSummariesRequested.clear();
diff --git a/pkg/analyzer/test/src/summary/summary_common.dart b/pkg/analyzer/test/src/summary/summary_common.dart
index 3f1e604..768bc8e 100644
--- a/pkg/analyzer/test/src/summary/summary_common.dart
+++ b/pkg/analyzer/test/src/summary/summary_common.dart
@@ -1,8 +1,7 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2015, 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:analyzer/analyzer.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/dart/scanner/reader.dart';
@@ -79,7 +78,7 @@
/// These test cases may be mixed into any class derived from
/// [SummaryBlackBoxTestStrategy], allowing summary generation to be unit-tested
/// in a variety of ways.
-abstract class SummaryTestCases implements SummaryBlackBoxTestStrategy {
+mixin SummaryTestCases implements SummaryBlackBoxTestStrategy {
/**
* Get access to the linked defining compilation unit.
*/
@@ -796,8 +795,11 @@
* with the given [variableName].
*/
UnlinkedVariable serializeVariableText(String text,
- {String variableName: 'v', bool allowErrors: false}) {
- serializeLibraryText(text, allowErrors: allowErrors);
+ {String variableName: 'v',
+ bool allowErrors: false,
+ bool enableSetLiterals: enableSetLiteralsDefault}) {
+ serializeLibraryText(text,
+ allowErrors: allowErrors, enableSetLiterals: enableSetLiterals);
return findVariable(variableName, failIfAbsent: true);
}
@@ -2836,6 +2838,117 @@
]);
}
+ test_constExpr_makeTypedSet() {
+ UnlinkedVariable variable = serializeVariableText(
+ 'const v = const <int>{11, 22, 33};',
+ enableSetLiterals: true);
+ assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
+ UnlinkedExprOperation.pushInt,
+ UnlinkedExprOperation.pushInt,
+ UnlinkedExprOperation.pushInt,
+ UnlinkedExprOperation.makeTypedSet
+ ], ints: [
+ 11,
+ 22,
+ 33,
+ 3
+ ], referenceValidators: [
+ (EntityRef r) => checkTypeRef(r, 'dart:core', 'int',
+ expectedKind: ReferenceKind.classOrEnum)
+ ]);
+ }
+
+ test_constExpr_makeTypedSet_dynamic() {
+ UnlinkedVariable variable = serializeVariableText(
+ 'const v = const <dynamic>{11, 22, 33};',
+ enableSetLiterals: true);
+ assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
+ UnlinkedExprOperation.pushInt,
+ UnlinkedExprOperation.pushInt,
+ UnlinkedExprOperation.pushInt,
+ UnlinkedExprOperation.makeTypedSet
+ ], ints: [
+ 11,
+ 22,
+ 33,
+ 3
+ ], referenceValidators: [
+ (EntityRef r) => checkDynamicTypeRef(r)
+ ]);
+ }
+
+ test_constExpr_makeTypedSet_functionType() {
+ UnlinkedVariable variable = serializeVariableText(
+ 'final v = <void Function(int)>{};',
+ enableSetLiterals: true);
+ assertUnlinkedConst(variable.initializer.bodyExpr,
+ operators: [UnlinkedExprOperation.makeTypedSet],
+ ints: [
+ 0 // Size of the list
+ ],
+ referenceValidators: [
+ (EntityRef reference) {
+ expect(reference, new TypeMatcher<EntityRef>());
+ expect(reference.entityKind, EntityRefKind.genericFunctionType);
+ expect(reference.syntheticParams, hasLength(1));
+ {
+ final param = reference.syntheticParams[0];
+ expect(param.name, ''); // no name for generic type parameters
+ checkTypeRef(param.type, 'dart:core', 'int',
+ expectedKind: ReferenceKind.classOrEnum);
+ }
+ expect(reference.paramReference, 0);
+ expect(reference.typeParameters, hasLength(0));
+ // TODO(mfairhurst) check this references void
+ expect(reference.syntheticReturnType, isNotNull);
+ }
+ ],
+ forTypeInferenceOnly: true);
+ }
+
+ test_constExpr_makeTypedSet_functionType_withTypeParameters() {
+ UnlinkedVariable variable = serializeVariableText(
+ 'final v = <void Function<T>(Function<Q>(T, Q))>{};',
+ enableSetLiterals: true);
+ assertUnlinkedConst(variable.initializer.bodyExpr,
+ operators: [UnlinkedExprOperation.makeTypedSet],
+ ints: [
+ 0 // Size of the list
+ ],
+ referenceValidators: [
+ (EntityRef reference) {
+ expect(reference, new TypeMatcher<EntityRef>());
+ expect(reference.entityKind, EntityRefKind.genericFunctionType);
+ expect(reference.syntheticParams, hasLength(1));
+ {
+ final param = reference.syntheticParams[0];
+ expect(param.type, new TypeMatcher<EntityRef>());
+ expect(param.type.entityKind, EntityRefKind.genericFunctionType);
+ expect(param.type.syntheticParams, hasLength(2));
+ {
+ final subparam = param.type.syntheticParams[0];
+ expect(
+ subparam.name, ''); // no name for generic type parameters
+ expect(subparam.type, new TypeMatcher<EntityRef>());
+ expect(subparam.type.paramReference, 2);
+ }
+ {
+ final subparam = param.type.syntheticParams[1];
+ expect(
+ subparam.name, ''); // no name for generic type parameters
+ expect(subparam.type, new TypeMatcher<EntityRef>());
+ expect(subparam.type.paramReference, 1);
+ }
+ }
+ expect(reference.paramReference, 0);
+ expect(reference.typeParameters, hasLength(1));
+ // TODO(mfairhurst) check this references void
+ expect(reference.syntheticReturnType, isNotNull);
+ }
+ ],
+ forTypeInferenceOnly: true);
+ }
+
test_constExpr_makeUntypedList() {
UnlinkedVariable variable =
serializeVariableText('const v = const [11, 22, 33];');
@@ -2875,6 +2988,23 @@
]);
}
+ test_constExpr_makeUntypedSet() {
+ UnlinkedVariable variable = serializeVariableText(
+ 'const v = const {11, 22, 33};',
+ enableSetLiterals: true);
+ assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
+ UnlinkedExprOperation.pushInt,
+ UnlinkedExprOperation.pushInt,
+ UnlinkedExprOperation.pushInt,
+ UnlinkedExprOperation.makeUntypedSet
+ ], ints: [
+ 11,
+ 22,
+ 33,
+ 3
+ ]);
+ }
+
test_constExpr_parenthesized() {
UnlinkedVariable variable = serializeVariableText('const v = (1 + 2) * 3;');
assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
@@ -7127,6 +7257,20 @@
forTypeInferenceOnly: true);
}
+ test_expr_makeTypedSet() {
+ UnlinkedVariable variable = serializeVariableText(
+ 'var v = <int>{11, 22, 33};',
+ enableSetLiterals: true);
+ assertUnlinkedConst(variable.initializer.bodyExpr,
+ operators: [UnlinkedExprOperation.makeTypedSet],
+ ints: [0],
+ referenceValidators: [
+ (EntityRef r) => checkTypeRef(r, 'dart:core', 'int',
+ expectedKind: ReferenceKind.classOrEnum)
+ ],
+ forTypeInferenceOnly: true);
+ }
+
test_expr_makeUntypedList() {
UnlinkedVariable variable = serializeVariableText('var v = [11, 22, 33];');
assertUnlinkedConst(variable.initializer.bodyExpr,
@@ -7158,6 +7302,20 @@
forTypeInferenceOnly: true);
}
+ test_expr_makeUntypedSet() {
+ UnlinkedVariable variable =
+ serializeVariableText('var v = {11, 22, 33};', enableSetLiterals: true);
+ assertUnlinkedConst(variable.initializer.bodyExpr,
+ operators: [
+ UnlinkedExprOperation.pushInt,
+ UnlinkedExprOperation.pushInt,
+ UnlinkedExprOperation.pushInt,
+ UnlinkedExprOperation.makeUntypedSet
+ ],
+ ints: [11, 22, 33, 3],
+ forTypeInferenceOnly: true);
+ }
+
test_expr_super() {
UnlinkedVariable variable = serializeVariableText('''
final v = super;
@@ -9640,6 +9798,16 @@
checkDynamicTypeRef(serializeTypeText('dynamic'));
}
+ test_type_inference_based_on_type_parameter() {
+ var class_ = serializeClassText('''
+class C<T> {
+ var field = T;
+}
+''');
+ var field = class_.fields[0];
+ checkLinkedTypeSlot(field.inferredTypeSlot, 'dart:core', 'Type');
+ }
+
test_type_invalid_typeParameter_asPrefix() {
UnlinkedClass c = serializeClassText('''
class C<T> {
diff --git a/pkg/analyzer/test/src/summary/test_strategies.dart b/pkg/analyzer/test/src/summary/test_strategies.dart
index 03c020d..b7b7958 100644
--- a/pkg/analyzer/test/src/summary/test_strategies.dart
+++ b/pkg/analyzer/test/src/summary/test_strategies.dart
@@ -23,10 +23,10 @@
import 'package:analyzer/src/summary/summarize_elements.dart';
import 'package:analyzer/src/task/api/dart.dart';
import 'package:analyzer/src/task/api/general.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:path/path.dart' show posix;
import 'package:test/test.dart';
-import '../context/mock_sdk.dart';
import 'resynthesize_common.dart';
/// Convert the given Posix style file [path] to the corresponding absolute URI.
@@ -35,13 +35,15 @@
return posix.toUri(absolutePath).toString();
}
-CompilationUnit _parseText(String text) {
+CompilationUnit _parseText(String text,
+ {bool enableSetLiterals: enableSetLiteralsDefault}) {
CharSequenceReader reader = new CharSequenceReader(text);
Scanner scanner =
new Scanner(null, reader, AnalysisErrorListener.NULL_LISTENER);
Token token = scanner.tokenize();
- Parser parser = new Parser(
- NonExistingSource.unknown, AnalysisErrorListener.NULL_LISTENER);
+ Parser parser =
+ new Parser(NonExistingSource.unknown, AnalysisErrorListener.NULL_LISTENER)
+ ..enableSetLiterals = enableSetLiterals;
CompilationUnit unit = parser.parseCompilationUnit(token);
unit.lineInfo = new LineInfo(scanner.lineStarts);
return unit;
@@ -257,7 +259,9 @@
try {
Map<String, UnlinkedUnit> uriToUnlinkedUnit = <String, UnlinkedUnit>{};
Map<String, LinkedLibrary> uriToLinkedLibrary = <String, LinkedLibrary>{};
- PackageBundle bundle = new MockSdk().getLinkedBundle();
+ var resourceProvider = new MemoryResourceProvider();
+ PackageBundle bundle =
+ new MockSdk(resourceProvider: resourceProvider).getLinkedBundle();
for (int i = 0; i < bundle.unlinkedUnitUris.length; i++) {
String uri = bundle.unlinkedUnitUris[i];
uriToUnlinkedUnit[uri] = bundle.unlinkedUnits[i];
@@ -327,7 +331,9 @@
/// Serialize the given library [text], then deserialize it and store its
/// summary in [lib].
- void serializeLibraryText(String text, {bool allowErrors: false});
+ void serializeLibraryText(String text,
+ {bool allowErrors: false,
+ bool enableSetLiterals: enableSetLiteralsDefault});
}
/// Implementation of [SummaryBlackBoxTestStrategy] that drives summary
@@ -339,8 +345,11 @@
bool get skipFullyLinkedData => true;
@override
- void serializeLibraryText(String text, {bool allowErrors: false}) {
- super.serializeLibraryText(text, allowErrors: allowErrors);
+ void serializeLibraryText(String text,
+ {bool allowErrors: false,
+ bool enableSetLiterals: enableSetLiteralsDefault}) {
+ super.serializeLibraryText(text,
+ allowErrors: allowErrors, enableSetLiterals: enableSetLiterals);
UnlinkedUnit getPart(String absoluteUri) {
return _linkerInputs.getUnit(absoluteUri);
@@ -531,15 +540,20 @@
return assembler.assemble();
}
- UnlinkedUnitBuilder createUnlinkedSummary(Uri uri, String text) =>
- serializeAstUnlinked(_parseText(text));
+ UnlinkedUnitBuilder createUnlinkedSummary(Uri uri, String text,
+ {bool enableSetLiterals: enableSetLiteralsDefault}) =>
+ serializeAstUnlinked(
+ _parseText(text, enableSetLiterals: enableSetLiterals));
_LinkerInputs _createLinkerInputs(String text,
- {String path: '/test.dart', String uri}) {
+ {String path: '/test.dart',
+ String uri,
+ bool enableSetLiterals: enableSetLiteralsDefault}) {
uri ??= absUri(path);
Uri testDartUri = Uri.parse(uri);
- UnlinkedUnitBuilder unlinkedDefiningUnit =
- createUnlinkedSummary(testDartUri, text);
+ UnlinkedUnitBuilder unlinkedDefiningUnit = createUnlinkedSummary(
+ testDartUri, text,
+ enableSetLiterals: enableSetLiterals);
_filesToLink.uriToUnit[testDartUri.toString()] = unlinkedDefiningUnit;
_LinkerInputs linkerInputs = new _LinkerInputs(
_allowMissingFiles,
@@ -580,9 +594,12 @@
bool get containsNonConstExprs => true;
@override
- void serializeLibraryText(String text, {bool allowErrors: false}) {
+ void serializeLibraryText(String text,
+ {bool allowErrors: false,
+ bool enableSetLiterals: enableSetLiteralsDefault}) {
Map<String, UnlinkedUnitBuilder> uriToUnit = this._filesToLink.uriToUnit;
- _linkerInputs = _createLinkerInputs(text);
+ _linkerInputs =
+ _createLinkerInputs(text, enableSetLiterals: enableSetLiterals);
linked = link(
_linkerInputs.linkedLibraries,
_linkerInputs.getDependency,
diff --git a/pkg/analyzer/test/src/summary/top_level_inference_test.dart b/pkg/analyzer/test/src/summary/top_level_inference_test.dart
index bf6a1bc..ace76cd 100644
--- a/pkg/analyzer/test/src/summary/top_level_inference_test.dart
+++ b/pkg/analyzer/test/src/summary/top_level_inference_test.dart
@@ -4,8 +4,8 @@
import 'dart:async';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/analysis/base.dart';
@@ -366,10 +366,6 @@
@reflectiveTest
class TopLevelInferenceTest extends BaseAnalysisDriverTest {
- void addFile(String path, String code) {
- provider.newFile(_p(path), code);
- }
-
test_initializer_additive() async {
var library = await _encodeDecodeLibrary(r'''
var vPlusIntInt = 1 + 2;
@@ -682,11 +678,11 @@
}
test_initializer_extractProperty_inOtherLibraryCycle() async {
- addFile('/a.dart', r'''
+ newFile('/a.dart', content: r'''
import 'b.dart';
var x = new C().f;
''');
- addFile('/b.dart', r'''
+ newFile('/b.dart', content: r'''
class C {
var f = 0;
}
@@ -2532,8 +2528,7 @@
}
test_method_OK_single_private_linkThroughOtherLibraryOfCycle() async {
- String path = _p('/other.dart');
- provider.newFile(path, r'''
+ newFile('/other.dart', content: r'''
import 'test.dart';
class B extends A2 {}
''');
@@ -2628,11 +2623,9 @@
}
Future<LibraryElement> _encodeDecodeLibrary(String text) async {
- String path = _p('/test.dart');
- provider.newFile(path, text);
+ String path = convertPath('/test.dart');
+ newFile(path, content: text);
UnitElementResult result = await driver.getUnitElement(path);
return result.element.library;
}
-
- String _p(String path) => provider.convertPath(path);
}
diff --git a/pkg/analyzer/test/src/task/dart_test.dart b/pkg/analyzer/test/src/task/dart_test.dart
index a2a0da0..22b79c4 100644
--- a/pkg/analyzer/test/src/task/dart_test.dart
+++ b/pkg/analyzer/test/src/task/dart_test.dart
@@ -3158,9 +3158,7 @@
void _performParseTask(String content) {
if (content == null) {
- source = resourceProvider
- .getFile(resourceProvider.convertPath('/test.dart'))
- .createSource();
+ source = getFile('/test.dart').createSource();
} else {
source = newSource('/test.dart', content);
}
diff --git a/pkg/analyzer/test/src/task/options_test.dart b/pkg/analyzer/test/src/task/options_test.dart
index befc23b..645c950 100644
--- a/pkg/analyzer/test/src/task/options_test.dart
+++ b/pkg/analyzer/test/src/task/options_test.dart
@@ -1,14 +1,17 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2015, 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:mirrors';
-import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/error/error.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/source/error_processor.dart';
import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
+import 'package:analyzer/src/analysis_options/error/option_codes.dart';
+import 'package:analyzer/src/dart/error/hint_codes.dart';
+import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
@@ -193,6 +196,7 @@
removeCode(StrongModeCode.INVALID_CAST_LITERAL);
removeCode(StrongModeCode.INVALID_CAST_LITERAL_LIST);
removeCode(StrongModeCode.INVALID_CAST_LITERAL_MAP);
+ removeCode(StrongModeCode.INVALID_CAST_LITERAL_SET);
removeCode(StrongModeCode.INVALID_CAST_FUNCTION_EXPR);
removeCode(StrongModeCode.INVALID_CAST_NEW_EXPR);
removeCode(StrongModeCode.INVALID_CAST_METHOD);
@@ -486,6 +490,22 @@
new OptionsFileValidator(new TestSource());
final AnalysisOptionsProvider optionsProvider = new AnalysisOptionsProvider();
+ test_analyzer_enableExperiment_badValue() {
+ validate('''
+analyzer:
+ enable-experiment:
+ - not-an-experiment
+ ''', [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITHOUT_VALUES]);
+ }
+
+ test_analyzer_enableExperiment_notAList() {
+ validate('''
+analyzer:
+ enable-experiment:
+ experiment: true
+ ''', [AnalysisOptionsWarningCode.INVALID_SECTION_FORMAT]);
+ }
+
test_analyzer_error_code_supported() {
validate('''
analyzer:
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index 5e74843..4194a0a 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -2134,73 +2134,49 @@
addFile(
'num n; int i; void main() { i = /*info:DOWN_CAST_IMPLICIT*/n;}//yy');
await check();
+
addFile(
'num n; int i; void main() { i = /*error:INVALID_ASSIGNMENT*/n;}//ny');
- await check(implicitCasts: false, declarationCasts: true);
- addFile(
- 'num n; int i; void main() { i = /*info:DOWN_CAST_IMPLICIT*/n;}//yn');
- await check(implicitCasts: true, declarationCasts: false);
- addFile(
- 'num n; int i; void main() { i = /*error:INVALID_ASSIGNMENT*/n;}//nn');
- await check(implicitCasts: false, declarationCasts: false);
+ await check(implicitCasts: false);
}
test_implicitCasts_compoundAssignment() async {
addFile('''f(num n, int i) {
/*info:DOWN_CAST_IMPLICIT_ASSIGN*/i += n;}//yy''');
await check();
+
addFile('''f(num n, int i) {
i += /*error:INVALID_ASSIGNMENT*/n;}//ny''');
- await check(implicitCasts: false, declarationCasts: true);
- addFile('''f(num n, int i) {
- /*info:DOWN_CAST_IMPLICIT_ASSIGN*/i += n;}//yn''');
- await check(implicitCasts: true, declarationCasts: false);
- addFile('''f(num n, int i) {
- i += /*error:INVALID_ASSIGNMENT*/n;}//nn''');
- await check(implicitCasts: false, declarationCasts: false);
+ await check(implicitCasts: false);
}
test_implicitCasts_constructorInitializer() async {
addFile(
'class A { int i; A(num n) : i = /*info:DOWN_CAST_IMPLICIT*/n;}//yy');
await check();
+
addFile(
'class A { int i; A(num n) : i = /*error:FIELD_INITIALIZER_NOT_ASSIGNABLE*/n;}//ny');
- await check(implicitCasts: false, declarationCasts: true);
- addFile(
- 'class A { int i; A(num n) : i = /*info:DOWN_CAST_IMPLICIT*/n;}//yn');
- await check(implicitCasts: true, declarationCasts: false);
- addFile(
- 'class A { int i; A(num n) : i = /*error:FIELD_INITIALIZER_NOT_ASSIGNABLE*/n;}//nn');
- await check(implicitCasts: false, declarationCasts: false);
+ await check(implicitCasts: false);
}
test_implicitCasts_defaultValue() async {
addFile('''const num n = 0;
f({int i = /*info:DOWN_CAST_IMPLICIT*/n}) => i;//yy''');
await check();
+
addFile('''const num n = 0;
f({int i = /*error:INVALID_ASSIGNMENT*/n}) => i;//ny''');
- await check(implicitCasts: false, declarationCasts: true);
- addFile('''const num n = 0;
- f({int i = /*info:DOWN_CAST_IMPLICIT*/n}) => i;//yn''');
- await check(implicitCasts: true, declarationCasts: false);
- addFile('''const num n = 0;
- f({int i = /*error:INVALID_ASSIGNMENT*/n}) => i;//nn''');
- await check(implicitCasts: false, declarationCasts: false);
+ await check(implicitCasts: false);
}
test_implicitCasts_fieldInitializer() async {
addFile('class A { static num n; int i = /*info:ASSIGNMENT_CAST*/n;}//yy');
await check();
- addFile('class A { static num n; int i = /*info:ASSIGNMENT_CAST*/n;}//ny');
- await check(implicitCasts: false, declarationCasts: true);
- addFile(
- 'class A { static num n; int i = /*error:INVALID_ASSIGNMENT*/n;}//yn');
- await check(implicitCasts: true, declarationCasts: false);
+
addFile(
'class A { static num n; int i = /*error:INVALID_ASSIGNMENT*/n;}//nn');
- await check(implicitCasts: false, declarationCasts: false);
+ await check(implicitCasts: false);
}
test_implicitCasts_functionCall() async {
@@ -2208,18 +2184,11 @@
f(int i) => i;
var i = f(/*info:DOWN_CAST_IMPLICIT*/n);//yy''');
await check();
- addFile('''num n;
- f(int i) => i;
- var i = f(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/n);//ny''');
- await check(implicitCasts: false, declarationCasts: true);
- addFile('''num n;
- f(int i) => i;
- var i = f(/*info:DOWN_CAST_IMPLICIT*/n);//yn''');
- await check(implicitCasts: true, declarationCasts: false);
+
addFile('''num n;
f(int i) => i;
var i = f(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/n);//nn''');
- await check(implicitCasts: false, declarationCasts: false);
+ await check(implicitCasts: false);
}
test_implicitCasts_genericMethods() async {
@@ -2232,12 +2201,9 @@
test_implicitCasts_initializer() async {
addFile('num n; int i = /*info:ASSIGNMENT_CAST*/n;//yy');
await check();
- addFile('num n; int i = /*info:ASSIGNMENT_CAST*/n;//ny');
- await check(implicitCasts: false, declarationCasts: true);
- addFile('num n; int i = /*error:INVALID_ASSIGNMENT*/n;//yn');
- await check(implicitCasts: true, declarationCasts: false);
+
addFile('num n; int i = /*error:INVALID_ASSIGNMENT*/n;//nn');
- await check(implicitCasts: false, declarationCasts: false);
+ await check(implicitCasts: false);
}
test_implicitCasts_numericOps() async {
@@ -2257,29 +2223,19 @@
int i;
var r = i & /*info:DOWN_CAST_IMPLICIT*/n;//yy''');
await check();
- addFile('''num n;
- int i;
- var r = i & /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/n;//ny''');
- await check(implicitCasts: false, declarationCasts: true);
- addFile('''num n;
- int i;
- var r = i & /*info:DOWN_CAST_IMPLICIT*/n;//yn''');
- await check(implicitCasts: true, declarationCasts: false);
+
addFile('''num n;
int i;
var r = i & /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/n;//nn''');
- await check(implicitCasts: false, declarationCasts: false);
+ await check(implicitCasts: false);
}
test_implicitCasts_return() async {
addFile('int f(num n) => /*info:DOWN_CAST_IMPLICIT*/n;//yy');
await check();
- addFile('int f(num n) => /*error:RETURN_OF_INVALID_TYPE*/n;//ny');
- await check(implicitCasts: false, declarationCasts: true);
- addFile('int f(num n) => /*info:DOWN_CAST_IMPLICIT*/n;//yn');
- await check(implicitCasts: true, declarationCasts: false);
+
addFile('int f(num n) => /*error:RETURN_OF_INVALID_TYPE*/n;//nn');
- await check(implicitCasts: false, declarationCasts: false);
+ await check(implicitCasts: false);
}
test_implicitCasts_return_async() async {
diff --git a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
index ccef7a7..2991634 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -20,7 +20,7 @@
});
}
-abstract class InferredTypeMixin {
+mixin InferredTypeMixin {
/// Extra top-level errors if needed due to being analyze multiple times.
bool get hasExtraTaskModelPass => true;
@@ -39,9 +39,7 @@
* unit.
*/
Future<CompilationUnit> checkFile(String content,
- {bool declarationCasts: true,
- bool implicitCasts: true,
- bool implicitDynamic: true});
+ {bool implicitCasts: true, bool implicitDynamic: true});
/**
* Add the file, process it (resolve, validate, etc) and return the resolved
@@ -1506,7 +1504,7 @@
Iterable<Map<int, int>> bar() sync* {
yield /*info:INFERRED_TYPE_LITERAL*/{};
yield /*error:YIELD_OF_INVALID_TYPE*/new List();
- yield* /*error:YIELD_OF_INVALID_TYPE*/{};
+ yield* {};
yield* /*info:INFERRED_TYPE_ALLOCATION*/new List();
}
''');
@@ -4484,22 +4482,8 @@
@failingTest
@override
- test_unsafeBlockClosureInference_functionCall_explicitDynamicParam_viaExpr2() async {
- await super
- .test_unsafeBlockClosureInference_functionCall_explicitDynamicParam_viaExpr2();
- }
-
- @failingTest
- @override
test_unsafeBlockClosureInference_functionCall_explicitTypeParam_viaExpr1() {
return super
.test_unsafeBlockClosureInference_functionCall_explicitTypeParam_viaExpr1();
}
-
- @failingTest
- @override
- test_unsafeBlockClosureInference_functionCall_explicitTypeParam_viaExpr2() async {
- await super
- .test_unsafeBlockClosureInference_functionCall_explicitTypeParam_viaExpr2();
- }
}
diff --git a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
index d9e4081..c9c3fcf 100644
--- a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
+++ b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
@@ -25,11 +25,11 @@
import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:source_span/source_span.dart';
import 'package:test/test.dart';
-import '../../context/mock_sdk.dart';
-
SourceSpanWithContext _createSpanHelper(
LineInfo lineInfo, int start, Source source, String content,
{int end}) {
@@ -237,8 +237,7 @@
fail('Checker errors do not match expected errors:\n\n$message');
}
-class AbstractStrongTest {
- MemoryResourceProvider _resourceProvider = new MemoryResourceProvider();
+class AbstractStrongTest with ResourceProviderMixin {
bool _checkCalled = false;
AnalysisContext _context = null;
@@ -266,7 +265,7 @@
/// For a single file, you may also use [checkFile].
void addFile(String content, {String name: '/main.dart'}) {
name = name.replaceFirst('^package:', '/packages/');
- _resourceProvider.newFile(_resourceProvider.convertPath(name), content);
+ newFile(name, content: content);
}
/// Run the checker on a program, staring from '/main.dart', and verifies that
@@ -277,27 +276,23 @@
///
/// Returns the main resolved library. This can be used for further checks.
Future<CompilationUnit> check(
- {bool declarationCasts: true,
- bool implicitCasts: true,
- bool implicitDynamic: true}) async {
+ {bool implicitCasts: true, bool implicitDynamic: true}) async {
_checkCalled = true;
- File mainFile =
- _resourceProvider.getFile(_resourceProvider.convertPath('/main.dart'));
+ File mainFile = getFile('/main.dart');
expect(mainFile.exists, true, reason: '`/main.dart` is missing');
AnalysisOptionsImpl analysisOptions = new AnalysisOptionsImpl();
analysisOptions.strongModeHints = true;
- analysisOptions.declarationCasts = declarationCasts;
analysisOptions.implicitCasts = implicitCasts;
analysisOptions.implicitDynamic = implicitDynamic;
- var mockSdk = new MockSdk(resourceProvider: _resourceProvider);
+ var mockSdk = new MockSdk(resourceProvider: resourceProvider);
mockSdk.context.analysisOptions = analysisOptions;
SourceFactory sourceFactory;
{
- var uriResolver = new _TestUriResolver(_resourceProvider);
+ var uriResolver = new _TestUriResolver(resourceProvider);
sourceFactory =
new SourceFactory([new DartUriResolver(mockSdk), uriResolver]);
}
@@ -311,7 +306,7 @@
_driver = new AnalysisDriver(
scheduler,
log,
- _resourceProvider,
+ resourceProvider,
new MemoryByteStore(),
fileContentOverlay,
null,
@@ -367,14 +362,12 @@
///
/// Also returns the resolved compilation unit.
Future<CompilationUnit> checkFile(String content,
- {bool declarationCasts: true,
- bool implicitCasts: true,
- bool implicitDynamic: true}) async {
+ {bool implicitCasts: true, bool implicitDynamic: true}) async {
addFile(content);
return await check(
- declarationCasts: declarationCasts,
- implicitCasts: implicitCasts,
- implicitDynamic: implicitDynamic);
+ implicitCasts: implicitCasts,
+ implicitDynamic: implicitDynamic,
+ );
}
void setUp() {
diff --git a/pkg/analyzer/test/src/task/yaml_test.dart b/pkg/analyzer/test/src/task/yaml_test.dart
index d952887..4342087 100644
--- a/pkg/analyzer/test/src/task/yaml_test.dart
+++ b/pkg/analyzer/test/src/task/yaml_test.dart
@@ -58,9 +58,9 @@
}
void _performParseTask(String content) {
- var path = resourceProvider.convertPath('/test.yaml');
+ var path = '/test.yaml';
if (content == null) {
- source = resourceProvider.getFile(path).createSource();
+ source = getFile(path).createSource();
} else {
source = newSource(path, content);
}
diff --git a/pkg/analyzer/test/src/test_all.dart b/pkg/analyzer/test/src/test_all.dart
index 369c7b9..20bdbbb 100644
--- a/pkg/analyzer/test/src/test_all.dart
+++ b/pkg/analyzer/test/src/test_all.dart
@@ -9,6 +9,7 @@
import 'dart/test_all.dart' as dart;
import 'fasta/test_all.dart' as fasta;
import 'lint/test_all.dart' as lint;
+import 'options/test_all.dart' as options;
import 'pubspec/test_all.dart' as pubspec;
import 'source/test_all.dart' as source;
import 'summary/test_all.dart' as summary;
@@ -23,6 +24,7 @@
dart.main();
fasta.main();
lint.main();
+ options.main();
pubspec.main();
source.main();
summary.main();
diff --git a/pkg/analyzer/test/generated/bazel_test.dart b/pkg/analyzer/test/src/workspace/bazel_test.dart
similarity index 98%
rename from pkg/analyzer/test/generated/bazel_test.dart
rename to pkg/analyzer/test/src/workspace/bazel_test.dart
index e339b74..2fff988 100644
--- a/pkg/analyzer/test/generated/bazel_test.dart
+++ b/pkg/analyzer/test/src/workspace/bazel_test.dart
@@ -1,10 +1,10 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import 'package:analyzer/src/generated/bazel.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:analyzer/src/workspace/bazel.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -17,7 +17,7 @@
}
@reflectiveTest
-class BazelFileUriResolverTest extends Object with ResourceProviderMixin {
+class BazelFileUriResolverTest with ResourceProviderMixin {
BazelWorkspace workspace;
BazelFileUriResolver resolver;
@@ -97,7 +97,7 @@
}
@reflectiveTest
-class BazelPackageUriResolverTest extends Object with ResourceProviderMixin {
+class BazelPackageUriResolverTest with ResourceProviderMixin {
BazelWorkspace workspace;
BazelPackageUriResolver resolver;
@@ -482,12 +482,12 @@
}
@reflectiveTest
-class BazelWorkspaceTest extends Object with ResourceProviderMixin {
+class BazelWorkspaceTest with ResourceProviderMixin {
void test_find_fail_notAbsolute() {
expect(
() =>
BazelWorkspace.find(resourceProvider, convertPath('not_absolute')),
- throwsArgumentError);
+ throwsA(const TypeMatcher<AssertionError>()));
}
void test_find_hasReadonlyFolder() {
diff --git a/pkg/analyzer/test/generated/gn_test.dart b/pkg/analyzer/test/src/workspace/gn_test.dart
similarity index 96%
rename from pkg/analyzer/test/generated/gn_test.dart
rename to pkg/analyzer/test/src/workspace/gn_test.dart
index 46ff4ea..99e3c00 100644
--- a/pkg/analyzer/test/generated/gn_test.dart
+++ b/pkg/analyzer/test/src/workspace/gn_test.dart
@@ -1,9 +1,9 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// 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:analyzer/src/generated/gn.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:analyzer/src/workspace/gn.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -14,7 +14,7 @@
}
@reflectiveTest
-class GnWorkspaceTest extends Object with ResourceProviderMixin {
+class GnWorkspaceTest with ResourceProviderMixin {
void test_find_noJiriRoot() {
newFolder('/workspace');
GnWorkspace workspace =
@@ -33,7 +33,7 @@
void test_find_notAbsolute() {
expect(
() => GnWorkspace.find(resourceProvider, convertPath('not_absolute')),
- throwsArgumentError);
+ throwsA(const TypeMatcher<AssertionError>()));
}
void test_find_withRoot() {
diff --git a/pkg/analyzer/test/generated/package_build_test.dart b/pkg/analyzer/test/src/workspace/package_build_test.dart
similarity index 96%
rename from pkg/analyzer/test/generated/package_build_test.dart
rename to pkg/analyzer/test/src/workspace/package_build_test.dart
index 81b7d35..9f7d917 100644
--- a/pkg/analyzer/test/generated/package_build_test.dart
+++ b/pkg/analyzer/test/src/workspace/package_build_test.dart
@@ -1,12 +1,12 @@
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2018, 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:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/context/builder.dart';
-import 'package:analyzer/src/generated/package_build.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:analyzer/src/workspace/package_build.dart';
import 'package:package_config/packages.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -46,8 +46,7 @@
}
@reflectiveTest
-class PackageBuildFileUriResolverTest extends Object
- with ResourceProviderMixin {
+class PackageBuildFileUriResolverTest with ResourceProviderMixin {
PackageBuildWorkspace workspace;
PackageBuildFileUriResolver resolver;
@@ -116,16 +115,14 @@
uri);
}
- Source _resolvePath(String absolutePosixPath) {
- String absolutePath = resourceProvider.convertPath(absolutePosixPath);
- Uri uri = resourceProvider.pathContext.toUri(absolutePath);
+ Source _resolvePath(String path) {
+ Uri uri = toUri(path);
return resolver.resolveAbsolute(uri);
}
}
@reflectiveTest
-class PackageBuildPackageUriResolverTest extends Object
- with ResourceProviderMixin {
+class PackageBuildPackageUriResolverTest with ResourceProviderMixin {
PackageBuildWorkspace workspace;
PackageBuildPackageUriResolver resolver;
MockUriResolver packageUriResolver;
@@ -230,7 +227,7 @@
}
@reflectiveTest
-class PackageBuildWorkspaceTest extends Object with ResourceProviderMixin {
+class PackageBuildWorkspaceTest with ResourceProviderMixin {
void test_builtFile_currentProject() {
newFolder('/workspace/.dart_tool/build');
newFileWithBytes('/workspace/pubspec.yaml', 'name: project'.codeUnits);
@@ -273,7 +270,7 @@
expect(
() => PackageBuildWorkspace.find(resourceProvider,
convertPath('not_absolute'), new MockContextBuilder()),
- throwsArgumentError);
+ throwsA(const TypeMatcher<AssertionError>()));
}
void test_find_hasDartToolAndPubspec() {
diff --git a/pkg/analyzer/test/src/workspace/test_all.dart b/pkg/analyzer/test/src/workspace/test_all.dart
new file mode 100644
index 0000000..351175b
--- /dev/null
+++ b/pkg/analyzer/test/src/workspace/test_all.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'bazel_test.dart' as bazel_test;
+import 'gn_test.dart' as gn_test;
+import 'package_build_test.dart' as package_build_test;
+
+main() {
+ defineReflectiveSuite(() {
+ bazel_test.main();
+ gn_test.main();
+ package_build_test.main();
+ }, name: 'workspace');
+}
diff --git a/pkg/analyzer/tool/task_dependency_graph/generate.dart b/pkg/analyzer/tool/task_dependency_graph/generate.dart
index 739ac6c..3a9aa7b 100644
--- a/pkg/analyzer/tool/task_dependency_graph/generate.dart
+++ b/pkg/analyzer/tool/task_dependency_graph/generate.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2015, 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.
@@ -19,13 +19,18 @@
import 'dart:io' hide File;
import 'dart:io' as io;
-import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/codegen/tools.dart';
import 'package:analyzer/src/context/builder.dart';
+import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
+import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/constant.dart';
@@ -35,9 +40,6 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/source/package_map_resolver.dart';
-import 'package:analyzer/src/dart/analysis/byte_store.dart';
-import 'package:analyzer/src/dart/analysis/performance_logger.dart';
-import 'package:analyzer/src/codegen/tools.dart';
import 'package:front_end/src/testing/package_root.dart' as package_root;
import 'package:path/path.dart' as path;
import 'package:path/path.dart';
diff --git a/pkg/analyzer_cli/lib/src/analyzer_impl.dart b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
index 1974fc4..e36008f 100644
--- a/pkg/analyzer_cli/lib/src/analyzer_impl.dart
+++ b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
@@ -7,6 +7,7 @@
import 'dart:async';
import 'dart:io';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/exception/exception.dart';
diff --git a/pkg/analyzer_cli/lib/src/build_mode.dart b/pkg/analyzer_cli/lib/src/build_mode.dart
index 206341a..5228897 100644
--- a/pkg/analyzer_cli/lib/src/build_mode.dart
+++ b/pkg/analyzer_cli/lib/src/build_mode.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2015, 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.
@@ -9,10 +9,14 @@
import 'dart:isolate';
import 'package:analyzer/dart/analysis/declared_variables.dart';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/dart/analysis/byte_store.dart';
+import 'package:analyzer/src/dart/analysis/cache.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
+import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
@@ -35,9 +39,6 @@
import 'package:bazel_worker/bazel_worker.dart';
import 'package:collection/collection.dart';
import 'package:convert/convert.dart';
-import 'package:analyzer/src/dart/analysis/byte_store.dart';
-import 'package:analyzer/src/dart/analysis/performance_logger.dart';
-import 'package:analyzer/src/dart/analysis/cache.dart';
/**
* Persistent Bazel worker.
@@ -58,14 +59,6 @@
resourceProvider, logger, 256 * 1024 * 1024);
}
- factory AnalyzerWorkerLoop.std(ResourceProvider resourceProvider,
- {io.Stdin stdinStream, io.Stdout stdoutStream, String dartSdkPath}) {
- AsyncWorkerConnection connection = new StdAsyncWorkerConnection(
- inputStream: stdinStream, outputStream: stdoutStream);
- return new AnalyzerWorkerLoop(resourceProvider, connection,
- dartSdkPath: dartSdkPath);
- }
-
factory AnalyzerWorkerLoop.sendPort(
ResourceProvider resourceProvider, SendPort sendPort,
{String dartSdkPath}) {
@@ -75,6 +68,14 @@
dartSdkPath: dartSdkPath);
}
+ factory AnalyzerWorkerLoop.std(ResourceProvider resourceProvider,
+ {io.Stdin stdinStream, io.Stdout stdoutStream, String dartSdkPath}) {
+ AsyncWorkerConnection connection = new StdAsyncWorkerConnection(
+ inputStream: stdinStream, outputStream: stdoutStream);
+ return new AnalyzerWorkerLoop(resourceProvider, connection,
+ dartSdkPath: dartSdkPath);
+ }
+
/**
* Performs analysis with given [options].
*/
@@ -174,7 +175,7 @@
/**
* Analyzer used when the "--build-mode" option is supplied.
*/
-class BuildMode extends Object with HasContextMixin {
+class BuildMode with HasContextMixin {
final ResourceProvider resourceProvider;
final CommandLineOptions options;
final AnalysisStats stats;
diff --git a/pkg/analyzer_cli/lib/src/context_cache.dart b/pkg/analyzer_cli/lib/src/context_cache.dart
index 0e875ce..3c2abe1 100644
--- a/pkg/analyzer_cli/lib/src/context_cache.dart
+++ b/pkg/analyzer_cli/lib/src/context_cache.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2018, 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.
@@ -87,15 +87,16 @@
/// automatically.
AnalysisOptionsImpl _getAnalysisOptions() {
AnalysisOptionsImpl contextOptions = builder.getAnalysisOptions(
- requestedSourceDirectory,
- verbosePrint: clOptions.verbose ? verbosePrint : null);
+ requestedSourceDirectory,
+ verbosePrint: clOptions.verbose ? verbosePrint : null)
+ as AnalysisOptionsImpl;
contextOptions.trackCacheDependencies = false;
contextOptions.disableCacheFlushing = clOptions.disableCacheFlushing;
+ contextOptions.enabledExperiments = clOptions.enabledExperiments;
contextOptions.hint = !clOptions.disableHints;
contextOptions.generateImplicitErrors = clOptions.showPackageWarnings;
contextOptions.generateSdkErrors = clOptions.showSdkWarnings;
- contextOptions.previewDart2 = clOptions.previewDart2;
contextOptions.useFastaParser = clOptions.useFastaParser;
return contextOptions;
}
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index 63ed79f..b5715bd 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2015, 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.
@@ -93,7 +93,7 @@
_analytics = replacementAnalytics;
}
-class Driver extends Object with HasContextMixin implements CommandLineStarter {
+class Driver with HasContextMixin implements CommandLineStarter {
static final PerformanceTag _analyzeAllTag =
new PerformanceTag("Driver._analyzeAll");
@@ -479,7 +479,7 @@
AnalysisOptions analysisOptions) {
// Create a custom package resolver if one has been specified.
if (packageResolverProvider != null) {
- file_system.Folder folder = resourceProvider.getResource('.');
+ file_system.Folder folder = resourceProvider.getFolder('.');
UriResolver resolver = packageResolverProvider(folder);
if (resolver != null) {
// TODO(brianwilkerson) This doesn't handle sdk extensions.
diff --git a/pkg/analyzer_cli/lib/src/error_formatter.dart b/pkg/analyzer_cli/lib/src/error_formatter.dart
index 0c84618..e5ca66b 100644
--- a/pkg/analyzer_cli/lib/src/error_formatter.dart
+++ b/pkg/analyzer_cli/lib/src/error_formatter.dart
@@ -262,7 +262,7 @@
void formatError(
Map<AnalysisError, LineInfo> errorToLine, AnalysisError error) {
Source source = error.source;
- CharacterLocation location = errorToLine[error].getLocation(error.offset);
+ var location = errorToLine[error].getLocation(error.offset);
ErrorSeverity severity = _severityProcessor(error);
@@ -323,7 +323,7 @@
void formatError(
Map<AnalysisError, LineInfo> errorToLine, AnalysisError error) {
Source source = error.source;
- CharacterLocation location = errorToLine[error].getLocation(error.offset);
+ var location = errorToLine[error].getLocation(error.offset);
int length = error.length;
ErrorSeverity severity = _severityProcessor(error);
diff --git a/pkg/analyzer_cli/lib/src/options.dart b/pkg/analyzer_cli/lib/src/options.dart
index 640fd1a..6b4215b 100644
--- a/pkg/analyzer_cli/lib/src/options.dart
+++ b/pkg/analyzer_cli/lib/src/options.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2015, 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.
@@ -7,6 +7,7 @@
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/src/command_line/arguments.dart';
import 'package:analyzer/src/context/builder.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/util/sdk.dart';
import 'package:analyzer_cli/src/ansi.dart' as ansi;
import 'package:analyzer_cli/src/driver.dart';
@@ -35,9 +36,6 @@
/// Analyzer commandline configuration options.
class CommandLineOptions {
- /// Whether declaration casts are enabled (in strong mode)
- final bool declarationCasts;
-
/// The path to output analysis results when in build mode.
final String buildAnalysisOutput;
@@ -93,6 +91,9 @@
/// Whether to display version information
final bool displayVersion;
+ /// A list of the names of the experiments that are to be enabled.
+ final List<String> enabledExperiments;
+
/// Whether to ignore unrecognized flags
final bool ignoreUnrecognizedFlags;
@@ -176,12 +177,11 @@
contextBuilderOptions = createContextBuilderOptions(args),
dartSdkPath = cast(args['dart-sdk']),
dartSdkSummaryPath = cast(args['dart-sdk-summary']),
- declarationCasts = args.wasParsed(declarationCastsFlag)
- ? cast(args[declarationCastsFlag])
- : cast(args[implicitCastsFlag]),
disableCacheFlushing = cast(args['disable-cache-flushing']),
disableHints = cast(args['no-hints']),
displayVersion = cast(args['version']),
+ enabledExperiments =
+ cast(args['enable-experiment'] ?? const <String>[]),
ignoreUnrecognizedFlags = cast(args['ignore-unrecognized-flags']),
lints = cast(args[lintsFlag]),
log = cast(args['log']),
@@ -219,11 +219,6 @@
String get packageRootPath =>
contextBuilderOptions.defaultPackagesDirectoryPath;
- /// Whether to enable the Dart 2.0 Preview.
- ///
- /// This flag is deprecated and hard-coded to `true`.
- bool get previewDart2 => true;
-
/// The source files to analyze
List<String> get sourceFiles => _sourceFiles;
@@ -338,6 +333,11 @@
help: 'Print the analyzer version.',
defaultsTo: false,
negatable: false)
+ ..addMultiOption('enable-experiment',
+ help:
+ 'Enable one or more experimental features. If multiple features '
+ 'are being added, they should be comma separated.',
+ splitCommas: true)
..addFlag('no-hints',
help: 'Do not show hint results.',
defaultsTo: false,
@@ -592,6 +592,23 @@
'Note: the --strong flag is deprecated and will be removed in an '
'future release.\n');
}
+ if (results.wasParsed('enable-experiment')) {
+ List<String> names =
+ (results['enable-experiment'] as List).cast<String>().toList();
+ for (String knownName in Experiments.activeExperimentNames) {
+ names.remove(knownName);
+ }
+ if (names.isNotEmpty) {
+ StringBuffer buffer = new StringBuffer();
+ for (String invalidName in names) {
+ if (buffer.length > 0) {
+ buffer.write(', ');
+ }
+ buffer.write(invalidName);
+ }
+ errorSink.writeln('Unknown experiments: $buffer');
+ }
+ }
return new CommandLineOptions._fromArgs(results);
} on FormatException catch (e) {
diff --git a/pkg/analyzer_cli/test/all.dart b/pkg/analyzer_cli/test/all.dart
index b5015f7..a16799b 100644
--- a/pkg/analyzer_cli/test/all.dart
+++ b/pkg/analyzer_cli/test/all.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2015, 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.
@@ -6,7 +6,6 @@
import 'build_mode_test.dart' as build_mode_test;
import 'driver_test.dart' as driver_test;
import 'embedder_test.dart' as embedder_test;
-import 'error_test.dart' as error_test;
import 'errors_reported_once_test.dart' as errors_reported_once_test;
import 'errors_upgrade_fails_cli_test.dart' as errors_upgrade_fails_cli_test;
import 'options_test.dart' as options_test;
@@ -21,7 +20,6 @@
build_mode_test.main();
driver_test.main();
embedder_test.main();
- error_test.main();
errors_reported_once_test.main();
errors_upgrade_fails_cli_test.main();
options_test.main();
diff --git a/pkg/analyzer_cli/test/driver_test.dart b/pkg/analyzer_cli/test/driver_test.dart
index cb85943..7b205a1 100644
--- a/pkg/analyzer_cli/test/driver_test.dart
+++ b/pkg/analyzer_cli/test/driver_test.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2015, 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.
@@ -952,15 +952,11 @@
}
void _expectUndefinedClassErrorsWithoutExclusions() {
- bool isStrong = usePreviewDart2 || new AnalysisOptionsImpl().previewDart2;
- final String issueType = isStrong ? 'error' : 'warning';
expect(bulletToDash(outSink),
- contains("$issueType - Undefined class 'IncludedUndefinedClass'"));
- expect(
- bulletToDash(outSink),
- isNot(
- contains("$issueType - Undefined class 'ExcludedUndefinedClass'")));
- expect(outSink.toString(), contains("1 $issueType found."));
+ contains("error - Undefined class 'IncludedUndefinedClass'"));
+ expect(bulletToDash(outSink),
+ isNot(contains("error - Undefined class 'ExcludedUndefinedClass'")));
+ expect(outSink.toString(), contains("1 error found."));
}
}
diff --git a/pkg/analyzer_cli/test/error_test.dart b/pkg/analyzer_cli/test/error_test.dart
deleted file mode 100644
index c8d1d0f..0000000
--- a/pkg/analyzer_cli/test/error_test.dart
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library analyzer_cli.test.error;
-
-import 'package:test/test.dart';
-
-import 'utils.dart';
-
-const badDeclaration = 'var int foo;';
-const badDeclarationMessage = 'Error in test.dart: '
- 'Variables can\'t be declared using both \'var\' and a type name.\n';
-
-void main() {
- group('error', () {
- test("a valid Dart file doesn't throw any errors", () {
- expect(errorsForFile('void main() => print("Hello, world!");'), isNull);
- });
-
- test("an empty Dart file doesn't throw any errors", () {
- expect(errorsForFile(''), isNull);
- });
-
- test("an error on the first line", () {
- expect(errorsForFile('$badDeclaration\n'), equals(badDeclarationMessage));
- });
-
- test("an error on the last line", () {
- expect(errorsForFile('\n$badDeclaration'), equals(badDeclarationMessage));
- });
-
- test("an error in the middle", () {
- expect(
- errorsForFile('\n$badDeclaration\n'), equals(badDeclarationMessage));
- });
-
- var veryLongString = new List.filled(107, ' ').join('');
-
- test("an error at the end of a very long line", () {
- expect(errorsForFile('$veryLongString $badDeclaration'),
- equals(badDeclarationMessage));
- });
-
- test("an error at the beginning of a very long line", () {
- expect(errorsForFile('$badDeclaration $veryLongString'),
- equals(badDeclarationMessage));
- });
-
- test("an error in the middle of a very long line", () {
- expect(errorsForFile('$veryLongString $badDeclaration$veryLongString'),
- equals(badDeclarationMessage));
- });
- });
-}
diff --git a/pkg/analyzer_cli/test/mocks.dart b/pkg/analyzer_cli/test/mocks.dart
index 985464c..49f7251 100644
--- a/pkg/analyzer_cli/test/mocks.dart
+++ b/pkg/analyzer_cli/test/mocks.dart
@@ -1,8 +1,8 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2015, 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:analyzer/analyzer.dart';
+import 'package:analyzer/error/error.dart';
import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analyzer_cli/test/options_test.dart b/pkg/analyzer_cli/test/options_test.dart
index b0c8a8c..6001816 100644
--- a/pkg/analyzer_cli/test/options_test.dart
+++ b/pkg/analyzer_cli/test/options_test.dart
@@ -1,9 +1,7 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer_cli.test.options;
-
import 'dart:io';
import 'package:analyzer_cli/src/driver.dart';
@@ -58,6 +56,7 @@
expect(options.dartSdkPath, isNotNull);
expect(options.disableCacheFlushing, isFalse);
expect(options.disableHints, isFalse);
+ expect(options.enabledExperiments, isEmpty);
expect(options.lints, isFalse);
expect(options.displayVersion, isFalse);
expect(options.infosAreFatal, isFalse);
@@ -72,7 +71,6 @@
expect(options.warningsAreFatal, isFalse);
expect(options.strongMode, isTrue);
expect(options.lintsAreFatal, isFalse);
- expect(options.previewDart2, isTrue);
expect(options.trainSnapshot, isFalse);
});
@@ -95,6 +93,49 @@
expect(options.disableCacheFlushing, isTrue);
});
+ group('enable experiment', () {
+ test('no values', () {
+ CommandLineOptions options = CommandLineOptions.parse(['foo.dart']);
+ expect(options.enabledExperiments, isEmpty);
+ });
+
+ test('single value', () {
+ CommandLineOptions options = CommandLineOptions.parse(
+ ['--enable-experiment', 'a', 'foo.dart']);
+ expect(options.enabledExperiments, ['a']);
+ });
+
+ group('multiple values', () {
+ test('single flag', () {
+ CommandLineOptions options = CommandLineOptions.parse(
+ ['--enable-experiment', 'a,b', 'foo.dart']);
+ expect(options.enabledExperiments, ['a', 'b']);
+ });
+
+ test('mixed single and multiple flags', () {
+ CommandLineOptions options = CommandLineOptions.parse([
+ '--enable-experiment',
+ 'a,b',
+ '--enable-experiment',
+ 'c',
+ 'foo.dart'
+ ]);
+ expect(options.enabledExperiments, ['a', 'b', 'c']);
+ });
+
+ test('multiple flags', () {
+ CommandLineOptions options = CommandLineOptions.parse([
+ '--enable-experiment',
+ 'a',
+ '--enable-experiment',
+ 'b',
+ 'foo.dart'
+ ]);
+ expect(options.enabledExperiments, ['a', 'b']);
+ });
+ });
+ });
+
test('hintsAreFatal', () {
CommandLineOptions options = CommandLineOptions.parse(
['--dart-sdk', '.', '--fatal-hints', 'foo.dart']);
@@ -231,12 +272,6 @@
expect(options.useFastaParser, isTrue);
});
- test('--preview-dart-2', () {
- CommandLineOptions options =
- CommandLineOptions.parse(['--preview-dart-2', 'foo.dart']);
- expect(options.previewDart2, isTrue);
- });
-
test('--train-snapshot', () {
CommandLineOptions options =
CommandLineOptions.parse(['--train-snapshot', 'foo.dart']);
diff --git a/pkg/analyzer_cli/test/reporter_test.dart b/pkg/analyzer_cli/test/reporter_test.dart
index a86c03d..26d37ac 100644
--- a/pkg/analyzer_cli/test/reporter_test.dart
+++ b/pkg/analyzer_cli/test/reporter_test.dart
@@ -1,8 +1,8 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2015, 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:analyzer/analyzer.dart';
+import 'package:analyzer/error/error.dart';
import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer_cli/src/ansi.dart' as ansi;
diff --git a/pkg/analyzer_cli/test/utils.dart b/pkg/analyzer_cli/test/utils.dart
index fd431a2..3803341 100644
--- a/pkg/analyzer_cli/test/utils.dart
+++ b/pkg/analyzer_cli/test/utils.dart
@@ -1,14 +1,11 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer_cli.test.utils;
-
import 'dart:async';
import 'dart:io';
import 'dart:mirrors';
-import 'package:analyzer/analyzer.dart';
import 'package:path/path.dart' as pathos;
/// Gets the test directory in a way that works with package:test
@@ -16,30 +13,6 @@
final String testDirectory = pathos.dirname(
pathos.fromUri((reflectClass(_TestUtils).owner as LibraryMirror).uri));
-/// Returns the string representation of the [AnalyzerErrorGroup] thrown when
-/// parsing [contents] as a Dart file. If [contents] doesn't throw any errors,
-/// this will return null.
-///
-/// This replaces the filename in the error string with its basename, since the
-/// full path will vary from machine to machine. It also replaces the exception
-/// message with "..." to decouple these tests from the specific exception
-/// messages.
-String errorsForFile(String contents) {
- return withTempDir((temp) {
- var path = pathos.join(temp, 'test.dart');
- new File(path).writeAsStringSync(contents);
- try {
- parseDartFile(path);
- } on AnalyzerErrorGroup catch (e) {
- return e.toString().replaceAllMapped(
- new RegExp(r"^(Error on line \d+ of )((?:[A-Z]+:)?[^:]+): .*$",
- multiLine: true),
- (match) => match[1] + pathos.basename(match[2]) + ': ...');
- }
- return null;
- });
-}
-
/// Recursively copy the specified [src] directory (or file)
/// to the specified destination path.
Future<Null> recursiveCopy(FileSystemEntity src, String dstPath) async {
diff --git a/pkg/analyzer_plugin/lib/plugin/assist_mixin.dart b/pkg/analyzer_plugin/lib/plugin/assist_mixin.dart
index 9eb8286..d17d4cd 100644
--- a/pkg/analyzer_plugin/lib/plugin/assist_mixin.dart
+++ b/pkg/analyzer_plugin/lib/plugin/assist_mixin.dart
@@ -17,10 +17,10 @@
* A mixin that can be used when creating a subclass of [ServerPlugin] to
* provide most of the implementation for handling assist requests.
*
- * Clients may not extend or implement this class, but are allowed to use it as
- * a mix-in when creating a subclass of [ServerPlugin].
+ * Clients may not implement this mixin, but are allowed to use it as a mix-in
+ * when creating a subclass of [ServerPlugin].
*/
-abstract class AssistsMixin implements ServerPlugin {
+mixin AssistsMixin implements ServerPlugin {
/**
* Return a list containing the assist contributors that should be used to
* create assists for the file with the given [path].
@@ -67,7 +67,7 @@
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
String path = parameters.file;
- ResolveResult result = await getResolveResult(path);
+ ResolvedUnitResult result = await getResolvedUnitResult(path);
return new DartAssistRequestImpl(
resourceProvider, parameters.offset, parameters.length, result);
}
diff --git a/pkg/analyzer_plugin/lib/plugin/completion_mixin.dart b/pkg/analyzer_plugin/lib/plugin/completion_mixin.dart
index 72de7ce..a8aa3b8 100644
--- a/pkg/analyzer_plugin/lib/plugin/completion_mixin.dart
+++ b/pkg/analyzer_plugin/lib/plugin/completion_mixin.dart
@@ -17,10 +17,10 @@
* A mixin that can be used when creating a subclass of [ServerPlugin] to
* provide most of the implementation for handling code completion requests.
*
- * Clients may not extend or implement this class, but are allowed to use it as
- * a mix-in when creating a subclass of [ServerPlugin].
+ * Clients may not implement this mixin, but are allowed to use it as a mix-in
+ * when creating a subclass of [ServerPlugin].
*/
-abstract class CompletionMixin implements ServerPlugin {
+mixin CompletionMixin implements ServerPlugin {
/**
* Return a list containing the completion contributors that should be used to
* create completion suggestions for the file with the given [path].
@@ -68,7 +68,7 @@
CompletionGetSuggestionsParams parameters) async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
- ResolveResult result = await getResolveResult(parameters.file);
+ ResolvedUnitResult result = await getResolvedUnitResult(parameters.file);
return new DartCompletionRequestImpl(
resourceProvider, parameters.offset, result);
}
diff --git a/pkg/analyzer_plugin/lib/plugin/fix_mixin.dart b/pkg/analyzer_plugin/lib/plugin/fix_mixin.dart
index 917dc3e..a4a113d 100644
--- a/pkg/analyzer_plugin/lib/plugin/fix_mixin.dart
+++ b/pkg/analyzer_plugin/lib/plugin/fix_mixin.dart
@@ -20,23 +20,23 @@
* mixing in [FixesMixin]. This implements the creation of the fixes request
* based on the assumption that the driver being created is an [AnalysisDriver].
*
- * Clients may not extend or implement this class, but are allowed to use it as
- * a mix-in when creating a subclass of [ServerPlugin] that also uses
- * [FixesMixin] as a mix-in.
+ * Clients may not implement this mixin, but are allowed to use it as a mix-in
+ * when creating a subclass of [ServerPlugin] that also uses [FixesMixin] as a
+ * mix-in.
*/
-abstract class DartFixesMixin implements FixesMixin {
+mixin DartFixesMixin implements FixesMixin {
@override
Future<FixesRequest> getFixesRequest(EditGetFixesParams parameters) async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
String path = parameters.file;
int offset = parameters.offset;
- ResolveResult result = await getResolveResult(path);
+ ResolvedUnitResult result = await getResolvedUnitResult(path);
return new DartFixesRequestImpl(
resourceProvider, offset, _getErrors(offset, result), result);
}
- List<AnalysisError> _getErrors(int offset, ResolveResult result) {
+ List<AnalysisError> _getErrors(int offset, ResolvedUnitResult result) {
LineInfo lineInfo = result.lineInfo;
int offsetLine = lineInfo.getLocation(offset).lineNumber;
return result.errors.where((AnalysisError error) {
@@ -50,10 +50,10 @@
* A mixin that can be used when creating a subclass of [ServerPlugin] to
* provide most of the implementation for handling fix requests.
*
- * Clients may not extend or implement this class, but are allowed to use it as
- * a mix-in when creating a subclass of [ServerPlugin].
+ * Clients may not implement this mixin, but are allowed to use it as a mix-in
+ * when creating a subclass of [ServerPlugin].
*/
-abstract class FixesMixin implements ServerPlugin {
+mixin FixesMixin implements ServerPlugin {
/**
* Return a list containing the fix contributors that should be used to create
* fixes for the file with the given [path].
diff --git a/pkg/analyzer_plugin/lib/plugin/folding_mixin.dart b/pkg/analyzer_plugin/lib/plugin/folding_mixin.dart
index 3c8d88c..1ca0f81 100644
--- a/pkg/analyzer_plugin/lib/plugin/folding_mixin.dart
+++ b/pkg/analyzer_plugin/lib/plugin/folding_mixin.dart
@@ -18,16 +18,16 @@
* request based on the assumption that the driver being created is an
* [AnalysisDriver].
*
- * Clients may not extend or implement this class, but are allowed to use it as
- * a mix-in when creating a subclass of [ServerPlugin] that also uses
- * [FoldingMixin] as a mix-in.
+ * Clients may not implement this mixin, but are allowed to use it as a mix-in
+ * when creating a subclass of [ServerPlugin] that also uses [FoldingMixin] as a
+ * mix-in.
*/
-abstract class DartFoldingMixin implements FoldingMixin {
+mixin DartFoldingMixin implements FoldingMixin {
@override
Future<FoldingRequest> getFoldingRequest(String path) async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
- ResolveResult result = await getResolveResult(path);
+ ResolvedUnitResult result = await getResolvedUnitResult(path);
return new DartFoldingRequestImpl(resourceProvider, result);
}
}
@@ -36,10 +36,10 @@
* A mixin that can be used when creating a subclass of [ServerPlugin] to
* provide most of the implementation for producing folding notifications.
*
- * Clients may not extend or implement this class, but are allowed to use it as
- * a mix-in when creating a subclass of [ServerPlugin].
+ * Clients may not implement this mixin, but are allowed to use it as a mix-in
+ * when creating a subclass of [ServerPlugin].
*/
-abstract class FoldingMixin implements ServerPlugin {
+mixin FoldingMixin implements ServerPlugin {
/**
* Return a list containing the folding contributors that should be used
* to create folding regions for the file with the given [path].
diff --git a/pkg/analyzer_plugin/lib/plugin/highlights_mixin.dart b/pkg/analyzer_plugin/lib/plugin/highlights_mixin.dart
index a401db8..20748c9 100644
--- a/pkg/analyzer_plugin/lib/plugin/highlights_mixin.dart
+++ b/pkg/analyzer_plugin/lib/plugin/highlights_mixin.dart
@@ -18,16 +18,16 @@
* highlighting request based on the assumption that the driver being created is
* an [AnalysisDriver].
*
- * Clients may not extend or implement this class, but are allowed to use it as
- * a mix-in when creating a subclass of [ServerPlugin] that also uses
- * [HighlightsMixin] as a mix-in.
+ * Clients may not implement this mixin, but are allowed to use it as a mix-in
+ * when creating a subclass of [ServerPlugin] that also uses [HighlightsMixin]
+ * as a mix-in.
*/
-abstract class DartHighlightsMixin implements HighlightsMixin {
+mixin DartHighlightsMixin implements HighlightsMixin {
@override
Future<HighlightsRequest> getHighlightsRequest(String path) async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
- ResolveResult result = await getResolveResult(path);
+ ResolvedUnitResult result = await getResolvedUnitResult(path);
return new DartHighlightsRequestImpl(resourceProvider, result);
}
}
@@ -36,10 +36,10 @@
* A mixin that can be used when creating a subclass of [ServerPlugin] to
* provide most of the implementation for producing highlighting notifications.
*
- * Clients may not extend or implement this class, but are allowed to use it as
- * a mix-in when creating a subclass of [ServerPlugin].
+ * Clients may not implement this mixin, but are allowed to use it as a mix-in
+ * when creating a subclass of [ServerPlugin].
*/
-abstract class HighlightsMixin implements ServerPlugin {
+mixin HighlightsMixin implements ServerPlugin {
/**
* Return a list containing the highlighting contributors that should be used
* to create highlighting information for the file with the given [path].
diff --git a/pkg/analyzer_plugin/lib/plugin/kythe_mixin.dart b/pkg/analyzer_plugin/lib/plugin/kythe_mixin.dart
index 999ba57..be89c6c 100644
--- a/pkg/analyzer_plugin/lib/plugin/kythe_mixin.dart
+++ b/pkg/analyzer_plugin/lib/plugin/kythe_mixin.dart
@@ -19,18 +19,18 @@
* request based on the assumption that the driver being created is an
* [AnalysisDriver].
*
- * Clients may not extend or implement this class, but are allowed to use it as
- * a mix-in when creating a subclass of [ServerPlugin] that also uses
- * [KytheMixin] as a mix-in.
+ * Clients may not implement this mixin, but are allowed to use it as a mix-in
+ * when creating a subclass of [ServerPlugin] that also uses [KytheMixin] as a
+ * mix-in.
*/
-abstract class DartEntryMixin implements EntryMixin {
+mixin DartEntryMixin implements EntryMixin {
@override
Future<EntryRequest> getEntryRequest(
KytheGetKytheEntriesParams parameters) async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
String path = parameters.file;
- ResolveResult result = await getResolveResult(path);
+ ResolvedUnitResult result = await getResolvedUnitResult(path);
return new DartEntryRequestImpl(resourceProvider, result);
}
}
@@ -39,10 +39,10 @@
* A mixin that can be used when creating a subclass of [ServerPlugin] to
* provide most of the implementation for handling kythe.getEntries requests.
*
- * Clients may not extend or implement this class, but are allowed to use it as
- * a mix-in when creating a subclass of [ServerPlugin].
+ * Clients may not implement this mixin, but are allowed to use it as a mix-in
+ * when creating a subclass of [ServerPlugin].
*/
-abstract class EntryMixin implements ServerPlugin {
+mixin EntryMixin implements ServerPlugin {
/**
* Return a list containing the entry contributors that should be used to
* create entries for the file with the given [path]
diff --git a/pkg/analyzer_plugin/lib/plugin/navigation_mixin.dart b/pkg/analyzer_plugin/lib/plugin/navigation_mixin.dart
index e1e6e28..96bfdc5 100644
--- a/pkg/analyzer_plugin/lib/plugin/navigation_mixin.dart
+++ b/pkg/analyzer_plugin/lib/plugin/navigation_mixin.dart
@@ -19,18 +19,18 @@
* request based on the assumption that the driver being created is an
* [AnalysisDriver].
*
- * Clients may not extend or implement this class, but are allowed to use it as
- * a mix-in when creating a subclass of [ServerPlugin] that also uses
- * [NavigationMixin] as a mix-in.
+ * Clients may not implement this mixin, but are allowed to use it as a mix-in
+ * when creating a subclass of [ServerPlugin] that also uses [NavigationMixin]
+ * as a mix-in.
*/
-abstract class DartNavigationMixin implements NavigationMixin {
+mixin DartNavigationMixin implements NavigationMixin {
@override
Future<NavigationRequest> getNavigationRequest(
AnalysisGetNavigationParams parameters) async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
String path = parameters.file;
- ResolveResult result = await getResolveResult(path);
+ ResolvedUnitResult result = await getResolvedUnitResult(path);
int offset = parameters.offset;
int length = parameters.length;
if (offset < 0 && length < 0) {
@@ -46,10 +46,10 @@
* A mixin that can be used when creating a subclass of [ServerPlugin] to
* provide most of the implementation for handling navigation requests.
*
- * Clients may not extend or implement this class, but are allowed to use it as
- * a mix-in when creating a subclass of [ServerPlugin].
+ * Clients may not implement this mixin, but are allowed to use it as a mix-in
+ * when creating a subclass of [ServerPlugin].
*/
-abstract class NavigationMixin implements ServerPlugin {
+mixin NavigationMixin implements ServerPlugin {
/**
* Return a list containing the navigation contributors that should be used to
* create navigation information for the file with the given [path]
diff --git a/pkg/analyzer_plugin/lib/plugin/occurrences_mixin.dart b/pkg/analyzer_plugin/lib/plugin/occurrences_mixin.dart
index 5766d9b..8547779 100644
--- a/pkg/analyzer_plugin/lib/plugin/occurrences_mixin.dart
+++ b/pkg/analyzer_plugin/lib/plugin/occurrences_mixin.dart
@@ -18,16 +18,16 @@
* request based on the assumption that the driver being created is an
* [AnalysisDriver].
*
- * Clients may not extend or implement this class, but are allowed to use it as
- * a mix-in when creating a subclass of [ServerPlugin] that also uses
- * [OccurrencesMixin] as a mix-in.
+ * Clients may not implement this mixin, but are allowed to use it as a mix-in
+ * when creating a subclass of [ServerPlugin] that also uses [OccurrencesMixin]
+ * as a mix-in.
*/
-abstract class DartOccurrencesMixin implements OccurrencesMixin {
+mixin DartOccurrencesMixin implements OccurrencesMixin {
@override
Future<OccurrencesRequest> getOccurrencesRequest(String path) async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
- ResolveResult result = await getResolveResult(path);
+ ResolvedUnitResult result = await getResolvedUnitResult(path);
return new DartOccurrencesRequestImpl(resourceProvider, result);
}
}
@@ -36,10 +36,10 @@
* A mixin that can be used when creating a subclass of [ServerPlugin] to
* provide most of the implementation for producing occurrences notifications.
*
- * Clients may not extend or implement this class, but are allowed to use it as
- * a mix-in when creating a subclass of [ServerPlugin].
+ * Clients may not implement this mixin, but are allowed to use it as a mix-in
+ * when creating a subclass of [ServerPlugin].
*/
-abstract class OccurrencesMixin implements ServerPlugin {
+mixin OccurrencesMixin implements ServerPlugin {
/**
* Return a list containing the occurrences contributors that should be used
* to create occurrences information for the file with the given [path].
diff --git a/pkg/analyzer_plugin/lib/plugin/outline_mixin.dart b/pkg/analyzer_plugin/lib/plugin/outline_mixin.dart
index 96bbdc4..4207a25 100644
--- a/pkg/analyzer_plugin/lib/plugin/outline_mixin.dart
+++ b/pkg/analyzer_plugin/lib/plugin/outline_mixin.dart
@@ -18,16 +18,16 @@
* request based on the assumption that the driver being created is an
* [AnalysisDriver].
*
- * Clients may not extend or implement this class, but are allowed to use it as
- * a mix-in when creating a subclass of [ServerPlugin] that also uses
- * [OutlineMixin] as a mix-in.
+ * Clients may not implement this mixin, but are allowed to use it as a mix-in
+ * when creating a subclass of [ServerPlugin] that also uses [OutlineMixin] as a
+ * mix-in.
*/
-abstract class DartOutlineMixin implements OutlineMixin {
+mixin DartOutlineMixin implements OutlineMixin {
@override
Future<OutlineRequest> getOutlineRequest(String path) async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
- ResolveResult result = await getResolveResult(path);
+ ResolvedUnitResult result = await getResolvedUnitResult(path);
return new DartOutlineRequestImpl(resourceProvider, result);
}
}
@@ -36,10 +36,10 @@
* A mixin that can be used when creating a subclass of [ServerPlugin] to
* provide most of the implementation for producing outline notifications.
*
- * Clients may not extend or implement this class, but are allowed to use it as
- * a mix-in when creating a subclass of [ServerPlugin].
+ * Clients may not implement this mixin, but are allowed to use it as a mix-in
+ * when creating a subclass of [ServerPlugin].
*/
-abstract class OutlineMixin implements ServerPlugin {
+mixin OutlineMixin implements ServerPlugin {
/**
* Return a list containing the outline contributors that should be used to
* create outline information for the file with the given [path].
diff --git a/pkg/analyzer_plugin/lib/plugin/plugin.dart b/pkg/analyzer_plugin/lib/plugin/plugin.dart
index 5fb6296..44ad8e9 100644
--- a/pkg/analyzer_plugin/lib/plugin/plugin.dart
+++ b/pkg/analyzer_plugin/lib/plugin/plugin.dart
@@ -208,7 +208,7 @@
* Throw a [RequestFailure] is the file cannot be analyzed or if the driver
* associated with the file is not an [AnalysisDriver].
*/
- Future<ResolveResult> getResolveResult(String path) async {
+ Future<ResolvedUnitResult> getResolvedUnitResult(String path) async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
AnalysisDriverGeneric driver = driverForPath(path);
@@ -217,7 +217,8 @@
throw new RequestFailure(
RequestErrorFactory.pluginError('Failed to analyze $path', null));
}
- ResolveResult result = await (driver as AnalysisDriver).getResult(path);
+ ResolvedUnitResult result =
+ await (driver as AnalysisDriver).getResult(path);
ResultState state = result.state;
if (state != ResultState.VALID) {
// Return an error from the request.
@@ -228,6 +229,16 @@
}
/**
+ * Return the result of analyzing the file with the given [path].
+ *
+ * Throw a [RequestFailure] is the file cannot be analyzed or if the driver
+ * associated with the file is not an [AnalysisDriver].
+ */
+ @deprecated
+ Future<ResolveResult> getResolveResult(String path) =>
+ getResolvedUnitResult(path);
+
+ /**
* Handle an 'analysis.getNavigation' request.
*
* Throw a [RequestFailure] if the request could not be handled.
diff --git a/pkg/analyzer_plugin/lib/src/channel/isolate_channel.dart b/pkg/analyzer_plugin/lib/src/channel/isolate_channel.dart
index 8d7b094..aa65532 100644
--- a/pkg/analyzer_plugin/lib/src/channel/isolate_channel.dart
+++ b/pkg/analyzer_plugin/lib/src/channel/isolate_channel.dart
@@ -121,7 +121,7 @@
void listen(void onRequest(Request request),
{Function onError, void onDone()}) {
void onData(data) {
- Map<String, Object> requestMap = data;
+ Map<String, Object> requestMap = data as Map<String, Object>;
Request request = new Request.fromJson(requestMap);
if (request != null) {
onRequest(request);
diff --git a/pkg/analyzer_plugin/lib/src/utilities/assist/assist.dart b/pkg/analyzer_plugin/lib/src/utilities/assist/assist.dart
index dcbe5eb..95b0893 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/assist/assist.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/assist/assist.dart
@@ -36,7 +36,7 @@
final int length;
@override
- final ResolveResult result;
+ final ResolvedUnitResult result;
/**
* Initialize a newly create request with the given data.
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
index 7618568..8a9eba3 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
@@ -44,7 +44,7 @@
String path, void buildFileEdit(DartFileEditBuilder builder),
{ImportPrefixGenerator importPrefixGenerator}) {
return super.addFileEdit(path, (builder) {
- DartFileEditBuilderImpl dartBuilder = builder;
+ DartFileEditBuilderImpl dartBuilder = builder as DartFileEditBuilderImpl;
dartBuilder.importPrefixGenerator = importPrefixGenerator;
buildFileEdit(dartBuilder);
});
@@ -54,7 +54,7 @@
Future<DartFileEditBuilderImpl> createFileEditBuilder(String path) async {
// TODO(brianwilkerson) Determine whether this await is necessary.
await null;
- ResolveResult result = await session.getResolvedAst(path);
+ ResolvedUnitResult result = await session.getResolvedUnit(path);
ResultState state = result?.state ?? ResultState.INVALID_FILE_TYPE;
if (state == ResultState.INVALID_FILE_TYPE) {
throw new AnalysisException('Cannot analyze "$path"');
@@ -402,7 +402,7 @@
}
}
- ExecutableElement element = signature.element;
+ ExecutableElement element = signature.element as ExecutableElement;
String prefix = getIndent(1);
String prefix2 = getIndent(2);
ElementKind elementKind = element.kind;
@@ -472,10 +472,11 @@
// TO-DO
write(prefix2);
- writeln('// TODO: implement $memberName');
+ write('// TODO: implement $memberName');
if (isSetter) {
if (invokeSuper) {
+ writeln();
write(prefix2);
selectAll(() {
write('super.');
@@ -485,9 +486,13 @@
write(';');
});
writeln();
+ } else {
+ selectHere();
+ writeln();
}
} else if (returnType.isVoid) {
if (invokeSuper) {
+ writeln();
write(prefix2);
selectAll(() {
write('super.');
@@ -502,8 +507,12 @@
write(');');
});
writeln();
+ } else {
+ selectHere();
+ writeln();
}
} else {
+ writeln();
write(prefix2);
if (invokeSuper) {
selectAll(() {
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/completion_core.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/completion_core.dart
index 209e451..7bf30d5 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/completion_core.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/completion_core.dart
@@ -84,7 +84,7 @@
final int offset;
@override
- final ResolveResult result;
+ final ResolvedUnitResult result;
/**
* A flag indicating whether completion has been aborted.
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
index 03fcb97..69a0aae 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
@@ -154,7 +154,7 @@
if (containingNode is Comment) {
// Comments are handled specially: we descend into any CommentReference
// child node that contains the cursor offset.
- Comment comment = containingNode;
+ Comment comment = containingNode as Comment;
for (CommentReference commentReference in comment.references) {
if (commentReference.offset <= offset &&
offset <= commentReference.end) {
@@ -276,7 +276,7 @@
token.type.isKeyword || token.type == TokenType.IDENTIFIER;
Token token = droppedToken ??
- (entity is AstNode ? (entity as AstNode).beginToken : entity);
+ (entity is AstNode ? (entity as AstNode).beginToken : entity as Token);
if (token != null && requestOffset < token.offset) {
token = containingNode.findPrevious(token);
}
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/element_suggestion_builder.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/element_suggestion_builder.dart
index 546f664..8b93677 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/element_suggestion_builder.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/element_suggestion_builder.dart
@@ -13,7 +13,7 @@
/**
* Common mixin for sharing behavior.
*/
-abstract class ElementSuggestionBuilder {
+mixin ElementSuggestionBuilder {
// Copied from analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
/**
* A collection of completion suggestions.
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
index a77fe18..e005b30 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
@@ -129,21 +129,26 @@
return optype;
}
- target.containingNode
- .accept(new _OpTypeAstVisitor(optype, target.entity, offset));
- var methodDeclaration =
- target.containingNode.getAncestor((node) => node is MethodDeclaration);
- optype.inMethodBody = methodDeclaration != null;
- optype.inStaticMethodBody =
- methodDeclaration is MethodDeclaration && methodDeclaration.isStatic;
+ var targetNode = target.containingNode;
+ targetNode.accept(new _OpTypeAstVisitor(optype, target.entity, offset));
- var functionDeclaration = target.containingNode
- .getAncestor((node) => node is FunctionDeclaration);
- optype.inFunctionBody = functionDeclaration != null;
+ var functionBody = targetNode.thisOrAncestorOfType<FunctionBody>();
+ if (functionBody != null) {
+ var parent = functionBody.parent;
- var constructorDeclaration = target.containingNode
- .getAncestor((node) => node is ConstructorDeclaration);
- optype.inConstructorBody = constructorDeclaration != null;
+ if (parent is ConstructorDeclaration) {
+ optype.inConstructorBody = true;
+ }
+
+ if (parent is FunctionExpression) {
+ optype.inFunctionBody = true;
+ }
+
+ if (parent is MethodDeclaration) {
+ optype.inMethodBody = true;
+ optype.inStaticMethodBody = parent.isStatic;
+ }
+ }
// If a value should be suggested, suggest also constructors.
if (optype.includeReturnValueSuggestions) {
@@ -482,6 +487,14 @@
}
@override
+ visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
+ if (identical(entity, node.expression)) {
+ optype.includeReturnValueSuggestions = true;
+ optype.includeTypeNameSuggestions = true;
+ }
+ }
+
+ @override
visitConstructorName(ConstructorName node) {
// some PrefixedIdentifier nodes are transformed into
// ConstructorName nodes during the resolution process.
@@ -548,7 +561,7 @@
// Given f[], the parser drops the [] from the expression statement
// but the [] token is the CompletionTarget entity
if (entity is Token) {
- Token token = entity;
+ Token token = entity as Token;
if (token.lexeme == '[]' && offset == token.offset + 1) {
optype.includeReturnValueSuggestions = true;
optype.includeTypeNameSuggestions = true;
@@ -976,7 +989,7 @@
@override
void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
if (entity is Token) {
- Token token = entity;
+ Token token = entity as Token;
if (token.isSynthetic || token.lexeme == ';') {
optype.includeVarNameSuggestions = true;
}
diff --git a/pkg/analyzer_plugin/lib/src/utilities/fixes/fixes.dart b/pkg/analyzer_plugin/lib/src/utilities/fixes/fixes.dart
index 54d9b45..8973624 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/fixes/fixes.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/fixes/fixes.dart
@@ -23,7 +23,7 @@
final List<AnalysisError> errorsToFix;
@override
- final ResolveResult result;
+ final ResolvedUnitResult result;
/**
* Initialize a newly create request with the given data.
diff --git a/pkg/analyzer_plugin/lib/src/utilities/folding/folding.dart b/pkg/analyzer_plugin/lib/src/utilities/folding/folding.dart
index 1e7eb67f..2d5578c 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/folding/folding.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/folding/folding.dart
@@ -17,7 +17,7 @@
final ResourceProvider resourceProvider;
@override
- final ResolveResult result;
+ final ResolvedUnitResult result;
/**
* Initialize a newly create request with the given data.
diff --git a/pkg/analyzer_plugin/lib/src/utilities/highlights/highlights.dart b/pkg/analyzer_plugin/lib/src/utilities/highlights/highlights.dart
index bb24bcb..8412dac 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/highlights/highlights.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/highlights/highlights.dart
@@ -17,7 +17,7 @@
final ResourceProvider resourceProvider;
@override
- final ResolveResult result;
+ final ResolvedUnitResult result;
/**
* Initialize a newly create request with the given data.
diff --git a/pkg/analyzer_plugin/lib/src/utilities/kythe/entries.dart b/pkg/analyzer_plugin/lib/src/utilities/kythe/entries.dart
index 72256df..eb4163a 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/kythe/entries.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/kythe/entries.dart
@@ -15,7 +15,7 @@
final ResourceProvider resourceProvider;
@override
- final ResolveResult result;
+ final ResolvedUnitResult result;
/**
* Initialize a newly create request with the given data.
diff --git a/pkg/analyzer_plugin/lib/src/utilities/navigation/navigation.dart b/pkg/analyzer_plugin/lib/src/utilities/navigation/navigation.dart
index f8b4b11..31e004b 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/navigation/navigation.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/navigation/navigation.dart
@@ -23,7 +23,7 @@
final int offset;
@override
- final ResolveResult result;
+ final ResolvedUnitResult result;
/**
* Initialize a newly create request with the given data.
diff --git a/pkg/analyzer_plugin/lib/src/utilities/occurrences/occurrences.dart b/pkg/analyzer_plugin/lib/src/utilities/occurrences/occurrences.dart
index 42b95c2..2538191 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/occurrences/occurrences.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/occurrences/occurrences.dart
@@ -16,7 +16,7 @@
final ResourceProvider resourceProvider;
@override
- final ResolveResult result;
+ final ResolvedUnitResult result;
/**
* Initialize a newly create request with the given data.
diff --git a/pkg/analyzer_plugin/lib/src/utilities/outline/outline.dart b/pkg/analyzer_plugin/lib/src/utilities/outline/outline.dart
index f87c5fc..47fba67 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/outline/outline.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/outline/outline.dart
@@ -16,7 +16,7 @@
final ResourceProvider resourceProvider;
@override
- final ResolveResult result;
+ final ResolvedUnitResult result;
/**
* Initialize a newly create request with the given data.
diff --git a/pkg/analyzer_plugin/lib/src/utilities/visitors/local_declaration_visitor.dart b/pkg/analyzer_plugin/lib/src/utilities/visitors/local_declaration_visitor.dart
index ec525ca..ba1ec8f 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/visitors/local_declaration_visitor.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/visitors/local_declaration_visitor.dart
@@ -35,6 +35,8 @@
void declaredFunctionTypeAlias(FunctionTypeAlias declaration);
+ void declaredGenericTypeAlias(GenericTypeAlias declaration);
+
void declaredLabel(Label label, bool isCaseLabel);
void declaredLocalVar(SimpleIdentifier name, TypeAnnotation type);
@@ -113,6 +115,8 @@
declaredClassTypeAlias(declaration);
} else if (declaration is FunctionTypeAlias) {
declaredFunctionTypeAlias(declaration);
+ } else if (declaration is GenericTypeAlias) {
+ declaredGenericTypeAlias(declaration);
}
});
}
diff --git a/pkg/analyzer_plugin/lib/utilities/analyzer_converter.dart b/pkg/analyzer_plugin/lib/utilities/analyzer_converter.dart
index 5fd4f25..c4fe0c2 100644
--- a/pkg/analyzer_plugin/lib/utilities/analyzer_converter.dart
+++ b/pkg/analyzer_plugin/lib/utilities/analyzer_converter.dart
@@ -36,7 +36,8 @@
int startLine = -1;
int startColumn = -1;
if (lineInfo != null) {
- analyzer.CharacterLocation lineLocation = lineInfo.getLocation(offset);
+ analyzer.CharacterLocation lineLocation =
+ lineInfo.getLocation(offset) as analyzer.CharacterLocation;
if (lineLocation != null) {
startLine = lineLocation.lineNumber;
startColumn = lineLocation.columnNumber;
@@ -126,6 +127,8 @@
return plugin.ElementKind.FUNCTION;
} else if (kind == analyzer.ElementKind.FUNCTION_TYPE_ALIAS) {
return plugin.ElementKind.FUNCTION_TYPE_ALIAS;
+ } else if (kind == analyzer.ElementKind.GENERIC_FUNCTION_TYPE) {
+ return plugin.ElementKind.FUNCTION_TYPE_ALIAS;
} else if (kind == analyzer.ElementKind.GETTER) {
return plugin.ElementKind.GETTER;
} else if (kind == analyzer.ElementKind.LABEL) {
@@ -340,7 +343,7 @@
analyzer.LineInfo lineInfo = unitElement.lineInfo;
if (lineInfo != null) {
analyzer.CharacterLocation offsetLocation =
- lineInfo.getLocation(range.offset);
+ lineInfo.getLocation(range.offset) as analyzer.CharacterLocation;
startLine = offsetLocation.lineNumber;
startColumn = offsetLocation.columnNumber;
}
diff --git a/pkg/analyzer_plugin/lib/utilities/assist/assist.dart b/pkg/analyzer_plugin/lib/utilities/assist/assist.dart
index 72c3e0d..7e02aea 100644
--- a/pkg/analyzer_plugin/lib/utilities/assist/assist.dart
+++ b/pkg/analyzer_plugin/lib/utilities/assist/assist.dart
@@ -145,5 +145,5 @@
/**
* The analysis result for the file in which the assists are being requested.
*/
- ResolveResult get result;
+ ResolvedUnitResult get result;
}
diff --git a/pkg/analyzer_plugin/lib/utilities/completion/completion_core.dart b/pkg/analyzer_plugin/lib/utilities/completion/completion_core.dart
index c037112..6a354cd 100644
--- a/pkg/analyzer_plugin/lib/utilities/completion/completion_core.dart
+++ b/pkg/analyzer_plugin/lib/utilities/completion/completion_core.dart
@@ -160,5 +160,5 @@
* The analysis result for the file in which the completion is being
* requested.
*/
- ResolveResult get result;
+ ResolvedUnitResult get result;
}
diff --git a/pkg/analyzer_plugin/lib/utilities/completion/inherited_reference_contributor.dart b/pkg/analyzer_plugin/lib/utilities/completion/inherited_reference_contributor.dart
index c3af0db..e3567fc 100644
--- a/pkg/analyzer_plugin/lib/utilities/completion/inherited_reference_contributor.dart
+++ b/pkg/analyzer_plugin/lib/utilities/completion/inherited_reference_contributor.dart
@@ -21,7 +21,7 @@
* Plugin developers should extend this function and primarily
* overload `computeSuggestions` (if needed).
*/
-class InheritedReferenceContributor extends Object
+class InheritedReferenceContributor
with ElementSuggestionBuilder
implements CompletionContributor {
@override
diff --git a/pkg/analyzer_plugin/lib/utilities/completion/type_member_contributor.dart b/pkg/analyzer_plugin/lib/utilities/completion/type_member_contributor.dart
index 28ab1f9..dd4a046 100644
--- a/pkg/analyzer_plugin/lib/utilities/completion/type_member_contributor.dart
+++ b/pkg/analyzer_plugin/lib/utilities/completion/type_member_contributor.dart
@@ -151,7 +151,7 @@
// Determine the name of the containing method because
// the most likely completion is a super expression with same name
MethodDeclaration containingMethod =
- expression.getAncestor((p) => p is MethodDeclaration);
+ expression.thisOrAncestorOfType<MethodDeclaration>();
if (containingMethod != null) {
SimpleIdentifier id = containingMethod.name;
if (id != null) {
@@ -241,6 +241,17 @@
}
@override
+ void declaredGenericTypeAlias(GenericTypeAlias declaration) {
+ if (declaration.name.name == targetName) {
+ TypeAnnotation typeName = declaration.functionType.returnType;
+ if (typeName != null) {
+ typeFound = typeName.type;
+ }
+ finished();
+ }
+ }
+
+ @override
void declaredLabel(Label label, bool isCaseLabel) {
if (label.label.name == targetName) {
// no type
diff --git a/pkg/analyzer_plugin/lib/utilities/fixes/fixes.dart b/pkg/analyzer_plugin/lib/utilities/fixes/fixes.dart
index 3b0ab66..377fe37 100644
--- a/pkg/analyzer_plugin/lib/utilities/fixes/fixes.dart
+++ b/pkg/analyzer_plugin/lib/utilities/fixes/fixes.dart
@@ -20,7 +20,7 @@
/**
* The analysis result for the file in which the fixes are being requested.
*/
- ResolveResult get result;
+ ResolvedUnitResult get result;
}
/**
@@ -147,11 +147,6 @@
final String appliedTogetherMessage;
/**
- * The change can be made with other fixes of this [FixKind].
- */
- bool canBeAppliedTogether() => appliedTogetherMessage != null;
-
- /**
* Initialize a newly created kind of fix to have the given [name],
* [priority], [message], and optionally [canBeAppliedTogether] and
* [appliedTogetherMessage].
@@ -160,11 +155,16 @@
{this.appliedTogetherMessage: null});
@override
- String toString() => name;
+ int get hashCode => name.hashCode;
@override
bool operator ==(o) => o is FixKind && o.name == name;
+ /**
+ * The change can be made with other fixes of this [FixKind].
+ */
+ bool canBeAppliedTogether() => appliedTogetherMessage != null;
+
@override
- int get hashCode => name.hashCode;
+ String toString() => name;
}
diff --git a/pkg/analyzer_plugin/lib/utilities/folding/folding.dart b/pkg/analyzer_plugin/lib/utilities/folding/folding.dart
index 7eab6ad..6408d2f 100644
--- a/pkg/analyzer_plugin/lib/utilities/folding/folding.dart
+++ b/pkg/analyzer_plugin/lib/utilities/folding/folding.dart
@@ -23,7 +23,7 @@
* The analysis result for the file for which the folding regions are being
* requested.
*/
- ResolveResult get result;
+ ResolvedUnitResult get result;
}
/**
diff --git a/pkg/analyzer_plugin/lib/utilities/highlights/highlights.dart b/pkg/analyzer_plugin/lib/utilities/highlights/highlights.dart
index 59acbe4..f24b280 100644
--- a/pkg/analyzer_plugin/lib/utilities/highlights/highlights.dart
+++ b/pkg/analyzer_plugin/lib/utilities/highlights/highlights.dart
@@ -22,7 +22,7 @@
* The analysis result for the file for which the highlight regions are being
* requested.
*/
- ResolveResult get result;
+ ResolvedUnitResult get result;
}
/**
diff --git a/pkg/analyzer_plugin/lib/utilities/kythe/entries.dart b/pkg/analyzer_plugin/lib/utilities/kythe/entries.dart
index b89cab9..11b42d1 100644
--- a/pkg/analyzer_plugin/lib/utilities/kythe/entries.dart
+++ b/pkg/analyzer_plugin/lib/utilities/kythe/entries.dart
@@ -20,7 +20,7 @@
/**
* The analysis result for the file in which the entries are being requested.
*/
- ResolveResult get result;
+ ResolvedUnitResult get result;
}
/**
diff --git a/pkg/analyzer_plugin/lib/utilities/navigation/navigation.dart b/pkg/analyzer_plugin/lib/utilities/navigation/navigation.dart
index d3233bc..3bc3471 100644
--- a/pkg/analyzer_plugin/lib/utilities/navigation/navigation.dart
+++ b/pkg/analyzer_plugin/lib/utilities/navigation/navigation.dart
@@ -23,7 +23,7 @@
* The analysis result for the file in which the navigation regions are being
* requested.
*/
- ResolveResult get result;
+ ResolvedUnitResult get result;
}
/**
diff --git a/pkg/analyzer_plugin/lib/utilities/occurrences/occurrences.dart b/pkg/analyzer_plugin/lib/utilities/occurrences/occurrences.dart
index 820f38e..1fe0c1b 100644
--- a/pkg/analyzer_plugin/lib/utilities/occurrences/occurrences.dart
+++ b/pkg/analyzer_plugin/lib/utilities/occurrences/occurrences.dart
@@ -22,7 +22,7 @@
* The analysis result for the file for which the occurrences information is
* being requested.
*/
- ResolveResult get result;
+ ResolvedUnitResult get result;
}
/**
diff --git a/pkg/analyzer_plugin/lib/utilities/outline/outline.dart b/pkg/analyzer_plugin/lib/utilities/outline/outline.dart
index f675976..21983f6 100644
--- a/pkg/analyzer_plugin/lib/utilities/outline/outline.dart
+++ b/pkg/analyzer_plugin/lib/utilities/outline/outline.dart
@@ -21,7 +21,7 @@
/**
* The analysis result for the file for which the outline is being requested.
*/
- ResolveResult get result;
+ ResolvedUnitResult get result;
}
/**
diff --git a/pkg/analyzer_plugin/test/integration/support/integration_tests.dart b/pkg/analyzer_plugin/test/integration/support/integration_tests.dart
index 4a58401..e27ac4c 100644
--- a/pkg/analyzer_plugin/test/integration/support/integration_tests.dart
+++ b/pkg/analyzer_plugin/test/integration/support/integration_tests.dart
@@ -548,10 +548,10 @@
return;
}
outOfTestExpect(message, isMap);
- Map messageAsMap = message;
+ Map messageAsMap = message as Map;
if (messageAsMap.containsKey('id')) {
outOfTestExpect(messageAsMap['id'], isString);
- String id = message['id'];
+ String id = message['id'] as String;
Completer completer = _pendingCommands[id];
if (completer == null) {
fail('Unexpected response from server: id=$id');
diff --git a/pkg/analyzer_plugin/test/plugin/assist_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/assist_mixin_test.dart
index 51e9802..f3d65c5 100644
--- a/pkg/analyzer_plugin/test/plugin/assist_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/assist_mixin_test.dart
@@ -5,14 +5,12 @@
import 'dart:async';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer_plugin/plugin/assist_mixin.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analyzer_plugin/protocol/protocol_generated.dart';
import 'package:analyzer_plugin/src/utilities/assist/assist.dart';
import 'package:analyzer_plugin/utilities/assist/assist.dart';
-import 'package:path/src/context.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -23,9 +21,7 @@
}
@reflectiveTest
-class AssistsMixinTest {
- MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
-
+class AssistsMixinTest with ResourceProviderMixin {
String packagePath1;
String filePath1;
ContextRoot contextRoot1;
@@ -34,11 +30,9 @@
_TestServerPlugin plugin;
void setUp() {
- Context pathContext = resourceProvider.pathContext;
-
- packagePath1 = resourceProvider.convertPath('/package1');
- filePath1 = pathContext.join(packagePath1, 'lib', 'test.dart');
- resourceProvider.newFile(filePath1, '');
+ packagePath1 = convertPath('/package1');
+ filePath1 = join(packagePath1, 'lib', 'test.dart');
+ newFile(filePath1);
contextRoot1 = new ContextRoot(packagePath1, <String>[]);
channel = new MockChannel();
@@ -90,7 +84,7 @@
@override
Future<AssistRequest> getAssistRequest(
EditGetAssistsParams parameters) async {
- AnalysisResult result = new MockAnalysisResult();
+ var result = new MockResolvedUnitResult();
return new DartAssistRequestImpl(
resourceProvider, parameters.offset, parameters.length, result);
}
diff --git a/pkg/analyzer_plugin/test/plugin/completion_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/completion_mixin_test.dart
index 0dcc99e..0c51a0a 100644
--- a/pkg/analyzer_plugin/test/plugin/completion_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/completion_mixin_test.dart
@@ -5,14 +5,12 @@
import 'dart:async';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer_plugin/plugin/completion_mixin.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analyzer_plugin/protocol/protocol_generated.dart';
import 'package:analyzer_plugin/src/utilities/completion/completion_core.dart';
import 'package:analyzer_plugin/utilities/completion/completion_core.dart';
-import 'package:path/src/context.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -23,9 +21,7 @@
}
@reflectiveTest
-class CompletionMixinTest {
- MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
-
+class CompletionMixinTest with ResourceProviderMixin {
String packagePath1;
String filePath1;
ContextRoot contextRoot1;
@@ -34,11 +30,9 @@
_TestServerPlugin plugin;
void setUp() {
- Context pathContext = resourceProvider.pathContext;
-
- packagePath1 = resourceProvider.convertPath('/package1');
- filePath1 = pathContext.join(packagePath1, 'lib', 'test.dart');
- resourceProvider.newFile(filePath1, 'int foo = bar;');
+ packagePath1 = convertPath('/package1');
+ filePath1 = join(packagePath1, 'lib', 'test.dart');
+ newFile(filePath1, content: 'int foo = bar;');
contextRoot1 = new ContextRoot(packagePath1, <String>[]);
channel = new MockChannel();
@@ -98,7 +92,7 @@
@override
Future<CompletionRequest> getCompletionRequest(
CompletionGetSuggestionsParams parameters) async {
- AnalysisResult result = new MockAnalysisResult();
+ var result = new MockResolvedUnitResult();
return new DartCompletionRequestImpl(
resourceProvider, parameters.offset, result);
}
diff --git a/pkg/analyzer_plugin/test/plugin/fix_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/fix_mixin_test.dart
index 1d785dd..decd70d 100644
--- a/pkg/analyzer_plugin/test/plugin/fix_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/fix_mixin_test.dart
@@ -6,17 +6,15 @@
import 'package:analyzer/error/error.dart';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer_plugin/plugin/fix_mixin.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart'
hide AnalysisError;
import 'package:analyzer_plugin/protocol/protocol_generated.dart';
import 'package:analyzer_plugin/src/utilities/fixes/fixes.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
-import 'package:path/src/context.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -27,9 +25,7 @@
}
@reflectiveTest
-class FixesMixinTest {
- MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
-
+class FixesMixinTest with ResourceProviderMixin {
String packagePath1;
String filePath1;
ContextRoot contextRoot1;
@@ -38,11 +34,9 @@
_TestServerPlugin plugin;
void setUp() {
- Context pathContext = resourceProvider.pathContext;
-
- packagePath1 = resourceProvider.convertPath('/package1');
- filePath1 = pathContext.join(packagePath1, 'lib', 'test.dart');
- resourceProvider.newFile(filePath1, '');
+ packagePath1 = convertPath('/package1');
+ filePath1 = join(packagePath1, 'lib', 'test.dart');
+ newFile(filePath1);
contextRoot1 = new ContextRoot(packagePath1, <String>[]);
channel = new MockChannel();
@@ -98,7 +92,7 @@
int offset = parameters.offset;
AnalysisError error = new AnalysisError(
new MockSource(), 0, 0, CompileTimeErrorCode.AWAIT_IN_WRONG_CONTEXT);
- AnalysisResult result = new MockAnalysisResult(
+ var result = new MockResolvedUnitResult(
lineInfo: new LineInfo([0, 20]), errors: [error]);
return new DartFixesRequestImpl(resourceProvider, offset, [error], result);
}
diff --git a/pkg/analyzer_plugin/test/plugin/folding_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/folding_mixin_test.dart
index 5123b40..0b429bc 100644
--- a/pkg/analyzer_plugin/test/plugin/folding_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/folding_mixin_test.dart
@@ -5,15 +5,13 @@
import 'dart:async';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer_plugin/plugin/folding_mixin.dart';
import 'package:analyzer_plugin/protocol/protocol.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analyzer_plugin/protocol/protocol_generated.dart';
import 'package:analyzer_plugin/src/utilities/folding/folding.dart';
import 'package:analyzer_plugin/utilities/folding/folding.dart';
-import 'package:path/src/context.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -24,9 +22,7 @@
}
@reflectiveTest
-class FoldingMixinTest {
- MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
-
+class FoldingMixinTest with ResourceProviderMixin {
String packagePath1;
String filePath1;
ContextRoot contextRoot1;
@@ -35,11 +31,9 @@
_TestServerPlugin plugin;
void setUp() {
- Context pathContext = resourceProvider.pathContext;
-
- packagePath1 = resourceProvider.convertPath('/package1');
- filePath1 = pathContext.join(packagePath1, 'lib', 'test.dart');
- resourceProvider.newFile(filePath1, '');
+ packagePath1 = convertPath('/package1');
+ filePath1 = join(packagePath1, 'lib', 'test.dart');
+ newFile(filePath1);
contextRoot1 = new ContextRoot(packagePath1, <String>[]);
channel = new MockChannel();
@@ -93,7 +87,7 @@
@override
Future<FoldingRequest> getFoldingRequest(String path) async {
- AnalysisResult result = new MockAnalysisResult(path: path);
+ var result = new MockResolvedUnitResult(path: path);
return new DartFoldingRequestImpl(resourceProvider, result);
}
}
diff --git a/pkg/analyzer_plugin/test/plugin/highlights_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/highlights_mixin_test.dart
index c0b4543..ced8227 100644
--- a/pkg/analyzer_plugin/test/plugin/highlights_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/highlights_mixin_test.dart
@@ -5,15 +5,13 @@
import 'dart:async';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer_plugin/plugin/highlights_mixin.dart';
import 'package:analyzer_plugin/protocol/protocol.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analyzer_plugin/protocol/protocol_generated.dart';
import 'package:analyzer_plugin/src/utilities/highlights/highlights.dart';
import 'package:analyzer_plugin/utilities/highlights/highlights.dart';
-import 'package:path/src/context.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -24,9 +22,7 @@
}
@reflectiveTest
-class HighlightsMixinTest {
- MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
-
+class HighlightsMixinTest with ResourceProviderMixin {
String packagePath1;
String filePath1;
ContextRoot contextRoot1;
@@ -35,11 +31,9 @@
_TestServerPlugin plugin;
void setUp() {
- Context pathContext = resourceProvider.pathContext;
-
- packagePath1 = resourceProvider.convertPath('/package1');
- filePath1 = pathContext.join(packagePath1, 'lib', 'test.dart');
- resourceProvider.newFile(filePath1, '');
+ packagePath1 = convertPath('/package1');
+ filePath1 = join(packagePath1, 'lib', 'test.dart');
+ newFile(filePath1);
contextRoot1 = new ContextRoot(packagePath1, <String>[]);
channel = new MockChannel();
@@ -93,7 +87,7 @@
@override
Future<HighlightsRequest> getHighlightsRequest(String path) async {
- AnalysisResult result = new MockAnalysisResult(path: path);
+ var result = new MockResolvedUnitResult(path: path);
return new DartHighlightsRequestImpl(resourceProvider, result);
}
}
diff --git a/pkg/analyzer_plugin/test/plugin/kythe_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/kythe_mixin_test.dart
index 0ce5e0a..63f0f63 100644
--- a/pkg/analyzer_plugin/test/plugin/kythe_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/kythe_mixin_test.dart
@@ -5,14 +5,12 @@
import 'dart:async';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer_plugin/plugin/kythe_mixin.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analyzer_plugin/protocol/protocol_generated.dart';
import 'package:analyzer_plugin/src/utilities/kythe/entries.dart';
import 'package:analyzer_plugin/utilities/kythe/entries.dart';
-import 'package:path/src/context.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -23,9 +21,7 @@
}
@reflectiveTest
-class KytheMixinTest {
- MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
-
+class KytheMixinTest with ResourceProviderMixin {
String packagePath1;
String filePath1;
ContextRoot contextRoot1;
@@ -34,11 +30,9 @@
_TestServerPlugin plugin;
void setUp() {
- Context pathContext = resourceProvider.pathContext;
-
- packagePath1 = resourceProvider.convertPath('/package1');
- filePath1 = pathContext.join(packagePath1, 'lib', 'test.dart');
- resourceProvider.newFile(filePath1, '');
+ packagePath1 = convertPath('/package1');
+ filePath1 = join(packagePath1, 'lib', 'test.dart');
+ newFile(filePath1);
contextRoot1 = new ContextRoot(packagePath1, <String>[]);
channel = new MockChannel();
@@ -94,7 +88,7 @@
@override
Future<EntryRequest> getEntryRequest(
KytheGetKytheEntriesParams parameters) async {
- AnalysisResult result = new MockAnalysisResult();
+ var result = new MockResolvedUnitResult();
return new DartEntryRequestImpl(resourceProvider, result);
}
}
diff --git a/pkg/analyzer_plugin/test/plugin/mocks.dart b/pkg/analyzer_plugin/test/plugin/mocks.dart
index 3e7d651..79bb3bb 100644
--- a/pkg/analyzer_plugin/test/plugin/mocks.dart
+++ b/pkg/analyzer_plugin/test/plugin/mocks.dart
@@ -5,6 +5,7 @@
import 'dart:async';
import 'dart:collection';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
@@ -56,22 +57,6 @@
Future<Null> performWork() => new Future.value(null);
}
-class MockAnalysisResult implements AnalysisResult {
- @override
- final List<AnalysisError> errors;
-
- @override
- final LineInfo lineInfo;
-
- @override
- final String path;
-
- MockAnalysisResult({this.errors, this.lineInfo, this.path});
-
- @override
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
-
class MockChannel implements PluginCommunicationChannel {
bool _closed = false;
@@ -143,6 +128,22 @@
}
}
+class MockResolvedUnitResult implements ResolvedUnitResult {
+ @override
+ final List<AnalysisError> errors;
+
+ @override
+ final LineInfo lineInfo;
+
+ @override
+ final String path;
+
+ MockResolvedUnitResult({this.errors, this.lineInfo, this.path});
+
+ @override
+ noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
class MockResourceProvider implements ResourceProvider {
@override
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
diff --git a/pkg/analyzer_plugin/test/plugin/navigation_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/navigation_mixin_test.dart
index 7996888..f4f2ffa 100644
--- a/pkg/analyzer_plugin/test/plugin/navigation_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/navigation_mixin_test.dart
@@ -5,15 +5,13 @@
import 'dart:async';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer_plugin/plugin/navigation_mixin.dart';
import 'package:analyzer_plugin/protocol/protocol.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analyzer_plugin/protocol/protocol_generated.dart';
import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
import 'package:analyzer_plugin/utilities/navigation/navigation.dart';
-import 'package:path/src/context.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -24,9 +22,7 @@
}
@reflectiveTest
-class NavigationMixinTest {
- MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
-
+class NavigationMixinTest with ResourceProviderMixin {
String packagePath1;
String filePath1;
ContextRoot contextRoot1;
@@ -35,11 +31,9 @@
_TestServerPlugin plugin;
void setUp() {
- Context pathContext = resourceProvider.pathContext;
-
- packagePath1 = resourceProvider.convertPath('/package1');
- filePath1 = pathContext.join(packagePath1, 'lib', 'test.dart');
- resourceProvider.newFile(filePath1, '');
+ packagePath1 = convertPath('/package1');
+ filePath1 = join(packagePath1, 'lib', 'test.dart');
+ newFile(filePath1);
contextRoot1 = new ContextRoot(packagePath1, <String>[]);
channel = new MockChannel();
@@ -109,7 +103,7 @@
@override
Future<NavigationRequest> getNavigationRequest(
AnalysisGetNavigationParams parameters) async {
- AnalysisResult result = new MockAnalysisResult(path: parameters.file);
+ var result = new MockResolvedUnitResult(path: parameters.file);
return new DartNavigationRequestImpl(
resourceProvider, parameters.offset, parameters.length, result);
}
diff --git a/pkg/analyzer_plugin/test/plugin/occurrences_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/occurrences_mixin_test.dart
index 6555427..cf2b96f 100644
--- a/pkg/analyzer_plugin/test/plugin/occurrences_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/occurrences_mixin_test.dart
@@ -5,15 +5,13 @@
import 'dart:async';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer_plugin/plugin/occurrences_mixin.dart';
import 'package:analyzer_plugin/protocol/protocol.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analyzer_plugin/protocol/protocol_generated.dart';
import 'package:analyzer_plugin/src/utilities/occurrences/occurrences.dart';
import 'package:analyzer_plugin/utilities/occurrences/occurrences.dart';
-import 'package:path/src/context.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -24,9 +22,7 @@
}
@reflectiveTest
-class OccurrencesMixinTest {
- MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
-
+class OccurrencesMixinTest with ResourceProviderMixin {
String packagePath1;
String filePath1;
ContextRoot contextRoot1;
@@ -35,11 +31,9 @@
_TestServerPlugin plugin;
void setUp() {
- Context pathContext = resourceProvider.pathContext;
-
- packagePath1 = resourceProvider.convertPath('/package1');
- filePath1 = pathContext.join(packagePath1, 'lib', 'test.dart');
- resourceProvider.newFile(filePath1, '');
+ packagePath1 = convertPath('/package1');
+ filePath1 = join(packagePath1, 'lib', 'test.dart');
+ newFile(filePath1);
contextRoot1 = new ContextRoot(packagePath1, <String>[]);
channel = new MockChannel();
@@ -120,7 +114,7 @@
@override
Future<OccurrencesRequest> getOccurrencesRequest(String path) async {
- AnalysisResult result = new MockAnalysisResult(path: path);
+ var result = new MockResolvedUnitResult(path: path);
return new DartOccurrencesRequestImpl(resourceProvider, result);
}
}
diff --git a/pkg/analyzer_plugin/test/plugin/outline_mixin_test.dart b/pkg/analyzer_plugin/test/plugin/outline_mixin_test.dart
index 2ac58ad..cd15cfa 100644
--- a/pkg/analyzer_plugin/test/plugin/outline_mixin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/outline_mixin_test.dart
@@ -5,15 +5,13 @@
import 'dart:async';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer_plugin/plugin/outline_mixin.dart';
import 'package:analyzer_plugin/protocol/protocol.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analyzer_plugin/protocol/protocol_generated.dart';
import 'package:analyzer_plugin/src/utilities/outline/outline.dart';
import 'package:analyzer_plugin/utilities/outline/outline.dart';
-import 'package:path/src/context.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -24,9 +22,7 @@
}
@reflectiveTest
-class OutlineMixinTest {
- MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
-
+class OutlineMixinTest with ResourceProviderMixin {
String packagePath1;
String filePath1;
ContextRoot contextRoot1;
@@ -35,11 +31,9 @@
_TestServerPlugin plugin;
void setUp() {
- Context pathContext = resourceProvider.pathContext;
-
- packagePath1 = resourceProvider.convertPath('/package1');
- filePath1 = pathContext.join(packagePath1, 'lib', 'test.dart');
- resourceProvider.newFile(filePath1, '');
+ packagePath1 = convertPath('/package1');
+ filePath1 = join(packagePath1, 'lib', 'test.dart');
+ newFile(filePath1);
contextRoot1 = new ContextRoot(packagePath1, <String>[]);
channel = new MockChannel();
@@ -94,7 +88,7 @@
@override
Future<OutlineRequest> getOutlineRequest(String path) async {
- AnalysisResult result = new MockAnalysisResult(path: path);
+ var result = new MockResolvedUnitResult(path: path);
return new DartOutlineRequestImpl(resourceProvider, result);
}
}
diff --git a/pkg/analyzer_plugin/test/plugin/plugin_test.dart b/pkg/analyzer_plugin/test/plugin/plugin_test.dart
index 0356e77..118f33e 100644
--- a/pkg/analyzer_plugin/test/plugin/plugin_test.dart
+++ b/pkg/analyzer_plugin/test/plugin/plugin_test.dart
@@ -5,12 +5,11 @@
import 'dart:async';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer_plugin/protocol/protocol.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analyzer_plugin/protocol/protocol_generated.dart';
-import 'package:path/src/context.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -21,9 +20,7 @@
}
@reflectiveTest
-class ServerPluginTest {
- MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
-
+class ServerPluginTest with ResourceProviderMixin {
MockChannel channel;
_TestServerPlugin plugin;
@@ -36,16 +33,14 @@
ContextRoot contextRoot2;
void setUp() {
- Context pathContext = resourceProvider.pathContext;
-
- packagePath1 = resourceProvider.convertPath('/package1');
- filePath1 = pathContext.join(packagePath1, 'lib', 'test.dart');
- resourceProvider.newFile(filePath1, '');
+ packagePath1 = convertPath('/package1');
+ filePath1 = join(packagePath1, 'lib', 'test.dart');
+ newFile(filePath1);
contextRoot1 = new ContextRoot(packagePath1, <String>[]);
- packagePath2 = resourceProvider.convertPath('/package2');
- filePath2 = pathContext.join(packagePath2, 'lib', 'test.dart');
- resourceProvider.newFile(filePath2, '');
+ packagePath2 = convertPath('/package2');
+ filePath2 = join(packagePath2, 'lib', 'test.dart');
+ newFile(filePath2);
contextRoot2 = new ContextRoot(packagePath2, <String>[]);
channel = new MockChannel();
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
index 0f8e505..34ec98d 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
@@ -4,14 +4,12 @@
import 'dart:async';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/standard_resolution_map.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/context/source.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/element/inheritance_manager2.dart';
-import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/testing/test_type_provider.dart';
@@ -33,7 +31,7 @@
});
}
-abstract class BuilderTestMixin {
+mixin BuilderTestMixin implements AbstractContextTest {
SourceEdit getEdit(DartChangeBuilder builder) {
SourceChange sourceChange = builder.sourceChange;
expect(sourceChange, isNotNull);
@@ -55,14 +53,19 @@
expect(fileEdit, isNotNull);
return fileEdit.edits;
}
+
+ /// Return a newly created Dart change builder.
+ DartChangeBuilderImpl newBuilder() =>
+ new DartChangeBuilder(session) as DartChangeBuilderImpl;
}
@reflectiveTest
-class DartChangeBuilderImplTest extends AbstractContextTest {
+class DartChangeBuilderImplTest extends AbstractContextTest
+ with BuilderTestMixin {
test_createFileEditBuilder() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
addSource(path, 'library test;');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
DartFileEditBuilderImpl fileEditBuilder =
await builder.createFileEditBuilder(path);
expect(fileEditBuilder, const TypeMatcher<DartFileEditBuilder>());
@@ -387,11 +390,11 @@
}
test_writeClassDeclaration_interfaces() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
addSource(path, 'class A {}');
DartType typeA = await _getType(path, 'A');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(0, (EditBuilder builder) {
(builder as DartEditBuilder)
@@ -404,10 +407,10 @@
}
test_writeClassDeclaration_isAbstract() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
addSource(path, '');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(0, (EditBuilder builder) {
(builder as DartEditBuilder)
@@ -419,10 +422,10 @@
}
test_writeClassDeclaration_memberWriter() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
addSource(path, '');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(0, (EditBuilder builder) {
(builder as DartEditBuilder).writeClassDeclaration('C',
@@ -436,11 +439,11 @@
}
test_writeClassDeclaration_mixins_noSuperclass() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
addSource(path, 'class A {}');
DartType typeA = await _getType(path, 'A');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(0, (EditBuilder builder) {
(builder as DartEditBuilder)
@@ -453,12 +456,12 @@
}
test_writeClassDeclaration_mixins_superclass() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
addSource(path, 'class A {} class B {}');
DartType typeA = await _getType(path, 'A');
DartType typeB = await _getType(path, 'B');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(0, (EditBuilder builder) {
(builder as DartEditBuilder)
@@ -471,10 +474,10 @@
}
test_writeClassDeclaration_nameGroupName() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
addSource(path, '');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(0, (EditBuilder builder) {
(builder as DartEditBuilder)
@@ -493,11 +496,11 @@
}
test_writeClassDeclaration_superclass() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
addSource(path, 'class B {}');
DartType typeB = await _getType(path, 'B');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(0, (EditBuilder builder) {
(builder as DartEditBuilder).writeClassDeclaration('C',
@@ -516,10 +519,10 @@
}
test_writeConstructorDeclaration_bodyWriter() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
addSource(path, 'class C {}');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (DartFileEditBuilder builder) {
builder.addInsertion(9, (DartEditBuilder builder) {
builder.writeConstructorDeclaration('A', bodyWriter: () {
@@ -532,7 +535,7 @@
}
test_writeConstructorDeclaration_fieldNames() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
addSource(path, r'''
class C {
final int a;
@@ -540,7 +543,7 @@
}
''');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (DartFileEditBuilder builder) {
builder.addInsertion(42, (DartEditBuilder builder) {
builder.writeConstructorDeclaration('A', fieldNames: ['a', 'bb']);
@@ -551,10 +554,10 @@
}
test_writeConstructorDeclaration_initializerWriter() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
addSource(path, 'class C {}');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (DartFileEditBuilder builder) {
builder.addInsertion(9, (DartEditBuilder builder) {
builder.writeConstructorDeclaration('A', initializerWriter: () {
@@ -567,10 +570,10 @@
}
test_writeConstructorDeclaration_parameterWriter() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
addSource(path, 'class C {}');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (DartFileEditBuilder builder) {
builder.addInsertion(9, (DartEditBuilder builder) {
builder.writeConstructorDeclaration('A', parameterWriter: () {
@@ -583,11 +586,11 @@
}
test_writeFieldDeclaration_initializerWriter() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = 'class A {}';
addSource(path, content);
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
(builder as DartEditBuilder).writeFieldDeclaration('f',
@@ -601,11 +604,11 @@
}
test_writeFieldDeclaration_isConst() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = 'class A {}';
addSource(path, content);
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
(builder as DartEditBuilder).writeFieldDeclaration('f', isConst: true);
@@ -616,11 +619,11 @@
}
test_writeFieldDeclaration_isConst_isFinal() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = 'class A {}';
addSource(path, content);
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
(builder as DartEditBuilder)
@@ -632,12 +635,12 @@
}
test_writeFieldDeclaration_isConst_type() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = 'class A {}';
addSource(path, content);
DartType typeA = await _getType(path, 'A');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
(builder as DartEditBuilder)
@@ -649,11 +652,11 @@
}
test_writeFieldDeclaration_isFinal() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = 'class A {}';
addSource(path, content);
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
(builder as DartEditBuilder).writeFieldDeclaration('f', isFinal: true);
@@ -664,12 +667,12 @@
}
test_writeFieldDeclaration_isFinal_type() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = 'class A {}';
addSource(path, content);
DartType typeA = await _getType(path, 'A');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
(builder as DartEditBuilder)
@@ -681,11 +684,11 @@
}
test_writeFieldDeclaration_isStatic() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = 'class A {}';
addSource(path, content);
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
(builder as DartEditBuilder).writeFieldDeclaration('f', isStatic: true);
@@ -696,11 +699,11 @@
}
test_writeFieldDeclaration_nameGroupName() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = 'class A {}';
addSource(path, content);
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
(builder as DartEditBuilder)
@@ -721,12 +724,12 @@
}
test_writeFieldDeclaration_type_typeGroupName() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = 'class A {} class B {}';
addSource(path, content);
DartType typeA = await _getType(path, 'A');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
(builder as DartEditBuilder)
@@ -747,11 +750,11 @@
}
test_writeFunctionDeclaration_noReturnType_noParams_body() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = '';
addSource(path, content);
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(0, (EditBuilder builder) {
(builder as DartEditBuilder).writeFunctionDeclaration('fib',
@@ -765,11 +768,11 @@
}
test_writeFunctionDeclaration_noReturnType_noParams_noBody() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = '';
addSource(path, content);
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(0, (EditBuilder builder) {
(builder as DartEditBuilder)
@@ -788,11 +791,11 @@
}
test_writeFunctionDeclaration_noReturnType_params_noBody() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = '';
addSource(path, content);
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(0, (EditBuilder builder) {
(builder as DartEditBuilder).writeFunctionDeclaration('fib',
@@ -806,13 +809,13 @@
}
test_writeFunctionDeclaration_returnType_noParams_noBody() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = 'class A {}';
addSource(path, content);
DartType typeA = await _getType(path, 'A');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(0, (EditBuilder builder) {
(builder as DartEditBuilder).writeFunctionDeclaration('fib',
@@ -831,11 +834,11 @@
}
test_writeGetterDeclaration_bodyWriter() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = 'class A {}';
addSource(path, content);
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
(builder as DartEditBuilder).writeGetterDeclaration('g',
@@ -849,11 +852,11 @@
}
test_writeGetterDeclaration_isStatic() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = 'class A {}';
addSource(path, content);
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
(builder as DartEditBuilder)
@@ -865,11 +868,11 @@
}
test_writeGetterDeclaration_nameGroupName() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = 'class A {}';
addSource(path, content);
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
(builder as DartEditBuilder)
@@ -890,12 +893,12 @@
}
test_writeGetterDeclaration_returnType() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = 'class A {} class B {}';
addSource(path, content);
DartType typeA = await _getType(path, 'A');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
(builder as DartEditBuilder).writeGetterDeclaration('g',
@@ -916,7 +919,7 @@
}
test_writeLocalVariableDeclaration_noType_initializer() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = '''
void f() {
@@ -924,7 +927,7 @@
addSource(path, content);
await driver.getResult(path);
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(11, (EditBuilder builder) {
(builder as DartEditBuilder).writeLocalVariableDeclaration('foo',
@@ -938,7 +941,7 @@
}
test_writeLocalVariableDeclaration_noType_noInitializer() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = '''
void f() {
@@ -946,7 +949,7 @@
addSource(path, content);
await driver.getResult(path);
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(11, (EditBuilder builder) {
(builder as DartEditBuilder)
@@ -965,7 +968,7 @@
}
test_writeLocalVariableDeclaration_noType_noInitializer_const() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = '''
void f() {
@@ -973,7 +976,7 @@
addSource(path, content);
await driver.getResult(path);
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(11, (EditBuilder builder) {
(builder as DartEditBuilder)
@@ -985,7 +988,7 @@
}
test_writeLocalVariableDeclaration_noType_noInitializer_final() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = '''
void f() {
@@ -993,7 +996,7 @@
addSource(path, content);
await driver.getResult(path);
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(11, (EditBuilder builder) {
(builder as DartEditBuilder)
@@ -1005,7 +1008,7 @@
}
test_writeLocalVariableDeclaration_type_initializer() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = '''
void f() {
@@ -1014,9 +1017,9 @@
addSource(path, content);
CompilationUnit unit = (await driver.getResult(path))?.unit;
- ClassDeclaration A = unit.declarations[1];
+ ClassDeclaration A = unit.declarations[1] as ClassDeclaration;
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(11, (EditBuilder builder) {
(builder as DartEditBuilder).writeLocalVariableDeclaration('foo',
@@ -1030,7 +1033,7 @@
}
test_writeLocalVariableDeclaration_type_noInitializer() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = '''
void f() {
@@ -1039,9 +1042,9 @@
addSource(path, content);
CompilationUnit unit = (await driver.getResult(path))?.unit;
- ClassDeclaration A = unit.declarations[1];
+ ClassDeclaration A = unit.declarations[1] as ClassDeclaration;
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(11, (EditBuilder builder) {
(builder as DartEditBuilder).writeLocalVariableDeclaration('foo',
@@ -1060,7 +1063,7 @@
}
test_writeLocalVariableDeclaration_type_noInitializer_final() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = '''
void f() {
@@ -1069,9 +1072,9 @@
addSource(path, content);
CompilationUnit unit = (await driver.getResult(path))?.unit;
- ClassDeclaration A = unit.declarations[1];
+ ClassDeclaration A = unit.declarations[1] as ClassDeclaration;
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(11, (EditBuilder builder) {
(builder as DartEditBuilder).writeLocalVariableDeclaration('foo',
@@ -1090,11 +1093,11 @@
}
test_writeMixinDeclaration_interfaces() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
addSource(path, 'class A {}');
DartType typeA = await _getType(path, 'A');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(0, (EditBuilder builder) {
(builder as DartEditBuilder)
@@ -1107,12 +1110,12 @@
}
test_writeMixinDeclaration_interfacesAndSuperclassConstraints() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
addSource(path, 'class A {} class B {}');
DartType typeA = await _getType(path, 'A');
DartType typeB = await _getType(path, 'B');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(0, (EditBuilder builder) {
(builder as DartEditBuilder).writeMixinDeclaration('M',
@@ -1125,10 +1128,10 @@
}
test_writeMixinDeclaration_memberWriter() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
addSource(path, '');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(0, (EditBuilder builder) {
(builder as DartEditBuilder).writeMixinDeclaration('M',
@@ -1142,10 +1145,10 @@
}
test_writeMixinDeclaration_nameGroupName() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
addSource(path, '');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(0, (EditBuilder builder) {
(builder as DartEditBuilder)
@@ -1164,11 +1167,11 @@
}
test_writeMixinDeclaration_superclassConstraints() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
addSource(path, 'class A {}');
DartType typeA = await _getType(path, 'A');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(0, (EditBuilder builder) {
(builder as DartEditBuilder)
@@ -1529,6 +1532,27 @@
);
}
+ test_writeOverride_method_returnVoid_abstract() async {
+ await _assertWriteOverride(
+ content: '''
+abstract class A {
+ void test();
+}
+class B extends A {
+}
+''',
+ nameToOverride: 'test',
+ expected: '''
+ @override
+ void test() {
+ // TODO: implement test
+ }
+''',
+ displayText: 'test() { … }',
+ selection: new SourceRange(109, 0),
+ );
+ }
+
test_writeOverride_method_voidAsTypeArgument_abstract() async {
await _assertWriteOverride(
content: '''
@@ -1590,6 +1614,7 @@
}
''',
displayText: 'value(int value) { … }',
+ selection: new SourceRange(133, 0),
);
}
@@ -1616,11 +1641,11 @@
}
test_writeParameter() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = 'class A {}';
addSource(path, content);
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
(builder as DartEditBuilder).writeParameter('a');
@@ -1631,12 +1656,12 @@
}
test_writeParameter_type() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = 'class A {}';
addSource(path, content);
DartType typeA = await _getType(path, 'A');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
(builder as DartEditBuilder).writeParameter('a', type: typeA);
@@ -1647,7 +1672,7 @@
}
test_writeParameterMatchingArgument() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = r'''
f() {}
g() {
@@ -1657,13 +1682,14 @@
''';
addSource(path, content);
CompilationUnit unit = (await driver.getResult(path))?.unit;
- FunctionDeclaration g = unit.declarations[1];
- BlockFunctionBody body = g.functionExpression.body;
- ExpressionStatement statement = body.block.statements[0];
- MethodInvocation invocation = statement.expression;
+ FunctionDeclaration g = unit.declarations[1] as FunctionDeclaration;
+ BlockFunctionBody body = g.functionExpression.body as BlockFunctionBody;
+ ExpressionStatement statement =
+ body.block.statements[0] as ExpressionStatement;
+ MethodInvocation invocation = statement.expression as MethodInvocation;
Expression argument = invocation.argumentList.arguments[0];
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(2, (EditBuilder builder) {
(builder as DartEditBuilder)
@@ -1675,17 +1701,17 @@
}
test_writeParameters_named() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = 'f(int a, {bool b = false, String c}) {}';
addSource(path, content);
CompilationUnit unit = (await driver.getResult(path))?.unit;
- FunctionDeclaration f = unit.declarations[0];
+ FunctionDeclaration f = unit.declarations[0] as FunctionDeclaration;
FormalParameterList parameters = f.functionExpression.parameters;
Iterable<ParameterElement> elements = parameters.parameters
.map(resolutionMap.elementDeclaredByFormalParameter);
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
(builder as DartEditBuilder).writeParameters(elements);
@@ -1697,16 +1723,16 @@
}
test_writeParameters_positional() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = 'f(int a, [bool b = false, String c]) {}';
addSource(path, content);
CompilationUnit unit = (await driver.getResult(path))?.unit;
- FunctionDeclaration f = unit.declarations[0];
+ FunctionDeclaration f = unit.declarations[0] as FunctionDeclaration;
FormalParameterList parameters = f.functionExpression.parameters;
Iterable<ParameterElement> elements = parameters.parameters
.map(resolutionMap.elementDeclaredByFormalParameter);
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
(builder as DartEditBuilder).writeParameters(elements);
@@ -1718,16 +1744,16 @@
}
test_writeParameters_required() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = 'f(int i, String s) {}';
addSource(path, content);
CompilationUnit unit = (await driver.getResult(path))?.unit;
- FunctionDeclaration f = unit.declarations[0];
+ FunctionDeclaration f = unit.declarations[0] as FunctionDeclaration;
FormalParameterList parameters = f.functionExpression.parameters;
Iterable<ParameterElement> elements = parameters.parameters
.map(resolutionMap.elementDeclaredByFormalParameter);
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
(builder as DartEditBuilder).writeParameters(elements);
@@ -1738,19 +1764,20 @@
}
test_writeParametersMatchingArguments_named() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = '''
f(int i, String s) {
g(s, index: i);
}''';
addSource(path, content);
CompilationUnit unit = (await driver.getResult(path))?.unit;
- FunctionDeclaration f = unit.declarations[0];
- BlockFunctionBody body = f.functionExpression.body;
- ExpressionStatement statement = body.block.statements[0];
- MethodInvocation invocation = statement.expression;
+ FunctionDeclaration f = unit.declarations[0] as FunctionDeclaration;
+ BlockFunctionBody body = f.functionExpression.body as BlockFunctionBody;
+ ExpressionStatement statement =
+ body.block.statements[0] as ExpressionStatement;
+ MethodInvocation invocation = statement.expression as MethodInvocation;
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
(builder as DartEditBuilder)
@@ -1762,19 +1789,20 @@
}
test_writeParametersMatchingArguments_required() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = '''
f(int i, String s) {
g(s, i);
}''';
addSource(path, content);
CompilationUnit unit = (await driver.getResult(path))?.unit;
- FunctionDeclaration f = unit.declarations[0];
- BlockFunctionBody body = f.functionExpression.body;
- ExpressionStatement statement = body.block.statements[0];
- MethodInvocation invocation = statement.expression;
+ FunctionDeclaration f = unit.declarations[0] as FunctionDeclaration;
+ BlockFunctionBody body = f.functionExpression.body as BlockFunctionBody;
+ ExpressionStatement statement =
+ body.block.statements[0] as ExpressionStatement;
+ MethodInvocation invocation = statement.expression as MethodInvocation;
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
(builder as DartEditBuilder)
@@ -1786,14 +1814,14 @@
}
test_writeReference_method() async {
- String aPath = provider.convertPath('/a.dart');
+ String aPath = convertPath('/a.dart');
addSource(aPath, r'''
class A {
void foo() {}
}
''');
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = r'''
import 'a.dart';
''';
@@ -1802,7 +1830,7 @@
var aElement = await _getClassElement(aPath, 'A');
var fooElement = aElement.methods[0];
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (DartFileEditBuilder builder) {
builder.addInsertion(content.length - 1, (DartEditBuilder builder) {
builder.writeReference(fooElement);
@@ -1813,10 +1841,10 @@
}
test_writeReference_topLevel_hasImport_noPrefix() async {
- String aPath = provider.convertPath('/a.dart');
+ String aPath = convertPath('/a.dart');
addSource(aPath, 'const a = 42;');
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = r'''
import 'a.dart';
''';
@@ -1824,7 +1852,7 @@
var aElement = await _getTopLevelAccessorElement(aPath, 'a');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (DartFileEditBuilder builder) {
builder.addInsertion(content.length - 1, (DartEditBuilder builder) {
builder.writeReference(aElement);
@@ -1835,10 +1863,10 @@
}
test_writeReference_topLevel_hasImport_prefix() async {
- String aPath = provider.convertPath('/a.dart');
+ String aPath = convertPath('/a.dart');
addSource(aPath, 'const a = 42;');
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = r'''
import 'a.dart' as p;
''';
@@ -1846,7 +1874,7 @@
var aElement = await _getTopLevelAccessorElement(aPath, 'a');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (DartFileEditBuilder builder) {
builder.addInsertion(content.length - 1, (DartEditBuilder builder) {
builder.writeReference(aElement);
@@ -1857,16 +1885,16 @@
}
test_writeReference_topLevel_noImport() async {
- String aPath = provider.convertPath('/a.dart');
+ String aPath = convertPath('/a.dart');
addSource(aPath, 'const a = 42;');
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = '';
addSource(path, content);
var aElement = await _getTopLevelAccessorElement(aPath, 'a');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (DartFileEditBuilder builder) {
builder.addInsertion(content.length - 1, (DartEditBuilder builder) {
builder.writeReference(aElement);
@@ -1879,12 +1907,12 @@
}
test_writeType_dynamic() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = 'class A {}';
addSource(path, content);
CompilationUnit unit = (await driver.getResult(path))?.unit;
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
(builder as DartEditBuilder).writeType(resolutionMap
@@ -1925,13 +1953,13 @@
}
test_writeType_genericType() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = 'class A {} class B<E> {}';
addSource(path, content);
InterfaceType typeA = await _getType(path, 'A');
InterfaceType typeB = await _getType(path, 'B');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
(builder as DartEditBuilder).writeType(typeB.instantiate([typeA]));
@@ -1942,12 +1970,12 @@
}
test_writeType_groupName() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = 'class A {} class B extends A {} class C extends B {}';
addSource(path, content);
DartType typeC = await _getType(path, 'C');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
(builder as DartEditBuilder).writeType(typeC, groupName: 'type');
@@ -1964,12 +1992,12 @@
}
test_writeType_groupName_addSupertypeProposals() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = 'class A {} class B extends A {} class C extends B {}';
addSource(path, content);
DartType typeC = await _getType(path, 'C');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
(builder as DartEditBuilder)
@@ -1997,14 +2025,14 @@
}
test_writeType_groupName_invalidType() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = 'class A<T> {}';
addSource(path, content);
InterfaceType typeA = await _getType(path, 'A');
DartType typeT = typeA.typeParameters.single.type;
- var builder = new DartChangeBuilder(session);
+ var builder = newBuilder();
await builder.addFileEdit(path, (builder) {
builder.addInsertion(content.length, (builder) {
// "T" cannot be written, because we are outside of "A".
@@ -2024,11 +2052,11 @@
}
test_writeType_null() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = 'class A {}';
addSource(path, content);
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
(builder as DartEditBuilder).writeType(null);
@@ -2039,8 +2067,8 @@
}
test_writeType_prefixGenerator() async {
- String aPath = provider.convertPath('/a.dart');
- String bPath = provider.convertPath('/b.dart');
+ String aPath = convertPath('/a.dart');
+ String bPath = convertPath('/b.dart');
addSource(aPath, r'''
class A1 {}
@@ -2050,7 +2078,7 @@
class B {}
''');
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = '';
addSource(path, content);
@@ -2063,7 +2091,7 @@
return '_prefix${nextPrefixIndex++}';
}
- var builder = new DartChangeBuilder(session);
+ var builder = newBuilder();
await builder.addFileEdit(path, (builder) {
builder.addInsertion(content.length - 1, (builder) {
builder.writeType(a1.type);
@@ -2089,12 +2117,12 @@
}
test_writeType_required_dynamic() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = 'class A {}';
addSource(path, content);
CompilationUnit unit = (await driver.getResult(path))?.unit;
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
(builder as DartEditBuilder).writeType(
@@ -2111,12 +2139,12 @@
}
test_writeType_required_notNull() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = 'class A {}';
addSource(path, content);
DartType typeA = await _getType(path, 'A');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
(builder as DartEditBuilder).writeType(typeA, required: true);
@@ -2127,11 +2155,11 @@
}
test_writeType_required_null() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = 'class A {}';
addSource(path, content);
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
(builder as DartEditBuilder).writeType(null, required: true);
@@ -2142,12 +2170,12 @@
}
test_writeType_simpleType() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = 'class A {}';
addSource(path, content);
DartType typeA = await _getType(path, 'A');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
(builder as DartEditBuilder).writeType(typeA);
@@ -2167,11 +2195,11 @@
}
test_writeTypes_empty() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = 'class A {}';
addSource(path, content);
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
(builder as DartEditBuilderImpl).writeTypes([]);
@@ -2182,13 +2210,13 @@
}
test_writeTypes_noPrefix() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = 'class A {} class B {}';
addSource(path, content);
DartType typeA = await _getType(path, 'A');
DartType typeB = await _getType(path, 'B');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
(builder as DartEditBuilderImpl).writeTypes([typeA, typeB]);
@@ -2199,11 +2227,11 @@
}
test_writeTypes_null() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = 'class A {}';
addSource(path, content);
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
(builder as DartEditBuilderImpl).writeTypes(null);
@@ -2214,13 +2242,13 @@
}
test_writeTypes_prefix() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = 'class A {} class B {}';
addSource(path, content);
DartType typeA = await _getType(path, 'A');
DartType typeB = await _getType(path, 'B');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 1, (EditBuilder builder) {
(builder as DartEditBuilderImpl)
@@ -2233,9 +2261,9 @@
Future<void> _assertImportLibrary(
String initialCode, List<String> newUris, String expectedCode) async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
addSource(path, initialCode);
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (DartFileEditBuilder builder) {
for (String newUri in newUris) {
builder.importLibrary(Uri.parse(newUri));
@@ -2266,7 +2294,7 @@
String displayText,
SourceRange selection,
}) async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
addSource(path, content);
TypeSystem typeSystem = await session.typeSystem;
@@ -2279,10 +2307,10 @@
StringBuffer displayBuffer =
displayText != null ? new StringBuffer() : null;
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
builder.addInsertion(content.length - 2, (EditBuilder builder) {
- ExecutableElement element = inherited.element;
+ ExecutableElement element = inherited.element as ExecutableElement;
(builder as DartEditBuilder).writeOverride(
inherited,
displayTextBuffer: displayBuffer,
@@ -2299,13 +2327,13 @@
}
Future<void> _assertWriteType(String typeCode, {String declarations}) async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
String content = (declarations ?? '') + '$typeCode v;';
addSource(path, content);
var f = await _getTopLevelAccessorElement(path, 'v');
- var builder = new DartChangeBuilder(session);
+ var builder = newBuilder();
await builder.addFileEdit(path, (builder) {
builder.addInsertion(content.length - 1, (builder) {
builder.writeType(f.returnType);
@@ -2336,22 +2364,21 @@
class DartFileEditBuilderImplTest extends AbstractContextTest
with BuilderTestMixin {
TypeProvider get typeProvider {
- AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
- context.sourceFactory = new SourceFactoryImpl([new DartUriResolver(sdk)]);
- return new TestTypeProvider(context);
+ return new TestTypeProvider(null, driver);
}
test_convertFunctionFromSyncToAsync_closure() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
addSource(path, '''var f = () {}''');
CompilationUnit unit = (await driver.getResult(path))?.unit;
- TopLevelVariableDeclaration variable = unit.declarations[0];
+ TopLevelVariableDeclaration variable =
+ unit.declarations[0] as TopLevelVariableDeclaration;
FunctionBody body =
(variable.variables.variables[0].initializer as FunctionExpression)
.body;
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
(builder as DartFileEditBuilder)
.convertFunctionFromSyncToAsync(body, typeProvider);
@@ -2362,30 +2389,28 @@
}
test_convertFunctionFromSyncToAsync_topLevelFunction() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
addSource(path, 'String f() {}');
CompilationUnit unit = (await driver.getResult(path))?.unit;
- FunctionDeclaration function = unit.declarations[0];
+ FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
FunctionBody body = function.functionExpression.body;
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
(builder as DartFileEditBuilder)
.convertFunctionFromSyncToAsync(body, typeProvider);
});
List<SourceEdit> edits = getEdits(builder);
- expect(edits, hasLength(3));
+ expect(edits, hasLength(2));
expect(edits[0].replacement, equalsIgnoringWhitespace('async'));
- expect(
- edits[1].replacement, equalsIgnoringWhitespace("import 'dart:async';"));
- expect(edits[2].replacement, equalsIgnoringWhitespace('Future<String>'));
+ expect(edits[1].replacement, equalsIgnoringWhitespace('Future<String>'));
}
test_createEditBuilder() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
addSource(path, 'library test;');
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
int offset = 4;
int length = 5;
@@ -2400,37 +2425,35 @@
}
test_replaceTypeWithFuture() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
addSource(path, 'String f() {}');
CompilationUnit unit = (await driver.getResult(path))?.unit;
- FunctionDeclaration function = unit.declarations[0];
+ FunctionDeclaration function = unit.declarations[0] as FunctionDeclaration;
TypeAnnotation type = function.returnType;
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ DartChangeBuilderImpl builder = newBuilder();
await builder.addFileEdit(path, (FileEditBuilder builder) {
(builder as DartFileEditBuilder)
.replaceTypeWithFuture(type, typeProvider);
});
List<SourceEdit> edits = getEdits(builder);
- expect(edits, hasLength(2));
- expect(
- edits[0].replacement, equalsIgnoringWhitespace("import 'dart:async';"));
- expect(edits[1].replacement, equalsIgnoringWhitespace('Future<String>'));
+ expect(edits, hasLength(1));
+ expect(edits[0].replacement, equalsIgnoringWhitespace('Future<String>'));
}
}
@reflectiveTest
class DartLinkedEditBuilderImplTest extends AbstractContextTest {
test_addSuperTypesAsSuggestions() async {
- String path = provider.convertPath('/test.dart');
+ String path = convertPath('/test.dart');
addSource(path, '''
class A {}
class B extends A {}
class C extends B {}
''');
CompilationUnit unit = (await driver.getResult(path))?.unit;
- ClassDeclaration classC = unit.declarations[2];
+ ClassDeclaration classC = unit.declarations[2] as ClassDeclaration;
DartLinkedEditBuilderImpl builder = new DartLinkedEditBuilderImpl(null);
builder.addSuperTypesAsSuggestions(classC.declaredElement.type);
List<LinkedEditSuggestion> suggestions = builder.suggestions;
diff --git a/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart b/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart
index 45c0388..241ec1f 100644
--- a/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart
@@ -4,8 +4,8 @@
import 'dart:async';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/generated/parser.dart' as analyzer;
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
@@ -36,8 +36,8 @@
expect(nextOffset, equals(-1), reason: 'too many ^');
content = content.substring(0, completionOffset) +
content.substring(completionOffset + 1);
- testSource = addSource(provider.convertPath('/test.dart'), content);
- AnalysisResult result = await driver.getResult(testSource.fullName);
+ testSource = addSource('/test.dart', content);
+ ResolvedUnitResult result = await driver.getResult(testSource.fullName);
target = new CompletionTarget.forOffset(result.unit, completionOffset);
}
@@ -56,7 +56,7 @@
// Assert with parsed unit
assertCommon();
- AnalysisResult result = await driver.getResult(testSource.fullName);
+ ResolvedUnitResult result = await driver.getResult(testSource.fullName);
target = new CompletionTarget.forOffset(result.unit, completionOffset);
// Assert more with resolved unit
assertCommon();
diff --git a/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart b/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
index f85cb6f..f4c2eb8 100644
--- a/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
@@ -4,7 +4,7 @@
import 'dart:async';
-import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
import 'package:analyzer_plugin/src/utilities/completion/optype.dart';
@@ -107,11 +107,7 @@
test_AssertInitializer() async {
addTestSource('class C { C() : assert(^); }');
- await assertOpType(
- constructors: true,
- returnValue: true,
- typeNames: true,
- constructorBody: true);
+ await assertOpType(constructors: true, returnValue: true, typeNames: true);
}
test_AssignmentExpression_RHS() async {
@@ -427,25 +423,13 @@
methodBody: true);
}
- test_Block_keyword() async {
- addTestSource('class C { static C get instance => null; } main() {C.in^}');
- await assertOpType(
- constructors: true,
- prefixed: true,
- returnValue: true,
- typeNames: true,
- voidReturn: true,
- functionBody: true);
- }
-
- test_Block_static() async {
- addTestSource('class A {static foo() {^}}');
+ test_Block_in_constructor() async {
+ addTestSource('class A {A() {^}}');
await assertOpType(
constructors: true,
returnValue: true,
typeNames: true,
- staticMethodBody: true,
- methodBody: true,
+ constructorBody: true,
voidReturn: true);
}
@@ -469,13 +453,25 @@
voidReturn: true);
}
- test_Block_in_constructor() async {
- addTestSource('class A {A() {^}}');
+ test_Block_keyword() async {
+ addTestSource('class C { static C get instance => null; } main() {C.in^}');
+ await assertOpType(
+ constructors: true,
+ prefixed: true,
+ returnValue: true,
+ typeNames: true,
+ voidReturn: true,
+ functionBody: true);
+ }
+
+ test_Block_static() async {
+ addTestSource('class A {static foo() {^}}');
await assertOpType(
constructors: true,
returnValue: true,
typeNames: true,
- constructorBody: true,
+ staticMethodBody: true,
+ methodBody: true,
voidReturn: true);
}
@@ -557,7 +553,6 @@
returnValue: true,
typeNames: true,
voidReturn: true,
- methodBody: true,
kind: CompletionSuggestionKind.IDENTIFIER);
}
@@ -611,14 +606,40 @@
methodBody: true);
}
+ test_ConstructorFieldInitializer_name() async {
+ addTestSource(r'''
+class C {
+ final int foo;
+
+ C() : ^
+}
+''');
+ await assertOpType();
+ }
+
+ test_ConstructorFieldInitializer_value() async {
+ addTestSource(r'''
+class C {
+ final int foo;
+
+ C() : foo = ^
+}
+''');
+ await assertOpType(
+ constructors: true,
+ returnValue: true,
+ typeNames: true,
+ );
+ }
+
test_DefaultFormalParameter_named_expression() async {
// DefaultFormalParameter FormalParameterList MethodDeclaration
addTestSource('class A {a(blat: ^) { }}');
await assertOpType(
- constructors: true,
- returnValue: true,
- typeNames: true,
- methodBody: true);
+ constructors: true,
+ returnValue: true,
+ typeNames: true,
+ );
}
test_DoStatement() async {
@@ -698,33 +719,33 @@
// FormalParameterList MethodDeclaration
addTestSource('class A {a(b.^ f) { }}');
await assertOpType(
- constructors: true,
- returnValue: true,
- typeNames: true,
- prefixed: true,
- methodBody: true);
+ constructors: true,
+ returnValue: true,
+ typeNames: true,
+ prefixed: true,
+ );
}
test_FormalParameter_partialType2() async {
// FormalParameterList MethodDeclaration
addTestSource('class A {a(b.z^ f) { }}');
await assertOpType(
- constructors: true,
- returnValue: true,
- typeNames: true,
- prefixed: true,
- methodBody: true);
+ constructors: true,
+ returnValue: true,
+ typeNames: true,
+ prefixed: true,
+ );
}
test_FormalParameter_partialType3() async {
// FormalParameterList MethodDeclaration
addTestSource('class A {a(b.^) { }}');
await assertOpType(
- constructors: true,
- returnValue: true,
- typeNames: true,
- prefixed: true,
- methodBody: true);
+ constructors: true,
+ returnValue: true,
+ typeNames: true,
+ prefixed: true,
+ );
}
test_ForStatement_condition() async {
@@ -1604,7 +1625,7 @@
test_FormalParameterList() async {
// FormalParameterList MethodDeclaration
addTestSource('class A {a(^) { }}');
- await assertOpType(typeNames: true, methodBody: true);
+ await assertOpType(typeNames: true);
}
test_ForStatement_initializer() async {
@@ -1680,7 +1701,7 @@
addTestSource('''
/// some dartdoc ^
zoo(z) { } String name;''');
- await assertOpType(functionBody: true);
+ await assertOpType();
}
test_FunctionDeclaration_inLineDocComment2() async {
@@ -1688,7 +1709,7 @@
addTestSource('''
/// some ^dartdoc
zoo(z) { } String name;''');
- await assertOpType(functionBody: true);
+ await assertOpType();
}
test_FunctionDeclaration_inStarComment() async {
@@ -1706,13 +1727,13 @@
test_FunctionDeclaration_inStarDocComment() async {
// Comment FunctionDeclaration CompilationUnit
addTestSource('/** ^ */ zoo(z) { } String name; ');
- await assertOpType(functionBody: true);
+ await assertOpType();
}
test_FunctionDeclaration_inStarDocComment2() async {
// Comment FunctionDeclaration CompilationUnit
addTestSource('/** *^/ zoo(z) { } String name;');
- await assertOpType(functionBody: true);
+ await assertOpType();
}
test_FunctionDeclaration_returnType() async {
@@ -1743,7 +1764,7 @@
addTestSource('''
/// some dartdoc
^ zoo(z) { } String name;''');
- await assertOpType(typeNames: true, functionBody: true);
+ await assertOpType(typeNames: true);
}
test_FunctionDeclaration_returnType_afterLineDocComment2() async {
@@ -1751,7 +1772,7 @@
addTestSource('''
/// some dartdoc
^ zoo(z) { } String name;''');
- await assertOpType(typeNames: true, functionBody: true);
+ await assertOpType(typeNames: true);
}
test_FunctionDeclaration_returnType_afterStarComment() async {
@@ -1769,19 +1790,19 @@
test_FunctionDeclaration_returnType_afterStarDocComment() async {
// FunctionDeclaration CompilationUnit
addTestSource('/** */ ^ zoo(z) { } String name;');
- await assertOpType(typeNames: true, functionBody: true);
+ await assertOpType(typeNames: true);
}
test_FunctionDeclaration_returnType_afterStarDocComment2() async {
// FunctionDeclaration CompilationUnit
addTestSource('/** */^ zoo(z) { } String name;');
- await assertOpType(typeNames: true, functionBody: true);
+ await assertOpType(typeNames: true);
}
test_FunctionExpression() async {
// BlockFunctionBody FunctionExpression FunctionDeclaration
addTestSource('main()^ { int b = 2; b++; b. }');
- await assertOpType(functionBody: true);
+ await assertOpType();
}
test_FunctionExpressionInvocation() async {
@@ -1898,7 +1919,7 @@
class C2 {
/// some dartdoc ^
zoo(z) { } String name; }''');
- await assertOpType(methodBody: true);
+ await assertOpType();
}
test_MethodDeclaration_inLineDocComment2() async {
@@ -1907,7 +1928,7 @@
class C2 {
/// some ^dartdoc
zoo(z) { } String name; }''');
- await assertOpType(methodBody: true);
+ await assertOpType();
}
test_MethodDeclaration_inStarComment() async {
@@ -1925,13 +1946,13 @@
test_MethodDeclaration_inStarDocComment() async {
// Comment MethodDeclaration ClassDeclaration CompilationUnit
addTestSource('class C2 {/** ^ */ zoo(z) { } String name; }');
- await assertOpType(methodBody: true);
+ await assertOpType();
}
test_MethodDeclaration_inStarDocComment2() async {
// Comment MethodDeclaration ClassDeclaration CompilationUnit
addTestSource('class C2 {/** *^/ zoo(z) { } String name; }');
- await assertOpType(methodBody: true);
+ await assertOpType();
}
test_MethodDeclaration_returnType() async {
@@ -1965,7 +1986,7 @@
class C2 {
/// some dartdoc
^ zoo(z) { } String name; }''');
- await assertOpType(typeNames: true, methodBody: true);
+ await assertOpType(typeNames: true);
}
test_MethodDeclaration_returnType_afterLineDocComment2() async {
@@ -1974,7 +1995,7 @@
class C2 {
/// some dartdoc
^ zoo(z) { } String name; }''');
- await assertOpType(typeNames: true, methodBody: true);
+ await assertOpType(typeNames: true);
}
test_MethodDeclaration_returnType_afterStarComment() async {
@@ -1992,13 +2013,13 @@
test_MethodDeclaration_returnType_afterStarDocComment() async {
// MethodDeclaration ClassDeclaration CompilationUnit
addTestSource('class C2 {/** */ ^ zoo(z) { } String name; }');
- await assertOpType(typeNames: true, methodBody: true);
+ await assertOpType(typeNames: true);
}
test_MethodDeclaration_returnType_afterStarDocComment2() async {
// MethodDeclaration ClassDeclaration CompilationUnit
addTestSource('class C2 {/** */^ zoo(z) { } String name; }');
- await assertOpType(typeNames: true, methodBody: true);
+ await assertOpType(typeNames: true);
}
test_NamedExpression() async {
@@ -2043,49 +2064,49 @@
test_SimpleFormalParameter_name1() async {
// SimpleIdentifier SimpleFormalParameter FormalParameterList
addTestSource('m(String na^) {}');
- await assertOpType(typeNames: false, functionBody: true);
+ await assertOpType(typeNames: false);
}
test_SimpleFormalParameter_name2() async {
// SimpleIdentifier SimpleFormalParameter FormalParameterList
addTestSource('m(int first, String na^) {}');
- await assertOpType(typeNames: false, functionBody: true);
+ await assertOpType(typeNames: false);
}
test_SimpleFormalParameter_type_optionalNamed() async {
// SimpleIdentifier DefaultFormalParameter FormalParameterList
addTestSource('m({Str^}) {}');
- await assertOpType(typeNames: true, functionBody: true);
+ await assertOpType(typeNames: true);
}
test_SimpleFormalParameter_type_optionalPositional() async {
// SimpleIdentifier DefaultFormalParameter FormalParameterList
addTestSource('m([Str^]) {}');
- await assertOpType(typeNames: true, functionBody: true);
+ await assertOpType(typeNames: true);
}
test_SimpleFormalParameter_type_withName() async {
// SimpleIdentifier SimpleFormalParameter FormalParameterList
addTestSource('m(Str^ name) {}');
- await assertOpType(typeNames: true, functionBody: true);
+ await assertOpType(typeNames: true);
}
test_SimpleFormalParameter_type_withoutName1() async {
// SimpleIdentifier SimpleFormalParameter FormalParameterList
addTestSource('m(Str^) {}');
- await assertOpType(typeNames: true, functionBody: true);
+ await assertOpType(typeNames: true);
}
test_SimpleFormalParameter_type_withoutName2() async {
// FormalParameterList
addTestSource('m(^) {}');
- await assertOpType(typeNames: true, functionBody: true);
+ await assertOpType(typeNames: true);
}
test_SimpleFormalParameter_type_withoutName3() async {
// SimpleIdentifier SimpleFormalParameter FormalParameterList
addTestSource('m(int first, Str^) {}');
- await assertOpType(typeNames: true, functionBody: true);
+ await assertOpType(typeNames: true);
}
test_SwitchCase_before() async {
@@ -2112,7 +2133,7 @@
class A implements I {
A(this.^) {}
}''');
- await assertOpType(prefixed: true, constructorBody: true);
+ await assertOpType(prefixed: true);
}
test_ThisExpression_constructor_param2() async {
@@ -2121,7 +2142,7 @@
class A implements I {
A(this.f^) {}
}''');
- await assertOpType(prefixed: true, constructorBody: true);
+ await assertOpType(prefixed: true);
}
test_ThisExpression_constructor_param3() async {
@@ -2130,7 +2151,7 @@
class A implements I {
A(this.^f) {}
}''');
- await assertOpType(prefixed: true, constructorBody: true);
+ await assertOpType(prefixed: true);
}
test_ThisExpression_constructor_param4() async {
@@ -2139,7 +2160,7 @@
class A implements I {
A(Str^ this.foo) {}
}''');
- await assertOpType(typeNames: true, constructorBody: true);
+ await assertOpType(typeNames: true);
}
test_TopLevelVariableDeclaration_typed_name() async {
@@ -2221,7 +2242,7 @@
/// Common test methods to Dart1/Dart2 versions of OpType tests.
class OpTypeTestCommon extends AbstractContextTest {
- String testpath;
+ String testPath;
int completionOffset;
OpType visitor;
@@ -2232,7 +2253,7 @@
expect(nextOffset, equals(-1), reason: 'too many ^');
content = content.substring(0, completionOffset) +
content.substring(completionOffset + 1);
- super.addSource(testpath, content);
+ super.addSource(testPath, content);
}
Future<void> assertOpType(
@@ -2251,10 +2272,10 @@
bool voidReturn: false,
CompletionSuggestionKind kind:
CompletionSuggestionKind.INVOCATION}) async {
- AnalysisResult analysisResult = await driver.getResult(testpath);
+ ResolvedUnitResult resolvedUnit = await driver.getResult(testPath);
CompletionTarget completionTarget =
- new CompletionTarget.forOffset(analysisResult.unit, completionOffset);
+ new CompletionTarget.forOffset(resolvedUnit.unit, completionOffset);
visitor = new OpType.forCompletion(completionTarget, completionOffset);
expect(visitor.includeCaseLabelSuggestions, caseLabel, reason: 'caseLabel');
@@ -2283,6 +2304,6 @@
@override
void setUp() {
super.setUp();
- testpath = provider.convertPath('/completionTest.dart');
+ testPath = convertPath('/completionTest.dart');
}
}
diff --git a/pkg/analyzer_plugin/test/src/utilities/visitors/local_declaration_visitor_test.dart b/pkg/analyzer_plugin/test/src/utilities/visitors/local_declaration_visitor_test.dart
index 3811ea4..fd96c31 100644
--- a/pkg/analyzer_plugin/test/src/utilities/visitors/local_declaration_visitor_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/visitors/local_declaration_visitor_test.dart
@@ -42,9 +42,9 @@
''');
NodeList<CompilationUnitMember> declarations = unit.declarations;
expect(declarations, hasLength(2));
- FunctionDeclaration f = declarations[1];
+ FunctionDeclaration f = declarations[1] as FunctionDeclaration;
expect(f, isNotNull);
- BlockFunctionBody body = f.functionExpression.body;
+ BlockFunctionBody body = f.functionExpression.body as BlockFunctionBody;
Statement statement = body.block.statements[0];
expect(statement, const TypeMatcher<ForEachStatement>());
statement.accept(new TestVisitor(statement.offset));
@@ -70,6 +70,9 @@
void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {}
@override
+ void declaredGenericTypeAlias(GenericTypeAlias declaration) {}
+
+ @override
void declaredLabel(Label label, bool isCaseLabel) {}
@override
diff --git a/pkg/analyzer_plugin/test/support/abstract_context.dart b/pkg/analyzer_plugin/test/support/abstract_context.dart
index 8c7cdaf..9c14f2b 100644
--- a/pkg/analyzer_plugin/test/support/abstract_context.dart
+++ b/pkg/analyzer_plugin/test/support/abstract_context.dart
@@ -10,7 +10,6 @@
import 'package:analyzer/dart/element/visitor.dart';
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
@@ -22,8 +21,8 @@
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/generated/testing/element_search.dart';
import 'package:analyzer/src/source/package_map_resolver.dart';
-
-import 'mock_sdk.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
/**
* Finds an [Element] with the given [name].
@@ -47,8 +46,7 @@
*/
typedef void _ElementVisitorFunction(Element element);
-class AbstractContextTest {
- MemoryResourceProvider provider;
+class AbstractContextTest with ResourceProviderMixin {
DartSdk sdk;
Map<String, List<Folder>> packageMap;
UriResolver resourceResolver;
@@ -64,7 +62,8 @@
*/
AnalysisSession get session => driver.currentSession;
- Source addMetaPackageSource() => addPackageSource('meta', 'meta.dart', r'''
+ void addMetaPackage() {
+ addPackageFile('meta', 'meta.dart', r'''
library meta;
const Required required = const Required();
@@ -74,21 +73,20 @@
const Required([this.reason]);
}
''');
+ }
- Source addPackageSource(String packageName, String filePath, String content) {
- packageMap[packageName] = [(newFolder('/pubcache/$packageName'))];
- File file = newFile('/pubcache/$packageName/$filePath', content);
- return file.createSource();
+ File addPackageFile(String packageName, String pathInLib, String content) {
+ var packageLibPath = '/.pub-cache/$packageName/lib';
+ packageMap[packageName] = [newFolder(packageLibPath)];
+ return newFile('$packageLibPath/$pathInLib', content: content);
}
Source addSource(String path, String content, [Uri uri]) {
- if (path.startsWith('/')) {
- path = provider.convertPath(path);
- }
+ path = convertPath(path);
driver.addFile(path);
driver.changeFile(path);
_fileContentOverlay[path] = content;
- return provider.getFile(path).createSource();
+ return getFile(path).createSource();
}
Element findElementInUnit(CompilationUnit unit, String name,
@@ -98,28 +96,16 @@
.single;
}
- File newFile(String path, [String content]) =>
- provider.newFile(provider.convertPath(path), content ?? '');
-
- Folder newFolder(String path) =>
- provider.newFolder(provider.convertPath(path));
-
- void processRequiredPlugins() {
- AnalysisEngine.instance.processRequiredPlugins();
- }
-
Future<CompilationUnit> resolveLibraryUnit(Source source) async {
return (await driver.getResult(source.fullName))?.unit;
}
void setUp() {
- processRequiredPlugins();
- setupResourceProvider();
- sdk = new MockSdk(resourceProvider: provider);
- resourceResolver = new ResourceUriResolver(provider);
+ sdk = new MockSdk(resourceProvider: resourceProvider);
+ resourceResolver = new ResourceUriResolver(resourceProvider);
packageMap = new Map<String, List<Folder>>();
PackageMapUriResolver packageResolver =
- new PackageMapUriResolver(provider, packageMap);
+ new PackageMapUriResolver(resourceProvider, packageMap);
SourceFactory sourceFactory = new SourceFactory(
[new DartUriResolver(sdk), packageResolver, resourceResolver]);
PerformanceLog log = new PerformanceLog(_logBuffer);
@@ -128,7 +114,7 @@
_driver = new AnalysisDriver(
scheduler,
log,
- provider,
+ resourceProvider,
new MemoryByteStore(),
_fileContentOverlay,
null,
@@ -138,12 +124,7 @@
AnalysisEngine.instance.logger = PrintLogger.instance;
}
- void setupResourceProvider() {
- provider = new MemoryResourceProvider();
- }
-
void tearDown() {
- provider = null;
AnalysisEngine.instance.clearCaches();
AnalysisEngine.instance.logger = null;
}
diff --git a/pkg/analyzer_plugin/test/support/abstract_single_unit.dart b/pkg/analyzer_plugin/test/support/abstract_single_unit.dart
index 7a3b6bc..0b14065 100644
--- a/pkg/analyzer_plugin/test/support/abstract_single_unit.dart
+++ b/pkg/analyzer_plugin/test/support/abstract_single_unit.dart
@@ -49,7 +49,7 @@
AstNode findNodeAtOffset(int offset, [Predicate<AstNode> predicate]) {
AstNode result = new NodeLocator(offset).searchWithin(testUnit);
if (result != null && predicate != null) {
- result = result.getAncestor(predicate);
+ result = result.thisOrAncestorMatching(predicate);
}
return result;
}
@@ -117,6 +117,6 @@
@override
void setUp() {
super.setUp();
- testFile = provider.convertPath('/test.dart');
+ testFile = convertPath('/test.dart');
}
}
diff --git a/pkg/analyzer_plugin/test/utilities/analyzer_converter_test.dart b/pkg/analyzer_plugin/test/utilities/analyzer_converter_test.dart
index 3d17d82..775e9a6 100644
--- a/pkg/analyzer_plugin/test/utilities/analyzer_converter_test.dart
+++ b/pkg/analyzer_plugin/test/utilities/analyzer_converter_test.dart
@@ -63,10 +63,8 @@
@override
void setUp() {
super.setUp();
- source = provider
- .newFile(provider.convertPath('/foo/bar.dart'), '')
- .createSource();
- testFile = provider.convertPath('/test.dart');
+ source = newFile('/foo/bar.dart').createSource();
+ testFile = convertPath('/test.dart');
}
test_convertAnalysisError_lineInfo_noSeverity() {
@@ -187,7 +185,8 @@
class B<K, V> {}''');
analyzer.CompilationUnit unit = await resolveLibraryUnit(source);
{
- analyzer.ClassElement engineElement = findElementInUnit(unit, '_A');
+ analyzer.ClassElement engineElement =
+ findElementInUnit(unit, '_A') as analyzer.ClassElement;
// create notification Element
plugin.Element element = converter.convertElement(engineElement);
expect(element.kind, plugin.ElementKind.CLASS);
@@ -209,7 +208,8 @@
plugin.Element.FLAG_PRIVATE);
}
{
- analyzer.ClassElement engineElement = findElementInUnit(unit, 'B');
+ analyzer.ClassElement engineElement =
+ findElementInUnit(unit, 'B') as analyzer.ClassElement;
// create notification Element
plugin.Element element = converter.convertElement(engineElement);
expect(element.kind, plugin.ElementKind.CLASS);
@@ -226,7 +226,7 @@
}''');
analyzer.CompilationUnit unit = await resolveLibraryUnit(source);
analyzer.ConstructorElement engineElement =
- findElementInUnit(unit, 'myConstructor');
+ findElementInUnit(unit, 'myConstructor') as analyzer.ConstructorElement;
// create notification Element
plugin.Element element = converter.convertElement(engineElement);
expect(element.kind, plugin.ElementKind.CONSTRUCTOR);
@@ -264,7 +264,8 @@
enum E2 { three, four }''');
analyzer.CompilationUnit unit = await resolveLibraryUnit(source);
{
- analyzer.ClassElement engineElement = findElementInUnit(unit, '_E1');
+ analyzer.ClassElement engineElement =
+ findElementInUnit(unit, '_E1') as analyzer.ClassElement;
expect(engineElement.hasDeprecated, isTrue);
// create notification Element
plugin.Element element = converter.convertElement(engineElement);
@@ -286,7 +287,8 @@
plugin.Element.FLAG_PRIVATE);
}
{
- analyzer.ClassElement engineElement = findElementInUnit(unit, 'E2');
+ analyzer.ClassElement engineElement =
+ findElementInUnit(unit, 'E2') as analyzer.ClassElement;
// create notification Element
plugin.Element element = converter.convertElement(engineElement);
expect(element.kind, plugin.ElementKind.ENUM);
@@ -303,7 +305,8 @@
enum E2 { three, four }''');
analyzer.CompilationUnit unit = await resolveLibraryUnit(source);
{
- analyzer.FieldElement engineElement = findElementInUnit(unit, 'one');
+ analyzer.FieldElement engineElement =
+ findElementInUnit(unit, 'one') as analyzer.FieldElement;
// create notification Element
plugin.Element element = converter.convertElement(engineElement);
expect(element.kind, plugin.ElementKind.ENUM_CONSTANT);
@@ -327,7 +330,8 @@
plugin.Element.FLAG_CONST | plugin.Element.FLAG_STATIC);
}
{
- analyzer.FieldElement engineElement = findElementInUnit(unit, 'three');
+ analyzer.FieldElement engineElement =
+ findElementInUnit(unit, 'three') as analyzer.FieldElement;
// create notification Element
plugin.Element element = converter.convertElement(engineElement);
expect(element.kind, plugin.ElementKind.ENUM_CONSTANT);
@@ -393,7 +397,8 @@
static const myField = 42;
}''');
analyzer.CompilationUnit unit = await resolveLibraryUnit(source);
- analyzer.FieldElement engineElement = findElementInUnit(unit, 'myField');
+ analyzer.FieldElement engineElement =
+ findElementInUnit(unit, 'myField') as analyzer.FieldElement;
// create notification Element
plugin.Element element = converter.convertElement(engineElement);
expect(element.kind, plugin.ElementKind.FIELD);
@@ -418,7 +423,7 @@
''');
analyzer.CompilationUnit unit = await resolveLibraryUnit(source);
analyzer.FunctionTypeAliasElement engineElement =
- findElementInUnit(unit, 'F');
+ findElementInUnit(unit, 'F') as analyzer.FunctionTypeAliasElement;
// create notification Element
plugin.Element element = converter.convertElement(engineElement);
expect(element.kind, plugin.ElementKind.FUNCTION_TYPE_ALIAS);
@@ -437,6 +442,31 @@
expect(element.flags, 0);
}
+ test_convertElement_genericTypeAlias_function() async {
+ analyzer.Source source = addSource(testFile, '''
+typedef F<T> = int Function(String x);
+''');
+ analyzer.CompilationUnit unit = await resolveLibraryUnit(source);
+ analyzer.FunctionTypeAliasElement engineElement =
+ findElementInUnit(unit, 'F') as analyzer.FunctionTypeAliasElement;
+ // create notification Element
+ plugin.Element element = converter.convertElement(engineElement);
+ expect(element.kind, plugin.ElementKind.FUNCTION_TYPE_ALIAS);
+ expect(element.name, 'F');
+ expect(element.typeParameters, '<T>');
+ {
+ plugin.Location location = element.location;
+ expect(location.file, testFile);
+ expect(location.offset, 8);
+ expect(location.length, 'F'.length);
+ expect(location.startLine, 1);
+ expect(location.startColumn, 9);
+ }
+ expect(element.parameters, '(String x)');
+ expect(element.returnType, 'int');
+ expect(element.flags, 0);
+ }
+
test_convertElement_getter() async {
analyzer.Source source = addSource(testFile, '''
class A {
@@ -444,7 +474,8 @@
}''');
analyzer.CompilationUnit unit = await resolveLibraryUnit(source);
analyzer.PropertyAccessorElement engineElement =
- findElementInUnit(unit, 'myGetter', analyzer.ElementKind.GETTER);
+ findElementInUnit(unit, 'myGetter', analyzer.ElementKind.GETTER)
+ as analyzer.PropertyAccessorElement;
// create notification Element
plugin.Element element = converter.convertElement(engineElement);
expect(element.kind, plugin.ElementKind.GETTER);
@@ -470,7 +501,8 @@
}
}''');
analyzer.CompilationUnit unit = await resolveLibraryUnit(source);
- analyzer.MethodElement engineElement = findElementInUnit(unit, 'myMethod');
+ analyzer.MethodElement engineElement =
+ findElementInUnit(unit, 'myMethod') as analyzer.MethodElement;
// create notification Element
plugin.Element element = converter.convertElement(engineElement);
expect(element.kind, plugin.ElementKind.METHOD);
@@ -495,7 +527,8 @@
}''');
analyzer.CompilationUnit unit = await resolveLibraryUnit(source);
analyzer.PropertyAccessorElement engineElement =
- findElementInUnit(unit, 'mySetter', analyzer.ElementKind.SETTER);
+ findElementInUnit(unit, 'mySetter', analyzer.ElementKind.SETTER)
+ as analyzer.PropertyAccessorElement;
// create notification Element
plugin.Element element = converter.convertElement(engineElement);
expect(element.kind, plugin.ElementKind.SETTER);
@@ -572,7 +605,8 @@
}
}''');
analyzer.CompilationUnit unit = await resolveLibraryUnit(source);
- analyzer.LabelElement engineElement = findElementInUnit(unit, 'myLabel');
+ analyzer.LabelElement engineElement =
+ findElementInUnit(unit, 'myLabel') as analyzer.LabelElement;
// create notification Element
plugin.Element element = converter.convertElement(engineElement);
expect(element.kind, plugin.ElementKind.LABEL);
diff --git a/pkg/analyzer_plugin/test/utilities/completion/completion_contributor_util.dart b/pkg/analyzer_plugin/test/utilities/completion/completion_contributor_util.dart
index b8a4aef..6fe32fb 100644
--- a/pkg/analyzer_plugin/test/utilities/completion/completion_contributor_util.dart
+++ b/pkg/analyzer_plugin/test/utilities/completion/completion_contributor_util.dart
@@ -446,18 +446,15 @@
return cs;
}
- /**
- * Return a [Future] that completes with the containing library information
- * after it is accessible via [context.getLibrariesContaining].
- */
Future<void> computeLibrariesContaining() {
return driver.getResult(testFile).then((result) => null);
}
Future computeSuggestions() async {
- ResolveResult result = await driver.getResult(testFile);
+ ResolvedUnitResult result = await driver.getResult(testFile);
testSource = result.unit.declaredElement.source;
- request = new DartCompletionRequestImpl(provider, completionOffset, result);
+ request = new DartCompletionRequestImpl(
+ resourceProvider, completionOffset, result);
CompletionTarget target =
new CompletionTarget.forOffset(request.result.unit, request.offset);
@@ -478,13 +475,16 @@
*/
void configureFlutterPkg(Map<String, String> pathToCode) {
pathToCode.forEach((path, code) {
- provider.newFile('$flutterPkgLibPath/$path', code);
+ newFile('$flutterPkgLibPath/$path', content: code);
});
// configure SourceFactory
- Folder myPkgFolder = provider.getResource(flutterPkgLibPath);
- UriResolver pkgResolver = new PackageMapUriResolver(provider, {
- 'flutter': [myPkgFolder]
- });
+ Folder myPkgFolder = getFolder(flutterPkgLibPath);
+ UriResolver pkgResolver = new PackageMapUriResolver(
+ resourceProvider,
+ {
+ 'flutter': [myPkgFolder]
+ },
+ );
SourceFactory sourceFactory = new SourceFactory(
[new DartUriResolver(sdk), pkgResolver, resourceResolver]);
driver.configure(sourceFactory: sourceFactory);
@@ -561,7 +561,7 @@
@override
void setUp() {
super.setUp();
- testFile = provider.convertPath('/completionTest.dart');
+ testFile = convertPath('/completionTest.dart');
contributor = createContributor();
}
}
diff --git a/pkg/analyzer_plugin/test/utilities/completion/completion_target_test.dart b/pkg/analyzer_plugin/test/utilities/completion/completion_target_test.dart
index 8e1674e..9b44141 100644
--- a/pkg/analyzer_plugin/test/utilities/completion/completion_target_test.dart
+++ b/pkg/analyzer_plugin/test/utilities/completion/completion_target_test.dart
@@ -2,7 +2,6 @@
// 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:analyzer/analyzer.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/standard_ast_factory.dart';
import 'package:analyzer/dart/ast/token.dart';
@@ -26,6 +25,17 @@
@reflectiveTest
class CompletionTargetTest {
+ /// Parse a dangling expression (no parent node). The angular plugin, for
+ /// instance, does this.
+ Expression parseDanglingDart(String code) {
+ final reader = new CharSequenceReader(code);
+ final scanner = new Scanner(null, reader, null);
+ final source = new StringSource(code, 'test.dart');
+ final listener = new _ErrorCollector();
+
+ return new Parser(source, listener).parseExpression(scanner.tokenize());
+ }
+
test_danglingExpressionCompletionIsValid() {
// Test that users can parse dangling expressions of dart and autocomplete
// them without crash/with the correct offset information.
@@ -39,17 +49,6 @@
expect(replacementRange.length, 'identifier'.length);
}
- /// Parse a dangling expression (no parent node). The angular plugin, for
- /// instance, does this.
- Expression parseDanglingDart(String code) {
- final reader = new CharSequenceReader(code);
- final scanner = new Scanner(null, reader, null);
- final source = new StringSource(code, 'test.dart');
- final listener = new _ErrorCollector();
-
- return new Parser(source, listener).parseExpression(scanner.tokenize());
- }
-
Expression wrapForCompliance(Expression expression) {
// TODO(mfairhurst) This should be performed for clients or the need should
// be dropped. It's a fairly valid invariant that all autocompletion target
@@ -69,10 +68,6 @@
_ErrorCollector();
- /// The group of errors collected.
- AnalyzerErrorGroup get group =>
- new AnalyzerErrorGroup.fromAnalysisErrors(_errors);
-
/// Whether any errors where collected.
bool get hasErrors => !_errors.isEmpty;
diff --git a/pkg/analyzer_plugin/test/utilities/completion/inherited_reference_contributor_test.dart b/pkg/analyzer_plugin/test/utilities/completion/inherited_reference_contributor_test.dart
index 9ac962d..b710466 100644
--- a/pkg/analyzer_plugin/test/utilities/completion/inherited_reference_contributor_test.dart
+++ b/pkg/analyzer_plugin/test/utilities/completion/inherited_reference_contributor_test.dart
@@ -28,7 +28,7 @@
/// Sanity check. Permutations tested in local_ref_contributor.
test_ArgDefaults_inherited_method_with_required_named() async {
- addMetaPackageSource();
+ addMetaPackage();
resolveSource('/testB.dart', '''
import 'package:meta/meta.dart';
@@ -71,7 +71,7 @@
assertNotSuggested('B');
assertNotSuggested('A');
assertNotSuggested('Object');
- assertSuggestMethod('y', 'A', 'dynamic');
+ assertSuggestMethod('y', 'A', 'Future<dynamic>');
}
test_Block_inherited_imported() async {
diff --git a/pkg/analyzer_plugin/test/utilities/completion/type_member_contributor_test.dart b/pkg/analyzer_plugin/test/utilities/completion/type_member_contributor_test.dart
index 8b3178c..3bb0120 100644
--- a/pkg/analyzer_plugin/test/utilities/completion/type_member_contributor_test.dart
+++ b/pkg/analyzer_plugin/test/utilities/completion/type_member_contributor_test.dart
@@ -82,7 +82,7 @@
}
test_ArgDefaults_method_with_optional_positional() async {
- addMetaPackageSource();
+ addMetaPackage();
addTestSource('''
import 'package:meta/meta.dart';
@@ -97,7 +97,7 @@
}
test_ArgDefaults_method_with_required_named() async {
- addMetaPackageSource();
+ addMetaPackage();
addTestSource('''
import 'package:meta/meta.dart';
@@ -1086,10 +1086,10 @@
}
test_Block_unimported() async {
- addPackageSource('myBar', 'bar.dart', 'class Foo2 { Foo2() { } }');
+ addPackageFile('myBar', 'bar.dart', 'class Foo2 { Foo2() { } }');
addSource(
'/proj/testAB.dart', 'import "package:myBar/bar.dart"; class Foo { }');
- testFile = provider.convertPath('/proj/completionTest.dart');
+ testFile = convertPath('/proj/completionTest.dart');
addTestSource('class C {foo(){F^}}');
await computeSuggestions();
expect(replacementOffset, completionOffset - 1);
diff --git a/pkg/analyzer_plugin/test/utilities/navigation_test.dart b/pkg/analyzer_plugin/test/utilities/navigation_test.dart
index fdafcd3..80ec0db 100644
--- a/pkg/analyzer_plugin/test/utilities/navigation_test.dart
+++ b/pkg/analyzer_plugin/test/utilities/navigation_test.dart
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/analysis/results.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
import 'package:analyzer_plugin/utilities/generator.dart';
import 'package:analyzer_plugin/utilities/navigation/navigation.dart';
@@ -17,15 +17,13 @@
}
@reflectiveTest
-class NavigationGeneratorTest {
- MemoryResourceProvider provider = new MemoryResourceProvider();
-
- ResolveResult resolveResult = new MockAnalysisResult(path: 'a.dart');
+class NavigationGeneratorTest with ResourceProviderMixin {
+ ResolvedUnitResult resolvedUnit = new MockResolvedUnitResult(path: 'a.dart');
test_none() {
NavigationGenerator generator = new NavigationGenerator([]);
NavigationRequest request =
- new DartNavigationRequestImpl(provider, 0, 100, resolveResult);
+ new DartNavigationRequestImpl(resourceProvider, 0, 100, resolvedUnit);
GeneratorResult result = generator.generateNavigationNotification(request);
expect(result.notifications, hasLength(1));
}
@@ -34,7 +32,7 @@
TestContributor contributor = new TestContributor();
NavigationGenerator generator = new NavigationGenerator([contributor]);
NavigationRequest request =
- new DartNavigationRequestImpl(provider, 0, 100, resolveResult);
+ new DartNavigationRequestImpl(resourceProvider, 0, 100, resolvedUnit);
GeneratorResult result = generator.generateNavigationNotification(request);
expect(result.notifications, hasLength(1));
expect(contributor.count, 1);
@@ -53,7 +51,7 @@
NavigationGenerator generator = new NavigationGenerator(
[contributor1, contributor2, contributor3, contributor4]);
NavigationRequest request =
- new DartNavigationRequestImpl(provider, 0, 100, resolveResult);
+ new DartNavigationRequestImpl(resourceProvider, 0, 100, resolvedUnit);
GeneratorResult result = generator.generateNavigationNotification(request);
expect(result.notifications, hasLength(3));
expect(
diff --git a/pkg/analyzer_plugin/test/utilities/range_factory_test.dart b/pkg/analyzer_plugin/test/utilities/range_factory_test.dart
index af79bc1..105ae6f 100644
--- a/pkg/analyzer_plugin/test/utilities/range_factory_test.dart
+++ b/pkg/analyzer_plugin/test/utilities/range_factory_test.dart
@@ -29,7 +29,8 @@
test_endEnd() async {
await resolveTestUnit('main() {}');
- FunctionDeclaration mainFunction = testUnit.declarations[0];
+ FunctionDeclaration mainFunction =
+ testUnit.declarations[0] as FunctionDeclaration;
SimpleIdentifier mainName = mainFunction.name;
FunctionBody mainBody = mainFunction.functionExpression.body;
expect(range.endEnd(mainName, mainBody), new SourceRange(4, 5));
@@ -37,14 +38,16 @@
test_endLength() async {
await resolveTestUnit('main() {}');
- FunctionDeclaration mainFunction = testUnit.declarations[0];
+ FunctionDeclaration mainFunction =
+ testUnit.declarations[0] as FunctionDeclaration;
SimpleIdentifier mainName = mainFunction.name;
expect(range.endLength(mainName, 3), new SourceRange(4, 3));
}
test_endStart() async {
await resolveTestUnit('main() {}');
- FunctionDeclaration mainFunction = testUnit.declarations[0];
+ FunctionDeclaration mainFunction =
+ testUnit.declarations[0] as FunctionDeclaration;
SimpleIdentifier mainName = mainFunction.name;
FunctionBody mainBody = mainFunction.functionExpression.body;
expect(range.endStart(mainName, mainBody), new SourceRange(4, 3));
@@ -58,14 +61,16 @@
test_node() async {
await resolveTestUnit('main() {}');
- FunctionDeclaration mainFunction = testUnit.declarations[0];
+ FunctionDeclaration mainFunction =
+ testUnit.declarations[0] as FunctionDeclaration;
SimpleIdentifier mainName = mainFunction.name;
expect(range.node(mainName), new SourceRange(0, 4));
}
test_nodes() async {
await resolveTestUnit(' main() {}');
- FunctionDeclaration mainFunction = testUnit.declarations[0];
+ FunctionDeclaration mainFunction =
+ testUnit.declarations[0] as FunctionDeclaration;
SimpleIdentifier mainName = mainFunction.name;
FunctionBody mainBody = mainFunction.functionExpression.body;
expect(range.nodes([mainName, mainBody]), new SourceRange(1, 9));
@@ -82,7 +87,8 @@
test_startEnd_nodeNode() async {
await resolveTestUnit(' main() {}');
- FunctionDeclaration mainFunction = testUnit.declarations[0];
+ FunctionDeclaration mainFunction =
+ testUnit.declarations[0] as FunctionDeclaration;
SimpleIdentifier mainName = mainFunction.name;
FunctionBody mainBody = mainFunction.functionExpression.body;
expect(range.startEnd(mainName, mainBody), new SourceRange(1, 9));
@@ -90,7 +96,8 @@
test_startLength_node() async {
await resolveTestUnit(' main() {}');
- FunctionDeclaration mainFunction = testUnit.declarations[0];
+ FunctionDeclaration mainFunction =
+ testUnit.declarations[0] as FunctionDeclaration;
SimpleIdentifier mainName = mainFunction.name;
expect(range.startLength(mainName, 10), new SourceRange(1, 10));
}
@@ -101,7 +108,8 @@
test_startStart_nodeNode() async {
await resolveTestUnit('main() {}');
- FunctionDeclaration mainFunction = testUnit.declarations[0];
+ FunctionDeclaration mainFunction =
+ testUnit.declarations[0] as FunctionDeclaration;
SimpleIdentifier mainName = mainFunction.name;
FunctionBody mainBody = mainFunction.functionExpression.body;
expect(range.startStart(mainName, mainBody), new SourceRange(0, 7));
@@ -109,7 +117,8 @@
test_token() async {
await resolveTestUnit(' main() {}');
- FunctionDeclaration mainFunction = testUnit.declarations[0];
+ FunctionDeclaration mainFunction =
+ testUnit.declarations[0] as FunctionDeclaration;
SimpleIdentifier mainName = mainFunction.name;
expect(range.token(mainName.beginToken), new SourceRange(1, 4));
}
diff --git a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
index 32f7d96..ae1d5ef 100644
--- a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
@@ -5718,6 +5718,10 @@
() => _emitConstList(elementType, _visitExpressionList(node.elements)));
}
+ @override
+ JS.Expression visitSetLiteral(SetLiteral node) =>
+ throw new UnsupportedError('literal sets are not yet supported');
+
JS.Expression _emitConstList(
DartType elementType, List<JS.Expression> elements) {
// dart.constList helper internally depends on _interceptors.JSArray.
diff --git a/pkg/dev_compiler/lib/src/analyzer/driver.dart b/pkg/dev_compiler/lib/src/analyzer/driver.dart
index 63d1223..ea9db64 100644
--- a/pkg/dev_compiler/lib/src/analyzer/driver.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/driver.dart
@@ -15,6 +15,7 @@
import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/dart/analysis/library_analyzer.dart';
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
+import 'package:analyzer/src/dart/element/inheritance_manager2.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
@@ -324,8 +325,8 @@
(uri) => _isLibraryUri('$uri'),
context,
resynthesizer,
- libraryFile,
- _fsState.resourceProvider);
+ InheritanceManager2(context.typeSystem),
+ libraryFile);
// TODO(jmesserly): ideally we'd use the existing public `analyze()` method,
// but it's async. We can't use `async` here because it would break our
// developer tools extension (see web/web_command.dart). We should be able
diff --git a/pkg/dev_compiler/lib/src/kernel/analyzer_to_kernel.dart b/pkg/dev_compiler/lib/src/kernel/analyzer_to_kernel.dart
index a94f7f6..e7f7da5 100644
--- a/pkg/dev_compiler/lib/src/kernel/analyzer_to_kernel.dart
+++ b/pkg/dev_compiler/lib/src/kernel/analyzer_to_kernel.dart
@@ -869,7 +869,7 @@
a.SummaryDataStore summaryData, String dartSdkPath) {
var context = _createContextForSummaries(summaryData, dartSdkPath);
return a.StoreBasedSummaryResynthesizer(
- context, context.sourceFactory, /*strongMode*/ true, summaryData);
+ context, null, context.sourceFactory, /*strongMode*/ true, summaryData);
}
/// Creates a dummy Analyzer context so we can use summary resynthesizer.
diff --git a/pkg/front_end/lib/src/fasta/scanner.dart b/pkg/front_end/lib/src/fasta/scanner.dart
index 8e24f03..f276eda 100644
--- a/pkg/front_end/lib/src/fasta/scanner.dart
+++ b/pkg/front_end/lib/src/fasta/scanner.dart
@@ -83,12 +83,16 @@
/// Scan/tokenize the given [source].
/// If [recover] is null, then the [defaultRecoveryStrategy] is used.
ScannerResult scanString(String source,
- {bool includeComments: false,
+ {bool enableGtGtGt: false,
+ bool includeComments: false,
bool scanLazyAssignmentOperators: false,
Recover recover}) {
+ // TODO(brianwilkerson): Remove the parameter `enableGtGtGt` after the feature
+ // has been anabled by default.
assert(source != null, 'source must not be null');
StringScanner scanner =
new StringScanner(source, includeComments: includeComments);
+ scanner.enableGtGtGt = enableGtGtGt;
return _tokenizeAndRecover(scanner, recover, source: source);
}
diff --git a/pkg/front_end/pubspec.yaml b/pkg/front_end/pubspec.yaml
index 97934cb..ad2abeb 100644
--- a/pkg/front_end/pubspec.yaml
+++ b/pkg/front_end/pubspec.yaml
@@ -1,7 +1,7 @@
name: front_end
# Currently, front_end API is not stable and users should not
# depend on semver semantics when depending on this package.
-version: 0.1.6+8
+version: 0.1.7
author: Dart Team <misc@dartlang.org>
description: Front end for compilation of Dart code.
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/front_end
@@ -11,14 +11,14 @@
charcode: '^1.1.1'
convert: '^2.0.1'
crypto: '^2.0.2'
- kernel: 0.3.6+8
+ kernel: 0.3.7
meta: '^1.1.1'
package_config: '^1.0.1'
path: '^1.3.9'
source_span: '^1.2.3'
yaml: '^2.1.12'
dev_dependencies:
- analyzer: '^0.33.6'
+ analyzer: 0.34.0
args: '>=0.13.0 <2.0.0'
build_integration:
path: ../build_integration
diff --git a/pkg/kernel/pubspec.yaml b/pkg/kernel/pubspec.yaml
index 0be2276..04f64a9 100644
--- a/pkg/kernel/pubspec.yaml
+++ b/pkg/kernel/pubspec.yaml
@@ -1,7 +1,7 @@
name: kernel
# Currently, kernel API is not stable and users should
# not depend on semver semantics when depending on this package.
-version: 0.3.6+8
+version: 0.3.7
author: Dart Team <misc@dartlang.org>
description: Dart IR (Intermediate Representation)
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/kernel
@@ -11,7 +11,7 @@
path: ^1.3.9
args: '>=0.13.4 <2.0.0'
dev_dependencies:
- front_end: 0.1.6+8
+ front_end: 0.1.7
test: ^1.3.4
stack_trace: ^1.6.6
test_reflective_loader: ^0.1.0
diff --git a/tests/co19_2/co19_2-analyzer.status b/tests/co19_2/co19_2-analyzer.status
index a13758c..c111847 100644
--- a/tests/co19_2/co19_2-analyzer.status
+++ b/tests/co19_2/co19_2-analyzer.status
@@ -174,11 +174,9 @@
LanguageFeatures/Set-literals/non_constant_set_literals_A01_t01: CompileTimeError # This feature is not implemented yet
LanguageFeatures/Set-literals/non_constant_set_literals_A02_t01: CompileTimeError # This feature is not implemented yet
LanguageFeatures/Set-literals/semantics_A04_t01: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Set-literals/semantics_A05_t01: CompileTimeError # This feature is not implemented yet
LanguageFeatures/Set-literals/set_literals_A01_t01: CompileTimeError # This feature is not implemented yet
LanguageFeatures/Set-literals/set_literals_A02_t01: CompileTimeError # This feature is not implemented yet
LanguageFeatures/Set-literals/set_literals_A04_t01: CompileTimeError # This feature is not implemented yet
-LanguageFeatures/Simple-bounds/dynamic/class_typedef_l1_t02: CompileTimeError
LanguageFeatures/Simple-bounds/static/class_typedef_l1_t01/none: CompileTimeError
LanguageFeatures/Simple-bounds/static/class_typedef_l1_t02/none: CompileTimeError
LanguageFeatures/Simple-bounds/static/class_typedef_l1_t03/none: CompileTimeError
@@ -199,7 +197,6 @@
LanguageFeatures/Super-mixins/covariance_t03: MissingCompileTimeError # Issue 35111
LanguageFeatures/Super-mixins/covariance_t06: MissingCompileTimeError # Issue 35111
LanguageFeatures/Super-mixins/covariance_t07: MissingCompileTimeError # Issue 35111
-LanguageFeatures/Super-mixins/super_invocation_t19: CompileTimeError # Issue 35090
LanguageFeatures/regression/33585_t01: MissingCompileTimeError # Please triage this failure
LanguageFeatures/regression/33585_t02: MissingCompileTimeError # Please triage this failure
LanguageFeatures/regression/33597_t01: MissingCompileTimeError # Please triage this failure
diff --git a/tests/language_2/issue34489_test.dart b/tests/language_2/issue34489_test.dart
new file mode 100644
index 0000000..59553a3
--- /dev/null
+++ b/tests/language_2/issue34489_test.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2018, 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.
+
+class C<T> {
+ var field = T;
+}
+
+main() {
+ new C().field = 'bad'; //# 01: compile-time error
+}
diff --git a/tests/language_2/issue34495_test.dart b/tests/language_2/issue34495_test.dart
new file mode 100644
index 0000000..e599403
--- /dev/null
+++ b/tests/language_2/issue34495_test.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2018, 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.
+
+final foo = A<B>.foo(); //# 01: compile-time error
+
+main() {}
diff --git a/tests/language_2/issue35043_test.dart b/tests/language_2/issue35043_test.dart
new file mode 100644
index 0000000..95c5f13
--- /dev/null
+++ b/tests/language_2/issue35043_test.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2018, 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.
+
+final foo = Map<int>(); //# 01: compile-time error
+
+main() {}
diff --git a/tests/language_2/issue35090_test.dart b/tests/language_2/issue35090_test.dart
new file mode 100644
index 0000000..3e3c564
--- /dev/null
+++ b/tests/language_2/issue35090_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2018, 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:expect/expect.dart";
+
+class A {
+ int get g => 0;
+}
+
+class C implements A {
+ noSuchMethod(Invocation i) {
+ return 1;
+ }
+}
+
+mixin M on A {
+ int test() {
+ return super.g;
+ }
+
+ noSuchMethod(Invocation i) {
+ return 2;
+ }
+}
+
+class MA extends C with M {}
+
+main() {
+ Expect.equals(new MA().g, 2);
+ Expect.equals(new MA().test(), 2);
+}
diff --git a/tests/language_2/language_2_analyzer.status b/tests/language_2/language_2_analyzer.status
index a1c001a..e48117e 100644
--- a/tests/language_2/language_2_analyzer.status
+++ b/tests/language_2/language_2_analyzer.status
@@ -11,7 +11,6 @@
accessor_conflict_import_prefixed2_test: CompileTimeError # Issue 25626
accessor_conflict_import_prefixed_test: CompileTimeError # Issue 25626
accessor_conflict_import_test: CompileTimeError # Issue 25626
-additional_interface_adds_optional_args_test: CompileTimeError # Issue #30568
cascaded_forwarding_stubs_test: CompileTimeError # Issue 34329
config_import_corelib_test: CompileTimeError, StaticWarning, OK # failing-by-design: Will never pass, see Issue #34332
const_cast2_test/01: CompileTimeError # failing-by-design: Not a const expression, see Issue #34334
@@ -72,12 +71,10 @@
large_class_declaration_test: Slow, Pass
malformed2_test: Pass, MissingCompileTimeError # Flaky: issue 31056.
mixin_declaration/mixin_declaration_factory_test/02: Crash # Issue 34809
-mixin_declaration/mixin_declaration_invalid_superinvocation_test/10: CompileTimeError # Issue 30552
mixin_method_override_test/01: MissingCompileTimeError
mixin_super_2_test: CompileTimeError
mixin_super_use_test: CompileTimeError
mock_writable_final_private_field_test: CompileTimeError # failing-by-design, see Issue #34377
-multiple_interface_inheritance_test: CompileTimeError # Issue 30552
nested_generic_closure_test: CompileTimeError # Issue #28515
no_main_test/01: Fail # failing-by-design, the analyzer has no restriction that a library include a main function.
no_such_constructor2_test: StaticWarning
@@ -94,16 +91,13 @@
regress_29025_test: CompileTimeError # Issue 29081
regress_29405_test: CompileTimeError # Issue 29421
regress_29784_test/02: MissingCompileTimeError # Issue 29784
-regress_30121_test: CompileTimeError # Issue 31087
regress_30339_test: CompileTimeError
regress_33479_test/01: Crash # Issue #33479
set_literals/*: Skip
setter3_test/01: CompileTimeError # Invalid test, see https://github.com/dart-lang/sdk/issues/33837
setter3_test/02: CompileTimeError # Invalid test, see https://github.com/dart-lang/sdk/issues/33837
super_bound_closure_test/none: CompileTimeError
-super_no_such_method1_test: CompileTimeError # Invalid test, probably, see https://github.com/dart-lang/sdk/issues/33963
-super_no_such_method2_test: CompileTimeError # Invalid test, probably, see https://github.com/dart-lang/sdk/issues/33963
-super_no_such_method3_test: CompileTimeError # Invalid test, probably, see https://github.com/dart-lang/sdk/issues/33963
+super_call4_test/01: MissingCompileTimeError
super_setter_test: CompileTimeError # Invalid test, see https://github.com/dart-lang/sdk/issues/33837
syntax_test/60: MissingCompileTimeError
syntax_test/61: MissingCompileTimeError
diff --git a/tests/language_2/language_2_dartdevc.status b/tests/language_2/language_2_dartdevc.status
index f8c2bfc..3816f84 100644
--- a/tests/language_2/language_2_dartdevc.status
+++ b/tests/language_2/language_2_dartdevc.status
@@ -10,7 +10,6 @@
accessor_conflict_import_prefixed2_test: CompileTimeError # Issue 25626
accessor_conflict_import_prefixed_test: CompileTimeError # Issue 25626
accessor_conflict_import_test: CompileTimeError # Issue 25626
-additional_interface_adds_optional_args_test: CompileTimeError # Issue #30568
assertion_test: RuntimeError # Issue 30326; Expect.equals(expected: <1>, actual: <0>) fails.
async_star_test/01: RuntimeError
async_star_test/03: RuntimeError
@@ -84,7 +83,7 @@
invalid_returns/sync_invalid_return_03_test/none: CompileTimeError # issue #34319
invalid_returns/sync_invalid_return_04_test/none: CompileTimeError # issue #34319
invalid_returns/sync_invalid_return_05_test/none: CompileTimeError # issue #34319
-issue31596_implement_covariant_test: CompileTimeError
+issue31596_implement_covariant_test: CompileTimeError # Issue #31596
issue31596_override_test/01: CompileTimeError
issue31596_override_test/02: CompileTimeError
issue31596_override_test/03: CompileTimeError
@@ -102,12 +101,10 @@
large_class_declaration_test: Slow, Pass
left_shift_test: RuntimeError # Ints and doubles are unified.
mixin_declaration/mixin_declaration_factory_test/02: Crash
-mixin_declaration/mixin_declaration_invalid_superinvocation_test/10: CompileTimeError # Analyzer chooses wrong(?) super method.
mixin_method_override_test/01: MissingCompileTimeError
mixin_super_2_test: CompileTimeError # Issue 34806
mixin_super_use_test: CompileTimeError # Issue 34806
mock_writable_final_private_field_test: CompileTimeError # Issue 30848
-multiple_interface_inheritance_test: CompileTimeError # Issue 30552
nested_generic_closure_test: CompileTimeError
override_inheritance_field_test/42: CompileTimeError
part_of_multiple_libs_test/01: MissingCompileTimeError
@@ -122,7 +119,6 @@
regress_29405_test: CompileTimeError # Issue 29421
regress_29784_test/02: Crash # assert initializers not implemented
regress_29784_test/02: MissingCompileTimeError
-regress_30121_test: CompileTimeError # Issue 31087
regress_30339_test: CompileTimeError # As expected. Should we make this a multi test?
regress_33479_test/01: Crash # Issue #33479
set_literals/*: Skip
@@ -130,9 +126,7 @@
setter3_test/02: CompileTimeError # Invalid test, see https://github.com/dart-lang/sdk/issues/33837
stacktrace_test: RuntimeError # Issue 29920
super_bound_closure_test/none: CompileTimeError
-super_no_such_method1_test: CompileTimeError # Invalid test, probably, see https://github.com/dart-lang/sdk/issues/33963
-super_no_such_method2_test: CompileTimeError # Invalid test, probably, see https://github.com/dart-lang/sdk/issues/33963
-super_no_such_method3_test: CompileTimeError # Invalid test, probably, see https://github.com/dart-lang/sdk/issues/33963
+super_call4_test/01: MissingCompileTimeError
super_operator_index5_test: RuntimeError # 33470
super_operator_index7_test: RuntimeError # 33470
super_operator_index8_test: RuntimeError # 33470
diff --git a/tools/FAKE_COMMITS b/tools/FAKE_COMMITS
index fbe07a6..14748a9 100644
--- a/tools/FAKE_COMMITS
+++ b/tools/FAKE_COMMITS
@@ -24,3 +24,6 @@
Trigger mirroring of github repository
Force build after DEPS format revert
Force build while trybots are broken, to check builders for brokenness.
+
+Analyzer branch commits:
+Force build on new analyzer-branch linux build with new workflow
\ No newline at end of file
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index b2d6139..e2ac026 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -1375,7 +1375,11 @@
"builders": [
"analyzer-linux-release",
"analyzer-mac-release",
- "analyzer-win-release"
+ "analyzer-win-release",
+ "analyzer-linux-release-analyzer",
+ "analyzer-linux-release-analyzer-new",
+ "analyzer-mac-release-analyzer",
+ "analyzer-win-release-analyzer"
],
"meta": {
"description": "This configuration is used by the analyzer builders."
@@ -1440,7 +1444,10 @@
]
},
{
- "builders": ["analyzer-analysis-server-linux"],
+ "builders": [
+ "analyzer-analysis-server-linux",
+ "analyzer-analysis-server-linux-analyzer"
+ ],
"meta": {
"description": "Analyze analyzer related packages."
},
diff --git a/tools/testing/dart/options.dart b/tools/testing/dart/options.dart
index 7bd82b8..e9b648c 100644
--- a/tools/testing/dart/options.dart
+++ b/tools/testing/dart/options.dart
@@ -634,7 +634,7 @@
// Expand compilers.
for (var compiler in compilers) {
// Expand modes.
- String modes = data["mode"] ?? compiler.defaultMode.name;
+ String modes = (data["mode"] as String) ?? compiler.defaultMode.name;
if (modes == "all") modes = "debug,release,product";
for (var modeName in modes.split(",")) {
var mode = Mode.find(modeName);
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index 0666aff..cb2ca1e 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -896,7 +896,7 @@
compilationArtifact);
Map<String, String> environment = environmentOverrides;
- Map<String, String> extraEnv = info.optionsFromFile['environment'];
+ var extraEnv = info.optionsFromFile['environment'] as Map<String, String>;
if (extraEnv != null) {
environment = new Map.from(environment)..addAll(extraEnv);
}