blob: e023b438ef46404a57ed45e28c75217dd99a25aa [file] [log] [blame]
// 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 classElement in builder.element.classes) {
for (var constructorElement in classElement.constructors) {
_constructor(classElement, constructorElement);
}
}
}
}
void _constructor(
ClassElementImpl classElement,
ConstructorElementImpl element,
) {
// Constructors of mixin applications are already configured.
if (classElement.isMixinApplication) {
return;
}
// We handle only generative constructors here.
if (element.isFactory) {
return;
}
var invokesDefaultSuperConstructor = true;
for (var fragment in element.fragments) {
var node = _linker.getLinkingNode2(fragment);
if (node is ConstructorDeclaration) {
for (var initializer in node.initializers) {
if (initializer is RedirectingConstructorInvocation) {
invokesDefaultSuperConstructor = false;
} else if (initializer is SuperConstructorInvocation) {
invokesDefaultSuperConstructor = false;
var name = initializer.constructorName?.name ?? 'new';
element.superConstructor = classElement.supertype
?.getNamedConstructor(name);
}
}
}
}
if (invokesDefaultSuperConstructor) {
element.superConstructor = classElement.supertype?.getNamedConstructor(
'new',
);
}
}
}