-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
Copy pathsource_function_builder.dart
137 lines (130 loc) · 5.07 KB
/
source_function_builder.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Copyright (c) 2016, 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:kernel/ast.dart';
import 'package:kernel/class_hierarchy.dart';
import '../base/messages.dart'
show
messagePatchDeclarationMismatch,
messagePatchDeclarationOrigin,
messagePatchNonExternal,
noLength,
templateRequiredNamedParameterHasDefaultValueError;
import '../builder/builder.dart';
import '../builder/formal_parameter_builder.dart';
import '../builder/omitted_type_builder.dart';
import '../builder/type_builder.dart';
import '../type_inference/type_inference_engine.dart'
show IncludesTypeParametersNonCovariantly;
import 'source_library_builder.dart';
import 'source_type_parameter_builder.dart';
/// Builds the [TypeParameter]s for [declaredTypeParameters] and the parameter
/// [VariableDeclaration]s for [declaredFormals] and adds them to [function].
///
/// If [classTypeParameters] the bounds on type parameters and formal parameter
/// types will be marked as `isCovariantByClass` depending on their use of the
/// [classTypeParameters].
///
/// If [supportsTypeParameters] is false, declared type parameters are not added
/// to the function. This is done to avoid adding type parameters to
/// [Constructor]s which don't support them.
void buildTypeParametersAndFormals(
SourceLibraryBuilder libraryBuilder,
FunctionNode function,
List<SourceNominalParameterBuilder>? declaredTypeParameters,
List<FormalParameterBuilder>? declaredFormals,
{required List<TypeParameter>? classTypeParameters,
required bool supportsTypeParameters}) {
IncludesTypeParametersNonCovariantly? needsCheckVisitor;
if (classTypeParameters != null && classTypeParameters.isNotEmpty) {
needsCheckVisitor =
new IncludesTypeParametersNonCovariantly(classTypeParameters,
// We are checking the parameter types which are in a
// contravariant position.
initialVariance: Variance.contravariant);
}
if (declaredTypeParameters != null) {
for (SourceNominalParameterBuilder t in declaredTypeParameters) {
TypeParameter parameter = t.parameter;
if (supportsTypeParameters) {
function.typeParameters.add(parameter);
}
if (needsCheckVisitor != null) {
if (parameter.bound.accept(needsCheckVisitor)) {
parameter.isCovariantByClass = true;
}
}
}
setParents(function.typeParameters, function);
}
if (declaredFormals != null) {
for (FormalParameterBuilder formal in declaredFormals) {
VariableDeclaration parameter = formal.build(libraryBuilder);
if (needsCheckVisitor != null) {
if (parameter.type.accept(needsCheckVisitor)) {
parameter.isCovariantByClass = true;
}
}
if (formal.isNamed) {
function.namedParameters.add(parameter);
} else {
function.positionalParameters.add(parameter);
}
parameter.parent = function;
if (formal.isRequiredPositional) {
function.requiredParameterCount++;
}
// Required named parameters can't have default values.
if (formal.isRequiredNamed && formal.initializerToken != null) {
libraryBuilder.addProblem(
templateRequiredNamedParameterHasDefaultValueError
.withArguments(formal.name),
formal.fileOffset,
formal.name.length,
formal.fileUri);
}
}
}
}
// Coverage-ignore(suite): Not run.
/// Reports an error if [augmentation] is from a patch library and [origin] is
/// not external.
bool checkAugmentation(
{required SourceLibraryBuilder augmentationLibraryBuilder,
required Builder origin,
required Builder augmentation}) {
if (!origin.isExternal && !augmentationLibraryBuilder.isAugmentationLibrary) {
augmentationLibraryBuilder.addProblem(messagePatchNonExternal,
augmentation.fileOffset, noLength, augmentation.fileUri!,
context: [
messagePatchDeclarationOrigin.withLocation(
origin.fileUri!, origin.fileOffset, noLength)
]);
return false;
}
return true;
}
// Coverage-ignore(suite): Not run.
/// Reports the error that [augmentation] cannot augment [origin].
void reportAugmentationMismatch(
{required SourceLibraryBuilder originLibraryBuilder,
required Builder origin,
required Builder augmentation}) {
originLibraryBuilder.addProblem(messagePatchDeclarationMismatch,
augmentation.fileOffset, noLength, augmentation.fileUri!,
context: [
messagePatchDeclarationOrigin.withLocation(
origin.fileUri!, origin.fileOffset, noLength)
]);
}
extension FormalsMethods on List<FormalParameterBuilder> {
/// Ensures the type of each of the formals is inferred.
void infer(ClassHierarchy classHierarchy) {
for (FormalParameterBuilder formal in this) {
TypeBuilder formalType = formal.type;
if (formalType is InferableTypeBuilder) {
formalType.inferType(classHierarchy);
}
}
}
}