Skip to content

Commit 671a5eb

Browse files
stereotype441Commit Queue
authored andcommitted
[analyzer] Make two derived classes for FunctionElementImpl.
Derived class `LocalFunctionFragmentImpl` is used for local functions and `TopLevelFunctionFragmentImpl` is used for top level functions. Only `LocalFunctionFragmentImpl` implements `LocalFunctionFragment` and only `TopLevelFunctionFragmentImpl` implements `TopLevelFunctionFragment`. This ensures that clients performing `is LocalFunctionFragment` and `is TopLevelFunctionFragment` checks get the expected behavior. (Previously, any instance of `FunctionElementImpl` would satisfy *both* `is LocalFunctionFragment` and `is TopLevelFunctionFragment` tests). This made it possible for the types of getters defined in `LocalFunctionFragmentImpl` and `TopLevelFunctionFragmentImpl` to be more precise, which in turn allowed some casts to be removed from the analyzer. Change-Id: I5637366936683f43d0f0818d3d8a28191086dad5 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/414162 Commit-Queue: Paul Berry <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]>
1 parent 957c9a1 commit 671a5eb

File tree

9 files changed

+110
-80
lines changed

9 files changed

+110
-80
lines changed

pkg/analyzer/lib/src/dart/element/element.dart

Lines changed: 89 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,7 @@ class CompilationUnitElementImpl extends UriReferencedElementImpl
816816

817817
/// A list containing all of the top-level functions contained in this
818818
/// compilation unit.
819-
List<FunctionElementImpl> _functions = const [];
819+
List<TopLevelFunctionFragmentImpl> _functions = const [];
820820

821821
List<MixinElementImpl> _mixins = const [];
822822

@@ -973,13 +973,13 @@ class CompilationUnitElementImpl extends UriReferencedElementImpl
973973
extensionTypes.cast<ExtensionTypeFragment>();
974974

