Version 2.16.0-123.0.dev
Merge commit '38cbbaa63d94b2ef56aaddef258fe3b2b374017c' into 'dev'
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/documentation_cache.dart b/pkg/analysis_server/lib/src/services/completion/dart/documentation_cache.dart
index 0ca62d6..8411094 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/documentation_cache.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/documentation_cache.dart
@@ -162,17 +162,16 @@
}
extension on Map<String, DocumentationWithSummary> {
- /// Cache the data associated with the top-level [element], and return the
- /// [key] used for the element. This does not cache any data associated with
- /// any other elements, including children of the [element].
- String? cacheTopLevelElement(
- DartdocDirectiveInfo dartdocDirectiveInfo, Element element) {
- var key = element.name;
- if (key == null) {
- return null;
+ /// Cache the data associated with the [element], using the given [key].
+ DocumentationWithSummary? cacheElement(
+ DartdocDirectiveInfo dartdocDirectiveInfo, String key, Element element) {
+ var documentation = DartUnitHoverComputer.computeDocumentation(
+ dartdocDirectiveInfo, element,
+ includeSummary: true);
+ if (documentation is DocumentationWithSummary) {
+ return this[key] = documentation;
}
- cacheElement(dartdocDirectiveInfo, key, element);
- return key;
+ return this[key] = DocumentationCache._emptyDocs;
}
/// Cache the data associated with the [member] element given that the key
@@ -186,15 +185,16 @@
cacheElement(dartdocDirectiveInfo, '$parentKey.$name', member);
}
- /// Cache the data associated with the [element], using the given [key].
- DocumentationWithSummary? cacheElement(
- DartdocDirectiveInfo dartdocDirectiveInfo, String key, Element element) {
- var documentation = DartUnitHoverComputer.computeDocumentation(
- dartdocDirectiveInfo, element,
- includeSummary: true);
- if (documentation is DocumentationWithSummary) {
- return this[key] = documentation;
+ /// Cache the data associated with the top-level [element], and return the
+ /// [key] used for the element. This does not cache any data associated with
+ /// any other elements, including children of the [element].
+ String? cacheTopLevelElement(
+ DartdocDirectiveInfo dartdocDirectiveInfo, Element element) {
+ var key = element.name;
+ if (key == null) {
+ return null;
}
- return this[key] = DocumentationCache._emptyDocs;
+ cacheElement(dartdocDirectiveInfo, key, element);
+ return key;
}
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
index 8ffc7d4..0e7d181 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
@@ -547,8 +547,7 @@
var suggestion = CompletionSuggestion(CompletionSuggestionKind.IDENTIFIER,
Relevance.label, completion, completion.length, 0, false, false);
suggestion.element = createLocalElement(
- request.source, protocol.ElementKind.LABEL, label.label,
- returnType: NO_RETURN_TYPE);
+ request.source, protocol.ElementKind.LABEL, label.label);
_add(suggestion);
}
}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart b/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart
index 33d20fe..eef975c 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/utilities.dart
@@ -7,11 +7,8 @@
show CompletionSuggestion, Location;
import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/standard_ast_factory.dart';
-import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/dart/ast/token.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol
show Element, ElementKind;
@@ -28,13 +25,6 @@
return b.relevance.compareTo(a.relevance);
};
-/// A marker used in place of `null` when a function has no return type.
-final NamedType NO_RETURN_TYPE = astFactory.namedType(
- name: astFactory.simpleIdentifier(
- StringToken(TokenType.IDENTIFIER, '', 0),
- ),
-);
-
/// Add default argument list text and ranges based on the given
/// [requiredParams] and [namedParams].
void addDefaultArgDetails(
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/rename_parameter.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/rename_parameter.dart
index 1072578..19ca94a 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/rename_parameter.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/rename_parameter.dart
@@ -111,20 +111,6 @@
}
extension on MethodDeclaration {
- /// Return the parameter of this method whose name matches the given [name],
- /// or `null` if there is no such parameter.
- FormalParameter? parameterNamed(String name) {
- final parameters = this.parameters;
- if (parameters != null) {
- for (var parameter in parameters.parameters) {
- if (parameter.declaredElement?.name == name) {
- return parameter;
- }
- }
- }
- return null;
- }
-
/// Return the element that this method overrides, or `null` if this method
/// doesn't override any inherited member.
ExecutableElement? overriddenElement() {
@@ -138,6 +124,20 @@
}
return null;
}
+
+ /// Return the parameter of this method whose name matches the given [name],
+ /// or `null` if there is no such parameter.
+ FormalParameter? parameterNamed(String name) {
+ final parameters = this.parameters;
+ if (parameters != null) {
+ for (var parameter in parameters.parameters) {
+ if (parameter.declaredElement?.name == name) {
+ return parameter;
+ }
+ }
+ }
+ return null;
+ }
}
extension on ExecutableElement {
diff --git a/pkg/analysis_server/lib/src/utilities/extensions/ast.dart b/pkg/analysis_server/lib/src/utilities/extensions/ast.dart
index efde1c5..b92d957 100644
--- a/pkg/analysis_server/lib/src/utilities/extensions/ast.dart
+++ b/pkg/analysis_server/lib/src/utilities/extensions/ast.dart
@@ -8,6 +8,18 @@
import 'package:analyzer/dart/element/element.dart';
extension AstNodeExtensions on AstNode {
+ /// Return the [IfStatement] associated with `this`.
+ IfStatement? get enclosingIfStatement {
+ for (var node in withParents) {
+ if (node is IfStatement) {
+ return node;
+ } else if (node is! Expression) {
+ return null;
+ }
+ }
+ return null;
+ }
+
/// Return `true` if this node has an `override` annotation.
bool get hasOverride {
var node = this;
@@ -62,18 +74,6 @@
bool get inWhileLoop => thisOrAncestorOfType<WhileStatement>() != null;
- /// Return the [IfStatement] associated with `this`.
- IfStatement? get enclosingIfStatement {
- for (var node in withParents) {
- if (node is IfStatement) {
- return node;
- } else if (node is! Expression) {
- return null;
- }
- }
- return null;
- }
-
/// Return this node and all its parents.
Iterable<AstNode> get withParents sync* {
var current = this;
diff --git a/pkg/analysis_server/lib/src/utilities/extensions/range_factory.dart b/pkg/analysis_server/lib/src/utilities/extensions/range_factory.dart
index b143cd4..95c5384 100644
--- a/pkg/analysis_server/lib/src/utilities/extensions/range_factory.dart
+++ b/pkg/analysis_server/lib/src/utilities/extensions/range_factory.dart
@@ -89,6 +89,26 @@
return startEnd(thisLeadingComment, thisTrailingComment);
}
+ /// Return the left-most comment immediately before the [token] that is not on
+ /// the same line as the first non-comment token before the [token]. Return
+ /// the [token] if there is no such comment.
+ Token _leadingComment(LineInfo lineInfo, Token token) {
+ var previous = token.previous;
+ if (previous == null || previous.type == TokenType.EOF) {
+ return token.precedingComments ?? token;
+ }
+ var previousLine = lineInfo.getLocation(previous.offset).lineNumber;
+ Token? comment = token.precedingComments;
+ while (comment != null) {
+ var commentLine = lineInfo.getLocation(comment.offset).lineNumber;
+ if (commentLine != previousLine) {
+ break;
+ }
+ comment = comment.next;
+ }
+ return comment ?? token;
+ }
+
/// Return the comment token immediately following the [token] if it is on the
/// same line as the [token], or the [token] if there is no comment after the
/// [token] or if the comment is on a different line than the [token]. If
@@ -111,24 +131,4 @@
}
return returnComma ? lastToken : token;
}
-
- /// Return the left-most comment immediately before the [token] that is not on
- /// the same line as the first non-comment token before the [token]. Return
- /// the [token] if there is no such comment.
- Token _leadingComment(LineInfo lineInfo, Token token) {
- var previous = token.previous;
- if (previous == null || previous.type == TokenType.EOF) {
- return token.precedingComments ?? token;
- }
- var previousLine = lineInfo.getLocation(previous.offset).lineNumber;
- Token? comment = token.precedingComments;
- while (comment != null) {
- var commentLine = lineInfo.getLocation(comment.offset).lineNumber;
- if (commentLine != previousLine) {
- break;
- }
- comment = comment.next;
- }
- return comment ?? token;
- }
}
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index c3ec9c3..e3a94a0 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -2783,18 +2783,18 @@
extension on CheckTarget<CompletionGetSuggestionDetails2Result> {
@useResult
- CheckTarget<String> get completion {
- return nest(
- value.completion,
- (selected) => 'has completion ${valueStr(selected)}',
- );
- }
-
- @useResult
CheckTarget<SourceChange> get change {
return nest(
value.change,
(selected) => 'has change ${valueStr(selected)}',
);
}
+
+ @useResult
+ CheckTarget<String> get completion {
+ return nest(
+ value.completion,
+ (selected) => 'has completion ${valueStr(selected)}',
+ );
+ }
}
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index f5e2631..105ec72 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,3 +1,6 @@
+## 3.1.0-dev
+* New internal API for `package:dart_style`.
+
## 3.0.0
* Removed deprecated `DartType.aliasElement/aliasArguments`.
* Removed deprecated constructors from `FeatureSet`.
diff --git a/pkg/analyzer/lib/src/clients/dart_style/rewrite_cascade.dart b/pkg/analyzer/lib/src/clients/dart_style/rewrite_cascade.dart
new file mode 100644
index 0000000..dc054a8
--- /dev/null
+++ b/pkg/analyzer/lib/src/clients/dart_style/rewrite_cascade.dart
@@ -0,0 +1,114 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. 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/standard_ast_factory.dart';
+import 'package:analyzer/dart/ast/token.dart';
+
+/// Parenthesize the target of the [expressionStatement]'s expression (assumed
+/// to [cascadeExpression]) before removing the cascade.
+ExpressionStatement fixCascadeByParenthesizingTarget({
+ required ExpressionStatement expressionStatement,
+ required CascadeExpression cascadeExpression,
+}) {
+ assert(cascadeExpression.cascadeSections.length == 1);
+
+ var newTarget = astFactory.parenthesizedExpression(
+ Token(TokenType.OPEN_PAREN, 0)
+ ..previous = expressionStatement.beginToken.previous
+ ..next = cascadeExpression.target.beginToken,
+ cascadeExpression.target,
+ Token(TokenType.CLOSE_PAREN, 0)
+ ..previous = cascadeExpression.target.endToken
+ ..next = expressionStatement.semicolon,
+ );
+
+ return astFactory.expressionStatement(
+ astFactory.cascadeExpression(
+ newTarget,
+ cascadeExpression.cascadeSections,
+ ),
+ expressionStatement.semicolon,
+ );
+}
+
+/// Recursively insert [cascadeTarget] (the LHS of the cascade) into the
+/// LHS of the assignment expression that used to be the cascade's RHS.
+Expression insertCascadeTargetIntoExpression({
+ required Expression expression,
+ required Expression cascadeTarget,
+}) {
+ // Base case: We've recursed as deep as possible.
+ if (expression == cascadeTarget) return cascadeTarget;
+
+ // Otherwise, copy `expression` and recurse into its LHS.
+ if (expression is AssignmentExpression) {
+ return astFactory.assignmentExpression(
+ insertCascadeTargetIntoExpression(
+ expression: expression.leftHandSide,
+ cascadeTarget: cascadeTarget,
+ ),
+ expression.operator,
+ expression.rightHandSide,
+ );
+ } else if (expression is IndexExpression) {
+ var expressionTarget = expression.realTarget;
+ var question = expression.question;
+
+ // A null-aware cascade treats the `?` in `?..` as part of the token, but
+ // for a non-cascade index, it is a separate `?` token.
+ if (expression.period?.type == TokenType.QUESTION_PERIOD_PERIOD) {
+ question = _synthesizeToken(TokenType.QUESTION, expression.period!);
+ }
+
+ return astFactory.indexExpressionForTarget2(
+ target: insertCascadeTargetIntoExpression(
+ expression: expressionTarget,
+ cascadeTarget: cascadeTarget,
+ ),
+ question: question,
+ leftBracket: expression.leftBracket,
+ index: expression.index,
+ rightBracket: expression.rightBracket,
+ );
+ } else if (expression is MethodInvocation) {
+ var expressionTarget = expression.realTarget!;
+ return astFactory.methodInvocation(
+ insertCascadeTargetIntoExpression(
+ expression: expressionTarget,
+ cascadeTarget: cascadeTarget,
+ ),
+ // If we've reached the end, replace the `..` operator with `.`
+ expressionTarget == cascadeTarget
+ ? _synthesizeToken(TokenType.PERIOD, expression.operator!)
+ : expression.operator,
+ expression.methodName,
+ expression.typeArguments,
+ expression.argumentList,
+ );
+ } else if (expression is PropertyAccess) {
+ var expressionTarget = expression.realTarget;
+ return astFactory.propertyAccess(
+ insertCascadeTargetIntoExpression(
+ expression: expressionTarget,
+ cascadeTarget: cascadeTarget,
+ ),
+ // If we've reached the end, replace the `..` operator with `.`
+ expressionTarget == cascadeTarget
+ ? _synthesizeToken(TokenType.PERIOD, expression.operator)
+ : expression.operator,
+ expression.propertyName,
+ );
+ }
+ throw UnimplementedError('Unhandled ${expression.runtimeType}'
+ '($expression)');
+}
+
+/// Synthesize a token with [type] to replace the given [operator].
+///
+/// Offset, comments, and previous/next links are all preserved.
+Token _synthesizeToken(TokenType type, Token operator) =>
+ Token(type, operator.offset, operator.precedingComments)
+ ..previous = operator.previous
+ ..next = operator.next;
diff --git a/pkg/analyzer/lib/src/dart/ast/extensions.dart b/pkg/analyzer/lib/src/dart/ast/extensions.dart
index 3df0bb6..f30fcca 100644
--- a/pkg/analyzer/lib/src/dart/ast/extensions.dart
+++ b/pkg/analyzer/lib/src/dart/ast/extensions.dart
@@ -118,14 +118,14 @@
/// TODO(scheglov) https://github.com/dart-lang/sdk/issues/43608
extension IdentifierExtension on Identifier {
- Element? get writeElement {
- return _writeElement(this);
- }
-
Element? get readElement {
return _readElement(this);
}
+ Element? get writeElement {
+ return _writeElement(this);
+ }
+
Element? get writeOrReadElement {
return _writeElement(this) ?? staticElement;
}
diff --git a/pkg/analyzer/lib/src/dart/element/extensions.dart b/pkg/analyzer/lib/src/dart/element/extensions.dart
index 7037407..ad00f5e 100644
--- a/pkg/analyzer/lib/src/dart/element/extensions.dart
+++ b/pkg/analyzer/lib/src/dart/element/extensions.dart
@@ -60,23 +60,6 @@
}
extension ElementExtension on Element {
- /// Return `true` if this element is an instance member of a class or mixin.
- ///
- /// Only [MethodElement]s and [PropertyAccessorElement]s are supported.
- /// We intentionally exclude [ConstructorElement]s - they can only be
- /// invoked in instance creation expressions, and [FieldElement]s - they
- /// cannot be invoked directly and are always accessed using corresponding
- /// [PropertyAccessorElement]s.
- bool get isInstanceMember {
- var this_ = this;
- var enclosing = this_.enclosingElement;
- if (enclosing is ClassElement) {
- return this_ is MethodElement && !this_.isStatic ||
- this_ is PropertyAccessorElement && !this_.isStatic;
- }
- return false;
- }
-
/// Return `true` if this element, the enclosing class (if there is one), or
/// the enclosing library, has been annotated with the `@doNotStore`
/// annotation.
@@ -101,6 +84,23 @@
return ancestor is CompilationUnitElement &&
ancestor.enclosingElement.hasDoNotStore;
}
+
+ /// Return `true` if this element is an instance member of a class or mixin.
+ ///
+ /// Only [MethodElement]s and [PropertyAccessorElement]s are supported.
+ /// We intentionally exclude [ConstructorElement]s - they can only be
+ /// invoked in instance creation expressions, and [FieldElement]s - they
+ /// cannot be invoked directly and are always accessed using corresponding
+ /// [PropertyAccessorElement]s.
+ bool get isInstanceMember {
+ var this_ = this;
+ var enclosing = this_.enclosingElement;
+ if (enclosing is ClassElement) {
+ return this_ is MethodElement && !this_.isStatic ||
+ this_ is PropertyAccessorElement && !this_.isStatic;
+ }
+ return false;
+ }
}
extension ParameterElementExtensions on ParameterElement {
diff --git a/pkg/analyzer/lib/src/dart/resolver/applicable_extensions.dart b/pkg/analyzer/lib/src/dart/resolver/applicable_extensions.dart
index 478c884..5d26817 100644
--- a/pkg/analyzer/lib/src/dart/resolver/applicable_extensions.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/applicable_extensions.dart
@@ -105,6 +105,17 @@
}
extension ExtensionsExtensions on Iterable<ExtensionElement> {
+ /// Extensions that can be applied, within [targetLibrary], to [targetType].
+ List<InstantiatedExtensionWithoutMember> applicableTo({
+ required LibraryElement targetLibrary,
+ required DartType targetType,
+ }) {
+ return map((e) => _NotInstantiatedExtensionWithoutMember(e)).applicableTo(
+ targetLibrary: targetLibrary,
+ targetType: targetType,
+ );
+ }
+
List<_NotInstantiatedExtensionWithMember> hasMemberWithBaseName(
String baseName,
) {
@@ -157,17 +168,6 @@
}
return result;
}
-
- /// Extensions that can be applied, within [targetLibrary], to [targetType].
- List<InstantiatedExtensionWithoutMember> applicableTo({
- required LibraryElement targetLibrary,
- required DartType targetType,
- }) {
- return map((e) => _NotInstantiatedExtensionWithoutMember(e)).applicableTo(
- targetLibrary: targetLibrary,
- targetType: targetType,
- );
- }
}
extension NotInstantiatedExtensionsExtensions<R>
diff --git a/pkg/analyzer/lib/src/generated/ffi_verifier.dart b/pkg/analyzer/lib/src/generated/ffi_verifier.dart
index aadcb78..53ec6ae 100644
--- a/pkg/analyzer/lib/src/generated/ffi_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/ffi_verifier.dart
@@ -1259,20 +1259,6 @@
}
extension on Annotation {
- bool get isArray {
- final element = this.element;
- return element is ConstructorElement &&
- element.ffiClass != null &&
- element.enclosingElement.name == 'Array';
- }
-
- bool get isPacked {
- final element = this.element;
- return element is ConstructorElement &&
- element.ffiClass != null &&
- element.enclosingElement.name == 'Packed';
- }
-
bool get isAbiSpecificIntegerMapping {
final element = this.element;
return element is ConstructorElement &&
@@ -1280,16 +1266,12 @@
element.enclosingElement.name ==
FfiVerifier._abiSpecificIntegerMappingClassName;
}
-}
-extension on ElementAnnotation {
bool get isArray {
final element = this.element;
return element is ConstructorElement &&
element.ffiClass != null &&
element.enclosingElement.name == 'Array';
- // Note: this is 'Array' instead of '_ArraySize' because it finds the
- // forwarding factory instead of the forwarded constructor.
}
bool get isPacked {
@@ -1298,7 +1280,9 @@
element.ffiClass != null &&
element.enclosingElement.name == 'Packed';
}
+}
+extension on ElementAnnotation {
List<int> get arraySizeDimensions {
assert(isArray);
final value = computeConstantValue();
@@ -1334,6 +1318,22 @@
return result;
}
+ bool get isArray {
+ final element = this.element;
+ return element is ConstructorElement &&
+ element.ffiClass != null &&
+ element.enclosingElement.name == 'Array';
+ // Note: this is 'Array' instead of '_ArraySize' because it finds the
+ // forwarding factory instead of the forwarded constructor.
+ }
+
+ bool get isPacked {
+ final element = this.element;
+ return element is ConstructorElement &&
+ element.ffiClass != null &&
+ element.enclosingElement.name == 'Packed';
+ }
+
int? get packedMemberAlignment {
assert(isPacked);
final value = computeConstantValue();
@@ -1342,6 +1342,33 @@
}
extension on Element? {
+ /// If this is a class element from `dart:ffi`, return it.
+ ClassElement? get ffiClass {
+ var element = this;
+ if (element is ConstructorElement) {
+ element = element.enclosingElement;
+ }
+ if (element is ClassElement && element.isFfiClass) {
+ return element;
+ }
+ return null;
+ }
+
+ /// Return `true` if this represents the class `AbiSpecificInteger`.
+ bool get isAbiSpecificInteger {
+ final element = this;
+ return element is ClassElement &&
+ element.name == FfiVerifier._abiSpecificIntegerClassName &&
+ element.isFfiClass;
+ }
+
+ /// Return `true` if this represents a subclass of the class
+ /// `AbiSpecificInteger`.
+ bool get isAbiSpecificIntegerSubclass {
+ final element = this;
+ return element is ClassElement && element.supertype.isAbiSpecificInteger;
+ }
+
/// Return `true` if this represents the extension `AllocatorAlloc`.
bool get isAllocatorExtension {
final element = this;
@@ -1350,6 +1377,14 @@
element.isFfiExtension;
}
+ /// Return `true` if this represents the extension `DynamicLibraryExtension`.
+ bool get isDynamicLibraryExtension {
+ final element = this;
+ return element is ExtensionElement &&
+ element.name == 'DynamicLibraryExtension' &&
+ element.isFfiExtension;
+ }
+
bool get isNativeFunctionPointerExtension {
final element = this;
return element is ExtensionElement &&
@@ -1371,14 +1406,6 @@
element.isFfiExtension;
}
- /// Return `true` if this represents the extension `DynamicLibraryExtension`.
- bool get isDynamicLibraryExtension {
- final element = this;
- return element is ExtensionElement &&
- element.name == 'DynamicLibraryExtension' &&
- element.isFfiExtension;
- }
-
/// Return `true` if this represents the class `Pointer`.
bool get isPointer {
final element = this;
@@ -1414,33 +1441,6 @@
final element = this;
return element is ClassElement && element.supertype.isUnion;
}
-
- /// Return `true` if this represents the class `AbiSpecificInteger`.
- bool get isAbiSpecificInteger {
- final element = this;
- return element is ClassElement &&
- element.name == FfiVerifier._abiSpecificIntegerClassName &&
- element.isFfiClass;
- }
-
- /// Return `true` if this represents a subclass of the class
- /// `AbiSpecificInteger`.
- bool get isAbiSpecificIntegerSubclass {
- final element = this;
- return element is ClassElement && element.supertype.isAbiSpecificInteger;
- }
-
- /// If this is a class element from `dart:ffi`, return it.
- ClassElement? get ffiClass {
- var element = this;
- if (element is ConstructorElement) {
- element = element.enclosingElement;
- }
- if (element is ClassElement && element.isFfiClass) {
- return element;
- }
- return null;
- }
}
extension on ClassElement {
@@ -1487,6 +1487,11 @@
}
extension on DartType? {
+ bool get isAbiSpecificInteger {
+ final self = this;
+ return self is InterfaceType && self.element.isAbiSpecificInteger;
+ }
+
bool get isStruct {
final self = this;
return self is InterfaceType && self.element.isStruct;
@@ -1496,24 +1501,9 @@
final self = this;
return self is InterfaceType && self.element.isUnion;
}
-
- bool get isAbiSpecificInteger {
- final self = this;
- return self is InterfaceType && self.element.isAbiSpecificInteger;
- }
}
extension on DartType {
- /// Return `true` if this represents the class `Array`.
- bool get isArray {
- final self = this;
- if (self is InterfaceType) {
- final element = self.element;
- return element.name == FfiVerifier._arrayClassName && element.isFfiClass;
- }
- return false;
- }
-
int get arrayDimensions {
DartType iterator = this;
int dimensions = 0;
@@ -1536,9 +1526,65 @@
return iterator;
}
- bool get isPointer {
+ bool get isAbiSpecificInteger {
final self = this;
- return self is InterfaceType && self.element.isPointer;
+ if (self is InterfaceType) {
+ final element = self.element;
+ final name = element.name;
+ return name == FfiVerifier._abiSpecificIntegerClassName &&
+ element.isFfiClass;
+ }
+ return false;
+ }
+
+ /// Returns `true` iff this is an Abi-specific integer type,
+ /// i.e. a subtype of `AbiSpecificInteger`.
+ bool get isAbiSpecificIntegerSubtype {
+ final self = this;
+ if (self is InterfaceType) {
+ final superType = self.element.supertype;
+ if (superType != null) {
+ final superClassElement = superType.element;
+ return superClassElement.name ==
+ FfiVerifier._abiSpecificIntegerClassName &&
+ superClassElement.isFfiClass;
+ }
+ }
+ return false;
+ }
+
+ /// Return `true` if this represents the class `Array`.
+ bool get isArray {
+ final self = this;
+ if (self is InterfaceType) {
+ final element = self.element;
+ return element.name == FfiVerifier._arrayClassName && element.isFfiClass;
+ }
+ return false;
+ }
+
+ bool get isCompound {
+ final self = this;
+ if (self is InterfaceType) {
+ final element = self.element;
+ final name = element.name;
+ return (name == FfiVerifier._structClassName ||
+ name == FfiVerifier._unionClassName) &&
+ element.isFfiClass;
+ }
+ return false;
+ }
+
+ /// Returns `true` if this is a struct type, i.e. a subtype of `Struct`.
+ bool get isCompoundSubtype {
+ final self = this;
+ if (self is InterfaceType) {
+ final superType = self.element.supertype;
+ if (superType != null) {
+ return superType.isCompound;
+ }
+ }
+ return false;
}
bool get isHandle {
@@ -1570,33 +1616,6 @@
return false;
}
- bool get isAbiSpecificInteger {
- final self = this;
- if (self is InterfaceType) {
- final element = self.element;
- final name = element.name;
- return name == FfiVerifier._abiSpecificIntegerClassName &&
- element.isFfiClass;
- }
- return false;
- }
-
- /// Returns `true` iff this is an Abi-specific integer type,
- /// i.e. a subtype of `AbiSpecificInteger`.
- bool get isAbiSpecificIntegerSubtype {
- final self = this;
- if (self is InterfaceType) {
- final superType = self.element.supertype;
- if (superType != null) {
- final superClassElement = superType.element;
- return superClassElement.name ==
- FfiVerifier._abiSpecificIntegerClassName &&
- superClassElement.isFfiClass;
- }
- }
- return false;
- }
-
/// Returns `true` iff this is a opaque type, i.e. a subtype of `Opaque`.
bool get isOpaqueSubtype {
final self = this;
@@ -1611,28 +1630,9 @@
return false;
}
- bool get isCompound {
+ bool get isPointer {
final self = this;
- if (self is InterfaceType) {
- final element = self.element;
- final name = element.name;
- return (name == FfiVerifier._structClassName ||
- name == FfiVerifier._unionClassName) &&
- element.isFfiClass;
- }
- return false;
- }
-
- /// Returns `true` if this is a struct type, i.e. a subtype of `Struct`.
- bool get isCompoundSubtype {
- final self = this;
- if (self is InterfaceType) {
- final superType = self.element.supertype;
- if (superType != null) {
- return superType.isCompound;
- }
- }
- return false;
+ return self is InterfaceType && self.element.isPointer;
}
}
@@ -1643,19 +1643,19 @@
}
/// Return `true` if this represents a subtype of `Struct` or `Union`.
- bool get isCompoundSubtype {
+ bool get isAbiSpecificIntegerSubtype {
var element = name.staticElement;
if (element is ClassElement) {
- return element.allSupertypes.any((e) => e.isCompound);
+ return element.allSupertypes.any((e) => e.isAbiSpecificInteger);
}
return false;
}
/// Return `true` if this represents a subtype of `Struct` or `Union`.
- bool get isAbiSpecificIntegerSubtype {
+ bool get isCompoundSubtype {
var element = name.staticElement;
if (element is ClassElement) {
- return element.allSupertypes.any((e) => e.isAbiSpecificInteger);
+ return element.allSupertypes.any((e) => e.isCompound);
}
return false;
}
diff --git a/pkg/analyzer/lib/src/lint/util.dart b/pkg/analyzer/lib/src/lint/util.dart
index a0c25dc..392df53 100644
--- a/pkg/analyzer/lib/src/lint/util.dart
+++ b/pkg/analyzer/lib/src/lint/util.dart
@@ -12,19 +12,8 @@
import 'package:analyzer/src/dart/ast/token.dart';
import 'package:path/path.dart' as path;
-final _identifier = RegExp(r'^([(_|$)a-zA-Z]+([_a-zA-Z0-9])*)$');
-
-final _lowerCamelCase = RegExp(r'^(_)*[?$a-z][a-z0-9?$]*([A-Z][a-z0-9?$]*)*$');
-
-final _lowerCaseUnderScore = RegExp(r'^([a-z]+([_]?[a-z0-9]+)*)+$');
-
-final _lowerCaseUnderScoreWithDots =
- RegExp(r'^[a-z][_a-z0-9]*(\.[a-z][_a-z0-9]*)*$');
-
final _pubspec = RegExp(r'^[_]?pubspec\.yaml$');
-final _underscores = RegExp(r'^[_]+$');
-
/// Create a library name prefix based on [libraryPath], [projectRoot] and
/// current [packageName].
String createLibraryNamePrefix(
@@ -50,37 +39,9 @@
/// Returns `true` if this [fileName] is a Dart file.
bool isDartFileName(String fileName) => fileName.endsWith('.dart');
-/// Returns `true` if this [name] is a legal Dart identifier.
-@deprecated // Never intended for public use.
-bool isIdentifier(String name) => _identifier.hasMatch(name);
-
-/// Returns `true` of the given [name] is composed only of `_`s.
-@deprecated // Never intended for public use.
-bool isJustUnderscores(String name) => _underscores.hasMatch(name);
-
-/// Returns `true` if this [id] is `lowerCamelCase`.
-@deprecated // Never intended for public use.
-bool isLowerCamelCase(String id) =>
- id.length == 1 && isUpperCase(id.codeUnitAt(0)) ||
- id == '_' ||
- _lowerCamelCase.hasMatch(id);
-
-/// Returns `true` if this [id] is `lower_camel_case_with_underscores`.
-@deprecated // Never intended for public use.
-bool isLowerCaseUnderScore(String id) => _lowerCaseUnderScore.hasMatch(id);
-
-/// Returns `true` if this [id] is `lower_camel_case_with_underscores_or.dots`.
-@deprecated // Never intended for public use.
-bool isLowerCaseUnderScoreWithDots(String id) =>
- _lowerCaseUnderScoreWithDots.hasMatch(id);
-
/// Returns `true` if this [fileName] is a Pubspec file.
bool isPubspecFileName(String fileName) => _pubspec.hasMatch(fileName);
-/// Returns `true` if the given code unit [c] is upper case.
-@deprecated // Never intended for public use.
-bool isUpperCase(int c) => c >= 0x40 && c <= 0x5A;
-
class Spelunker {
final String path;
final IOSink sink;
diff --git a/pkg/analyzer/lib/src/util/yaml.dart b/pkg/analyzer/lib/src/util/yaml.dart
index dfa104e..416828c 100644
--- a/pkg/analyzer/lib/src/util/yaml.dart
+++ b/pkg/analyzer/lib/src/util/yaml.dart
@@ -106,12 +106,15 @@
}
extension YamlMapExtensions on YamlMap {
- /// Return the value associated with the key whose value matches the given
- /// [key], or `null` if there is no matching key.
- YamlNode? valueAt(String key) {
- for (var keyNode in nodes.keys) {
- if (keyNode is YamlScalar && keyNode.value == key) {
- return nodes[keyNode];
+ /// Return [nodes] as a Map with [YamlNode] keys.
+ Map<YamlNode, YamlNode> get nodeMap => nodes.cast<YamlNode, YamlNode>();
+
+ /// Return the [YamlNode] associated with the given [key], or `null` if there
+ /// is no matching key.
+ YamlNode? getKey(String key) {
+ for (YamlNode k in nodes.keys) {
+ if (k is YamlScalar && k.value == key) {
+ return k;
}
}
return null;
@@ -128,17 +131,14 @@
return null;
}
- /// Return the [YamlNode] associated with the given [key], or `null` if there
- /// is no matching key.
- YamlNode? getKey(String key) {
- for (YamlNode k in nodes.keys) {
- if (k is YamlScalar && k.value == key) {
- return k;
+ /// Return the value associated with the key whose value matches the given
+ /// [key], or `null` if there is no matching key.
+ YamlNode? valueAt(String key) {
+ for (var keyNode in nodes.keys) {
+ if (keyNode is YamlScalar && keyNode.value == key) {
+ return nodes[keyNode];
}
}
return null;
}
-
- /// Return [nodes] as a Map with [YamlNode] keys.
- Map<YamlNode, YamlNode> get nodeMap => nodes.cast<YamlNode, YamlNode>();
}
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 9261ded..e706822 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
name: analyzer
-version: 3.0.0
+version: 3.1.0-dev
description: This package provides a library that performs static analysis of Dart code.
homepage: https://github.com/dart-lang/sdk/tree/main/pkg/analyzer
diff --git a/pkg/analyzer/test/src/clients/dart_style/rewrite_cascade_test.dart b/pkg/analyzer/test/src/clients/dart_style/rewrite_cascade_test.dart
new file mode 100644
index 0000000..81d2486
--- /dev/null
+++ b/pkg/analyzer/test/src/clients/dart_style/rewrite_cascade_test.dart
@@ -0,0 +1,121 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/dart/analysis/utilities.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/src/clients/dart_style/rewrite_cascade.dart';
+import 'package:analyzer/src/test_utilities/find_node.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RewriteCascadeTest);
+ });
+}
+
+@reflectiveTest
+class RewriteCascadeTest {
+ test_fixCascadeByParenthesizingTarget() {
+ const pairs = {
+ 'c ? a : b..method();': '(c ? a : b)..method();',
+ 'a ?? b..method();': '(a ?? b)..method();',
+ 'a && b..method();': '(a && b)..method();',
+ 'a || b..method();': '(a || b)..method();',
+ 'a == b..method();': '(a == b)..method();',
+ 'a != b..method();': '(a != b)..method();',
+ 'a < b..method();': '(a < b)..method();',
+ 'a > b..method();': '(a > b)..method();',
+ 'a <= b..method();': '(a <= b)..method();',
+ 'a >= b..method();': '(a >= b)..method();',
+ 'a ^ b..method();': '(a ^ b)..method();',
+ 'a | b..method();': '(a | b)..method();',
+ 'a << b..method();': '(a << b)..method();',
+ 'a >> b..method();': '(a >> b)..method();',
+ 'a + b..method();': '(a + b)..method();',
+ 'a - b..method();': '(a - b)..method();',
+ 'a * b..method();': '(a * b)..method();',
+ 'a / b..method();': '(a / b)..method();',
+ 'a ~/ b..method();': '(a ~/ b)..method();',
+ '-a..method();': '(-a)..method();',
+ '!a..method();': '(!a)..method();',
+ '~a..method();': '(~a)..method();',
+ 'a++..method();': '(a++)..method();',
+ 'a--..method();': '(a--)..method();',
+ };
+
+ void assertSingle({
+ required String input,
+ required String expected,
+ }) {
+ var statement = _parseStringToFindNode('''
+void f() {
+ $input
+}
+''').expressionStatement(input);
+ var result = fixCascadeByParenthesizingTarget(
+ expressionStatement: statement,
+ cascadeExpression: statement.expression as CascadeExpression,
+ );
+ expect(result.toSource(), expected);
+ expect(result.semicolon, same(statement.semicolon));
+ }
+
+ for (var entry in pairs.entries) {
+ assertSingle(
+ input: entry.key,
+ expected: entry.value,
+ );
+ }
+ }
+
+ test_insertCascadeTargetIntoExpression() {
+ void assertSingle({
+ required String input,
+ required String expected,
+ }) {
+ var statement = _parseStringToFindNode('''
+void f() {
+ $input;
+ }
+ ''').expressionStatement(input);
+ var cascadeExpression = statement.expression as CascadeExpression;
+ var result = insertCascadeTargetIntoExpression(
+ expression: cascadeExpression.cascadeSections.single,
+ cascadeTarget: cascadeExpression.target,
+ );
+ expect(result.toSource(), expected);
+ }
+
+ const pairs = {
+ 'obj..method()': 'obj.method()',
+ 'obj..getter': 'obj.getter',
+ 'obj..setter = 3': 'obj.setter = 3',
+ 'obj..[subscript] = 3': 'obj[subscript] = 3',
+ 'obj?..[subscript] = 3': 'obj?[subscript] = 3',
+ 'obj..index[subscript] = 3': 'obj.index[subscript] = 3',
+ 'obj..index?[subscript] = 3': 'obj.index?[subscript] = 3',
+ // Nested
+ 'obj..foo().bar().method()': 'obj.foo().bar().method()',
+ 'obj..foo.bar.getter': 'obj.foo.bar.getter',
+ 'obj..foo.bar.setter = 0': 'obj.foo.bar.setter = 0',
+ };
+
+ for (var entry in pairs.entries) {
+ assertSingle(
+ input: entry.key,
+ expected: entry.value,
+ );
+ }
+ }
+
+ FindNode _parseStringToFindNode(String content) {
+ var parseResult = parseString(
+ content: content,
+ featureSet: FeatureSet.latestLanguageVersion(),
+ );
+ return FindNode(parseResult.content, parseResult.unit);
+ }
+}
diff --git a/pkg/analyzer/test/src/clients/dart_style/test_all.dart b/pkg/analyzer/test/src/clients/dart_style/test_all.dart
new file mode 100644
index 0000000..d5179bd
--- /dev/null
+++ b/pkg/analyzer/test/src/clients/dart_style/test_all.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'rewrite_cascade_test.dart' as rewrite_cascade;
+
+main() {
+ defineReflectiveSuite(() {
+ rewrite_cascade.main();
+ }, name: 'dart_style');
+}
diff --git a/pkg/analyzer/test/src/clients/test_all.dart b/pkg/analyzer/test/src/clients/test_all.dart
new file mode 100644
index 0000000..5118a6b
--- /dev/null
+++ b/pkg/analyzer/test/src/clients/test_all.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'dart_style/test_all.dart' as dart_style;
+
+main() {
+ defineReflectiveSuite(() {
+ dart_style.main();
+ }, name: 'clients');
+}
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index 8568ee0..cb4869d 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -71,33 +71,30 @@
// Reference "inner" using a non-canonical URI.
{
- var path = convertPath('$outerLibPath/a.dart');
- newFile(path, content: r'''
+ var a = newFile(convertPath('$outerLibPath/a.dart'), content: r'''
import 'inner/lib/b.dart';
''');
- var result = await analysisSession.getResolvedUnit(path);
+ var result = await analysisSession.getResolvedUnit(a.path);
result as ResolvedUnitResult;
assertInnerUri(result);
}
// Reference "inner" using the canonical URI, via relative.
{
- var path = '$outerLibPath/inner/lib/c.dart';
- newFile(path, content: r'''
+ var c = newFile('$outerLibPath/inner/lib/c.dart', content: r'''
import 'b.dart';
''');
- var result = await analysisSession.getResolvedUnit(path);
+ var result = await analysisSession.getResolvedUnit(c.path);
result as ResolvedUnitResult;
assertInnerUri(result);
}
// Reference "inner" using the canonical URI, via absolute.
{
- var path = '$outerLibPath/inner/lib/d.dart';
- newFile(path, content: '''
+ var d = newFile('$outerLibPath/inner/lib/d.dart', content: '''
import '$innerUri';
''');
- var result = await analysisSession.getResolvedUnit(path);
+ var result = await analysisSession.getResolvedUnit(d.path);
result as ResolvedUnitResult;
assertInnerUri(result);
}
@@ -3428,10 +3425,6 @@
}
extension on AnalysisDriver {
- FileResult getFileSyncValid(String path) {
- return getFileSync(path) as FileResult;
- }
-
Set<String> get loadedLibraryUriSet {
var elementFactory = this.test.libraryContext!.elementFactory;
var libraryReferences = elementFactory.rootReference.children;
@@ -3453,11 +3446,15 @@
}
}
- Future<ResolvedUnitResult> getResultValid(String path) async {
- return await getResult(path) as ResolvedUnitResult;
+ FileResult getFileSyncValid(String path) {
+ return getFileSync(path) as FileResult;
}
Future<LibraryElementResult> getLibraryByUriValid(String uriStr) async {
return await getLibraryByUri(uriStr) as LibraryElementResult;
}
+
+ Future<ResolvedUnitResult> getResultValid(String path) async {
+ return await getResult(path) as ResolvedUnitResult;
+ }
}
diff --git a/pkg/analyzer/test/src/dart/analysis/search_test.dart b/pkg/analyzer/test/src/dart/analysis/search_test.dart
index 612ac02..91057d0 100644
--- a/pkg/analyzer/test/src/dart/analysis/search_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/search_test.dart
@@ -2400,14 +2400,6 @@
}
extension on List<Declaration> {
- void assertNo(String name) {
- for (var declaration in this) {
- if (declaration.name == name) {
- fail('Unexpected declaration $name');
- }
- }
- }
-
Declaration assertHas(String name, DeclarationKind kind,
{int? offset,
int? codeOffset,
@@ -2432,4 +2424,12 @@
fail('Expected to find (name=$name, kind=$kind, offset=$offset, '
'codeOffset=$codeOffset, codeLength=$codeLength) in\n$actual');
}
+
+ void assertNo(String name) {
+ for (var declaration in this) {
+ if (declaration.name == name) {
+ fail('Unexpected declaration $name');
+ }
+ }
+ }
}
diff --git a/pkg/analyzer/test/src/dart/analysis/session_test.dart b/pkg/analyzer/test/src/dart/analysis/session_test.dart
index 9512475..5a90033 100644
--- a/pkg/analyzer/test/src/dart/analysis/session_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/session_test.dart
@@ -641,40 +641,40 @@
}
extension on AnalysisSession {
- Future<UnitElementResult> getUnitElementValid(String path) async {
- return await getUnitElement(path) as UnitElementResult;
- }
-
- ParsedLibraryResult getParsedLibraryValid(String path) {
- return getParsedLibrary(path) as ParsedLibraryResult;
+ Future<ErrorsResult> getErrorsValid(String path) async {
+ return await getErrors(path) as ErrorsResult;
}
FileResult getFileValid(String path) {
return getFile(path) as FileResult;
}
- ParsedUnitResult getParsedUnitValid(String path) {
- return getParsedUnit(path) as ParsedUnitResult;
- }
-
- Future<ResolvedLibraryResult> getResolvedLibraryValid(String path) async {
- return await getResolvedLibrary(path) as ResolvedLibraryResult;
- }
-
Future<LibraryElementResult> getLibraryByUriValid(String path) async {
return await getLibraryByUri(path) as LibraryElementResult;
}
+ ParsedLibraryResult getParsedLibraryByElementValid(LibraryElement element) {
+ return getParsedLibraryByElement(element) as ParsedLibraryResult;
+ }
+
+ ParsedLibraryResult getParsedLibraryValid(String path) {
+ return getParsedLibrary(path) as ParsedLibraryResult;
+ }
+
+ ParsedUnitResult getParsedUnitValid(String path) {
+ return getParsedUnit(path) as ParsedUnitResult;
+ }
+
Future<ResolvedLibraryResult> getResolvedLibraryByElementValid(
LibraryElement element) async {
return await getResolvedLibraryByElement(element) as ResolvedLibraryResult;
}
- ParsedLibraryResult getParsedLibraryByElementValid(LibraryElement element) {
- return getParsedLibraryByElement(element) as ParsedLibraryResult;
+ Future<ResolvedLibraryResult> getResolvedLibraryValid(String path) async {
+ return await getResolvedLibrary(path) as ResolvedLibraryResult;
}
- Future<ErrorsResult> getErrorsValid(String path) async {
- return await getErrors(path) as ErrorsResult;
+ Future<UnitElementResult> getUnitElementValid(String path) async {
+ return await getUnitElement(path) as UnitElementResult;
}
}
diff --git a/pkg/analyzer/test/src/dart/element/class_element_test.dart b/pkg/analyzer/test/src/dart/element/class_element_test.dart
index c6ed690..9505982 100644
--- a/pkg/analyzer/test/src/dart/element/class_element_test.dart
+++ b/pkg/analyzer/test/src/dart/element/class_element_test.dart
@@ -1331,10 +1331,6 @@
}
extension on ClassElement {
- MethodElement? _lookUpInheritedMethod(String name) {
- return lookUpInheritedMethod(name, library);
- }
-
PropertyAccessorElement? _lookUpInheritedConcreteGetter(String name) {
return lookUpInheritedConcreteGetter(name, library);
}
@@ -1346,4 +1342,8 @@
PropertyAccessorElement? _lookUpInheritedConcreteSetter(String name) {
return lookUpInheritedConcreteSetter(name, library);
}
+
+ MethodElement? _lookUpInheritedMethod(String name) {
+ return lookUpInheritedMethod(name, library);
+ }
}
diff --git a/pkg/analyzer/test/src/test_all.dart b/pkg/analyzer/test/src/test_all.dart
index 9969e39..c6fe9f8 100644
--- a/pkg/analyzer/test/src/test_all.dart
+++ b/pkg/analyzer/test/src/test_all.dart
@@ -4,6 +4,7 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'clients/test_all.dart' as clients;
import 'context/test_all.dart' as context;
import 'dart/test_all.dart' as dart;
import 'dartdoc/test_all.dart' as dartdoc;
@@ -25,6 +26,7 @@
main() {
defineReflectiveSuite(() {
+ clients.main();
context.main();
dart.main();
dartdoc.main();
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
index 31590d0..e235487 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/standard_ast_factory.dart';
import 'package:analyzer/dart/ast/syntactic_entity.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
@@ -413,15 +412,21 @@
}
}
if (token is StringToken) {
- var uri = astFactory.simpleStringLiteral(token, token.lexeme);
- var keyword = containingNode.findPrevious(token)?.keyword;
- if (keyword == Keyword.IMPORT ||
- keyword == Keyword.EXPORT ||
- keyword == Keyword.PART) {
+ final containingNode = this.containingNode;
+ StringLiteral? uri;
+ Directive? directive;
+ if (containingNode is NamespaceDirective) {
+ directive = containingNode;
+ uri = containingNode.uri;
+ } else if (containingNode is SimpleStringLiteral) {
+ uri = containingNode;
+ directive = containingNode.parent.ifTypeOrNull();
+ }
+ // Replacement range for a URI.
+ if (directive != null && uri is SimpleStringLiteral) {
var start = uri.contentsOffset;
var end = uri.contentsEnd;
if (start <= requestOffset && requestOffset <= end) {
- // Replacement range for import URI
return SourceRange(start, end - start);
}
}
@@ -660,3 +665,11 @@
}
}
}
+
+extension on Object? {
+ /// If the target is [T], return it, otherwise `null`.
+ T? ifTypeOrNull<T>() {
+ final self = this;
+ return self is T ? self : null;
+ }
+}
diff --git a/pkg/analyzer_plugin/lib/src/utilities/visitors/local_declaration_visitor.dart b/pkg/analyzer_plugin/lib/src/utilities/visitors/local_declaration_visitor.dart
index c622af3..728782a 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/visitors/local_declaration_visitor.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/visitors/local_declaration_visitor.dart
@@ -3,21 +3,12 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/standard_ast_factory.dart';
-import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
-import 'package:analyzer/src/dart/ast/token.dart';
/// A visitor that visits an [AstNode] and its parent recursively along with any
/// declarations in those nodes. Consumers typically call [visit] which catches
/// the exception thrown by [finished].
abstract class LocalDeclarationVisitor extends GeneralizingAstVisitor {
- static final NamedType STACKTRACE_TYPE = astFactory.namedType(
- name: astFactory.simpleIdentifier(
- StringToken(TokenType.IDENTIFIER, 'StackTrace', 0),
- ),
- );
-
final int offset;
LocalDeclarationVisitor(this.offset);
@@ -81,14 +72,16 @@
@override
void visitCatchClause(CatchClause node) {
- var param = node.exceptionParameter;
- if (param != null) {
- declaredParam(param, node.exceptionType);
+ var exceptionParameter = node.exceptionParameter;
+ if (exceptionParameter != null) {
+ declaredParam(exceptionParameter, node.exceptionType);
}
- param = node.stackTraceParameter;
- if (param != null) {
- declaredParam(param, STACKTRACE_TYPE);
+
+ var stackTraceParameter = node.stackTraceParameter;
+ if (stackTraceParameter != null) {
+ declaredParam(stackTraceParameter, null);
}
+
visitNode(node);
}
diff --git a/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart b/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
index 8d5106f..5ad2871 100644
--- a/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
+++ b/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
@@ -253,6 +253,52 @@
}
@override
+ void visitComment(Comment node) {
+ for (var commentReference in node.references) {
+ commentReference.accept(this);
+ }
+
+ var inToolAnnotation = false;
+ for (var token in node.tokens) {
+ if (token.isEof) {
+ break;
+ }
+ var strValue = token.toString();
+ if (strValue.isEmpty) {
+ continue;
+ }
+
+ if (inToolAnnotation) {
+ if (strValue.contains('{@end-tool}')) {
+ inToolAnnotation = false;
+ } else if (strValue.contains('** See code in ')) {
+ var startIndex = strValue.indexOf('** See code in ') + 15;
+ var endIndex = strValue.indexOf('.dart') + 5;
+ var pathSnippet = strValue.substring(startIndex, endIndex);
+ var parentPath =
+ _computeParentWithExamplesAPI(node, resourceProvider);
+ if (parentPath != null) {
+ computer.collector.addRegion(
+ token.offset + startIndex,
+ token.offset + endIndex,
+ protocol.ElementKind.LIBRARY,
+ protocol.Location(
+ resourceProvider.pathContext.join(parentPath, pathSnippet),
+ 0,
+ 0,
+ 0,
+ 0,
+ endLine: 0,
+ endColumn: 0));
+ }
+ }
+ } else if (strValue.contains('{@tool ')) {
+ inToolAnnotation = true;
+ }
+ }
+ }
+
+ @override
void visitCompilationUnit(CompilationUnit unit) {
// prepare top-level nodes sorted by their offsets
var nodes = <AstNode>[];
@@ -476,4 +522,31 @@
}
}
}
+
+ /// Given some [Comment], compute and return the parent directory absolute
+ /// path which contains the directories 'examples/api/'. Null is returned if
+ /// such directories are not found.
+ String? _computeParentWithExamplesAPI(
+ Comment node, ResourceProvider resourceProvider) {
+ var source =
+ node.thisOrAncestorOfType<CompilationUnit>()?.declaredElement?.source;
+ if (source == null) {
+ return null;
+ }
+
+ var file = resourceProvider.getFile(source.fullName);
+ if (!file.exists) {
+ return null;
+ }
+ var parent = file.parent2;
+ while (parent != parent.parent2) {
+ var examplesFolder = parent.getChildAssumingFolder('examples');
+ if (examplesFolder.exists &&
+ examplesFolder.getChildAssumingFolder('api').exists) {
+ return parent.path;
+ }
+ parent = parent.parent2;
+ }
+ return null;
+ }
}
diff --git a/pkg/analyzer_utilities/lib/check/bool.dart b/pkg/analyzer_utilities/lib/check/bool.dart
index 18d5054..1b13751 100644
--- a/pkg/analyzer_utilities/lib/check/bool.dart
+++ b/pkg/analyzer_utilities/lib/check/bool.dart
@@ -5,15 +5,15 @@
import 'package:analyzer_utilities/check/check.dart';
extension BoolExtension on CheckTarget<bool> {
- void get isTrue {
- if (!value) {
- fail('is not true');
- }
- }
-
void get isFalse {
if (value) {
fail('is not false');
}
}
+
+ void get isTrue {
+ if (!value) {
+ fail('is not true');
+ }
+ }
}
diff --git a/pkg/analyzer_utilities/lib/check/nullability.dart b/pkg/analyzer_utilities/lib/check/nullability.dart
index 3a31513..ef1860e 100644
--- a/pkg/analyzer_utilities/lib/check/nullability.dart
+++ b/pkg/analyzer_utilities/lib/check/nullability.dart
@@ -5,12 +5,6 @@
import 'package:analyzer_utilities/check/check.dart';
extension NullabilityExtension<T> on CheckTarget<T?> {
- void get isNull {
- if (value != null) {
- fail('is not null');
- }
- }
-
CheckTarget<T> get isNotNull {
final value = this.value;
if (value == null) {
@@ -18,4 +12,10 @@
}
return nest(value, (value) => 'is not null');
}
+
+ void get isNull {
+ if (value != null) {
+ fail('is not null');
+ }
+ }
}
diff --git a/pkg/analyzer_utilities/lib/check/string.dart b/pkg/analyzer_utilities/lib/check/string.dart
index 3d80003..75278b8 100644
--- a/pkg/analyzer_utilities/lib/check/string.dart
+++ b/pkg/analyzer_utilities/lib/check/string.dart
@@ -12,12 +12,6 @@
}
}
- void startsWith(Pattern other) {
- if (!value.startsWith(other)) {
- fail('does not start with ${valueStr(other)}');
- }
- }
-
@UseResult.unless(parameterDefined: 'expected')
CheckTarget<int> hasLength([int? expected]) {
var actual = value.length;
@@ -28,4 +22,10 @@
return nest(actual, (length) => 'has length $length');
}
+
+ void startsWith(Pattern other) {
+ if (!value.startsWith(other)) {
+ fail('does not start with ${valueStr(other)}');
+ }
+ }
}
diff --git a/pkg/dart_internal/analysis_options.yaml b/pkg/dart_internal/analysis_options.yaml
index edcd64e..6f7501d 100644
--- a/pkg/dart_internal/analysis_options.yaml
+++ b/pkg/dart_internal/analysis_options.yaml
@@ -1,5 +1,5 @@
analyzer:
errors:
import_internal_library: ignore
- strong-mode:
- implicit-casts: false
+ language:
+ strict-casts: true
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index c8cbcec..b2dce5c 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -4545,13 +4545,14 @@
ElideJSONSubstring("libraries", buffer, buffer);
ElideJSONSubstring("_List@", buffer, buffer);
ElideJSONSubstring("_TypeParameter@", buffer, buffer);
+ StripTokenPositions(buffer);
EXPECT_SUBSTRING(
"{\"type\":\"@Instance\",\"_vmType\":\"Array\",\"class\":{\"type\":\"@"
"Class\",\"fixedId\":true,\"id\":\"\",\"name\":\"_List\",\"_vmName\":"
"\"\",\"location\":{\"type\":\"SourceLocation\",\"script\":{\"type\":"
"\"@Script\",\"fixedId\":true,\"id\":\"\",\"uri\":\"dart:core-patch\\/"
- "array.dart\",\"_kind\":\"kernel\"},\"tokenPos\":248,\"endTokenPos\":"
- "7917},\"library\":{\"type\":\"@Library\",\"fixedId\":true,\"id\":\"\","
+ "array.dart\",\"_kind\":\"kernel\"}},"
+ "\"library\":{\"type\":\"@Library\",\"fixedId\":true,\"id\":\"\","
"\"name\":\"dart.core\",\"uri\":\"dart:core\"},\"typeParameters\":[{"
"\"type\":\"@"
"Instance\",\"_vmType\":\"TypeParameter\",\"class\":{\"type\":\"@"
@@ -4559,8 +4560,8 @@
"vmName\":\"\",\"location\":{\"type\":"
"\"SourceLocation\",\"script\":{\"type\":\"@Script\",\"fixedId\":true,"
"\"id\":\"\",\"uri\":\"dart:core-patch\\/"
- "type_patch.dart\",\"_kind\":\"kernel\"},\"tokenPos\":1749,"
- "\"endTokenPos\":1894},\"library\":{\"type\":\"@Library\",\"fixedId\":"
+ "type_patch.dart\",\"_kind\":\"kernel\"}},"
+ "\"library\":{\"type\":\"@Library\",\"fixedId\":"
"true,\"id\":\"\",\"name\":\"dart.core\",\"uri\":\"dart:core\"}},"
"\"identityHashCode\":",
buffer);
@@ -4572,8 +4573,8 @@
"\"Null\",\"location\":{\"type\":\"SourceLocation\",\"script\":{"
"\"type\":\"@Script\",\"fixedId\":true,\"id\":\"\",\"uri\":\"dart:"
"core\\/"
- "null.dart\",\"_kind\":\"kernel\"},\"tokenPos\":925,\"endTokenPos\":"
- "1165},\"library\":{\"type\":\"@Library\",\"fixedId\":true,\"id\":\"\","
+ "null.dart\",\"_kind\":\"kernel\"}},"
+ "\"library\":{\"type\":\"@Library\",\"fixedId\":true,\"id\":\"\","
"\"name\":\"dart.core\",\"uri\":\"dart:core\"}},\"kind\":\"Null\","
"\"fixedId\":true,\"id\":\"\",\"valueAsString\":\"null\"}}]},"
"\"identityHashCode\":0,\"kind\":\"List\",\"id\":\"\",\"length\":0}",
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 3298b08..c6280c1 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -7125,14 +7125,6 @@
setProperty('grid-column-end', value, '');
}
- /** Gets the value of "grid-column-gap" */
- String get gridColumnGap => getPropertyValue('grid-column-gap');
-
- /** Sets the value of "grid-column-gap" */
- set gridColumnGap(String value) {
- setProperty('grid-column-gap', value, '');
- }
-
/** Gets the value of "grid-column-start" */
String get gridColumnStart => getPropertyValue('grid-column-start');
@@ -7157,14 +7149,6 @@
setProperty('grid-row-end', value, '');
}
- /** Gets the value of "grid-row-gap" */
- String get gridRowGap => getPropertyValue('grid-row-gap');
-
- /** Sets the value of "grid-row-gap" */
- set gridRowGap(String value) {
- setProperty('grid-row-gap', value, '');
- }
-
/** Gets the value of "grid-row-start" */
String get gridRowStart => getPropertyValue('grid-row-start');
diff --git a/tools/VERSION b/tools/VERSION
index 40c1a10..1745e69 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 16
PATCH 0
-PRERELEASE 122
+PRERELEASE 123
PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 388f037..ed2057e 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -547,14 +547,6 @@
"use-sdk": true
}
},
- "dart2js-canary-(linux|mac|win)-chrome": {
- "options": {
- "use-sdk": true,
- "dart2js-options": [
- "--canary"
- ]
- }
- },
"dart2js-(linux|mac|win)-chrome-unsound": {
"options": {
"use-sdk": true,
@@ -699,7 +691,17 @@
"dart2js-canary-(linux|mac|win)-d8": {
"options": {
"builder-tag": "dart2js_canary",
- "use-sdk": true,
+ "host-checked": true,
+ "timeout": 240,
+ "dart2js-options": [
+ "--canary"
+ ]
+ }
+ },
+ "dart2js-canary-(linux|mac|win)-chrome": {
+ "options": {
+ "host-checked": true,
+ "timeout": 240,
"dart2js-options": [
"--canary"
]
diff --git a/tools/dom/scripts/CSSPropertyNames.in b/tools/dom/scripts/CSSPropertyNames.in
index cf59dca..8947335 100644
--- a/tools/dom/scripts/CSSPropertyNames.in
+++ b/tools/dom/scripts/CSSPropertyNames.in
@@ -329,7 +329,6 @@
grid-area
grid-column
grid-column-end
-grid-column-gap
grid-column-start
grid
grid-template
@@ -337,7 +336,6 @@
grid-template-rows
grid-row
grid-row-end
-grid-row-gap
grid-row-start
grid-template-areas
-webkit-highlight
diff --git a/tools/dom/templates/html/impl/impl_CSSStyleDeclaration.darttemplate b/tools/dom/templates/html/impl/impl_CSSStyleDeclaration.darttemplate
index a81ff5a..7aade98 100644
--- a/tools/dom/templates/html/impl/impl_CSSStyleDeclaration.darttemplate
+++ b/tools/dom/templates/html/impl/impl_CSSStyleDeclaration.darttemplate
@@ -3211,15 +3211,6 @@
setProperty('grid-column-end', value, '');
}
- /** Gets the value of "grid-column-gap" */
- String get gridColumnGap =>
- getPropertyValue('grid-column-gap');
-
- /** Sets the value of "grid-column-gap" */
- set gridColumnGap(String value) {
- setProperty('grid-column-gap', value, '');
- }
-
/** Gets the value of "grid-column-start" */
String get gridColumnStart =>
getPropertyValue('grid-column-start');
@@ -3247,15 +3238,6 @@
setProperty('grid-row-end', value, '');
}
- /** Gets the value of "grid-row-gap" */
- String get gridRowGap =>
- getPropertyValue('grid-row-gap');
-
- /** Sets the value of "grid-row-gap" */
- set gridRowGap(String value) {
- setProperty('grid-row-gap', value, '');
- }
-
/** Gets the value of "grid-row-start" */
String get gridRowStart =>
getPropertyValue('grid-row-start');