blob: 694f27dc289d8b64a699d6d1268374c4e907c5f1 [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/dart/element/element.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/summary2/link.dart';
import 'package:collection/collection.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 unitElement in builder.element.units) {
for (var classElement in unitElement.classes) {
for (var constructorElement in classElement.constructors) {
_constructor(classElement, constructorElement);
}
}
}
}
}
void _constructor(ClassElement classElement, ConstructorElement element) {
element as ConstructorElementImpl;
// Constructors of mixin applications are already configured.
if (classElement.isMixinApplication) {
return;
}
// We handle only generative constructors here.
if (element.isFactory) {
return;
}
var invokesDefaultSuperConstructor = true;
var node = _linker.getLinkingNode(element);
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 ?? '';
element.superConstructor = classElement.supertype?.constructors
.where((element) => element.name == name)
.firstOrNull;
}
}
}
if (invokesDefaultSuperConstructor) {
element.superConstructor = classElement.supertype?.constructors
.where((element) => element.name.isEmpty)
.firstOrNull;
}
}
}