blob: 3da915be35458236113c519d9b7483a0bc70eeb2 [file]
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/summary2/link.dart';
/// Resolves the explicit or implicit super-constructors invoked by
/// non-redirecting generative constructors.
class SuperConstructorResolver {
final Linker _linker;
SuperConstructorResolver(this._linker);
void perform() {
for (var builder in _linker.builders.values) {
for (var interfaceElement in <InterfaceElementImpl>[
...builder.element.classes,
...builder.element.enums,
]) {
for (var constructorElement in interfaceElement.constructors) {
_constructor(interfaceElement, constructorElement);
}
}
}
}
void _constructor(
InterfaceElementImpl interfaceElement,
ConstructorElementImpl element,
) {
// Constructors of mixin applications are already configured.
if (interfaceElement is ClassElementImpl &&
interfaceElement.isMixinApplication) {
return;
}
// We handle only generative constructors here.
if (element.isFactory) {
return;
}
var invokesDefaultSuperConstructor = true;
void handleInitializers(List<ConstructorInitializer> initializers) {
for (var initializer in initializers) {
if (initializer is RedirectingConstructorInvocation) {
invokesDefaultSuperConstructor = false;
} else if (initializer is SuperConstructorInvocation) {
invokesDefaultSuperConstructor = false;
var name = initializer.constructorSelector?.name2.lexeme ?? 'new';
element.superConstructor = interfaceElement.supertype
?.getNamedConstructor(name);
}
}
}
for (var fragment in element.fragments) {
var node = _linker.getLinkingNode(fragment);
if (node is ConstructorDeclaration) {
handleInitializers(node.initializers);
} else if (node is PrimaryConstructorDeclaration) {
if (node.body case var body?) {
handleInitializers(body.initializers);
}
}
}
if (invokesDefaultSuperConstructor) {
element.superConstructor = interfaceElement.supertype
?.getNamedConstructor('new');
}
}
}