diff --git a/DEPS b/DEPS index a22e73920fe2..fd13549cc3b4 100644 --- a/DEPS +++ b/DEPS @@ -168,7 +168,7 @@ vars = { "path_rev": "e969f42ed112dd702a9453beb9df6c12ae2d3805", "pool_rev": "924fb04353cec915d927f9f1aed88e2eda92b98a", "protobuf_rev": "ccf104dbc36929c0f8708285d5f3a8fae206343e", - "pub_rev": "23e3d4f4a761867b1e3eded9a92a4290a01daadb", # disable tools/rev_sdk_deps.dart + "pub_rev": "9adca58e4fa8e1d94924e64a184532231826496c", # disable tools/rev_sdk_deps.dart "pub_semver_rev": "d9e5ee68a350fbf4319bd4dfcb895fc016337d3a", "shelf_rev": "d53a8f9a98ccbe69078d397d45c2c6b3e7c243b6", "source_maps_rev": "5f82c613664ade03c7a6d0e6c59687c69dec894b", diff --git a/pkg/analysis_server/lib/src/services/completion/dart/in_scope_completion_pass.dart b/pkg/analysis_server/lib/src/services/completion/dart/in_scope_completion_pass.dart index fbd72ff770d6..7bfe1a6a467d 100644 --- a/pkg/analysis_server/lib/src/services/completion/dart/in_scope_completion_pass.dart +++ b/pkg/analysis_server/lib/src/services/completion/dart/in_scope_completion_pass.dart @@ -1887,7 +1887,7 @@ class InScopeCompletionPass extends SimpleAstVisitor { var target = node.realTarget; var type = target?.staticType; if (type != null) { - _forMemberAccess(node, node.parent, type); + _forMemberAccess(node, type); } if ((type == null || type is InvalidType || type.isDartCoreType) && target is Identifier && @@ -2192,7 +2192,7 @@ class InScopeCompletionPass extends SimpleAstVisitor { var target = node.prefix; var type = target.staticType; if (type != null) { - _forMemberAccess(node, node.parent, type); + _forMemberAccess(node, type, onlySuper: target is SuperExpression); } else { var element = target.staticElement; if (element != null) { @@ -2244,8 +2244,7 @@ class InScopeCompletionPass extends SimpleAstVisitor { } var type = target.staticType; if (type != null) { - _forMemberAccess(node, parent, type, - onlySuper: target is SuperExpression); + _forMemberAccess(node, type, onlySuper: target is SuperExpression); } if ((type == null || type is InvalidType || type.isDartCoreType) && target is Identifier && @@ -3165,6 +3164,19 @@ class InScopeCompletionPass extends SimpleAstVisitor { return null; } + bool _computeMustBeAssignable(Expression node) { + var request = state.request; + var lineInfo = request.fileState.lineInfo; + if (node.parent case AssignmentExpression assignment) { + if (assignment.leftHandSide == node) { + var requestLoc = lineInfo.getLocation(request.offset); + var opLoc = lineInfo.getLocation(assignment.operator.offset); + return requestLoc.lineNumber == opLoc.lineNumber; + } + } + return false; + } + /// Adds the suggestions that are appropriate at the beginning of an /// annotation. void _forAnnotation(AstNode node) { @@ -3407,19 +3419,24 @@ class InScopeCompletionPass extends SimpleAstVisitor { return false; } - /// Adds the suggestions that are appropriate when the [expression] is - /// referencing a member of the given [type]. The [parent] is the parent of - /// the [node]. - void _forMemberAccess(Expression node, AstNode? parent, DartType type, - {bool onlySuper = false}) { + /// Adds the suggestions that are appropriate when the [node] is + /// referencing a member of the given [type]. + void _forMemberAccess( + Expression node, + DartType type, { + bool onlySuper = false, + }) { + var parent = node.parent; // TODO(brianwilkerson): Handle the case of static member accesses. - var mustBeAssignable = - parent is AssignmentExpression && node == parent.leftHandSide; + var mustBeAssignable = _computeMustBeAssignable(node); declarationHelper( - mustBeAssignable: mustBeAssignable, - mustBeConstant: node.inConstantContext, - mustBeNonVoid: parent is ArgumentList) - .addInstanceMembersOfType(type, onlySuper: onlySuper); + mustBeAssignable: mustBeAssignable, + mustBeConstant: node.inConstantContext, + mustBeNonVoid: parent is ArgumentList, + ).addInstanceMembersOfType( + type, + onlySuper: onlySuper, + ); } /// Adds the suggestions that are appropriate when the selection is at the diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_call_super.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_call_super.dart index 5207afbda3f0..8b80b7cae91d 100644 --- a/pkg/analysis_server/lib/src/services/correction/dart/add_call_super.dart +++ b/pkg/analysis_server/lib/src/services/correction/dart/add_call_super.dart @@ -30,16 +30,18 @@ class AddCallSuper extends ResolvedCorrectionProducer { Future compute(ChangeBuilder builder) async { var methodDeclaration = node; if (methodDeclaration is! MethodDeclaration) return; - var classElement = methodDeclaration + + var classFragment = methodDeclaration .thisOrAncestorOfType() - ?.declaredElement; - if (classElement == null) return; + ?.declaredFragment; + if (classFragment == null) return; + var classElement = classFragment.element; var name = methodDeclaration.name.lexeme; - var nameObj = Name(classElement.library.source.uri, name); - var overridden = InheritanceManager3().getInherited2(classElement, nameObj); + var nameObj = Name.forLibrary(classElement.library2, name); + var overridden = InheritanceManager3().getInherited4(classElement, nameObj); if (overridden == null) return; - var overriddenParameters = overridden.parameters.map((p) => p.name); + var overriddenParameters = overridden.formalParameters.map((p) => p.name); var body = methodDeclaration.body; var parameters = methodDeclaration.parameters?.parameters; diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_diagnostic_property_reference.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_diagnostic_property_reference.dart index 51805ee34320..a3346d9c5717 100644 --- a/pkg/analysis_server/lib/src/services/correction/dart/add_diagnostic_property_reference.dart +++ b/pkg/analysis_server/lib/src/services/correction/dart/add_diagnostic_property_reference.dart @@ -8,7 +8,7 @@ import 'package:analysis_server/src/services/linter/lint_names.dart'; import 'package:analysis_server/src/utilities/extensions/flutter.dart'; import 'package:analysis_server_plugin/edit/dart/correction_producer.dart'; import 'package:analyzer/dart/ast/ast.dart'; -import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/element2.dart'; import 'package:analyzer/dart/element/type.dart'; import 'package:analyzer/error/error.dart'; import 'package:analyzer/src/dart/ast/utilities.dart'; @@ -48,13 +48,19 @@ class AddDiagnosticPropertyReference extends ResolvedCorrectionProducer { } var classDeclaration = node.thisOrAncestorOfType(); - if (classDeclaration == null || - // TODO(dantup): Remove this and update this fix to handle - // augmenting the method once augmented() expressions are - // fully implemented. - // https://github.com/dart-lang/sdk/issues/55326 - classDeclaration.declaredElement!.isAugmentation || - !classDeclaration.declaredElement!.thisType.isDiagnosticable) { + if (classDeclaration == null) { + return; + } + + var classFragment = classDeclaration.declaredFragment!; + var classElement = classFragment.element; + + // TODO(dantup): Remove this and update this fix to handle + // augmenting the method once augmented() expressions are + // fully implemented. + // https://github.com/dart-lang/sdk/issues/55326 + if (classFragment.isAugmentation || + !classElement.thisType.isDiagnosticable) { return; } @@ -418,24 +424,23 @@ class AddDiagnosticPropertyReference extends ResolvedCorrectionProducer { /// Return the return type of the given [node]. DartType? _getReturnType(AstNode node) { - if (node is MethodDeclaration) { - // Getter. - var element = node.declaredElement; - if (element is PropertyAccessorElement) { - return element.returnType; - } - } else if (node is VariableDeclaration) { - // Field. - var element = node.declaredElement; - if (element is FieldElement) { - return element.type; - } + switch (node) { + case MethodDeclaration(): + var element = node.declaredFragment?.element; + if (element is GetterElement) { + return element.returnType; + } + case VariableDeclaration(): + var element = node.declaredFragment?.element; + if (element is FieldElement2) { + return element.type; + } } return null; } bool _isEnum(DartType type) { - return type is InterfaceType && type.element is EnumElement; + return type is InterfaceType && type.element3 is EnumElement2; } bool _isIterable(DartType type) { diff --git a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_cascade.dart b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_cascade.dart index 2304034d8835..df02ecce8800 100644 --- a/pkg/analysis_server/lib/src/services/correction/dart/convert_to_cascade.dart +++ b/pkg/analysis_server/lib/src/services/correction/dart/convert_to_cascade.dart @@ -30,8 +30,20 @@ class ConvertToCascade extends ResolvedCorrectionProducer { if (block is! Block) return; var previous = _getPrevious(block, node); - if (previous is! ExpressionStatement) return; - var previousOperator = _getTargetAndOperator(previous.expression)?.operator; + Token? previousOperator; + Token? semicolon; + if (previous is ExpressionStatement) { + semicolon = previous.semicolon; + previousOperator = _getTargetAndOperator(previous.expression)?.operator; + } else if (previous is VariableDeclarationStatement) { + // Single variable declaration. + if (previous.variables.variables.length != 1) { + return; + } + semicolon = previous.endToken; + } else { + return; + } var expression = node.expression; var target = _getTargetAndOperator(expression)?.target; @@ -43,7 +55,9 @@ class ConvertToCascade extends ResolvedCorrectionProducer { if (previousOperator != null) { builder.addSimpleInsertion(previousOperator.offset, '.'); } - builder.addDeletion(range.token(previous.semicolon!)); + if (semicolon != null) { + builder.addDeletion(range.token(semicolon)); + } builder.addSimpleReplacement(range.node(target), targetReplacement); }); } diff --git a/pkg/analysis_server/test/services/completion/dart/location/property_access_expression_test.dart b/pkg/analysis_server/test/services/completion/dart/location/property_access_expression_test.dart index d12da88259dd..595b55ad3017 100644 --- a/pkg/analysis_server/test/services/completion/dart/location/property_access_expression_test.dart +++ b/pkg/analysis_server/test/services/completion/dart/location/property_access_expression_test.dart @@ -724,6 +724,50 @@ suggestions '''); } + Future test_property_assignmentLeft_newLine() async { + await computeSuggestions(''' +class A { + int? f01; + void m01() {} +} + +void f(A? a, Object? v01) { + a.^ + v01 = null; +} +'''); + + assertResponse(r''' +suggestions + f01 + kind: field + m01 + kind: methodInvocation +'''); + } + + Future test_property_assignmentLeft_newLine2() async { + await computeSuggestions(''' +class A { + int? f01; + void m01() {} +} + +void f(A? a, Object? v01) { + (a).^ + v01 = null; +} +'''); + + assertResponse(r''' +suggestions + f01 + kind: field + m01 + kind: methodInvocation +'''); + } + Future test_target_assignmentLeft() async { await computeSuggestions(''' void f(Object v01) { diff --git a/pkg/analysis_server/test/src/services/correction/fix/convert_to_cascade_test.dart b/pkg/analysis_server/test/src/services/correction/fix/convert_to_cascade_test.dart index 66c1a2a2e40d..02749a4e5f62 100644 --- a/pkg/analysis_server/test/src/services/correction/fix/convert_to_cascade_test.dart +++ b/pkg/analysis_server/test/src/services/correction/fix/convert_to_cascade_test.dart @@ -50,6 +50,27 @@ void f(A a) { '''); } + Future test_declaration_method() async { + await resolveTestCode(''' +class A { + void m() {} +} +void f() { + final a = A(); + a.m(); +} +'''); + await assertHasFix(''' +class A { + void m() {} +} +void f() { + final a = A() + ..m(); +} +'''); + } + Future test_method_method() async { await resolveTestCode(''' class A { @@ -96,6 +117,32 @@ void f(A a) { '''); } + Future test_multipleDeclaration_first_method() async { + await resolveTestCode(''' +class A { + void m() {} +} +void f() { + final a = A(), a2 = A(); + a.m(); +} +'''); + await assertNoFix(); + } + + Future test_multipleDeclaration_last_method() async { + await resolveTestCode(''' +class A { + void m() {} +} +void f() { + final a = A(), a2 = A(); + a2.m(); +} +'''); + await assertNoFix(); + } + Future test_property_cascade() async { await resolveTestCode(''' class A { diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart index e70b7cdf496e..fc84c3cc81e4 100644 --- a/pkg/analyzer/lib/src/dart/ast/ast.dart +++ b/pkg/analyzer/lib/src/dart/ast/ast.dart @@ -18409,6 +18409,13 @@ abstract final class VariableDeclaration @override VariableElement? get declaredElement; + /// The element declared by this declaration. + /// + /// Returns `null` if the AST structure hasn't been resolved or if this node + /// represents the declaration of a top-level variable or a field. + @experimental + LocalVariableElement2? get declaredElement2; + /// The fragment declared by this declaration. /// /// Returns `null` if the AST structure hasn't been resolved or if this node @@ -18472,6 +18479,12 @@ final class VariableDeclarationImpl extends DeclarationImpl _becomeParentOf(_initializer); } + @experimental + @override + LocalVariableElement2? get declaredElement2 { + return declaredElement.asElement2 as LocalVariableElement2; + } + @experimental @override VariableFragment? get declaredFragment { diff --git a/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart b/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart index 2c0b725be0c9..56f78b7e0363 100644 --- a/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart +++ b/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart @@ -1289,6 +1289,11 @@ class Name { } } + factory Name.forLibrary(LibraryElement2 library, String name) { + var uri = library.firstFragment.source.uri; + return Name(uri, name); + } + Name._internal(this.libraryUri, this.name, this.isPublic, this.hashCode); Name get forGetter { diff --git a/pkg/analyzer/lib/src/error/codes.g.dart b/pkg/analyzer/lib/src/error/codes.g.dart index 4e815ca29047..ea181a6fa604 100644 --- a/pkg/analyzer/lib/src/error/codes.g.dart +++ b/pkg/analyzer/lib/src/error/codes.g.dart @@ -696,124 +696,124 @@ class CompileTimeErrorCode extends AnalyzerErrorCode { ); /// Parameters: - /// 0: the name of the type variable + /// 0: the name of the type parameter static const CompileTimeErrorCode CONFLICTING_TYPE_VARIABLE_AND_CLASS = CompileTimeErrorCode( 'CONFLICTING_TYPE_VARIABLE_AND_CONTAINER', - "'{0}' can't be used to name both a type variable and the class in which " - "the type variable is defined.", - correctionMessage: "Try renaming either the type variable or the class.", + "'{0}' can't be used to name both a type parameter and the class in which " + "the type parameter is defined.", + correctionMessage: "Try renaming either the type parameter or the class.", hasPublishedDocs: true, uniqueName: 'CONFLICTING_TYPE_VARIABLE_AND_CLASS', ); /// Parameters: - /// 0: the name of the type variable + /// 0: the name of the type parameter static const CompileTimeErrorCode CONFLICTING_TYPE_VARIABLE_AND_ENUM = CompileTimeErrorCode( 'CONFLICTING_TYPE_VARIABLE_AND_CONTAINER', - "'{0}' can't be used to name both a type variable and the enum in which " - "the type variable is defined.", - correctionMessage: "Try renaming either the type variable or the enum.", + "'{0}' can't be used to name both a type parameter and the enum in which " + "the type parameter is defined.", + correctionMessage: "Try renaming either the type parameter or the enum.", hasPublishedDocs: true, uniqueName: 'CONFLICTING_TYPE_VARIABLE_AND_ENUM', ); /// Parameters: - /// 0: the name of the type variable + /// 0: the name of the type parameter static const CompileTimeErrorCode CONFLICTING_TYPE_VARIABLE_AND_EXTENSION = CompileTimeErrorCode( 'CONFLICTING_TYPE_VARIABLE_AND_CONTAINER', - "'{0}' can't be used to name both a type variable and the extension in " - "which the type variable is defined.", + "'{0}' can't be used to name both a type parameter and the extension in " + "which the type parameter is defined.", correctionMessage: - "Try renaming either the type variable or the extension.", + "Try renaming either the type variaparameterble or the extension.", hasPublishedDocs: true, uniqueName: 'CONFLICTING_TYPE_VARIABLE_AND_EXTENSION', ); /// Parameters: - /// 0: the name of the type variable + /// 0: the name of the type parameter static const CompileTimeErrorCode CONFLICTING_TYPE_VARIABLE_AND_EXTENSION_TYPE = CompileTimeErrorCode( 'CONFLICTING_TYPE_VARIABLE_AND_CONTAINER', - "'{0}' can't be used to name both a type variable and the extension type " - "in which the type variable is defined.", + "'{0}' can't be used to name both a type parameter and the extension type " + "in which the type parameter is defined.", correctionMessage: - "Try renaming either the type variable or the extension.", + "Try renaming either the type parameter or the extension.", hasPublishedDocs: true, uniqueName: 'CONFLICTING_TYPE_VARIABLE_AND_EXTENSION_TYPE', ); /// Parameters: - /// 0: the name of the type variable + /// 0: the name of the type parameter static const CompileTimeErrorCode CONFLICTING_TYPE_VARIABLE_AND_MEMBER_CLASS = CompileTimeErrorCode( 'CONFLICTING_TYPE_VARIABLE_AND_MEMBER', - "'{0}' can't be used to name both a type variable and a member in this " + "'{0}' can't be used to name both a type parameter and a member in this " "class.", - correctionMessage: "Try renaming either the type variable or the member.", + correctionMessage: "Try renaming either the type parameter or the member.", hasPublishedDocs: true, uniqueName: 'CONFLICTING_TYPE_VARIABLE_AND_MEMBER_CLASS', ); /// Parameters: - /// 0: the name of the type variable + /// 0: the name of the type parameter static const CompileTimeErrorCode CONFLICTING_TYPE_VARIABLE_AND_MEMBER_ENUM = CompileTimeErrorCode( 'CONFLICTING_TYPE_VARIABLE_AND_MEMBER', - "'{0}' can't be used to name both a type variable and a member in this " + "'{0}' can't be used to name both a type parameter and a member in this " "enum.", - correctionMessage: "Try renaming either the type variable or the member.", + correctionMessage: "Try renaming either the type parameter or the member.", hasPublishedDocs: true, uniqueName: 'CONFLICTING_TYPE_VARIABLE_AND_MEMBER_ENUM', ); /// Parameters: - /// 0: the name of the type variable + /// 0: the name of the type parameter static const CompileTimeErrorCode CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION = CompileTimeErrorCode( 'CONFLICTING_TYPE_VARIABLE_AND_MEMBER', - "'{0}' can't be used to name both a type variable and a member in this " + "'{0}' can't be used to name both a type parameter and a member in this " "extension.", - correctionMessage: "Try renaming either the type variable or the member.", + correctionMessage: "Try renaming either the type parameter or the member.", hasPublishedDocs: true, uniqueName: 'CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION', ); /// Parameters: - /// 0: the name of the type variable + /// 0: the name of the type parameter static const CompileTimeErrorCode CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION_TYPE = CompileTimeErrorCode( 'CONFLICTING_TYPE_VARIABLE_AND_MEMBER', - "'{0}' can't be used to name both a type variable and a member in this " + "'{0}' can't be used to name both a type parameter and a member in this " "extension type.", - correctionMessage: "Try renaming either the type variable or the member.", + correctionMessage: "Try renaming either the type parameter or the member.", hasPublishedDocs: true, uniqueName: 'CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION_TYPE', ); /// Parameters: - /// 0: the name of the type variable + /// 0: the name of the type parameter static const CompileTimeErrorCode CONFLICTING_TYPE_VARIABLE_AND_MEMBER_MIXIN = CompileTimeErrorCode( 'CONFLICTING_TYPE_VARIABLE_AND_MEMBER', - "'{0}' can't be used to name both a type variable and a member in this " + "'{0}' can't be used to name both a type parameter and a member in this " "mixin.", - correctionMessage: "Try renaming either the type variable or the member.", + correctionMessage: "Try renaming either the type parameter or the member.", hasPublishedDocs: true, uniqueName: 'CONFLICTING_TYPE_VARIABLE_AND_MEMBER_MIXIN', ); /// Parameters: - /// 0: the name of the type variable + /// 0: the name of the type parameter static const CompileTimeErrorCode CONFLICTING_TYPE_VARIABLE_AND_MIXIN = CompileTimeErrorCode( 'CONFLICTING_TYPE_VARIABLE_AND_CONTAINER', - "'{0}' can't be used to name both a type variable and the mixin in which " - "the type variable is defined.", - correctionMessage: "Try renaming either the type variable or the mixin.", + "'{0}' can't be used to name both a type parameter and the mixin in which " + "the type parameter is defined.", + correctionMessage: "Try renaming either the type parameter or the mixin.", hasPublishedDocs: true, uniqueName: 'CONFLICTING_TYPE_VARIABLE_AND_MIXIN', ); diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml index 77d5a5bca39f..7ffd9e88d5ca 100644 --- a/pkg/analyzer/messages.yaml +++ b/pkg/analyzer/messages.yaml @@ -2340,12 +2340,12 @@ CompileTimeErrorCode: 2: the name of the class defining the field with which the method conflicts CONFLICTING_TYPE_VARIABLE_AND_CLASS: sharedName: CONFLICTING_TYPE_VARIABLE_AND_CONTAINER - problemMessage: "'{0}' can't be used to name both a type variable and the class in which the type variable is defined." - correctionMessage: Try renaming either the type variable or the class. + problemMessage: "'{0}' can't be used to name both a type parameter and the class in which the type parameter is defined." + correctionMessage: Try renaming either the type parameter or the class. hasPublishedDocs: true comment: |- Parameters: - 0: the name of the type variable + 0: the name of the type parameter documentation: |- #### Description @@ -2371,44 +2371,44 @@ CompileTimeErrorCode: ``` CONFLICTING_TYPE_VARIABLE_AND_ENUM: sharedName: CONFLICTING_TYPE_VARIABLE_AND_CONTAINER - problemMessage: "'{0}' can't be used to name both a type variable and the enum in which the type variable is defined." - correctionMessage: Try renaming either the type variable or the enum. + problemMessage: "'{0}' can't be used to name both a type parameter and the enum in which the type parameter is defined." + correctionMessage: Try renaming either the type parameter or the enum. hasPublishedDocs: true comment: |- Parameters: - 0: the name of the type variable + 0: the name of the type parameter CONFLICTING_TYPE_VARIABLE_AND_EXTENSION: sharedName: CONFLICTING_TYPE_VARIABLE_AND_CONTAINER - problemMessage: "'{0}' can't be used to name both a type variable and the extension in which the type variable is defined." - correctionMessage: Try renaming either the type variable or the extension. + problemMessage: "'{0}' can't be used to name both a type parameter and the extension in which the type parameter is defined." + correctionMessage: Try renaming either the type variaparameterble or the extension. hasPublishedDocs: true comment: |- Parameters: - 0: the name of the type variable + 0: the name of the type parameter CONFLICTING_TYPE_VARIABLE_AND_EXTENSION_TYPE: sharedName: CONFLICTING_TYPE_VARIABLE_AND_CONTAINER - problemMessage: "'{0}' can't be used to name both a type variable and the extension type in which the type variable is defined." - correctionMessage: Try renaming either the type variable or the extension. + problemMessage: "'{0}' can't be used to name both a type parameter and the extension type in which the type parameter is defined." + correctionMessage: Try renaming either the type parameter or the extension. hasPublishedDocs: true comment: |- Parameters: - 0: the name of the type variable + 0: the name of the type parameter CONFLICTING_TYPE_VARIABLE_AND_MIXIN: sharedName: CONFLICTING_TYPE_VARIABLE_AND_CONTAINER - problemMessage: "'{0}' can't be used to name both a type variable and the mixin in which the type variable is defined." - correctionMessage: Try renaming either the type variable or the mixin. + problemMessage: "'{0}' can't be used to name both a type parameter and the mixin in which the type parameter is defined." + correctionMessage: Try renaming either the type parameter or the mixin. hasPublishedDocs: true comment: |- Parameters: - 0: the name of the type variable + 0: the name of the type parameter CONFLICTING_TYPE_VARIABLE_AND_MEMBER_CLASS: sharedName: CONFLICTING_TYPE_VARIABLE_AND_MEMBER - problemMessage: "'{0}' can't be used to name both a type variable and a member in this class." - correctionMessage: Try renaming either the type variable or the member. + problemMessage: "'{0}' can't be used to name both a type parameter and a member in this class." + correctionMessage: Try renaming either the type parameter or the member. hasPublishedDocs: true comment: |- Parameters: - 0: the name of the type variable + 0: the name of the type parameter documentation: |- #### Description @@ -2438,36 +2438,36 @@ CompileTimeErrorCode: ``` CONFLICTING_TYPE_VARIABLE_AND_MEMBER_MIXIN: sharedName: CONFLICTING_TYPE_VARIABLE_AND_MEMBER - problemMessage: "'{0}' can't be used to name both a type variable and a member in this mixin." - correctionMessage: Try renaming either the type variable or the member. + problemMessage: "'{0}' can't be used to name both a type parameter and a member in this mixin." + correctionMessage: Try renaming either the type parameter or the member. hasPublishedDocs: true comment: |- Parameters: - 0: the name of the type variable + 0: the name of the type parameter CONFLICTING_TYPE_VARIABLE_AND_MEMBER_ENUM: sharedName: CONFLICTING_TYPE_VARIABLE_AND_MEMBER - problemMessage: "'{0}' can't be used to name both a type variable and a member in this enum." - correctionMessage: Try renaming either the type variable or the member. + problemMessage: "'{0}' can't be used to name both a type parameter and a member in this enum." + correctionMessage: Try renaming either the type parameter or the member. hasPublishedDocs: true comment: |- Parameters: - 0: the name of the type variable + 0: the name of the type parameter CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION: sharedName: CONFLICTING_TYPE_VARIABLE_AND_MEMBER - problemMessage: "'{0}' can't be used to name both a type variable and a member in this extension." - correctionMessage: Try renaming either the type variable or the member. + problemMessage: "'{0}' can't be used to name both a type parameter and a member in this extension." + correctionMessage: Try renaming either the type parameter or the member. hasPublishedDocs: true comment: |- Parameters: - 0: the name of the type variable + 0: the name of the type parameter CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION_TYPE: sharedName: CONFLICTING_TYPE_VARIABLE_AND_MEMBER - problemMessage: "'{0}' can't be used to name both a type variable and a member in this extension type." - correctionMessage: Try renaming either the type variable or the member. + problemMessage: "'{0}' can't be used to name both a type parameter and a member in this extension type." + correctionMessage: Try renaming either the type parameter or the member. hasPublishedDocs: true comment: |- Parameters: - 0: the name of the type variable + 0: the name of the type parameter CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH: problemMessage: "In a const constructor, a value of type '{0}' can't be assigned to the field '{1}', which has type '{2}'." correctionMessage: "Try using a subtype, or removing the keyword 'const'." @@ -8675,7 +8675,8 @@ CompileTimeErrorCode: method. The concrete implementation can be invalid because of incompatibilities in - either the return type, the types of parameters, or the type variables. + either the return type, the types of the method's parameters, or the type + parameters. #### Example diff --git a/pkg/analyzer/tool/diagnostics/diagnostics.md b/pkg/analyzer/tool/diagnostics/diagnostics.md index 4c38437045fe..d6b659ffe57d 100644 --- a/pkg/analyzer/tool/diagnostics/diagnostics.md +++ b/pkg/analyzer/tool/diagnostics/diagnostics.md @@ -2614,20 +2614,20 @@ class C extends A implements B {} ### conflicting_type_variable_and_container -_'{0}' can't be used to name both a type variable and the class in which the -type variable is defined._ +_'{0}' can't be used to name both a type parameter and the class in which the +type parameter is defined._ -_'{0}' can't be used to name both a type variable and the enum in which the type -variable is defined._ +_'{0}' can't be used to name both a type parameter and the enum in which the +type parameter is defined._ -_'{0}' can't be used to name both a type variable and the extension in which the -type variable is defined._ +_'{0}' can't be used to name both a type parameter and the extension in which +the type parameter is defined._ -_'{0}' can't be used to name both a type variable and the extension type in -which the type variable is defined._ +_'{0}' can't be used to name both a type parameter and the extension type in +which the type parameter is defined._ -_'{0}' can't be used to name both a type variable and the mixin in which the -type variable is defined._ +_'{0}' can't be used to name both a type parameter and the mixin in which the +type parameter is defined._ #### Description @@ -2654,17 +2654,17 @@ class C {} ### conflicting_type_variable_and_member -_'{0}' can't be used to name both a type variable and a member in this class._ +_'{0}' can't be used to name both a type parameter and a member in this class._ -_'{0}' can't be used to name both a type variable and a member in this enum._ +_'{0}' can't be used to name both a type parameter and a member in this enum._ -_'{0}' can't be used to name both a type variable and a member in this extension -type._ +_'{0}' can't be used to name both a type parameter and a member in this +extension type._ -_'{0}' can't be used to name both a type variable and a member in this +_'{0}' can't be used to name both a type parameter and a member in this extension._ -_'{0}' can't be used to name both a type variable and a member in this mixin._ +_'{0}' can't be used to name both a type parameter and a member in this mixin._ #### Description @@ -10281,7 +10281,8 @@ The analyzer produces this diagnostic when all of the following are true: method. The concrete implementation can be invalid because of incompatibilities in -either the return type, the types of parameters, or the type variables. +either the return type, the types of the method's parameters, or the type +parameters. #### Example diff --git a/pkg/dev_compiler/lib/js/ddc/ddc_module_loader.js b/pkg/dev_compiler/lib/js/ddc/ddc_module_loader.js index 7ecde9a91d3f..26dae950c668 100644 --- a/pkg/dev_compiler/lib/js/ddc/ddc_module_loader.js +++ b/pkg/dev_compiler/lib/js/ddc/ddc_module_loader.js @@ -1432,14 +1432,20 @@ if (!self.deferred_loader) { throw 'Library not defined: ' + libraryName + '. Failed to initialize.'; } currentLibrary = initializer(currentLibrary); + // We make the library available in the map before linking to break out + // of cycles in library dependencies. + // Invariant: during linking a library dependency can be read in a state + // where it is initialized but may not be linked. + this.libraries[libraryName] = currentLibrary; // Link the library. This action will trigger the initialization and // linking of dependency libraries as needed. currentLibrary.link(); - this.libraries[libraryName] = currentLibrary; } if (installFn != null) { installFn(currentLibrary); } + // Invariant: at this point the library and all of its recursive + // dependencies are fully initialized and linked. return currentLibrary; } @@ -1528,29 +1534,38 @@ if (!self.deferred_loader) { /** * Completes a hot reload operation. + * + * This method runs synchronously to guarantee that all libraries + * are in a consistent state before yielding control back to the + * application. */ hotReloadEnd() { - let oldLibraries = Object.create(null); - // Remove all the current library values to ensure all reloaded libraries - // get fresh copies of each other when imported. + // On a hot reload, we reuse the existing library objects to ensure all + // references remain valid and continue to be unique. We track in + // `previouslyLoaded` which libraries already exist in the system, so we + // can properly initialize and link them with the new version of the code. + let previouslyLoaded = Object.create(null); for (let name of this.pendingHotReloadLibraryNames) { - oldLibraries[name] = this.libraries[name]; - this.libraries[name] = null; + previouslyLoaded[name] = (this.libraries[name] != null); } - // Initialize all reloaded libraries. + + // All initializers are updated, but only libraries that were previously + // loaded need to be reinitialized. for (let name of this.pendingHotReloadLibraryNames) { - let currentLibrary = oldLibraries[name]; - if (currentLibrary == null) { - currentLibrary = this.createEmptyLibrary(); - } let initializer = this.pendingHotReloadLibraryInitializers[name]; this.libraryInitializers[name] = initializer; - this.libraries[name] = initializer(currentLibrary); + if (previouslyLoaded[name]) { + initializer(this.libraries[name]); + } } - // Link all reloaded libraries. + + // Then we link the existing libraries. Note this may trigger initializing + // and linking new library dependencies that were not present before and + // requires for all library intitializers to be up to date. for (let name in this.pendingHotReloadLibraryInitializers) { - let currentLibrary = this.libraries[name]; - currentLibrary.link(); + if (previouslyLoaded[name]) { + this.libraries[name].link(); + } } // Cleanup. this.pendingHotReloadLibraryInitializers = Object.create(null); diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart index 955764da0fe8..ea955fee6a90 100644 --- a/pkg/dev_compiler/lib/src/kernel/compiler.dart +++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart @@ -632,7 +632,7 @@ class ProgramCompiler extends ComputeOnceConstantVisitor if (_constLazyAccessors.isNotEmpty) { var constTableBody = _runtimeStatement( - 'defineLazy(#, { # }, false)', [_constTable, _constLazyAccessors]); + 'defineLazy(#, { # })', [_constTable, _constLazyAccessors]); _moduleItems.insert(_constTableInsertionIndex, constTableBody); _constLazyAccessors.clear(); } @@ -2762,8 +2762,7 @@ class ProgramCompiler extends ComputeOnceConstantVisitor } _currentUri = savedUri; - return _runtimeStatement( - 'defineLazy(#, { # }, #)', [objExpr, accessors, js.boolean(false)]); + return _runtimeStatement('defineLazy(#, { # })', [objExpr, accessors]); } js_ast.Fun _emitStaticFieldInitializer(Field field) { @@ -3610,7 +3609,7 @@ class ProgramCompiler extends ComputeOnceConstantVisitor .add(js.statement('const # = Object.create(null);', [_constTable])); constTable.add(_runtimeStatement( - 'defineLazy(#, { # }, false)', [_constTable, _constLazyAccessors])); + 'defineLazy(#, { # })', [_constTable, _constLazyAccessors])); constTable.addAll(_constTableCache.emit()); } diff --git a/pkg/dev_compiler/lib/src/kernel/compiler_new.dart b/pkg/dev_compiler/lib/src/kernel/compiler_new.dart index 7e8a8ed84ece..6ef2783c6321 100644 --- a/pkg/dev_compiler/lib/src/kernel/compiler_new.dart +++ b/pkg/dev_compiler/lib/src/kernel/compiler_new.dart @@ -731,7 +731,7 @@ class LibraryCompiler extends ComputeOnceConstantVisitor if (_constLazyAccessors.isNotEmpty) { var constTableBody = _runtimeStatement( - 'defineLazy(#, { # }, false)', [_constTable, _constLazyAccessors]); + 'defineLazy(#, { # })', [_constTable, _constLazyAccessors]); _moduleItems.insert(_constTableInsertionIndex, constTableBody); _constLazyAccessors.clear(); } @@ -2892,8 +2892,7 @@ class LibraryCompiler extends ComputeOnceConstantVisitor } _currentUri = savedUri; - return _runtimeStatement( - 'defineLazy(#, { # }, #)', [objExpr, accessors, js.boolean(false)]); + return _runtimeStatement('defineLazy(#, { # })', [objExpr, accessors]); } js_ast.Fun _emitStaticFieldInitializer(Field field) { @@ -3690,7 +3689,7 @@ class LibraryCompiler extends ComputeOnceConstantVisitor .add(js.statement('const # = Object.create(null);', [_constTable])); constTable.add(_runtimeStatement( - 'defineLazy(#, { # }, false)', [_constTable, _constLazyAccessors])); + 'defineLazy(#, { # })', [_constTable, _constLazyAccessors])); constTable.addAll(_constTableCache.emit()); } diff --git a/pkg/linter/lib/src/rules/avoid_catches_without_on_clauses.dart b/pkg/linter/lib/src/rules/avoid_catches_without_on_clauses.dart index 6cdcf8bfb24e..70dfffcd921f 100644 --- a/pkg/linter/lib/src/rules/avoid_catches_without_on_clauses.dart +++ b/pkg/linter/lib/src/rules/avoid_catches_without_on_clauses.dart @@ -4,7 +4,7 @@ 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/dart/element/type.dart'; import '../analyzer.dart'; @@ -32,7 +32,7 @@ class AvoidCatchesWithoutOnClauses extends LintRule { } class _CaughtExceptionUseVisitor extends RecursiveAstVisitor { - final Element caughtException; + final Element2 caughtException; var exceptionWasUsed = false; @@ -40,14 +40,14 @@ class _CaughtExceptionUseVisitor extends RecursiveAstVisitor { @override void visitSimpleIdentifier(SimpleIdentifier node) { - if (node.staticElement == caughtException) { + if (node.element == caughtException) { exceptionWasUsed = true; } } } class _ValidUseVisitor extends RecursiveAstVisitor { - final Element caughtException; + final Element2 caughtException; bool hasValidUse = false; @@ -86,8 +86,8 @@ class _ValidUseVisitor extends RecursiveAstVisitor { _checkUseInArgument(node.argumentList); } else if (node.methodName.name == 'reportError') { var target = node.realTarget; - var targetElement = target is Identifier ? target.staticElement : null; - if (targetElement is ClassElement && + var targetElement = target is Identifier ? target.element : null; + if (targetElement is ClassElement2 && targetElement.name == 'FlutterError') { _checkUseInArgument(node.argumentList); } @@ -136,7 +136,7 @@ class _Visitor extends SimpleAstVisitor { @override void visitCatchClause(CatchClause node) { if (node.onKeyword != null) return; - var caughtException = node.exceptionParameter?.declaredElement; + var caughtException = node.exceptionParameter?.declaredElement2; if (caughtException == null) return; var validUseVisitor = _ValidUseVisitor(caughtException); diff --git a/pkg/linter/lib/src/rules/avoid_double_and_int_checks.dart b/pkg/linter/lib/src/rules/avoid_double_and_int_checks.dart index b8afe508ad31..52de5cd60b60 100644 --- a/pkg/linter/lib/src/rules/avoid_double_and_int_checks.dart +++ b/pkg/linter/lib/src/rules/avoid_double_and_int_checks.dart @@ -4,7 +4,7 @@ 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 '../analyzer.dart'; import '../linter_lint_codes.dart'; @@ -51,8 +51,8 @@ class _Visitor extends SimpleAstVisitor { ifExpression.name == elseIsExpression.name && ifCondition.type.type == typeProvider.doubleType && elseCondition.type.type == typeProvider.intType && - (ifExpression.staticElement is ParameterElement || - ifExpression.staticElement is LocalVariableElement)) { + (ifExpression.element is FormalParameterElement || + ifExpression.element is LocalVariableElement2)) { rule.reportLint(elseCondition); } } diff --git a/pkg/linter/lib/src/rules/avoid_shadowing_type_parameters.dart b/pkg/linter/lib/src/rules/avoid_shadowing_type_parameters.dart index 9f249f44bbd9..eb9484fe9a6c 100644 --- a/pkg/linter/lib/src/rules/avoid_shadowing_type_parameters.dart +++ b/pkg/linter/lib/src/rules/avoid_shadowing_type_parameters.dart @@ -5,7 +5,7 @@ import 'package:analyzer/dart/analysis/features.dart'; import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/ast/visitor.dart'; -import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/element2.dart'; import '../analyzer.dart'; import '../linter_lint_codes.dart'; @@ -25,7 +25,7 @@ class AvoidShadowingTypeParameters extends LintRule { @override void registerNodeProcessors( NodeLintRegistry registry, LinterContext context) { - var visitor = _Visitor(this, context.libraryElement); + var visitor = _Visitor(this, context.libraryElement2); registry.addFunctionDeclarationStatement(this, visitor); registry.addGenericTypeAlias(this, visitor); registry.addMethodDeclaration(this, visitor); @@ -38,7 +38,7 @@ class _Visitor extends SimpleAstVisitor { final LintRule rule; - _Visitor(this.rule, LibraryElement? library) + _Visitor(this.rule, LibraryElement2? library) : _wildCardVariablesEnabled = library?.featureSet.isEnabled(Feature.wildcard_variables) ?? false; diff --git a/pkg/linter/lib/src/rules/library_prefixes.dart b/pkg/linter/lib/src/rules/library_prefixes.dart index 553f2a4e9a79..3b1cfa23de8c 100644 --- a/pkg/linter/lib/src/rules/library_prefixes.dart +++ b/pkg/linter/lib/src/rules/library_prefixes.dart @@ -5,7 +5,7 @@ import 'package:analyzer/dart/analysis/features.dart'; import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/ast/visitor.dart'; -import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/element2.dart'; import '../analyzer.dart'; import '../linter_lint_codes.dart'; @@ -27,7 +27,7 @@ class LibraryPrefixes extends LintRule { @override void registerNodeProcessors( NodeLintRegistry registry, LinterContext context) { - var visitor = _Visitor(this, context.libraryElement); + var visitor = _Visitor(this, context.libraryElement2); registry.addImportDirective(this, visitor); } } @@ -38,7 +38,7 @@ class _Visitor extends SimpleAstVisitor { final LintRule rule; - _Visitor(this.rule, LibraryElement? library) + _Visitor(this.rule, LibraryElement2? library) : _wildCardVariablesEnabled = library?.featureSet.isEnabled(Feature.wildcard_variables) ?? false; diff --git a/pkg/linter/lib/src/rules/no_leading_underscores_for_library_prefixes.dart b/pkg/linter/lib/src/rules/no_leading_underscores_for_library_prefixes.dart index 30636bf77013..5721d53eb492 100644 --- a/pkg/linter/lib/src/rules/no_leading_underscores_for_library_prefixes.dart +++ b/pkg/linter/lib/src/rules/no_leading_underscores_for_library_prefixes.dart @@ -5,7 +5,7 @@ import 'package:analyzer/dart/analysis/features.dart'; import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/ast/visitor.dart'; -import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/element2.dart'; import '../analyzer.dart'; import '../linter_lint_codes.dart'; @@ -27,7 +27,7 @@ class NoLeadingUnderscoresForLibraryPrefixes extends LintRule { @override void registerNodeProcessors( NodeLintRegistry registry, LinterContext context) { - var visitor = _Visitor(this, context.libraryElement); + var visitor = _Visitor(this, context.libraryElement2); registry.addImportDirective(this, visitor); } } @@ -38,7 +38,7 @@ class _Visitor extends SimpleAstVisitor { final LintRule rule; - _Visitor(this.rule, LibraryElement? library) + _Visitor(this.rule, LibraryElement2? library) : _wildCardVariablesEnabled = library?.featureSet.isEnabled(Feature.wildcard_variables) ?? false; diff --git a/pkg/linter/lib/src/rules/prefer_collection_literals.dart b/pkg/linter/lib/src/rules/prefer_collection_literals.dart index 7e091865fb37..e7a286ac6666 100644 --- a/pkg/linter/lib/src/rules/prefer_collection_literals.dart +++ b/pkg/linter/lib/src/rules/prefer_collection_literals.dart @@ -4,7 +4,7 @@ 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/dart/element/type.dart'; import 'package:analyzer/dart/element/type_provider.dart'; @@ -42,7 +42,7 @@ class _Visitor extends SimpleAstVisitor { void visitInstanceCreationExpression(InstanceCreationExpression node) { var constructorName = node.constructorName.name?.name; - if (node.constructorName.type.element is TypeAliasElement) { + if (node.constructorName.type.element2 is TypeAliasElement2) { // Allow the use of typedef constructors. return; } diff --git a/pkg/linter/lib/src/rules/tighten_type_of_initializing_formals.dart b/pkg/linter/lib/src/rules/tighten_type_of_initializing_formals.dart index c6884924f5fa..0354c019f17a 100644 --- a/pkg/linter/lib/src/rules/tighten_type_of_initializing_formals.dart +++ b/pkg/linter/lib/src/rules/tighten_type_of_initializing_formals.dart @@ -5,7 +5,7 @@ import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/ast/token.dart'; import 'package:analyzer/dart/ast/visitor.dart'; -import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/element2.dart'; import '../analyzer.dart'; import '../linter_lint_codes.dart'; @@ -51,7 +51,7 @@ class _Visitor extends SimpleAstVisitor { var staticType = leftOperand.staticType; if (staticType != null && context.typeSystem.isNullable(staticType)) { - _check(leftOperand.staticElement, node); + _check(leftOperand.element, node); } } } else if (condition.leftOperand is NullLiteral) { @@ -60,7 +60,7 @@ class _Visitor extends SimpleAstVisitor { var staticType = rightOperand.staticType; if (staticType != null && context.typeSystem.isNullable(staticType)) { - _check(rightOperand.staticElement, node); + _check(rightOperand.element, node); } } } @@ -68,11 +68,11 @@ class _Visitor extends SimpleAstVisitor { } } - void _check(Element? element, ConstructorDeclaration node) { - if (element is FieldFormalParameterElement || - element is SuperFormalParameterElement) { + void _check(Element2? element, ConstructorDeclaration node) { + if (element is FieldFormalParameterElement2 || + element is SuperFormalParameterElement2) { rule.reportLint(node.parameters.parameters - .firstWhere((p) => p.declaredElement == element)); + .firstWhere((p) => p.declaredFragment?.element == element)); } } } diff --git a/pkg/linter/lib/src/rules/unnecessary_null_aware_assignments.dart b/pkg/linter/lib/src/rules/unnecessary_null_aware_assignments.dart index 91facfbab21d..673eccc05590 100644 --- a/pkg/linter/lib/src/rules/unnecessary_null_aware_assignments.dart +++ b/pkg/linter/lib/src/rules/unnecessary_null_aware_assignments.dart @@ -5,7 +5,7 @@ import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/ast/token.dart'; import 'package:analyzer/dart/ast/visitor.dart'; -import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/element2.dart'; import '../analyzer.dart'; import '../extensions.dart'; @@ -38,8 +38,7 @@ class _Visitor extends SimpleAstVisitor { @override void visitAssignmentExpression(AssignmentExpression node) { - if (node.readElement is PropertyAccessorElement) return; - if (node.writeElement is PropertyAccessorElement) return; + if (node.writeElement2 is SetterElement) return; if (node.operator.type == TokenType.QUESTION_QUESTION_EQ && node.rightHandSide.isNullLiteral) { diff --git a/pkg/linter/lib/src/rules/unnecessary_parenthesis.dart b/pkg/linter/lib/src/rules/unnecessary_parenthesis.dart index 20c58dba0623..9b19455b7427 100644 --- a/pkg/linter/lib/src/rules/unnecessary_parenthesis.dart +++ b/pkg/linter/lib/src/rules/unnecessary_parenthesis.dart @@ -5,7 +5,7 @@ import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/ast/token.dart'; import 'package:analyzer/dart/ast/visitor.dart'; -import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/element2.dart'; import 'package:analyzer/dart/element/type.dart'; import '../analyzer.dart'; @@ -116,8 +116,8 @@ class _Visitor extends SimpleAstVisitor { // Parentheses are required to stop null-aware shorting, which then // allows an extension getter, which extends a nullable type, to be // called on a `null` value. - var target = parent.propertyName.staticElement?.enclosingElement3; - if (target is ExtensionElement && + var target = parent.propertyName.element?.enclosingElement2; + if (target is ExtensionElement2 && typeSystem.isNullable(target.extendedType)) { return; } @@ -131,8 +131,8 @@ class _Visitor extends SimpleAstVisitor { // Parentheses are required to stop null-aware shorting, which then // allows an extension method, which extends a nullable type, to be // called on a `null` value. - var target = parent.methodName.staticElement?.enclosingElement3; - if (target is ExtensionElement && + var target = parent.methodName.element?.enclosingElement2; + if (target is ExtensionElement2 && typeSystem.isNullable(target.extendedType)) { return; } diff --git a/pkg/linter/messages.yaml b/pkg/linter/messages.yaml index be208989fd5c..0153700d7069 100644 --- a/pkg/linter/messages.yaml +++ b/pkg/linter/messages.yaml @@ -217,7 +217,7 @@ LintCode: deprecatedDetails: |- NOTE: This rule is removed in Dart 3.3.0; it is no longer functional. - **DO** specify `@required` on named parameters without a default value on which + **DO** specify `@required` on named parameters without a default value on which an `assert(param != null)` is done. **BAD:** @@ -272,7 +272,7 @@ LintCode: ``` NOTE: Using the the `@optionalTypeArgs` annotation in the `meta` package, API - authors can special-case type variables whose type needs to be dynamic but whose + authors can special-case type parameters whose type needs to be dynamic but whose declaration should be treated as optional. For example, suppose you have a `Key` object whose type parameter you'd like to treat as optional. Using the `@optionalTypeArgs` would look like this: @@ -1198,8 +1198,8 @@ LintCode: position (e.g., as the type of a formal parameter). Hence, in type alias declarations, only the type parameter bounds are checked. - A replacement for the type `FutureOr` which is often useful is - `Future?`. This type encodes that the result is either a + A replacement for the type `FutureOr` which is often useful is + `Future?`. This type encodes that the result is either a `Future` or it is null, and there is no ambiguity at run time since no object can have both types. @@ -2413,7 +2413,7 @@ LintCode: deprecatedDetails: |- **AVOID** wrapping widgets in unnecessary containers. - Wrapping a widget in `Container` with no other parameters set has no effect + Wrapping a widget in `Container` with no other parameters set has no effect and makes code needlessly more complex. **BAD:** @@ -2569,8 +2569,8 @@ LintCode: See [Developing packages & plugins](https://flutter.dev/to/develop-packages) for more information. deprecatedDetails: |- - **AVOID** using web libraries, `dart:html`, `dart:js` and - `dart:js_util` in Flutter packages that are not web plugins. These libraries are + **AVOID** using web libraries, `dart:html`, `dart:js` and + `dart:js_util` in Flutter packages that are not web plugins. These libraries are not supported outside of a web context; functionality that depends on them will fail at runtime in Flutter mobile, and their use is generally discouraged in Flutter web. @@ -2622,7 +2622,7 @@ LintCode: deprecatedDetails: |- **AVOID** using await on anything which is not a future. - Await is allowed on the types: `Future`, `FutureOr`, `Future?`, + Await is allowed on the types: `Future`, `FutureOr`, `Future?`, `FutureOr?` and `dynamic`. Further, using `await null` is specifically allowed as a way to introduce a @@ -2634,7 +2634,7 @@ LintCode: print(await 23); } ``` - + **GOOD:** ```dart main() async { @@ -2718,8 +2718,8 @@ LintCode: **GOOD:** ```dart - extension MyFancyList on List { - // ... + extension MyFancyList on List { + // ... } extension SmartIterable on Iterable { @@ -4858,7 +4858,7 @@ LintCode: } ``` - With patterns, the identifier `_` is treated as a pattern that matches all + With patterns, the identifier `_` is treated as a pattern that matches all values, so this prints "Matched" twice. **Logic operators.** The logic operators `&&` and `||` are valid constant @@ -5839,7 +5839,7 @@ LintCode: this.color, super.height, // Bad, actually corresponds to the `width` parameter. super.width, // Bad, actually corresponds to the `height` parameter. - ); + ); } ``` @@ -5859,8 +5859,8 @@ LintCode: ColoredRectangle( this.color, super.width, - super.height, - ); + super.height, + ); } ``` missing_code_block_language_in_doc_comment: @@ -6150,7 +6150,7 @@ LintCode: deprecatedDetails: |- **DON'T** use a leading underscore for library prefixes. There is no concept of "private" for library prefixes. When one of those has a - name that starts with an underscore, it sends a confusing signal to the reader. + name that starts with an underscore, it sends a confusing signal to the reader. To avoid that, don't use leading underscores in those names. **BAD:** @@ -6198,7 +6198,7 @@ LintCode: uses a leading underscore in an identifier to mark members and top-level declarations as private. This trains users to associate a leading underscore with one of those kinds of declarations. They see `_` and think "private". - There is no concept of "private" for local variables or parameters. When one of + There is no concept of "private" for local variables or parameters. When one of those has a name that starts with an underscore, it sends a confusing signal to the reader. To avoid that, don't use leading underscores in those names. @@ -6315,7 +6315,7 @@ LintCode: **DON'T** put any logic in `createState()`. Implementations of `createState()` should return a new instance - of a State object and do nothing more. Since state access is preferred + of a State object and do nothing more. Since state access is preferred via the `widget` field, passing data to `State` objects using custom constructor parameters should also be avoided and so further, the State constructor is required to be passed no arguments. @@ -6329,7 +6329,7 @@ LintCode: MyState createState() { global = MyState(); return global; - } + } } ``` @@ -8806,7 +8806,7 @@ LintCode: categories: [brevity, style] hasPublishedDocs: true deprecatedDetails: |- - Declare elements in list literals inline, rather than using `add` and + Declare elements in list literals inline, rather than using `add` and `addAll` methods where possible. @@ -9370,8 +9370,8 @@ LintCode: deprecatedDetails: |- Use spread collections when possible. - Collection literals are excellent when you want to create a new collection out - of individual items. But, when existing items are already stored in another + Collection literals are excellent when you want to create a new collection out + of individual items. But, when existing items are already stored in another collection, spread collection syntax leads to simpler code. **BAD:** @@ -10364,7 +10364,7 @@ LintCode: Type annotations on local variables can serve as a request for type inference, documenting the expected outcome of the type inference step, and declaratively - allowing the compiler and analyzer to solve the possibly complex task of + allowing the compiler and analyzer to solve the possibly complex task of finding type arguments and annotations in the initializing expression that yield the desired result. @@ -10386,10 +10386,10 @@ LintCode: obvious type, and all elements have the same type. For instance, [1, 2] and { [true, false], [] }, but not [1, 1.5]. - e is a map literal where all key-value pair have a key with an obvious type - and a value with an obvious type, and all keys have the same type, and all + and a value with an obvious type, and all keys have the same type, and all values have the same type. For instance, { #a: [] }, but not {1: 1, 2: true}. - - e is an instance creation expression whose class part is not raw. For + - e is an instance creation expression whose class part is not raw. For instance C(14) if C is a non-generic class, or C(14) if C accepts one type argument, but not C(14) if C accepts one or more type arguments. - e is a cascade whose target has an obvious type. For instance, @@ -10416,7 +10416,7 @@ LintCode: ```dart List> possibleDesserts(Set pantry) { List> desserts = genericFunctionDeclaredFarAway( - [42], + [42], 'Something', ); for (final List recipe in cookbook) { @@ -10789,7 +10789,7 @@ LintCode: **DON'T** type annotate initializing formals. If a constructor parameter is using `this.x` to initialize a field, then the - type of the parameter is understood to be the same type as the field. If a + type of the parameter is understood to be the same type as the field. If a a constructor parameter is using `super.x` to forward to a super constructor, then the type of the parameter is understood to be the same as the super constructor parameter. @@ -11556,7 +11556,7 @@ LintCode: ``` deprecatedDetails: |- **DO** not specify the `late` modifier for top-level and static variables - when the declaration contains an initializer. + when the declaration contains an initializer. Top-level and static variables with initializers are already evaluated lazily as if they are marked `late`. @@ -11591,7 +11591,7 @@ LintCode: categories: [brevity] hasPublishedDocs: false deprecatedDetails: |- - **DO** use library directives if you want to document a library and/or annotate + **DO** use library directives if you want to document a library and/or annotate a library. **BAD:** @@ -12489,7 +12489,7 @@ LintCode: likely will return `false` and might not reflect programmer's intent. `Int64` and `Int32` from `package:fixnum` allow comparing to `int` provided - the `int` is on the right hand side. The lint allows this as a special case. + the `int` is on the right hand side. The lint allows this as a special case. **BAD:** ```dart @@ -13620,9 +13620,9 @@ LintCode: } ``` deprecatedDetails: |- - "Forwarding constructor"s, that do nothing except forward parameters to their - superclass constructors should take advantage of super-initializer parameters - rather than repeating the names of parameters when passing them to the + "Forwarding constructor"s, that do nothing except forward parameters to their + superclass constructors should take advantage of super-initializer parameters + rather than repeating the names of parameters when passing them to the superclass constructors. This makes the code more concise and easier to read and maintain. diff --git a/runtime/tests/vm/dart/gen_snapshot_include_resolved_urls_test.dart b/runtime/tests/vm/dart/gen_snapshot_include_resolved_urls_test.dart index 4832f47ffa17..e4c090457e34 100644 --- a/runtime/tests/vm/dart/gen_snapshot_include_resolved_urls_test.dart +++ b/runtime/tests/vm/dart/gen_snapshot_include_resolved_urls_test.dart @@ -76,6 +76,9 @@ main(List args) async { expect( await run(dartPrecompiledRuntime, [ '--enable-vm-service=0', + // Spawning DDS in SIMARM configs can be slow and causes this already + // slow test to timeout. + '--no-dds', '--profiler', elfFile, ]), 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 50e9ec622b53..c232bf82e6af 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 @@ -1049,16 +1049,9 @@ void setDynamicModuleLoader(Object loaderFunction, Object entrypointHelper) { } /// Defines lazy statics. -/// -/// TODO: Remove useOldSemantics when non-null-safe late static field behavior is -/// deprecated. -void defineLazy(to, from, bool useOldSemantics) { +void defineLazy(to, from) { for (var name in getOwnNamesAndSymbols(from)) { - if (useOldSemantics) { - defineLazyFieldOld(to, name, getOwnPropertyDescriptor(from, name)); - } else { - defineLazyField(to, name, getOwnPropertyDescriptor(from, name)); - } + defineLazyField(to, name, getOwnPropertyDescriptor(from, name)); } } @@ -1124,63 +1117,6 @@ defineLazyField(to, name, desc) => JS('', '''(() => { return ${defineProperty(to, name, desc)}; })()'''); -/// Defines a lazy static field with pre-null-safety semantics. -defineLazyFieldOld(to, name, desc) => JS('', '''(() => { - const initializer = $desc.get; - let init = initializer; - let value = null; - // Tracks if these local variables have been saved so they can be restored - // after a hot restart. - let savedLocals = false; - $desc.get = function() { - if (init == null) return value; - let f = init; - init = $throwCyclicInitializationError; - if (f === init) f($name); // throw cycle error - - // On the first (non-cyclic) execution, record the field so we can reset it - // later if needed (hot restart). - if (!savedLocals) { - $resetFields.push(() => { - init = initializer; - value = null; - savedLocals = false; - }); - savedLocals = true; - } - - // Try to evaluate the field, using try+catch to ensure we implement the - // correct Dart error semantics. - try { - value = f(); - init = null; - return value; - } catch (e) { - init = null; - value = null; - throw e; - } - }; - $desc.configurable = true; - let setter = $desc.set; - if (setter != null) { - $desc.set = function(x) { - if (!savedLocals) { - $resetFields.push(() => { - init = initializer; - value = null; - savedLocals = false; - }); - savedLocals = true; - } - init = null; - value = x; - setter(x); - }; - } - return ${defineProperty(to, name, desc)}; -})()'''); - /// Checks for null or undefined and returns [val]. /// /// Throws a [TypeError] when [val] is null or undefined and the option for diff --git a/tests/language/identifier/built_in_not_prefix_test.dart b/tests/language/identifier/built_in_not_prefix_test.dart index db1e856b644a..0225875d86fe 100644 --- a/tests/language/identifier/built_in_not_prefix_test.dart +++ b/tests/language/identifier/built_in_not_prefix_test.dart @@ -18,44 +18,44 @@ // Dart test for using a built-in identifier as a library prefix. import "dart:core" // Fine unless imported with a built-in identifier as prefix. -deferred as abstract // //# deferred-abstract: compile-time error -deferred as as // //# deferred-as: compile-time error -deferred as covariant // //# deferred-covariant: compile-time error -deferred as deferred // //# deferred-deferred: compile-time error +deferred as abstract // //# deferred-abstract: syntax error +deferred as as // //# deferred-as: syntax error +deferred as covariant // //# deferred-covariant: syntax error +deferred as deferred // //# deferred-deferred: syntax error deferred as dynamic // //# deferred-dynamic: compile-time error -deferred as export // //# deferred-export: compile-time error -deferred as external // //# deferred-external: compile-time error -deferred as factory // //# deferred-factory: compile-time error -deferred as get // //# deferred-get: compile-time error -deferred as implements // //# deferred-implements: compile-time error -deferred as import // //# deferred-import: compile-time error -deferred as interface // //# deferred-interface: compile-time error -deferred as library // //# deferred-library: compile-time error -deferred as mixin // //# deferred-mixin: compile-time error -deferred as operator // //# deferred-operator: compile-time error -deferred as part // //# deferred-part: compile-time error -deferred as set // //# deferred-set: compile-time error -deferred as static // //# deferred-static: compile-time error -deferred as typedef // //# deferred-typedef: compile-time error -as abstract // //# abstract: compile-time error -as as // //# as: compile-time error -as covariant // //# covariant: compile-time error -as deferred // //# deferred: compile-time error +deferred as export // //# deferred-export: syntax error +deferred as external // //# deferred-external: syntax error +deferred as factory // //# deferred-factory: syntax error +deferred as get // //# deferred-get: syntax error +deferred as implements // //# deferred-implements: syntax error +deferred as import // //# deferred-import: syntax error +deferred as interface // //# deferred-interface: syntax error +deferred as library // //# deferred-library: syntax error +deferred as mixin // //# deferred-mixin: syntax error +deferred as operator // //# deferred-operator: syntax error +deferred as part // //# deferred-part: syntax error +deferred as set // //# deferred-set: syntax error +deferred as static // //# deferred-static: syntax error +deferred as typedef // //# deferred-typedef: syntax error +as abstract // //# abstract: syntax error +as as // //# as: syntax error +as covariant // //# covariant: syntax error +as deferred // //# deferred: syntax error as dynamic // //# dynamic: compile-time error -as export // //# export: compile-time error -as external // //# external: compile-time error -as factory // //# factory: compile-time error -as get // //# get: compile-time error -as implements // //# implements: compile-time error -as import // //# import: compile-time error -as interface // //# interface: compile-time error -as library // //# library: compile-time error -as mixin // //# mixin: compile-time error -as operator // //# operator: compile-time error -as part // //# part: compile-time error -as set // //# set: compile-time error -as static // //# static: compile-time error -as typedef // //# typedef: compile-time error +as export // //# export: syntax error +as external // //# external: syntax error +as factory // //# factory: syntax error +as get // //# get: syntax error +as implements // //# implements: syntax error +as import // //# import: syntax error +as interface // //# interface: syntax error +as library // //# library: syntax error +as mixin // //# mixin: syntax error +as operator // //# operator: syntax error +as part // //# part: syntax error +as set // //# set: syntax error +as static // //# static: syntax error +as typedef // //# typedef: syntax error ; main() { diff --git a/tests/language/language_spec_parser.status b/tests/language/language_spec_parser.status index f8ae206dc956..a481b6d696ec 100644 --- a/tests/language/language_spec_parser.status +++ b/tests/language/language_spec_parser.status @@ -8,6 +8,7 @@ closure/type_test: Pass # Marked as RuntimeError for all in language_2.status. const/native_factory_test: Skip # Uses `native`. double/invalid_test: Skip # Contains illegally formatted double. regress/regress1751477_test: Skip # Times out: 9 levels, exponential blowup => 430 secs. +switch/switch_legacy_test: Skip # Dart 2.19. syntax/deep_nesting_expression_test: Skip # JVM stack overflow. syntax/deep_nesting_statement_test: Skip # JVM stack overflow. variance: Skip # Not yet supported. diff --git a/tests/language/nnbd/static_errors/nullable_supertype_test.dart b/tests/language/nnbd/static_errors/nullable_supertype_test.dart index 44cd58aa788b..a63238312e85 100644 --- a/tests/language/nnbd/static_errors/nullable_supertype_test.dart +++ b/tests/language/nnbd/static_errors/nullable_supertype_test.dart @@ -11,8 +11,8 @@ import 'dart:core' as core; main() {} class A {} -class B extends A? {} //# 01: compile-time error -class B implements A? {} //# 02: compile-time error -class B with A? {} //# 03: compile-time error -mixin B on A? {} //# 04: compile-time error -mixin B implements A? {} //# 05: compile-time error +class B extends A? {} //# 01: syntax error +class B implements A? {} //# 02: syntax error +class B with A? {} //# 03: syntax error +mixin B on A? {} //# 04: syntax error +mixin B implements A? {} //# 05: syntax error diff --git a/tools/VERSION b/tools/VERSION index 9c239322b6f1..faa4838bb008 100644 --- a/tools/VERSION +++ b/tools/VERSION @@ -27,5 +27,5 @@ CHANNEL dev MAJOR 3 MINOR 6 PATCH 0 -PRERELEASE 291 +PRERELEASE 292 PRERELEASE_PATCH 0 diff --git a/tools/spec_parser/Dart.g b/tools/spec_parser/Dart.g index 3ced048fa2a2..d4a7f9dfd0cb 100644 --- a/tools/spec_parser/Dart.g +++ b/tools/spec_parser/Dart.g @@ -4,6 +4,8 @@ // CHANGES: // +// v0.51 Support a `switchExpression` with no cases. +// // v0.50 Add support for digit separators in numeric literals. // // v0.49 Add support for static and top-level members with no implementation. @@ -787,7 +789,7 @@ constructorTearoff switchExpression : SWITCH '(' expression ')' - LBRACE switchExpressionCase (',' switchExpressionCase)* ','? RBRACE + LBRACE (switchExpressionCase (',' switchExpressionCase)* ','?)? RBRACE ; switchExpressionCase diff --git a/tools/spec_parser/dart_spec_parser/Dart.g4 b/tools/spec_parser/dart_spec_parser/Dart.g4 index b2edd1d02f1f..36bbeb5d6e83 100644 --- a/tools/spec_parser/dart_spec_parser/Dart.g4 +++ b/tools/spec_parser/dart_spec_parser/Dart.g4 @@ -4,6 +4,8 @@ // CHANGES: // +// v0.52 Support a `switchExpression` with no cases. +// // v0.51 Add support for digit separators in numeric literals. // // v0.50 Add support for static and top-level members with no implementation. @@ -793,7 +795,7 @@ constructorTearoff switchExpression : SWITCH '(' expression ')' - LBRACE switchExpressionCase (',' switchExpressionCase)* ','? RBRACE + LBRACE (switchExpressionCase (',' switchExpressionCase)* ','?)? RBRACE ; switchExpressionCase