Version 3.8.0-187.0.dev Merge 58ab0bb9e71910ade9ec485025c26f2ce471cddf into dev
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart index 7d2cee7..d2376d7 100644 --- a/pkg/analyzer/lib/src/dart/element/element.dart +++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -7208,12 +7208,12 @@ } @override - List<GetterElement2OrMember> get getters { - var declarations = <GetterElement2OrMember>{}; + List<GetterElementImpl> get getters { + var declarations = <GetterElementImpl>{}; for (var unit in units) { declarations.addAll(unit._accessors .where((accessor) => accessor.isGetter) - .map((accessor) => accessor.element as GetterElement2OrMember)); + .map((accessor) => accessor.element as GetterElementImpl)); } return declarations.toList(); } @@ -7306,12 +7306,12 @@ } @override - List<SetterElement> get setters { - var declarations = <SetterElement>{}; + List<SetterElementImpl> get setters { + var declarations = <SetterElementImpl>{}; for (var unit in units) { declarations.addAll(unit._accessors .where((accessor) => accessor.isSetter) - .map((accessor) => (accessor as SetterFragment).element)); + .map((accessor) => accessor.element as SetterElementImpl)); } return declarations.toList(); }
diff --git a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart index 9930dc1..ccc7a23 100644 --- a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart +++ b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
@@ -4,11 +4,10 @@ // ignore_for_file: analyzer_use_new_elements -import 'dart:collection'; - import 'package:analyzer/dart/analysis/features.dart'; import 'package:analyzer/dart/ast/token.dart'; import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/element2.dart'; import 'package:analyzer/error/error.dart'; import 'package:analyzer/error/listener.dart'; import 'package:analyzer/src/dart/analysis/file_analysis.dart'; @@ -28,6 +27,7 @@ final DuplicationDefinitionContext context; final DiagnosticFactory _diagnosticFactory = DiagnosticFactory(); + final Set<Token> _reportedTokens = Set.identity(); DuplicateDefinitionVerifier( this._currentLibrary, @@ -44,13 +44,15 @@ if (element != null && element.isWildcardVariable) return; String exceptionName = exceptionParameter.name.lexeme; if (exceptionName == stackTraceParameter.name.lexeme) { - _errorReporter.reportError(_diagnosticFactory - .duplicateDefinitionForNodes( - _errorReporter.source, - CompileTimeErrorCode.DUPLICATE_DEFINITION, - stackTraceParameter, - exceptionParameter, - [exceptionName])); + _errorReporter.reportError( + _diagnosticFactory.duplicateDefinitionForNodes( + _errorReporter.source, + CompileTimeErrorCode.DUPLICATE_DEFINITION, + stackTraceParameter, + exceptionParameter, + [exceptionName], + ), + ); } } } @@ -58,16 +60,19 @@ /// Check that the given list of variable declarations does not define /// multiple variables of the same name. void checkForVariables(VariableDeclarationListImpl node) { - var definedNames = HashMap<String, ElementImpl>(); + var definedNames = <String, Element2>{}; for (var variable in node.variables) { - _checkDuplicateIdentifier(definedNames, variable.name, - element: variable.declaredFragment!); + _checkDuplicateIdentifier( + definedNames, + variable.name, + element: variable.declaredFragment!.element, + ); } } /// Check that all of the parameters have unique names. void checkParameters(FormalParameterListImpl node) { - var definedNames = HashMap<String, ElementImpl>(); + var definedNames = <String, Element2>{}; for (var parameter in node.parameters) { var identifier = parameter.name; if (identifier != null) { @@ -76,8 +81,11 @@ // Skip wildcard `super._`. if (!_isSuperFormalWildcard(parameter, identifier)) { - _checkDuplicateIdentifier(definedNames, identifier, - element: parameter.declaredFragment!); + _checkDuplicateIdentifier( + definedNames, + identifier, + element: parameter.declaredFragment!.element, + ); } } } @@ -85,25 +93,31 @@ /// Check that all of the variables have unique names. void checkStatements(List<StatementImpl> statements) { - var definedNames = HashMap<String, ElementImpl>(); + var definedNames = <String, Element2>{}; for (var statement in statements) { if (statement is VariableDeclarationStatementImpl) { for (var variable in statement.variables.variables) { - _checkDuplicateIdentifier(definedNames, variable.name, - element: variable.declaredFragment!); + _checkDuplicateIdentifier( + definedNames, + variable.name, + element: variable.declaredFragment!.element, + ); } } else if (statement is FunctionDeclarationStatementImpl) { if (!_isWildCardFunction(statement)) { _checkDuplicateIdentifier( definedNames, statement.functionDeclaration.name, - element: statement.functionDeclaration.declaredFragment!, + element: statement.functionDeclaration.declaredFragment!.element, ); } } else if (statement is PatternVariableDeclarationStatementImpl) { for (var variable in statement.declaration.elements) { - _checkDuplicateIdentifier(definedNames, variable.node.name, - element: variable.asElement); + _checkDuplicateIdentifier( + definedNames, + variable.node.name, + element: variable, + ); } } } @@ -111,55 +125,76 @@ /// Check that all of the parameters have unique names. void checkTypeParameters(TypeParameterListImpl node) { - var definedNames = HashMap<String, ElementImpl>(); + var definedNames = <String, Element2>{}; for (var parameter in node.typeParameters) { - _checkDuplicateIdentifier(definedNames, parameter.name, - element: parameter.declaredFragment!); + _checkDuplicateIdentifier( + definedNames, + parameter.name, + element: parameter.declaredFragment!.element, + ); } } /// Check that there are no members with the same name. void checkUnit(CompilationUnitImpl node) { var fragment = node.declaredFragment!; - var definedGetters = <String, Element>{}; - var definedSetters = <String, Element>{}; + var definedGetters = <String, Element2>{}; + var definedSetters = <String, Element2>{}; - void addWithoutChecking(CompilationUnitElement element) { - for (PropertyAccessorElement accessor in element.accessors) { - String name = accessor.name; - if (accessor.isSetter) { - name += '='; - } - definedGetters[name] = accessor; - } - for (var class_ in element.classes) { - definedGetters[class_.name] = class_; - } - for (var enum_ in element.enums) { - definedGetters[enum_.name] = enum_; - } - for (var extension_ in element.extensions) { - if (extension_.name case var name?) { - definedGetters[name] = extension_; + void addWithoutChecking(LibraryFragment libraryFragment) { + for (var fragment in libraryFragment.getters) { + var element = fragment.element; + if (element.lookupName case var name?) { + definedGetters[name] = element; } } - for (var extensionType in element.extensionTypes) { - definedGetters[extensionType.name] = extensionType; - } - for (var function in element.functions) { - definedGetters[function.name] = function; - } - for (var mixin_ in element.mixins) { - definedGetters[mixin_.name] = mixin_; - } - for (var variable in element.topLevelVariables) { - definedGetters[variable.name] = variable; - if (!variable.isFinal && !variable.isConst) { - definedGetters['${variable.name}='] = variable; + for (var fragment in libraryFragment.setters) { + var element = fragment.element; + if (element.lookupName case var name?) { + definedSetters[name] = element; } } - for (var alias in element.typeAliases) { - definedGetters[alias.name] = alias; + for (var fragment in libraryFragment.classes2) { + var element = fragment.element; + if (element.lookupName case var name?) { + definedGetters[name] = element; + } + } + for (var fragment in libraryFragment.enums2) { + var element = fragment.element; + if (element.lookupName case var name?) { + definedGetters[name] = element; + } + } + for (var fragment in libraryFragment.extensions2) { + var element = fragment.element; + if (element.lookupName case var name?) { + definedGetters[name] = element; + } + } + for (var fragment in libraryFragment.extensionTypes2) { + var element = fragment.element; + if (element.lookupName case var name?) { + definedGetters[name] = element; + } + } + for (var fragment in libraryFragment.functions2) { + var element = fragment.element; + if (element.lookupName case var name?) { + definedGetters[name] = element; + } + } + for (var fragment in libraryFragment.mixins2) { + var element = fragment.element; + if (element.lookupName case var name?) { + definedGetters[name] = element; + } + } + for (var fragment in libraryFragment.typeAliases2) { + var element = fragment.element; + if (element.lookupName case var name?) { + definedGetters[name] = element; + } } } @@ -178,31 +213,60 @@ } } - var element = node.declaredFragment!; - if (element != _currentLibrary.definingCompilationUnit) { - addWithoutChecking(_currentLibrary.definingCompilationUnit); - for (var unitElement in _currentLibrary.units) { - if (element == unitElement) { - break; - } - addWithoutChecking(unitElement); + // TODO(scheglov): carry across resolved units + var currentLibraryFragment = node.declaredFragment!; + for (var libraryFragment in _currentLibrary.fragments) { + if (libraryFragment == currentLibraryFragment) { + break; } + addWithoutChecking(libraryFragment); } + for (var member in node.declarations) { if (member is ExtensionDeclarationImpl) { var identifier = member.name; if (identifier != null) { - _checkDuplicateIdentifier(definedGetters, identifier, - element: member.declaredFragment!, setterScope: definedSetters); + var declaredFragment = member.declaredFragment!; + if (!declaredFragment.isAugmentation) { + _checkDuplicateIdentifier( + definedGetters, + identifier, + element: declaredFragment.element, + setterScope: definedSetters, + ); + } } } else if (member is NamedCompilationUnitMemberImpl) { - _checkDuplicateIdentifier(definedGetters, member.name, - element: member.declaredFragment as ElementImpl, - setterScope: definedSetters); + var declaredFragment = member.declaredFragment!; + var augmentable = declaredFragment as AugmentableFragment; + if (!augmentable.isAugmentation) { + _checkDuplicateIdentifier( + definedGetters, + member.name, + element: declaredFragment.element, + setterScope: definedSetters, + ); + } } else if (member is TopLevelVariableDeclarationImpl) { for (var variable in member.variables.variables) { - _checkDuplicateIdentifier(definedGetters, variable.name, - element: variable.declaredFragment!, setterScope: definedSetters); + var declaredFragment = variable.declaredFragment; + declaredFragment as TopLevelVariableElementImpl; + if (!declaredFragment.isAugmentation) { + _checkDuplicateIdentifier( + definedGetters, + variable.name, + element: declaredFragment.element.getter2, + setterScope: definedSetters, + ); + if (declaredFragment.element.definesSetter) { + _checkDuplicateIdentifier( + definedGetters, + variable.name, + element: declaredFragment.element.setter2, + setterScope: definedSetters, + ); + } + } } } } @@ -212,77 +276,71 @@ /// in one of the scopes - [getterScope] or [setterScope], and produce an /// error if it is. void _checkDuplicateIdentifier( - Map<String, Element> getterScope, Token identifier, - {required ElementImpl element, Map<String, Element>? setterScope}) { - if (identifier.isSynthetic || element.asElement2.isWildcardVariable) { + Map<String, Element2> getterScope, + Token identifier, { + required Element2? element, + Map<String, Element2>? setterScope, + }) { + if (identifier.isSynthetic) { return; } - - switch (element) { - case ExecutableElementImpl _: - if (element.isAugmentation) return; - case FieldElementImpl _: - if (element.isAugmentation) return; - case InstanceElementImpl _: - if (element.isAugmentation) return; - case TypeAliasElementImpl _: - if (element.isAugmentation) return; - case TopLevelVariableElementImpl _: - if (element.isAugmentation) return; + if (element == null || element.isWildcardVariable) { + return; } - - // Fields define getters and setters, so check them separately. - if (element is PropertyInducingElementImpl) { - _checkDuplicateIdentifier(getterScope, identifier, - element: element.getter!, setterScope: setterScope); - var setter = element.setter; - if (setter != null && setter.isSynthetic) { - _checkDuplicateIdentifier(getterScope, identifier, - element: setter, setterScope: setterScope); + if (element case AugmentableFragment augmentable) { + if (augmentable.isAugmentation) { + return; } + } + + var lookupName = element.lookupName; + if (lookupName == null) { return; } - ErrorCode getError(Element previous, Element current) { - if (previous is FieldFormalParameterElement && - current is FieldFormalParameterElement) { + if (_reportedTokens.contains(identifier)) { + return; + } + + ErrorCode getError(Element2 previous, Element2 current) { + if (previous is FieldFormalParameterElement2 && + current is FieldFormalParameterElement2) { return CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER; } return CompileTimeErrorCode.DUPLICATE_DEFINITION; } - var name = identifier.lexeme; - if (element is MethodElementImpl) { - name = element.name; - } - - var previous = getterScope[name]; - if (previous != null) { - if (!_isGetterSetterPair(element, previous)) { - _errorReporter.reportError(_diagnosticFactory.duplicateDefinition( - getError(previous, element), - element.asElement2!, - previous.asElement2!, - [name], - )); + if (element is SetterElement) { + if (setterScope != null) { + var previous = setterScope[lookupName]; + if (previous != null) { + _reportedTokens.add(identifier); + _errorReporter.reportError( + _diagnosticFactory.duplicateDefinition( + getError(previous, element), + element, + previous, + [lookupName], + ), + ); + } else { + setterScope[lookupName] = element; + } } } else { - getterScope[name] = element; - } - - if (setterScope != null) { - if (element is PropertyAccessorElementImpl && element.isSetter) { - previous = setterScope[name]; - if (previous != null) { - _errorReporter.reportError(_diagnosticFactory.duplicateDefinition( + var previous = getterScope[lookupName]; + if (previous != null) { + _reportedTokens.add(identifier); + _errorReporter.reportError( + _diagnosticFactory.duplicateDefinition( getError(previous, element), - element.asElement2, - previous.asElement2!, - [name], - )); - } else { - setterScope[name] = element; - } + element, + previous, + [lookupName], + ), + ); + } else { + getterScope[lookupName] = element; } } } @@ -299,13 +357,6 @@ bool _isWildCardFunction(FunctionDeclarationStatement statement) => statement.functionDeclaration.name.lexeme == '_' && _currentLibrary.hasWildcardVariablesFeatureEnabled; - - static bool _isGetterSetterPair(Element a, Element b) { - if (a is PropertyAccessorElement && b is PropertyAccessorElement) { - return a.isGetter && b.isSetter || a.isSetter && b.isGetter; - } - return false; - } } /// Information to pass from declarations to augmentations.
diff --git a/pkg/analyzer/lib/src/utilities/extensions/element.dart b/pkg/analyzer/lib/src/utilities/extensions/element.dart index a3833c7..23bfc12 100644 --- a/pkg/analyzer/lib/src/utilities/extensions/element.dart +++ b/pkg/analyzer/lib/src/utilities/extensions/element.dart
@@ -726,6 +726,19 @@ } } +extension PropertyInducingElementExtension on PropertyInducingElement2 { + bool get definesSetter { + if (isConst) { + return false; + } + if (isFinal) { + return isLate && !hasInitializer; + } else { + return true; + } + } +} + extension TopLevelFunctionElementExtension on TopLevelFunctionElement { FunctionElement get asElement { return (this as TopLevelFunctionElementImpl).lastFragment;
diff --git a/pkg/analyzer/test/src/diagnostics/duplicate_definition_test.dart b/pkg/analyzer/test/src/diagnostics/duplicate_definition_test.dart index 3b30e33e..81c2631 100644 --- a/pkg/analyzer/test/src/diagnostics/duplicate_definition_test.dart +++ b/pkg/analyzer/test/src/diagnostics/duplicate_definition_test.dart
@@ -3102,6 +3102,16 @@ ]); } + test_topLevel_field_field() async { + await assertErrorsInCode(r''' +var f = 1; +var f = 2; +''', [ + error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 15, 1, + contextMessages: [message(testFile, 4, 1)]), + ]); + } + test_topLevel_field_getter() async { await assertErrorsInCode(r''' int f = 1; @@ -3122,6 +3132,13 @@ ]); } + test_topLevel_fieldConst_setter() async { + await assertNoErrorsInCode(r''' +const f = 0; +set f(_) {} +'''); + } + test_topLevel_fieldFinal_setter() async { await assertNoErrorsInCode(r''' final f = 1; @@ -3146,6 +3163,33 @@ ]); } + test_topLevel_setter_setter() async { + await assertErrorsInCode(r''' +set f(int value) {} +set f(int value) {} +''', [ + error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 24, 1, + contextMessages: [message(testFile, 4, 1)]), + ]); + } + + test_topLevel_setter_setter_inPart() async { + var a = newFile('$testPackageLibPath/a.dart', r''' +part of 'test.dart'; +set f(int value) {} +'''); + + await assertNoErrorsInCode(r''' +part 'a.dart'; +set f(int value) {} +'''); + + await assertErrorsInFile2(a, [ + error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 25, 1, + contextMessages: [message(testFile, 19, 1)]), + ]); + } + test_typeParameters_class() async { await assertErrorsInCode(r''' class A<T, T> {}
diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart index 8017b87..5e75caa 100644 --- a/pkg/vm/lib/transformations/type_flow/transformer.dart +++ b/pkg/vm/lib/transformations/type_flow/transformer.dart
@@ -1850,6 +1850,7 @@ null, initializer: node.value, isSynthesized: true, + type: field.type, ), ); } else {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/instance_fields_with_initializers.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/instance_fields_with_initializers.dart.expect index c1e051a..5b48de3 100644 --- a/pkg/vm/testcases/transformations/type_flow/transformer/instance_fields_with_initializers.dart.expect +++ b/pkg/vm/testcases/transformations/type_flow/transformer/instance_fields_with_initializers.dart.expect
@@ -23,13 +23,13 @@ [@vm.unboxing-info.metadata=(i)->i] field core::int f7; constructor •() → self::A - : dynamic #t1 = self::sideEffect(1), dynamic #t2 = self::sideEffect(2), self::A::f7 = [@vm.inferred-type.metadata=dart.core::_Smi (value: 7)] self::sideEffect(7), dynamic #t3 = self::sideEffect(8), dynamic #t4 = [@vm.inferred-type.metadata=dart.core::_Smi (value: 100)] self::sideEffect(100), dynamic #t5 = [@vm.inferred-type.metadata=dart.core::_Smi (value: 200)] self::sideEffect(200), super core::Object::•() + : dynamic #t1 = self::sideEffect(1), dynamic #t2 = self::sideEffect(2), self::A::f7 = [@vm.inferred-type.metadata=dart.core::_Smi (value: 7)] self::sideEffect(7), dynamic #t3 = self::sideEffect(8), core::int #t4 = [@vm.inferred-type.metadata=dart.core::_Smi (value: 100)] self::sideEffect(100), core::int #t5 = [@vm.inferred-type.metadata=dart.core::_Smi (value: 200)] self::sideEffect(200), super core::Object::•() ; constructor foo() → self::A : this self::A::•() ; constructor bar() → self::A - : dynamic #t6 = self::sideEffect(1), dynamic #t7 = [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] self::sideEffect(2), self::A::f7 = [@vm.inferred-type.metadata=dart.core::_Smi (value: 7)] self::sideEffect(7), dynamic #t8 = self::sideEffect(8), dynamic #t9 = [@vm.inferred-type.metadata=dart.core::_Smi (value: 801)] self::sideEffect(801), super core::Object::•() + : dynamic #t6 = self::sideEffect(1), core::int #t7 = [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] self::sideEffect(2), self::A::f7 = [@vm.inferred-type.metadata=dart.core::_Smi (value: 7)] self::sideEffect(7), dynamic #t8 = self::sideEffect(8), core::int #t9 = [@vm.inferred-type.metadata=dart.core::_Smi (value: 801)] self::sideEffect(801), super core::Object::•() ; }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field.dart.expect index 9036aca..d2f151a 100644 --- a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field.dart.expect +++ b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field.dart.expect
@@ -12,7 +12,7 @@ } class C extends core::Object { synthetic constructor •() → self::C - : dynamic #t1 = new self::B::•(), super core::Object::•() + : self::B? #t1 = new self::B::•(), super core::Object::•() ; [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1]
diff --git a/tools/VERSION b/tools/VERSION index a78ff4a..d3c8628 100644 --- a/tools/VERSION +++ b/tools/VERSION
@@ -27,5 +27,5 @@ MAJOR 3 MINOR 8 PATCH 0 -PRERELEASE 186 +PRERELEASE 187 PRERELEASE_PATCH 0