Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(166)

Side by Side Diff: pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart

Issue 2755983002: Implement override checks for methods. (Closed)
Patch Set: Add TODO and merged with master. Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library fasta.kernel_class_builder; 5 library fasta.kernel_class_builder;
6 6
7 import 'package:kernel/ast.dart' 7 import 'package:kernel/ast.dart'
8 show 8 show
9 Class, 9 Class,
10 Constructor,
10 DartType, 11 DartType,
11 Expression, 12 Expression,
12 ExpressionStatement, 13 ExpressionStatement,
13 Field, 14 Field,
15 FunctionNode,
14 InterfaceType, 16 InterfaceType,
15 ListLiteral, 17 ListLiteral,
16 Member, 18 Member,
17 Name, 19 Name,
20 Procedure,
21 ProcedureKind,
18 StaticGet, 22 StaticGet,
19 StringLiteral, 23 StringLiteral,
20 Supertype, 24 Supertype,
21 Throw; 25 Throw,
26 VariableDeclaration;
27
28 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
22 29
23 import '../errors.dart' show internalError; 30 import '../errors.dart' show internalError;
24 31
25 import '../messages.dart' show warning; 32 import '../messages.dart' show warning;
26 33
34 import '../dill/dill_member_builder.dart' show DillMemberBuilder;
35
27 import 'kernel_builder.dart' 36 import 'kernel_builder.dart'
28 show 37 show
29 Builder, 38 Builder,
30 ClassBuilder, 39 ClassBuilder,
31 ConstructorReferenceBuilder, 40 ConstructorReferenceBuilder,
32 KernelLibraryBuilder, 41 KernelLibraryBuilder,
33 KernelProcedureBuilder, 42 KernelProcedureBuilder,
34 KernelTypeBuilder, 43 KernelTypeBuilder,
35 LibraryBuilder, 44 LibraryBuilder,
36 MetadataBuilder, 45 MetadataBuilder,
37 ProcedureBuilder, 46 ProcedureBuilder,
38 TypeVariableBuilder, 47 TypeVariableBuilder,
39 computeDefaultTypeArguments; 48 computeDefaultTypeArguments;
40 49
41 import '../dill/dill_member_builder.dart' show DillMemberBuilder;
42
43 import 'redirecting_factory_body.dart' show RedirectingFactoryBody; 50 import 'redirecting_factory_body.dart' show RedirectingFactoryBody;
44 51
45 abstract class KernelClassBuilder 52 abstract class KernelClassBuilder
46 extends ClassBuilder<KernelTypeBuilder, InterfaceType> { 53 extends ClassBuilder<KernelTypeBuilder, InterfaceType> {
47 KernelClassBuilder( 54 KernelClassBuilder(
48 List<MetadataBuilder> metadata, 55 List<MetadataBuilder> metadata,
49 int modifiers, 56 int modifiers,
50 String name, 57 String name,
51 List<TypeVariableBuilder> typeVariables, 58 List<TypeVariableBuilder> typeVariables,
52 KernelTypeBuilder supertype, 59 KernelTypeBuilder supertype,
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 initializer: literal, 166 initializer: literal,
160 fileUri: cls.fileUri)..fileOffset = cls.fileOffset; 167 fileUri: cls.fileUri)..fileOffset = cls.fileOffset;
161 cls.addMember(field); 168 cls.addMember(field);
162 return new DillMemberBuilder(field, this); 169 return new DillMemberBuilder(field, this);
163 }); 170 });
164 Field field = constructorsField.target; 171 Field field = constructorsField.target;
165 ListLiteral literal = field.initializer; 172 ListLiteral literal = field.initializer;
166 literal.expressions 173 literal.expressions
167 .add(new StaticGet(constructor.target)..parent = literal); 174 .add(new StaticGet(constructor.target)..parent = literal);
168 } 175 }
176
177 void checkOverrides(ClassHierarchy hierarchy) {
178 hierarchy.forEachOverridePair(cls, checkOverride);
179 }
180
181 void checkOverride(
182 Member declaredMember, Member interfaceMember, bool isSetter) {
183 if (declaredMember is Constructor || interfaceMember is Constructor) {
184 internalError(
185 "Constructor in override check.", fileUri, declaredMember.fileOffset);
186 }
187 if (declaredMember is Procedure && interfaceMember is Procedure) {
188 if (declaredMember.kind == ProcedureKind.Method &&
189 interfaceMember.kind == ProcedureKind.Method) {
190 checkMethodOverride(declaredMember, interfaceMember);
191 return;
192 }
193 }
194 // TODO(ahe): Handle other cases: accessors, operators, and fields.
195 }
196
197 void checkMethodOverride(
198 Procedure declaredMember, Procedure interfaceMember) {
199 if (declaredMember.enclosingClass != cls) {
200 // TODO(ahe): Include these checks as well, but the message needs to
201 // explain that [declaredMember] is inherited.
202 return;
203 }
204 assert(declaredMember.kind == ProcedureKind.Method);
205 assert(interfaceMember.kind == ProcedureKind.Method);
206 FunctionNode declaredFunction = declaredMember.function;
207 FunctionNode interfaceFunction = interfaceMember.function;
208 if (declaredFunction.typeParameters?.length !=
209 interfaceFunction.typeParameters?.length) {
210 addWarning(
211 declaredMember.fileOffset,
212 "Declared type variables of '$name::${declaredMember.name.name}' "
213 "doesn't match those on overridden method "
214 "'${interfaceMember.enclosingClass.name}::"
215 "${interfaceMember.name.name}'.");
216 }
217 if (declaredFunction.positionalParameters.length <
218 interfaceFunction.requiredParameterCount ||
219 declaredFunction.positionalParameters.length <
220 interfaceFunction.positionalParameters.length) {
221 addWarning(
222 declaredMember.fileOffset,
223 "The method '$name::${declaredMember.name.name}' has fewer "
224 "positional arguments than those of overridden method "
225 "'${interfaceMember.enclosingClass.name}::"
226 "${interfaceMember.name.name}'.");
227 }
228 if (interfaceFunction.requiredParameterCount <
229 declaredFunction.requiredParameterCount) {
230 addWarning(
231 declaredMember.fileOffset,
232 "The method '$name::${declaredMember.name.name}' has more "
233 "positional arguments than those of overridden method "
234 "'${interfaceMember.enclosingClass.name}::"
235 "${interfaceMember.name.name}'.");
236 }
237 if (declaredFunction.namedParameters.isEmpty &&
238 interfaceFunction.namedParameters.isEmpty) {
239 return;
240 }
241 if (declaredFunction.namedParameters.length <
242 interfaceFunction.namedParameters.length) {
243 addWarning(
244 declaredMember.fileOffset,
245 "The method '$name::${declaredMember.name.name}' has fewer named "
246 "arguments than those of overridden method "
247 "'${interfaceMember.enclosingClass.name}::"
248 "${interfaceMember.name.name}'.");
249 }
250 Iterator<VariableDeclaration> declaredNamedParameters =
251 declaredFunction.namedParameters.iterator;
252 Iterator<VariableDeclaration> interfaceNamedParameters =
253 interfaceFunction.namedParameters.iterator;
254 outer:
255 while (declaredNamedParameters.moveNext() &&
256 interfaceNamedParameters.moveNext()) {
257 while (declaredNamedParameters.current.name !=
258 interfaceNamedParameters.current.name) {
259 if (!declaredNamedParameters.moveNext()) {
260 addWarning(
261 declaredMember.fileOffset,
262 "The method '$name::${declaredMember.name.name}' doesn't have "
263 "the named parameter '${interfaceNamedParameters.current.name}' "
264 "of overriden method '${interfaceMember.enclosingClass.name}::"
265 "${interfaceMember.name.name}'.");
266 break outer;
267 }
268 }
269 }
270 }
271
272 void addCompileTimeError(int charOffset, String message) {
273 library.addCompileTimeError(charOffset, message, fileUri: fileUri);
274 }
275
276 void addWarning(int charOffset, String message) {
277 library.addWarning(charOffset, message, fileUri: fileUri);
278 }
279
280 void addNit(int charOffset, String message) {
281 library.addNit(charOffset, message, fileUri: fileUri);
282 }
169 } 283 }
OLDNEW
« no previous file with comments | « pkg/front_end/lib/src/fasta/colors.dart ('k') | pkg/front_end/lib/src/fasta/kernel/kernel_target.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698