blob: 478c841cc2f2aafed81fc6794eea7323b591de07 [file] [log] [blame]
// Copyright (c) 2022, 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 '../builder/builder.dart';
import '../builder/declaration_builders.dart';
import '../builder/member_builder.dart';
import '../builder/name_iterator.dart';
import 'source_library_builder.dart';
/// Common interface for builders for a class declarations in source code, such
/// as a regular class declaration and an extension type declaration.
// TODO(johnniwinther): Should this be renamed now that inline classes are
// renamed to extension type declarations?
// TODO(johnniwinther): Merge this with [IDeclarationBuilder]? Extensions are
// the only declarations without constructors, this might come with the static
// extension feature.
abstract class ClassDeclarationBuilder
implements IDeclarationBuilder, ClassMemberAccess {
@override
SourceLibraryBuilder get libraryBuilder;
bool get isMixinDeclaration;
int resolveConstructors(SourceLibraryBuilder library);
/// [Iterator] for all members declared directly in this class, including
/// augmenting members.
///
/// Duplicates are _not_ included.
///
/// For instance:
///
/// class Class {
/// // Declared, so it is included for this class but not for the
/// // augmentation class below.
/// method() {}
/// // Declared, so it is included for this class but not for the
/// // augmentation class below.
/// method2() {}
/// method2() {} // Duplicate, so it is *not* included.
/// }
///
/// augment class Class {
/// // Augmenting, so it is included for this augmentation class but
/// // not for the origin class above.
/// augment method() {}
/// // Declared, so it is included for this augmentation class but not
/// // for the origin class above.
/// extra() {}
/// }
///
Iterator<T> localMemberIterator<T extends Builder>();
/// [Iterator] for all constructors declared directly in this class, including
/// augmenting constructors.
///
/// For instance:
///
/// class Class {
/// // Declared, so it is included for this class but not for the
/// // augmentation class below.
/// Class();
/// // Declared, so it is included for this class but not for the
/// // augmentation class below.
/// Class.named();
/// Class.named(); // Duplicate, so it is *not* included.
/// }
///
/// augment class Class {
/// // Augmenting, so it is included for this augmentation class but
/// // not for the origin class above.
/// augment Class();
/// // Declared, so it is included for this augmentation class but not
/// // for the origin class above.
/// Class.extra();
/// }
///
Iterator<T> localConstructorIterator<T extends MemberBuilder>();
}
abstract class ClassDeclarationAugmentationAccess<
D extends ClassDeclarationBuilder> {
D getOrigin(D classDeclaration);
Iterable<D>? getAugmentations(D classDeclaration);
}
class ClassDeclarationMemberIterator<D extends ClassDeclarationBuilder,
T extends Builder> implements Iterator<T> {
Iterator<T>? _iterator;
Iterator<D>? augmentationBuilders;
final bool includeDuplicates;
factory ClassDeclarationMemberIterator.full(
ClassDeclarationAugmentationAccess<D> access, D classBuilder,
{required bool includeDuplicates}) {
return new ClassDeclarationMemberIterator._(
access.getOrigin(classBuilder),
access
.getAugmentations(classBuilder)
// Coverage-ignore(suite): Not run.
?.iterator,
includeDuplicates: includeDuplicates);
}
// Coverage-ignore(suite): Not run.
factory ClassDeclarationMemberIterator.local(D classBuilder,
{required bool includeDuplicates}) {
return new ClassDeclarationMemberIterator._(classBuilder, null,
includeDuplicates: includeDuplicates);
}
ClassDeclarationMemberIterator._(
D classDeclaration, this.augmentationBuilders,
{required this.includeDuplicates})
: _iterator = classDeclaration.nameSpace.filteredIterator<T>(
parent: classDeclaration,
includeDuplicates: includeDuplicates,
includeAugmentations: false);
@override
bool moveNext() {
if (_iterator != null) {
if (_iterator!.moveNext()) {
return true;
}
}
if (augmentationBuilders != null &&
// Coverage-ignore(suite): Not run.
augmentationBuilders!.moveNext()) {
// Coverage-ignore-block(suite): Not run.
D augmentationClassDeclaration = augmentationBuilders!.current;
_iterator = augmentationClassDeclaration.nameSpace.filteredIterator<T>(
parent: augmentationClassDeclaration,
includeDuplicates: includeDuplicates,
includeAugmentations: false);
}
if (_iterator != null) {
if (_iterator!.moveNext()) {
return true;
}
}
return false;
}
@override
T get current =>
_iterator?.current ?? // Coverage-ignore(suite): Not run.
(throw new StateError('No element'));
}
// Coverage-ignore(suite): Not run.
class ClassDeclarationMemberNameIterator<D extends ClassDeclarationBuilder,
T extends Builder> implements NameIterator<T> {
NameIterator<T>? _iterator;
Iterator<D>? augmentationBuilders;
final bool includeDuplicates;
factory ClassDeclarationMemberNameIterator(
ClassDeclarationAugmentationAccess<D> access, D classBuilder,
{required bool includeDuplicates}) {
return new ClassDeclarationMemberNameIterator._(
access.getOrigin(classBuilder),
access.getAugmentations(classBuilder)?.iterator,
includeDuplicates: includeDuplicates);
}
ClassDeclarationMemberNameIterator._(
D classDeclaration, this.augmentationBuilders,
{required this.includeDuplicates})
: _iterator = classDeclaration.nameSpace.filteredNameIterator<T>(
parent: classDeclaration,
includeDuplicates: includeDuplicates,
includeAugmentations: false);
@override
bool moveNext() {
if (_iterator != null) {
if (_iterator!.moveNext()) {
return true;
}
}
if (augmentationBuilders != null && augmentationBuilders!.moveNext()) {
D augmentationClassDeclaration = augmentationBuilders!.current;
_iterator = augmentationClassDeclaration.nameSpace
.filteredNameIterator<T>(
parent: augmentationClassDeclaration,
includeDuplicates: includeDuplicates,
includeAugmentations: false);
}
if (_iterator != null) {
if (_iterator!.moveNext()) {
return true;
}
}
return false;
}
@override
T get current => _iterator?.current ?? (throw new StateError('No element'));
@override
String get name => _iterator?.name ?? (throw new StateError('No element'));
}
class ClassDeclarationConstructorIterator<D extends ClassDeclarationBuilder,
T extends MemberBuilder> implements Iterator<T> {
Iterator<T>? _iterator;
Iterator<D>? augmentationBuilders;
final bool includeDuplicates;
factory ClassDeclarationConstructorIterator.full(
ClassDeclarationAugmentationAccess<D> access, D classBuilder,
{required bool includeDuplicates}) {
return new ClassDeclarationConstructorIterator._(
access.getOrigin(classBuilder),
access
.getAugmentations(classBuilder)
// Coverage-ignore(suite): Not run.
?.iterator,
includeDuplicates: includeDuplicates);
}
// Coverage-ignore(suite): Not run.
factory ClassDeclarationConstructorIterator.local(D classBuilder,
{required bool includeDuplicates}) {
return new ClassDeclarationConstructorIterator._(classBuilder, null,
includeDuplicates: includeDuplicates);
}
ClassDeclarationConstructorIterator._(
D classDeclaration, this.augmentationBuilders,
{required this.includeDuplicates})
: _iterator = classDeclaration.nameSpace.filteredConstructorIterator<T>(
parent: classDeclaration,
includeDuplicates: includeDuplicates,
includeAugmentations: false);
@override
bool moveNext() {
if (_iterator != null) {
if (_iterator!.moveNext()) {
return true;
}
}
if (augmentationBuilders != null &&
// Coverage-ignore(suite): Not run.
augmentationBuilders!.moveNext()) {
// Coverage-ignore-block(suite): Not run.
D augmentationClassDeclaration = augmentationBuilders!.current;
_iterator = augmentationClassDeclaration.nameSpace
.filteredConstructorIterator<T>(
parent: augmentationClassDeclaration,
includeDuplicates: includeDuplicates,
includeAugmentations: false);
}
if (_iterator != null) {
if (_iterator!.moveNext()) {
return true;
}
}
return false;
}
@override
T get current =>
_iterator?.current ?? // Coverage-ignore(suite): Not run.
(throw new StateError('No element'));
}
class ClassDeclarationConstructorNameIterator<D extends ClassDeclarationBuilder,
T extends MemberBuilder> implements NameIterator<T> {
NameIterator<T>? _iterator;
Iterator<D>? augmentationBuilders;
final bool includeDuplicates;
factory ClassDeclarationConstructorNameIterator(
ClassDeclarationAugmentationAccess<D> access, D classDeclaration,
{required bool includeDuplicates}) {
return new ClassDeclarationConstructorNameIterator._(
access.getOrigin(classDeclaration),
access
.getAugmentations(classDeclaration)
// Coverage-ignore(suite): Not run.
?.iterator,
includeDuplicates: includeDuplicates);
}
ClassDeclarationConstructorNameIterator._(
D classBuilder, this.augmentationBuilders,
{required this.includeDuplicates})
: _iterator = classBuilder.nameSpace.filteredConstructorNameIterator<T>(
parent: classBuilder,
includeDuplicates: includeDuplicates,
includeAugmentations: false);
@override
bool moveNext() {
if (_iterator != null) {
if (_iterator!.moveNext()) {
return true;
}
}
if (augmentationBuilders != null &&
// Coverage-ignore(suite): Not run.
augmentationBuilders!.moveNext()) {
// Coverage-ignore-block(suite): Not run.
D augmentationClassDeclaration = augmentationBuilders!.current;
_iterator = augmentationClassDeclaration.nameSpace
.filteredConstructorNameIterator<T>(
parent: augmentationClassDeclaration,
includeDuplicates: includeDuplicates,
includeAugmentations: false);
}
if (_iterator != null) {
if (_iterator!.moveNext()) {
return true;
}
}
return false;
}
@override
T get current =>
_iterator?.current ?? // Coverage-ignore(suite): Not run.
(throw new StateError('No element'));
@override
String get name =>
_iterator?.name ?? // Coverage-ignore(suite): Not run.
(throw new StateError('No element'));
}