Version 2.12.0-37.0.dev
Merge commit '2f9cb8e81b02fcf6a0cfb0d6e722f4a6e2bd6341' into 'dev'
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index 37b095d9..b5db21c 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -109,7 +109,7 @@
<body>
<h1>Analysis Server API Specification</h1>
<h1 style="color:#999999">Version
- 1.30.0
+ 1.31.0
</h1>
<p>
This document contains a specification of the API provided by the
@@ -4239,152 +4239,47 @@
<dl><dt class="value">ANNOTATION</dt><dt class="value">BUILT_IN</dt><dt class="value">CLASS</dt><dt class="value">COMMENT_BLOCK</dt><dt class="value">COMMENT_DOCUMENTATION</dt><dt class="value">COMMENT_END_OF_LINE</dt><dt class="value">CONSTRUCTOR</dt><dt class="value">DIRECTIVE</dt><dt class="value">DYNAMIC_TYPE</dt><dd>
- <p>Only for version 1 of highlight.</p>
- </dd><dt class="value">DYNAMIC_LOCAL_VARIABLE_DECLARATION</dt><dd>
+ <p>Deprecated - no longer sent.</p>
+ </dd><dt class="value">DYNAMIC_LOCAL_VARIABLE_DECLARATION</dt><dt class="value">DYNAMIC_LOCAL_VARIABLE_REFERENCE</dt><dt class="value">DYNAMIC_PARAMETER_DECLARATION</dt><dt class="value">DYNAMIC_PARAMETER_REFERENCE</dt><dt class="value">ENUM</dt><dt class="value">ENUM_CONSTANT</dt><dt class="value">FIELD</dt><dd>
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">DYNAMIC_LOCAL_VARIABLE_REFERENCE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">DYNAMIC_PARAMETER_DECLARATION</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">DYNAMIC_PARAMETER_REFERENCE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">ENUM</dt><dt class="value">ENUM_CONSTANT</dt><dt class="value">FIELD</dt><dd>
-
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</dd><dt class="value">FIELD_STATIC</dt><dd>
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</dd><dt class="value">FUNCTION</dt><dd>
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</dd><dt class="value">FUNCTION_DECLARATION</dt><dd>
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</dd><dt class="value">FUNCTION_TYPE_ALIAS</dt><dt class="value">GETTER_DECLARATION</dt><dd>
- <p>Only for version 1 of highlight.</p>
- </dd><dt class="value">IDENTIFIER_DEFAULT</dt><dt class="value">IMPORT_PREFIX</dt><dt class="value">INSTANCE_FIELD_DECLARATION</dt><dd>
+ <p>Deprecated - no longer sent.</p>
+ </dd><dt class="value">IDENTIFIER_DEFAULT</dt><dt class="value">IMPORT_PREFIX</dt><dt class="value">INSTANCE_FIELD_DECLARATION</dt><dt class="value">INSTANCE_FIELD_REFERENCE</dt><dt class="value">INSTANCE_GETTER_DECLARATION</dt><dt class="value">INSTANCE_GETTER_REFERENCE</dt><dt class="value">INSTANCE_METHOD_DECLARATION</dt><dt class="value">INSTANCE_METHOD_REFERENCE</dt><dt class="value">INSTANCE_SETTER_DECLARATION</dt><dt class="value">INSTANCE_SETTER_REFERENCE</dt><dt class="value">INVALID_STRING_ESCAPE</dt><dt class="value">KEYWORD</dt><dt class="value">LABEL</dt><dt class="value">LIBRARY_NAME</dt><dt class="value">LITERAL_BOOLEAN</dt><dt class="value">LITERAL_DOUBLE</dt><dt class="value">LITERAL_INTEGER</dt><dt class="value">LITERAL_LIST</dt><dt class="value">LITERAL_MAP</dt><dt class="value">LITERAL_STRING</dt><dt class="value">LOCAL_FUNCTION_DECLARATION</dt><dt class="value">LOCAL_FUNCTION_REFERENCE</dt><dt class="value">LOCAL_VARIABLE</dt><dd>
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">INSTANCE_FIELD_REFERENCE</dt><dd>
+ <p>Deprecated - no longer sent.</p>
+ </dd><dt class="value">LOCAL_VARIABLE_DECLARATION</dt><dt class="value">LOCAL_VARIABLE_REFERENCE</dt><dt class="value">METHOD</dt><dd>
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">INSTANCE_GETTER_DECLARATION</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">INSTANCE_GETTER_REFERENCE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">INSTANCE_METHOD_DECLARATION</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">INSTANCE_METHOD_REFERENCE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">INSTANCE_SETTER_DECLARATION</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">INSTANCE_SETTER_REFERENCE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">INVALID_STRING_ESCAPE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">KEYWORD</dt><dt class="value">LABEL</dt><dt class="value">LIBRARY_NAME</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">LITERAL_BOOLEAN</dt><dt class="value">LITERAL_DOUBLE</dt><dt class="value">LITERAL_INTEGER</dt><dt class="value">LITERAL_LIST</dt><dt class="value">LITERAL_MAP</dt><dt class="value">LITERAL_STRING</dt><dt class="value">LOCAL_FUNCTION_DECLARATION</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">LOCAL_FUNCTION_REFERENCE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">LOCAL_VARIABLE</dt><dd>
-
- <p>Only for version 1 of highlight.</p>
- </dd><dt class="value">LOCAL_VARIABLE_DECLARATION</dt><dt class="value">LOCAL_VARIABLE_REFERENCE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">METHOD</dt><dd>
-
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</dd><dt class="value">METHOD_DECLARATION</dt><dd>
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</dd><dt class="value">METHOD_DECLARATION_STATIC</dt><dd>
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</dd><dt class="value">METHOD_STATIC</dt><dd>
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</dd><dt class="value">PARAMETER</dt><dd>
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</dd><dt class="value">SETTER_DECLARATION</dt><dd>
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</dd><dt class="value">TOP_LEVEL_VARIABLE</dt><dd>
- <p>Only for version 1 of highlight.</p>
- </dd><dt class="value">PARAMETER_DECLARATION</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">PARAMETER_REFERENCE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">STATIC_FIELD_DECLARATION</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">STATIC_GETTER_DECLARATION</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">STATIC_GETTER_REFERENCE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">STATIC_METHOD_DECLARATION</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">STATIC_METHOD_REFERENCE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">STATIC_SETTER_DECLARATION</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">STATIC_SETTER_REFERENCE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">TOP_LEVEL_FUNCTION_DECLARATION</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">TOP_LEVEL_FUNCTION_REFERENCE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">TOP_LEVEL_GETTER_DECLARATION</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">TOP_LEVEL_GETTER_REFERENCE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">TOP_LEVEL_SETTER_DECLARATION</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">TOP_LEVEL_SETTER_REFERENCE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">TOP_LEVEL_VARIABLE_DECLARATION</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">TYPE_NAME_DYNAMIC</dt><dt class="value">TYPE_PARAMETER</dt><dt class="value">UNRESOLVED_INSTANCE_MEMBER_REFERENCE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">VALID_STRING_ESCAPE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd></dl></dd><dt class="typeDefinition"><a name="type_HoverInformation">HoverInformation: object</a></dt><dd>
+ <p>Deprecated - no longer sent.</p>
+ </dd><dt class="value">PARAMETER_DECLARATION</dt><dt class="value">PARAMETER_REFERENCE</dt><dt class="value">STATIC_FIELD_DECLARATION</dt><dt class="value">STATIC_GETTER_DECLARATION</dt><dt class="value">STATIC_GETTER_REFERENCE</dt><dt class="value">STATIC_METHOD_DECLARATION</dt><dt class="value">STATIC_METHOD_REFERENCE</dt><dt class="value">STATIC_SETTER_DECLARATION</dt><dt class="value">STATIC_SETTER_REFERENCE</dt><dt class="value">TOP_LEVEL_FUNCTION_DECLARATION</dt><dt class="value">TOP_LEVEL_FUNCTION_REFERENCE</dt><dt class="value">TOP_LEVEL_GETTER_DECLARATION</dt><dt class="value">TOP_LEVEL_GETTER_REFERENCE</dt><dt class="value">TOP_LEVEL_SETTER_DECLARATION</dt><dt class="value">TOP_LEVEL_SETTER_REFERENCE</dt><dt class="value">TOP_LEVEL_VARIABLE_DECLARATION</dt><dt class="value">TYPE_NAME_DYNAMIC</dt><dt class="value">TYPE_PARAMETER</dt><dt class="value">UNRESOLVED_INSTANCE_MEMBER_REFERENCE</dt><dt class="value">VALID_STRING_ESCAPE</dt></dl></dd><dt class="typeDefinition"><a name="type_HoverInformation">HoverInformation: object</a></dt><dd>
<p>
The hover information associated with a specific location.
</p>
diff --git a/pkg/analysis_server/lib/protocol/protocol_constants.dart b/pkg/analysis_server/lib/protocol/protocol_constants.dart
index 25f5a64..61ada08 100644
--- a/pkg/analysis_server/lib/protocol/protocol_constants.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_constants.dart
@@ -6,7 +6,7 @@
// To regenerate the file, use the script
// "pkg/analysis_server/tool/spec/generate_files".
-const String PROTOCOL_VERSION = '1.30.0';
+const String PROTOCOL_VERSION = '1.31.0';
const String ANALYSIS_NOTIFICATION_ANALYZED_FILES = 'analysis.analyzedFiles';
const String ANALYSIS_NOTIFICATION_ANALYZED_FILES_DIRECTORIES = 'directories';
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index ce3c063..adbfc57 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -15,7 +15,6 @@
hide AnalysisOptions;
import 'package:analysis_server/src/analysis_server_abstract.dart';
import 'package:analysis_server/src/channel/channel.dart';
-import 'package:analysis_server/src/computer/computer_highlights.dart';
import 'package:analysis_server/src/computer/computer_highlights2.dart';
import 'package:analysis_server/src/computer/new_notifications.dart';
import 'package:analysis_server/src/context_manager.dart';
@@ -601,8 +600,6 @@
/// Various IDE options.
class AnalysisServerOptions {
- bool useAnalysisHighlight2 = false;
-
String fileReadMode = 'as-is';
String newAnalysisDriverLog;
@@ -829,11 +826,7 @@
}
List<HighlightRegion> _computeHighlightRegions(CompilationUnit unit) {
- if (analysisServer.options.useAnalysisHighlight2) {
- return DartUnitHighlightsComputer2(unit).compute();
- } else {
- return DartUnitHighlightsComputer(unit).compute();
- }
+ return DartUnitHighlightsComputer2(unit).compute();
}
server.AnalysisNavigationParams _computeNavigationParams(
diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights.dart b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
deleted file mode 100644
index 3c280ff..0000000
--- a/pkg/analysis_server/lib/src/computer/computer_highlights.dart
+++ /dev/null
@@ -1,828 +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/dart/ast/ast.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/src/dart/ast/extensions.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element;
-
-/// A computer for [HighlightRegion]s in a Dart [CompilationUnit].
-class DartUnitHighlightsComputer {
- final CompilationUnit _unit;
-
- final List<HighlightRegion> _regions = <HighlightRegion>[];
-
- DartUnitHighlightsComputer(this._unit);
-
- /// Returns the computed highlight regions, not `null`.
- List<HighlightRegion> compute() {
- _unit.accept(_DartUnitHighlightsComputerVisitor(this));
- _addCommentRanges();
- return _regions;
- }
-
- void _addCommentRanges() {
- var token = _unit.beginToken;
- while (token != null) {
- Token commentToken = token.precedingComments;
- while (commentToken != null) {
- HighlightRegionType highlightType;
- if (commentToken.type == TokenType.MULTI_LINE_COMMENT) {
- if (commentToken.lexeme.startsWith('/**')) {
- highlightType = HighlightRegionType.COMMENT_DOCUMENTATION;
- } else {
- highlightType = HighlightRegionType.COMMENT_BLOCK;
- }
- }
- if (commentToken.type == TokenType.SINGLE_LINE_COMMENT) {
- highlightType = HighlightRegionType.COMMENT_END_OF_LINE;
- }
- if (highlightType != null) {
- _addRegion_token(commentToken, highlightType);
- }
- commentToken = commentToken.next;
- }
- if (token.type == TokenType.EOF) {
- // Only exit the loop *after* processing the EOF token as it may
- // have preceeding comments.
- break;
- }
- token = token.next;
- }
- }
-
- void _addIdentifierRegion(SimpleIdentifier node) {
- if (_addIdentifierRegion_keyword(node)) {
- return;
- }
- if (_addIdentifierRegion_class(node)) {
- return;
- }
- if (_addIdentifierRegion_constructor(node)) {
- return;
- }
- if (_addIdentifierRegion_dynamicType(node)) {
- return;
- }
- if (_addIdentifierRegion_getterSetterDeclaration(node)) {
- return;
- }
- if (_addIdentifierRegion_field(node)) {
- return;
- }
- if (_addIdentifierRegion_function(node)) {
- return;
- }
- if (_addIdentifierRegion_functionTypeAlias(node)) {
- return;
- }
- if (_addIdentifierRegion_importPrefix(node)) {
- return;
- }
- if (_addIdentifierRegion_label(node)) {
- return;
- }
- if (_addIdentifierRegion_localVariable(node)) {
- return;
- }
- if (_addIdentifierRegion_method(node)) {
- return;
- }
- if (_addIdentifierRegion_parameter(node)) {
- return;
- }
- if (_addIdentifierRegion_typeParameter(node)) {
- return;
- }
- _addRegion_node(node, HighlightRegionType.IDENTIFIER_DEFAULT);
- }
-
- void _addIdentifierRegion_annotation(Annotation node) {
- var arguments = node.arguments;
- if (arguments == null) {
- _addRegion_node(node, HighlightRegionType.ANNOTATION);
- } else {
- _addRegion_nodeStart_tokenEnd(
- node, arguments.beginToken, HighlightRegionType.ANNOTATION);
- _addRegion_token(arguments.endToken, HighlightRegionType.ANNOTATION);
- }
- }
-
- bool _addIdentifierRegion_class(SimpleIdentifier node) {
- var element = node.writeOrReadElement;
- if (element is! ClassElement) {
- return false;
- }
- ClassElement classElement = element;
- // prepare type
- HighlightRegionType type;
- if (node.parent is TypeName &&
- node.parent.parent is ConstructorName &&
- node.parent.parent.parent is InstanceCreationExpression) {
- // new Class()
- type = HighlightRegionType.CONSTRUCTOR;
- } else if (classElement.isEnum) {
- type = HighlightRegionType.ENUM;
- } else {
- type = HighlightRegionType.CLASS;
- }
- // add region
- return _addRegion_node(node, type);
- }
-
- bool _addIdentifierRegion_constructor(SimpleIdentifier node) {
- var element = node.writeOrReadElement;
- if (element is! ConstructorElement) {
- return false;
- }
- return _addRegion_node(node, HighlightRegionType.CONSTRUCTOR);
- }
-
- bool _addIdentifierRegion_dynamicType(SimpleIdentifier node) {
- var element = node.writeOrReadElement;
- if (element is VariableElement) {
- var staticType = element.type;
- if (staticType == null || !staticType.isDynamic) {
- return false;
- }
- return _addRegion_node(node, HighlightRegionType.DYNAMIC_TYPE);
- }
- return false;
- }
-
- bool _addIdentifierRegion_field(SimpleIdentifier node) {
- var element = node.writeOrReadElement;
- if (element is FieldFormalParameterElement) {
- element = (element as FieldFormalParameterElement).field;
- }
- if (element is PropertyAccessorElement) {
- element = (element as PropertyAccessorElement).variable;
- }
- // prepare type
- HighlightRegionType type;
- if (element is FieldElement) {
- var enclosingElement = element.enclosingElement;
- if (enclosingElement is ClassElement && enclosingElement.isEnum) {
- type = HighlightRegionType.ENUM_CONSTANT;
- } else if (element.isStatic) {
- type = HighlightRegionType.FIELD_STATIC;
- } else {
- type = HighlightRegionType.FIELD;
- }
- } else if (element is TopLevelVariableElement) {
- type = HighlightRegionType.TOP_LEVEL_VARIABLE;
- }
- // add region
- if (type != null) {
- return _addRegion_node(node, type);
- }
- return false;
- }
-
- bool _addIdentifierRegion_function(SimpleIdentifier node) {
- var element = node.writeOrReadElement;
- if (element is! FunctionElement) {
- return false;
- }
- HighlightRegionType type;
- if (node.inDeclarationContext()) {
- type = HighlightRegionType.FUNCTION_DECLARATION;
- } else {
- type = HighlightRegionType.FUNCTION;
- }
- return _addRegion_node(node, type);
- }
-
- bool _addIdentifierRegion_functionTypeAlias(SimpleIdentifier node) {
- var element = node.writeOrReadElement;
- if (element is! FunctionTypeAliasElement) {
- return false;
- }
- return _addRegion_node(node, HighlightRegionType.FUNCTION_TYPE_ALIAS);
- }
-
- bool _addIdentifierRegion_getterSetterDeclaration(SimpleIdentifier node) {
- // should be declaration
- var parent = node.parent;
- if (!(parent is MethodDeclaration || parent is FunctionDeclaration)) {
- return false;
- }
- // should be property accessor
- var element = node.writeOrReadElement;
- if (element is! PropertyAccessorElement) {
- return false;
- }
- // getter or setter
- var propertyAccessorElement = element as PropertyAccessorElement;
- if (propertyAccessorElement.isGetter) {
- return _addRegion_node(node, HighlightRegionType.GETTER_DECLARATION);
- } else {
- return _addRegion_node(node, HighlightRegionType.SETTER_DECLARATION);
- }
- }
-
- bool _addIdentifierRegion_importPrefix(SimpleIdentifier node) {
- var element = node.writeOrReadElement;
- if (element is! PrefixElement) {
- return false;
- }
- return _addRegion_node(node, HighlightRegionType.IMPORT_PREFIX);
- }
-
- bool _addIdentifierRegion_keyword(SimpleIdentifier node) {
- var name = node.name;
- if (name == 'void') {
- return _addRegion_node(node, HighlightRegionType.KEYWORD);
- }
- return false;
- }
-
- bool _addIdentifierRegion_label(SimpleIdentifier node) {
- var element = node.writeOrReadElement;
- if (element is! LabelElement) {
- return false;
- }
- return _addRegion_node(node, HighlightRegionType.LABEL);
- }
-
- bool _addIdentifierRegion_localVariable(SimpleIdentifier node) {
- var element = node.writeOrReadElement;
- if (element is! LocalVariableElement) {
- return false;
- }
- // OK
- HighlightRegionType type;
- if (node.inDeclarationContext()) {
- type = HighlightRegionType.LOCAL_VARIABLE_DECLARATION;
- } else {
- type = HighlightRegionType.LOCAL_VARIABLE;
- }
- return _addRegion_node(node, type);
- }
-
- bool _addIdentifierRegion_method(SimpleIdentifier node) {
- var element = node.writeOrReadElement;
- if (element is! MethodElement) {
- return false;
- }
- var methodElement = element as MethodElement;
- var isStatic = methodElement.isStatic;
- // OK
- HighlightRegionType type;
- if (node.inDeclarationContext()) {
- if (isStatic) {
- type = HighlightRegionType.METHOD_DECLARATION_STATIC;
- } else {
- type = HighlightRegionType.METHOD_DECLARATION;
- }
- } else {
- if (isStatic) {
- type = HighlightRegionType.METHOD_STATIC;
- } else {
- type = HighlightRegionType.METHOD;
- }
- }
- return _addRegion_node(node, type);
- }
-
- bool _addIdentifierRegion_parameter(SimpleIdentifier node) {
- var element = node.writeOrReadElement;
- if (element is! ParameterElement) {
- return false;
- }
- return _addRegion_node(node, HighlightRegionType.PARAMETER);
- }
-
- bool _addIdentifierRegion_typeParameter(SimpleIdentifier node) {
- var element = node.writeOrReadElement;
- if (element is! TypeParameterElement) {
- return false;
- }
- return _addRegion_node(node, HighlightRegionType.TYPE_PARAMETER);
- }
-
- void _addRegion(int offset, int length, HighlightRegionType type) {
- _regions.add(HighlightRegion(type, offset, length));
- }
-
- bool _addRegion_node(AstNode node, HighlightRegionType type) {
- var offset = node.offset;
- var length = node.length;
- _addRegion(offset, length, type);
- return true;
- }
-
- void _addRegion_nodeStart_tokenEnd(
- AstNode a, Token b, HighlightRegionType type) {
- var offset = a.offset;
- var end = b.end;
- _addRegion(offset, end - offset, type);
- }
-
- void _addRegion_token(Token token, HighlightRegionType type) {
- if (token != null) {
- var offset = token.offset;
- var length = token.length;
- _addRegion(offset, length, type);
- }
- }
-
- void _addRegion_tokenStart_tokenEnd(
- Token a, Token b, HighlightRegionType type) {
- var offset = a.offset;
- var end = b.end;
- _addRegion(offset, end - offset, type);
- }
-}
-
-/// An AST visitor for [DartUnitHighlightsComputer].
-class _DartUnitHighlightsComputerVisitor extends RecursiveAstVisitor<void> {
- final DartUnitHighlightsComputer computer;
-
- _DartUnitHighlightsComputerVisitor(this.computer);
-
- @override
- void visitAnnotation(Annotation node) {
- computer._addIdentifierRegion_annotation(node);
- super.visitAnnotation(node);
- }
-
- @override
- void visitAsExpression(AsExpression node) {
- computer._addRegion_token(node.asOperator, HighlightRegionType.BUILT_IN);
- super.visitAsExpression(node);
- }
-
- @override
- void visitAssertStatement(AssertStatement node) {
- computer._addRegion_token(node.assertKeyword, HighlightRegionType.KEYWORD);
- super.visitAssertStatement(node);
- }
-
- @override
- void visitAwaitExpression(AwaitExpression node) {
- computer._addRegion_token(node.awaitKeyword, HighlightRegionType.BUILT_IN);
- super.visitAwaitExpression(node);
- }
-
- @override
- void visitBlockFunctionBody(BlockFunctionBody node) {
- _addRegions_functionBody(node);
- super.visitBlockFunctionBody(node);
- }
-
- @override
- void visitBooleanLiteral(BooleanLiteral node) {
- computer._addRegion_node(node, HighlightRegionType.KEYWORD);
- computer._addRegion_node(node, HighlightRegionType.LITERAL_BOOLEAN);
- super.visitBooleanLiteral(node);
- }
-
- @override
- void visitBreakStatement(BreakStatement node) {
- computer._addRegion_token(node.breakKeyword, HighlightRegionType.KEYWORD);
- super.visitBreakStatement(node);
- }
-
- @override
- void visitCatchClause(CatchClause node) {
- computer._addRegion_token(node.catchKeyword, HighlightRegionType.KEYWORD);
- computer._addRegion_token(node.onKeyword, HighlightRegionType.BUILT_IN);
- super.visitCatchClause(node);
- }
-
- @override
- void visitClassDeclaration(ClassDeclaration node) {
- computer._addRegion_token(node.classKeyword, HighlightRegionType.KEYWORD);
- computer._addRegion_token(
- node.abstractKeyword, HighlightRegionType.BUILT_IN);
- super.visitClassDeclaration(node);
- }
-
- @override
- void visitClassTypeAlias(ClassTypeAlias node) {
- computer._addRegion_token(
- node.abstractKeyword, HighlightRegionType.BUILT_IN);
- super.visitClassTypeAlias(node);
- }
-
- @override
- void visitConstructorDeclaration(ConstructorDeclaration node) {
- computer._addRegion_token(
- node.externalKeyword, HighlightRegionType.BUILT_IN);
- computer._addRegion_token(
- node.factoryKeyword, HighlightRegionType.BUILT_IN);
- super.visitConstructorDeclaration(node);
- }
-
- @override
- void visitContinueStatement(ContinueStatement node) {
- computer._addRegion_token(
- node.continueKeyword, HighlightRegionType.KEYWORD);
- super.visitContinueStatement(node);
- }
-
- @override
- void visitDefaultFormalParameter(DefaultFormalParameter node) {
- computer._addRegion_token(
- node.requiredKeyword, HighlightRegionType.KEYWORD);
- super.visitDefaultFormalParameter(node);
- }
-
- @override
- void visitDoStatement(DoStatement node) {
- computer._addRegion_token(node.doKeyword, HighlightRegionType.KEYWORD);
- computer._addRegion_token(node.whileKeyword, HighlightRegionType.KEYWORD);
- super.visitDoStatement(node);
- }
-
- @override
- void visitDoubleLiteral(DoubleLiteral node) {
- computer._addRegion_node(node, HighlightRegionType.LITERAL_DOUBLE);
- super.visitDoubleLiteral(node);
- }
-
- @override
- void visitEnumDeclaration(EnumDeclaration node) {
- computer._addRegion_token(node.enumKeyword, HighlightRegionType.KEYWORD);
- super.visitEnumDeclaration(node);
- }
-
- @override
- void visitExportDirective(ExportDirective node) {
- computer._addRegion_node(node, HighlightRegionType.DIRECTIVE);
- computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN);
- super.visitExportDirective(node);
- }
-
- @override
- void visitExpressionFunctionBody(ExpressionFunctionBody node) {
- _addRegions_functionBody(node);
- super.visitExpressionFunctionBody(node);
- }
-
- @override
- void visitExtendsClause(ExtendsClause node) {
- computer._addRegion_token(node.extendsKeyword, HighlightRegionType.KEYWORD);
- super.visitExtendsClause(node);
- }
-
- @override
- void visitExtensionDeclaration(ExtensionDeclaration node) {
- computer._addRegion_token(
- node.extensionKeyword, HighlightRegionType.KEYWORD);
- computer._addRegion_token(node.onKeyword, HighlightRegionType.BUILT_IN);
- super.visitExtensionDeclaration(node);
- }
-
- @override
- void visitFieldDeclaration(FieldDeclaration node) {
- computer._addRegion_token(
- node.abstractKeyword, HighlightRegionType.BUILT_IN);
- computer._addRegion_token(
- node.externalKeyword, HighlightRegionType.BUILT_IN);
- computer._addRegion_token(node.staticKeyword, HighlightRegionType.BUILT_IN);
- super.visitFieldDeclaration(node);
- }
-
- @override
- void visitFieldFormalParameter(FieldFormalParameter node) {
- computer._addRegion_token(
- node.requiredKeyword, HighlightRegionType.KEYWORD);
- super.visitFieldFormalParameter(node);
- }
-
- @override
- void visitForEachPartsWithDeclaration(ForEachPartsWithDeclaration node) {
- computer._addRegion_token(node.inKeyword, HighlightRegionType.KEYWORD);
- super.visitForEachPartsWithDeclaration(node);
- }
-
- @override
- void visitForEachPartsWithIdentifier(ForEachPartsWithIdentifier node) {
- computer._addRegion_token(node.inKeyword, HighlightRegionType.KEYWORD);
- super.visitForEachPartsWithIdentifier(node);
- }
-
- @override
- void visitForElement(ForElement node) {
- computer._addRegion_token(node.awaitKeyword, HighlightRegionType.BUILT_IN);
- computer._addRegion_token(node.forKeyword, HighlightRegionType.KEYWORD);
- super.visitForElement(node);
- }
-
- @override
- void visitForStatement(ForStatement node) {
- computer._addRegion_token(node.awaitKeyword, HighlightRegionType.BUILT_IN);
- computer._addRegion_token(node.forKeyword, HighlightRegionType.KEYWORD);
- super.visitForStatement(node);
- }
-
- @override
- void visitFunctionDeclaration(FunctionDeclaration node) {
- computer._addRegion_token(
- node.externalKeyword, HighlightRegionType.BUILT_IN);
- computer._addRegion_token(
- node.propertyKeyword, HighlightRegionType.BUILT_IN);
- super.visitFunctionDeclaration(node);
- }
-
- @override
- void visitFunctionTypeAlias(FunctionTypeAlias node) {
- computer._addRegion_token(
- node.typedefKeyword, HighlightRegionType.BUILT_IN);
- super.visitFunctionTypeAlias(node);
- }
-
- @override
- void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
- computer._addRegion_token(
- node.requiredKeyword, HighlightRegionType.KEYWORD);
- super.visitFunctionTypedFormalParameter(node);
- }
-
- @override
- void visitGenericFunctionType(GenericFunctionType node) {
- computer._addRegion_token(
- node.functionKeyword, HighlightRegionType.KEYWORD);
- super.visitGenericFunctionType(node);
- }
-
- @override
- void visitGenericTypeAlias(GenericTypeAlias node) {
- computer._addRegion_token(node.typedefKeyword, HighlightRegionType.KEYWORD);
- super.visitGenericTypeAlias(node);
- }
-
- @override
- void visitHideCombinator(HideCombinator node) {
- computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN);
- super.visitHideCombinator(node);
- }
-
- @override
- void visitIfElement(IfElement node) {
- computer._addRegion_token(node.ifKeyword, HighlightRegionType.KEYWORD);
- computer._addRegion_token(node.elseKeyword, HighlightRegionType.KEYWORD);
- super.visitIfElement(node);
- }
-
- @override
- void visitIfStatement(IfStatement node) {
- computer._addRegion_token(node.ifKeyword, HighlightRegionType.KEYWORD);
- computer._addRegion_token(node.elseKeyword, HighlightRegionType.KEYWORD);
- super.visitIfStatement(node);
- }
-
- @override
- void visitImplementsClause(ImplementsClause node) {
- computer._addRegion_token(
- node.implementsKeyword, HighlightRegionType.BUILT_IN);
- super.visitImplementsClause(node);
- }
-
- @override
- 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);
- super.visitImportDirective(node);
- }
-
- @override
- void visitInstanceCreationExpression(InstanceCreationExpression node) {
- if (node.keyword != null) {
- computer._addRegion_token(node.keyword, HighlightRegionType.KEYWORD);
- }
- super.visitInstanceCreationExpression(node);
- }
-
- @override
- void visitIntegerLiteral(IntegerLiteral node) {
- computer._addRegion_node(node, HighlightRegionType.LITERAL_INTEGER);
- super.visitIntegerLiteral(node);
- }
-
- @override
- void visitIsExpression(IsExpression node) {
- computer._addRegion_token(node.isOperator, HighlightRegionType.KEYWORD);
- super.visitIsExpression(node);
- }
-
- @override
- void visitLibraryDirective(LibraryDirective node) {
- computer._addRegion_node(node, HighlightRegionType.DIRECTIVE);
- computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN);
- super.visitLibraryDirective(node);
- }
-
- @override
- void visitListLiteral(ListLiteral node) {
- computer._addRegion_node(node, HighlightRegionType.LITERAL_LIST);
- computer._addRegion_token(node.constKeyword, HighlightRegionType.KEYWORD);
- super.visitListLiteral(node);
- }
-
- @override
- void visitMethodDeclaration(MethodDeclaration node) {
- computer._addRegion_token(
- node.externalKeyword, HighlightRegionType.BUILT_IN);
- computer._addRegion_token(
- node.modifierKeyword, HighlightRegionType.BUILT_IN);
- computer._addRegion_token(
- node.operatorKeyword, HighlightRegionType.BUILT_IN);
- computer._addRegion_token(
- node.propertyKeyword, HighlightRegionType.BUILT_IN);
- super.visitMethodDeclaration(node);
- }
-
- @override
- void visitMixinDeclaration(MixinDeclaration node) {
- computer._addRegion_token(node.mixinKeyword, HighlightRegionType.BUILT_IN);
- super.visitMixinDeclaration(node);
- }
-
- @override
- void visitNativeClause(NativeClause node) {
- computer._addRegion_token(node.nativeKeyword, HighlightRegionType.BUILT_IN);
- super.visitNativeClause(node);
- }
-
- @override
- void visitNativeFunctionBody(NativeFunctionBody node) {
- computer._addRegion_token(node.nativeKeyword, HighlightRegionType.BUILT_IN);
- super.visitNativeFunctionBody(node);
- }
-
- @override
- void visitOnClause(OnClause node) {
- computer._addRegion_token(node.onKeyword, HighlightRegionType.BUILT_IN);
- super.visitOnClause(node);
- }
-
- @override
- void visitPartDirective(PartDirective node) {
- computer._addRegion_node(node, HighlightRegionType.DIRECTIVE);
- computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN);
- super.visitPartDirective(node);
- }
-
- @override
- void visitPartOfDirective(PartOfDirective node) {
- computer._addRegion_node(node, HighlightRegionType.DIRECTIVE);
- computer._addRegion_tokenStart_tokenEnd(
- node.partKeyword, node.ofKeyword, HighlightRegionType.BUILT_IN);
- super.visitPartOfDirective(node);
- }
-
- @override
- void visitRethrowExpression(RethrowExpression node) {
- computer._addRegion_token(node.rethrowKeyword, HighlightRegionType.KEYWORD);
- super.visitRethrowExpression(node);
- }
-
- @override
- void visitReturnStatement(ReturnStatement node) {
- computer._addRegion_token(node.returnKeyword, HighlightRegionType.KEYWORD);
- super.visitReturnStatement(node);
- }
-
- @override
- void visitSetOrMapLiteral(SetOrMapLiteral node) {
- if (node.isMap) {
- computer._addRegion_node(node, HighlightRegionType.LITERAL_MAP);
- // TODO(brianwilkerson) Add a highlight region for set literals. This
- // would be a breaking change, but would be consistent with list and map
- // literals.
-// } else if (node.isSet) {
-// computer._addRegion_node(node, HighlightRegionType.LITERAL_SET);
- }
- computer._addRegion_token(node.constKeyword, HighlightRegionType.KEYWORD);
- super.visitSetOrMapLiteral(node);
- }
-
- @override
- void visitShowCombinator(ShowCombinator node) {
- computer._addRegion_token(node.keyword, HighlightRegionType.BUILT_IN);
- super.visitShowCombinator(node);
- }
-
- @override
- void visitSimpleFormalParameter(SimpleFormalParameter node) {
- computer._addRegion_token(
- node.requiredKeyword, HighlightRegionType.KEYWORD);
- super.visitSimpleFormalParameter(node);
- }
-
- @override
- void visitSimpleIdentifier(SimpleIdentifier node) {
- computer._addIdentifierRegion(node);
- super.visitSimpleIdentifier(node);
- }
-
- @override
- void visitSimpleStringLiteral(SimpleStringLiteral node) {
- computer._addRegion_node(node, HighlightRegionType.LITERAL_STRING);
- super.visitSimpleStringLiteral(node);
- }
-
- @override
- void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
- computer._addRegion_token(node.superKeyword, HighlightRegionType.KEYWORD);
- super.visitSuperConstructorInvocation(node);
- }
-
- @override
- void visitSwitchCase(SwitchCase node) {
- computer._addRegion_token(node.keyword, HighlightRegionType.KEYWORD);
- super.visitSwitchCase(node);
- }
-
- @override
- void visitSwitchDefault(SwitchDefault node) {
- computer._addRegion_token(node.keyword, HighlightRegionType.KEYWORD);
- super.visitSwitchDefault(node);
- }
-
- @override
- void visitSwitchStatement(SwitchStatement node) {
- computer._addRegion_token(node.switchKeyword, HighlightRegionType.KEYWORD);
- super.visitSwitchStatement(node);
- }
-
- @override
- void visitThisExpression(ThisExpression node) {
- computer._addRegion_token(node.thisKeyword, HighlightRegionType.KEYWORD);
- super.visitThisExpression(node);
- }
-
- @override
- void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
- computer._addRegion_token(
- node.externalKeyword, HighlightRegionType.BUILT_IN);
- super.visitTopLevelVariableDeclaration(node);
- }
-
- @override
- void visitTryStatement(TryStatement node) {
- computer._addRegion_token(node.tryKeyword, HighlightRegionType.KEYWORD);
- computer._addRegion_token(node.finallyKeyword, HighlightRegionType.KEYWORD);
- super.visitTryStatement(node);
- }
-
- @override
- void visitTypeName(TypeName node) {
- var type = node.type;
- if (type != null) {
- if (type.isDynamic && node.name.name == 'dynamic') {
- computer._addRegion_node(node, HighlightRegionType.TYPE_NAME_DYNAMIC);
- return null;
- }
- }
- super.visitTypeName(node);
- }
-
- @override
- void visitVariableDeclarationList(VariableDeclarationList node) {
- computer._addRegion_token(node.lateKeyword, HighlightRegionType.KEYWORD);
- computer._addRegion_token(node.keyword, HighlightRegionType.KEYWORD);
- super.visitVariableDeclarationList(node);
- }
-
- @override
- void visitWhileStatement(WhileStatement node) {
- computer._addRegion_token(node.whileKeyword, HighlightRegionType.KEYWORD);
- super.visitWhileStatement(node);
- }
-
- @override
- void visitWithClause(WithClause node) {
- computer._addRegion_token(node.withKeyword, HighlightRegionType.KEYWORD);
- super.visitWithClause(node);
- }
-
- @override
- void visitYieldStatement(YieldStatement node) {
- var keyword = node.yieldKeyword;
- var star = node.star;
- var offset = keyword.offset;
- var end = star != null ? star.end : keyword.end;
- computer._addRegion(offset, end - offset, HighlightRegionType.BUILT_IN);
- super.visitYieldStatement(node);
- }
-
- void _addRegions_functionBody(FunctionBody node) {
- var keyword = node.keyword;
- if (keyword != null) {
- var star = node.star;
- var offset = keyword.offset;
- var end = star != null ? star.end : keyword.end;
- computer._addRegion(offset, end - offset, HighlightRegionType.BUILT_IN);
- }
- }
-}
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
index ad0869e..d34bcea 100644
--- 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
@@ -9,6 +9,7 @@
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>> {
@@ -26,9 +27,13 @@
return error(ServerErrorCodes.InvalidFilePath, 'Invalid file path', path);
}
- final unformattedSource = file.readAsStringSync();
- return success(generateEditsForFormatting(
- unformattedSource, server.clientConfiguration.lineLength));
+ final result = server.getParsedUnit(path);
+ if (result.state != ResultState.VALID || result.errors.isNotEmpty) {
+ return success();
+ }
+
+ return generateEditsForFormatting(
+ result, server.clientConfiguration.lineLength);
}
@override
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_format_range.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_format_range.dart
new file mode 100644
index 0000000..3c6183d
--- /dev/null
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_format_range.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. 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/constants.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 FormatRangeHandler
+ extends MessageHandler<DocumentRangeFormattingParams, List<TextEdit>> {
+ FormatRangeHandler(LspAnalysisServer server) : super(server);
+ @override
+ Method get handlesMessage => Method.textDocument_rangeFormatting;
+
+ @override
+ LspJsonHandler<DocumentRangeFormattingParams> get jsonHandler =>
+ DocumentRangeFormattingParams.jsonHandler;
+
+ ErrorOr<List<TextEdit>> formatRange(String path, Range range) {
+ final file = server.resourceProvider.getFile(path);
+ if (!file.exists) {
+ return error(ServerErrorCodes.InvalidFilePath, 'Invalid file path', path);
+ }
+
+ final result = server.getParsedUnit(path);
+ if (result.state != ResultState.VALID || result.errors.isNotEmpty) {
+ return success();
+ }
+
+ return generateEditsForFormatting(
+ result, server.clientConfiguration.lineLength,
+ range: range);
+ }
+
+ @override
+ Future<ErrorOr<List<TextEdit>>> handle(
+ DocumentRangeFormattingParams params, CancellationToken token) async {
+ if (!isDartDocument(params.textDocument)) {
+ return success(null);
+ }
+
+ if (!server.clientConfiguration.enableSdkFormatter) {
+ return error(ServerErrorCodes.FeatureDisabled,
+ 'Formatter was disabled by client settings');
+ }
+
+ final path = pathOfDoc(params.textDocument);
+ return path.mapResult((path) => formatRange(path, params.range));
+ }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_formatting.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_formatting.dart
index 031d5a9..554ed01 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_formatting.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_formatting.dart
@@ -9,6 +9,7 @@
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>> {
@@ -26,9 +27,13 @@
return error(ServerErrorCodes.InvalidFilePath, 'Invalid file path', path);
}
- final unformattedSource = file.readAsStringSync();
- return success(generateEditsForFormatting(
- unformattedSource, server.clientConfiguration.lineLength));
+ final result = server.getParsedUnit(path);
+ if (result.state != ResultState.VALID || result.errors.isNotEmpty) {
+ return success();
+ }
+
+ return generateEditsForFormatting(
+ result, server.clientConfiguration.lineLength);
}
@override
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart
index 949777a..be00dc9 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_states.dart
@@ -21,6 +21,7 @@
import 'package:analysis_server/src/lsp/handlers/handler_exit.dart';
import 'package:analysis_server/src/lsp/handlers/handler_folding.dart';
import 'package:analysis_server/src/lsp/handlers/handler_format_on_type.dart';
+import 'package:analysis_server/src/lsp/handlers/handler_format_range.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_implementation.dart';
@@ -81,6 +82,7 @@
registerHandler(ImplementationHandler(server));
registerHandler(FormattingHandler(server));
registerHandler(FormatOnTypeHandler(server));
+ registerHandler(FormatRangeHandler(server));
registerHandler(DocumentHighlightsHandler(server));
registerHandler(DocumentSymbolHandler(server));
registerHandler(CodeActionHandler(server));
diff --git a/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart b/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart
index 2a7a501e..fe82284 100644
--- a/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart
+++ b/pkg/analysis_server/lib/src/lsp/server_capabilities_computer.dart
@@ -30,6 +30,7 @@
Method.textDocument_documentHighlight,
Method.textDocument_formatting,
Method.textDocument_onTypeFormatting,
+ Method.textDocument_rangeFormatting,
Method.textDocument_definition,
Method.textDocument_codeAction,
Method.textDocument_rename,
@@ -71,6 +72,9 @@
bool get implementation =>
_capabilities.textDocument?.implementation?.dynamicRegistration ?? false;
+ bool get rangeFormatting =>
+ _capabilities.textDocument?.rangeFormatting?.dynamicRegistration ?? false;
+
bool get references =>
_capabilities.textDocument?.references?.dynamicRegistration ?? false;
@@ -187,6 +191,9 @@
moreTriggerCharacter:
dartTypeFormattingCharacters.skip(1).toList())
: null,
+ documentRangeFormattingProvider: dynamicRegistrations.typeFormatting
+ ? null
+ : Either2<bool, DocumentRangeFormattingOptions>.t1(enableFormatter),
renameProvider: dynamicRegistrations.rename
? null
: renameOptionsSupport
@@ -340,6 +347,13 @@
),
);
register(
+ enableFormatter && dynamicRegistrations.rangeFormatting,
+ Method.textDocument_rangeFormatting,
+ DocumentRangeFormattingRegistrationOptions(
+ documentSelector: [dartFiles], // This one is currently Dart-specific
+ ),
+ );
+ register(
dynamicRegistrations.definition,
Method.textDocument_definition,
TextDocumentRegistrationOptions(documentSelector: allTypes),
diff --git a/pkg/analysis_server/lib/src/lsp/source_edits.dart b/pkg/analysis_server/lib/src/lsp/source_edits.dart
index 2105c85..b98a101 100644
--- a/pkg/analysis_server/lib/src/lsp/source_edits.dart
+++ b/pkg/analysis_server/lib/src/lsp/source_edits.dart
@@ -7,7 +7,13 @@
import 'package:analysis_server/src/lsp/mapping.dart';
import 'package:analysis_server/src/protocol_server.dart' as server
show SourceEdit;
+import 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/source/line_info.dart';
+import 'package:analyzer/src/dart/scanner/reader.dart';
+import 'package:analyzer/src/dart/scanner/scanner.dart';
+import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart' as plugin;
import 'package:analyzer_plugin/utilities/pair.dart';
import 'package:dart_style/dart_style.dart';
@@ -70,9 +76,13 @@
return ErrorOr.success(Pair(newContent, serverEdits));
}
-List<TextEdit> generateEditsForFormatting(
- String unformattedSource, int lineLength) {
- final lineInfo = LineInfo.fromContent(unformattedSource);
+ErrorOr<List<TextEdit>> generateEditsForFormatting(
+ ParsedUnitResult result,
+ int lineLength, {
+ Range range,
+}) {
+ final unformattedSource = result.content;
+
final code =
SourceCode(unformattedSource, uri: null, isCompilationUnit: true);
SourceCode formattedResult;
@@ -87,16 +97,19 @@
// 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;
+ return success();
}
final formattedSource = formattedResult.text;
if (formattedSource == unformattedSource) {
- return null;
+ return success();
}
- // We don't currently support returning "minimal" edits, we just replace
- // entire document.
+ return _generateMinimalEdits(result, formattedSource, range: range);
+}
+
+List<TextEdit> _generateFullEdit(
+ LineInfo lineInfo, String unformattedSource, String formattedSource) {
final end = lineInfo.getLocation(unformattedSource.length);
return [
TextEdit(
@@ -107,6 +120,185 @@
];
}
+/// Generates edits that modify the minimum amount of code (only whitespace) to
+/// change [unformatted] to [formatted].
+///
+/// This allows editors to more easily track important locations (such as
+/// breakpoints) without needing to do their own diffing.
+///
+/// If [range] is supplied, only whitespace edits that fall entirely inside this
+/// range will be included in the results.
+ErrorOr<List<TextEdit>> _generateMinimalEdits(
+ ParsedUnitResult result,
+ String formatted, {
+ Range range,
+}) {
+ final unformatted = result.content;
+ final lineInfo = result.lineInfo;
+ final rangeStart = range != null ? toOffset(lineInfo, range.start) : null;
+ final rangeEnd = range != null ? toOffset(lineInfo, range.end) : null;
+
+ if (rangeStart?.isError ?? false) {
+ return failure(rangeStart);
+ }
+ if (rangeEnd?.isError ?? false) {
+ return failure(rangeEnd);
+ }
+
+ // It shouldn't be the case that we can't parse the code but if it happens
+ // fall back to a full replacement rather than fail.
+ final parsedFormatted = _parse(formatted, result.unit.featureSet);
+ final parsedUnformatted = _parse(unformatted, result.unit.featureSet);
+ if (parsedFormatted == null || parsedUnformatted == null) {
+ return success(_generateFullEdit(lineInfo, unformatted, formatted));
+ }
+
+ final unformattedTokens = _iterateAllTokens(parsedUnformatted).iterator;
+ final formattedTokens = _iterateAllTokens(parsedFormatted).iterator;
+
+ var unformattedOffset = 0;
+ var formattedOffset = 0;
+ final edits = <TextEdit>[];
+
+ /// Helper for comparing whitespace and appending an edit.
+ void addEditFor(
+ int unformattedStart,
+ int unformattedEnd,
+ int formattedStart,
+ int formattedEnd,
+ ) {
+ if (rangeStart != null && rangeEnd != null) {
+ // If we're formatting only a range, skip over any segments that don't fall
+ // entirely within that range.
+ if (unformattedStart < rangeStart.result ||
+ unformattedEnd > rangeEnd.result) {
+ return;
+ }
+ }
+
+ final unformattedWhitespace =
+ unformatted.substring(unformattedStart, unformattedEnd);
+ final formattedWhitespace =
+ formatted.substring(formattedStart, formattedEnd);
+
+ if (unformattedWhitespace == formattedWhitespace) {
+ return;
+ }
+
+ // Validate we didn't find more than whitespace. If this occurs, it's likely
+ // the token offsets used were incorrect. In this case it's better to not
+ // modify the code than potentially remove something important.
+ if (unformattedWhitespace.trim().isNotEmpty ||
+ formattedWhitespace.trim().isNotEmpty) {
+ return;
+ }
+
+ var startOffset = unformattedStart;
+ var endOffset = unformattedEnd;
+ var newText = formattedWhitespace;
+
+ // Simplify some common cases where the new whitespace is a subset of
+ // the old.
+ if (formattedWhitespace.isNotEmpty) {
+ if (unformattedWhitespace.startsWith(formattedWhitespace)) {
+ startOffset = unformattedStart + formattedWhitespace.length;
+ newText = '';
+ } else if (unformattedWhitespace.endsWith(formattedWhitespace)) {
+ endOffset = unformattedEnd - formattedWhitespace.length;
+ newText = '';
+ }
+ }
+
+ // Finally, append the edit for this whitespace.
+ // Note: As with all LSP edits, offsets are based on the original location
+ // as they are applied in one shot. They should not account for the previous
+ // edits in the same set.
+ edits.add(TextEdit(
+ range: Range(
+ start: toPosition(lineInfo.getLocation(startOffset)),
+ end: toPosition(lineInfo.getLocation(endOffset)),
+ ),
+ newText: newText,
+ ));
+ }
+
+ // Process the whitespace before each token.
+ bool unformattedHasMore, formattedHasMore;
+ while ((unformattedHasMore =
+ unformattedTokens.moveNext()) & // Don't short-circuit
+ (formattedHasMore = formattedTokens.moveNext())) {
+ final unformattedToken = unformattedTokens.current;
+ final formattedToken = formattedTokens.current;
+
+ if (unformattedToken.lexeme != formattedToken.lexeme) {
+ // If the token lexems do not match, there is a difference in the parsed
+ // token streams (this should not ordinarily happen) so fall back to a
+ // full edit.
+ return success(_generateFullEdit(lineInfo, unformatted, formatted));
+ }
+
+ addEditFor(
+ unformattedOffset,
+ unformattedToken.offset,
+ formattedOffset,
+ formattedToken.offset,
+ );
+
+ // When range formatting, if we've processed a token that ends after the
+ // range then there can't be any more relevant edits and we can return early.
+ if (rangeEnd != null && unformattedToken.end > rangeEnd.result) {
+ return success(edits);
+ }
+
+ unformattedOffset = unformattedToken.end;
+ formattedOffset = formattedToken.end;
+ }
+
+ // If we got here and either of the streams still have tokens, something
+ // did not match so fall back to a full edit.
+ if (unformattedHasMore || formattedHasMore) {
+ return success(_generateFullEdit(lineInfo, unformatted, formatted));
+ }
+
+ // Finally, handle any whitespace that was after the last token.
+ addEditFor(
+ unformattedOffset,
+ unformatted.length,
+ formattedOffset,
+ formatted.length,
+ );
+
+ return success(edits);
+}
+
+/// Iterates over a token stream returning all tokens including comments.
+Iterable<Token> _iterateAllTokens(Token token) sync* {
+ while (token.type != TokenType.EOF) {
+ var commentToken = token.precedingComments;
+ while (commentToken != null) {
+ yield commentToken;
+ commentToken = commentToken.next;
+ }
+ yield token;
+ token = token.next;
+ }
+}
+
+/// Parse and return the first of the given Dart source, `null` if code cannot
+/// be parsed.
+Token _parse(String s, FeatureSet featureSet) {
+ try {
+ var scanner = Scanner(null, CharSequenceReader(s), null)
+ ..configureFeatures(
+ featureSetForOverriding: featureSet,
+ featureSet: featureSet,
+ );
+ return scanner.tokenize();
+ } catch (e) {
+ return null;
+ }
+}
+
/// Helper class that bundles up all information required when converting server
/// SourceEdits into LSP-compatible WorkspaceEdits.
class FileEditInformation {
diff --git a/pkg/analysis_server/lib/src/operation/operation_analysis.dart b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
index c26fd4a..1f2391e 100644
--- a/pkg/analysis_server/lib/src/operation/operation_analysis.dart
+++ b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
@@ -5,7 +5,6 @@
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/computer/computer_closingLabels.dart';
import 'package:analysis_server/src/computer/computer_folding.dart';
-import 'package:analysis_server/src/computer/computer_highlights.dart';
import 'package:analysis_server/src/computer/computer_highlights2.dart';
import 'package:analysis_server/src/computer/computer_outline.dart';
import 'package:analysis_server/src/computer/computer_overrides.dart';
@@ -100,12 +99,7 @@
void sendAnalysisNotificationHighlights(
AnalysisServer server, String file, CompilationUnit dartUnit) {
_sendNotification(server, () {
- List<protocol.HighlightRegion> regions;
- if (server.options.useAnalysisHighlight2) {
- regions = DartUnitHighlightsComputer2(dartUnit).compute();
- } else {
- regions = DartUnitHighlightsComputer(dartUnit).compute();
- }
+ var regions = DartUnitHighlightsComputer2(dartUnit).compute();
var params = protocol.AnalysisHighlightsParams(file, regions);
server.sendNotification(params.toNotification());
});
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index 8e7af39..36cd808 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.dart
@@ -252,10 +252,6 @@
/// The name of the option used to describe the new analysis driver logger.
static const String NEW_ANALYSIS_DRIVER_LOG = 'new-analysis-driver-log';
- /// The name of the flag used to enable version 2 of semantic highlight
- /// notification.
- static const String USE_ANALYSIS_HIGHLIGHT2 = 'useAnalysisHighlight2';
-
/// The option for specifying the http diagnostic port.
/// If specified, users can review server status and performance information
/// by opening a web browser on http://localhost:<port>
@@ -309,8 +305,6 @@
var results = parser.parse(arguments, <String, String>{});
var analysisServerOptions = AnalysisServerOptions();
- analysisServerOptions.useAnalysisHighlight2 =
- results[USE_ANALYSIS_HIGHLIGHT2];
analysisServerOptions.fileReadMode = results[FILE_READ_MODE];
analysisServerOptions.newAnalysisDriverLog =
results[NEW_ANALYSIS_DRIVER_LOG];
@@ -769,10 +763,6 @@
' status and performance information');
parser.addOption(SDK_OPTION,
valueHelp: 'path', help: 'Path to the Dart sdk');
- parser.addFlag(USE_ANALYSIS_HIGHLIGHT2,
- help: 'enable version 2 of semantic highlight',
- defaultsTo: false,
- negatable: false);
parser.addOption(FILE_READ_MODE,
help: 'an option for reading files (some clients normalize eol '
'characters, which make the file offset and range information '
@@ -820,6 +810,8 @@
parser.addFlag('enable-instrumentation', hide: true);
// Removed 11/8/2020.
parser.addFlag('preview-dart-2', hide: true);
+ // Removed 11/11/2020.
+ parser.addFlag('useAnalysisHighlight2', hide: true);
// Removed 9/23/2020.
parser.addFlag('use-fasta-parser', hide: true);
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware.dart
index 403a6c4..feb830d 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_null_aware.dart
@@ -86,7 +86,7 @@
} else {
return;
}
- if (operator.type != TokenType.PERIOD) {
+ if (operator == null || operator.type != TokenType.PERIOD) {
return;
}
if (!(target is SimpleIdentifier &&
diff --git a/pkg/analysis_server/test/analysis/notification_highlights2_test.dart b/pkg/analysis_server/test/analysis/notification_highlights2_test.dart
index 411e163..8d9c2bb 100644
--- a/pkg/analysis_server/test/analysis/notification_highlights2_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_highlights2_test.dart
@@ -1142,7 +1142,6 @@
@override
void setUp() {
super.setUp();
- server.options.useAnalysisHighlight2 = true;
createProject();
}
diff --git a/pkg/analysis_server/test/analysis/notification_highlights_test.dart b/pkg/analysis_server/test/analysis/notification_highlights_test.dart
deleted file mode 100644
index 9432795..0000000
--- a/pkg/analysis_server/test/analysis/notification_highlights_test.dart
+++ /dev/null
@@ -1,1194 +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/protocol/protocol.dart';
-import 'package:analysis_server/protocol/protocol_constants.dart';
-import 'package:analysis_server/protocol/protocol_generated.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../analysis_abstract.dart';
-
-void main() {
- defineReflectiveSuite(() {
- defineReflectiveTests(AnalysisNotificationHighlightsTest);
- defineReflectiveTests(HighlightsWithControlFlowCollectionsTest);
- defineReflectiveTests(HighlightsWithNullSafetyTest);
- defineReflectiveTests(HighlightTypeTest);
- });
-}
-
-@reflectiveTest
-class AnalysisNotificationHighlightsTest extends HighlightsTestSupport {
- Future<void> test_ANNOTATION_hasArguments() async {
- addTestFile('''
-class AAA {
- const AAA(a, b, c);
-}
-@AAA(1, 2, 3) main() {}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.ANNOTATION, '@AAA(', '@AAA('.length);
- assertHasRegion(HighlightRegionType.ANNOTATION, ') main', ')'.length);
- }
-
- Future<void> test_ANNOTATION_noArguments() async {
- addTestFile('''
-const AAA = 42;
-@AAA main() {}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.ANNOTATION, '@AAA');
- }
-
- Future<void> test_BUILT_IN_abstract() async {
- addTestFile('''
-abstract class A {};
-abstract class B = Object with A;
-main() {
- var abstract = 42;
-}''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.BUILT_IN, 'abstract class A');
- assertHasRegion(HighlightRegionType.BUILT_IN, 'abstract class B');
- assertNoRegion(HighlightRegionType.BUILT_IN, 'abstract = 42');
- }
-
- Future<void> test_BUILT_IN_as() async {
- addTestFile('''
-import 'dart:math' as math;
-main() {
- p as int;
- var as = 42;
-}''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.BUILT_IN, 'as math');
- assertHasRegion(HighlightRegionType.BUILT_IN, 'as int');
- assertNoRegion(HighlightRegionType.BUILT_IN, 'as = 42');
- }
-
- Future<void> test_BUILT_IN_async() async {
- addTestFile('''
-fa() async {}
-fb() async* {}
-main() {
- bool async = false;
-}
-''');
- await prepareHighlights();
- assertHasStringRegion(HighlightRegionType.BUILT_IN, 'async');
- assertHasStringRegion(HighlightRegionType.BUILT_IN, 'async*');
- assertNoRegion(HighlightRegionType.BUILT_IN, 'async = false');
- }
-
- Future<void> test_BUILT_IN_await() async {
- addTestFile('''
-main() async {
- await 42;
- await for (var item in []) {
- print(item);
- }
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.BUILT_IN, 'await 42');
- assertHasRegion(HighlightRegionType.BUILT_IN, 'await for');
- }
-
- Future<void> test_BUILT_IN_deferred() async {
- addTestFile('''
-import 'dart:math' deferred as math;
-main() {
- var deferred = 42;
-}''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.BUILT_IN, 'deferred as math');
- assertNoRegion(HighlightRegionType.BUILT_IN, 'deferred = 42');
- }
-
- Future<void> test_BUILT_IN_export() async {
- addTestFile('''
-export "dart:math";
-main() {
- var export = 42;
-}''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.BUILT_IN, 'export "dart:');
- assertNoRegion(HighlightRegionType.BUILT_IN, 'export = 42');
- }
-
- Future<void> test_BUILT_IN_external() async {
- addTestFile('''
-class A {
- external A();
- external aaa();
-}
-external main() {
- var external = 42;
-}''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.BUILT_IN, 'external A()');
- assertHasRegion(HighlightRegionType.BUILT_IN, 'external aaa()');
- assertHasRegion(HighlightRegionType.BUILT_IN, 'external main()');
- assertNoRegion(HighlightRegionType.BUILT_IN, 'external = 42');
- }
-
- Future<void> test_BUILT_IN_factory() async {
- addTestFile('''
-class A {
- A.named();
- factory A() => A();
-}
-main() {
- var factory = 42;
-}''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.BUILT_IN, 'factory A()');
- assertNoRegion(HighlightRegionType.BUILT_IN, 'factory = 42');
- }
-
- Future<void> test_BUILT_IN_get() async {
- addTestFile('''
-get aaa => 1;
-class A {
- get bbb => 2;
-}
-main() {
- var get = 42;
-}''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.BUILT_IN, 'get aaa =>');
- assertHasRegion(HighlightRegionType.BUILT_IN, 'get bbb =>');
- assertNoRegion(HighlightRegionType.BUILT_IN, 'get = 42');
- }
-
- Future<void> test_BUILT_IN_hide() async {
- addTestFile('''
-import 'foo.dart' hide Foo;
-main() {
- var hide = 42;
-}''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.BUILT_IN, 'hide Foo');
- assertNoRegion(HighlightRegionType.BUILT_IN, 'hide = 42');
- }
-
- Future<void> test_BUILT_IN_implements() async {
- addTestFile('''
-class A {}
-class B implements A {}
-main() {
- var implements = 42;
-}''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.BUILT_IN, 'implements A {}');
- assertNoRegion(HighlightRegionType.BUILT_IN, 'implements = 42');
- }
-
- Future<void> test_BUILT_IN_import() async {
- addTestFile('''
-import "foo.dart";
-main() {
- var import = 42;
-}''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.BUILT_IN, 'import "');
- assertNoRegion(HighlightRegionType.BUILT_IN, 'import = 42');
- }
-
- Future<void> test_BUILT_IN_library() async {
- addTestFile('''
-library lib;
-main() {
- var library = 42;
-}''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.BUILT_IN, 'library lib;');
- assertNoRegion(HighlightRegionType.BUILT_IN, 'library = 42');
- }
-
- Future<void> test_BUILT_IN_native() async {
- addTestFile('''
-class A native "A_native" {}
-class B {
- bbb() native "bbb_native";
-}
-main() {
- var native = 42;
-}''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.BUILT_IN, 'native "A_');
- assertHasRegion(HighlightRegionType.BUILT_IN, 'native "bbb_');
- assertNoRegion(HighlightRegionType.BUILT_IN, 'native = 42');
- }
-
- Future<void> test_BUILT_IN_on_inMixin() async {
- addTestFile('''
-mixin M on N {}
-class N {}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.BUILT_IN, 'on N');
- }
-
- Future<void> test_BUILT_IN_on_inTry() async {
- addTestFile('''
-main() {
- try {
- } on int catch (e) {
- }
- var on = 42;
-}''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.BUILT_IN, 'on int');
- assertNoRegion(HighlightRegionType.BUILT_IN, 'on = 42');
- }
-
- Future<void> test_BUILT_IN_operator() async {
- addTestFile('''
-class A {
- operator +(x) => null;
-}
-main() {
- var operator = 42;
-}''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.BUILT_IN, 'operator +(');
- assertNoRegion(HighlightRegionType.BUILT_IN, 'operator = 42');
- }
-
- Future<void> test_BUILT_IN_part() async {
- addTestFile('''
-part "my_part.dart";
-main() {
- var part = 42;
-}''');
- newFile('/project/bin/my_part.dart', content: 'part of lib;');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.BUILT_IN, 'part "my_');
- assertNoRegion(HighlightRegionType.BUILT_IN, 'part = 42');
- }
-
- Future<void> test_BUILT_IN_partOf() async {
- addTestFile('''
-part of lib;
-main() {
- var part = 1;
- var of = 2;
-}''');
- _addLibraryForTestPart();
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.BUILT_IN, 'part of', 'part of'.length);
- assertNoRegion(HighlightRegionType.BUILT_IN, 'part = 1');
- assertNoRegion(HighlightRegionType.BUILT_IN, 'of = 2');
- }
-
- Future<void> test_BUILT_IN_set() async {
- addTestFile('''
-set aaa(x) {}
-class A
- set bbb(x) {}
-}
-main() {
- var set = 42;
-}''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.BUILT_IN, 'set aaa(');
- assertHasRegion(HighlightRegionType.BUILT_IN, 'set bbb(');
- assertNoRegion(HighlightRegionType.BUILT_IN, 'set = 42');
- }
-
- Future<void> test_BUILT_IN_show() async {
- addTestFile('''
-import 'foo.dart' show Foo;
-main() {
- var show = 42;
-}''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.BUILT_IN, 'show Foo');
- assertNoRegion(HighlightRegionType.BUILT_IN, 'show = 42');
- }
-
- Future<void> test_BUILT_IN_static() async {
- addTestFile('''
-class A {
- static aaa;
- static bbb() {}
-}
-main() {
- var static = 42;
-}''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.BUILT_IN, 'static aaa;');
- assertHasRegion(HighlightRegionType.BUILT_IN, 'static bbb()');
- assertNoRegion(HighlightRegionType.BUILT_IN, 'static = 42');
- }
-
- Future<void> test_BUILT_IN_sync() async {
- addTestFile('''
-fa() sync {}
-fb() sync* {}
-main() {
- bool sync = false;
-}
-''');
- await prepareHighlights();
- assertHasStringRegion(HighlightRegionType.BUILT_IN, 'sync');
- assertHasStringRegion(HighlightRegionType.BUILT_IN, 'sync*');
- assertNoRegion(HighlightRegionType.BUILT_IN, 'sync = false');
- }
-
- Future<void> test_BUILT_IN_typedef() async {
- addTestFile('''
-typedef A();
-main() {
- var typedef = 42;
-}''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.BUILT_IN, 'typedef A();');
- assertNoRegion(HighlightRegionType.BUILT_IN, 'typedef = 42');
- }
-
- Future<void> test_BUILT_IN_yield() async {
- addTestFile('''
-main() async* {
- yield 42;
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.BUILT_IN, 'yield 42');
- }
-
- Future<void> test_BUILT_IN_yieldStar() async {
- addTestFile('''
-main() async* {
- yield* [];
-}
-''');
- await prepareHighlights();
- assertHasStringRegion(HighlightRegionType.BUILT_IN, 'yield*');
- }
-
- Future<void> test_CLASS() async {
- addTestFile('''
-class AAA {}
-AAA aaa;
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.CLASS, 'AAA {}');
- assertHasRegion(HighlightRegionType.CLASS, 'AAA aaa');
- }
-
- Future<void> test_CLASS_notDynamic() async {
- addTestFile('''
-dynamic f() {}
-''');
- await prepareHighlights();
- assertNoRegion(HighlightRegionType.CLASS, 'dynamic f()');
- }
-
- Future<void> test_CLASS_notVoid() async {
- addTestFile('''
-void f() {}
-''');
- await prepareHighlights();
- assertNoRegion(HighlightRegionType.CLASS, 'void f()');
- }
-
- Future<void> test_COMMENT() async {
- addTestFile('''
-/**
- * documentation comment
- */
-void main() {
- // end-of-line comment
- my_function(1);
-}
-
-void my_function(String a) {
- /* block comment */
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.COMMENT_DOCUMENTATION, '/**', 32);
- assertHasRegion(HighlightRegionType.COMMENT_END_OF_LINE, '//', 22);
- assertHasRegion(HighlightRegionType.COMMENT_BLOCK, '/* b', 19);
- }
-
- Future<void> test_CONSTRUCTOR_explicitNew() async {
- addTestFile('''
-class AAA<T> {
- AAA() {}
- AAA.name(p) {}
-}
-main() {
- new AAA<int>();
- new AAA<int>.name(42);
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'AAA<int>(');
- assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'AAA<int>.name(');
- assertHasRegion(HighlightRegionType.CLASS, 'int>(');
- assertHasRegion(HighlightRegionType.CLASS, 'int>.name(');
- assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'name(p)');
- assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'name(42)');
- }
-
- Future<void> test_CONSTRUCTOR_implicitNew() async {
- addTestFile('''
-class AAA<T> {
- AAA() {}
- AAA.name(p) {}
-}
-main() {
- AAA<int>();
- AAA<int>.name(42);
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'AAA<int>(');
- assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'AAA<int>.name(');
- assertHasRegion(HighlightRegionType.CLASS, 'int>(');
- assertHasRegion(HighlightRegionType.CLASS, 'int>.name(');
- assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'name(p)');
- assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'name(42)');
- }
-
- Future<void> test_DIRECTIVE() async {
- addTestFile('''
-library lib;
-import 'dart:math';
-export 'dart:math';
-part 'part.dart';
-''');
- await prepareHighlights();
- assertHasStringRegion(HighlightRegionType.DIRECTIVE, 'library lib;');
- assertHasStringRegion(HighlightRegionType.DIRECTIVE, "import 'dart:math';");
- assertHasStringRegion(HighlightRegionType.DIRECTIVE, "export 'dart:math';");
- assertHasStringRegion(HighlightRegionType.DIRECTIVE, "part 'part.dart';");
- }
-
- Future<void> test_DIRECTIVE_partOf() async {
- addTestFile('''
-part of lib;
-''');
- _addLibraryForTestPart();
- await prepareHighlights();
- assertHasStringRegion(HighlightRegionType.DIRECTIVE, 'part of lib;');
- }
-
- Future<void> test_DYNAMIC_TYPE() async {
- addTestFile('''
-f() {}
-main(p) {
- print(p);
- var v1 = f();
- int v2;
- var v3 = v2;
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.DYNAMIC_TYPE, 'p)');
- assertHasRegion(HighlightRegionType.DYNAMIC_TYPE, 'v1 =');
- assertNoRegion(HighlightRegionType.DYNAMIC_TYPE, 'v2;');
- assertNoRegion(HighlightRegionType.DYNAMIC_TYPE, 'v3 =');
- }
-
- Future<void> test_ENUM() async {
- addTestFile('''
-enum MyEnum {A, B, C}
-MyEnum value;
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.ENUM, 'MyEnum {');
- assertHasRegion(HighlightRegionType.ENUM, 'MyEnum value;');
- }
-
- Future<void> test_ENUM_CONSTANT() async {
- addTestFile('''
-enum MyEnum {AAA, BBB}
-main() {
- print(MyEnum.AAA);
- print(MyEnum.BBB);
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'AAA, ');
- assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'BBB}');
- assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'AAA);');
- assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'BBB);');
- }
-
- Future<void> test_FIELD() async {
- addTestFile('''
-class A {
- int aaa = 1;
- int bbb = 2;
- A([this.bbb = 3]);
-}
-main(A a) {
- a.aaa = 4;
- a.bbb = 5;
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.FIELD, 'aaa = 1');
- assertHasRegion(HighlightRegionType.FIELD, 'bbb = 2');
- assertHasRegion(HighlightRegionType.FIELD, 'bbb = 3');
- assertHasRegion(HighlightRegionType.FIELD, 'aaa = 4');
- assertHasRegion(HighlightRegionType.FIELD, 'bbb = 5');
- }
-
- Future<void> test_FIELD_STATIC() async {
- addTestFile('''
-class A {
- static aaa = 1;
- static get bbb => null;
- static set ccc(x) {}
-}
-main() {
- A.aaa = 2;
- A.bbb;
- A.ccc = 3;
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.FIELD_STATIC, 'aaa = 1');
- assertHasRegion(HighlightRegionType.FIELD_STATIC, 'aaa = 2');
- assertHasRegion(HighlightRegionType.FIELD_STATIC, 'bbb;');
- assertHasRegion(HighlightRegionType.FIELD_STATIC, 'ccc = 3');
- }
-
- Future<void> test_FUNCTION() async {
- addTestFile('''
-fff(p) {}
-main() {
- fff(42);
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.FUNCTION_DECLARATION, 'fff(p) {}');
- assertHasRegion(HighlightRegionType.FUNCTION, 'fff(42)');
- }
-
- Future<void> test_FUNCTION_TYPE_ALIAS() async {
- addTestFile('''
-typedef FFF(p);
-main(FFF fff) {
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.FUNCTION_TYPE_ALIAS, 'FFF(p)');
- assertHasRegion(HighlightRegionType.FUNCTION_TYPE_ALIAS, 'FFF fff)');
- }
-
- Future<void> test_GETTER_DECLARATION() async {
- addTestFile('''
-get aaa => null;
-class A {
- get bbb => null;
-}
-main(A a) {
- aaa;
- a.bbb;
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.GETTER_DECLARATION, 'aaa => null');
- assertHasRegion(HighlightRegionType.GETTER_DECLARATION, 'bbb => null');
- assertHasRegion(HighlightRegionType.TOP_LEVEL_VARIABLE, 'aaa;');
- assertHasRegion(HighlightRegionType.FIELD, 'bbb;');
- }
-
- Future<void> test_IDENTIFIER_DEFAULT() async {
- addTestFile('''
-main() {
- aaa = 42;
- bbb(84);
- CCC ccc;
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'aaa = 42');
- assertHasRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'bbb(84)');
- assertHasRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'CCC ccc');
- }
-
- Future<void> test_IMPORT_PREFIX() async {
- addTestFile('''
-import 'dart:math' as ma;
-main() {
- ma.max(1, 2);
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.IMPORT_PREFIX, 'ma;');
- assertHasRegion(HighlightRegionType.IMPORT_PREFIX, 'ma.max');
- }
-
- Future<void> test_KEYWORD() async {
- addTestFile('''
-main() {
- assert(true);
- for (;;) break;
- switch (0) {
- case 0: break;
- default: break;
- }
- try {} catch (e) {}
- const v1 = 0;
- for (;;) continue;
- do {} while (true);
- if (true) {} else {}
- var v2 = false;
- final v3 = 1;
- try {} finally {}
- for (var v4 in []) {}
- v3 is int;
- new A();
- try {} catch (e) {rethrow;}
- var v5 = true;
- while (true) {}
-}
-class A {}
-class B extends A {
- B() : super();
- m() {
- return this;
- }
-}
-class C = Object with A;
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.KEYWORD, 'assert(true)');
- assertHasRegion(HighlightRegionType.KEYWORD, 'for (;;)');
- assertHasRegion(HighlightRegionType.KEYWORD, 'for (var v4 in');
- assertHasRegion(HighlightRegionType.KEYWORD, 'break;');
- assertHasRegion(HighlightRegionType.KEYWORD, 'case 0:');
- assertHasRegion(HighlightRegionType.KEYWORD, 'catch (e) {}');
- assertHasRegion(HighlightRegionType.KEYWORD, 'class A {}');
- assertHasRegion(HighlightRegionType.KEYWORD, 'const v1');
- assertHasRegion(HighlightRegionType.KEYWORD, 'continue;');
- assertHasRegion(HighlightRegionType.KEYWORD, 'default:');
- assertHasRegion(HighlightRegionType.KEYWORD, 'do {} while');
- assertHasRegion(HighlightRegionType.KEYWORD, 'if (true)');
- assertHasRegion(HighlightRegionType.KEYWORD, 'false;');
- assertHasRegion(HighlightRegionType.KEYWORD, 'final v3 =');
- assertHasRegion(HighlightRegionType.KEYWORD, 'finally {}');
- assertHasRegion(HighlightRegionType.KEYWORD, 'in []');
- assertHasRegion(HighlightRegionType.KEYWORD, 'is int');
- assertHasRegion(HighlightRegionType.KEYWORD, 'new A();');
- assertHasRegion(HighlightRegionType.KEYWORD, 'rethrow;');
- assertHasRegion(HighlightRegionType.KEYWORD, 'return this');
- assertHasRegion(HighlightRegionType.KEYWORD, 'super();');
- assertHasRegion(HighlightRegionType.KEYWORD, 'switch (0)');
- assertHasRegion(HighlightRegionType.KEYWORD, 'this;');
- assertHasRegion(HighlightRegionType.KEYWORD, 'true;');
- assertHasRegion(HighlightRegionType.KEYWORD, 'try {');
- assertHasRegion(HighlightRegionType.KEYWORD, 'while (true) {}');
- assertHasRegion(HighlightRegionType.KEYWORD, 'while (true);');
- assertHasRegion(HighlightRegionType.KEYWORD, 'with A;');
- }
-
- Future<void> test_KEYWORD_ifElse_statement() async {
- addTestFile('''
-f(a, b) {
- if (a < b) {} else {}
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.KEYWORD, 'if');
- assertHasRegion(HighlightRegionType.KEYWORD, 'else');
- }
-
- Future<void> test_KEYWORD_mixin() async {
- addTestFile('''
-mixin M {}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.BUILT_IN, 'mixin');
- }
-
- Future<void> test_KEYWORD_void() async {
- addTestFile('''
-void main() {
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.KEYWORD, 'void main()');
- }
-
- Future<void> test_LABEL() async {
- addTestFile('''
-main() {
-myLabel:
- while (true) {
- break myLabel;
- }
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.LABEL, 'myLabel:');
- assertHasRegion(HighlightRegionType.LABEL, 'myLabel;');
- }
-
- Future<void> test_LITERAL_BOOLEAN() async {
- addTestFile('var V = true;');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.LITERAL_BOOLEAN, 'true;');
- }
-
- Future<void> test_LITERAL_DOUBLE() async {
- addTestFile('var V = 4.2;');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.LITERAL_DOUBLE, '4.2;', '4.2'.length);
- }
-
- Future<void> test_LITERAL_INTEGER() async {
- addTestFile('var V = 42;');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.LITERAL_INTEGER, '42;');
- }
-
- Future<void> test_LITERAL_LIST() async {
- addTestFile('var V = <int>[1, 2, 3];');
- await prepareHighlights();
- assertHasStringRegion(HighlightRegionType.LITERAL_LIST, '<int>[1, 2, 3]');
- }
-
- Future<void> test_LITERAL_MAP() async {
- addTestFile("var V = const <int, String>{1: 'a', 2: 'b', 3: 'c'};");
- await prepareHighlights();
- assertHasStringRegion(HighlightRegionType.LITERAL_MAP,
- "const <int, String>{1: 'a', 2: 'b', 3: 'c'}");
- }
-
- Future<void> test_LITERAL_STRING() async {
- addTestFile('var V = "abc";');
- await prepareHighlights();
- assertHasRegion(
- HighlightRegionType.LITERAL_STRING, '"abc";', '"abc"'.length);
- }
-
- Future<void> test_LOCAL_VARIABLE() async {
- addTestFile('''
-main() {
- int vvv = 0;
- vvv;
- vvv = 1;
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.LOCAL_VARIABLE_DECLARATION, 'vvv = 0');
- assertHasRegion(HighlightRegionType.LOCAL_VARIABLE, 'vvv;');
- assertHasRegion(HighlightRegionType.LOCAL_VARIABLE, 'vvv = 1;');
- }
-
- Future<void> test_METHOD() async {
- addTestFile('''
-class A {
- aaa() {}
- static bbb() {}
-}
-main(A a) {
- a.aaa();
- a.aaa;
- A.bbb();
- A.bbb;
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.METHOD_DECLARATION, 'aaa() {}');
- assertHasRegion(HighlightRegionType.METHOD_DECLARATION_STATIC, 'bbb() {}');
- assertHasRegion(HighlightRegionType.METHOD, 'aaa();');
- assertHasRegion(HighlightRegionType.METHOD, 'aaa;');
- assertHasRegion(HighlightRegionType.METHOD_STATIC, 'bbb();');
- assertHasRegion(HighlightRegionType.METHOD_STATIC, 'bbb;');
- }
-
- Future<void> test_METHOD_bestType() async {
- addTestFile('''
-main(p) {
- if (p is List) {
- p.add(null);
- }
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.METHOD, 'add(null)');
- }
-
- Future<void> test_PARAMETER() async {
- addTestFile('''
-main(int p) {
- p;
- p = 42;
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.PARAMETER, 'p) {');
- assertHasRegion(HighlightRegionType.PARAMETER, 'p;');
- assertHasRegion(HighlightRegionType.PARAMETER, 'p = 42');
- }
-
- Future<void> test_SETTER_DECLARATION() async {
- addTestFile('''
-set aaa(x) {}
-class A {
- set bbb(x) {}
-}
-main(A a) {
- aaa = 1;
- a.bbb = 2;
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.SETTER_DECLARATION, 'aaa(x)');
- assertHasRegion(HighlightRegionType.SETTER_DECLARATION, 'bbb(x)');
- assertHasRegion(HighlightRegionType.TOP_LEVEL_VARIABLE, 'aaa = 1');
- assertHasRegion(HighlightRegionType.FIELD, 'bbb = 2');
- }
-
- Future<void> test_TOP_LEVEL_VARIABLE() async {
- addTestFile('''
-const VVV = 0;
-@VVV // annotation
-main() {
- print(VVV);
- VVV = 1;
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.TOP_LEVEL_VARIABLE, 'VVV = 0');
- assertHasRegion(
- HighlightRegionType.TOP_LEVEL_VARIABLE, 'VVV // annotation');
- assertHasRegion(HighlightRegionType.TOP_LEVEL_VARIABLE, 'VVV);');
- assertHasRegion(HighlightRegionType.TOP_LEVEL_VARIABLE, 'VVV = 1');
- }
-
- Future<void> test_TYPE_NAME_DYNAMIC() async {
- addTestFile('''
-dynamic main() {
- dynamic = 42;
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.TYPE_NAME_DYNAMIC, 'dynamic main()');
- assertNoRegion(HighlightRegionType.IDENTIFIER_DEFAULT, 'dynamic main()');
- assertNoRegion(HighlightRegionType.TYPE_NAME_DYNAMIC, 'dynamic = 42');
- }
-
- Future<void> test_TYPE_PARAMETER() async {
- addTestFile('''
-class A<T> {
- T fff;
- T mmm(T p) => null;
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T> {');
- assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T fff;');
- assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T mmm(');
- assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T p)');
- }
-}
-
-class HighlightsTestSupport extends AbstractAnalysisTest {
- List<HighlightRegion> regions;
-
- final Completer<void> _resultsAvailable = Completer();
-
- void assertHasRawRegion(HighlightRegionType type, int offset, int length) {
- for (var region in regions) {
- if (region.offset == offset &&
- region.length == length &&
- region.type == type) {
- return;
- }
- }
- fail('Expected to find (offset=$offset; length=$length; type=$type) in\n'
- '${regions.join('\n')}');
- }
-
- void assertHasRegion(HighlightRegionType type, String search,
- [int length = -1]) {
- var offset = findOffset(search);
- length = findRegionLength(search, length);
- assertHasRawRegion(type, offset, length);
- }
-
- void assertHasStringRegion(HighlightRegionType type, String str) {
- var offset = findOffset(str);
- var length = str.length;
- assertHasRawRegion(type, offset, length);
- }
-
- void assertNoRawRegion(HighlightRegionType type, int offset, int length) {
- for (var region in regions) {
- if (region.offset == offset &&
- region.length == length &&
- region.type == type) {
- fail(
- 'Not expected to find (offset=$offset; length=$length; type=$type) in\n'
- '${regions.join('\n')}');
- }
- }
- }
-
- void assertNoRegion(HighlightRegionType type, String search,
- [int length = -1]) {
- var offset = findOffset(search);
- length = findRegionLength(search, length);
- assertNoRawRegion(type, offset, length);
- }
-
- int findRegionLength(String search, int length) {
- if (length == -1) {
- length = 0;
- while (length < search.length) {
- var c = search.codeUnitAt(length);
- if (length == 0 && c == '@'.codeUnitAt(0)) {
- length++;
- continue;
- }
- if (!(c >= 'a'.codeUnitAt(0) && c <= 'z'.codeUnitAt(0) ||
- c >= 'A'.codeUnitAt(0) && c <= 'Z'.codeUnitAt(0) ||
- c >= '0'.codeUnitAt(0) && c <= '9'.codeUnitAt(0))) {
- break;
- }
- length++;
- }
- }
- return length;
- }
-
- Future prepareHighlights() {
- addAnalysisSubscription(AnalysisService.HIGHLIGHTS, testFile);
- return _resultsAvailable.future;
- }
-
- @override
- void processNotification(Notification notification) {
- if (notification.event == SERVER_NOTIFICATION_ERROR) {
- print('SERVER_NOTIFICATION_ERROR: ${notification.toJson()}');
- _resultsAvailable.complete();
- fail('SERVER_NOTIFICATION_ERROR');
- }
- if (notification.event == ANALYSIS_NOTIFICATION_HIGHLIGHTS) {
- var params = AnalysisHighlightsParams.fromNotification(notification);
- if (params.file == testFile) {
- regions = params.regions;
- _resultsAvailable.complete();
- }
- }
- }
-
- @override
- void setUp() {
- super.setUp();
- createProject();
- }
-
- void _addLibraryForTestPart() {
- newFile(join(testFolder, 'my_lib.dart'), content: '''
-library lib;
-part 'test.dart';
- ''');
- }
-}
-
-@reflectiveTest
-class HighlightsWithControlFlowCollectionsTest extends HighlightsTestSupport {
- @failingTest
- Future<void> test_KEYWORD_awaitForIn_list() async {
- addTestFile('''
-f(a) async {
- return [await for(var b in a) b];
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.KEYWORD, 'await');
- assertHasRegion(HighlightRegionType.KEYWORD, 'for');
- assertHasRegion(HighlightRegionType.KEYWORD, 'in');
- }
-
- @failingTest
- Future<void> test_KEYWORD_awaitForIn_map() async {
- addTestFile('''
-f(a) async {
- return {await for(var b in a) b : 0};
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.KEYWORD, 'await');
- assertHasRegion(HighlightRegionType.KEYWORD, 'for');
- assertHasRegion(HighlightRegionType.KEYWORD, 'in');
- }
-
- @failingTest
- Future<void> test_KEYWORD_awaitForIn_set() async {
- addTestFile('''
-f(a) async {
- return {await for(var b in a) b};
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.KEYWORD, 'await');
- assertHasRegion(HighlightRegionType.KEYWORD, 'for');
- assertHasRegion(HighlightRegionType.KEYWORD, 'in');
- }
-
- Future<void> test_KEYWORD_const_list() async {
- addTestFile('''
-var v = const [];
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.KEYWORD, 'const');
- }
-
- Future<void> test_KEYWORD_const_map() async {
- addTestFile('''
-var v = const {0 : 1};
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.KEYWORD, 'const');
- }
-
- Future<void> test_KEYWORD_const_set() async {
- addTestFile('''
-var v = const {0};
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.KEYWORD, 'const');
- }
-
- Future<void> test_KEYWORD_if_list() async {
- addTestFile('''
-f(a, b) {
- return [if (a < b) 'a'];
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.KEYWORD, 'if');
- }
-
- Future<void> test_KEYWORD_if_map() async {
- addTestFile('''
-f(a, b) {
- return {if (a < b) 'a' : 1};
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.KEYWORD, 'if');
- }
-
- Future<void> test_KEYWORD_if_set() async {
- addTestFile('''
-f(a, b) {
- return {if (a < b) 'a'};
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.KEYWORD, 'if');
- }
-
- Future<void> test_KEYWORD_ifElse_list() async {
- addTestFile('''
-f(a, b) {
- return [if (a < b) 'a' else 'b'];
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.KEYWORD, 'if');
- assertHasRegion(HighlightRegionType.KEYWORD, 'else');
- }
-
- Future<void> test_KEYWORD_ifElse_map() async {
- addTestFile('''
-f(a, b) {
- return {if (a < b) 'a' : 1 else 'b' : 2};
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.KEYWORD, 'if');
- assertHasRegion(HighlightRegionType.KEYWORD, 'else');
- }
-
- Future<void> test_KEYWORD_ifElse_set() async {
- addTestFile('''
-f(a, b) {
- return {if (a < b) 'a' else 'b'};
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.KEYWORD, 'if');
- assertHasRegion(HighlightRegionType.KEYWORD, 'else');
- }
-
- Future<void> test_LITERAL_LIST_withControlFlow() async {
- addTestFile('var V = <int>[1, 2, 3];');
- await prepareHighlights();
- assertHasStringRegion(HighlightRegionType.LITERAL_LIST, '<int>[1, 2, 3]');
- }
-
- Future<void> test_LITERAL_MAP_withControlFlow() async {
- addTestFile("var V = const <int, String>{1: 'a', 2: 'b', 3: 'c'};");
- await prepareHighlights();
- assertHasStringRegion(HighlightRegionType.LITERAL_MAP,
- "const <int, String>{1: 'a', 2: 'b', 3: 'c'}");
- }
-}
-
-@reflectiveTest
-class HighlightsWithNullSafetyTest extends HighlightsTestSupport {
- @override
- void createProject({Map<String, String> packageRoots}) {
- addAnalysisOptionsFile('''
-analyzer:
- enable-experiment:
- - non-nullable
-''');
- super.createProject(packageRoots: packageRoots);
- }
-
- Future<void> test_KEYWORD_late() async {
- addTestFile('''
-class C {
- late int x;
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.KEYWORD, 'late');
- }
-
- Future<void> test_KEYWORD_required() async {
- addTestFile('''
-void f({required int x}) {}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.KEYWORD, 'required');
- }
-}
-
-@reflectiveTest
-class HighlightTypeTest {
- void test_constructor() {
- expect(HighlightRegionType.CLASS,
- HighlightRegionType(HighlightRegionType.CLASS.name));
- }
-
- void test_toString() {
- expect(HighlightRegionType.CLASS.toString(), 'HighlightRegionType.CLASS');
- }
-
- void test_valueOf_unknown() {
- expect(() {
- HighlightRegionType('no-such-type');
- }, throwsException);
- }
-}
diff --git a/pkg/analysis_server/test/analysis/test_all.dart b/pkg/analysis_server/test/analysis/test_all.dart
index 702a96c..1187065 100644
--- a/pkg/analysis_server/test/analysis/test_all.dart
+++ b/pkg/analysis_server/test/analysis/test_all.dart
@@ -15,7 +15,6 @@
import 'notification_errors_test.dart' as notification_errors;
import 'notification_folding_test.dart' as notification_folding;
import 'notification_highlights2_test.dart' as notification_highlights2;
-import 'notification_highlights_test.dart' as notification_highlights;
import 'notification_implemented_test.dart' as notification_implemented;
import 'notification_navigation_test.dart' as notification_navigation;
import 'notification_occurrences_test.dart' as notification_occurrences;
@@ -37,7 +36,6 @@
notification_folding.main();
notification_errors.main();
notification_highlights2.main();
- notification_highlights.main();
notification_implemented.main();
notification_navigation.main();
notification_occurrences.main();
diff --git a/pkg/analysis_server/test/integration/analysis/highlights2_test.dart b/pkg/analysis_server/test/integration/analysis/highlights2_test.dart
deleted file mode 100644
index 9dfcaf7..0000000
--- a/pkg/analysis_server/test/integration/analysis/highlights2_test.dart
+++ /dev/null
@@ -1,179 +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:analysis_server/protocol/protocol_generated.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../support/integration_tests.dart';
-
-void main() {
- defineReflectiveSuite(() {
- defineReflectiveTests(AnalysisHighlightsTest);
- });
-}
-
-@reflectiveTest
-class AnalysisHighlightsTest extends AbstractAnalysisServerIntegrationTest {
- Map<HighlightRegionType, Set<String>> highlights;
-
- void check(HighlightRegionType type, List<String> expected) {
- expect(highlights[type], equals(expected.toSet()));
- highlights.remove(type);
- }
-
- Future<void> computeHighlights(String pathname, String text) async {
- writeFile(pathname, text);
- standardAnalysisSetup();
- sendAnalysisSetSubscriptions({
- AnalysisService.HIGHLIGHTS: [pathname]
- });
- // Map from highlight type to highlighted text
- onAnalysisHighlights.listen((AnalysisHighlightsParams params) {
- expect(params.file, equals(pathname));
- highlights = <HighlightRegionType, Set<String>>{};
- for (var region in params.regions) {
- var startIndex = region.offset;
- var endIndex = startIndex + region.length;
- var highlightedText = text.substring(startIndex, endIndex);
- var type = region.type;
- if (!highlights.containsKey(type)) {
- highlights[type] = <String>{};
- }
- highlights[type].add(highlightedText);
- }
- });
- await analysisFinished;
- }
-
- @override
- Future startServer({
- int diagnosticPort,
- int servicesPort,
- }) {
- return server.start(
- diagnosticPort: diagnosticPort,
- servicesPort: servicesPort,
- useAnalysisHighlight2: true);
- }
-
- Future<void> test_highlights() async {
- var pathname = sourcePath('test.dart');
- var text = r'''
-import 'dart:async' as async;
-
-/**
- * Doc comment
- */
-class Class<TypeParameter> {
- Class() {
- field = {1.0: [].toList()};
- }
-
- Class.constructor() {
- dynamic local = true;
- field = {2: local};
- }
-
- Map field = {3: 4};
- static int staticField = 0;
-
- method() {
- // End of line comment
- /* Block comment */
- }
-
- static staticMethod() {
- }
-
- get getter {
- }
-
- set setter(int parameter) {
- print(parameter);
- }
-}
-
-class Class2<TypeParameter> extends Class<TypeParameter> {
- @override
- method() {
- }
-}
-
-typedef functionType();
-
-function(dynamicType) {
- print('string');
- unresolvedIdentifier = 42;
- return async.Future.wait([]);
-}
-
-int topLevelVariable = 0;
-''';
- await computeHighlights(pathname, text);
- // There should be 1 error due to the fact that unresolvedIdentifier is
- // unresolved.
- expect(currentAnalysisErrors[pathname], hasLength(1));
-
- check(HighlightRegionType.ANNOTATION, ['@override']);
- check(HighlightRegionType.BUILT_IN,
- ['as', 'get', 'import', 'set', 'static', 'typedef']);
- check(
- HighlightRegionType.CLASS, ['Class', 'Class2', 'Future', 'Map', 'int']);
- check(HighlightRegionType.COMMENT_BLOCK, ['/* Block comment */']);
- check(HighlightRegionType.COMMENT_DOCUMENTATION,
- ['/**\n * Doc comment\n */']);
- check(HighlightRegionType.COMMENT_END_OF_LINE, ['// End of line comment']);
- check(HighlightRegionType.CONSTRUCTOR, ['constructor']);
- check(HighlightRegionType.DIRECTIVE, ["import 'dart:async' as async;"]);
- check(HighlightRegionType.DYNAMIC_PARAMETER_DECLARATION, ['dynamicType']);
- check(HighlightRegionType.INSTANCE_FIELD_DECLARATION, ['field']);
- check(HighlightRegionType.INSTANCE_SETTER_REFERENCE, ['field']);
- check(HighlightRegionType.STATIC_FIELD_DECLARATION, ['staticField']);
- check(HighlightRegionType.TOP_LEVEL_FUNCTION_REFERENCE, ['print']);
- check(HighlightRegionType.TOP_LEVEL_FUNCTION_DECLARATION, ['function']);
- check(HighlightRegionType.FUNCTION_TYPE_ALIAS, ['functionType']);
- check(HighlightRegionType.INSTANCE_GETTER_DECLARATION, ['getter']);
- check(HighlightRegionType.IDENTIFIER_DEFAULT, ['unresolvedIdentifier']);
- check(HighlightRegionType.IMPORT_PREFIX, ['async']);
- check(HighlightRegionType.KEYWORD, ['class', 'extends', 'true', 'return']);
- check(HighlightRegionType.LITERAL_BOOLEAN, ['true']);
- check(HighlightRegionType.LITERAL_DOUBLE, ['1.0']);
- check(HighlightRegionType.LITERAL_INTEGER, ['2', '3', '4', '0', '42']);
- check(HighlightRegionType.LITERAL_LIST, ['[]']);
- check(HighlightRegionType.LITERAL_MAP,
- ['{1.0: [].toList()}', '{2: local}', '{3: 4}']);
- check(HighlightRegionType.LITERAL_STRING, ["'dart:async'", "'string'"]);
- check(HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_DECLARATION, ['local']);
- check(HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_REFERENCE, ['local']);
- check(HighlightRegionType.INSTANCE_METHOD_REFERENCE, ['toList']);
- check(HighlightRegionType.INSTANCE_METHOD_DECLARATION, ['method']);
- check(HighlightRegionType.STATIC_METHOD_DECLARATION, ['staticMethod']);
- check(HighlightRegionType.STATIC_METHOD_REFERENCE, ['wait']);
- check(HighlightRegionType.PARAMETER_DECLARATION, ['parameter']);
- check(HighlightRegionType.PARAMETER_REFERENCE, ['parameter']);
- check(HighlightRegionType.INSTANCE_SETTER_DECLARATION, ['setter']);
- check(HighlightRegionType.TOP_LEVEL_GETTER_REFERENCE, ['override']);
- check(HighlightRegionType.TOP_LEVEL_VARIABLE_DECLARATION,
- ['topLevelVariable']);
- check(HighlightRegionType.TYPE_NAME_DYNAMIC, ['dynamic']);
- check(HighlightRegionType.TYPE_PARAMETER, ['TypeParameter']);
- expect(highlights, isEmpty);
- }
-
- Future<void> test_highlights_mixin() async {
- var pathname = sourcePath('test.dart');
- var text = r'''
-mixin M on A implements B {}
-class A {}
-class B {}
-''';
- await computeHighlights(pathname, text);
- expect(currentAnalysisErrors[pathname], hasLength(0));
-
- check(HighlightRegionType.BUILT_IN, ['implements', 'mixin', 'on']);
- check(HighlightRegionType.KEYWORD, ['class']);
- }
-}
diff --git a/pkg/analysis_server/test/integration/analysis/highlights_test.dart b/pkg/analysis_server/test/integration/analysis/highlights_test.dart
index 63f668b..9dfcaf7 100644
--- a/pkg/analysis_server/test/integration/analysis/highlights_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/highlights_test.dart
@@ -48,6 +48,17 @@
await analysisFinished;
}
+ @override
+ Future startServer({
+ int diagnosticPort,
+ int servicesPort,
+ }) {
+ return server.start(
+ diagnosticPort: diagnosticPort,
+ servicesPort: servicesPort,
+ useAnalysisHighlight2: true);
+ }
+
Future<void> test_highlights() async {
var pathname = sourcePath('test.dart');
var text = r'''
@@ -81,6 +92,7 @@
}
set setter(int parameter) {
+ print(parameter);
}
}
@@ -116,13 +128,14 @@
check(HighlightRegionType.COMMENT_END_OF_LINE, ['// End of line comment']);
check(HighlightRegionType.CONSTRUCTOR, ['constructor']);
check(HighlightRegionType.DIRECTIVE, ["import 'dart:async' as async;"]);
- check(HighlightRegionType.DYNAMIC_TYPE, ['dynamicType', 'local']);
- check(HighlightRegionType.FIELD, ['field']);
- check(HighlightRegionType.FIELD_STATIC, ['staticField']);
- check(HighlightRegionType.FUNCTION, ['print']);
- check(HighlightRegionType.FUNCTION_DECLARATION, ['function']);
+ check(HighlightRegionType.DYNAMIC_PARAMETER_DECLARATION, ['dynamicType']);
+ check(HighlightRegionType.INSTANCE_FIELD_DECLARATION, ['field']);
+ check(HighlightRegionType.INSTANCE_SETTER_REFERENCE, ['field']);
+ check(HighlightRegionType.STATIC_FIELD_DECLARATION, ['staticField']);
+ check(HighlightRegionType.TOP_LEVEL_FUNCTION_REFERENCE, ['print']);
+ check(HighlightRegionType.TOP_LEVEL_FUNCTION_DECLARATION, ['function']);
check(HighlightRegionType.FUNCTION_TYPE_ALIAS, ['functionType']);
- check(HighlightRegionType.GETTER_DECLARATION, ['getter']);
+ check(HighlightRegionType.INSTANCE_GETTER_DECLARATION, ['getter']);
check(HighlightRegionType.IDENTIFIER_DEFAULT, ['unresolvedIdentifier']);
check(HighlightRegionType.IMPORT_PREFIX, ['async']);
check(HighlightRegionType.KEYWORD, ['class', 'extends', 'true', 'return']);
@@ -133,16 +146,18 @@
check(HighlightRegionType.LITERAL_MAP,
['{1.0: [].toList()}', '{2: local}', '{3: 4}']);
check(HighlightRegionType.LITERAL_STRING, ["'dart:async'", "'string'"]);
- //check(HighlightRegionType.LOCAL_VARIABLE, ['local']);
- //check(HighlightRegionType.LOCAL_VARIABLE_DECLARATION, ['local']);
- check(HighlightRegionType.METHOD, ['toList']);
- check(HighlightRegionType.METHOD_DECLARATION, ['method']);
- check(HighlightRegionType.METHOD_DECLARATION_STATIC, ['staticMethod']);
- check(HighlightRegionType.METHOD_STATIC, ['wait']);
- check(HighlightRegionType.PARAMETER, ['parameter']);
- check(HighlightRegionType.SETTER_DECLARATION, ['setter']);
- check(HighlightRegionType.TOP_LEVEL_VARIABLE,
- ['override', 'topLevelVariable']);
+ check(HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_DECLARATION, ['local']);
+ check(HighlightRegionType.DYNAMIC_LOCAL_VARIABLE_REFERENCE, ['local']);
+ check(HighlightRegionType.INSTANCE_METHOD_REFERENCE, ['toList']);
+ check(HighlightRegionType.INSTANCE_METHOD_DECLARATION, ['method']);
+ check(HighlightRegionType.STATIC_METHOD_DECLARATION, ['staticMethod']);
+ check(HighlightRegionType.STATIC_METHOD_REFERENCE, ['wait']);
+ check(HighlightRegionType.PARAMETER_DECLARATION, ['parameter']);
+ check(HighlightRegionType.PARAMETER_REFERENCE, ['parameter']);
+ check(HighlightRegionType.INSTANCE_SETTER_DECLARATION, ['setter']);
+ check(HighlightRegionType.TOP_LEVEL_GETTER_REFERENCE, ['override']);
+ check(HighlightRegionType.TOP_LEVEL_VARIABLE_DECLARATION,
+ ['topLevelVariable']);
check(HighlightRegionType.TYPE_NAME_DYNAMIC, ['dynamic']);
check(HighlightRegionType.TYPE_PARAMETER, ['TypeParameter']);
expect(highlights, isEmpty);
@@ -157,6 +172,7 @@
''';
await computeHighlights(pathname, text);
expect(currentAnalysisErrors[pathname], hasLength(0));
+
check(HighlightRegionType.BUILT_IN, ['implements', 'mixin', 'on']);
check(HighlightRegionType.KEYWORD, ['class']);
}
diff --git a/pkg/analysis_server/test/integration/analysis/test_all.dart b/pkg/analysis_server/test/integration/analysis/test_all.dart
index 2a760bf..2e463f0 100644
--- a/pkg/analysis_server/test/integration/analysis/test_all.dart
+++ b/pkg/analysis_server/test/integration/analysis/test_all.dart
@@ -13,7 +13,6 @@
import 'get_library_dependencies_test.dart' as get_library_dependencies_test;
import 'get_navigation_test.dart' as get_navigation_test;
import 'get_reachable_sources_test.dart' as get_reachable_sources_test;
-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;
@@ -44,7 +43,6 @@
get_imported_elements_test.main();
get_navigation_test.main();
get_reachable_sources_test.main();
- highlights2_test.main();
highlights_test.main();
hint_sdk_version_async_exported_from_core_test.main();
lint_test.main();
diff --git a/pkg/analysis_server/test/lsp/format_test.dart b/pkg/analysis_server/test/lsp/format_test.dart
index 5a51229..e629a4d 100644
--- a/pkg/analysis_server/test/lsp/format_test.dart
+++ b/pkg/analysis_server/test/lsp/format_test.dart
@@ -18,11 +18,22 @@
@reflectiveTest
class FormatTest extends AbstractLspAnalysisServerTest {
- Future<void> expectFormattedContents(
+ Future<List<TextEdit>> expectFormattedContents(
Uri uri, String original, String expected) async {
final formatEdits = await formatDocument(uri.toString());
final formattedContents = applyTextEdits(original, formatEdits);
expect(formattedContents, equals(expected));
+ return formatEdits;
+ }
+
+ Future<List<TextEdit>> expectRangeFormattedContents(
+ Uri uri, String original, String expected) async {
+ final formatEdits =
+ await formatRange(uri.toString(), rangeFromMarkers(original));
+ final formattedContents =
+ applyTextEdits(withoutMarkers(original), formatEdits);
+ expect(formattedContents, equals(expected));
+ return formatEdits;
}
Future<void> test_alreadyFormatted() async {
@@ -37,6 +48,32 @@
expect(formatEdits, isNull);
}
+ Future<void> test_complex() async {
+ const contents = '''
+ErrorOr<Pair<A, List<B>>> c(
+ String d,
+ List<
+ Either2<E,
+ F>>
+ g, {
+ h = false,
+}) {
+}
+
+
+ ''';
+ final expected = '''
+ErrorOr<Pair<A, List<B>>> c(
+ String d,
+ List<Either2<E, F>> g, {
+ h = false,
+}) {}
+''';
+ await initialize();
+ await openFile(mainFileUri, contents);
+ await expectFormattedContents(mainFileUri, contents, expected);
+ }
+
/// Ensures we use the same registration ID when unregistering even if the
/// server has regenerated registrations multiple times.
Future<void> test_dynamicRegistration_correctIdAfterMultipleChanges() async {
@@ -63,6 +100,7 @@
// By default, the formatters should have been registered.
expect(registration(Method.textDocument_formatting), isNotNull);
expect(registration(Method.textDocument_onTypeFormatting), isNotNull);
+ expect(registration(Method.textDocument_rangeFormatting), isNotNull);
// Sending config updates causes the server to rebuild its list of registrations
// which exposes a previous bug where we'd retain newly-built registrations
@@ -78,6 +116,7 @@
);
expect(registration(Method.textDocument_formatting), isNull);
expect(registration(Method.textDocument_onTypeFormatting), isNull);
+ expect(registration(Method.textDocument_rangeFormatting), isNull);
}
Future<void> test_dynamicRegistration_forConfiguration() async {
@@ -104,6 +143,7 @@
// By default, the formatters should have been registered.
expect(registration(Method.textDocument_formatting), isNotNull);
expect(registration(Method.textDocument_onTypeFormatting), isNotNull);
+ expect(registration(Method.textDocument_rangeFormatting), isNotNull);
// They should be unregistered if we change the config to disabled.
await monitorDynamicUnregistrations(
@@ -112,6 +152,7 @@
);
expect(registration(Method.textDocument_formatting), isNull);
expect(registration(Method.textDocument_onTypeFormatting), isNull);
+ expect(registration(Method.textDocument_rangeFormatting), isNull);
// They should be reregistered if we change the config to enabled.
await monitorDynamicRegistrations(
@@ -120,6 +161,7 @@
);
expect(registration(Method.textDocument_formatting), isNotNull);
expect(registration(Method.textDocument_onTypeFormatting), isNotNull);
+ expect(registration(Method.textDocument_rangeFormatting), isNotNull);
}
Future<void> test_formatOnType_simple() async {
@@ -140,10 +182,96 @@
final formatEdits = await formatOnType(
mainFileUri.toString(), positionFromMarker(contents), '}');
expect(formatEdits, isNotNull);
- final formattedContents = applyTextEdits(contents, formatEdits);
+ final formattedContents =
+ applyTextEdits(withoutMarkers(contents), formatEdits);
expect(formattedContents, equals(expected));
}
+ Future<void> test_formatRange_editsOverlapRange() async {
+ // Only ranges that are fully contained by the range should be applied,
+ // not those that intersect the start/end.
+ const contents = '''
+main()
+{
+ [[ print('test');
+ print('test');
+ ]] print('test');
+}
+''';
+ final expected = '''
+main()
+{
+ print('test');
+ print('test');
+ print('test');
+}
+''';
+ await initialize();
+ await openFile(mainFileUri, withoutMarkers(contents));
+ await expectRangeFormattedContents(mainFileUri, contents, expected);
+ }
+
+ Future<void> test_formatRange_invalidRange() async {
+ const contents = '''
+main()
+{
+ print('test');
+}
+''';
+ await initialize();
+ await openFile(mainFileUri, withoutMarkers(contents));
+ final formatRangeRequest = formatRange(
+ mainFileUri.toString(),
+ Range(
+ start: Position(line: 0, character: 0),
+ end: Position(line: 10000, character: 0)),
+ );
+ await expectLater(formatRangeRequest,
+ throwsA(isResponseError(ServerErrorCodes.InvalidFileLineCol)));
+ }
+
+ Future<void> test_formatRange_simple() async {
+ const contents = '''
+main ()
+{
+
+ print('test');
+}
+
+[[main2 ()
+{
+
+ print('test');
+}]]
+
+main3 ()
+{
+
+ print('test');
+}
+''';
+ final expected = '''
+main ()
+{
+
+ print('test');
+}
+
+main2() {
+ print('test');
+}
+
+main3 ()
+{
+
+ print('test');
+}
+''';
+ await initialize();
+ await openFile(mainFileUri, withoutMarkers(contents));
+ await expectRangeFormattedContents(mainFileUri, contents, expected);
+ }
+
Future<void> test_invalidSyntax() async {
const contents = '''main(((( {
print('test');
@@ -182,6 +310,186 @@
await expectFormattedContents(mainFileUri, contents, expectedLongLines);
}
+ Future<void> test_minimalEdits_addWhitespace() async {
+ // Check we only get one edit to add the required whitespace and not
+ // an entire document replacement.
+ const contents = '''
+main(){}
+''';
+ const expected = '''
+main() {}
+''';
+ await initialize();
+ await openFile(mainFileUri, contents);
+ final formatEdits =
+ await expectFormattedContents(mainFileUri, contents, expected);
+ expect(formatEdits, hasLength(1));
+ expect(formatEdits[0].newText, ' ');
+ expect(formatEdits[0].range.start, equals(Position(line: 0, character: 6)));
+ }
+
+ Future<void> test_minimalEdits_removeFileLeadingWhitespace() async {
+ // Check whitespace before the first token is handled.
+ const contents = '''
+
+
+
+main() {}
+''';
+ const expected = '''
+main() {}
+''';
+ await initialize();
+ await openFile(mainFileUri, contents);
+ final formatEdits =
+ await expectFormattedContents(mainFileUri, contents, expected);
+ expect(formatEdits, hasLength(1));
+ expect(formatEdits[0].newText, '');
+ expect(formatEdits[0].range.start, equals(Position(line: 0, character: 0)));
+ expect(formatEdits[0].range.end, equals(Position(line: 3, character: 0)));
+ }
+
+ Future<void> test_minimalEdits_removeFileTrailingWhitespace() async {
+ // Check whitespace after the last token is handled.
+ const contents = '''
+main() {}
+
+
+
+
+''';
+ const expected = '''
+main() {}
+''';
+ await initialize();
+ await openFile(mainFileUri, contents);
+ final formatEdits =
+ await expectFormattedContents(mainFileUri, contents, expected);
+ expect(formatEdits, hasLength(1));
+ expect(formatEdits[0].newText, '');
+ expect(formatEdits[0].range.start, equals(Position(line: 1, character: 0)));
+ expect(formatEdits[0].range.end, equals(Position(line: 5, character: 0)));
+ }
+
+ Future<void> test_minimalEdits_removePartialWhitespaceAfter() async {
+ // Check we get an edit only to remove the unnecessary trailing whitespace
+ // and not to replace the whole whitespace with a single space.
+ const contents = '''
+main() {}
+''';
+ const expected = '''
+main() {}
+''';
+ await initialize();
+ await openFile(mainFileUri, contents);
+ final formatEdits =
+ await expectFormattedContents(mainFileUri, contents, expected);
+ expect(formatEdits, hasLength(1));
+ expect(
+ formatEdits[0],
+ equals(TextEdit(
+ range: Range(
+ start: Position(line: 0, character: 7),
+ end: Position(line: 0, character: 13)),
+ newText: '',
+ )));
+ }
+
+ Future<void> test_minimalEdits_removePartialWhitespaceBefore() async {
+ // Check we get an edit only to remove the unnecessary leading whitespace
+ // and not to replace the whole whitespace with a single space.
+ const contents = '''
+main()
+
+
+ {}
+''';
+ const expected = '''
+main() {}
+''';
+ await initialize();
+ await openFile(mainFileUri, contents);
+ final formatEdits =
+ await expectFormattedContents(mainFileUri, contents, expected);
+ expect(formatEdits, hasLength(1));
+ expect(
+ formatEdits[0],
+ equals(TextEdit(
+ range: Range(
+ start: Position(line: 0, character: 6),
+ end: Position(line: 3, character: 0)),
+ newText: '',
+ )));
+ }
+
+ Future<void> test_minimalEdits_removeWhitespace() async {
+ // Check we only get two edits to remove the unwanted whitespace and not
+ // an entire document replacement.
+ const contents = '''
+main( ) { }
+''';
+ const expected = '''
+main() {}
+''';
+ await initialize();
+ await openFile(mainFileUri, contents);
+ final formatEdits =
+ await expectFormattedContents(mainFileUri, contents, expected);
+ expect(formatEdits, hasLength(2));
+ expect(formatEdits[0].newText, isEmpty);
+ expect(formatEdits[0].range.start, equals(Position(line: 0, character: 5)));
+ expect(formatEdits[1].newText, isEmpty);
+ expect(formatEdits[1].range.start, equals(Position(line: 0, character: 9)));
+ }
+
+ Future<void> test_minimalEdits_withComments() async {
+ // Check we can get edits that span a comment (which does not appear in the
+ // main token list).
+ const contents = '''
+main() {
+ var a = 1;
+ // Comment
+ print(a);
+}
+''';
+ const expected = '''
+main() {
+ var a = 1;
+ // Comment
+ print(a);
+}
+''';
+ await initialize();
+ await openFile(mainFileUri, contents);
+ final formatEdits =
+ await expectFormattedContents(mainFileUri, contents, expected);
+ expect(formatEdits, hasLength(3));
+ expect(
+ formatEdits[0],
+ equals(TextEdit(
+ range: Range(
+ start: Position(line: 1, character: 2),
+ end: Position(line: 1, character: 8)),
+ newText: '',
+ )));
+ expect(
+ formatEdits[1],
+ equals(TextEdit(
+ range: Range(
+ start: Position(line: 2, character: 2),
+ end: Position(line: 2, character: 8)),
+ newText: '',
+ )));
+ expect(
+ formatEdits[2],
+ equals(TextEdit(
+ range: Range(
+ start: Position(line: 3, character: 2),
+ end: Position(line: 3, character: 8)),
+ newText: '',
+ )));
+ }
+
Future<void> test_nonDartFile() async {
await initialize();
await openFile(pubspecFileUri, simplePubspecContent);
@@ -253,4 +561,21 @@
await initialize();
await expectFormattedContents(mainFileUri, contents, expected);
}
+
+ Future<void> test_validSyntax_withErrors() async {
+ // We should still be able to format syntactically valid code even if it has analysis
+ // errors.
+ const contents = '''main() {
+ print(a);
+}
+''';
+ const expected = '''main() {
+ print(a);
+}
+''';
+ await initialize();
+ await openFile(mainFileUri, contents);
+
+ await expectFormattedContents(mainFileUri, contents, expected);
+ }
}
diff --git a/pkg/analysis_server/test/lsp/initialization_test.dart b/pkg/analysis_server/test/lsp/initialization_test.dart
index 4caaecc..50bcc58 100644
--- a/pkg/analysis_server/test/lsp/initialization_test.dart
+++ b/pkg/analysis_server/test/lsp/initialization_test.dart
@@ -115,6 +115,7 @@
expect(initResult.capabilities.documentHighlightProvider, isNotNull);
expect(initResult.capabilities.documentFormattingProvider, isNotNull);
expect(initResult.capabilities.documentOnTypeFormattingProvider, isNotNull);
+ expect(initResult.capabilities.documentRangeFormattingProvider, isNotNull);
expect(initResult.capabilities.definitionProvider, isNotNull);
expect(initResult.capabilities.codeActionProvider, isNotNull);
expect(initResult.capabilities.renameProvider, isNotNull);
@@ -164,6 +165,7 @@
expect(initResult.capabilities.documentHighlightProvider, isNull);
expect(initResult.capabilities.documentFormattingProvider, isNull);
expect(initResult.capabilities.documentOnTypeFormattingProvider, isNull);
+ expect(initResult.capabilities.documentRangeFormattingProvider, isNull);
expect(initResult.capabilities.definitionProvider, isNull);
expect(initResult.capabilities.codeActionProvider, isNull);
expect(initResult.capabilities.renameProvider, isNull);
diff --git a/pkg/analysis_server/test/lsp/server_abstract.dart b/pkg/analysis_server/test/lsp/server_abstract.dart
index 342e9f1..64e8480 100644
--- a/pkg/analysis_server/test/lsp/server_abstract.dart
+++ b/pkg/analysis_server/test/lsp/server_abstract.dart
@@ -217,6 +217,7 @@
'documentSymbol': {'dynamicRegistration': true},
'formatting': {'dynamicRegistration': true},
'onTypeFormatting': {'dynamicRegistration': true},
+ 'rangeFormatting': {'dynamicRegistration': true},
'declaration': {'dynamicRegistration': true},
'definition': {'dynamicRegistration': true},
'implementation': {'dynamicRegistration': true},
@@ -330,6 +331,7 @@
return extendTextDocumentCapabilities(source, {
'formatting': {'dynamicRegistration': true},
'onTypeFormatting': {'dynamicRegistration': true},
+ 'rangeFormatting': {'dynamicRegistration': true},
});
}
@@ -615,12 +617,13 @@
}
validateChangesCanBeApplied();
- changes.sort(
- (c1, c2) =>
- positionCompare(c1.range.start, c2.range.start) *
- -1, // Multiply by -1 to get descending sort.
- );
- for (final change in changes) {
+ final sortedChanges = changes.toList() // Don't mutate the original list.
+ ..sort(
+ // Multiply by -1 to get descending sort.
+ (c1, c2) => positionCompare(c1.range.start, c2.range.start) * -1,
+ );
+
+ for (final change in sortedChanges) {
newContent = applyTextEdit(newContent, change);
}
@@ -806,6 +809,21 @@
request, _fromJsonList(TextEdit.fromJson));
}
+ Future<List<TextEdit>> formatRange(String fileUri, Range range) {
+ final request = makeRequest(
+ Method.textDocument_rangeFormatting,
+ DocumentRangeFormattingParams(
+ options: FormattingOptions(
+ tabSize: 2,
+ insertSpaces: true), // These currently don't do anything
+ textDocument: TextDocumentIdentifier(uri: fileUri),
+ range: range,
+ ),
+ );
+ return expectSuccessfulResponseTo(
+ request, _fromJsonList(TextEdit.fromJson));
+ }
+
Future<List<Either2<Command, CodeAction>>> getCodeActions(
String fileUri, {
Range range,
diff --git a/pkg/analysis_server/test/src/computer/highlights_computer_test.dart b/pkg/analysis_server/test/src/computer/highlights_computer_test.dart
deleted file mode 100644
index b9d1af4..0000000
--- a/pkg/analysis_server/test/src/computer/highlights_computer_test.dart
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analysis_server/src/computer/computer_highlights.dart';
-import 'package:analysis_server/src/protocol_server.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../../abstract_context.dart';
-
-void main() {
- defineReflectiveSuite(() {
- defineReflectiveTests(HighlightsComputerTest);
- });
-}
-
-@reflectiveTest
-class HighlightsComputerTest extends AbstractContextTest {
- String sourcePath;
- String content;
- List<HighlightRegion> highlights;
-
- @override
- void setUp() {
- super.setUp();
- sourcePath = convertPath('/home/test/lib/test.dart');
- }
-
- Future<void> test_comment() async {
- await _computeHighlights('''
-// A trailing comment
-''');
- _check(HighlightRegionType.COMMENT_END_OF_LINE, '// A trailing comment');
- }
-
- Future<void> test_comment_trailing() async {
- await _computeHighlights('''
-class A {}
-// A trailing comment
-''');
- _check(HighlightRegionType.COMMENT_END_OF_LINE, '// A trailing comment');
- }
-
- Future<void> test_extension() async {
- await _computeHighlights('''
-extension E on String {}
-''');
- _check(HighlightRegionType.KEYWORD, 'extension');
- _check(HighlightRegionType.BUILT_IN, 'on');
- }
-
- Future<void> test_methodInvocation_ofExtensionOverride_unresolved() async {
- await _computeHighlights('''
-extension E on int {}
-
-main() {
- E(0).foo();
-}
-''', hasErrors: true);
- _check(HighlightRegionType.IDENTIFIER_DEFAULT, 'foo');
- }
-
- void _check(HighlightRegionType expectedType, String expectedText) {
- for (var region in highlights) {
- if (region.type == expectedType) {
- var startIndex = region.offset;
- var endIndex = startIndex + region.length;
- var highlightedText = content.substring(startIndex, endIndex);
- if (highlightedText == expectedText) {
- return;
- }
- }
- }
- fail('Expected region of type $expectedType with text "$expectedText"');
- }
-
- Future<void> _computeHighlights(
- String content, {
- bool hasErrors = false,
- }) async {
- this.content = content;
- newFile(sourcePath, content: content);
- var result = await session.getResolvedUnit(sourcePath);
-
- if (hasErrors) {
- expect(result.errors, isNotEmpty);
- } else {
- expect(result.errors, isEmpty);
- }
-
- var computer = DartUnitHighlightsComputer(result.unit);
- highlights = computer.compute();
- }
-}
diff --git a/pkg/analysis_server/test/src/computer/test_all.dart b/pkg/analysis_server/test/src/computer/test_all.dart
index 8d7653e..b35ad77 100644
--- a/pkg/analysis_server/test/src/computer/test_all.dart
+++ b/pkg/analysis_server/test/src/computer/test_all.dart
@@ -7,7 +7,6 @@
import 'closing_labels_computer_test.dart' as closing_labels_computer;
import 'folding_computer_test.dart' as folding_computer;
import 'highlights2_computer_test.dart' as highlights2_computer;
-import 'highlights_computer_test.dart' as highlights_computer;
import 'import_elements_computer_test.dart' as import_elements_computer;
import 'imported_elements_computer_test.dart' as imported_elements_computer;
import 'outline_computer_test.dart' as outline_computer;
@@ -17,7 +16,6 @@
closing_labels_computer.main();
folding_computer.main();
highlights2_computer.main();
- highlights_computer.main();
import_elements_computer.main();
imported_elements_computer.main();
outline_computer.main();
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_null_aware_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_null_aware_test.dart
index d12dd4c..7d6b659 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_to_null_aware_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_null_aware_test.dart
@@ -11,12 +11,12 @@
void main() {
defineReflectiveSuite(() {
- defineReflectiveTests(ConvertToNormalParameterTest);
+ defineReflectiveTests(ConvertToNullAwareTest);
});
}
@reflectiveTest
-class ConvertToNormalParameterTest extends AssistProcessorTest {
+class ConvertToNullAwareTest extends AssistProcessorTest {
@override
AssistKind get kind => DartAssistKind.CONVERT_TO_NULL_AWARE;
@@ -138,6 +138,18 @@
''');
}
+ Future<void> test_notEqual_noTarget() async {
+ // https://github.com/dart-lang/sdk/issues/44173
+ verifyNoTestUnitErrors = false;
+ await resolveTestCode('''
+foo() {
+ var range = 1;
+ var rangeStart = range != null ? toOffset() : null;
+}
+''');
+ await assertNoAssistAt(' null;');
+ }
+
Future<void> test_notEqual_notNullPreserving() async {
await resolveTestCode('''
abstract class A {
diff --git a/pkg/analysis_server/tool/lsp_spec/README.md b/pkg/analysis_server/tool/lsp_spec/README.md
index e95c70a..20b35d8 100644
--- a/pkg/analysis_server/tool/lsp_spec/README.md
+++ b/pkg/analysis_server/tool/lsp_spec/README.md
@@ -94,7 +94,7 @@
| textDocument/documentColor | | | | | |
| textDocument/colorPresentation | | | | | |
| textDocument/formatting | ✅ | ✅ | | ✅ | ✅ |
-| textDocument/rangeFormatting | | | | | | requires support from dart_style?
+| textDocument/rangeFormatting | ✅ | ✅ | | ✅ | ✅ |
| textDocument/onTypeFormatting | ✅ | ✅ | | ✅ | ✅ |
| textDocument/rename | ✅ | ✅ | | ✅ | ✅ |
| textDocument/prepareRename | ✅ | ✅ | | ✅ | ✅ |
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java b/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java
index 21d7fbc..2b1e1d2 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java
@@ -32,28 +32,16 @@
public static final String DIRECTIVE = "DIRECTIVE";
/**
- * Only for version 1 of highlight.
+ * Deprecated - no longer sent.
*/
public static final String DYNAMIC_TYPE = "DYNAMIC_TYPE";
- /**
- * Only for version 2 of highlight.
- */
public static final String DYNAMIC_LOCAL_VARIABLE_DECLARATION = "DYNAMIC_LOCAL_VARIABLE_DECLARATION";
- /**
- * Only for version 2 of highlight.
- */
public static final String DYNAMIC_LOCAL_VARIABLE_REFERENCE = "DYNAMIC_LOCAL_VARIABLE_REFERENCE";
- /**
- * Only for version 2 of highlight.
- */
public static final String DYNAMIC_PARAMETER_DECLARATION = "DYNAMIC_PARAMETER_DECLARATION";
- /**
- * Only for version 2 of highlight.
- */
public static final String DYNAMIC_PARAMETER_REFERENCE = "DYNAMIC_PARAMETER_REFERENCE";
public static final String ENUM = "ENUM";
@@ -61,29 +49,29 @@
public static final String ENUM_CONSTANT = "ENUM_CONSTANT";
/**
- * Only for version 1 of highlight.
+ * Deprecated - no longer sent.
*/
public static final String FIELD = "FIELD";
/**
- * Only for version 1 of highlight.
+ * Deprecated - no longer sent.
*/
public static final String FIELD_STATIC = "FIELD_STATIC";
/**
- * Only for version 1 of highlight.
+ * Deprecated - no longer sent.
*/
public static final String FUNCTION = "FUNCTION";
/**
- * Only for version 1 of highlight.
+ * Deprecated - no longer sent.
*/
public static final String FUNCTION_DECLARATION = "FUNCTION_DECLARATION";
public static final String FUNCTION_TYPE_ALIAS = "FUNCTION_TYPE_ALIAS";
/**
- * Only for version 1 of highlight.
+ * Deprecated - no longer sent.
*/
public static final String GETTER_DECLARATION = "GETTER_DECLARATION";
@@ -91,58 +79,28 @@
public static final String IMPORT_PREFIX = "IMPORT_PREFIX";
- /**
- * Only for version 2 of highlight.
- */
public static final String INSTANCE_FIELD_DECLARATION = "INSTANCE_FIELD_DECLARATION";
- /**
- * Only for version 2 of highlight.
- */
public static final String INSTANCE_FIELD_REFERENCE = "INSTANCE_FIELD_REFERENCE";
- /**
- * Only for version 2 of highlight.
- */
public static final String INSTANCE_GETTER_DECLARATION = "INSTANCE_GETTER_DECLARATION";
- /**
- * Only for version 2 of highlight.
- */
public static final String INSTANCE_GETTER_REFERENCE = "INSTANCE_GETTER_REFERENCE";
- /**
- * Only for version 2 of highlight.
- */
public static final String INSTANCE_METHOD_DECLARATION = "INSTANCE_METHOD_DECLARATION";
- /**
- * Only for version 2 of highlight.
- */
public static final String INSTANCE_METHOD_REFERENCE = "INSTANCE_METHOD_REFERENCE";
- /**
- * Only for version 2 of highlight.
- */
public static final String INSTANCE_SETTER_DECLARATION = "INSTANCE_SETTER_DECLARATION";
- /**
- * Only for version 2 of highlight.
- */
public static final String INSTANCE_SETTER_REFERENCE = "INSTANCE_SETTER_REFERENCE";
- /**
- * Only for version 2 of highlight.
- */
public static final String INVALID_STRING_ESCAPE = "INVALID_STRING_ESCAPE";
public static final String KEYWORD = "KEYWORD";
public static final String LABEL = "LABEL";
- /**
- * Only for version 2 of highlight.
- */
public static final String LIBRARY_NAME = "LIBRARY_NAME";
public static final String LITERAL_BOOLEAN = "LITERAL_BOOLEAN";
@@ -157,155 +115,92 @@
public static final String LITERAL_STRING = "LITERAL_STRING";
- /**
- * Only for version 2 of highlight.
- */
public static final String LOCAL_FUNCTION_DECLARATION = "LOCAL_FUNCTION_DECLARATION";
- /**
- * Only for version 2 of highlight.
- */
public static final String LOCAL_FUNCTION_REFERENCE = "LOCAL_FUNCTION_REFERENCE";
/**
- * Only for version 1 of highlight.
+ * Deprecated - no longer sent.
*/
public static final String LOCAL_VARIABLE = "LOCAL_VARIABLE";
public static final String LOCAL_VARIABLE_DECLARATION = "LOCAL_VARIABLE_DECLARATION";
- /**
- * Only for version 2 of highlight.
- */
public static final String LOCAL_VARIABLE_REFERENCE = "LOCAL_VARIABLE_REFERENCE";
/**
- * Only for version 1 of highlight.
+ * Deprecated - no longer sent.
*/
public static final String METHOD = "METHOD";
/**
- * Only for version 1 of highlight.
+ * Deprecated - no longer sent.
*/
public static final String METHOD_DECLARATION = "METHOD_DECLARATION";
/**
- * Only for version 1 of highlight.
+ * Deprecated - no longer sent.
*/
public static final String METHOD_DECLARATION_STATIC = "METHOD_DECLARATION_STATIC";
/**
- * Only for version 1 of highlight.
+ * Deprecated - no longer sent.
*/
public static final String METHOD_STATIC = "METHOD_STATIC";
/**
- * Only for version 1 of highlight.
+ * Deprecated - no longer sent.
*/
public static final String PARAMETER = "PARAMETER";
/**
- * Only for version 1 of highlight.
+ * Deprecated - no longer sent.
*/
public static final String SETTER_DECLARATION = "SETTER_DECLARATION";
/**
- * Only for version 1 of highlight.
+ * Deprecated - no longer sent.
*/
public static final String TOP_LEVEL_VARIABLE = "TOP_LEVEL_VARIABLE";
- /**
- * Only for version 2 of highlight.
- */
public static final String PARAMETER_DECLARATION = "PARAMETER_DECLARATION";
- /**
- * Only for version 2 of highlight.
- */
public static final String PARAMETER_REFERENCE = "PARAMETER_REFERENCE";
- /**
- * Only for version 2 of highlight.
- */
public static final String STATIC_FIELD_DECLARATION = "STATIC_FIELD_DECLARATION";
- /**
- * Only for version 2 of highlight.
- */
public static final String STATIC_GETTER_DECLARATION = "STATIC_GETTER_DECLARATION";
- /**
- * Only for version 2 of highlight.
- */
public static final String STATIC_GETTER_REFERENCE = "STATIC_GETTER_REFERENCE";
- /**
- * Only for version 2 of highlight.
- */
public static final String STATIC_METHOD_DECLARATION = "STATIC_METHOD_DECLARATION";
- /**
- * Only for version 2 of highlight.
- */
public static final String STATIC_METHOD_REFERENCE = "STATIC_METHOD_REFERENCE";
- /**
- * Only for version 2 of highlight.
- */
public static final String STATIC_SETTER_DECLARATION = "STATIC_SETTER_DECLARATION";
- /**
- * Only for version 2 of highlight.
- */
public static final String STATIC_SETTER_REFERENCE = "STATIC_SETTER_REFERENCE";
- /**
- * Only for version 2 of highlight.
- */
public static final String TOP_LEVEL_FUNCTION_DECLARATION = "TOP_LEVEL_FUNCTION_DECLARATION";
- /**
- * Only for version 2 of highlight.
- */
public static final String TOP_LEVEL_FUNCTION_REFERENCE = "TOP_LEVEL_FUNCTION_REFERENCE";
- /**
- * Only for version 2 of highlight.
- */
public static final String TOP_LEVEL_GETTER_DECLARATION = "TOP_LEVEL_GETTER_DECLARATION";
- /**
- * Only for version 2 of highlight.
- */
public static final String TOP_LEVEL_GETTER_REFERENCE = "TOP_LEVEL_GETTER_REFERENCE";
- /**
- * Only for version 2 of highlight.
- */
public static final String TOP_LEVEL_SETTER_DECLARATION = "TOP_LEVEL_SETTER_DECLARATION";
- /**
- * Only for version 2 of highlight.
- */
public static final String TOP_LEVEL_SETTER_REFERENCE = "TOP_LEVEL_SETTER_REFERENCE";
- /**
- * Only for version 2 of highlight.
- */
public static final String TOP_LEVEL_VARIABLE_DECLARATION = "TOP_LEVEL_VARIABLE_DECLARATION";
public static final String TYPE_NAME_DYNAMIC = "TYPE_NAME_DYNAMIC";
public static final String TYPE_PARAMETER = "TYPE_PARAMETER";
- /**
- * Only for version 2 of highlight.
- */
public static final String UNRESOLVED_INSTANCE_MEMBER_REFERENCE = "UNRESOLVED_INSTANCE_MEMBER_REFERENCE";
- /**
- * Only for version 2 of highlight.
- */
public static final String VALID_STRING_ESCAPE = "VALID_STRING_ESCAPE";
}
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index eb8cf23..262ca7c 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -7,7 +7,7 @@
<body>
<h1>Analysis Server API Specification</h1>
<h1 style="color:#999999">Version
- <version>1.30.0</version>
+ <version>1.31.0</version>
</h1>
<p>
This document contains a specification of the API provided by the
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
index 25f5a64..61ada08 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
@@ -6,7 +6,7 @@
// To regenerate the file, use the script
// "pkg/analysis_server/tool/spec/generate_files".
-const String PROTOCOL_VERSION = '1.30.0';
+const String PROTOCOL_VERSION = '1.31.0';
const String ANALYSIS_NOTIFICATION_ANALYZED_FILES = 'analysis.analyzedFiles';
const String ANALYSIS_NOTIFICATION_ANALYZED_FILES_DIRECTORIES = 'directories';
diff --git a/pkg/analyzer_plugin/doc/api.html b/pkg/analyzer_plugin/doc/api.html
index 76ba245..777a128 100644
--- a/pkg/analyzer_plugin/doc/api.html
+++ b/pkg/analyzer_plugin/doc/api.html
@@ -1354,152 +1354,47 @@
<dl><dt class="value">ANNOTATION</dt><dt class="value">BUILT_IN</dt><dt class="value">CLASS</dt><dt class="value">COMMENT_BLOCK</dt><dt class="value">COMMENT_DOCUMENTATION</dt><dt class="value">COMMENT_END_OF_LINE</dt><dt class="value">CONSTRUCTOR</dt><dt class="value">DIRECTIVE</dt><dt class="value">DYNAMIC_TYPE</dt><dd>
- <p>Only for version 1 of highlight.</p>
- </dd><dt class="value">DYNAMIC_LOCAL_VARIABLE_DECLARATION</dt><dd>
+ <p>Deprecated - no longer sent.</p>
+ </dd><dt class="value">DYNAMIC_LOCAL_VARIABLE_DECLARATION</dt><dt class="value">DYNAMIC_LOCAL_VARIABLE_REFERENCE</dt><dt class="value">DYNAMIC_PARAMETER_DECLARATION</dt><dt class="value">DYNAMIC_PARAMETER_REFERENCE</dt><dt class="value">ENUM</dt><dt class="value">ENUM_CONSTANT</dt><dt class="value">FIELD</dt><dd>
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">DYNAMIC_LOCAL_VARIABLE_REFERENCE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">DYNAMIC_PARAMETER_DECLARATION</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">DYNAMIC_PARAMETER_REFERENCE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">ENUM</dt><dt class="value">ENUM_CONSTANT</dt><dt class="value">FIELD</dt><dd>
-
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</dd><dt class="value">FIELD_STATIC</dt><dd>
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</dd><dt class="value">FUNCTION</dt><dd>
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</dd><dt class="value">FUNCTION_DECLARATION</dt><dd>
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</dd><dt class="value">FUNCTION_TYPE_ALIAS</dt><dt class="value">GETTER_DECLARATION</dt><dd>
- <p>Only for version 1 of highlight.</p>
- </dd><dt class="value">IDENTIFIER_DEFAULT</dt><dt class="value">IMPORT_PREFIX</dt><dt class="value">INSTANCE_FIELD_DECLARATION</dt><dd>
+ <p>Deprecated - no longer sent.</p>
+ </dd><dt class="value">IDENTIFIER_DEFAULT</dt><dt class="value">IMPORT_PREFIX</dt><dt class="value">INSTANCE_FIELD_DECLARATION</dt><dt class="value">INSTANCE_FIELD_REFERENCE</dt><dt class="value">INSTANCE_GETTER_DECLARATION</dt><dt class="value">INSTANCE_GETTER_REFERENCE</dt><dt class="value">INSTANCE_METHOD_DECLARATION</dt><dt class="value">INSTANCE_METHOD_REFERENCE</dt><dt class="value">INSTANCE_SETTER_DECLARATION</dt><dt class="value">INSTANCE_SETTER_REFERENCE</dt><dt class="value">INVALID_STRING_ESCAPE</dt><dt class="value">KEYWORD</dt><dt class="value">LABEL</dt><dt class="value">LIBRARY_NAME</dt><dt class="value">LITERAL_BOOLEAN</dt><dt class="value">LITERAL_DOUBLE</dt><dt class="value">LITERAL_INTEGER</dt><dt class="value">LITERAL_LIST</dt><dt class="value">LITERAL_MAP</dt><dt class="value">LITERAL_STRING</dt><dt class="value">LOCAL_FUNCTION_DECLARATION</dt><dt class="value">LOCAL_FUNCTION_REFERENCE</dt><dt class="value">LOCAL_VARIABLE</dt><dd>
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">INSTANCE_FIELD_REFERENCE</dt><dd>
+ <p>Deprecated - no longer sent.</p>
+ </dd><dt class="value">LOCAL_VARIABLE_DECLARATION</dt><dt class="value">LOCAL_VARIABLE_REFERENCE</dt><dt class="value">METHOD</dt><dd>
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">INSTANCE_GETTER_DECLARATION</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">INSTANCE_GETTER_REFERENCE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">INSTANCE_METHOD_DECLARATION</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">INSTANCE_METHOD_REFERENCE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">INSTANCE_SETTER_DECLARATION</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">INSTANCE_SETTER_REFERENCE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">INVALID_STRING_ESCAPE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">KEYWORD</dt><dt class="value">LABEL</dt><dt class="value">LIBRARY_NAME</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">LITERAL_BOOLEAN</dt><dt class="value">LITERAL_DOUBLE</dt><dt class="value">LITERAL_INTEGER</dt><dt class="value">LITERAL_LIST</dt><dt class="value">LITERAL_MAP</dt><dt class="value">LITERAL_STRING</dt><dt class="value">LOCAL_FUNCTION_DECLARATION</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">LOCAL_FUNCTION_REFERENCE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">LOCAL_VARIABLE</dt><dd>
-
- <p>Only for version 1 of highlight.</p>
- </dd><dt class="value">LOCAL_VARIABLE_DECLARATION</dt><dt class="value">LOCAL_VARIABLE_REFERENCE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">METHOD</dt><dd>
-
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</dd><dt class="value">METHOD_DECLARATION</dt><dd>
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</dd><dt class="value">METHOD_DECLARATION_STATIC</dt><dd>
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</dd><dt class="value">METHOD_STATIC</dt><dd>
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</dd><dt class="value">PARAMETER</dt><dd>
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</dd><dt class="value">SETTER_DECLARATION</dt><dd>
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</dd><dt class="value">TOP_LEVEL_VARIABLE</dt><dd>
- <p>Only for version 1 of highlight.</p>
- </dd><dt class="value">PARAMETER_DECLARATION</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">PARAMETER_REFERENCE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">STATIC_FIELD_DECLARATION</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">STATIC_GETTER_DECLARATION</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">STATIC_GETTER_REFERENCE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">STATIC_METHOD_DECLARATION</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">STATIC_METHOD_REFERENCE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">STATIC_SETTER_DECLARATION</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">STATIC_SETTER_REFERENCE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">TOP_LEVEL_FUNCTION_DECLARATION</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">TOP_LEVEL_FUNCTION_REFERENCE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">TOP_LEVEL_GETTER_DECLARATION</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">TOP_LEVEL_GETTER_REFERENCE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">TOP_LEVEL_SETTER_DECLARATION</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">TOP_LEVEL_SETTER_REFERENCE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">TOP_LEVEL_VARIABLE_DECLARATION</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">TYPE_NAME_DYNAMIC</dt><dt class="value">TYPE_PARAMETER</dt><dt class="value">UNRESOLVED_INSTANCE_MEMBER_REFERENCE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd><dt class="value">VALID_STRING_ESCAPE</dt><dd>
-
- <p>Only for version 2 of highlight.</p>
- </dd></dl></dd><dt class="typeDefinition"><a name="type_KytheEntry">KytheEntry: object</a></dt><dd>
+ <p>Deprecated - no longer sent.</p>
+ </dd><dt class="value">PARAMETER_DECLARATION</dt><dt class="value">PARAMETER_REFERENCE</dt><dt class="value">STATIC_FIELD_DECLARATION</dt><dt class="value">STATIC_GETTER_DECLARATION</dt><dt class="value">STATIC_GETTER_REFERENCE</dt><dt class="value">STATIC_METHOD_DECLARATION</dt><dt class="value">STATIC_METHOD_REFERENCE</dt><dt class="value">STATIC_SETTER_DECLARATION</dt><dt class="value">STATIC_SETTER_REFERENCE</dt><dt class="value">TOP_LEVEL_FUNCTION_DECLARATION</dt><dt class="value">TOP_LEVEL_FUNCTION_REFERENCE</dt><dt class="value">TOP_LEVEL_GETTER_DECLARATION</dt><dt class="value">TOP_LEVEL_GETTER_REFERENCE</dt><dt class="value">TOP_LEVEL_SETTER_DECLARATION</dt><dt class="value">TOP_LEVEL_SETTER_REFERENCE</dt><dt class="value">TOP_LEVEL_VARIABLE_DECLARATION</dt><dt class="value">TYPE_NAME_DYNAMIC</dt><dt class="value">TYPE_PARAMETER</dt><dt class="value">UNRESOLVED_INSTANCE_MEMBER_REFERENCE</dt><dt class="value">VALID_STRING_ESCAPE</dt></dl></dd><dt class="typeDefinition"><a name="type_KytheEntry">KytheEntry: object</a></dt><dd>
<p>
This object matches the format and documentation of the Entry object
documented in the
diff --git a/pkg/analyzer_plugin/lib/protocol/protocol_common.dart b/pkg/analyzer_plugin/lib/protocol/protocol_common.dart
index 6e2aeae..2d0391d 100644
--- a/pkg/analyzer_plugin/lib/protocol/protocol_common.dart
+++ b/pkg/analyzer_plugin/lib/protocol/protocol_common.dart
@@ -2307,23 +2307,19 @@
static const HighlightRegionType DIRECTIVE =
HighlightRegionType._('DIRECTIVE');
- /// Only for version 1 of highlight.
+ /// Deprecated - no longer sent.
static const HighlightRegionType DYNAMIC_TYPE =
HighlightRegionType._('DYNAMIC_TYPE');
- /// Only for version 2 of highlight.
static const HighlightRegionType DYNAMIC_LOCAL_VARIABLE_DECLARATION =
HighlightRegionType._('DYNAMIC_LOCAL_VARIABLE_DECLARATION');
- /// Only for version 2 of highlight.
static const HighlightRegionType DYNAMIC_LOCAL_VARIABLE_REFERENCE =
HighlightRegionType._('DYNAMIC_LOCAL_VARIABLE_REFERENCE');
- /// Only for version 2 of highlight.
static const HighlightRegionType DYNAMIC_PARAMETER_DECLARATION =
HighlightRegionType._('DYNAMIC_PARAMETER_DECLARATION');
- /// Only for version 2 of highlight.
static const HighlightRegionType DYNAMIC_PARAMETER_REFERENCE =
HighlightRegionType._('DYNAMIC_PARAMETER_REFERENCE');
@@ -2332,24 +2328,24 @@
static const HighlightRegionType ENUM_CONSTANT =
HighlightRegionType._('ENUM_CONSTANT');
- /// Only for version 1 of highlight.
+ /// Deprecated - no longer sent.
static const HighlightRegionType FIELD = HighlightRegionType._('FIELD');
- /// Only for version 1 of highlight.
+ /// Deprecated - no longer sent.
static const HighlightRegionType FIELD_STATIC =
HighlightRegionType._('FIELD_STATIC');
- /// Only for version 1 of highlight.
+ /// Deprecated - no longer sent.
static const HighlightRegionType FUNCTION = HighlightRegionType._('FUNCTION');
- /// Only for version 1 of highlight.
+ /// Deprecated - no longer sent.
static const HighlightRegionType FUNCTION_DECLARATION =
HighlightRegionType._('FUNCTION_DECLARATION');
static const HighlightRegionType FUNCTION_TYPE_ALIAS =
HighlightRegionType._('FUNCTION_TYPE_ALIAS');
- /// Only for version 1 of highlight.
+ /// Deprecated - no longer sent.
static const HighlightRegionType GETTER_DECLARATION =
HighlightRegionType._('GETTER_DECLARATION');
@@ -2359,39 +2355,30 @@
static const HighlightRegionType IMPORT_PREFIX =
HighlightRegionType._('IMPORT_PREFIX');
- /// Only for version 2 of highlight.
static const HighlightRegionType INSTANCE_FIELD_DECLARATION =
HighlightRegionType._('INSTANCE_FIELD_DECLARATION');
- /// Only for version 2 of highlight.
static const HighlightRegionType INSTANCE_FIELD_REFERENCE =
HighlightRegionType._('INSTANCE_FIELD_REFERENCE');
- /// Only for version 2 of highlight.
static const HighlightRegionType INSTANCE_GETTER_DECLARATION =
HighlightRegionType._('INSTANCE_GETTER_DECLARATION');
- /// Only for version 2 of highlight.
static const HighlightRegionType INSTANCE_GETTER_REFERENCE =
HighlightRegionType._('INSTANCE_GETTER_REFERENCE');
- /// Only for version 2 of highlight.
static const HighlightRegionType INSTANCE_METHOD_DECLARATION =
HighlightRegionType._('INSTANCE_METHOD_DECLARATION');
- /// Only for version 2 of highlight.
static const HighlightRegionType INSTANCE_METHOD_REFERENCE =
HighlightRegionType._('INSTANCE_METHOD_REFERENCE');
- /// Only for version 2 of highlight.
static const HighlightRegionType INSTANCE_SETTER_DECLARATION =
HighlightRegionType._('INSTANCE_SETTER_DECLARATION');
- /// Only for version 2 of highlight.
static const HighlightRegionType INSTANCE_SETTER_REFERENCE =
HighlightRegionType._('INSTANCE_SETTER_REFERENCE');
- /// Only for version 2 of highlight.
static const HighlightRegionType INVALID_STRING_ESCAPE =
HighlightRegionType._('INVALID_STRING_ESCAPE');
@@ -2399,7 +2386,6 @@
static const HighlightRegionType LABEL = HighlightRegionType._('LABEL');
- /// Only for version 2 of highlight.
static const HighlightRegionType LIBRARY_NAME =
HighlightRegionType._('LIBRARY_NAME');
@@ -2421,113 +2407,94 @@
static const HighlightRegionType LITERAL_STRING =
HighlightRegionType._('LITERAL_STRING');
- /// Only for version 2 of highlight.
static const HighlightRegionType LOCAL_FUNCTION_DECLARATION =
HighlightRegionType._('LOCAL_FUNCTION_DECLARATION');
- /// Only for version 2 of highlight.
static const HighlightRegionType LOCAL_FUNCTION_REFERENCE =
HighlightRegionType._('LOCAL_FUNCTION_REFERENCE');
- /// Only for version 1 of highlight.
+ /// Deprecated - no longer sent.
static const HighlightRegionType LOCAL_VARIABLE =
HighlightRegionType._('LOCAL_VARIABLE');
static const HighlightRegionType LOCAL_VARIABLE_DECLARATION =
HighlightRegionType._('LOCAL_VARIABLE_DECLARATION');
- /// Only for version 2 of highlight.
static const HighlightRegionType LOCAL_VARIABLE_REFERENCE =
HighlightRegionType._('LOCAL_VARIABLE_REFERENCE');
- /// Only for version 1 of highlight.
+ /// Deprecated - no longer sent.
static const HighlightRegionType METHOD = HighlightRegionType._('METHOD');
- /// Only for version 1 of highlight.
+ /// Deprecated - no longer sent.
static const HighlightRegionType METHOD_DECLARATION =
HighlightRegionType._('METHOD_DECLARATION');
- /// Only for version 1 of highlight.
+ /// Deprecated - no longer sent.
static const HighlightRegionType METHOD_DECLARATION_STATIC =
HighlightRegionType._('METHOD_DECLARATION_STATIC');
- /// Only for version 1 of highlight.
+ /// Deprecated - no longer sent.
static const HighlightRegionType METHOD_STATIC =
HighlightRegionType._('METHOD_STATIC');
- /// Only for version 1 of highlight.
+ /// Deprecated - no longer sent.
static const HighlightRegionType PARAMETER =
HighlightRegionType._('PARAMETER');
- /// Only for version 1 of highlight.
+ /// Deprecated - no longer sent.
static const HighlightRegionType SETTER_DECLARATION =
HighlightRegionType._('SETTER_DECLARATION');
- /// Only for version 1 of highlight.
+ /// Deprecated - no longer sent.
static const HighlightRegionType TOP_LEVEL_VARIABLE =
HighlightRegionType._('TOP_LEVEL_VARIABLE');
- /// Only for version 2 of highlight.
static const HighlightRegionType PARAMETER_DECLARATION =
HighlightRegionType._('PARAMETER_DECLARATION');
- /// Only for version 2 of highlight.
static const HighlightRegionType PARAMETER_REFERENCE =
HighlightRegionType._('PARAMETER_REFERENCE');
- /// Only for version 2 of highlight.
static const HighlightRegionType STATIC_FIELD_DECLARATION =
HighlightRegionType._('STATIC_FIELD_DECLARATION');
- /// Only for version 2 of highlight.
static const HighlightRegionType STATIC_GETTER_DECLARATION =
HighlightRegionType._('STATIC_GETTER_DECLARATION');
- /// Only for version 2 of highlight.
static const HighlightRegionType STATIC_GETTER_REFERENCE =
HighlightRegionType._('STATIC_GETTER_REFERENCE');
- /// Only for version 2 of highlight.
static const HighlightRegionType STATIC_METHOD_DECLARATION =
HighlightRegionType._('STATIC_METHOD_DECLARATION');
- /// Only for version 2 of highlight.
static const HighlightRegionType STATIC_METHOD_REFERENCE =
HighlightRegionType._('STATIC_METHOD_REFERENCE');
- /// Only for version 2 of highlight.
static const HighlightRegionType STATIC_SETTER_DECLARATION =
HighlightRegionType._('STATIC_SETTER_DECLARATION');
- /// Only for version 2 of highlight.
static const HighlightRegionType STATIC_SETTER_REFERENCE =
HighlightRegionType._('STATIC_SETTER_REFERENCE');
- /// Only for version 2 of highlight.
static const HighlightRegionType TOP_LEVEL_FUNCTION_DECLARATION =
HighlightRegionType._('TOP_LEVEL_FUNCTION_DECLARATION');
- /// Only for version 2 of highlight.
static const HighlightRegionType TOP_LEVEL_FUNCTION_REFERENCE =
HighlightRegionType._('TOP_LEVEL_FUNCTION_REFERENCE');
- /// Only for version 2 of highlight.
static const HighlightRegionType TOP_LEVEL_GETTER_DECLARATION =
HighlightRegionType._('TOP_LEVEL_GETTER_DECLARATION');
- /// Only for version 2 of highlight.
static const HighlightRegionType TOP_LEVEL_GETTER_REFERENCE =
HighlightRegionType._('TOP_LEVEL_GETTER_REFERENCE');
- /// Only for version 2 of highlight.
static const HighlightRegionType TOP_LEVEL_SETTER_DECLARATION =
HighlightRegionType._('TOP_LEVEL_SETTER_DECLARATION');
- /// Only for version 2 of highlight.
static const HighlightRegionType TOP_LEVEL_SETTER_REFERENCE =
HighlightRegionType._('TOP_LEVEL_SETTER_REFERENCE');
- /// Only for version 2 of highlight.
static const HighlightRegionType TOP_LEVEL_VARIABLE_DECLARATION =
HighlightRegionType._('TOP_LEVEL_VARIABLE_DECLARATION');
@@ -2537,11 +2504,9 @@
static const HighlightRegionType TYPE_PARAMETER =
HighlightRegionType._('TYPE_PARAMETER');
- /// Only for version 2 of highlight.
static const HighlightRegionType UNRESOLVED_INSTANCE_MEMBER_REFERENCE =
HighlightRegionType._('UNRESOLVED_INSTANCE_MEMBER_REFERENCE');
- /// Only for version 2 of highlight.
static const HighlightRegionType VALID_STRING_ESCAPE =
HighlightRegionType._('VALID_STRING_ESCAPE');
diff --git a/pkg/analyzer_plugin/tool/spec/common_types_spec.html b/pkg/analyzer_plugin/tool/spec/common_types_spec.html
index f4acea4..b14bca8 100644
--- a/pkg/analyzer_plugin/tool/spec/common_types_spec.html
+++ b/pkg/analyzer_plugin/tool/spec/common_types_spec.html
@@ -6,7 +6,7 @@
</head>
<body>
<h1>Common Types</h1>
-<version>1.3.0</version>
+<version>1.4.0</version>
<p>
This document contains a specification of the types that are common between
the analysis server wire protocol and the analysis server plugin wire
@@ -645,90 +645,76 @@
<value><code>DIRECTIVE</code></value>
<value>
<code>DYNAMIC_TYPE</code>
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</value>
<value>
<code>DYNAMIC_LOCAL_VARIABLE_DECLARATION</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value>
<code>DYNAMIC_LOCAL_VARIABLE_REFERENCE</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value>
<code>DYNAMIC_PARAMETER_DECLARATION</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value>
<code>DYNAMIC_PARAMETER_REFERENCE</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value><code>ENUM</code></value>
<value><code>ENUM_CONSTANT</code></value>
<value>
<code>FIELD</code>
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</value>
<value>
<code>FIELD_STATIC</code>
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</value>
<value>
<code>FUNCTION</code>
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</value>
<value>
<code>FUNCTION_DECLARATION</code>
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</value>
<value><code>FUNCTION_TYPE_ALIAS</code></value>
<value>
<code>GETTER_DECLARATION</code>
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</value>
<value><code>IDENTIFIER_DEFAULT</code></value>
<value><code>IMPORT_PREFIX</code></value>
<value>
<code>INSTANCE_FIELD_DECLARATION</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value>
<code>INSTANCE_FIELD_REFERENCE</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value>
<code>INSTANCE_GETTER_DECLARATION</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value>
<code>INSTANCE_GETTER_REFERENCE</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value>
<code>INSTANCE_METHOD_DECLARATION</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value>
<code>INSTANCE_METHOD_REFERENCE</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value>
<code>INSTANCE_SETTER_DECLARATION</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value>
<code>INSTANCE_SETTER_REFERENCE</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value>
<code>INVALID_STRING_ESCAPE</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value><code>KEYWORD</code></value>
<value><code>LABEL</code></value>
<value>
<code>LIBRARY_NAME</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value><code>LITERAL_BOOLEAN</code></value>
<value><code>LITERAL_DOUBLE</code></value>
@@ -738,122 +724,101 @@
<value><code>LITERAL_STRING</code></value>
<value>
<code>LOCAL_FUNCTION_DECLARATION</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value>
<code>LOCAL_FUNCTION_REFERENCE</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value>
<code>LOCAL_VARIABLE</code>
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</value>
<value><code>LOCAL_VARIABLE_DECLARATION</code></value>
<value>
<code>LOCAL_VARIABLE_REFERENCE</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value>
<code>METHOD</code>
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</value>
<value>
<code>METHOD_DECLARATION</code>
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</value>
<value>
<code>METHOD_DECLARATION_STATIC</code>
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</value>
<value>
<code>METHOD_STATIC</code>
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</value>
<value>
<code>PARAMETER</code>
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</value>
<value>
<code>SETTER_DECLARATION</code>
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</value>
<value>
<code>TOP_LEVEL_VARIABLE</code>
- <p>Only for version 1 of highlight.</p>
+ <p>Deprecated - no longer sent.</p>
</value>
<value>
<code>PARAMETER_DECLARATION</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value>
<code>PARAMETER_REFERENCE</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value>
<code>STATIC_FIELD_DECLARATION</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value>
<code>STATIC_GETTER_DECLARATION</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value>
<code>STATIC_GETTER_REFERENCE</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value>
<code>STATIC_METHOD_DECLARATION</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value>
<code>STATIC_METHOD_REFERENCE</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value>
<code>STATIC_SETTER_DECLARATION</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value>
<code>STATIC_SETTER_REFERENCE</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value>
<code>TOP_LEVEL_FUNCTION_DECLARATION</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value>
<code>TOP_LEVEL_FUNCTION_REFERENCE</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value>
<code>TOP_LEVEL_GETTER_DECLARATION</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value>
<code>TOP_LEVEL_GETTER_REFERENCE</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value>
<code>TOP_LEVEL_SETTER_DECLARATION</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value>
<code>TOP_LEVEL_SETTER_REFERENCE</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value>
<code>TOP_LEVEL_VARIABLE_DECLARATION</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value><code>TYPE_NAME_DYNAMIC</code></value>
<value><code>TYPE_PARAMETER</code></value>
<value>
<code>UNRESOLVED_INSTANCE_MEMBER_REFERENCE</code>
- <p>Only for version 2 of highlight.</p>
</value>
<value>
<code>VALID_STRING_ESCAPE</code>
- <p>Only for version 2 of highlight.</p>
</value>
</enum>
</type>
diff --git a/pkg/dartdev/test/commands/migrate_test.dart b/pkg/dartdev/test/commands/migrate_test.dart
index 307c85a..8101640 100644
--- a/pkg/dartdev/test/commands/migrate_test.dart
+++ b/pkg/dartdev/test/commands/migrate_test.dart
@@ -12,7 +12,8 @@
}
void defineMigrateTests() {
- final didYouForgetToRunPubGet = contains('Did you forget to run "pub get"?');
+ final runPubGet = contains('Run `dart pub get`');
+ final setLowerSdkConstraint = contains('Set the lower SDK constraint');
TestProject p;
@@ -60,7 +61,8 @@
var result = p.runSync('migrate', [p.dirPath]);
expect(result.exitCode, 1);
expect(result.stderr, isEmpty);
- expect(result.stdout, didYouForgetToRunPubGet);
+ expect(result.stdout, runPubGet);
+ expect(result.stdout, isNot(setLowerSdkConstraint));
});
test('non-pub-related error', () {
@@ -68,6 +70,7 @@
var result = p.runSync('migrate', [p.dirPath]);
expect(result.exitCode, 1);
expect(result.stderr, isEmpty);
- expect(result.stdout, isNot(didYouForgetToRunPubGet));
+ expect(result.stdout, runPubGet);
+ expect(result.stdout, setLowerSdkConstraint);
});
}
diff --git a/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_nnbd_test.dart b/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_nnbd_test.dart
index d070369..9bc5b5d 100644
--- a/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_nnbd_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_nnbd_test.dart
@@ -8,7 +8,7 @@
import 'package:kernel/ast.dart';
import 'package:kernel/core_types.dart';
import 'package:kernel/class_hierarchy.dart';
-import 'package:kernel/testing/mock_sdk_component.dart';
+import 'package:kernel/testing/type_parser_environment.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -20,352 +20,365 @@
@reflectiveTest
class TypeConstraintGathererTest {
- static const UnknownType unknownType = const UnknownType();
+ Env env;
- static const DynamicType dynamicType = const DynamicType();
+ final Map<String, DartType Function()> additionalTypes = {
+ 'UNKNOWN': () => new UnknownType()
+ };
- static const VoidType voidType = const VoidType();
+ Library _coreLibrary;
- final testLib =
- new Library(Uri.parse('org-dartlang:///test.dart'), name: 'lib')
- ..isNonNullableByDefault = true;
+ Library _testLibrary;
- Component component;
+ TypeConstraintGathererTest();
- CoreTypes coreTypes;
+ Component get component => env.component;
- TypeParameterType T1;
- TypeParameterType T2;
- TypeParameterType S1;
- TypeParameterType S2;
- TypeParameterType R1;
- TypeParameterType R2;
+ CoreTypes get coreTypes => env.coreTypes;
- Class classP;
+ Library get coreLibrary => _coreLibrary;
- Class classQ;
+ Library get testLibrary => _testLibrary;
- TypeConstraintGathererTest() {
- component = createMockSdkComponent();
- component.libraries.add(testLib..parent = component);
- coreTypes = new CoreTypes(component);
- T1 = new TypeParameterType(
- new TypeParameter('T1', coreTypes.objectLegacyRawType),
- Nullability.legacy);
- T2 = new TypeParameterType(
- new TypeParameter('T2', coreTypes.objectLegacyRawType),
- Nullability.legacy);
- S1 = new TypeParameterType(
- new TypeParameter('S1', coreTypes.objectNullableRawType),
- Nullability.undetermined);
- S2 = new TypeParameterType(
- new TypeParameter('S2', coreTypes.objectNullableRawType),
- Nullability.undetermined);
- R1 = new TypeParameterType(
- new TypeParameter('R1', coreTypes.objectNonNullableRawType),
- Nullability.nonNullable);
- R2 = new TypeParameterType(
- new TypeParameter('R2', coreTypes.objectNonNullableRawType),
- Nullability.nonNullable);
- classP = _addClass(_class('P'));
- classQ = _addClass(_class('Q'));
+ void parseTestLibrary(String testLibraryText) {
+ env = new Env(testLibraryText, isNonNullableByDefault: true);
+ assert(
+ env.component.libraries.length == 2,
+ "The tests are supposed to have exactly two libraries: "
+ "the core library and the test library.");
+ Library firstLibrary = env.component.libraries.first;
+ Library secondLibrary = env.component.libraries.last;
+ if (firstLibrary.importUri.scheme == "dart" &&
+ firstLibrary.importUri.path == "core") {
+ _coreLibrary = firstLibrary;
+ _testLibrary = secondLibrary;
+ } else {
+ assert(
+ secondLibrary.importUri.scheme == "dart" &&
+ secondLibrary.importUri.path == "core",
+ "One of the libraries is expected to be 'dart:core'.");
+ _coreLibrary == secondLibrary;
+ _testLibrary = firstLibrary;
+ }
}
- Class get functionClass => coreTypes.functionClass;
-
- InterfaceType get functionType => coreTypes.functionLegacyRawType;
-
- Class get iterableClass => coreTypes.iterableClass;
-
- Class get listClass => coreTypes.listClass;
-
- Class get mapClass => coreTypes.mapClass;
-
- Class get objectClass => coreTypes.objectClass;
-
- InterfaceType get P => coreTypes.legacyRawType(classP);
-
- InterfaceType get Q => coreTypes.legacyRawType(classQ);
-
void test_any_subtype_parameter() {
- DartType nullableQ = Q.withDeclaredNullability(Nullability.nullable);
- DartType nonNullableQ = Q.withDeclaredNullability(Nullability.nonNullable);
+ parseTestLibrary('class P; class Q;');
- _checkConstraintsLower(T1, nullableQ, testLib, ['lib::Q? <: T1']);
- _checkConstraintsLower(T1, nonNullableQ, testLib, ['lib::Q <: T1']);
- _checkConstraintsUpper(T1, nullableQ, testLib, ['T1 <: lib::Q?']);
- _checkConstraintsUpper(T1, nonNullableQ, testLib, ['T1 <: lib::Q']);
+ checkConstraintsLower('T1*', 'Q?', ['lib::Q? <: T1'],
+ typeParameters: 'T1 extends Object*');
+ checkConstraintsLower('T1*', 'Q', ['lib::Q <: T1'],
+ typeParameters: 'T1 extends Object*');
+ checkConstraintsUpper('T1*', 'Q?', ['T1 <: lib::Q?'],
+ typeParameters: 'T1 extends Object*');
+ checkConstraintsUpper('T1*', 'Q', ['T1 <: lib::Q'],
+ typeParameters: 'T1 extends Object*');
- DartType nullableS1 = S1.withDeclaredNullability(Nullability.nullable);
- _checkConstraintsLower(S1, nonNullableQ, testLib, ['lib::Q <: S1']);
- _checkConstraintsLower(S1, nullableQ, testLib, ['lib::Q? <: S1']);
- _checkConstraintsLower(nullableS1, nonNullableQ, testLib, ['lib::Q <: S1']);
- _checkConstraintsLower(nullableS1, nullableQ, testLib, ['lib::Q <: S1']);
- _checkConstraintsUpper(S1, nonNullableQ, testLib, ['S1 <: lib::Q']);
- _checkConstraintsUpper(S1, nullableQ, testLib, ['S1 <: lib::Q?']);
- _checkConstraintsUpper(nullableS1, nonNullableQ, testLib, null);
- _checkConstraintsUpper(nullableS1, nullableQ, testLib, ['S1 <: lib::Q']);
+ checkConstraintsLower('S1', 'Q', ['lib::Q <: S1'],
+ typeParameters: 'S1 extends Object?');
+ checkConstraintsLower('S1', 'Q?', ['lib::Q? <: S1'],
+ typeParameters: 'S1 extends Object?');
+ checkConstraintsLower('S1?', 'Q', ['lib::Q <: S1'],
+ typeParameters: 'S1 extends Object?');
+ checkConstraintsLower('S1?', 'Q?', ['lib::Q <: S1'],
+ typeParameters: 'S1 extends Object?');
+ checkConstraintsUpper('S1', 'Q', ['S1 <: lib::Q'],
+ typeParameters: 'S1 extends Object?');
+ checkConstraintsUpper('S1', 'Q?', ['S1 <: lib::Q?'],
+ typeParameters: 'S1 extends Object?');
+ checkConstraintsUpper('S1?', 'Q', null,
+ typeParameters: 'S1 extends Object?');
+ checkConstraintsUpper('S1?', 'Q?', ['S1 <: lib::Q'],
+ typeParameters: 'S1 extends Object?');
}
void test_any_subtype_top() {
- _checkConstraintsUpper(P, dynamicType, testLib, []);
- _checkConstraintsUpper(P, coreTypes.objectLegacyRawType, testLib, []);
- _checkConstraintsUpper(P, voidType, testLib, []);
+ parseTestLibrary('class P; class Q;');
+
+ checkConstraintsUpper('P*', 'dynamic', []);
+ checkConstraintsUpper('P*', 'Object*', []);
+ checkConstraintsUpper('P*', 'void', []);
}
void test_any_subtype_unknown() {
- _checkConstraintsUpper(P, unknownType, testLib, []);
- _checkConstraintsUpper(T1, unknownType, testLib, []);
- _checkConstraintsUpper(S1, unknownType, testLib, []);
- _checkConstraintsUpper(R1, unknownType, testLib, []);
+ parseTestLibrary('class P; class Q;');
+
+ checkConstraintsUpper('P*', 'UNKNOWN', []);
+ checkConstraintsUpper('T1*', 'UNKNOWN', [],
+ typeParameters: 'T1 extends Object*');
+ checkConstraintsUpper('S1', 'UNKNOWN', [],
+ typeParameters: 'S1 extends Object?');
+ checkConstraintsUpper('R1', 'UNKNOWN', [],
+ typeParameters: 'R1 extends Object');
}
void test_different_classes() {
- _checkConstraintsUpper(_list(T1), _iterable(Q), testLib, ['T1 <: lib::Q*']);
- _checkConstraintsUpper(_iterable(T1), _list(Q), testLib, null);
- _checkConstraintsUpper(_list(S1), _iterable(Q), testLib, ['S1 <: lib::Q*']);
- _checkConstraintsUpper(_iterable(S1), _list(Q), testLib, null);
- _checkConstraintsUpper(_list(R1), _iterable(Q), testLib, ['R1 <: lib::Q*']);
- _checkConstraintsUpper(_iterable(R1), _list(Q), testLib, null);
+ parseTestLibrary('class P; class Q;');
+
+ checkConstraintsUpper('List<T1*>*', 'Iterable<Q*>*', ['T1 <: lib::Q*'],
+ typeParameters: 'T1 extends Object*');
+ checkConstraintsUpper('Iterable<T1*>*', 'List<Q*>*', null,
+ typeParameters: 'T1 extends Object*');
+ checkConstraintsUpper('List<S1>*', 'Iterable<Q*>*', ['S1 <: lib::Q*'],
+ typeParameters: 'S1 extends Object?');
+ checkConstraintsUpper('Iterable<S1>*', 'List<Q*>*', null,
+ typeParameters: 'S1 extends Object?');
+ checkConstraintsUpper('List<R1>*', 'Iterable<Q*>*', ['R1 <: lib::Q*'],
+ typeParameters: 'R1 extends Object');
+ checkConstraintsUpper('Iterable<R1>*', 'List<Q*>*', null,
+ typeParameters: 'R1 extends Object');
}
void test_equal_types() {
- _checkConstraintsUpper(P, P, testLib, []);
+ parseTestLibrary('class P; class Q;');
+
+ checkConstraintsUpper('P*', 'P*', []);
}
void test_function_generic() {
- var T = new TypeParameterType(
- new TypeParameter('T', coreTypes.objectLegacyRawType),
- Nullability.legacy);
- var U = new TypeParameterType(
- new TypeParameter('U', coreTypes.objectLegacyRawType),
- Nullability.legacy);
+ parseTestLibrary('');
+
// <T>() -> dynamic <: () -> dynamic, never
- _checkConstraintsUpper(
- new FunctionType([], dynamicType, Nullability.legacy,
- typeParameters: [T.parameter]),
- new FunctionType([], dynamicType, Nullability.legacy),
- testLib,
- null);
+ checkConstraintsUpper(
+ '<T extends Object*>() ->* dynamic', '() ->* dynamic', null);
// () -> dynamic <: <T>() -> dynamic, never
- _checkConstraintsUpper(
- new FunctionType([], dynamicType, Nullability.legacy),
- new FunctionType([], dynamicType, Nullability.legacy,
- typeParameters: [T.parameter]),
- testLib,
- null);
+ checkConstraintsUpper(
+ '() ->* dynamic', '<T extends Object*>() ->* dynamic', null);
// <T>(T) -> T <: <U>(U) -> U, always
- _checkConstraintsUpper(
- new FunctionType([T], T, Nullability.legacy,
- typeParameters: [T.parameter]),
- new FunctionType([U], U, Nullability.legacy,
- typeParameters: [U.parameter]),
- testLib,
- []);
+ checkConstraintsUpper(
+ '<T extends Object*>(T*) ->* T*', '<U extends Object*>(U*) ->* U*', []);
}
void test_function_parameter_mismatch() {
+ parseTestLibrary('class P; class Q;');
+
// (P) -> dynamic <: () -> dynamic, never
- _checkConstraintsUpper(
- new FunctionType([P], dynamicType, Nullability.legacy),
- new FunctionType([], dynamicType, Nullability.legacy),
- testLib,
- null);
+ checkConstraintsUpper('(P*) ->* dynamic', '() ->* dynamic', null);
// () -> dynamic <: (P) -> dynamic, never
- _checkConstraintsUpper(
- new FunctionType([], dynamicType, Nullability.legacy),
- new FunctionType([P], dynamicType, Nullability.legacy),
- testLib,
- null);
+ checkConstraintsUpper('() ->* dynamic', '(P*) ->* dynamic', null);
// ([P]) -> dynamic <: () -> dynamic, always
- _checkConstraintsUpper(
- new FunctionType([P], dynamicType, Nullability.legacy,
- requiredParameterCount: 0),
- new FunctionType([], dynamicType, Nullability.legacy),
- testLib,
- []);
+ checkConstraintsUpper('([P*]) ->* dynamic', '() ->* dynamic', []);
// () -> dynamic <: ([P]) -> dynamic, never
- _checkConstraintsUpper(
- new FunctionType([], dynamicType, Nullability.legacy),
- new FunctionType([P], dynamicType, Nullability.legacy,
- requiredParameterCount: 0),
- testLib,
- null);
+ checkConstraintsUpper('() ->* dynamic', '([P*]) ->* dynamic', null);
// ({x: P}) -> dynamic <: () -> dynamic, always
- _checkConstraintsUpper(
- new FunctionType([], dynamicType, Nullability.legacy,
- namedParameters: [new NamedType('x', P)]),
- new FunctionType([], dynamicType, Nullability.legacy),
- testLib,
- []);
+ checkConstraintsUpper('({P* x}) ->* dynamic', '() ->* dynamic', []);
// () -> dynamic !<: ({x: P}) -> dynamic, never
- _checkConstraintsUpper(
- new FunctionType([], dynamicType, Nullability.legacy),
- new FunctionType([], dynamicType, Nullability.legacy,
- namedParameters: [new NamedType('x', P)]),
- testLib,
- null);
+ checkConstraintsUpper('() ->* dynamic', '({P* x}) ->* dynamic', null);
}
void test_function_parameter_types() {
+ parseTestLibrary('class P; class Q;');
+
// (T1) -> dynamic <: (Q) -> dynamic, under constraint Q <: T1
- _checkConstraintsUpper(
- new FunctionType([T1], dynamicType, Nullability.legacy),
- new FunctionType([Q], dynamicType, Nullability.legacy),
- testLib,
- ['lib::Q* <: T1']);
+ checkConstraintsUpper(
+ '(T1*) ->* dynamic', '(Q*) ->* dynamic', ['lib::Q* <: T1'],
+ typeParameters: 'T1 extends Object*');
// ({x: T1}) -> dynamic <: ({x: Q}) -> dynamic, under constraint Q <: T1
- _checkConstraintsUpper(
- new FunctionType([], dynamicType, Nullability.legacy,
- namedParameters: [new NamedType('x', T1)]),
- new FunctionType([], dynamicType, Nullability.legacy,
- namedParameters: [new NamedType('x', Q)]),
- testLib,
- ['lib::Q* <: T1']);
+ checkConstraintsUpper(
+ '({T1* x}) ->* dynamic', '({Q* x}) ->* dynamic', ['lib::Q* <: T1'],
+ typeParameters: 'T1 extends Object*');
// (S1) -> S1? <: (P) -> P?
- _checkConstraintsUpper(
- new FunctionType([S1], S1.withDeclaredNullability(Nullability.nullable),
- Nullability.nonNullable),
- new FunctionType(
- [P.withDeclaredNullability(Nullability.nonNullable)],
- P.withDeclaredNullability(Nullability.nullable),
- Nullability.nonNullable),
- testLib,
- ['lib::P <: S1 <: lib::P']);
+ checkConstraintsUpper(
+ '(S1) -> S1?', '(P) -> P?', ['lib::P <: S1 <: lib::P'],
+ typeParameters: 'S1 extends Object?');
// (S1, List<S1?>) -> void <: (P, List<P?>) -> void
- _checkConstraintsUpper(
- new FunctionType(
- [S1, _list(S1.withDeclaredNullability(Nullability.nullable))],
- voidType,
- Nullability.nonNullable),
- new FunctionType([
- P.withDeclaredNullability(Nullability.nonNullable),
- _list(P.withDeclaredNullability(Nullability.nullable))
- ], voidType, Nullability.nonNullable),
- testLib,
- ['lib::P <: S1']);
+ checkConstraintsUpper(
+ '(S1, List<S1?>*) -> void', '(P, List<P?>*) -> void', ['lib::P <: S1'],
+ typeParameters: 'S1 extends Object?');
}
void test_function_return_type() {
+ parseTestLibrary('class P; class Q;');
+
// () -> T1 <: () -> Q, under constraint T1 <: Q
- _checkConstraintsUpper(
- new FunctionType([], T1, Nullability.legacy),
- new FunctionType([], Q, Nullability.legacy),
- testLib,
- ['T1 <: lib::Q*']);
+ checkConstraintsUpper('() ->* T1', '() ->* Q*', ['T1 <: lib::Q*'],
+ typeParameters: 'T1 extends Object*');
// () -> P <: () -> void, always
- _checkConstraintsUpper(new FunctionType([], P, Nullability.legacy),
- new FunctionType([], voidType, Nullability.legacy), testLib, []);
+ checkConstraintsUpper('() ->* P*', '() ->* void', []);
// () -> void <: () -> P, never
- _checkConstraintsUpper(new FunctionType([], voidType, Nullability.legacy),
- new FunctionType([], P, Nullability.legacy), testLib, null);
+ checkConstraintsUpper('() ->* void', '() ->* P*', null);
}
void test_function_trivial_cases() {
- var F = new FunctionType([], dynamicType, Nullability.legacy);
+ parseTestLibrary('');
+
// () -> dynamic <: dynamic, always
- _checkConstraintsUpper(F, dynamicType, testLib, []);
+ checkConstraintsUpper('() ->* dynamic', 'dynamic', []);
// () -> dynamic <: Function, always
- _checkConstraintsUpper(F, functionType, testLib, []);
+ checkConstraintsUpper('() ->* dynamic', 'Function*', []);
// () -> dynamic <: Object, always
- _checkConstraintsUpper(F, coreTypes.objectLegacyRawType, testLib, []);
+ checkConstraintsUpper('() ->* dynamic', 'Object*', []);
}
void test_nonInferredParameter_subtype_any() {
- var U = new TypeParameterType(
- new TypeParameter('U', _list(P)), Nullability.legacy);
- _checkConstraintsLower(_list(T1), U, testLib, ['lib::P* <: T1']);
+ parseTestLibrary('class P; class Q;');
+
+ checkConstraintsLower('List<T1*>*', 'U*', ['lib::P* <: T1'],
+ typeParameters: 'T1 extends Object*, U extends List<P*>*',
+ typeParametersToConstrain: 'T1');
}
void test_null_subtype_any() {
- _checkConstraintsLower(T1, new NullType(), testLib, ['Null <: T1']);
- _checkConstraintsUpper(new NullType(), Q, testLib, []);
+ parseTestLibrary('class P; class Q;');
+
+ checkConstraintsLower('T1*', 'Null', ['Null <: T1'],
+ typeParameters: 'T1 extends Object*');
+ checkConstraintsUpper('Null', 'Q*', []);
}
void test_parameter_subtype_any() {
- _checkConstraintsUpper(T1, Q, testLib, ['T1 <: lib::Q*']);
- _checkConstraintsLower(T1, Q, testLib, ['lib::Q* <: T1']);
+ parseTestLibrary('class P; class Q;');
- _checkConstraintsUpper(S1, Q, testLib, ['S1 <: lib::Q*']);
- _checkConstraintsLower(S1, Q, testLib, ['lib::Q* <: S1']);
- _checkConstraintsUpper(S1.withDeclaredNullability(Nullability.legacy), Q,
- testLib, ['S1 <: lib::Q*']);
- _checkConstraintsLower(S1.withDeclaredNullability(Nullability.legacy), Q,
- testLib, ['lib::Q <: S1']);
+ checkConstraintsUpper('T1*', 'Q*', ['T1 <: lib::Q*'],
+ typeParameters: 'T1 extends Object*');
+ checkConstraintsLower('T1*', 'Q*', ['lib::Q* <: T1'],
+ typeParameters: 'T1 extends Object*');
- _checkConstraintsUpper(R1, Q, testLib, ['R1 <: lib::Q*']);
- _checkConstraintsLower(R1, Q, testLib, ['lib::Q* <: R1']);
- _checkConstraintsUpper(R1.withDeclaredNullability(Nullability.legacy), Q,
- testLib, ['R1 <: lib::Q*']);
- _checkConstraintsLower(R1.withDeclaredNullability(Nullability.legacy), Q,
- testLib, ['lib::Q <: R1']);
+ checkConstraintsUpper('S1', 'Q*', ['S1 <: lib::Q*'],
+ typeParameters: 'S1 extends Object?');
+ checkConstraintsLower('S1', 'Q*', ['lib::Q* <: S1'],
+ typeParameters: 'S1 extends Object?');
+ checkConstraintsUpper('S1*', 'Q*', ['S1 <: lib::Q*'],
+ typeParameters: 'S1 extends Object?');
+ checkConstraintsLower('S1*', 'Q*', ['lib::Q <: S1'],
+ typeParameters: 'S1 extends Object?');
+
+ checkConstraintsUpper('R1', 'Q*', ['R1 <: lib::Q*'],
+ typeParameters: 'R1 extends Object');
+ checkConstraintsLower('R1', 'Q*', ['lib::Q* <: R1'],
+ typeParameters: 'R1 extends Object');
+ checkConstraintsUpper('R1*', 'Q*', ['R1 <: lib::Q*'],
+ typeParameters: 'R1 extends Object');
+ checkConstraintsLower('R1*', 'Q*', ['lib::Q <: R1'],
+ typeParameters: 'R1 extends Object');
}
void test_same_classes() {
- _checkConstraintsUpper(_list(T1), _list(Q), testLib, ['T1 <: lib::Q*']);
+ parseTestLibrary('class P; class Q;');
+
+ checkConstraintsUpper('List<T1*>*', 'List<Q*>*', ['T1 <: lib::Q*'],
+ typeParameters: 'T1 extends Object*');
}
void test_typeParameters() {
- _checkConstraintsUpper(
- _map(T1, T2), _map(P, Q), testLib, ['T1 <: lib::P*', 'T2 <: lib::Q*']);
- _checkConstraintsLower(
- _map(T1, T2), _map(P, Q), testLib, ['lib::P* <: T1', 'lib::Q* <: T2']);
+ parseTestLibrary('class P; class Q; class Map<X, Y>;');
- _checkConstraintsUpper(
- _map(S1, S2), _map(P, Q), testLib, ['S1 <: lib::P*', 'S2 <: lib::Q*']);
- _checkConstraintsLower(
- _map(S1, S2), _map(P, Q), testLib, ['lib::P* <: S1', 'lib::Q* <: S2']);
- _checkConstraintsUpper(
- _map(S1.withDeclaredNullability(Nullability.legacy),
- S2.withDeclaredNullability(Nullability.legacy)),
- _map(P, Q),
- testLib,
- ['S1 <: lib::P*', 'S2 <: lib::Q*']);
- _checkConstraintsLower(
- _map(S1.withDeclaredNullability(Nullability.legacy),
- S2.withDeclaredNullability(Nullability.legacy)),
- _map(P, Q),
- testLib,
- ['lib::P <: S1', 'lib::Q <: S2']);
+ checkConstraintsUpper(
+ 'Map<T1*, T2*>*', 'Map<P*, Q*>*', ['T1 <: lib::P*', 'T2 <: lib::Q*'],
+ typeParameters: 'T1 extends Object*, T2 extends Object*');
+ checkConstraintsLower(
+ 'Map<T1*, T2*>*', 'Map<P*, Q*>*', ['lib::P* <: T1', 'lib::Q* <: T2'],
+ typeParameters: 'T1 extends Object*, T2 extends Object*');
- _checkConstraintsUpper(
- _map(R1, R2), _map(P, Q), testLib, ['R1 <: lib::P*', 'R2 <: lib::Q*']);
- _checkConstraintsLower(
- _map(R1, R2), _map(P, Q), testLib, ['lib::P* <: R1', 'lib::Q* <: R2']);
- _checkConstraintsUpper(
- _map(R1.withDeclaredNullability(Nullability.legacy),
- R2.withDeclaredNullability(Nullability.legacy)),
- _map(P, Q),
- testLib,
- ['R1 <: lib::P*', 'R2 <: lib::Q*']);
- _checkConstraintsLower(
- _map(R1.withDeclaredNullability(Nullability.legacy),
- R2.withDeclaredNullability(Nullability.legacy)),
- _map(P, Q),
- testLib,
- ['lib::P <: R1', 'lib::Q <: R2']);
+ checkConstraintsUpper(
+ 'Map<S1, S2>*', 'Map<P*, Q*>*', ['S1 <: lib::P*', 'S2 <: lib::Q*'],
+ typeParameters: 'S1 extends Object?, S2 extends Object?');
+ checkConstraintsLower(
+ 'Map<S1, S2>*', 'Map<P*, Q*>*', ['lib::P* <: S1', 'lib::Q* <: S2'],
+ typeParameters: 'S1 extends Object?, S2 extends Object?');
+ checkConstraintsUpper(
+ 'Map<S1*, S2*>*', 'Map<P*, Q*>*', ['S1 <: lib::P*', 'S2 <: lib::Q*'],
+ typeParameters: 'S1 extends Object?, S2 extends Object?');
+ checkConstraintsLower(
+ 'Map<S1*, S2*>*', 'Map<P*, Q*>*', ['lib::P <: S1', 'lib::Q <: S2'],
+ typeParameters: 'S1 extends Object?, S2 extends Object?');
+
+ checkConstraintsUpper(
+ 'Map<R1, R2>*', 'Map<P*, Q*>*', ['R1 <: lib::P*', 'R2 <: lib::Q*'],
+ typeParameters: 'R1 extends Object, R2 extends Object');
+ checkConstraintsLower(
+ 'Map<R1, R2>*', 'Map<P*, Q*>*', ['lib::P* <: R1', 'lib::Q* <: R2'],
+ typeParameters: 'R1 extends Object, R2 extends Object');
+ checkConstraintsUpper(
+ 'Map<R1*, R2*>*', 'Map<P*, Q*>*', ['R1 <: lib::P*', 'R2 <: lib::Q*'],
+ typeParameters: 'R1 extends Object, R2 extends Object');
+ checkConstraintsLower(
+ 'Map<R1*, R2*>*', 'Map<P*, Q*>*', ['lib::P <: R1', 'lib::Q <: R2'],
+ typeParameters: 'R1 extends Object, R2 extends Object');
}
void test_unknown_subtype_any() {
- _checkConstraintsLower(Q, unknownType, testLib, []);
- _checkConstraintsLower(T1, unknownType, testLib, []);
+ parseTestLibrary('class P; class Q;');
+
+ checkConstraintsLower('Q*', 'UNKNOWN', []);
+ checkConstraintsLower('T1*', 'UNKNOWN', [],
+ typeParameters: 'T1 extends Object*');
}
- Class _addClass(Class c) {
- testLib.addClass(c);
- return c;
+ void checkConstraintsLower(String type, String bound, List<String> expected,
+ {String typeParameters, String typeParametersToConstrain}) {
+ env.withTypeParameters(typeParameters ?? '',
+ (List<TypeParameter> typeParameterNodes) {
+ List<TypeParameter> typeParameterNodesToConstrain;
+ if (typeParametersToConstrain != null) {
+ Set<String> namesToConstrain =
+ typeParametersToConstrain.split(",").map((s) => s.trim()).toSet();
+ typeParameterNodesToConstrain = typeParameterNodes
+ .where((p) => namesToConstrain.contains(p.name))
+ .toList();
+ } else {
+ typeParameterNodesToConstrain = typeParameterNodes;
+ }
+ _checkConstraintsLowerTypes(
+ env.parseType(type, additionalTypes: additionalTypes),
+ env.parseType(bound, additionalTypes: additionalTypes),
+ testLibrary,
+ expected,
+ typeParameterNodesToConstrain);
+ });
}
- void _checkConstraintsLower(DartType type, DartType bound,
- Library clientLibrary, List<String> expectedConstraints) {
- _checkConstraintsHelper(type, bound, clientLibrary, expectedConstraints,
- (gatherer, type, bound) => gatherer.tryConstrainLower(type, bound));
+ void _checkConstraintsLowerTypes(
+ DartType type,
+ DartType bound,
+ Library clientLibrary,
+ List<String> expectedConstraints,
+ List<TypeParameter> typeParameterNodesToConstrain) {
+ _checkConstraintsHelper(
+ type,
+ bound,
+ clientLibrary,
+ expectedConstraints,
+ (gatherer, type, bound) => gatherer.tryConstrainLower(type, bound),
+ typeParameterNodesToConstrain);
}
- void _checkConstraintsUpper(DartType type, DartType bound,
- Library clientLibrary, List<String> expectedConstraints) {
- _checkConstraintsHelper(type, bound, clientLibrary, expectedConstraints,
- (gatherer, type, bound) => gatherer.tryConstrainUpper(type, bound));
+ void checkConstraintsUpper(String type, String bound, List<String> expected,
+ {String typeParameters, String typeParametersToConstrain}) {
+ env.withTypeParameters(typeParameters ?? '',
+ (List<TypeParameter> typeParameterNodes) {
+ List<TypeParameter> typeParameterNodesToConstrain;
+ if (typeParametersToConstrain != null) {
+ Set<String> namesToConstrain =
+ typeParametersToConstrain.split(",").map((s) => s.trim()).toSet();
+ typeParameterNodesToConstrain = typeParameterNodes
+ .where((p) => namesToConstrain.contains(p.name))
+ .toList();
+ } else {
+ typeParameterNodesToConstrain = typeParameterNodes;
+ }
+ _checkConstraintsUpperTypes(
+ env.parseType(type, additionalTypes: additionalTypes),
+ env.parseType(bound, additionalTypes: additionalTypes),
+ testLibrary,
+ expected,
+ typeParameterNodesToConstrain);
+ });
+ }
+
+ void _checkConstraintsUpperTypes(
+ DartType type,
+ DartType bound,
+ Library clientLibrary,
+ List<String> expectedConstraints,
+ List<TypeParameter> typeParameterNodesToConstrain) {
+ _checkConstraintsHelper(
+ type,
+ bound,
+ clientLibrary,
+ expectedConstraints,
+ (gatherer, type, bound) => gatherer.tryConstrainUpper(type, bound),
+ typeParameterNodesToConstrain);
}
void _checkConstraintsHelper(
@@ -373,20 +386,12 @@
DartType b,
Library clientLibrary,
List<String> expectedConstraints,
- bool Function(TypeConstraintGatherer, DartType, DartType) tryConstrain) {
+ bool Function(TypeConstraintGatherer, DartType, DartType) tryConstrain,
+ List<TypeParameter> typeParameterNodesToConstrain) {
var typeSchemaEnvironment = new TypeSchemaEnvironment(
coreTypes, new ClassHierarchy(component, coreTypes));
var typeConstraintGatherer = new TypeConstraintGatherer(
- typeSchemaEnvironment,
- [
- T1.parameter,
- T2.parameter,
- S1.parameter,
- S2.parameter,
- R1.parameter,
- R2.parameter
- ],
- testLib);
+ typeSchemaEnvironment, typeParameterNodesToConstrain, testLibrary);
var constraints = tryConstrain(typeConstraintGatherer, a, b)
? typeConstraintGatherer.computeConstraints(clientLibrary)
: null;
@@ -411,24 +416,4 @@
});
expect(constraintStrings, unorderedEquals(expectedConstraints));
}
-
- Class _class(String name,
- {Supertype supertype,
- List<TypeParameter> typeParameters,
- List<Supertype> implementedTypes}) {
- return new Class(
- name: name,
- supertype: supertype ?? objectClass.asThisSupertype,
- typeParameters: typeParameters,
- implementedTypes: implementedTypes);
- }
-
- DartType _iterable(DartType element) =>
- new InterfaceType(iterableClass, Nullability.legacy, [element]);
-
- DartType _list(DartType element) =>
- new InterfaceType(listClass, Nullability.legacy, [element]);
-
- DartType _map(DartType key, DartType value) =>
- new InterfaceType(mapClass, Nullability.legacy, [key, value]);
}
diff --git a/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_test.dart b/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_test.dart
index ebdb227..d690cba 100644
--- a/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_test.dart
@@ -8,7 +8,7 @@
import 'package:kernel/ast.dart';
import 'package:kernel/core_types.dart';
import 'package:kernel/class_hierarchy.dart';
-import 'package:kernel/testing/mock_sdk_component.dart';
+import 'package:kernel/testing/type_parser_environment.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -20,239 +20,273 @@
@reflectiveTest
class TypeConstraintGathererTest {
- static const UnknownType unknownType = const UnknownType();
+ Env env;
- static const DynamicType dynamicType = const DynamicType();
+ final Map<String, DartType Function()> additionalTypes = {
+ 'UNKNOWN': () => UnknownType()
+ };
- static const VoidType voidType = const VoidType();
+ Library _coreLibrary;
- final testLib =
- new Library(Uri.parse('org-dartlang:///test.dart'), name: 'lib');
+ Library _testLibrary;
- Component component;
+ TypeConstraintGathererTest();
- CoreTypes coreTypes;
+ Component get component => env.component;
- TypeParameterType T1;
+ CoreTypes get coreTypes => env.coreTypes;
- TypeParameterType T2;
+ Library get coreLibrary => _coreLibrary;
- Class classP;
+ Library get testLibrary => _testLibrary;
- Class classQ;
-
- TypeConstraintGathererTest() {
- component = createMockSdkComponent();
- component.libraries.add(testLib..parent = component);
- coreTypes = new CoreTypes(component);
- T1 = new TypeParameterType(
- new TypeParameter('T1', objectType), Nullability.legacy);
- T2 = new TypeParameterType(
- new TypeParameter('T2', objectType), Nullability.legacy);
- classP = _addClass(_class('P'));
- classQ = _addClass(_class('Q'));
+ void parseTestLibrary(String testLibraryText) {
+ env = new Env(testLibraryText, isNonNullableByDefault: false);
+ assert(
+ env.component.libraries.length == 2,
+ "The tests are supposed to have exactly two libraries: "
+ "the core library and the test library.");
+ Library firstLibrary = env.component.libraries.first;
+ Library secondLibrary = env.component.libraries.last;
+ if (firstLibrary.importUri.scheme == "dart" &&
+ firstLibrary.importUri.path == "core") {
+ _coreLibrary = firstLibrary;
+ _testLibrary = secondLibrary;
+ } else {
+ assert(
+ secondLibrary.importUri.scheme == "dart" &&
+ secondLibrary.importUri.path == "core",
+ "One of the libraries is expected to be 'dart:core'.");
+ _coreLibrary == secondLibrary;
+ _testLibrary = firstLibrary;
+ }
}
- Class get functionClass => coreTypes.functionClass;
-
- InterfaceType get functionType => coreTypes.functionLegacyRawType;
-
- Class get iterableClass => coreTypes.iterableClass;
-
- Class get listClass => coreTypes.listClass;
-
- Class get mapClass => coreTypes.mapClass;
-
- Class get objectClass => coreTypes.objectClass;
-
- InterfaceType get objectType => coreTypes.objectLegacyRawType;
-
- InterfaceType get P => coreTypes.legacyRawType(classP);
-
- InterfaceType get Q => coreTypes.legacyRawType(classQ);
-
void test_any_subtype_parameter() {
- _checkConstraintsLower(T1, Q, testLib, ['lib::Q* <: T1']);
+ parseTestLibrary('class P; class Q;');
+
+ checkConstraintsLower('T1*', 'Q*', ['lib::Q* <: T1'],
+ typeParameters: 'T1 extends Object*');
}
void test_any_subtype_top() {
- _checkConstraintsUpper(P, dynamicType, testLib, []);
- _checkConstraintsUpper(P, objectType, testLib, []);
- _checkConstraintsUpper(P, voidType, testLib, []);
+ parseTestLibrary('class P; class Q;');
+
+ checkConstraintsUpper('P*', 'dynamic', []);
+ checkConstraintsUpper('P*', 'Object*', []);
+ checkConstraintsUpper('P*', 'void', []);
}
void test_any_subtype_unknown() {
- _checkConstraintsUpper(P, unknownType, testLib, []);
- _checkConstraintsUpper(T1, unknownType, testLib, []);
+ parseTestLibrary('class P; class Q;');
+
+ checkConstraintsUpper('P*', 'UNKNOWN', []);
+ checkConstraintsUpper('T1*', 'UNKNOWN', [],
+ typeParameters: 'T1 extends Object*');
}
void test_different_classes() {
- _checkConstraintsUpper(_list(T1), _iterable(Q), testLib, ['T1 <: lib::Q*']);
- _checkConstraintsUpper(_iterable(T1), _list(Q), testLib, null);
+ parseTestLibrary('class P; class Q;');
+
+ checkConstraintsUpper('List<T1*>*', 'Iterable<Q*>*', ['T1 <: lib::Q*'],
+ typeParameters: 'T1 extends Object*');
+ checkConstraintsUpper('Iterable<T1*>*', 'List<Q*>*', null,
+ typeParameters: 'T1 extends Object*');
}
void test_equal_types() {
- _checkConstraintsUpper(P, P, testLib, []);
+ parseTestLibrary('class P; class Q;');
+
+ checkConstraintsUpper('P*', 'P*', []);
}
void test_function_generic() {
- var T = new TypeParameterType(
- new TypeParameter('T', objectType), Nullability.legacy);
- var U = new TypeParameterType(
- new TypeParameter('U', objectType), Nullability.legacy);
+ parseTestLibrary('');
+
// <T>() -> dynamic <: () -> dynamic, never
- _checkConstraintsUpper(
- new FunctionType([], dynamicType, Nullability.legacy,
- typeParameters: [T.parameter]),
- new FunctionType([], dynamicType, Nullability.legacy),
- testLib,
- null);
+ checkConstraintsUpper(
+ '<T extends Object*>() ->* dynamic', '() ->* dynamic', null);
// () -> dynamic <: <T>() -> dynamic, never
- _checkConstraintsUpper(
- new FunctionType([], dynamicType, Nullability.legacy),
- new FunctionType([], dynamicType, Nullability.legacy,
- typeParameters: [T.parameter]),
- testLib,
- null);
+ checkConstraintsUpper(
+ '() ->* dynamic', '<T extends Object*>() ->* dynamic', null);
// <T>(T) -> T <: <U>(U) -> U, always
- _checkConstraintsUpper(
- new FunctionType([T], T, Nullability.legacy,
- typeParameters: [T.parameter]),
- new FunctionType([U], U, Nullability.legacy,
- typeParameters: [U.parameter]),
- testLib,
- []);
+ checkConstraintsUpper(
+ '<T extends Object*>(T*) ->* T*', '<U extends Object*>(U*) ->* U*', []);
}
void test_function_parameter_mismatch() {
+ parseTestLibrary('class P; class Q;');
+
// (P) -> dynamic <: () -> dynamic, never
- _checkConstraintsUpper(
- new FunctionType([P], dynamicType, Nullability.legacy),
- new FunctionType([], dynamicType, Nullability.legacy),
- testLib,
- null);
+ checkConstraintsUpper('(P*) ->* dynamic', '() ->* dynamic', null);
// () -> dynamic <: (P) -> dynamic, never
- _checkConstraintsUpper(
- new FunctionType([], dynamicType, Nullability.legacy),
- new FunctionType([P], dynamicType, Nullability.legacy),
- testLib,
- null);
+ checkConstraintsUpper('() ->* dynamic', '(P*) ->* dynamic', null);
// ([P]) -> dynamic <: () -> dynamic, always
- _checkConstraintsUpper(
- new FunctionType([P], dynamicType, Nullability.legacy,
- requiredParameterCount: 0),
- new FunctionType([], dynamicType, Nullability.legacy),
- testLib,
- []);
+ checkConstraintsUpper('([P*]) ->* dynamic', '() ->* dynamic', []);
// () -> dynamic <: ([P]) -> dynamic, never
- _checkConstraintsUpper(
- new FunctionType([], dynamicType, Nullability.legacy),
- new FunctionType([P], dynamicType, Nullability.legacy,
- requiredParameterCount: 0),
- testLib,
- null);
+ checkConstraintsUpper('() ->* dynamic', '([P*]) ->* dynamic', null);
// ({x: P}) -> dynamic <: () -> dynamic, always
- _checkConstraintsUpper(
- new FunctionType([], dynamicType, Nullability.legacy,
- namedParameters: [new NamedType('x', P)]),
- new FunctionType([], dynamicType, Nullability.legacy),
- testLib,
- []);
+ checkConstraintsUpper('({P* x}) ->* dynamic', '() ->* dynamic', []);
// () -> dynamic !<: ({x: P}) -> dynamic, never
- _checkConstraintsUpper(
- new FunctionType([], dynamicType, Nullability.legacy),
- new FunctionType([], dynamicType, Nullability.legacy,
- namedParameters: [new NamedType('x', P)]),
- testLib,
- null);
+ checkConstraintsUpper('() ->* dynamic', '({P* x}) ->* dynamic', null);
}
void test_function_parameter_types() {
+ parseTestLibrary('class P; class Q;');
+
// (T1) -> dynamic <: (Q) -> dynamic, under constraint Q <: T1
- _checkConstraintsUpper(
- new FunctionType([T1], dynamicType, Nullability.legacy),
- new FunctionType([Q], dynamicType, Nullability.legacy),
- testLib,
- ['lib::Q* <: T1']);
+ checkConstraintsUpper(
+ '(T1*) ->* dynamic', '(Q*) ->* dynamic', ['lib::Q* <: T1'],
+ typeParameters: 'T1 extends Object*');
// ({x: T1}) -> dynamic <: ({x: Q}) -> dynamic, under constraint Q <: T1
- _checkConstraintsUpper(
- new FunctionType([], dynamicType, Nullability.legacy,
- namedParameters: [new NamedType('x', T1)]),
- new FunctionType([], dynamicType, Nullability.legacy,
- namedParameters: [new NamedType('x', Q)]),
- testLib,
- ['lib::Q* <: T1']);
+ checkConstraintsUpper(
+ '({T1* x}) ->* dynamic', '({Q* x}) ->* dynamic', ['lib::Q* <: T1'],
+ typeParameters: 'T1 extends Object*');
}
void test_function_return_type() {
+ parseTestLibrary('class P; class Q;');
+
// () -> T1 <: () -> Q, under constraint T1 <: Q
- _checkConstraintsUpper(
- new FunctionType([], T1, Nullability.legacy),
- new FunctionType([], Q, Nullability.legacy),
- testLib,
- ['T1 <: lib::Q*']);
+ checkConstraintsUpper('() ->* T1*', '() ->* Q*', ['T1 <: lib::Q*'],
+ typeParameters: 'T1 extends Object*');
// () -> P <: () -> void, always
- _checkConstraintsUpper(new FunctionType([], P, Nullability.legacy),
- new FunctionType([], voidType, Nullability.legacy), testLib, []);
+ checkConstraintsUpper('() ->* P*', '() ->* void', []);
// () -> void <: () -> P, never
- _checkConstraintsUpper(new FunctionType([], voidType, Nullability.legacy),
- new FunctionType([], P, Nullability.legacy), testLib, null);
+ checkConstraintsUpper('() ->* void', '() ->* P*', null);
}
void test_function_trivial_cases() {
- var F = new FunctionType([], dynamicType, Nullability.legacy);
+ parseTestLibrary('');
+
// () -> dynamic <: dynamic, always
- _checkConstraintsUpper(F, dynamicType, testLib, []);
+ checkConstraintsUpper('() ->* dynamic', 'dynamic', []);
// () -> dynamic <: Function, always
- _checkConstraintsUpper(F, functionType, testLib, []);
+ checkConstraintsUpper('() ->* dynamic', "Function*", []);
// () -> dynamic <: Object, always
- _checkConstraintsUpper(F, objectType, testLib, []);
+ checkConstraintsUpper('() ->* dynamic', 'Object*', []);
}
void test_nonInferredParameter_subtype_any() {
- var U = new TypeParameterType(
- new TypeParameter('U', _list(P)), Nullability.legacy);
- _checkConstraintsLower(_list(T1), U, testLib, ['lib::P* <: T1']);
+ parseTestLibrary('class P; class Q;');
+
+ checkConstraintsLower('List<T1*>*', 'U*', ['lib::P* <: T1'],
+ typeParameters: 'T1 extends Object*, U extends List<P*>*',
+ typeParametersToConstrain: 'T1');
}
void test_null_subtype_any() {
- _checkConstraintsLower(T1, new NullType(), testLib, ['Null <: T1']);
- _checkConstraintsUpper(new NullType(), Q, testLib, []);
+ parseTestLibrary('class P; class Q;');
+
+ checkConstraintsLower('T1*', 'Null', ['Null <: T1'],
+ typeParameters: 'T1 extends Object*');
+ checkConstraintsUpper('Null', 'Q*', []);
}
void test_parameter_subtype_any() {
- _checkConstraintsUpper(T1, Q, testLib, ['T1 <: lib::Q*']);
+ parseTestLibrary('class P; class Q;');
+
+ checkConstraintsUpper('T1*', 'Q*', ['T1 <: lib::Q*'],
+ typeParameters: 'T1 extends Object*');
}
void test_same_classes() {
- _checkConstraintsUpper(_list(T1), _list(Q), testLib, ['T1 <: lib::Q*']);
+ parseTestLibrary('class P; class Q;');
+
+ checkConstraintsUpper('List<T1*>*', 'List<Q*>*', ['T1 <: lib::Q*'],
+ typeParameters: 'T1 extends Object*');
}
void test_typeParameters() {
- _checkConstraintsUpper(
- _map(T1, T2), _map(P, Q), testLib, ['T1 <: lib::P*', 'T2 <: lib::Q*']);
+ parseTestLibrary('class P; class Q; class Map<X, Y>;');
+
+ checkConstraintsUpper(
+ 'Map<T1*, T2*>*', 'Map<P*, Q*>*', ['T1 <: lib::P*', 'T2 <: lib::Q*'],
+ typeParameters: 'T1 extends Object*, T2 extends Object*');
}
void test_unknown_subtype_any() {
- _checkConstraintsUpper(Q, unknownType, testLib, []);
- _checkConstraintsUpper(T1, unknownType, testLib, []);
+ parseTestLibrary('class P; class Q;');
+
+ checkConstraintsUpper('Q*', 'UNKNOWN', []);
+ checkConstraintsUpper('T1*', 'UNKNOWN', [],
+ typeParameters: 'T1 extends Object*');
}
- Class _addClass(Class c) {
- testLib.addClass(c);
- return c;
+ void checkConstraintsLower(String type, String bound, List<String> expected,
+ {String typeParameters, String typeParametersToConstrain}) {
+ env.withTypeParameters(typeParameters ?? '',
+ (List<TypeParameter> typeParameterNodes) {
+ List<TypeParameter> typeParameterNodesToConstrain;
+ if (typeParametersToConstrain != null) {
+ Set<String> namesToConstrain =
+ typeParametersToConstrain.split(",").map((s) => s.trim()).toSet();
+ typeParameterNodesToConstrain = typeParameterNodes
+ .where((p) => namesToConstrain.contains(p.name))
+ .toList();
+ } else {
+ typeParameterNodesToConstrain = typeParameterNodes;
+ }
+ _checkConstraintsLowerTypes(
+ env.parseType(type, additionalTypes: additionalTypes),
+ env.parseType(bound, additionalTypes: additionalTypes),
+ testLibrary,
+ expected,
+ typeParameterNodesToConstrain);
+ });
}
- void _checkConstraintsLower(DartType type, DartType bound,
- Library clientLibrary, List<String> expectedConstraints) {
- _checkConstraintsHelper(type, bound, clientLibrary, expectedConstraints,
- (gatherer, type, bound) => gatherer.tryConstrainLower(type, bound));
+ void _checkConstraintsLowerTypes(
+ DartType type,
+ DartType bound,
+ Library clientLibrary,
+ List<String> expectedConstraints,
+ List<TypeParameter> typeParameterNodesToConstrain) {
+ _checkConstraintsHelper(
+ type,
+ bound,
+ clientLibrary,
+ expectedConstraints,
+ (gatherer, type, bound) => gatherer.tryConstrainLower(type, bound),
+ typeParameterNodesToConstrain);
}
- void _checkConstraintsUpper(DartType type, DartType bound,
- Library clientLibrary, List<String> expectedConstraints) {
- _checkConstraintsHelper(type, bound, clientLibrary, expectedConstraints,
- (gatherer, type, bound) => gatherer.tryConstrainUpper(type, bound));
+ void checkConstraintsUpper(String type, String bound, List<String> expected,
+ {String typeParameters, String typeParametersToConstrain}) {
+ env.withTypeParameters(typeParameters ?? '',
+ (List<TypeParameter> typeParameterNodes) {
+ List<TypeParameter> typeParameterNodesToConstrain;
+ if (typeParametersToConstrain != null) {
+ Set<String> namesToConstrain =
+ typeParametersToConstrain.split(",").map((s) => s.trim()).toSet();
+ typeParameterNodesToConstrain = typeParameterNodes
+ .where((p) => namesToConstrain.contains(p.name))
+ .toList();
+ } else {
+ typeParameterNodesToConstrain = typeParameterNodes;
+ }
+ _checkConstraintsUpperTypes(
+ env.parseType(type, additionalTypes: additionalTypes),
+ env.parseType(bound, additionalTypes: additionalTypes),
+ testLibrary,
+ expected,
+ typeParameterNodesToConstrain);
+ });
+ }
+
+ void _checkConstraintsUpperTypes(
+ DartType type,
+ DartType bound,
+ Library clientLibrary,
+ List<String> expectedConstraints,
+ List<TypeParameter> typeParameterNodesToConstrain) {
+ _checkConstraintsHelper(
+ type,
+ bound,
+ clientLibrary,
+ expectedConstraints,
+ (gatherer, type, bound) => gatherer.tryConstrainUpper(type, bound),
+ typeParameterNodesToConstrain);
}
void _checkConstraintsHelper(
@@ -260,11 +294,12 @@
DartType b,
Library clientLibrary,
List<String> expectedConstraints,
- bool Function(TypeConstraintGatherer, DartType, DartType) tryConstrain) {
+ bool Function(TypeConstraintGatherer, DartType, DartType) tryConstrain,
+ List<TypeParameter> typeParameterNodesToConstrain) {
var typeSchemaEnvironment = new TypeSchemaEnvironment(
coreTypes, new ClassHierarchy(component, coreTypes));
var typeConstraintGatherer = new TypeConstraintGatherer(
- typeSchemaEnvironment, [T1.parameter, T2.parameter], testLib);
+ typeSchemaEnvironment, typeParameterNodesToConstrain, testLibrary);
var constraints = tryConstrain(typeConstraintGatherer, a, b)
? typeConstraintGatherer.computeConstraints(clientLibrary)
: null;
@@ -289,24 +324,4 @@
});
expect(constraintStrings, unorderedEquals(expectedConstraints));
}
-
- Class _class(String name,
- {Supertype supertype,
- List<TypeParameter> typeParameters,
- List<Supertype> implementedTypes}) {
- return new Class(
- name: name,
- supertype: supertype ?? objectClass.asThisSupertype,
- typeParameters: typeParameters,
- implementedTypes: implementedTypes);
- }
-
- DartType _iterable(DartType element) =>
- new InterfaceType(iterableClass, Nullability.legacy, [element]);
-
- DartType _list(DartType element) =>
- new InterfaceType(listClass, Nullability.legacy, [element]);
-
- DartType _map(DartType key, DartType value) =>
- new InterfaceType(mapClass, Nullability.legacy, [key, value]);
}
diff --git a/pkg/front_end/test/fasta/type_inference/type_schema_elimination_nnbd_test.dart b/pkg/front_end/test/fasta/type_inference/type_schema_elimination_nnbd_test.dart
index d32c54a..aa491cc 100644
--- a/pkg/front_end/test/fasta/type_inference/type_schema_elimination_nnbd_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_schema_elimination_nnbd_test.dart
@@ -18,7 +18,7 @@
@reflectiveTest
class TypeSchemaEliminationTest {
- final Env env = new Env("");
+ final Env env = new Env("", isNonNullableByDefault: true);
final Map<String, DartType Function()> additionalTypes = {
"UNKNOWN": () => new UnknownType()
};
diff --git a/pkg/front_end/test/fasta/type_inference/type_schema_elimination_test.dart b/pkg/front_end/test/fasta/type_inference/type_schema_elimination_test.dart
index dd4a329..3d30f92 100644
--- a/pkg/front_end/test/fasta/type_inference/type_schema_elimination_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_schema_elimination_test.dart
@@ -18,7 +18,7 @@
@reflectiveTest
class TypeSchemaEliminationTest {
- final Env env = new Env("");
+ final Env env = new Env("", isNonNullableByDefault: false);
final Map<String, DartType Function()> additionalTypes = {
"UNKNOWN": () => new UnknownType()
};
diff --git a/pkg/front_end/test/fasta/types/fasta_legacy_upper_bound_test.dart b/pkg/front_end/test/fasta/types/fasta_legacy_upper_bound_test.dart
index cf9cfa5..b1ac139 100644
--- a/pkg/front_end/test/fasta/types/fasta_legacy_upper_bound_test.dart
+++ b/pkg/front_end/test/fasta/types/fasta_legacy_upper_bound_test.dart
@@ -36,6 +36,9 @@
FastaLegacyUpperBoundTest(this.ticker, this.context);
@override
+ bool get isNonNullableByDefault => false;
+
+ @override
Future<void> parseComponent(String source) async {
await super.parseComponent(source);
diff --git a/pkg/front_end/test/fasta/types/kernel_legacy_upper_bound_test.dart b/pkg/front_end/test/fasta/types/kernel_legacy_upper_bound_test.dart
index 0409fcb..e353327 100644
--- a/pkg/front_end/test/fasta/types/kernel_legacy_upper_bound_test.dart
+++ b/pkg/front_end/test/fasta/types/kernel_legacy_upper_bound_test.dart
@@ -12,6 +12,9 @@
ClassHierarchy hierarchy;
@override
+ bool get isNonNullableByDefault => true;
+
+ @override
Future<void> parseComponent(String source) {
super.parseComponent(source);
hierarchy = new ClassHierarchy(env.component, env.coreTypes);
diff --git a/pkg/front_end/test/fasta/types/legacy_upper_bound_helper.dart b/pkg/front_end/test/fasta/types/legacy_upper_bound_helper.dart
index f55fe0a..5a50c9e 100644
--- a/pkg/front_end/test/fasta/types/legacy_upper_bound_helper.dart
+++ b/pkg/front_end/test/fasta/types/legacy_upper_bound_helper.dart
@@ -17,8 +17,11 @@
Library coreLibrary;
Library testLibrary;
+ bool get isNonNullableByDefault;
+
void parseComponent(String source) {
- env = new parser.Env(source);
+ env =
+ new parser.Env(source, isNonNullableByDefault: isNonNullableByDefault);
assert(
env.component.libraries.length == 2,
"The test component is expected to have exactly two libraries: "
@@ -30,6 +33,10 @@
coreLibrary = firstLibrary;
testLibrary = secondLibrary;
} else {
+ assert(
+ secondLibrary.importUri.scheme == "dart" &&
+ secondLibrary.importUri.path == "core",
+ "One of the libraries is expected to be 'dart:core'.");
coreLibrary = secondLibrary;
testLibrary = firstLibrary;
}
diff --git a/pkg/js/analysis_options.yaml b/pkg/js/analysis_options.yaml
index 9951703..afaa4eb 100644
--- a/pkg/js/analysis_options.yaml
+++ b/pkg/js/analysis_options.yaml
@@ -3,8 +3,6 @@
analyzer:
strong-mode:
implicit-casts: false
- enable-experiment:
- - non-nullable
linter:
rules:
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index 70dd2ef..ced3c9e 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -2629,7 +2629,7 @@
@override
Supertype readSupertype() {
final int nodeOffset = _byteOffset;
- InterfaceType type = super.readDartType();
+ InterfaceType type = super.readDartType(forSupertype: true);
return _associateMetadata(
new Supertype.byReference(type.className, type.typeArguments),
nodeOffset);
diff --git a/pkg/kernel/lib/testing/type_parser_environment.dart b/pkg/kernel/lib/testing/type_parser_environment.dart
index 757ee7a..7388412 100644
--- a/pkg/kernel/lib/testing/type_parser_environment.dart
+++ b/pkg/kernel/lib/testing/type_parser_environment.dart
@@ -98,17 +98,22 @@
TypeParserEnvironment _libraryEnvironment;
- Env(String source) {
+ final bool isNonNullableByDefault;
+
+ Env(String source, {this.isNonNullableByDefault}) {
+ assert(isNonNullableByDefault != null);
Uri libraryUri = Uri.parse('memory:main.dart');
Uri coreUri = Uri.parse("dart:core");
TypeParserEnvironment coreEnvironment =
new TypeParserEnvironment(coreUri, coreUri);
Library coreLibrary =
- parseLibrary(coreUri, mockSdk, environment: coreEnvironment);
+ parseLibrary(coreUri, mockSdk, environment: coreEnvironment)
+ ..isNonNullableByDefault = isNonNullableByDefault;
_libraryEnvironment = new TypeParserEnvironment(libraryUri, libraryUri)
._extend(coreEnvironment._declarations);
Library library =
- parseLibrary(libraryUri, source, environment: _libraryEnvironment);
+ parseLibrary(libraryUri, source, environment: _libraryEnvironment)
+ ..isNonNullableByDefault = isNonNullableByDefault;
library.name = "lib";
component = new Component(libraries: <Library>[coreLibrary, library]);
coreTypes = new CoreTypes(component);
@@ -120,16 +125,27 @@
additionalTypes: additionalTypes);
}
- void extendWithTypeParameters(String typeParameters) {
- _libraryEnvironment =
- _libraryEnvironment.extendWithTypeParameters(typeParameters);
+ List<TypeParameter> extendWithTypeParameters(String typeParameters) {
+ if (typeParameters == null || typeParameters.isEmpty) {
+ return <TypeParameter>[];
+ }
+ ParameterEnvironment parameterEnvironment =
+ _libraryEnvironment.extendToParameterEnvironment(typeParameters);
+ _libraryEnvironment = parameterEnvironment.environment;
+ return parameterEnvironment.parameters;
}
- void withTypeParameters(String typeParameters, void Function() f) {
- TypeParserEnvironment oldLibraryEnvironment = _libraryEnvironment;
- extendWithTypeParameters(typeParameters);
- f();
- _libraryEnvironment = oldLibraryEnvironment;
+ void withTypeParameters(
+ String typeParameters, void Function(List<TypeParameter>) f) {
+ if (typeParameters == null || typeParameters.isEmpty) {
+ f(<TypeParameter>[]);
+ } else {
+ TypeParserEnvironment oldLibraryEnvironment = _libraryEnvironment;
+ List<TypeParameter> typeParameterNodes =
+ extendWithTypeParameters(typeParameters);
+ f(typeParameterNodes);
+ _libraryEnvironment = oldLibraryEnvironment;
+ }
}
}
@@ -197,10 +213,13 @@
TypeParserEnvironment extendWithTypeParameters(String typeParameters) {
if (typeParameters?.isEmpty ?? true) return this;
- return const _KernelFromParsedType()
- .computeTypeParameterEnvironment(
- parseTypeVariables("<${typeParameters}>"), this)
- .environment;
+ return extendToParameterEnvironment(typeParameters).environment;
+ }
+
+ ParameterEnvironment extendToParameterEnvironment(String typeParameters) {
+ assert(typeParameters != null && typeParameters.isNotEmpty);
+ return const _KernelFromParsedType().computeTypeParameterEnvironment(
+ parseTypeVariables("<${typeParameters}>"), this);
}
/// Returns the predefined type by the [name], if any.
diff --git a/pkg/kernel/test/dart_type_equivalence_test.dart b/pkg/kernel/test/dart_type_equivalence_test.dart
index 4f27768..462c637 100644
--- a/pkg/kernel/test/dart_type_equivalence_test.dart
+++ b/pkg/kernel/test/dart_type_equivalence_test.dart
@@ -169,8 +169,9 @@
bool equateTopTypes = false,
bool ignoreAllNullabilities = false,
bool ignoreTopLevelNullability = false}) {
- Env env = new Env("typedef Typedef<T> () -> T;\n")
- ..extendWithTypeParameters(typeParameters);
+ Env env =
+ new Env("typedef Typedef<T> () -> T;\n", isNonNullableByDefault: true)
+ ..extendWithTypeParameters(typeParameters);
DartType t1 = env.parseType(type1);
DartType t2 = env.parseType(type2);
@@ -208,8 +209,9 @@
bool equateTopTypes = false,
bool ignoreAllNullabilities = false,
bool ignoreTopLevelNullability = false}) {
- Env env = new Env("typedef Typedef<T> () -> T;\n")
- ..extendWithTypeParameters(typeParameters);
+ Env env =
+ new Env("typedef Typedef<T> () -> T;\n", isNonNullableByDefault: true)
+ ..extendWithTypeParameters(typeParameters);
DartType t1 = env.parseType(type1);
DartType t2 = env.parseType(type2);
diff --git a/pkg/kernel/test/flatten_test.dart b/pkg/kernel/test/flatten_test.dart
index ab6c1ee..6983445 100644
--- a/pkg/kernel/test/flatten_test.dart
+++ b/pkg/kernel/test/flatten_test.dart
@@ -66,13 +66,14 @@
}
main() {
- Env env = new Env('');
+ Env env = new Env('', isNonNullableByDefault: true);
ClassHierarchy classHierarchy =
new ClassHierarchy(env.component, env.coreTypes);
TypeEnvironment typeEnvironment =
new TypeEnvironment(env.coreTypes, classHierarchy);
data.forEach((Test test) {
- env.withTypeParameters(test.typeParameters, () {
+ env.withTypeParameters(test.typeParameters,
+ (List<TypeParameter> typeParameterNodes) {
String input = test.input;
String output = test.output;
DartType inputType = env.parseType(input);
diff --git a/pkg/kernel/test/future_value_type_test.dart b/pkg/kernel/test/future_value_type_test.dart
index 5c0f032..8a7bfac 100644
--- a/pkg/kernel/test/future_value_type_test.dart
+++ b/pkg/kernel/test/future_value_type_test.dart
@@ -68,7 +68,7 @@
};
main() {
- Env env = new Env('')
+ Env env = new Env('', isNonNullableByDefault: true)
..extendWithTypeParameters('X,'
'X_extends_FutureInt extends Future<int>,'
'X_extends_FutureOrInt extends FutureOr<int>');
diff --git a/pkg/kernel/test/legacy_erasure_test.dart b/pkg/kernel/test/legacy_erasure_test.dart
index 4757d00..4f82dea 100644
--- a/pkg/kernel/test/legacy_erasure_test.dart
+++ b/pkg/kernel/test/legacy_erasure_test.dart
@@ -54,7 +54,7 @@
};
main() {
- Env env = new Env('');
+ Env env = new Env('', isNonNullableByDefault: true);
data.forEach((String input, String output) {
DartType inputType = env.parseType(input);
DartType expectedOutputType = env.parseType(output);
diff --git a/pkg/kernel/test/nnbd_top_merge_test.dart b/pkg/kernel/test/nnbd_top_merge_test.dart
index 4eb5d40..bd82a7e 100644
--- a/pkg/kernel/test/nnbd_top_merge_test.dart
+++ b/pkg/kernel/test/nnbd_top_merge_test.dart
@@ -111,7 +111,7 @@
};
main() {
- Env env = new Env('');
+ Env env = new Env('', isNonNullableByDefault: true);
data.forEach((String input, dynamic output) {
List<String> parts = input.split(' vs ');
DartType aType = env.parseType(parts[0]);
diff --git a/pkg/kernel/test/non_null_test.dart b/pkg/kernel/test/non_null_test.dart
index 542cc09..d9a04aa 100644
--- a/pkg/kernel/test/non_null_test.dart
+++ b/pkg/kernel/test/non_null_test.dart
@@ -78,7 +78,7 @@
};
main() {
- Env env = new Env('')
+ Env env = new Env('', isNonNullableByDefault: true)
..extendWithTypeParameters('X,'
'X_extends_Object extends Object,'
'X_extends_dynamic extends dynamic,'
diff --git a/pkg/kernel/test/norm_test.dart b/pkg/kernel/test/norm_test.dart
index b8a5f3e..c287025 100644
--- a/pkg/kernel/test/norm_test.dart
+++ b/pkg/kernel/test/norm_test.dart
@@ -143,7 +143,8 @@
}
check(String input, String output, [String typeParameters = '']) {
- Env env = new Env('')..extendWithTypeParameters(typeParameters);
+ Env env = new Env('', isNonNullableByDefault: true)
+ ..extendWithTypeParameters(typeParameters);
DartType inputType = env.parseType(input);
DartType expectedOutputType = env.parseType(output);
DartType actualOutputType = norm(env.coreTypes, inputType);
diff --git a/pkg/nnbd_migration/lib/migration_cli.dart b/pkg/nnbd_migration/lib/migration_cli.dart
index 8833c58..3ded01d 100644
--- a/pkg/nnbd_migration/lib/migration_cli.dart
+++ b/pkg/nnbd_migration/lib/migration_cli.dart
@@ -807,11 +807,6 @@
}
}
- void _fatalErrorReported(String detail) {
- logger.stderr(detail);
- throw MigrationExit(1);
- }
-
void _exceptionReported(String detail) {
if (_hasExceptions) return;
_hasExceptions = true;
@@ -849,6 +844,11 @@
}
}
+ void _fatalErrorReported(String detail) {
+ logger.stderr(detail);
+ throw MigrationExit(1);
+ }
+
void _logErrors(AnalysisResult analysisResult) {
logger.stdout('');
@@ -861,35 +861,41 @@
for (AnalysisError error in analysisResult.errors) {
renderer.render(error);
}
-
logger.stdout('');
- logger.stdout('Note: analysis errors will result in erroneous migration '
- 'suggestions.');
-
_hasAnalysisErrors = true;
+
if (options.ignoreErrors) {
+ logger.stdout('Note: analysis errors will result in erroneous migration '
+ 'suggestions.');
logger.stdout('Continuing with migration suggestions due to the use of '
'--${CommandLineOptions.ignoreErrorsFlag}.');
} else {
// Fail with how to continue.
+ logger.stdout("The migration tool didn't start, due to analysis errors.");
logger.stdout('');
if (analysisResult.hasImportErrors) {
- logger
- .stdout('Unresolved URIs found. Did you forget to run "pub get"?');
- logger.stdout('');
- }
- if (analysisResult.allSourcesAlreadyMigrated) {
logger.stdout('''
-All files appear to have null safety already enabled. Did you update the
-language version prior to running "dart migrate"? If so, you need to un-do this
-(and re-run "pub get") prior to performing the migration.
+The following steps might fix your problem:
+1. Run `dart pub get`.
+2. Try running `dart migrate` again.
''');
- logger.stdout('');
+ } else if (analysisResult.allSourcesAlreadyMigrated) {
+ logger.stdout('''
+The following steps might fix your problem:
+1. Set the lower SDK constraint (in pubspec.yaml) to a version before 2.12.
+2. Run `dart pub get`.
+3. Try running `dart migrate` again.
+''');
+ } else {
+ const ignoreErrors = CommandLineOptions.ignoreErrorsFlag;
+ logger.stdout('''
+We recommend fixing the analysis issues before running `dart migrate`.
+Alternatively, you can run `dart migrate --$ignoreErrors`, but you might
+get erroneous migration suggestions.
+''');
}
logger.stdout(
- 'Please fix the analysis issues (or, force generation of migration '
- 'suggestions by re-running with '
- '--${CommandLineOptions.ignoreErrorsFlag}).');
+ 'More information: https://dart.dev/go/null-safety-migration');
}
}
diff --git a/pkg/nnbd_migration/lib/nnbd_migration.dart b/pkg/nnbd_migration/lib/nnbd_migration.dart
index 36027a0..af33d0d 100644
--- a/pkg/nnbd_migration/lib/nnbd_migration.dart
+++ b/pkg/nnbd_migration/lib/nnbd_migration.dart
@@ -330,15 +330,15 @@
/// Check if this migration is being run permissively.
bool get isPermissive;
- void finalizeInput(ResolvedUnitResult result);
-
- void finish();
-
/// Use this getter after any calls to [prepareInput] to obtain a list of URIs
/// of unmigrated dependencies. Ideally, this list should be empty before the
/// user tries to migrate their package.
List<String> get unmigratedDependencies;
+ void finalizeInput(ResolvedUnitResult result);
+
+ void finish();
+
void prepareInput(ResolvedUnitResult result);
void processInput(ResolvedUnitResult result);
diff --git a/pkg/nnbd_migration/test/migration_cli_test.dart b/pkg/nnbd_migration/test/migration_cli_test.dart
index 35957ce..ce9eb5f 100644
--- a/pkg/nnbd_migration/test/migration_cli_test.dart
+++ b/pkg/nnbd_migration/test/migration_cli_test.dart
@@ -745,15 +745,9 @@
output,
contains("error • Expected to find ';' at lib${sep}test.dart:1:12 • "
'(expected_token)'));
- expect(
- output,
- contains(
- 'analysis errors will result in erroneous migration suggestions'));
- expect(output, contains('Please fix the analysis issues'));
- expect(
- output,
- isNot(
- contains('All files appear to have null safety already enabled')));
+ expect(output, contains('erroneous migration suggestions'));
+ expect(output, contains('We recommend fixing the analysis issues'));
+ expect(output, isNot(contains('Set the lower SDK constraint')));
}
test_lifecycle_ignore_errors_enable() async {
@@ -1488,17 +1482,10 @@
var output = logger.stdoutBuffer.toString();
expect(output, contains('1 analysis issue found'));
expect(output, contains('uri_does_not_exist'));
- expect(
- output,
- contains(
- 'analysis errors will result in erroneous migration suggestions'));
- expect(output,
- contains('Unresolved URIs found. Did you forget to run "pub get"?'));
- expect(output, contains('Please fix the analysis issues'));
- expect(
- output,
- isNot(
- contains('All files appear to have null safety already enabled')));
+ expect(output, isNot(contains('erroneous migration suggestions')));
+ expect(output, contains('Run `dart pub get`'));
+ expect(output, contains('Try running `dart migrate` again'));
+ expect(output, isNot(contains('Set the lower SDK constraint')));
}
test_migrate_path_absolute() {
@@ -1912,9 +1899,7 @@
errorOutput,
contains("A value of type 'Null' can't be returned from function 'f' "
"because it has a return type of 'int'"));
- expect(errorOutput, contains('''
-All files appear to have null safety already enabled. Did you update the
-language version prior to running "dart migrate"?'''));
+ expect(errorOutput, contains('Set the lower SDK constraint'));
}
String _getHelpText({@required bool verbose}) {
diff --git a/pkg/vm_service/test/get_stack_test.dart b/pkg/vm_service/test/get_stack_test.dart
new file mode 100644
index 0000000..6e61379
--- /dev/null
+++ b/pkg/vm_service/test/get_stack_test.dart
@@ -0,0 +1,161 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// VMOptions=--lazy-async-stacks --no-causal-async-stacks --verbose_debug
+
+import 'dart:developer';
+
+import 'package:vm_service/vm_service.dart';
+import 'package:test/test.dart';
+
+import 'common/service_test_common.dart';
+import 'common/test_helper.dart';
+
+const LINE_A = 33;
+const LINE_B = 35;
+
+Future<void> testMain() async {
+ await func1();
+}
+
+Future func1() async => await func2();
+Future func2() async => await func3();
+Future func3() async => await func4();
+Future func4() async => await func5();
+Future func5() async => await func6();
+Future func6() async => await func7();
+Future func7() async => await func8();
+Future func8() async => await func9();
+Future func9() async => await func10();
+Future func10() async {
+ debugger(); // LINE_A
+ await 0;
+ debugger(); // LINE_B
+ print("Hello, world!");
+}
+
+void expectFrame(
+ final frame, final kindExpectation, final codeNameExpectation) {
+ expect(frame.kind, kindExpectation);
+ expect(frame.code?.name, codeNameExpectation);
+}
+
+void expectFrames(final frames, final expectKindAndCodeName) {
+ for (int i = 0; i < expectKindAndCodeName.length; i++) {
+ expectFrame(
+ frames[i], expectKindAndCodeName[i][0], expectKindAndCodeName[i][1]);
+ }
+}
+
+final tests = <IsolateTest>[
+ // Before the first await.
+ hasStoppedAtBreakpoint,
+ stoppedAtLine(LINE_A),
+ (VmService service, IsolateRef isolateRef) async {
+ final result = await service.getStack(isolateRef.id);
+
+ expect(result.frames, hasLength(16));
+ expect(result.asyncCausalFrames, hasLength(16));
+ expect(result.awaiterFrames, hasLength(16));
+
+ expectFrames(result.frames, [
+ [equals('Regular'), endsWith(' func10')],
+ [equals('Regular'), endsWith(' func9')],
+ [equals('Regular'), endsWith(' func8')],
+ [equals('Regular'), endsWith(' func7')],
+ [equals('Regular'), endsWith(' func6')],
+ [equals('Regular'), endsWith(' func5')],
+ [equals('Regular'), endsWith(' func4')],
+ [equals('Regular'), endsWith(' func3')],
+ [equals('Regular'), endsWith(' func2')],
+ [equals('Regular'), endsWith(' func1')],
+ [equals('Regular'), endsWith(' testMain')],
+ ]);
+
+ expectFrames(result.asyncCausalFrames, [
+ [equals('AsyncCausal'), endsWith(' func10')],
+ [equals('AsyncCausal'), endsWith(' func9')],
+ [equals('AsyncCausal'), endsWith(' func8')],
+ [equals('AsyncCausal'), endsWith(' func7')],
+ [equals('AsyncCausal'), endsWith(' func6')],
+ [equals('AsyncCausal'), endsWith(' func5')],
+ [equals('AsyncCausal'), endsWith(' func4')],
+ [equals('AsyncCausal'), endsWith(' func3')],
+ [equals('AsyncCausal'), endsWith(' func2')],
+ [equals('AsyncCausal'), endsWith(' func1')],
+ [equals('AsyncCausal'), endsWith(' testMain')],
+ ]);
+
+ expectFrames(result.awaiterFrames, [
+ [equals('AsyncActivation'), endsWith(' func10')],
+ [equals('AsyncActivation'), endsWith(' func9')],
+ [equals('AsyncActivation'), endsWith(' func8')],
+ [equals('AsyncActivation'), endsWith(' func7')],
+ [equals('AsyncActivation'), endsWith(' func6')],
+ [equals('AsyncActivation'), endsWith(' func5')],
+ [equals('AsyncActivation'), endsWith(' func4')],
+ [equals('AsyncActivation'), endsWith(' func3')],
+ [equals('AsyncActivation'), endsWith(' func2')],
+ [equals('AsyncActivation'), endsWith(' func1')],
+ [equals('AsyncActivation'), endsWith(' testMain')],
+ ]);
+ },
+ // After resuming the continuation - i.e. running async.
+ resumeIsolate,
+ hasStoppedAtBreakpoint,
+ stoppedAtLine(LINE_B),
+ (VmService service, IsolateRef isolateRef) async {
+ final result = await service.getStack(isolateRef.id);
+
+ expect(result.frames, hasLength(10));
+ expect(result.asyncCausalFrames, hasLength(26));
+ expect(result.awaiterFrames, hasLength(2));
+
+ expectFrames(result.frames, [
+ [equals('Regular'), endsWith(' func10')],
+ [equals('Regular'), endsWith(' _RootZone.runUnary')],
+ [equals('Regular'), anything], // Internal mech. ..
+ [equals('Regular'), anything],
+ [equals('Regular'), anything],
+ [equals('Regular'), anything],
+ [equals('Regular'), anything],
+ [equals('Regular'), anything],
+ [equals('Regular'), anything],
+ [equals('Regular'), endsWith(' _RawReceivePortImpl._handleMessage')],
+ ]);
+
+ expectFrames(result.asyncCausalFrames, [
+ [equals('AsyncCausal'), endsWith(' func10')],
+ [equals('AsyncSuspensionMarker'), isNull],
+ [equals('AsyncCausal'), endsWith(' func9')],
+ [equals('AsyncSuspensionMarker'), isNull],
+ [equals('AsyncCausal'), endsWith(' func8')],
+ [equals('AsyncSuspensionMarker'), isNull],
+ [equals('AsyncCausal'), endsWith(' func7')],
+ [equals('AsyncSuspensionMarker'), isNull],
+ [equals('AsyncCausal'), endsWith(' func6')],
+ [equals('AsyncSuspensionMarker'), isNull],
+ [equals('AsyncCausal'), endsWith(' func5')],
+ [equals('AsyncSuspensionMarker'), isNull],
+ [equals('AsyncCausal'), endsWith(' func4')],
+ [equals('AsyncSuspensionMarker'), isNull],
+ [equals('AsyncCausal'), endsWith(' func3')],
+ [equals('AsyncSuspensionMarker'), isNull],
+ [equals('AsyncCausal'), endsWith(' func2')],
+ [equals('AsyncSuspensionMarker'), isNull],
+ [equals('AsyncCausal'), endsWith(' func1')],
+ [equals('AsyncSuspensionMarker'), isNull],
+ [equals('AsyncCausal'), endsWith(' testMain')],
+ [equals('AsyncSuspensionMarker'), isNull],
+ ]);
+
+ expectFrames(result.awaiterFrames, [
+ [equals('AsyncActivation'), endsWith(' func10')],
+ [equals('AsyncActivation'), endsWith(' func9')],
+ ]);
+ },
+];
+
+main([args = const <String>[]]) =>
+ runIsolateTests(args, tests, testeeConcurrent: testMain);
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 0c3d7cd..36394b0 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -1919,31 +1919,23 @@
DebuggerStackTrace* Debugger::CollectAsyncLazyStackTrace() {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
- Isolate* isolate = thread->isolate();
Code& code = Code::Handle(zone);
- Code& inlined_code = Code::Handle(zone);
- Smi& offset = Smi::Handle();
- Array& deopt_frame = Array::Handle(zone);
+ Smi& offset = Smi::Handle(zone);
+ Function& function = Function::Handle(zone);
constexpr intptr_t kDefaultStackAllocation = 8;
auto stack_trace = new DebuggerStackTrace(kDefaultStackAllocation);
- std::function<void(StackFrame*)> on_sync_frame = [&](StackFrame* frame) {
- code = frame->LookupDartCode();
- AppendCodeFrames(thread, isolate, zone, stack_trace, frame, &code,
- &inlined_code, &deopt_frame);
- };
-
const auto& code_array = GrowableObjectArray::ZoneHandle(
zone, GrowableObjectArray::New(kDefaultStackAllocation));
const auto& pc_offset_array = GrowableObjectArray::ZoneHandle(
zone, GrowableObjectArray::New(kDefaultStackAllocation));
bool has_async = false;
StackTraceUtils::CollectFramesLazy(thread, code_array, pc_offset_array,
- /*skip_frames=*/0, &on_sync_frame,
- &has_async);
+ /*skip_frames=*/0, &has_async);
+ // If the entire stack is sync, return no trace.
if (!has_async) {
return nullptr;
}
@@ -1951,13 +1943,25 @@
const intptr_t length = code_array.Length();
for (intptr_t i = stack_trace->Length(); i < length; ++i) {
code ^= code_array.At(i);
- offset ^= pc_offset_array.At(i);
+
if (code.raw() == StubCode::AsynchronousGapMarker().raw()) {
stack_trace->AddMarker(ActivationFrame::kAsyncSuspensionMarker);
- } else {
- const uword absolute_pc = code.PayloadStart() + offset.Value();
- stack_trace->AddAsyncCausalFrame(absolute_pc, code);
+ continue;
}
+
+ if (!code.IsFunctionCode()) {
+ continue;
+ }
+
+ // Skip invisible function frames.
+ function ^= code.function();
+ if (!function.is_visible()) {
+ continue;
+ }
+
+ offset ^= pc_offset_array.At(i);
+ const uword absolute_pc = code.PayloadStart() + offset.Value();
+ stack_trace->AddAsyncCausalFrame(absolute_pc, code);
}
return stack_trace;
diff --git a/runtime/vm/stack_trace.cc b/runtime/vm/stack_trace.cc
index 5b146ff..572c222 100644
--- a/runtime/vm/stack_trace.cc
+++ b/runtime/vm/stack_trace.cc
@@ -287,7 +287,6 @@
const GrowableObjectArray& code_array,
const GrowableObjectArray& pc_offset_array,
int skip_frames,
- std::function<void(StackFrame*)>* on_sync_frames,
bool* has_async) {
if (has_async != nullptr) {
*has_async = false;
@@ -327,9 +326,6 @@
ASSERT(pc_offset > 0 && pc_offset <= code.Size());
offset = Smi::New(pc_offset);
pc_offset_array.Add(offset);
- if (on_sync_frames != nullptr) {
- (*on_sync_frames)(frame);
- }
// Either continue the loop (sync-async case) or find all await'ers and
// return.
diff --git a/runtime/vm/stack_trace.h b/runtime/vm/stack_trace.h
index 660746a..e3fd332 100644
--- a/runtime/vm/stack_trace.h
+++ b/runtime/vm/stack_trace.h
@@ -80,15 +80,11 @@
/// closure = closure.context[Context::kAsyncCompleterVarIndex]._future
/// ._resultOrListeners.callback;
/// }
- ///
- /// If [on_sync_frames] is non-nullptr, it will be called for every
- /// synchronous frame which is collected.
static void CollectFramesLazy(
Thread* thread,
const GrowableObjectArray& code_array,
const GrowableObjectArray& pc_offset_array,
int skip_frames,
- std::function<void(StackFrame*)>* on_sync_frames = nullptr,
bool* has_async = nullptr);
/// Counts the number of stack frames.
diff --git a/tools/VERSION b/tools/VERSION
index 517c0f1..ffc3992 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 12
PATCH 0
-PRERELEASE 36
+PRERELEASE 37
PRERELEASE_PATCH 0
\ No newline at end of file