blob: 29497d3ab612d67961b2b3f9e0e72ffbb03c65f9 [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,
);
}
}
}