diff --git a/lib/src/generator/templates.runtime_renderers.dart b/lib/src/generator/templates.runtime_renderers.dart index 688afec70e..8128e08f63 100644 --- a/lib/src/generator/templates.runtime_renderers.dart +++ b/lib/src/generator/templates.runtime_renderers.dart @@ -33,6 +33,20 @@ class _Renderer_Accessor extends RendererBase { CT_, () => { ..._Renderer_ModelElement.propertyMap(), + 'characterLocation': Property( + getValue: (CT_ c) => c.characterLocation, + renderVariable: (CT_ c, Property self, + List remainingNames) => + self.renderSimpleVariable( + c, remainingNames, 'CharacterLocation'), + isNullValue: (CT_ c) => c.characterLocation == null, + renderValue: + (CT_ c, RendererBase r, List ast) { + return renderSimple(c.characterLocation, ast, r.template, + parent: r, + getters: _invisibleGetters['CharacterLocation']); + }, + ), 'definingCombo': Property( getValue: (CT_ c) => c.definingCombo, renderVariable: diff --git a/lib/src/model/accessor.dart b/lib/src/model/accessor.dart index c8aba534ff..48daf92fdf 100644 --- a/lib/src/model/accessor.dart +++ b/lib/src/model/accessor.dart @@ -21,6 +21,16 @@ class Accessor extends ModelElement implements EnclosedElement { [ExecutableMember /*?*/ originalMember]) : super(element, library, packageGraph, originalMember); + @override + CharacterLocation get characterLocation { + if (element.nameOffset < 0) { + assert(element.isSynthetic, 'Invalid offset for non-synthetic element'); + // TODO(jcollins-g): switch to [element.nonSynthetic] after analyzer 1.8 + return enclosingCombo.characterLocation; + } + return super.characterLocation; + } + @override PropertyAccessorElement get element => super.element; diff --git a/test/end2end/model_test.dart b/test/end2end/model_test.dart index 8992d99f63..d23abdf6ef 100644 --- a/test/end2end/model_test.dart +++ b/test/end2end/model_test.dart @@ -389,6 +389,7 @@ void main() { inferredTypeSet, specifiedSet, untypedMap, + untypedMapWithoutConst, typedSet; setUpAll(() async { @@ -402,6 +403,8 @@ void main() { set_literals.constants.firstWhere((v) => v.name == 'specifiedSet'); untypedMap = set_literals.constants.firstWhere((v) => v.name == 'untypedMap'); + untypedMapWithoutConst = set_literals.constants + .firstWhere((v) => v.name == 'untypedMapWithoutConst'); typedSet = set_literals.constants.firstWhere((v) => v.name == 'typedSet'); }); @@ -431,6 +434,10 @@ void main() { .toList(), equals(['int'])); expect(specifiedSet.constantValue, equals('const {}')); + // The analyzer is allowed to return a string with or without leading + // `const` here. + expect( + untypedMapWithoutConst.constantValue, matches(RegExp('(const )?{}'))); expect(untypedMap.modelType.name, equals('Map')); expect( (untypedMap.modelType as ParameterizedElementType) diff --git a/testing/test_package/lib/example.dart b/testing/test_package/lib/example.dart index 49d8af1b3e..85d73e69a1 100644 --- a/testing/test_package/lib/example.dart +++ b/testing/test_package/lib/example.dart @@ -58,8 +58,8 @@ class aThingToDo { const aThingToDo(this.who, this.what); } -const ConstantCat MY_CAT = ConstantCat('tabby'); -const List PRETTY_COLORS = [COLOR_GREEN, COLOR_ORANGE, 'blue']; +const ConstantCat MY_CAT = const ConstantCat('tabby'); +const List PRETTY_COLORS = const [COLOR_GREEN, COLOR_ORANGE, 'blue']; @deprecated int deprecatedField; @@ -313,7 +313,7 @@ class Dog implements Cat, E { static const String aStaticConstField = "A Constant Dog"; /// Verify link substitution in constants (#1535) - static const ShortName aName = ExtendedShortName("hello there"); + static const ShortName aName = const ExtendedShortName("hello there"); @protected final int aProtectedFinalField = 84; diff --git a/testing/test_package/lib/fake.dart b/testing/test_package/lib/fake.dart index 5f2f33580b..5b94160ec3 100644 --- a/testing/test_package/lib/fake.dart +++ b/testing/test_package/lib/fake.dart @@ -254,7 +254,7 @@ class AClassWithFancyProperties { String aProperty; } -const _APrivateConstClass CUSTOM_CLASS_PRIVATE = _APrivateConstClass(); +const _APrivateConstClass CUSTOM_CLASS_PRIVATE = const _APrivateConstClass(); /// Type inference mixing with anonymous functions. final importantComputations = { diff --git a/testing/test_package/lib/set_literals.dart b/testing/test_package/lib/set_literals.dart index 47be4068a2..8765936af9 100644 --- a/testing/test_package/lib/set_literals.dart +++ b/testing/test_package/lib/set_literals.dart @@ -1,9 +1,11 @@ // @dart=2.9 -const inferredTypeSet = {1, 3, 5}; -const Set specifiedSet = {}; -const untypedMap = {}; -const typedSet = {}; +const inferredTypeSet = const {1, 3, 5}; +const Set specifiedSet = const {}; +const untypedMap = const {}; +const typedSet = const {}; +const untypedMapWithoutConst = {}; + class AClassContainingLiterals { final int value1; @@ -12,4 +14,4 @@ class AClassContainingLiterals { const AClassContainingLiterals(this.value1, this.value2); } -const aComplexSet = {AClassContainingLiterals(3, 5)}; +const aComplexSet = const {const AClassContainingLiterals(3, 5)};