diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ef801d37685..01e0d697c74c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,11 +59,43 @@ main() { and with a `Flexible` widget. - Offer an assist to "inline" an else-block's inner if-statement with the else-block to read `else if`. +- Add an additional fix to import an unknown prefixed identifier by updating + the `show` combinator on an existing import. +- Add a fix to import an unknown prefixed identifier by adding an + import directive with the given prefix. +- Add a fix to import an unknown prefixed identifier by removing a `hide` + combinator. +- Add a fix to import an unknown identifier by adding an import directive with a + `show` combinator, and optionally a prefix. +- Code completion now suggests instance variables when completing inside the + initializer of a _late_ field. +- Assists and quick fixes that add a const keyword now consider the + `prefer_const_declarations` lint rule, prefering to add `const` to a variable + declaration rather than the initial value. +- Add a fix to add a missing `on` keyword in an extension declaration. +- Add a fix to wrap an ambiguous property access or method call in an extension + override. (Thanks [@FMorschel](https://github.com/FMorschel) for the above enhancements! -- Add the experimental `specify_nonobvious_property_types` lint rule. -- Add the experimental `omit_obvious_property_types` lint rule. -- Remove the `package_api_docs` lint rule. -- Remove the `unsafe_html` lint rule. +- The 'sort members' command now considers the `sort_constructors_first` lint + rule. +- The 'extract method' refactoring now uses generic method syntax for + function-typed parameters. +- Add quick fixes for more than 30 diagnostics. +- Add the [`strict_top_level_inference`] lint rule. +- Add the [`unnecessary_underscores`][] lint rule. +- Add the experimental [`specify_nonobvious_property_types`][] lint rule. +- Add the experimental [`omit_obvious_property_types`][] lint rule. +- Add the experimental [`unsafe_variance`][] lint rule. +- Remove the [`package_api_docs`][] lint rule. +- Remove the [`unsafe_html`][] lint rule. + +[`strict_top_level_inference`]: https://dart.dev/tools/linter-rules/strict_top_level_inference +[`unnecessary_underscores`]: https://dart.dev/lints/unnecessary_underscores +[`specify_nonobvious_property_types`]: https://dart.dev/tools/linter-rules/specify_nonobvious_property_types +[`omit_obvious_property_types`]: https://dart.dev/tools/linter-rules/omit_obvious_property_types +[`unsafe_variance`]: https://dart.dev/tools/linter-rules/unsafe_variance +[`package_api_docs`]: https://dart.dev/tools/linter-rules/package_api_docs +[`unsafe_html`]: https://dart.dev/tools/linter-rules/unsafe_html #### Dart format diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart index 8014e350434c..e874b72dca15 100644 --- a/pkg/analysis_server/lib/src/analysis_server.dart +++ b/pkg/analysis_server/lib/src/analysis_server.dart @@ -698,7 +698,19 @@ abstract class AnalysisServer { if (node is StringLiteral && node.parent is UriBasedDirective) { return null; } - var element = ElementLocator.locate(node); + + Element? element; + switch (node) { + case ExportDirective(): + element = node.element; + case ImportDirective(): + element = node.element; + case PartOfDirective(): + element = node.element; + default: + element = ElementLocator.locate2(node).asElement; + } + if (node is SimpleIdentifier && element is PrefixElement) { element = getImportElement(node); } diff --git a/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_imports.dart b/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_imports.dart index 02c498a6666c..ac6057617cbb 100644 --- a/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_imports.dart +++ b/pkg/analysis_server/lib/src/lsp/handlers/custom/handler_imports.dart @@ -69,17 +69,17 @@ class ImportsHandler return success(null); } - String? prefix; + String? prefixName; if (node is NamedType) { - prefix = node.importPrefix?.name.lexeme; + prefixName = node.importPrefix?.name.lexeme; } else if (node.thisOrAncestorOfType() - case PrefixedIdentifier identifier) { - prefix = identifier.prefix.name; + case PrefixedIdentifier(:var prefix) when prefix != node) { + prefixName = prefix.name; } else if (node is SimpleIdentifier) { if (node.parent case MethodInvocation( target: SimpleIdentifier target?, )) { - prefix = target.toString(); + prefixName = target.toString(); } } @@ -88,7 +88,7 @@ class ImportsHandler element = enclosingElement; } - var locations = _getImportLocations(library, unit, element, prefix); + var locations = _getImportLocations(library, unit, element, prefixName); return success(nullIfEmpty(locations)); }); diff --git a/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml b/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml index 25eae6ca7274..11c411a6d52b 100644 --- a/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml +++ b/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml @@ -2401,6 +2401,10 @@ LintCode.unintended_html_in_doc_comment: status: needsFix notes: |- The fix is to encode the angle brackets. +LintCode.unnecessary_async: + status: needsFix + notes: |- + And probably also quick assist that works even if returns `Future`. LintCode.unnecessary_await_in_return: status: hasFix LintCode.unnecessary_brace_in_string_interps: diff --git a/pkg/analysis_server/test/lsp/import_test.dart b/pkg/analysis_server/test/lsp/import_test.dart index 3ccc01ad99db..02b090515b2d 100644 --- a/pkg/analysis_server/test/lsp/import_test.dart +++ b/pkg/analysis_server/test/lsp/import_test.dart @@ -79,7 +79,7 @@ void foo() { } Future test_import_double() async { - newFile('/home/my_project/lib/other.dart', ''' + newFile(join(projectFolderPath, 'lib', 'other.dart'), ''' export 'dart:math'; '''); await _verifyGoToImports( @@ -93,10 +93,10 @@ Rando^m? r; } Future test_import_double_ambiguous() async { - newFile('/home/my_project/lib/a1.dart', ''' + newFile(join(projectFolderPath, 'lib', 'a1.dart'), ''' class A {} '''); - newFile('/home/my_project/lib/a2.dart', ''' + newFile(join(projectFolderPath, 'lib', 'a2.dart'), ''' class A {} '''); await _verifyGoToImports( @@ -111,10 +111,10 @@ class A {} } Future test_import_double_hide() async { - newFile('/home/my_project/lib/a1.dart', ''' + newFile(join(projectFolderPath, 'lib', 'a1.dart'), ''' class A {} '''); - newFile('/home/my_project/lib/a2.dart', ''' + newFile(join(projectFolderPath, 'lib', 'a2.dart'), ''' class A {} '''); await _verifyGoToImports( @@ -128,7 +128,7 @@ import 'a1.dart' hide A; } Future test_import_double_same_different_alias() async { - newFile('/home/my_project/lib/other.dart', ''' + newFile(join(projectFolderPath, 'lib', 'other.dart'), ''' export 'dart:math'; '''); await _verifyGoToImports( @@ -142,7 +142,7 @@ other.Rando^m? r; } Future test_import_double_same_different_alias_prefix() async { - newFile('/home/my_project/lib/other.dart', ''' + newFile(join(projectFolderPath, 'lib', 'other.dart'), ''' export 'dart:math'; '''); await _verifyGoToImports( @@ -156,12 +156,12 @@ other.Ran^dom? r; } Future test_import_double_show() async { - newFile('/home/my_project/lib/a1.dart', ''' + newFile(join(projectFolderPath, 'lib', 'a1.dart'), ''' class A {} class B {} '''); - newFile('/home/my_project/lib/a2.dart', ''' + newFile(join(projectFolderPath, 'lib', 'a2.dart'), ''' class A {} '''); await _verifyGoToImports( @@ -175,10 +175,10 @@ import 'a1.dart' show B; } Future test_import_double_unambiguous_aliased() async { - newFile('/home/my_project/lib/a1.dart', ''' + newFile(join(projectFolderPath, 'lib', 'a1.dart'), ''' class A {} '''); - newFile('/home/my_project/lib/a2.dart', ''' + newFile(join(projectFolderPath, 'lib', 'a2.dart'), ''' class A {} '''); await _verifyGoToImports( @@ -371,7 +371,7 @@ math.Rando^m? r; } Future test_import_single_exported() async { - newFile('/home/my_project/lib/other.dart', ''' + newFile(join(projectFolderPath, 'lib', 'other.dart'), ''' export 'dart:math'; '''); await _verifyGoToImports( @@ -397,7 +397,7 @@ class LocalClass {} } Future test_nestedInvocations() async { - newFile('/home/my_project/lib/other.dart', ''' + newFile(join(projectFolderPath, 'lib', 'other.dart'), ''' class A { const A(); A foo() => A(); @@ -414,7 +414,7 @@ var a = A().foo().ba^r(); } Future test_nestedInvocations_extension() async { - newFile('/home/my_project/lib/other.dart', ''' + newFile(join(projectFolderPath, 'lib', 'other.dart'), ''' extension E on int { void bar() {} } @@ -428,6 +428,36 @@ var a = 1.abs().ba^r(); ); } + Future test_staticDeclarations() async { + newFile(join(projectFolderPath, 'lib', 'other.dart'), ''' +class A { + static const a = 1; +} +'''); + await _verifyGoToImports( + TestCode.parse(''' +[!import 'other.dart';!] + +var a = A^.a; +'''), + ); + } + + Future test_staticDeclarations_prefixed() async { + newFile(join(projectFolderPath, 'lib', 'other.dart'), ''' +class A { + static const a = 1; +} +'''); + await _verifyGoToImports( + TestCode.parse(''' +[!import 'other.dart' as o;!] + +var a = o.A^.a; +'''), + ); + } + Future _verifyGoToImports( TestCode code, { Uri? fileUri, diff --git a/pkg/analysis_server/test/services/refactoring/legacy/abstract_rename.dart b/pkg/analysis_server/test/services/refactoring/legacy/abstract_rename.dart index 10fac2c896bd..24d4a6849b8a 100644 --- a/pkg/analysis_server/test/services/refactoring/legacy/abstract_rename.dart +++ b/pkg/analysis_server/test/services/refactoring/legacy/abstract_rename.dart @@ -8,6 +8,7 @@ import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/element2.dart'; import 'package:analyzer/src/dart/ast/element_locator.dart'; +import 'package:analyzer/src/utilities/extensions/element.dart'; import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element; import 'package:test/test.dart'; @@ -41,11 +42,24 @@ class RenameRefactoringTest extends RefactoringTest { /// Creates a new [RenameRefactoring] in [refactoring] for the [Element] of /// the [SimpleIdentifier] at the given [search] pattern. void createRenameRefactoringAtString(String search) { - var identifier = findNode.any(search); - var element = ElementLocator.locate(identifier); - if (identifier is SimpleIdentifier && element is PrefixElement) { - element = getImportElement(identifier); + var node = findNode.any(search); + + Element? element; + switch (node) { + case ExportDirective(): + element = node.element; + case ImportDirective(): + element = node.element; + case PartOfDirective(): + element = node.element; + default: + element = ElementLocator.locate2(node).asElement; + } + + if (node is SimpleIdentifier && element is PrefixElement) { + element = getImportElement(node); } + createRenameRefactoringForElement(element); } diff --git a/pkg/analyzer/analyzer_use_new_elements.txt b/pkg/analyzer/analyzer_use_new_elements.txt index 087f1d0a8e41..d29932ec570e 100644 --- a/pkg/analyzer/analyzer_use_new_elements.txt +++ b/pkg/analyzer/analyzer_use_new_elements.txt @@ -18,7 +18,6 @@ lib/src/dart/analysis/search.dart lib/src/dart/analysis/session.dart lib/src/dart/analysis/session_helper.dart lib/src/dart/ast/ast.dart -lib/src/dart/ast/element_locator.dart lib/src/dart/ast/extensions.dart lib/src/dart/ast/utilities.dart lib/src/dart/constant/constant_verifier.dart @@ -147,7 +146,6 @@ test/generated/elements_types_mixin.dart test/generated/non_error_resolver_test.dart test/generated/resolver_test_case.dart test/generated/type_system_test.dart -test/id_tests/type_constraint_generation_test.dart test/src/dart/analysis/index_test.dart test/src/dart/analysis/result_printer.dart test/src/dart/analysis/results/get_element_declaration_test.dart diff --git a/pkg/analyzer/lib/src/dart/ast/element_locator.dart b/pkg/analyzer/lib/src/dart/ast/element_locator.dart index 4c321ed66bce..24b7dde72e2a 100644 --- a/pkg/analyzer/lib/src/dart/ast/element_locator.dart +++ b/pkg/analyzer/lib/src/dart/ast/element_locator.dart @@ -4,21 +4,11 @@ import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/ast/visitor.dart'; -import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/element2.dart'; import 'package:analyzer/src/dart/ast/extensions.dart'; -/// An object used to locate the [Element] associated with a given [AstNode]. +/// An object used to locate the [Element2] associated with a given [AstNode]. class ElementLocator { - /// Return the element associated with the given [node], or `null` if there - /// is no element associated with the node. - static Element? locate(AstNode? node) { - if (node == null) return null; - - var mapper = _ElementMapper(); - return node.accept(mapper); - } - /// Return the element associated with the given [node], or `null` if there /// is no element associated with the node. static Element2? locate2(AstNode? node) { @@ -29,277 +19,6 @@ class ElementLocator { } } -/// Visitor that maps nodes to elements. -class _ElementMapper extends GeneralizingAstVisitor { - @override - Element? visitAnnotation(Annotation node) { - return node.element; - } - - @override - Element? visitAssignedVariablePattern(AssignedVariablePattern node) { - return node.element; - } - - @override - Element? visitAssignmentExpression(AssignmentExpression node) { - return node.staticElement; - } - - @override - Element? visitBinaryExpression(BinaryExpression node) { - return node.staticElement; - } - - @override - Element? visitClassDeclaration(ClassDeclaration node) { - return node.declaredElement; - } - - @override - Element? visitClassTypeAlias(ClassTypeAlias node) { - return node.declaredElement; - } - - @override - Element? visitCompilationUnit(CompilationUnit node) { - return node.declaredElement; - } - - @override - Element? visitConstructorDeclaration(ConstructorDeclaration node) { - return node.declaredElement; - } - - @override - Element? visitConstructorSelector(ConstructorSelector node) { - var parent = node.parent; - if (parent is EnumConstantArguments) { - var parent2 = parent.parent; - if (parent2 is EnumConstantDeclaration) { - return parent2.constructorElement; - } - } - return null; - } - - @override - Element? visitDeclaredIdentifier(DeclaredIdentifier node) { - return node.declaredElement; - } - - @override - Element? visitDeclaredVariablePattern(DeclaredVariablePattern node) { - return node.declaredElement; - } - - @override - Element? visitEnumConstantDeclaration(EnumConstantDeclaration node) { - return node.declaredElement; - } - - @override - Element? visitEnumDeclaration(EnumDeclaration node) { - return node.declaredElement; - } - - @override - Element? visitExportDirective(ExportDirective node) { - return node.element; - } - - @override - Element? visitExtensionDeclaration(ExtensionDeclaration node) { - return node.declaredElement; - } - - @override - Element? visitExtensionOverride(ExtensionOverride node) { - return node.element; - } - - @override - Element? visitExtensionTypeDeclaration(ExtensionTypeDeclaration node) { - return node.declaredElement; - } - - @override - Element? visitFormalParameter(FormalParameter node) { - return node.declaredElement; - } - - @override - Element? visitFunctionDeclaration(FunctionDeclaration node) { - return node.declaredElement; - } - - @override - Element? visitFunctionTypeAlias(FunctionTypeAlias node) { - return node.declaredElement; - } - - @override - Element? visitGenericTypeAlias(GenericTypeAlias node) { - return node.declaredElement; - } - - @override - Element? visitIdentifier(Identifier node) { - var parent = node.parent; - if (parent is Annotation) { - // Type name in Annotation - if (identical(parent.name, node) && parent.constructorName == null) { - return parent.element; - } - } else if (parent is ConstructorDeclaration) { - // Extra work to map Constructor Declarations to their associated - // Constructor Elements - var returnType = parent.returnType; - if (identical(returnType, node)) { - var name = parent.name; - if (name != null) { - return parent.declaredElement; - } - var element = node.staticElement; - if (element is InterfaceElement) { - return element.unnamedConstructor; - } - } else if (parent.name == node.endToken) { - return parent.declaredElement; - } - } else if (parent is LibraryIdentifier) { - var grandParent = parent.parent; - if (grandParent is PartOfDirective) { - var element = grandParent.element; - if (element is LibraryElement) { - return element.definingCompilationUnit; - } - } else if (grandParent is LibraryDirective) { - return grandParent.element; - } - } - return node.writeOrReadElement; - } - - @override - Element? visitImportDirective(ImportDirective node) { - return node.element; - } - - @override - Element? visitImportPrefixReference(ImportPrefixReference node) { - return node.element; - } - - @override - Element? visitIndexExpression(IndexExpression node) { - return node.staticElement; - } - - @override - Element? visitInstanceCreationExpression(InstanceCreationExpression node) { - return node.constructorName.staticElement; - } - - @override - Element? visitLibraryDirective(LibraryDirective node) { - return node.element; - } - - @override - Element? visitMethodDeclaration(MethodDeclaration node) { - return node.declaredElement; - } - - @override - Element? visitMethodInvocation(MethodInvocation node) { - return node.methodName.staticElement; - } - - @override - Element? visitMixinDeclaration(MixinDeclaration node) { - return node.declaredElement; - } - - @override - Element? visitNamedType(NamedType node) { - return node.element; - } - - @override - Element? visitPartOfDirective(PartOfDirective node) { - return node.element; - } - - @override - Element? visitPatternField(PatternField node) { - return node.element; - } - - @override - Element? visitPatternFieldName(PatternFieldName node) { - var parent = node.parent; - if (parent is PatternField) { - return parent.element; - } else { - return null; - } - } - - @override - Element? visitPostfixExpression(PostfixExpression node) { - return node.staticElement; - } - - @override - Element? visitPrefixedIdentifier(PrefixedIdentifier node) { - return node.staticElement; - } - - @override - Element? visitPrefixExpression(PrefixExpression node) { - return node.staticElement; - } - - @override - Element? visitRepresentationConstructorName( - RepresentationConstructorName node) { - var representation = node.parent as RepresentationDeclaration; - return representation.constructorElement; - } - - @override - Element? visitRepresentationDeclaration(RepresentationDeclaration node) { - return node.fieldElement; - } - - @override - Element? visitStringLiteral(StringLiteral node) { - var parent = node.parent; - if (parent is ExportDirective) { - return parent.element?.exportedLibrary; - } else if (parent is ImportDirective) { - return parent.element?.importedLibrary; - } else if (parent is PartDirective) { - var elementUri = parent.element?.uri; - if (elementUri is DirectiveUriWithUnit) { - return elementUri.unit; - } - } - return null; - } - - @override - Element? visitTypeParameter(TypeParameter node) { - return node.declaredElement; - } - - @override - Element? visitVariableDeclaration(VariableDeclaration node) { - return node.declaredElement; - } -} - /// Visitor that maps nodes to elements. class _ElementMapper2 extends GeneralizingAstVisitor { @override diff --git a/pkg/analyzer/lib/src/dart/micro/utils.dart b/pkg/analyzer/lib/src/dart/micro/utils.dart index 4be404e3b23f..f762550dd3ed 100644 --- a/pkg/analyzer/lib/src/dart/micro/utils.dart +++ b/pkg/analyzer/lib/src/dart/micro/utils.dart @@ -24,7 +24,19 @@ Element? getElementOfNode(AstNode? node) { if (node is StringLiteral && node.parent is UriBasedDirective) { return null; } - var element = ElementLocator.locate(node); + + Element? element; + switch (node) { + case ExportDirective(): + element = node.element; + case ImportDirective(): + element = node.element; + case PartOfDirective(): + element = node.element; + default: + element = ElementLocator.locate2(node).asElement; + } + if (node is SimpleIdentifier && element is PrefixElement) { var parent = node.parent; if (parent is ImportDirective) { @@ -33,6 +45,7 @@ Element? getElementOfNode(AstNode? node) { element = _getImportElementInfo(node); } } + return element; } diff --git a/pkg/analyzer/lib/src/dart/resolver/body_inference_context.dart b/pkg/analyzer/lib/src/dart/resolver/body_inference_context.dart index d4e17b437281..d91149fdf8ea 100644 --- a/pkg/analyzer/lib/src/dart/resolver/body_inference_context.dart +++ b/pkg/analyzer/lib/src/dart/resolver/body_inference_context.dart @@ -26,6 +26,14 @@ class BodyInferenceContext { /// Types of all `return` or `yield` statements in the body. final List _returnTypes = []; + /// Whether the execution flow can reach the end of the body. + /// + /// For example here, because there is no `return` at the end. + /// ``` + /// void f() {} + /// ``` + bool mayCompleteNormally = true; + factory BodyInferenceContext({ required TypeSystemImpl typeSystem, required FunctionBodyImpl node, diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart index c020b9695bb2..d167b5d0ff89 100644 --- a/pkg/analyzer/lib/src/generated/resolver.dart +++ b/pkg/analyzer/lib/src/generated/resolver.dart @@ -543,14 +543,16 @@ class ResolverVisitor extends ThrowingAstVisitor required FunctionBodyImpl body, required SyntacticEntity errorNode, }) { - if (!flowAnalysis.flow!.isReachable) { + var bodyContext = body.bodyContext; + if (bodyContext == null) { return; } - var bodyContext = body.bodyContext; - if (bodyContext == null) { + if (!flowAnalysis.flow!.isReachable) { + bodyContext.mayCompleteNormally = false; return; } + var returnType = bodyContext.contextType; if (returnType == null) { if (errorNode is BlockFunctionBody) { diff --git a/pkg/analyzer/test/id_tests/type_constraint_generation_test.dart b/pkg/analyzer/test/id_tests/type_constraint_generation_test.dart index 7e888cb6ac63..aff9cef1557c 100644 --- a/pkg/analyzer/test/id_tests/type_constraint_generation_test.dart +++ b/pkg/analyzer/test/id_tests/type_constraint_generation_test.dart @@ -41,8 +41,8 @@ class _TypeConstraintGenerationDataComputer Map>> actualMap) { _TypeConstraintGenerationDataExtractor( testingData.uriToTypeConstraintGenerationData[ - unit.declaredElement!.source.uri]!, - unit.declaredElement!.source.uri, + unit.declaredFragment?.source.uri]!, + unit.declaredFragment!.source.uri, actualMap) .run(unit); } diff --git a/pkg/analyzer/test/src/dart/ast/element_locator_test.dart b/pkg/analyzer/test/src/dart/ast/element_locator_test.dart index 34c5624e51d9..5868c17597fa 100644 --- a/pkg/analyzer/test/src/dart/ast/element_locator_test.dart +++ b/pkg/analyzer/test/src/dart/ast/element_locator_test.dart @@ -2,7 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/element2.dart'; import 'package:analyzer/src/dart/ast/element_locator.dart'; import 'package:analyzer_utilities/testing/tree_string_sink.dart'; @@ -15,583 +14,11 @@ import '../resolution/node_text_expectations.dart'; main() { defineReflectiveSuite(() { - defineReflectiveTests(ElementLocatorTest); defineReflectiveTests(ElementLocatorTest2); defineReflectiveTests(UpdateNodeTextExpectations); }); } -@reflectiveTest -class ElementLocatorTest extends PubPackageResolutionTest { - test_locate_AssignedVariablePattern() async { - await resolveTestCode(r''' -void f() { - int foo; - (foo, _) = (0, 1); -} -'''); - var node = findNode.assignedVariablePattern('foo,'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -foo@17 -'''); - } - - test_locate_AssignmentExpression() async { - await resolveTestCode(r''' -int x = 0; -void main() { - x += 1; -} -'''); - var node = findNode.assignment('+='); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -dart:core::::@class::num::@method::+ -'''); - } - - test_locate_BinaryExpression() async { - await resolveTestCode('var x = 3 + 4'); - var node = findNode.binary('+'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -dart:core::::@class::num::@method::+ -'''); - } - - test_locate_ClassDeclaration() async { - await resolveTestCode('class A {}'); - var node = findNode.classDeclaration('class'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -::@class::A -'''); - } - - test_locate_CompilationUnit() async { - await resolveTestCode('// only comment'); - - var element = ElementLocator.locate(result.unit); - _assertElement(element, r''' - -'''); - } - - test_locate_ConstructorDeclaration_named() async { - await resolveTestCode(r''' -class A { - A.foo(); -} -'''); - var node = findNode.constructor('A.foo()'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -::@class::A::@constructor::foo -'''); - } - - test_locate_ConstructorDeclaration_unnamed() async { - await resolveTestCode(r''' -class A { - A(); -} -'''); - var node = findNode.constructor('A()'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -::@class::A::@constructor::new -'''); - } - - test_locate_ConstructorSelector_EnumConstantArguments_EnumConstantDeclaration() async { - await resolveTestCode(r''' -enum E { - v.named(); // 0 - const E.named(); -} -'''); - var node = findNode.constructorSelector('named(); // 0'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -::@enum::E::@constructor::named -'''); - } - - test_locate_DeclaredVariablePattern() async { - await resolveTestCode(r''' -void f(Object? x) { - if (x case int foo) {} -} -'''); - var node = findNode.declaredVariablePattern('foo'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -foo@37 -'''); - } - - test_locate_EnumConstantDeclaration() async { - await resolveTestCode(r''' -enum E { - one -} -'''); - var node = findNode.enumConstantDeclaration('one'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -::@enum::E::@field::one -'''); - } - - test_locate_ExportDirective() async { - await resolveTestCode("export 'dart:core';"); - var node = findNode.export('export'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -LibraryExportElement - uri: DirectiveUriWithLibrary - uri: dart:core -'''); - } - - test_locate_ExtensionDeclaration() async { - await resolveTestCode('extension A on int {}'); - var node = findNode.singleExtensionDeclaration; - var element = ElementLocator.locate(node); - _assertElement(element, r''' -::@extension::A -'''); - } - - test_locate_ExtensionTypeDeclaration() async { - await resolveTestCode('extension type A(int it) {}'); - var node = findNode.singleExtensionTypeDeclaration; - var element = ElementLocator.locate(node); - _assertElement(element, r''' -::@extensionType::A -'''); - } - - test_locate_FunctionDeclaration() async { - await resolveTestCode('int f() => 3;'); - var node = findNode.functionDeclaration('f'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -::@function::f -'''); - } - - test_locate_Identifier_annotationClass_namedConstructor() async { - await resolveTestCode(r''' -class Class { - const Class.name(); -} -void main(@Class.name() parameter) {} -'''); - var node = findNode.simple('Class.name() parameter'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -::@class::Class -'''); - } - - test_locate_Identifier_annotationClass_unnamedConstructor() async { - await resolveTestCode(r''' -class Class { - const Class(); -} -void main(@Class() parameter) {} -'''); - var node = findNode.simple('Class() parameter'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -::@class::Class::@constructor::new -'''); - } - - test_locate_Identifier_className() async { - await resolveTestCode('class A {}'); - var node = findNode.classDeclaration('A'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -::@class::A -'''); - } - - test_locate_Identifier_constructor_named() async { - await resolveTestCode(r''' -class A { - A.bar(); -} -'''); - var node = findNode.constructor('bar'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -::@class::A::@constructor::bar -'''); - } - - test_locate_Identifier_constructor_unnamed() async { - await resolveTestCode(r''' -class A { - A(); -} -'''); - var node = findNode.simple('A()'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -::@class::A::@constructor::new -'''); - } - - test_locate_Identifier_fieldName() async { - await resolveTestCode(''' -class A { - var x; -} -'''); - var node = findNode.variableDeclaration('x;'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -::@class::A::@field::x -'''); - } - - test_locate_Identifier_libraryDirective() async { - await resolveTestCode('library foo.bar;'); - var node = findNode.simple('foo'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' - -'''); - } - - test_locate_Identifier_propertyAccess() async { - await resolveTestCode(r''' -void main() { - int x = 'foo'.length; -} -'''); - var node = findNode.simple('length'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -dart:core::::@class::String::@getter::length -'''); - } - - test_locate_ImportDirective() async { - await resolveTestCode("import 'dart:core';"); - var node = findNode.import('import'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -LibraryImportElement - uri: DirectiveUriWithLibrary - uri: dart:core -'''); - } - - test_locate_IndexExpression() async { - await resolveTestCode(r''' -void main() { - var x = [1, 2]; - var y = x[0]; -} -'''); - var node = findNode.index('[0]'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -MethodMember - base: dart:core::::@class::List::@method::[] - substitution: {E: int} -'''); - } - - test_locate_InstanceCreationExpression() async { - await resolveTestCode(r''' -class A {} - -void main() { - new A(); -} -'''); - var node = findNode.instanceCreation('new A()'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -::@class::A::@constructor::new -'''); - } - - test_locate_InstanceCreationExpression_type_prefixedIdentifier() async { - newFile('$testPackageLibPath/a.dart', r''' -class A {} -'''); - await resolveTestCode(r''' -import 'a.dart' as pref; - -void main() { - new pref.A(); -} -'''); - var node = findNode.instanceCreation('A();'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -package:test/a.dart::::@class::A::@constructor::new -'''); - } - - test_locate_InstanceCreationExpression_type_simpleIdentifier() async { - newFile('$testPackageLibPath/a.dart', r''' -'''); - await resolveTestCode(r''' -class A {} - -void main() { - new A(); -} -'''); - var node = findNode.instanceCreation('A();'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -::@class::A::@constructor::new -'''); - } - - test_locate_LibraryDirective() async { - await resolveTestCode('library foo;'); - var node = findNode.library('library'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' - -'''); - } - - test_locate_MethodDeclaration() async { - await resolveTestCode(r''' -class A { - void foo() {} -} -'''); - var node = findNode.methodDeclaration('foo'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -::@class::A::@method::foo -'''); - } - - test_locate_MethodInvocation_method() async { - await resolveTestCode(r''' -class A { - void foo() {} -} - -void main() { - new A().foo(); -} -'''); - var node = findNode.methodInvocation('foo();'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -::@class::A::@method::foo -'''); - } - - test_locate_MethodInvocation_topLevel() async { - await resolveTestCode(r''' -foo(x) {} - -void main() { - foo(0); -} -'''); - var node = findNode.methodInvocation('foo(0)'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -::@function::foo -'''); - } - - test_locate_MixinDeclaration() async { - await resolveTestCode('mixin A {}'); - var node = findNode.singleMixinDeclaration; - var element = ElementLocator.locate(node); - _assertElement(element, r''' -::@mixin::A -'''); - } - - test_locate_PartOfDirective_withName() async { - var libFile = newFile('$testPackageLibPath/lib.dart', r''' -library my.lib; -part 'test.dart'; -'''); - - var partFile = newFile('$testPackageLibPath/test.dart', r''' -part of my.lib; -'''); - - await resolveFile(libFile); - - await resolveFile2(partFile); - var node = findNode.partOf('part of'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -package:test/lib.dart -'''); - } - - test_locate_PatternField() async { - await resolveTestCode(r''' -void f(Object? x) { - if (x case int(isEven: true)) {} -} -'''); - var node = findNode.patternField('isEven:'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -dart:core::::@class::int::@getter::isEven -'''); - } - - test_locate_PostfixExpression() async { - await resolveTestCode('int addOne(int x) => x++;'); - var node = findNode.postfix('x++'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -dart:core::::@class::num::@method::+ -'''); - } - - test_locate_Prefix() async { - await resolveTestCode(r''' -import 'dart:math' as math; - -math.Random? r; -'''); - var node = findNode.importPrefixReference('math.Random'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -::@prefix::math -'''); - } - - test_locate_PrefixedIdentifier() async { - await resolveTestCode(r''' -void f(int a) { - a.isEven; -} -'''); - var node = findNode.prefixed('a.isEven'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -dart:core::::@class::int::@getter::isEven -'''); - } - - test_locate_PrefixExpression() async { - await resolveTestCode('int addOne(int x) => ++x;'); - var node = findNode.prefix('++x'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -dart:core::::@class::num::@method::+ -'''); - } - - test_locate_RepresentationDeclaration() async { - await resolveTestCode('extension type A(int it) {}'); - var node = findNode.singleRepresentationDeclaration; - var element = ElementLocator.locate(node); - _assertElement(element, r''' -::@extensionType::A::@field::it -'''); - } - - test_locate_RepresentationDeclaration2() async { - await resolveTestCode('extension type A.named(int it) {}'); - var node = findNode.singleRepresentationConstructorName; - var element = ElementLocator.locate(node); - _assertElement(element, r''' -::@extensionType::A::@constructor::named -'''); - } - - test_locate_StringLiteral_exportUri() async { - newFile("$testPackageLibPath/foo.dart", ''); - await resolveTestCode("export 'foo.dart';"); - var node = findNode.stringLiteral('foo.dart'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -package:test/foo.dart -'''); - } - - test_locate_StringLiteral_expression() async { - await resolveTestCode("var x = 'abc';"); - var node = findNode.stringLiteral('abc'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' - -'''); - } - - test_locate_StringLiteral_importUri() async { - newFile("$testPackageLibPath/foo.dart", ''); - await resolveTestCode("import 'foo.dart';"); - var node = findNode.stringLiteral('foo.dart'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -package:test/foo.dart -'''); - } - - test_locate_StringLiteral_partUri() async { - newFile("$testPackageLibPath/foo.dart", 'part of lib;'); - await resolveTestCode(''' -library lib; - -part 'foo.dart'; -'''); - var node = findNode.stringLiteral('foo.dart'); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -::@fragment::package:test/foo.dart -'''); - } - - test_locate_VariableDeclaration() async { - await resolveTestCode('var x = 42;'); - var node = findNode.variableDeclaration('x ='); - var element = ElementLocator.locate(node); - _assertElement(element, r''' -::@topLevelVariable::x -'''); - } - - void _assertElement(Element? element, String expected) { - var buffer = StringBuffer(); - - var sink = TreeStringSink( - sink: buffer, - indent: '', - ); - - var elementPrinter = ElementPrinter( - sink: sink, - configuration: ElementPrinterConfiguration(), - ); - - elementPrinter.writeElement(element); - - var actual = buffer.toString(); - if (actual != expected) { - print('-------- Actual --------'); - print('$actual------------------------'); - NodeTextExpectationsCollector.add(actual); - } - expect(actual, expected); - } -} - @reflectiveTest class ElementLocatorTest2 extends PubPackageResolutionTest { test_locate_AssignedVariablePattern() async { diff --git a/pkg/analyzer_plugin/test/support/abstract_single_unit.dart b/pkg/analyzer_plugin/test/support/abstract_single_unit.dart index b8bbcbfb862d..25a0d2702f20 100644 --- a/pkg/analyzer_plugin/test/support/abstract_single_unit.dart +++ b/pkg/analyzer_plugin/test/support/abstract_single_unit.dart @@ -12,6 +12,7 @@ import 'package:analyzer/src/error/codes.dart'; import 'package:analyzer/src/test_utilities/find_element.dart'; import 'package:analyzer/src/test_utilities/find_element2.dart'; import 'package:analyzer/src/test_utilities/find_node.dart'; +import 'package:analyzer/src/utilities/extensions/element.dart'; import 'package:test/test.dart'; import 'abstract_context.dart'; @@ -69,7 +70,17 @@ class AbstractSingleUnitTest extends AbstractContextTest { if (node == null) { return null; } - return ElementLocator.locate(node); + + switch (node) { + case ExportDirective(): + return node.element; + case ImportDirective(): + return node.element; + case PartOfDirective(): + return node.element; + default: + return ElementLocator.locate2(node).asElement; + } } int findOffset(String search) { diff --git a/pkg/dev_compiler/lib/src/kernel/compiler_new.dart b/pkg/dev_compiler/lib/src/kernel/compiler_new.dart index e7d3106156d6..8b7838a8fc52 100644 --- a/pkg/dev_compiler/lib/src/kernel/compiler_new.dart +++ b/pkg/dev_compiler/lib/src/kernel/compiler_new.dart @@ -1236,12 +1236,32 @@ class LibraryCompiler extends ComputeOnceConstantVisitor var jsCtors = _defineConstructors(c, className); var jsProperties = _emitClassProperties(c); + var jsStaticMethodTypeTags = []; + for (var member in c.procedures) { + // TODO(#57049): We tag all static members because we don't know if + // they've been changed after a hot reload. This won't be necessary if we + // can tag them during the delta diff phase. + if (member.isStatic && _reifyTearoff(member) && !member.isExternal) { + var propertyAccessor = _emitStaticTarget(member); + var result = js.call( + '#.#', [propertyAccessor.receiver, propertyAccessor.selector]); + // We only need to tag static functions that are torn off at + // compile-time. We attach these at late so tearoffs have access to + // their types. + var reifiedType = member.function + .computeThisFunctionType(member.enclosingLibrary.nonNullable); + jsStaticMethodTypeTags.add( + _emitFunctionTagged(result, reifiedType, asLazy: true) + .toStatement()); + } + } _emitSuperHelperSymbols(body); // Emit the class, e.g. `core.Object = class Object { ... }` _defineClass(c, className, jsProperties, body); body.addAll(jsCtors); + body.addAll(jsStaticMethodTypeTags); // Emit things that come after the ES6 `class ... { ... }`. @@ -2473,7 +2493,6 @@ class LibraryCompiler extends ComputeOnceConstantVisitor } else { method.sourceInformation = _nodeEnd(member.fileEndOffset); } - return method; } @@ -3454,10 +3473,23 @@ class LibraryCompiler extends ComputeOnceConstantVisitor .where((p) => !p.isExternal && !p.isAbstract && !_isStaticInteropTearOff(p)) .toList(); - _moduleItems.addAll(procedures - .where((p) => !p.isAccessor) - .map(_emitLibraryFunction) - .toList()); + for (var p in procedures) { + if (!p.isAccessor) { + _moduleItems.add(_emitLibraryFunction(p)); + } + // TODO(#57049): We tag all static members because we don't know if + // they've been changed after a hot reload. This won't be necessary if we + // can tag them during the delta diff phase. + if (p.isStatic && _reifyTearoff(p) && !p.isExternal) { + var nameExpr = _emitTopLevelName(p); + _moduleItems.add(_emitFunctionTagged( + nameExpr, + p.function + .computeThisFunctionType(p.enclosingLibrary.nonNullable), + asLazy: true) + .toStatement()); + } + } var accessors = procedures.where((p) => p.isAccessor).map(_emitLibraryAccessor); libraryProperties.addAll(accessors); @@ -3638,13 +3670,15 @@ class LibraryCompiler extends ComputeOnceConstantVisitor return candidateName; } - js_ast.Expression _emitFunctionTagged( - js_ast.Expression fn, FunctionType type) { + js_ast.Expression _emitFunctionTagged(js_ast.Expression fn, FunctionType type, + {bool asLazy = false}) { var typeRep = _emitType( // Avoid tagging a closure as Function? or Function* type.withDeclaredNullability(Nullability.nonNullable)); if (type.typeParameters.isEmpty) { - return _runtimeCall('fn(#, #)', [fn, typeRep]); + return asLazy + ? _runtimeCall('lazyFn(#, () => #)', [fn, typeRep]) + : _runtimeCall('fn(#, #)', [fn, typeRep]); } else { var typeParameterDefaults = [ for (var parameter in type.typeParameters) @@ -3652,8 +3686,11 @@ class LibraryCompiler extends ComputeOnceConstantVisitor ]; var defaultInstantiatedBounds = _emitConstList(const DynamicType(), typeParameterDefaults); - return _runtimeCall( - 'gFn(#, #, #)', [fn, typeRep, defaultInstantiatedBounds]); + return asLazy + ? _runtimeCall('lazyGFn(#, () => #, () => #)', + [fn, typeRep, defaultInstantiatedBounds]) + : _runtimeCall( + 'gFn(#, #, #)', [fn, typeRep, defaultInstantiatedBounds]); } } @@ -5422,7 +5459,7 @@ class LibraryCompiler extends ComputeOnceConstantVisitor } var jsMemberName = _emitMemberName(memberName, member: member); if (_reifyTearoff(member)) { - return _runtimeCall('bind(#, #)', [jsReceiver, jsMemberName]); + return _runtimeCall('tearoff(#, #)', [jsReceiver, jsMemberName]); } var jsPropertyAccess = js_ast.PropertyAccess(jsReceiver, jsMemberName); return isJsMember(member) @@ -5612,15 +5649,12 @@ class LibraryCompiler extends ComputeOnceConstantVisitor _emitStaticGet(node.target); js_ast.Expression _emitStaticGet(Member target) { - var result = _emitStaticTarget(target); + var propertyAccessor = _emitStaticTarget(target); + var context = propertyAccessor.receiver; + var property = propertyAccessor.selector; + var result = js.call('#.#', [context, property]); if (_reifyTearoff(target)) { - // TODO(jmesserly): we could tag static/top-level function types once - // in the module initialization, rather than at the point where they - // escape. - return _emitFunctionTagged( - result, - target.function! - .computeThisFunctionType(target.enclosingLibrary.nonNullable)); + return _runtimeCall('staticTearoff(#, #)', [context, property]); } return result; } @@ -6721,7 +6755,7 @@ class LibraryCompiler extends ComputeOnceConstantVisitor } /// Emits the target of a [StaticInvocation], [StaticGet], or [StaticSet]. - js_ast.Expression _emitStaticTarget(Member target) { + js_ast.PropertyAccess _emitStaticTarget(Member target) { var c = target.enclosingClass; if (c != null) { // A static native element should just forward directly to the JS type's @@ -6731,9 +6765,12 @@ class LibraryCompiler extends ComputeOnceConstantVisitor if (isExternal && (target as Procedure).isStatic) { var nativeName = _extensionTypes.getNativePeers(c); if (nativeName.isNotEmpty) { - var memberName = _annotationName(target, isJSName) ?? - _emitStaticMemberName(target.name.text, target); - return _runtimeCall('global.#.#', [nativeName[0], memberName]); + var annotationName = _annotationName(target, isJSName); + var memberName = annotationName == null + ? _emitStaticMemberName(target.name.text, target) + : js.string(annotationName); + return js_ast.PropertyAccess( + _runtimeCall('global.#', [nativeName[0]]), memberName); } } return js_ast.PropertyAccess(_emitStaticClassName(c, isExternal), diff --git a/pkg/dev_compiler/lib/src/kernel/expression_compiler.dart b/pkg/dev_compiler/lib/src/kernel/expression_compiler.dart index 7a9a21682939..c368ebdf0a92 100644 --- a/pkg/dev_compiler/lib/src/kernel/expression_compiler.dart +++ b/pkg/dev_compiler/lib/src/kernel/expression_compiler.dart @@ -233,9 +233,9 @@ class ExpressionCompiler { var args = localJsScope.join(',\n '); jsExpression = jsExpression.split('\n').join('\n '); - var callExpression = '\n ($jsExpression(' - '\n $args' - '\n ))'; + // We check for '_boundMethod' in case tearoffs are returned. + var callExpression = '((() => {var output = $jsExpression($args); ' + 'return output?._boundMethod || output;})())'; _log('Compiled expression \n$expression to $callExpression'); return callExpression; diff --git a/pkg/dev_compiler/test/expression_compiler/runtime_debugger_api_test.dart b/pkg/dev_compiler/test/expression_compiler/runtime_debugger_api_test.dart index a05d6d5a5636..b69ea9a891d6 100644 --- a/pkg/dev_compiler/test/expression_compiler/runtime_debugger_api_test.dart +++ b/pkg/dev_compiler/test/expression_compiler/runtime_debugger_api_test.dart @@ -697,11 +697,13 @@ void runSharedTests( test('getFunctionName (static method)', () async { var getFunctionName = setup.emitLibraryBundle ? 'getFunctionName' : 'getFunctionMetadata'; + var expectedName = + setup.emitLibraryBundle ? 'BaseClass.staticMethod' : 'staticMethod'; await driver.checkRuntimeInFrame( breakpointId: 'BP', expression: 'dart.$getFunctionName(staticMethod)', - expectedResult: 'staticMethod'); + expectedResult: expectedName); }); test('getFunctionName (global method)', () async { diff --git a/pkg/linter/CHANGELOG.md b/pkg/linter/CHANGELOG.md index c6db35bda2c4..f249f76fa2d2 100644 --- a/pkg/linter/CHANGELOG.md +++ b/pkg/linter/CHANGELOG.md @@ -4,6 +4,7 @@ - new lint: `strict_top_level_inference` - new _(experimental)_ lint: `omit_obvious_property_types` - new _(experimental)_ lint: `specify_nonobvious_property_types` +- new _(experimental)_ lint: `unnecessary_async` - new _(experimental)_ lint: `unsafe_variance` - removed lint: `package_api_docs` - removed lint: `unsafe_html` diff --git a/pkg/linter/example/all.yaml b/pkg/linter/example/all.yaml index 97eabdde8816..07fac799e0e5 100644 --- a/pkg/linter/example/all.yaml +++ b/pkg/linter/example/all.yaml @@ -180,6 +180,7 @@ linter: - type_literal_in_constant_pattern - unawaited_futures - unintended_html_in_doc_comment + - unnecessary_async - unnecessary_await_in_return - unnecessary_brace_in_string_interps - unnecessary_breaks diff --git a/pkg/linter/lib/src/extensions.dart b/pkg/linter/lib/src/extensions.dart index 98bf0b0bd1fa..fe12b0351630 100644 --- a/pkg/linter/lib/src/extensions.dart +++ b/pkg/linter/lib/src/extensions.dart @@ -141,7 +141,7 @@ extension BlockExtension on Block { } } -extension ClassElement2Extension on ClassElement2 { +extension ClassElementExtension on ClassElement2 { bool get hasImmutableAnnotation { var inheritedAndSelfElements = [ ...allSupertypes.map((t) => t.element3), @@ -309,7 +309,7 @@ extension DartTypeExtension on DartType? { _extendsClass(type.superclass, seenElements, className, library)); } -extension ElementExtension2 on Element2? { +extension ElementExtension on Element2? { Element2? get canonicalElement2 => switch (this) { PropertyAccessorElement2(:var variable3?) => variable3, _ => this, @@ -482,7 +482,7 @@ extension InhertanceManager3Extension on InheritanceManager3 { } } -extension InterfaceElement2Extension on InterfaceElement2 { +extension InterfaceElementExtension on InterfaceElement2 { /// Whether this element has the exact [name] and defined in the file with /// the given [uri]. bool isExactly(String name, Uri uri) => diff --git a/pkg/linter/lib/src/lint_codes.g.dart b/pkg/linter/lib/src/lint_codes.g.dart index 9be22956108d..72762f5163d1 100644 --- a/pkg/linter/lib/src/lint_codes.g.dart +++ b/pkg/linter/lib/src/lint_codes.g.dart @@ -1572,6 +1572,12 @@ class LinterLintCode extends LintCode { hasPublishedDocs: true, ); + static const LintCode unnecessary_async = LinterLintCode( + LintNames.unnecessary_async, + "Don't make a function 'async' if it doesn't use 'await'.", + correctionMessage: "Try removing the 'async' modifier.", + ); + static const LintCode unnecessary_await_in_return = LinterLintCode( LintNames.unnecessary_await_in_return, "Unnecessary 'await'.", diff --git a/pkg/linter/lib/src/lint_names.g.dart b/pkg/linter/lib/src/lint_names.g.dart index 844d13a9dda5..f2dce25a7f6e 100644 --- a/pkg/linter/lib/src/lint_names.g.dart +++ b/pkg/linter/lib/src/lint_names.g.dart @@ -480,6 +480,8 @@ abstract final class LintNames { static const String unintended_html_in_doc_comment = 'unintended_html_in_doc_comment'; + static const String unnecessary_async = 'unnecessary_async'; + static const String unnecessary_await_in_return = 'unnecessary_await_in_return'; diff --git a/pkg/linter/lib/src/rules.dart b/pkg/linter/lib/src/rules.dart index 1f5d4f0f7a51..8d1efd6f311b 100644 --- a/pkg/linter/lib/src/rules.dart +++ b/pkg/linter/lib/src/rules.dart @@ -198,6 +198,7 @@ import 'rules/type_init_formals.dart'; import 'rules/type_literal_in_constant_pattern.dart'; import 'rules/unawaited_futures.dart'; import 'rules/unintended_html_in_doc_comment.dart'; +import 'rules/unnecessary_async.dart'; import 'rules/unnecessary_await_in_return.dart'; import 'rules/unnecessary_brace_in_string_interps.dart'; import 'rules/unnecessary_breaks.dart'; @@ -446,6 +447,7 @@ void registerLintRules() { ..registerLintRule(TypeLiteralInConstantPattern()) ..registerLintRule(UnawaitedFutures()) ..registerLintRule(UnintendedHtmlInDocComment()) + ..registerLintRule(UnnecessaryAsync()) ..registerLintRule(UnnecessaryAwaitInReturn()) ..registerLintRule(UnnecessaryBraceInStringInterps()) ..registerLintRule(UnnecessaryBreaks()) diff --git a/pkg/linter/lib/src/rules/unnecessary_async.dart b/pkg/linter/lib/src/rules/unnecessary_async.dart new file mode 100644 index 000000000000..30be4af58ece --- /dev/null +++ b/pkg/linter/lib/src/rules/unnecessary_async.dart @@ -0,0 +1,205 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. 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/token.dart'; +import 'package:analyzer/dart/ast/visitor.dart'; +import 'package:analyzer/dart/element/nullability_suffix.dart'; +import 'package:analyzer/dart/element/type.dart'; +// ignore: implementation_imports +import 'package:analyzer/src/dart/ast/ast.dart'; + +import '../analyzer.dart'; + +const _desc = r'No await no async.'; + +class UnnecessaryAsync extends LintRule { + UnnecessaryAsync() + : super( + name: LintNames.unnecessary_async, + description: _desc, + state: const State.experimental(), + ); + + @override + LintCode get lintCode => LinterLintCode.unnecessary_async; + + @override + void registerNodeProcessors( + NodeLintRegistry registry, + LinterContext context, + ) { + var visitor = _Visitor(this); + registry.addFunctionDeclaration(this, visitor); + registry.addFunctionExpression(this, visitor); + registry.addMethodDeclaration(this, visitor); + } +} + +class _HasAwaitVisitor extends RecursiveAstVisitor { + bool hasAwait = false; + bool everyReturnHasValue = true; + bool returnsOnlyFuture = true; + + @override + void visitAwaitExpression(AwaitExpression node) { + hasAwait = true; + super.visitAwaitExpression(node); + } + + @override + void visitExpressionFunctionBody(ExpressionFunctionBody node) { + _updateWithExpression(node.expression); + super.visitExpressionFunctionBody(node); + } + + @override + void visitForElement(ForElement node) { + hasAwait |= node.awaitKeyword != null; + super.visitForElement(node); + } + + @override + void visitForStatement(ForStatement node) { + hasAwait |= node.awaitKeyword != null; + super.visitForStatement(node); + } + + @override + void visitFunctionExpression(FunctionExpression node) { + // Stop the recursion. + } + + @override + void visitReturnStatement(ReturnStatement node) { + var expression = node.expression; + if (expression != null) { + _updateWithExpression(expression); + } else { + everyReturnHasValue = false; + } + + super.visitReturnStatement(node); + } + + void _updateWithExpression(Expression expression) { + var type = expression.staticType; + if (!(type is InterfaceType && + type.isDartAsyncFutureOrSubtype && + type.nullabilitySuffix == NullabilitySuffix.none)) { + returnsOnlyFuture = false; + } + } +} + +class _Visitor extends SimpleAstVisitor { + final LintRule rule; + + _Visitor(this.rule); + + @override + void visitFunctionDeclaration(covariant FunctionDeclarationImpl node) { + var element = node.declaredFragment!.element; + + _checkBody( + body: node.functionExpression.body, + returnType: element.returnType, + ); + } + + @override + void visitFunctionExpression(covariant FunctionExpressionImpl node) { + // Here we handle only closures. + if (node.parent is FunctionDeclaration) { + return; + } + + var bodyContext = node.body.bodyContext; + + _checkBody( + body: node.body, + returnType: bodyContext?.imposedType, + ); + } + + @override + void visitMethodDeclaration(covariant MethodDeclarationImpl node) { + var element = node.declaredFragment!.element; + + _checkBody( + body: node.body, + returnType: element.returnType, + ); + } + + void _checkBody({ + required FunctionBodyImpl body, + required DartType? returnType, + }) { + var asyncKeyword = body.keyword; + if (asyncKeyword == null || asyncKeyword.keyword != Keyword.ASYNC) { + return; + } + + if (body.star != null) { + return; + } + + var bodyContext = body.bodyContext; + if (bodyContext == null) { + return; + } + + var visitor = _HasAwaitVisitor(); + body.accept(visitor); + + if (visitor.hasAwait) { + return; + } + + // If no imposed return type, then any type is OK. + if (returnType == null) { + rule.reportLintForToken(asyncKeyword); + return; + } + + // We don't have to return anything. + // So, the generated `Future` is not necessary. + if (returnType is VoidType) { + rule.reportLintForToken(asyncKeyword); + return; + } + + // It is OK to return values into `FutureOr`. + // So, wrapping values into `Future` is not necessary. + if (returnType.isDartAsyncFutureOr) { + rule.reportLintForToken(asyncKeyword); + return; + } + + // We handle only `Future` below. + if (!returnType.isDartAsyncFuture) { + return; + } + + // If the body may complete normally, we cannot remove `async`. + // This would make the body return `null`. + // And `null` is not the same as `Future.value(null)`. + if (bodyContext.mayCompleteNormally) { + return; + } + + // If every `return` returns `Future`, we don't need wrapping. + if (visitor.everyReturnHasValue && visitor.returnsOnlyFuture) { + rule.reportLintForToken(asyncKeyword); + return; + } + } +} + +extension on InterfaceType { + bool get isDartAsyncFutureOrSubtype { + var typeProvider = element3.library2.typeProvider; + return asInstanceOf2(typeProvider.futureElement2) != null; + } +} diff --git a/pkg/linter/messages.yaml b/pkg/linter/messages.yaml index c25219863fe3..5d4e9fed77a7 100644 --- a/pkg/linter/messages.yaml +++ b/pkg/linter/messages.yaml @@ -11632,6 +11632,35 @@ LintCode: /// \ -> \ = \` /// ``` + unnecessary_async: + problemMessage: "Don't make a function 'async' if it doesn't use 'await'." + correctionMessage: "Try removing the 'async' modifier." + state: + experimental: "3.7" + categories: [style] + hasPublishedDocs: false + deprecatedDetails: |- + Functions that don't do `await` don't have to be `async`. + + Usually such functions also don't have to return a `Future`, which allows + an invoker to avoid `await` in its code, etc. Synchronous code in + general runs faster, and is easier to reason about. + + **BAD:** + ```dart + void f() async { + // await Future.delayed(const Duration(seconds: 2)); + print(0); + } + ``` + + **GOOD:** + ```dart + void f() { + // await Future.delayed(const Duration(seconds: 2)); + print(0); + } + ``` unnecessary_await_in_return: problemMessage: "Unnecessary 'await'." correctionMessage: "Try removing the 'await'." diff --git a/pkg/linter/test/rules/all.dart b/pkg/linter/test/rules/all.dart index 8e71c6ec4aef..a63f3693d159 100644 --- a/pkg/linter/test/rules/all.dart +++ b/pkg/linter/test/rules/all.dart @@ -253,6 +253,7 @@ import 'type_literal_in_constant_pattern_test.dart' import 'unawaited_futures_test.dart' as unawaited_futures; import 'unintended_html_in_doc_comment_test.dart' as unintended_html_in_doc_comment; +import 'unnecessary_async_test.dart' as unnecessary_async; import 'unnecessary_await_in_return_test.dart' as unnecessary_await_in_return; import 'unnecessary_brace_in_string_interps_test.dart' as unnecessary_brace_in_string_interps; @@ -506,6 +507,7 @@ void main() { type_literal_in_constant_pattern.main(); unawaited_futures.main(); unintended_html_in_doc_comment.main(); + unnecessary_async.main(); unnecessary_await_in_return.main(); unnecessary_brace_in_string_interps.main(); unnecessary_breaks.main(); diff --git a/pkg/linter/test/rules/unnecessary_async_test.dart b/pkg/linter/test/rules/unnecessary_async_test.dart new file mode 100644 index 000000000000..d0c449833522 --- /dev/null +++ b/pkg/linter/test/rules/unnecessary_async_test.dart @@ -0,0 +1,457 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. 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 '../rule_test_support.dart'; + +main() { + defineReflectiveSuite(() { + defineReflectiveTests(UnnecessaryAsyncTest); + }); +} + +@reflectiveTest +class UnnecessaryAsyncTest extends LintRuleTest { + @override + String get lintRule => LintNames.unnecessary_async; + + test_closure_imposedReturnTypeFuture_noAwait() async { + await assertNoDiagnostics(r''' +void f() { + useFunction(() async {}); +} + +void useFunction(Future Function() x) {} +'''); + } + + test_closure_imposedReturnTypeVoid_hasAwait() async { + await assertNoDiagnostics(r''' +void f() { + useFunction(() async { + await 0; + }); +} + +void useFunction(void Function() x) {} +'''); + } + + test_closure_imposedReturnTypeVoid_noAwait() async { + await assertDiagnostics(r''' +void f() { + useFunction(() async {}); +} + +void useFunction(void Function() x) {} +''', [ + lint(28, 5), + ]); + } + + test_closure_noImposedReturnType_hasAwait() async { + await assertNoDiagnostics(r''' +void f() { + var v = () async { + await 0; + }; +} +'''); + } + + test_closure_noImposedReturnType_noAwait() async { + await assertDiagnostics(r''' +void f() { + var v = () async {}; +} +''', [ + lint(24, 5), + ]); + } + + test_localFunction_void_hasAwait() async { + await assertDiagnostics(r''' +void foo() { + void f() async { + await 0; + } +} +''', [ + error(WarningCode.UNUSED_ELEMENT, 20, 1), + ]); + } + + test_localFunction_void_noAwait() async { + await assertDiagnostics(r''' +void foo() { + void f() async {} +} +''', [ + error(WarningCode.UNUSED_ELEMENT, 20, 1), + lint(24, 5), + ]); + } + + test_localFunction_void_noAwait_outerHasAwait() async { + await assertDiagnostics(r''' +Future foo() async { + void f() async {} + await 0; +} +''', [ + error(WarningCode.UNUSED_ELEMENT, 34, 1), + lint(38, 5), + ]); + } + + test_method_future_returnFuture() async { + await assertDiagnostics(r''' +class A { + Future f() async { + return Future.value(0); + } +} +''', [ + lint(28, 5), + ]); + } + + test_method_future_returnValue() async { + await assertNoDiagnostics(r''' +class A { + Future f() async { + return 0; + } +} +'''); + } + + test_method_futureOr_returnFuture() async { + await assertDiagnostics(r''' +import 'dart:async'; + +class A { + FutureOr f() async { + return Future.value(0); + } +} +''', [ + lint(52, 5), + ]); + } + + test_method_futureOr_returnValue() async { + await assertDiagnostics(r''' +import 'dart:async'; + +class A { + FutureOr f() async { + return 0; + } +} +''', [ + lint(52, 5), + ]); + } + + test_method_void_hasAwaitExpression() async { + await assertNoDiagnostics(r''' +class A { + void f() async { + await 0; + } +} +'''); + } + + test_method_void_noAwait() async { + await assertDiagnostics(r''' +class A { + void f() async {} +} +''', [ + lint(21, 5), + ]); + } + + test_topLevelFunction_block_future_intNullable_returnNullable() async { + await assertNoDiagnostics(r''' +Future f(int? x) async { + return x == null ? null : Future.value(x); +} +'''); + } + + test_topLevelFunction_blockBody_dynamic() async { + await assertNoDiagnostics(r''' +dynamic f() async { + return 0; +} +'''); + } + + test_topLevelFunction_blockBody_future_int_hasReturn_futureCustom() async { + await assertDiagnostics(r''' +Future f() async { + return MyFuture.value(0); +} + +class MyFuture implements Future { + MyFuture.value(T _); + + @override + noSuchMethod(invocation) => super.noSuchMethod(invocation); +} +''', [ + lint(16, 5), + ]); + } + + test_topLevelFunction_blockBody_future_int_returnFuture() async { + await assertDiagnostics(r''' +Future f() async { + return Future.value(0); +} +''', [ + lint(16, 5), + ]); + } + + test_topLevelFunction_blockBody_future_int_returnValue() async { + await assertNoDiagnostics(r''' +Future f() async { + return 0; +} +'''); + } + + test_topLevelFunction_blockBody_future_intNullable_hasReturn_null() async { + await assertNoDiagnostics(r''' +Future f() async { + return null; +} +'''); + } + + test_topLevelFunction_blockBody_future_void_hasReturn_future() async { + await assertDiagnostics(r''' +Future f() async { + return foo(); +} + +Future foo() { + return Future.value(); +} +''', [ + lint(17, 5), + ]); + } + + test_topLevelFunction_blockBody_future_void_hasReturn_nothing() async { + await assertNoDiagnostics(r''' +Future f() async { + return; +} +'''); + } + + test_topLevelFunction_blockBody_future_void_noReturn_atAll() async { + await assertNoDiagnostics(r''' +Future f() async {} +'''); + } + + test_topLevelFunction_blockBody_future_void_noReturn_atEnd_hasReturnFuture() async { + await assertNoDiagnostics(r''' +Future f() async { + if (0 == 0) { + return Future.value(); + } +} +'''); + } + + test_topLevelFunction_blockBody_future_void_noReturn_atEnd_hasReturnNothing() async { + await assertNoDiagnostics(r''' +Future f() async { + if (0 == 0) { + return; + } +} +'''); + } + + test_topLevelFunction_blockBody_futureNullable_int_hasReturn_future() async { + await assertDiagnostics(r''' +Future? f() async { + return Future.value(0); +} +''', [ + lint(17, 5), + ]); + } + + test_topLevelFunction_blockBody_futureNullable_int_hasReturn_value() async { + await assertNoDiagnostics(r''' +Future? f() async { + return 0; +} +'''); + } + + test_topLevelFunction_blockBody_futureNullable_intNullable_hasReturn_null() async { + await assertNoDiagnostics(r''' +Future? f() async { + return null; +} +'''); + } + + test_topLevelFunction_blockBody_futureNullable_intNullable_noReturn() async { + await assertDiagnostics(r''' +Future? f() async {} +''', [ + error(WarningCode.BODY_MIGHT_COMPLETE_NORMALLY_NULLABLE, 14, 1), + ]); + } + + test_topLevelFunction_blockBody_futureNullable_void_hasReturn_nothing() async { + await assertNoDiagnostics(r''' +Future? f() async { + return; +} +'''); + } + + test_topLevelFunction_blockBody_futureNullable_void_noReturn_atAll() async { + await assertNoDiagnostics(r''' +Future? f() async {} +'''); + } + + test_topLevelFunction_blockBody_futureNullable_void_noReturn_atEnd_hasReturnFuture() async { + await assertNoDiagnostics(r''' +Future? f() async { + if (0 == 0) { + return Future.value(); + } +} +'''); + } + + test_topLevelFunction_blockBody_futureNullable_void_noReturn_atEnd_hasReturnNull() async { + await assertNoDiagnostics(r''' +Future? f() async { + if (0 == 0) { + return null; + } +} +'''); + } + + test_topLevelFunction_blockBody_futureOr_returnFuture() async { + await assertDiagnostics(r''' +import 'dart:async'; + +FutureOr f() async { + return Future.value(0); +} +''', [ + lint(40, 5), + ]); + } + + test_topLevelFunction_blockBody_futureOr_returnValue() async { + await assertDiagnostics(r''' +import 'dart:async'; + +FutureOr f() async { + return 0; +} +''', [ + lint(40, 5), + ]); + } + + test_topLevelFunction_blockBody_object() async { + await assertNoDiagnostics(r''' +Object f() async { + return 0; +} +'''); + } + + test_topLevelFunction_blockBody_void_hasAwait_expression() async { + await assertNoDiagnostics(r''' +void f() async { + await 0; +} +'''); + } + + test_topLevelFunction_blockBody_void_hasAwait_forElement() async { + await assertNoDiagnostics(r''' +void f(Stream values) async { + [ + await for (var value in values) value, + ]; +} +'''); + } + + test_topLevelFunction_blockBody_void_hasAwait_forStatement() async { + await assertNoDiagnostics(r''' +void f(Stream values) async { + await for (var value in values) {} +} +'''); + } + + test_topLevelFunction_blockBody_void_hasAwait_nestedFunctionExpression() async { + await assertDiagnostics(r''' +void f() async { + () async { + await 0; + }(); +} +''', [ + lint(9, 5), + ]); + } + + test_topLevelFunction_blockBody_void_noAwait() async { + await assertDiagnostics(r''' +void f() async {} +''', [ + lint(9, 5), + ]); + } + + test_topLevelFunction_exprBody_future_int_returnFuture() async { + await assertDiagnostics(r''' +Future f() async => Future.value(0); +''', [ + lint(16, 5), + ]); + } + + test_topLevelFunction_exprBody_future_int_returnValue() async { + await assertNoDiagnostics(r''' +Future f() async => 0; +'''); + } + + test_topLevelFunction_exprBody_future_intNullable_returnNullable() async { + await assertNoDiagnostics(r''' +Future f(int? x) async => x == null ? null : Future.value(x); +'''); + } + + test_topLevelFunction_exprBody_futureNullable_intNullable_returnNull() async { + await assertNoDiagnostics(r''' +Future? f() async => null; +'''); + } +} diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/debugger.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/debugger.dart index 912925808085..70a87063997c 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/debugger.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/debugger.dart @@ -270,15 +270,21 @@ void _collectFieldDescriptors( /// returns `C.functionName`. /// Otherwise, returns function name. String getFunctionMetadata(@notNull Function function) { - var name = _get(function, 'name'); + var boundName = _get(function, '_boundName'); + var name = boundName ?? _get(function, 'name'); var boundObject = _get(function, '_boundObject'); if (boundObject != null) { - var cls = _get(boundObject, 'constructor'); - var className = _dartClassName(cls); - - var boundMethod = _get(function, '_boundMethod'); - name = className + '.' + _get(boundMethod, 'name'); + if (_hasConstructor(boundObject)) { + // Bound objects for global methods are libraries, which don't have a + // constructor. + var constructor = _get(boundObject, 'constructor'); + if (JS('', '# == null', constructor)) return name; + if (_isDartClassObject(boundObject)) { + var className = _dartClassName(boundObject); + name = className + '.' + name; + } + } } return name; } @@ -306,7 +312,9 @@ Object getObjectMetadata(@notNull Object object) { // When the object is actually represented by a JavaScript Array use // the interceptor class that matches the reified type. ? JS_CLASS_REF(JSArray) - : _get(object, 'constructor'); + : (_hasConstructor(object) + ? _get(object, 'constructor') + : object); if (cls != null) { libraryId = getLibraryUri(cls); } @@ -391,7 +399,8 @@ Object getObjectMetadata(@notNull Object object) { @notNull List getObjectFieldNames(@notNull Object object) { var fieldNames = []; - var cls = _get(object, 'constructor'); + var cls = + _hasConstructor(object) ? _get(object, 'constructor') : object; _collectObjectFieldNames(fieldNames, getFields(cls)); return fieldNames..sort(); @@ -538,6 +547,10 @@ Object getSubRange(@notNull Object object, int offset, int count) { return object; } +@notNull +bool _hasConstructor(@notNull Object object) => + _get(object, 'constructor') != null; + @notNull bool _isDartClassObject(@notNull Object object) => _get(object, rti.interfaceTypeRecipePropertyName) != null; diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart index ceb1bcf51b17..cf552819126e 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart @@ -48,6 +48,87 @@ class InvocationImpl extends Invocation { } } +/// Encodes [property] as a valid JS member name. +String stringNameForProperty(property) { + if (JS('', 'typeof # === "symbol"', property)) { + return _toSymbolName(property); + } + if (JS('', 'typeof # === "string"', property)) { + return '$property'; + } + throw Exception('Unable to construct a valid JS string name for $property.'); +} + +/// Used for canonicalizing tearoffs via a two-way lookup of enclosing object +/// and member name. +final tearoffCache = JS('!', 'new WeakMap()'); + +/// Constructs a static tearoff, on `context[property]`. +/// +/// Static tearoffs are canonicalized at runtime via `tearoffCache`. +staticTearoff(context, property) { + if (context == null) context = jsNull; + var propertyMap = _lookupNonTerminal(tearoffCache, context); + var canonicalizedTearoff = JS('', '#.get(#)', propertyMap, property); + if (canonicalizedTearoff != null) return canonicalizedTearoff; + var tear = tearoff(context, property); + JS('', '#.set(#, #)', propertyMap, property, tear); + return tear; +} + +/// Constructs a new tearoff, on `context[property]`. Tearoffs are represented +/// as a closure that resolves its underlying member late. +/// +/// Note: We do not canonicalize instance tearoffs to be consistent with +/// Dart2JS, but we should update this if the spec changes. See #3612. +tearoff(context, property) { + if (context == null) context = jsNull; + var tear = JS('', '(...args) => #[#](...args)', context, property); + var rtiName = JS_GET_NAME(JsGetName.SIGNATURE_NAME); + // Type-resolving members on tearoffs must be resolved late. Static tearoffs + // are tagged with their RTIs ahead of time. Runtime/instance tearoffs must + // access them through `getMethodType` and `getMethodDefaultTypeArgs`. + defineAccessor( + tear, + rtiName, + get: () { + var existingRti = JS('', '#[#][#]', context, property, rtiName); + return existingRti ?? getMethodType(context, property); + }, + configurable: true, + enumerable: false, + ); + defineAccessor( + tear, + '_defaultTypeArgs', + get: () { + var existingDefaultTypeArgs = JS( + '', + '#[#][#]', + context, + property, + '_defaultTypeArgs', + ); + return existingDefaultTypeArgs ?? + getMethodDefaultTypeArgs(context, property); + }, + configurable: true, + enumerable: false, + ); + defineAccessor( + tear, + '_boundMethod', + get: () { + return JS('', '#[#]', context, property); + }, + configurable: true, + enumerable: false, + ); + JS('', '#._boundObject = #', tear, context); + JS('', '#._boundName = #', tear, stringNameForProperty(property)); + return tear; +} + /// Given an object and a method name, tear off the method. /// Sets the runtime type of the torn off method appropriately, /// and also binds the object. @@ -62,6 +143,7 @@ bind(obj, name, method) { var f = JS('', '#.bind(#)', method, obj); // TODO(jmesserly): canonicalize tearoffs. JS('', '#._boundObject = #', f, obj); + JS('', '#._boundName = #', f, stringNameForProperty(name)); JS('', '#._boundMethod = #', f, method); var methodType = getMethodType(obj, name); // Native JavaScript methods do not have Dart signatures attached that need @@ -85,8 +167,8 @@ bind(obj, name, method) { /// canonical member [name]. /// /// [name] is typically `"call"` but it could be the [extensionSymbol] for -/// `call`, if we define it on a native type, and [obj] is known statially to be -/// a native type/interface with `call`. +/// `call`, if we define it on a native type, and [obj] is known statically to +/// be a native type/interface with `call`. bindCall(obj, name) { if (obj == null) return null; var ftype = getMethodType(obj, name); @@ -151,7 +233,7 @@ dload(obj, field) { if (hasField(typeSigHolder, f) || hasGetter(typeSigHolder, f)) return JS('', '#[#]', obj, f); - if (hasMethod(typeSigHolder, f)) return bind(obj, f, null); + if (hasMethod(typeSigHolder, f)) return tearoff(obj, f); // Handle record types by trying to access [f] via convenience getters. if (_jsInstanceOf(obj, RecordImpl) && f is String) { @@ -551,7 +633,7 @@ dcall(f, args, [named]) => _checkAndCall( null, args, named, - JS('', '#.name', f), + JS('', '#._boundName || #.name', f, f), ); dgcall(f, typeArgs, args, [named]) => _checkAndCall( @@ -561,7 +643,7 @@ dgcall(f, typeArgs, args, [named]) => _checkAndCall( typeArgs, args, named, - JS('', "#.name || 'call'", f), + JS('', "#._boundName || #.name || 'call'", f, f), ); /// Helper for REPL dynamic invocation variants that make a best effort to @@ -922,7 +1004,7 @@ String Function() toStringTearoff(obj) { JS('!', '#[#] !== void 0', obj, extensionSymbol('toString'))) { // The bind helper can handle finding the toString method for null or Dart // Objects. - return bind(obj, extensionSymbol('toString'), null); + return tearoff(obj, extensionSymbol('toString')); } // Otherwise bind the native JavaScript toString method. // This differs from dart2js to provide a more useful toString at development @@ -930,7 +1012,7 @@ String Function() toStringTearoff(obj) { // If obj does not have a native toString method this will throw but that // matches the behavior of dart2js and it would be misleading to make this // work at development time but allow it to fail in production. - return bind(obj, 'toString', null); + return tearoff(obj, 'toString'); } /// Converts to a non-null [String], equivalent to @@ -999,7 +1081,7 @@ dynamic Function(Invocation) noSuchMethodTearoff(obj) { JS('!', '#[#] !== void 0', obj, extensionSymbol('noSuchMethod'))) { // The bind helper can handle finding the toString method for null or Dart // Objects. - return bind(obj, extensionSymbol('noSuchMethod'), null); + return tearoff(obj, extensionSymbol('noSuchMethod')); } // Otherwise, manually pass the Dart Core Object noSuchMethod to the bind // helper. diff --git a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/rtti.dart b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/rtti.dart index e6a7491045ee..1e93794ccb61 100644 --- a/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/rtti.dart +++ b/sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/rtti.dart @@ -53,8 +53,6 @@ fn(closure, type) { } /// Tag a generic [closure] with a [type] and the [defaultTypeArgs] values. -/// -/// Only called from generated code when running with the new type system. gFn(Object closure, Object type, JSArray defaultTypeArgs) { JS('', '#[#] = #', closure, JS_GET_NAME(JsGetName.SIGNATURE_NAME), type); JS('', '#._defaultTypeArgs = #', closure, defaultTypeArgs); @@ -72,10 +70,54 @@ gFn(Object closure, Object type, JSArray defaultTypeArgs) { lazyFn(closure, Object Function() computeType) { defineAccessor( closure, - _runtimeType, - get: () => defineValue(closure, _runtimeType, computeType()), - set: (value) => defineValue(closure, _runtimeType, value), + JS_GET_NAME(JsGetName.SIGNATURE_NAME), + get: + () => defineValue( + closure, + JS_GET_NAME(JsGetName.SIGNATURE_NAME), + computeType(), + ), + set: + (value) => + defineValue(closure, JS_GET_NAME(JsGetName.SIGNATURE_NAME), value), + configurable: true, + enumerable: false, + ); + return closure; +} + +/// Tag a generic [closure] with a getter that uses [computeType] and +/// [computeDefaultTypeArgs] to lazily return its runtime type and default type +/// arguments, respectively, +lazyGFn( + Object closure, + Object Function() computeType, + Object Function() computeDefaultTypeArgs, +) { + defineAccessor( + closure, + JS_GET_NAME(JsGetName.SIGNATURE_NAME), + get: + () => defineValue( + closure, + JS_GET_NAME(JsGetName.SIGNATURE_NAME), + computeType(), + ), + set: + (value) => + defineValue(closure, JS_GET_NAME(JsGetName.SIGNATURE_NAME), value), + configurable: true, + enumerable: false, + ); + defineAccessor( + closure, + '_defaultTypeArgs', + get: + () => + defineValue(closure, '_defaultTypeArgs', computeDefaultTypeArgs()), + set: (value) => defineValue(closure, '_defaultTypeArgs', value), configurable: true, + enumerable: false, ); return closure; } diff --git a/tests/dartdevc/debugger/debugger_ddc_test_golden.txt b/tests/dartdevc/debugger/debugger_ddc_test_golden.txt new file mode 100644 index 000000000000..c41db6ed483b --- /dev/null +++ b/tests/dartdevc/debugger/debugger_ddc_test_golden.txt @@ -0,0 +1,7648 @@ +Test: List formatting header +Value: +[ + "span", + { + "style": "background-color: #d9edf7;color: black" + }, + "List length 3" +] +----------------------------------- +Test: List formatting body +Value: +[ + "ol", + { + "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;" + }, + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "0: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + "foo" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "1: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + "bar" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "2: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + "baz" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "[[class]]: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ] +] +----------------------------------- +Test: List instance header +Value: +[ + "span", + { + "style": "background-color: #d9edf7;color: black" + }, + "List length 3" +] +----------------------------------- +Test: List instance body +Value: +[ + "ol", + { + "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;" + }, + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "0: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + "42" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "1: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + "bar" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "2: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + "true" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "[[class]]: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ] +] +----------------------------------- +Test: List definition formatting header +Value: +[ + "span", + { + "style": "background-color: #d9edf7;color: black" + }, + "List" +] +----------------------------------- +Test: List definition formatting body +Value: +[ + "ol", + { + "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;" + }, + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "" + }, + "[[Instance Methods]]" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "+: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "add: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "addAll: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "any: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "asMap: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "cast: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "checkGrowable: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "checkMutable: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "clear: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "contains: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "elementAt: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "every: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "expand: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "fillRange: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "firstWhere: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "fold: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "followedBy: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "forEach: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "getRange: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "indexOf: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "indexWhere: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "insert: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "insertAll: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "join: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "lastIndexOf: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "lastIndexWhere: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "lastWhere: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "map: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "reduce: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "remove: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "removeAt: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "removeLast: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "removeRange: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "removeWhere: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "replaceRange: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "retainWhere: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "setAll: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "setRange: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "shuffle: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "singleWhere: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "skip: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "skipWhile: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "sort: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "sublist: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "take: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "takeWhile: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "toList: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "toSet: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "where: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "whereType: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "_get: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "_removeWhere: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "_set: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "_setLengthUnsafe: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "[[base class]]: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ] +] +----------------------------------- +Test: List large instance header +Value: +[ + "span", + { + "style": "background-color: #d9edf7;color: black" + }, + "List length 200" +] +----------------------------------- +Test: List large instance body +Value: +[ + "ol", + { + "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;" + }, + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "[[class]]: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ] +] +----------------------------------- +Test: List large definition formatting header +Value: +[ + "span", + { + "style": "background-color: #d9edf7;color: black" + }, + "List" +] +----------------------------------- +Test: List large definition formatting body +Value: +[ + "ol", + { + "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;" + }, + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "" + }, + "[[Instance Methods]]" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "+: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "add: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "addAll: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "any: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "asMap: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "cast: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "checkGrowable: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "checkMutable: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "clear: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "contains: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "elementAt: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "every: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "expand: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "fillRange: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "firstWhere: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "fold: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "followedBy: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "forEach: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "getRange: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "indexOf: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "indexWhere: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "insert: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "insertAll: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "join: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "lastIndexOf: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "lastIndexWhere: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "lastWhere: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "map: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "reduce: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "remove: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "removeAt: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "removeLast: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "removeRange: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "removeWhere: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "replaceRange: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "retainWhere: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "setAll: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "setRange: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "shuffle: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "singleWhere: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "skip: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "skipWhile: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "sort: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "sublist: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "take: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "takeWhile: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "toList: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "toSet: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "where: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "whereType: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "_get: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "_removeWhere: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "_set: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "_setLengthUnsafe: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "[[base class]]: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ] +] +----------------------------------- +Test: Iterable instance header +Value: +[ + "span", + { + "style": "background-color: #d9edf7;color: black" + }, + "MappedListIterable length 3" +] +----------------------------------- +Test: Iterable instance body +Value: +[ + "ol", + { + "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;" + }, + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "0: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + "foofoofoofoofoo" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "1: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + "barbarbarbarbar" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "2: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + "bazbazbazbazbaz" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "[[class]]: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ] +] +----------------------------------- +Test: Iterable definition formatting header +Value: +[ + "span", + { + "style": "background-color: #d9edf7;color: black" + }, + "MappedListIterable" +] +----------------------------------- +Test: Iterable definition formatting body +Value: +[ + "ol", + { + "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;" + }, + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "" + }, + "[[Instance Methods]]" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "any: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "cast: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "contains: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "elementAt: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "every: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "expand: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "firstWhere: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "fold: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "followedBy: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "forEach: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "join: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "lastWhere: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "map: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "reduce: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "singleWhere: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "skip: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "skipWhile: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "take: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "takeWhile: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "toList: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "toSet: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "where: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "whereType: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "[[base class]]: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ] +] +----------------------------------- +Test: Set instance header +Value: +[ + "span", + { + "style": "background-color: #d9edf7;color: black" + }, + "LinkedSet length 3" +] +----------------------------------- +Test: Set instance body +Value: +[ + "ol", + { + "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;" + }, + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "0: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + "foo" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "1: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + "42" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "2: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + "true" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "[[class]]: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ] +] +----------------------------------- +Test: Set definition formatting header +Value: +[ + "span", + { + "style": "background-color: #d9edf7;color: black" + }, + "LinkedSet" +] +----------------------------------- +Test: Set definition formatting body +Value: +[ + "ol", + { + "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;" + }, + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "" + }, + "[[Instance Methods]]" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "add: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "contains: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "lookup: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "remove: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "[[base class]]: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ] +] +----------------------------------- +Test: Map formatting header +Value: +[ + "span", + { + "style": "background-color: #d9edf7;color: black" + }, + "IdentityMap length 3" +] +----------------------------------- +Test: Map formatting body +Value: +[ + "ol", + { + "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;" + }, + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "0: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "1: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "2: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "[[class]]: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ] +] +----------------------------------- +Test: Map instance header +Value: +[ + "span", + { + "style": "background-color: #d9edf7;color: black" + }, + "LinkedMap length 3" +] +----------------------------------- +Test: Map instance body +Value: +[ + "ol", + { + "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;" + }, + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "0: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "1: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "2: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "[[class]]: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ] +] +----------------------------------- +Test: Map definition formatting header +Value: +[ + "span", + { + "style": "background-color: #d9edf7;color: black" + }, + "LinkedMap" +] +----------------------------------- +Test: Map definition formatting body +Value: +[ + "ol", + { + "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;" + }, + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "" + }, + "[[Instance Methods]]" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "clear: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "remove: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "_get: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "_putIfAbsentKeyMap: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "_set: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "[[base class]]: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ] +] +----------------------------------- +Test: Function formatting header +Value: +[ + "span", + { + "style": "background-color: #d9edf7;color: black" + }, + "(int, int) => int" +] +----------------------------------- +Test: Function formatting body +Value: +[ + "ol", + { + "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;" + }, + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "signature: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + "(int, int) => int" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "JavaScript Function: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ] +] +----------------------------------- +Test: Function with function arguments formatting header +Value: +[ + "span", + { + "style": "background-color: #d9edf7;color: black" + }, + "(String, (Event) => bool) => Null" +] +----------------------------------- +Test: Function with function arguments formatting body +Value: +[ + "ol", + { + "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;" + }, + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "signature: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + "(String, (Event) => bool) => Null" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "JavaScript Function: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ] +] +----------------------------------- +Test: dart:html method +Value: +null +----------------------------------- +Test: Raw reference to dart constructor formatting header +Value: +[ + "span", + { + "style": "background-color: #d9edf7;color: black" + }, + "TestClass" +] +----------------------------------- +Test: Raw reference to dart constructor formatting body +Value: +[ + "ol", + { + "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;" + }, + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "" + }, + "[[Instance Methods]]" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "addOne: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "last: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "nameAndDate: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "returnObject: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "[[base class]]: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ] +] +----------------------------------- +Test: Object formatting header +Value: +[ + "span", + { + "style": "background-color: #d9edf7;color: black" + }, + "Instance of 'Object'" +] +----------------------------------- +Test: Object formatting body +Value: +[ + "ol", + { + "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;" + }, + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "runtimeType: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "[[class]]: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ] +] +----------------------------------- +Test: Type TestClass formatting header +Value: +[ + "span", + { + "style": "background-color: #d9edf7;color: black" + }, + "TestClass" +] +----------------------------------- +Test: Type TestClass formatting body +Value: +[ + "ol", + { + "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;" + } +] +----------------------------------- +Test: Type HttpRequest formatting header +Value: +[ + "span", + { + "style": "background-color: #d9edf7;color: black" + }, + "HttpRequest" +] +----------------------------------- +Test: Type HttpRequest formatting body +Value: +[ + "ol", + { + "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;" + } +] +----------------------------------- +Test: Test library formatting header +Value: +[ + "span", + { + "style": "background-color: #d9edf7;color: black" + }, + "debugger_test" +] +----------------------------------- +Test: Test library formatting body +Value: +[ + "ol", + { + "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;" + }, + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "TestClass: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "TestGenericClass: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "FormattedObject: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "PackageJSClass: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "FormattedJSObject|constructor#_: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "FormattedJSObject|constructor#_#_#tearOff: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "Prototype|constructor#_: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "Prototype|constructor#_#_#tearOff: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "FooBar|constructor#_: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "FooBar|constructor#_#_#tearOff: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "unsafeCast: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "replacer: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "format: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "extractNestedFormattedObjects: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "getCurrentLibrary: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "main: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "link: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ] +] +----------------------------------- +Test: StackTrace formatting header +Value: +[ + "span", + { + "style": "background-color: #d9edf7;color: black" + }, + "StackTrace" +] +----------------------------------- +Test: StackTrace formatting body +Value: +[ + "ol", + { + "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;background-color: thistle;color: rgb(196, 26, 22);" + }, + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "" + }, + "Error" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "" + }, + "" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "" + }, + "" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "" + }, + "" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "" + }, + "" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "" + }, + "" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "" + }, + "" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "" + }, + "" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "" + }, + "" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "" + }, + "" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "" + }, + "" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "" + }, + "" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "" + }, + "" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "" + }, + "" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "" + }, + "" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "" + }, + "" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "" + }, + "" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "" + }, + "" + ] + ] + ] +] +----------------------------------- +Test: TestClass instance header +Value: +[ + "span", + { + "style": "background-color: #d9edf7;color: black" + }, + "Instance of 'TestClass'" +] +----------------------------------- +Test: TestClass instance body +Value: +[ + "ol", + { + "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;" + }, + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "date: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + "17" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "name: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + "test class" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "runtimeType: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "someInt: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + "42" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "someObject: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "someString: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + "Hello world" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "[[class]]: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ] +] +----------------------------------- +Test: TestClass definition formatting header +Value: +[ + "span", + { + "style": "background-color: #d9edf7;color: black" + }, + "TestClass" +] +----------------------------------- +Test: TestClass definition formatting body +Value: +[ + "ol", + { + "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;" + }, + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "" + }, + "[[Instance Methods]]" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "addOne: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "last: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "nameAndDate: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "returnObject: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "[[base class]]: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ] +] +----------------------------------- +Test: HttpRequest instance header +Value: +[ + "span", + { + "style": "background-color: #d9edf7;color: black" + }, + "[object XMLHttpRequest]" +] +----------------------------------- +Test: HttpRequest instance body +Value: +[ + "ol", + { + "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;" + }, + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "on: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "onAbort: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "onError: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "onLoad: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "onLoadEnd: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "onLoadStart: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "onProgress: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "onReadyStateChange: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "onTimeout: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "readyState: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + "0" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "response: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + "" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "responseHeaders: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "responseText: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + "" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "responseType: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + "" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "responseUrl: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + "" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "responseXml: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "runtimeType: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "status: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + "0" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "statusText: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + "" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "timeout: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + "0" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "upload: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "withCredentials: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + "false" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "_get_response: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + "" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "[[class]]: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ] +] +----------------------------------- +Test: HttpRequest definition formatting header +Value: +[ + "span", + { + "style": "background-color: #d9edf7;color: black" + }, + "HttpRequest" +] +----------------------------------- +Test: HttpRequest definition formatting body +Value: +[ + "ol", + { + "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;" + }, + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "" + }, + "[[Instance Methods]]" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "abort: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "getAllResponseHeaders: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "getResponseHeader: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "open: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "overrideMimeType: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "send: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "setRequestHeader: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "[[base class]]: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ] +] +----------------------------------- +Test: TestGenericClass instance header +Value: +[ + "span", + { + "style": "background-color: #d9edf7;color: black" + }, + "Instance of 'TestGenericClass>'" +] +----------------------------------- +Test: TestGenericClass instance body +Value: +[ + "ol", + { + "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;" + }, + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "x: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + "42" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "runtimeType: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "[[class]]: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ] +] +----------------------------------- +Test: TestGenericClass definition formatting header +Value: +[ + "span", + { + "style": "background-color: #d9edf7;color: black" + }, + "TestGenericClass" +] +----------------------------------- +Test: TestGenericClass definition formatting body +Value: +[ + "ol", + { + "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;" + }, + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "" + }, + "[[Instance Methods]]" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "noSuchMethod: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "toString: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "_equals: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "[[base class]]: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ] +] +----------------------------------- +Test: TestGenericClassJSInterop instance header +Value: +[ + "span", + { + "style": "background-color: #d9edf7;color: black" + }, + "Instance of 'TestGenericClass, int>'" +] +----------------------------------- +Test: TestGenericClassJSInterop instance body +Value: +[ + "ol", + { + "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;" + }, + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "x: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "runtimeType: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "[[class]]: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ] +] +----------------------------------- +Test: TestGenericClassJSInterop definition formatting header +Value: +[ + "span", + { + "style": "background-color: #d9edf7;color: black" + }, + "TestGenericClass" +] +----------------------------------- +Test: TestGenericClassJSInterop definition formatting body +Value: +[ + "ol", + { + "style": "list-style-type: none;padding-left: 0px;margin-top: 0px;margin-bottom: 0px;margin-left: 12px;" + }, + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + {}, + [ + "span", + { + "style": "" + }, + "[[Instance Methods]]" + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "noSuchMethod: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "toString: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "_equals: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ], + [ + "li", + { + "style": "padding-left: 13px;" + }, + [ + "span", + { + "style": "background-color: thistle; color: rgb(136, 19, 145); margin-right: -13px" + }, + "[[base class]]: " + ], + [ + "span", + { + "style": "margin-left: 13px" + }, + [ + "object", + { + "object": "", + "config": {} + } + ] + ] + ] +] +----------------------------------- diff --git a/tests/dartdevc/debugger/debugger_test.dart b/tests/dartdevc/debugger/debugger_test.dart index 5f6f47eaf6c9..7a945a61edcd 100644 --- a/tests/dartdevc/debugger/debugger_test.dart +++ b/tests/dartdevc/debugger/debugger_test.dart @@ -168,9 +168,10 @@ main() async { // Cache blocker is a workaround for: // https://code.google.com/p/dart/issues/detail?id=11834 var cacheBlocker = new DateTime.now().millisecondsSinceEpoch; + var embedder_suffix = dartDevEmbedder != null ? '_ddc' : ''; var goldenUrl = '/root_dart/tests/dartdevc/debugger/' - 'debugger_test_golden.txt?cacheBlock=$cacheBlocker'; + 'debugger${embedder_suffix}_test_golden.txt?cacheBlock=$cacheBlocker'; String? golden; try { diff --git a/tests/dartdevc/no_such_method_errors_test.dart b/tests/dartdevc/no_such_method_errors_test.dart index 90f813574892..d62cf7046499 100644 --- a/tests/dartdevc/no_such_method_errors_test.dart +++ b/tests/dartdevc/no_such_method_errors_test.dart @@ -263,8 +263,7 @@ void main() { dynamic tearoff = A().arity1; Expect.throws( () => tearoff(), - (error) => - error.toString().contains("NoSuchMethodError: 'bound arity1'"), + (error) => error.toString().contains("NoSuchMethodError: 'arity1'"), ); }); test('class instance generic method', () { @@ -279,9 +278,8 @@ void main() { dynamic tearoff = A().genericArity2; Expect.throws( () => tearoff(10), - (error) => error.toString().contains( - "NoSuchMethodError: 'bound genericArity2'", - ), + (error) => + error.toString().contains("NoSuchMethodError: 'genericArity2'"), ); }); test('class instance generic method tearoff instantiated', () { diff --git a/tests/hot_reload/tear_off_add_arguments/main.0.dart b/tests/hot_reload/tear_off_add_arguments/main.0.dart index 6299256b1b40..113ae4cc13ce 100644 --- a/tests/hot_reload/tear_off_add_arguments/main.0.dart +++ b/tests/hot_reload/tear_off_add_arguments/main.0.dart @@ -27,8 +27,5 @@ helper() { Future main() async { helper(); await hotReload(); - Expect.throws( - helper, - (err) => '$err'.contains("Class 'C' has no instance method " - "'foo' with matching arguments.")); + Expect.throws(helper); } diff --git a/tests/hot_reload/tear_off_add_arguments/main.1.dart b/tests/hot_reload/tear_off_add_arguments/main.1.dart index 2029fc8890b5..d30e47e7a4f4 100644 --- a/tests/hot_reload/tear_off_add_arguments/main.1.dart +++ b/tests/hot_reload/tear_off_add_arguments/main.1.dart @@ -26,11 +26,9 @@ helper() { Future main() async { helper(); await hotReload(); - Expect.throws( - helper, - (err) => '$err'.contains("Class 'C' has no instance method " - "'foo' with matching arguments.")); + Expect.throws(helper); } + /** DIFF **/ /* @@ -15,13 +15,12 @@ @@ -50,4 +48,9 @@ Future main() async { } Future main() async { +@@ -29,3 +28,4 @@ + await hotReload(); + Expect.throws(helper); + } ++ */ diff --git a/tests/hot_reload/tear_off_add_arguments2/main.0.dart b/tests/hot_reload/tear_off_add_arguments2/main.0.dart index 8c81487dcf03..3852d01f4a47 100644 --- a/tests/hot_reload/tear_off_add_arguments2/main.0.dart +++ b/tests/hot_reload/tear_off_add_arguments2/main.0.dart @@ -26,8 +26,5 @@ helper() { Future main() async { helper(); await hotReload(); - Expect.throws( - helper, - (err) => '$err'.contains("Closure call with mismatched arguments: " - "function 'C.foo'")); + Expect.throws(helper); } diff --git a/tests/hot_reload/tear_off_add_arguments2/main.1.dart b/tests/hot_reload/tear_off_add_arguments2/main.1.dart index 3e38aff820e1..be7ebc2a213f 100644 --- a/tests/hot_reload/tear_off_add_arguments2/main.1.dart +++ b/tests/hot_reload/tear_off_add_arguments2/main.1.dart @@ -26,11 +26,9 @@ helper() { Future main() async { helper(); await hotReload(); - Expect.throws( - helper, - (err) => '$err'.contains("Closure call with mismatched arguments: " - "function 'C.foo'")); + Expect.throws(helper); } + /** DIFF **/ /* @@ -15,12 +15,12 @@ @@ -49,4 +47,9 @@ Future main() async { } Future main() async { +@@ -28,3 +28,4 @@ + await hotReload(); + Expect.throws(helper); + } ++ */ diff --git a/tests/hot_reload/tear_off_add_arguments3/main.0.dart b/tests/hot_reload/tear_off_add_arguments3/main.0.dart new file mode 100644 index 000000000000..5a983a91ae97 --- /dev/null +++ b/tests/hot_reload/tear_off_add_arguments3/main.0.dart @@ -0,0 +1,18 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:expect/expect.dart'; +import 'package:reload_test/reload_test_utils.dart'; + +void foo(int a) => a + 1; + +Future main() async { + void Function() bar() { + return () => foo(3); + } + + final f = bar(); + await hotReload(); + Expect.throws(f); +} diff --git a/tests/hot_reload/tear_off_add_arguments3/main.1.dart b/tests/hot_reload/tear_off_add_arguments3/main.1.dart new file mode 100644 index 000000000000..a96dee62abfb --- /dev/null +++ b/tests/hot_reload/tear_off_add_arguments3/main.1.dart @@ -0,0 +1,40 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:expect/expect.dart'; +import 'package:reload_test/reload_test_utils.dart'; + +void foo(int a, int b) => a + b; + +Future main() async { + void Function() bar() { + return () => foo(3, 4); + } + + final f = bar(); + await hotReload(); + Expect.throws(f); +} + +/** DIFF **/ +/* +@@ -5,14 +5,15 @@ + import 'package:expect/expect.dart'; + import 'package:reload_test/reload_test_utils.dart'; + +-void foo(int a) => a + 1; ++void foo(int a, int b) => a + b; + + Future main() async { + void Function() bar() { +- return () => foo(3); ++ return () => foo(3, 4); + } + + final f = bar(); + await hotReload(); + Expect.throws(f); + } ++ +*/ diff --git a/tests/hot_reload/tear_off_instance_equality/main.0.dart b/tests/hot_reload/tear_off_instance_equality/main.0.dart index 034947b74697..a6e26199e42d 100644 --- a/tests/hot_reload/tear_off_instance_equality/main.0.dart +++ b/tests/hot_reload/tear_off_instance_equality/main.0.dart @@ -25,5 +25,7 @@ Future main() async { Expect.equals('new', f1()); Expect.equals('new', f2()); Expect.equals(f1, f2); + // We test that instance tearoffs are not identical to be consistent wih the + // VM. This behavior is not guaranteed by the spec. Expect.notIdentical(f1, f2); } diff --git a/tests/hot_reload/tear_off_instance_equality/main.1.dart b/tests/hot_reload/tear_off_instance_equality/main.1.dart index 21f260d718b5..e6002995f4a8 100644 --- a/tests/hot_reload/tear_off_instance_equality/main.1.dart +++ b/tests/hot_reload/tear_off_instance_equality/main.1.dart @@ -24,6 +24,8 @@ Future main() async { Expect.equals('new', f1()); Expect.equals('new', f2()); Expect.equals(f1, f2); + // We test that instance tearoffs are not identical to be consistent wih the + // VM. This behavior is not guaranteed by the spec. Expect.notIdentical(f1, f2); } /** DIFF **/ diff --git a/tools/VERSION b/tools/VERSION index 3187f78f919c..e5d66b546398 100644 --- a/tools/VERSION +++ b/tools/VERSION @@ -27,5 +27,5 @@ CHANNEL dev MAJOR 3 MINOR 7 PATCH 0 -PRERELEASE 311 +PRERELEASE 312 PRERELEASE_PATCH 0