blob: 731b73b461751d6d60ef32d732a0f5bc761c279a [file] [log] [blame]
// Copyright (c) 2018, 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:_fe_analyzer_shared/src/scanner/token.dart' show Token;
import 'package:kernel/ast.dart';
import 'package:kernel/type_algebra.dart';
import 'package:kernel/type_environment.dart';
import '../api_prototype/experimental_flags.dart';
import '../base/constant_context.dart' show ConstantContext;
import '../base/lookup_result.dart';
import '../base/messages.dart' show Message;
import '../base/scope.dart';
import '../builder/builder.dart';
import '../builder/declaration_builders.dart';
import '../builder/formal_parameter_builder.dart';
import '../builder/library_builder.dart';
import '../builder/named_type_builder.dart';
import '../builder/prefix_builder.dart';
import '../builder/type_builder.dart';
import '../codes/cfe_codes.dart' show LocatedMessage;
import '../source/source_library_builder.dart' show SourceLibraryBuilder;
import '../type_inference/inference_helper.dart' show InferenceHelper;
import 'constness.dart' show Constness;
import 'expression_generator.dart';
import 'forest.dart' show Forest;
import 'internal_ast.dart';
/// Alias for Expression | Generator
typedef Expression_Generator = dynamic;
/// Alias for Expression | Generator | Builder
typedef Expression_Generator_Builder = dynamic;
/// Alias for Expression | Generator | Initializer
typedef Expression_Generator_Initializer = dynamic;
/// Alias for Expression | Initializer
typedef Expression_Initializer = dynamic;
abstract class ExpressionGeneratorHelper implements InferenceHelper {
SourceLibraryBuilder get libraryBuilder;
ConstantContext get constantContext;
/// Whether instance type parameters can be accessed.
///
/// This is used when creating [NamedTypeBuilder]s within
/// [ExpressionGenerator]s.
InstanceTypeParameterAccessState get instanceTypeParameterAccessState;
Forest get forest;
MemberLookupResult? lookupSuperConstructor(
String name,
LibraryBuilder accessingLibrary,
);
Expression toValue(Object? node);
Member? lookupSuperMember(Name name, {bool isSetter});
LibraryFeatures get libraryFeatures;
bool isDeclaredInEnclosingCase(VariableDeclaration variable);
Generator processLookupResult({
required LookupResult? lookupResult,
required String name,
required Token nameToken,
required int nameOffset,
required ScopeKind scopeKind,
PrefixBuilder? prefix,
Token? prefixToken,
});
Expression_Generator_Initializer finishSend(
Object receiver,
List<TypeBuilder>? typeArguments,
ArgumentsImpl arguments,
int offset, {
bool isTypeArgumentsInForest = false,
});
Initializer buildInvalidInitializer(
Expression expression, [
int offset = TreeNode.noOffset,
]);
List<Initializer> buildFieldInitializer(
String name,
int fieldNameOffset,
int assignmentOffset,
Expression expression, {
FormalParameterBuilder? formal,
});
Initializer buildSuperInitializer(
bool isSynthetic,
Constructor constructor,
Arguments arguments, [
int offset = TreeNode.noOffset,
]);
Initializer buildRedirectingInitializer(
Name name,
Arguments arguments, {
required int fileOffset,
});
Expression buildStaticInvocation(
Member target,
Arguments arguments, {
Constness constness = Constness.implicit,
int charOffset = TreeNode.noOffset,
required bool isConstructorInvocation,
});
Expression buildUnresolvedError(
String name,
int charOffset, {
Member candidate,
bool isSuper,
required UnresolvedKind kind,
bool isStatic,
Arguments? arguments,
Expression? rhs,
LocatedMessage message,
int? length,
bool errorHasBeenReported,
});
LocatedMessage? checkArgumentsForFunction(
FunctionNode function,
Arguments arguments,
int offset,
List<TypeParameter> typeParameters, {
Extension? extension,
});
Expression wrapInDeferredCheck(
Expression expression,
PrefixBuilder prefix,
int charOffset,
);
bool isIdentical(Member? member);
Expression buildMethodInvocation(
Expression receiver,
Name name,
Arguments arguments,
int offset, {
bool isConstantExpression = false,
bool isNullAware = false,
});
Expression buildSuperInvocation(
Name name,
Arguments arguments,
int offset, {
bool isConstantExpression = false,
bool isNullAware = false,
bool isImplicitCall = false,
});
Expression buildConstructorInvocation(
TypeDeclarationBuilder type,
Token nameToken,
Token nameLastToken,
Arguments arguments,
String name,
List<TypeBuilder>? typeArguments,
int charOffset,
Constness constness, {
bool isTypeArgumentsInForest = false,
TypeDeclarationBuilder? typeAliasBuilder,
required UnresolvedKind unresolvedKind,
});
TypeBuilder validateTypeParameterUse(
TypeBuilder typeBuilder, {
required bool allowPotentiallyConstantType,
});
void addProblemErrorIfConst(Message message, int charOffset, int length);
Expression buildProblemErrorIfConst(
Message message,
int charOffset,
int length,
);
Expression wrapInLocatedProblem(
Expression expression,
LocatedMessage message, {
List<LocatedMessage>? context,
bool includeExpression = true,
});
Expression evaluateArgumentsBefore(
Arguments arguments,
Expression expression,
);
DartType buildDartType(
TypeBuilder typeBuilder,
TypeUse typeUse, {
required bool allowPotentiallyConstantType,
});
List<DartType> buildDartTypeArguments(
List<TypeBuilder>? typeArguments,
TypeUse typeUse, {
required bool allowPotentiallyConstantType,
});
void reportDuplicatedDeclaration(
Builder existing,
String name,
int charOffset,
);
/// Creates a synthetic variable declaration for the value of [expression].
VariableDeclarationImpl createVariableDeclarationForValue(
Expression expression,
);
/// Creates a [VariableGet] of the [variable] using [charOffset] as the file
/// offset of the created node.
Expression createVariableGet(VariableDeclaration variable, int charOffset);
/// Registers that [variable] is read from.
///
/// This is needed for type promotion.
void registerVariableRead(VariableDeclaration variable);
/// Registers that [variable] is assigned to.
///
/// This is needed for type promotion.
void registerVariableAssignment(VariableDeclaration variable);
TypeEnvironment get typeEnvironment;
/// If explicit instantiations are supported in this library, create an
/// instantiation of the result of [receiverFunction] using
/// [typeArguments] followed by an invocation of [name] with [arguments].
/// Otherwise create the errors for the corresponding invalid implicit
/// creation expression.
///
/// This is used to handle the syntax for implicit creation expression as
/// an explicit instantiation with and invocation. For instance
///
/// a.b<c>.d()
///
/// The parser treat the as the constructor invocation of constructor `d` on
/// class `b` with prefix `a` with type arguments `<c>`, but with explicit
/// instantiation it could instead be the explicit instantiation of expression
/// `a.b` with type arguments `<c>` followed by and invocation of `d()`.
///
/// If [inImplicitCreationContext] is `false`, then the expression is
/// preceded by `new` or `const`, and an error should be reported instead of
/// creating the instantiation and invocation.
Expression createInstantiationAndInvocation(
Expression Function() receiverFunction,
List<TypeBuilder>? typeArguments,
String className,
String constructorName,
Arguments arguments, {
required int instantiationOffset,
required int invocationOffset,
required bool inImplicitCreationContext,
});
}
/// Checks that a generic [typedef] for a generic type declaration.
bool isProperRenameForTypeDeclaration(
TypeEnvironment typeEnvironment,
Typedef typedef,
Library typedefLibrary,
) {
DartType? rhsType = typedef.type;
if (rhsType is! TypeDeclarationType) {
return false;
}
List<TypeParameter> fromParameters = typedef.typeParameters;
List<TypeParameter> toParameters = rhsType.typeDeclaration.typeParameters;
List<DartType> typeArguments = rhsType.typeArguments;
if (fromParameters.length != typeArguments.length) {
return false;
}
for (int i = 0; i < fromParameters.length; ++i) {
if (typeArguments[i] !=
new TypeParameterType.withDefaultNullability(fromParameters[i])) {
return false;
}
}
Map<TypeParameter, DartType> substitutionMap = {};
for (int i = 0; i < fromParameters.length; ++i) {
substitutionMap[fromParameters[i]] =
new TypeParameterType.withDefaultNullability(toParameters[i]);
}
Substitution substitution = Substitution.fromMap(substitutionMap);
for (int i = 0; i < fromParameters.length; ++i) {
if (!typeEnvironment.areMutualSubtypes(
toParameters[i].bound,
substitution.substituteType(fromParameters[i].bound),
)) {
return false;
}
}
return true;
}
enum UnresolvedKind { Unknown, Member, Method, Getter, Setter, Constructor }