blob: 7743380ef2323afc45ab37f37ea2fd964aad789b [file] [log] [blame]
// Copyright (c) 2024, 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 'proto.dart';
import 'references.dart';
import 'type_annotations.dart';
/// Scope used to lookup named entities.
abstract class Scope {
/// Returns the [Proto] corresponding to [name] in this scope.
///
/// This might be an [UnresolvedIdentifier] if [name] was not found in this
/// scope.
Proto lookup(String name);
}
/// Scope of a type declaration used to lookup static members.
abstract class TypeDeclarationScope {
/// Returns the [Proto] corresponding to accessing [name] on the type
/// declaration.
///
/// If the access is preceded by [typeArguments], these must be passed and
/// included in the returned [Proto].
Proto lookup(String name, [List<TypeAnnotation>? typeArguments]);
}
/// Base implementation for creating a [TypeDeclarationScope] for a class.
abstract base class BaseClassScope implements TypeDeclarationScope {
ClassReference get classReference;
Proto createConstructorProto(List<TypeAnnotation>? typeArguments,
ConstructorReference constructorReference) {
return new ConstructorProto(
classReference, typeArguments ?? const [], constructorReference);
}
Proto createMemberProto<T>(List<TypeAnnotation>? typeArguments, String name,
T? member, Proto Function(T, String) memberToProto) {
if (member == null) {
if (typeArguments != null) {
return new UnresolvedAccess(
new GenericClassProto(classReference, this, typeArguments), name);
} else {
return new UnresolvedAccess(new ClassProto(classReference, this), name);
}
} else {
if (typeArguments != null) {
return new InvalidAccessProto(
new GenericClassProto(classReference, this, typeArguments), name);
} else {
return memberToProto(member, name);
}
}
}
}
/// Base implementation for creating a [TypeDeclarationScope] for an extension.
abstract base class BaseExtensionScope implements TypeDeclarationScope {
ExtensionReference get extensionReference;
Proto createMemberProto<T>(List<TypeAnnotation>? typeArguments, String name,
T? member, Proto Function(T, String) memberToProto) {
if (typeArguments != null) {
return new UnresolvedAccess(
new InvalidInstantiationProto(
new ExtensionProto(extensionReference, this), typeArguments),
name);
} else if (member == null) {
return new UnresolvedAccess(
new ExtensionProto(extensionReference, this), name);
} else {
return memberToProto(member, name);
}
}
}
/// Base implementation for creating a [TypeDeclarationScope] for an extension
/// type.
abstract base class BaseExtensionTypeScope implements TypeDeclarationScope {
ExtensionTypeReference get extensionTypeReference;
Proto createConstructorProto(List<TypeAnnotation>? typeArguments,
ConstructorReference constructorReference) {
return new ConstructorProto(extensionTypeReference,
typeArguments ?? const [], constructorReference);
}
Proto createMemberProto<T>(List<TypeAnnotation>? typeArguments, String name,
T? member, Proto Function(T, String) memberToProto) {
if (member == null) {
if (typeArguments != null) {
return new UnresolvedAccess(
new GenericExtensionTypeProto(
extensionTypeReference, this, typeArguments),
name);
} else {
return new UnresolvedAccess(
new ExtensionTypeProto(extensionTypeReference, this), name);
}
} else {
if (typeArguments != null) {
return new InvalidAccessProto(
new GenericExtensionTypeProto(
extensionTypeReference, this, typeArguments),
name);
} else {
return memberToProto(member, name);
}
}
}
}
/// Base implementation for creating a [TypeDeclarationScope] for an enum.
abstract base class BaseEnumScope implements TypeDeclarationScope {
EnumReference get enumReference;
// TODO(johnniwinther): Support constructor lookup to support full parsing.
Proto createMemberProto<T>(List<TypeAnnotation>? typeArguments, String name,
T? member, Proto Function(T, String) memberToProto) {
if (member == null) {
if (typeArguments != null) {
return new UnresolvedAccess(
new GenericEnumProto(enumReference, this, typeArguments), name);
} else {
return new UnresolvedAccess(new EnumProto(enumReference, this), name);
}
} else {
if (typeArguments != null) {
return new InvalidAccessProto(
new GenericEnumProto(enumReference, this, typeArguments), name);
} else {
return memberToProto(member, name);
}
}
}
}
/// Base implementation for creating a [TypeDeclarationScope] for a mixin.
abstract base class BaseMixinScope implements TypeDeclarationScope {
MixinReference get mixinReference;
Proto createMemberProto<T>(List<TypeAnnotation>? typeArguments, String name,
T? member, Proto Function(T, String) memberToProto) {
if (member == null) {
if (typeArguments != null) {
return new UnresolvedAccess(
new GenericMixinProto(mixinReference, this, typeArguments), name);
} else {
return new UnresolvedAccess(new MixinProto(mixinReference, this), name);
}
} else {
if (typeArguments != null) {
return new InvalidAccessProto(
new GenericMixinProto(mixinReference, this, typeArguments), name);
} else {
return memberToProto(member, name);
}
}
}
}
/// Base implementation for creating a [TypeDeclarationScope] for a typedef.
abstract base class BaseTypedefScope implements TypeDeclarationScope {
TypedefReference get typedefReference;
Proto createConstructorProto(List<TypeAnnotation>? typeArguments,
ConstructorReference constructorReference) {
return new ConstructorProto(
typedefReference, typeArguments ?? const [], constructorReference);
}
Proto createMemberProto(List<TypeAnnotation>? typeArguments, String name) {
if (typeArguments != null) {
return new UnresolvedAccess(
new GenericTypedefProto(typedefReference, this, typeArguments), name);
} else {
return new UnresolvedAccess(
new TypedefProto(typedefReference, this), name);
}
}
}