975975
@override
976-
List<FunctionElementImpl> get functions {
976+
List<TopLevelFunctionFragmentImpl> get functions {
977977
return _functions;
978978
}
979979

980980
/// Set the top-level functions contained in this compilation unit to the
981981
/// given[functions].
982-
set functions(List<FunctionElementImpl> functions) {
982+
set functions(List<TopLevelFunctionFragmentImpl> functions) {
983983
for (var function in functions) {
984984
function.enclosingElement3 = this;
985985
}
@@ -5272,26 +5272,17 @@ mixin FragmentedTypeParameterizedElementMixin<
52725272
}
52735273

52745274
/// A concrete implementation of a [FunctionElement].
5275-
class FunctionElementImpl extends ExecutableElementImpl
5276-
with AugmentableElement<FunctionElementImpl>
5275+
sealed class FunctionElementImpl extends ExecutableElementImpl
52775276
implements
52785277
FunctionElement,
52795278
FunctionTypedElementImpl,
5280-
LocalFunctionFragment,
5281-
TopLevelFunctionFragment,
52825279
ExecutableElementOrMember {
52835280
@override
52845281
String? name2;
52855282

52865283
@override
52875284
int? nameOffset2;
52885285

5289-
/// The element corresponding to this fragment.
5290-
// TODO(brianwilkerson): Use either `LocalFunctionElement` or
5291-
// `TopLevelFunctionElement` when this class is split.
5292-
@override
5293-
late ExecutableElementImpl2 element;
5294-
52955286
/// Initialize a newly created function element to have the given [name] and
52965287
/// [offset].
52975288
FunctionElementImpl(super.name, super.offset);
@@ -5300,14 +5291,6 @@ class FunctionElementImpl extends ExecutableElementImpl
53005291
/// [nameOffset]. This is used for function expressions, that have no name.
53015292
FunctionElementImpl.forOffset(int nameOffset) : super("", nameOffset);
53025293

5303-
@override
5304-
List<Element2> get children2 {
5305-
if (enclosingElement3 is LibraryFragment) {
5306-
return element.children2;
5307-
}
5308-
throw StateError('Not an Element2');
5309-
}
5310-
53115294
@override
53125295
ExecutableElementImpl get declaration => this;
53135296

@@ -5332,37 +5315,9 @@ class FunctionElementImpl extends ExecutableElementImpl
53325315
throw UnsupportedError('This is not a fragment');
53335316
}
53345317

5335-
@override
5336-
bool get isDartCoreIdentical {
5337-
return isStatic && name == 'identical' && library.isDartCore;
5338-
}
5339-
5340-
@override
5341-
bool get isEntryPoint {
5342-
return isStatic && displayName == FunctionElement.MAIN_FUNCTION_NAME;
5343-
}
5344-
5345-
/// Whether this function element represents a top-level function, and is
5346-
/// therefore safe to treat as a fragment.
5347-
bool get isTopLevelFunction =>
5348-
enclosingElement3 is CompilationUnitElementImpl;
5349-
53505318
@override
53515319
ElementKind get kind => ElementKind.FUNCTION;
53525320

5353-
@override
5354-
FunctionElementImpl? get nextFragment => augmentation;
5355-
5356-
@override
5357-
FunctionElementImpl? get previousFragment => augmentationTarget;
5358-
5359-
@override
5360-
bool get _includeNameOffsetInIdentifier {
5361-
return super._includeNameOffsetInIdentifier ||
5362-
enclosingElement3 is ExecutableElement ||
5363-
enclosingElement3 is VariableElement;
5364-
}
5365-
53665321
@Deprecated('Use Element2 and accept2() instead')
53675322
@override
53685323
T? accept<T>(ElementVisitor<T> visitor) => visitor.visitFunctionElement(this);
@@ -7444,7 +7399,7 @@ class LibraryElementImpl extends ElementImpl
74447399
}
74457400

74467401
@override
7447-
FunctionElementImpl get loadLibraryFunction {
7402+
TopLevelFunctionFragmentImpl get loadLibraryFunction {
74487403
return loadLibraryFunction2.firstFragment;
74497404
}
74507405

@@ -7837,7 +7792,7 @@ final class LoadLibraryFunctionProvider {
78377792
TopLevelFunctionElementImpl _create(LibraryElementImpl library) {
78387793
var name = FunctionElement.LOAD_LIBRARY_NAME;
78397794

7840-
var fragment = FunctionElementImpl(name, -1);
7795+
var fragment = TopLevelFunctionFragmentImpl(name, -1);
78417796
fragment.name2 = name;
78427797
fragment.isSynthetic = true;
78437798
fragment.isStatic = true;
@@ -7855,7 +7810,7 @@ class LocalFunctionElementImpl extends ExecutableElementImpl2
78557810
with WrappedElementMixin
78567811
implements LocalFunctionElement {
78577812
@override
7858-
final FunctionElementImpl _wrappedElement;
7813+
final LocalFunctionFragmentImpl _wrappedElement;
78597814

78607815
LocalFunctionElementImpl(this._wrappedElement) {
78617816
_wrappedElement.element = this;
@@ -7869,7 +7824,7 @@ class LocalFunctionElementImpl extends ExecutableElementImpl2
78697824
Element2? get enclosingElement2 => null;
78707825

78717826
@override
7872-
FunctionElementImpl get firstFragment => _wrappedElement;
7827+
LocalFunctionFragmentImpl get firstFragment => _wrappedElement;
78737828

78747829
@override
78757830
List<FormalParameterElementMixin> get formalParameters =>
@@ -7878,9 +7833,9 @@ class LocalFunctionElementImpl extends ExecutableElementImpl2
78787833
.toList();
78797834

78807835
@override
7881-
List<FunctionElementImpl> get fragments {
7836+
List<LocalFunctionFragmentImpl> get fragments {
78827837
return [
7883-
for (FunctionElementImpl? fragment = firstFragment;
7838+
for (LocalFunctionFragmentImpl? fragment = firstFragment;
78847839
fragment != null;
78857840
fragment = fragment.nextFragment)
78867841
fragment,
@@ -7930,6 +7885,43 @@ class LocalFunctionElementImpl extends ExecutableElementImpl2
79307885
}
79317886
}
79327887

7888+
/// A concrete implementation of a [LocalFunctionFragment].
7889+
class LocalFunctionFragmentImpl extends FunctionElementImpl
7890+
with AugmentableElement<LocalFunctionFragmentImpl>
7891+
implements LocalFunctionFragment {
7892+
/// The element corresponding to this fragment.
7893+
@override
7894+
late LocalFunctionElementImpl element;
7895+
7896+
LocalFunctionFragmentImpl(super.name, super.offset);
7897+
7898+
LocalFunctionFragmentImpl.forOffset(super.nameOffset) : super.forOffset();
7899+
7900+
@override
7901+
Never get children2 {
7902+
throw StateError('Not an Element2');
7903+
}
7904+
7905+
@override
7906+
bool get isDartCoreIdentical => false;
7907+
7908+
@override
7909+
bool get isEntryPoint => false;
7910+
7911+
@override
7912+
LocalFunctionFragmentImpl? get nextFragment => augmentation;
7913+
7914+
@override
7915+
LocalFunctionFragmentImpl? get previousFragment => augmentationTarget;
7916+
7917+
@override
7918+
bool get _includeNameOffsetInIdentifier {
7919+
return super._includeNameOffsetInIdentifier ||
7920+
enclosingElement3 is ExecutableElement ||
7921+
enclosingElement3 is VariableElement;
7922+
}
7923+
}
7924+
79337925
/// A concrete implementation of a [LocalVariableElement].
79347926
class LocalVariableElementImpl extends NonParameterVariableElementImpl
79357927
implements
@@ -10932,7 +10924,7 @@ class TopLevelFunctionElementImpl extends ExecutableElementImpl2
1093210924
final Reference reference;
1093310925

1093410926
@override
10935-
final FunctionElementImpl firstFragment;
10927+
final TopLevelFunctionFragmentImpl firstFragment;
1093610928

1093710929
TopLevelFunctionElementImpl(this.reference, this.firstFragment) {
1093810930
reference.element2 = this;
@@ -10946,9 +10938,9 @@ class TopLevelFunctionElementImpl extends ExecutableElementImpl2
1094610938
Element2? get enclosingElement2 => firstFragment._enclosingElement3?.library2;
1094710939

1094810940
@override
10949-
List<FunctionElementImpl> get fragments {
10941+
List<TopLevelFunctionFragmentImpl> get fragments {
1095010942
return [
10951-
for (FunctionElementImpl? fragment = firstFragment;
10943+
for (TopLevelFunctionFragmentImpl? fragment = firstFragment;
1095210944
fragment != null;
1095310945
fragment = fragment.nextFragment)
1095410946
fragment,
@@ -10965,8 +10957,8 @@ class TopLevelFunctionElementImpl extends ExecutableElementImpl2
1096510957
ElementKind get kind => ElementKind.FUNCTION;
1096610958

1096710959
@override
10968-
FunctionElementImpl get lastFragment {
10969-
return super.lastFragment as FunctionElementImpl;
10960+
TopLevelFunctionFragmentImpl get lastFragment {
10961+
return super.lastFragment as TopLevelFunctionFragmentImpl;
1097010962
}
1097110963

1097210964
@override
@@ -10983,6 +10975,43 @@ class TopLevelFunctionElementImpl extends ExecutableElementImpl2
1098310975
}
1098410976
}
1098510977

10978+
/// A concrete implementation of a [TopLevelFunctionFragment].
10979+
class TopLevelFunctionFragmentImpl extends FunctionElementImpl
10980+
with AugmentableElement<TopLevelFunctionFragmentImpl>
10981+
implements TopLevelFunctionFragment {
10982+
/// The element corresponding to this fragment.
10983+
@override
10984+
late TopLevelFunctionElementImpl element;
10985+
10986+
TopLevelFunctionFragmentImpl(super.name, super.offset);
10987+
10988+
@override
10989+
List<Element2> get children2 => element.children2;
10990+
10991+
@override
10992+
CompilationUnitElementImpl get enclosingElement3 =>
10993+
super.enclosingElement3 as CompilationUnitElementImpl;
10994+
10995+
@override
10996+
set enclosingElement3(covariant CompilationUnitElementImpl element);
10997+
10998+
@override
10999+
bool get isDartCoreIdentical {
11000+
return name == 'identical' && library.isDartCore;
11001+
}
11002+
11003+
@override
11004+
bool get isEntryPoint {
11005+
return displayName == FunctionElement.MAIN_FUNCTION_NAME;
11006+
}
11007+
11008+
@override
11009+
TopLevelFunctionFragmentImpl? get nextFragment => augmentation;
11010+
11011+
@override
11012+
TopLevelFunctionFragmentImpl? get previousFragment => augmentationTarget;
11013+
}
11014+
1098611015
/// A concrete implementation of a [TopLevelVariableElement].
1098711016
class TopLevelVariableElementImpl extends PropertyInducingElementImpl
1098811017
with AugmentableElement<TopLevelVariableElementImpl>

pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,7 @@ class ResolutionVisitor extends RecursiveAstVisitor<void> {
712712
node.declaredFragment = fragment;
713713
expression.declaredFragment = fragment;
714714
} else {
715-
var functionFragment = node.declaredFragment as FunctionElementImpl;
715+
var functionFragment = node.declaredFragment as LocalFunctionFragmentImpl;
716716
functionFragment.element = LocalFunctionElementImpl(functionFragment);
717717

718718
fragment = functionFragment;
@@ -779,7 +779,7 @@ class ResolutionVisitor extends RecursiveAstVisitor<void> {
779779

780780
@override
781781
void visitFunctionExpression(covariant FunctionExpressionImpl node) {
782-
var fragment = FunctionElementImpl.forOffset(node.offset);
782+
var fragment = LocalFunctionFragmentImpl.forOffset(node.offset);
783783
fragment.element = LocalFunctionElementImpl(fragment);
784784

785785
_elementHolder.enclose(fragment);
@@ -1495,7 +1495,8 @@ class ResolutionVisitor extends RecursiveAstVisitor<void> {
14951495
var node = statement.functionDeclaration;
14961496
var nameToken = node.name;
14971497

1498-
var fragment = FunctionElementImpl(nameToken.lexeme, nameToken.offset);
1498+
var fragment =
1499+
LocalFunctionFragmentImpl(nameToken.lexeme, nameToken.offset);
14991500
fragment.name2 = nameToken.nameIfNotEmpty;
15001501
fragment.nameOffset2 = nameToken.offsetIfNotEmpty;
15011502
node.declaredFragment = fragment;

pkg/analyzer/lib/src/summary2/augmentation.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -384,13 +384,13 @@ class SetterElementBuilder
384384
}
385385

386386
class TopLevelFunctionElementBuilder extends FragmentedElementBuilder<
387-
TopLevelFunctionElementImpl, FunctionElementImpl> {
387+
TopLevelFunctionElementImpl, TopLevelFunctionFragmentImpl> {
388388
TopLevelFunctionElementBuilder({
389389
required super.element,
390390
required super.firstFragment,
391391
});
392392

393-
void addFragment(FunctionElementImpl fragment) {
393+
void addFragment(TopLevelFunctionFragmentImpl fragment) {
394394
if (!identical(fragment, firstFragment)) {
395395
lastFragment.augmentation = fragment;
396396
lastFragment = fragment;

pkg/analyzer/lib/src/summary2/bundle_reader.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1207,7 +1207,7 @@ class LibraryReader {
12071207
var fragmentName = _readFragmentName();
12081208
var name = reference.elementName;
12091209

1210-
var fragment = FunctionElementImpl(name, -1);
1210+
var fragment = TopLevelFunctionFragmentImpl(name, -1);
12111211
fragment.name2 = fragmentName;
12121212

12131213
if (reference2.element2 case TopLevelFunctionElementImpl element?) {

pkg/analyzer/lib/src/summary2/bundle_writer.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -401,10 +401,10 @@ class BundleWriter {
401401
_sink._writeOptionalStringReference(fragment.name2);
402402
}
403403

404-
void _writeFunctionElement(FunctionElementImpl fragment) {
404+
void _writeFunctionElement(TopLevelFunctionFragmentImpl fragment) {
405405
_sink.writeUInt30(_resolutionSink.offset);
406406

407-
var element = fragment.element as TopLevelFunctionElementImpl;
407+
var element = fragment.element;
408408

409409
_writeReference(fragment);
410410
_writeReference2(element.reference);

pkg/analyzer/lib/src/summary2/element_builder.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -881,7 +881,7 @@ class ElementBuilder extends ThrowingAstVisitor<void> {
881881
_libraryBuilder.elementBuilderSetters[name] = elementBuilder;
882882
}
883883
} else {
884-
var fragment = FunctionElementImpl(name, nameOffset);
884+
var fragment = TopLevelFunctionFragmentImpl(name, nameOffset);
885885
fragment.name2 = _getFragmentName(nameToken);
886886
fragment.nameOffset2 = _getFragmentNameOffset(nameToken);
887887
fragment.isAugmentation = node.augmentKeyword != null;
@@ -1920,7 +1920,7 @@ class _EnclosingContext {
19201920
final List<ExtensionElementImpl> _extensions = [];
19211921
final List<ExtensionTypeElementImpl> _extensionTypes = [];
19221922
final List<FieldElementImpl> _fields = [];
1923-
final List<FunctionElementImpl> _functions = [];
1923+
final List<TopLevelFunctionFragmentImpl> _functions = [];
19241924
final List<MethodElementImpl> _methods = [];
19251925
final List<MixinElementImpl> _mixins = [];
19261926
final List<ParameterElementImpl> _parameters = [];
@@ -1974,7 +1974,7 @@ class _EnclosingContext {
19741974
return fragment.reference!;
19751975
}
19761976

1977-
List<FunctionElementImpl> get functions {
1977+
List<TopLevelFunctionFragmentImpl> get functions {
19781978
return _functions.toFixedList();
19791979
}
19801980

@@ -2060,7 +2060,7 @@ class _EnclosingContext {
20602060
_bindReference(reference, element);
20612061
}
20622062

2063-
Reference addFunction(String name, FunctionElementImpl element) {
2063+
Reference addFunction(String name, TopLevelFunctionFragmentImpl element) {
20642064
_functions.add(element);
20652065
var containerName =
20662066
element.isAugmentation ? '@functionAugmentation' : '@function';

pkg/analyzer/lib/src/summary2/element_flags.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,8 @@ class FunctionElementFlags {
220220
static const int _isGenerator = 1 << 4;
221221
static const int _isStatic = 1 << 5;
222222

223-
static void read(SummaryDataReader reader, FunctionElementImpl element) {
223+
static void read(
224+
SummaryDataReader reader, TopLevelFunctionFragmentImpl element) {
224225
var byte = reader.readByte();
225226
element.hasImplicitReturnType = (byte & _hasImplicitReturnType) != 0;
226227
element.isAsynchronous = (byte & _isAsynchronous) != 0;

pkg/analyzer/lib/src/summary2/informative_data.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,7 @@ class InformativeDataApplier {
568568
FunctionElement element,
569569
_InfoFunctionDeclaration info,
570570
) {
571-
element as FunctionElementImpl;
571+
element as TopLevelFunctionFragmentImpl;
572572
element.setCodeRange(info.codeOffset, info.codeLength);
573573
element.nameOffset = info.nameOffset;
574574
element.nameOffset2 = info.nameOffset2;

0 commit comments

Comments
 (0)