OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 dart2js.resolution.compute_members; | 5 library dart2js.resolution.compute_members; |
6 | 6 |
7 import '../common.dart'; | 7 import '../common.dart'; |
8 import '../common/names.dart' show | 8 import '../common/names.dart' show Identifiers, Names; |
9 Identifiers, | 9 import '../common/resolution.dart' show Resolution; |
10 Names; | 10 import '../compiler.dart' show Compiler; |
11 import '../common/resolution.dart' show | |
12 Resolution; | |
13 import '../compiler.dart' show | |
14 Compiler; | |
15 import '../dart_types.dart'; | 11 import '../dart_types.dart'; |
16 import '../elements/elements.dart' show | 12 import '../elements/elements.dart' |
17 ClassElement, | 13 show |
18 Element, | 14 ClassElement, |
19 LibraryElement, | 15 Element, |
20 Member, | 16 LibraryElement, |
21 MemberElement, | 17 Member, |
22 MemberSignature, | 18 MemberElement, |
23 MixinApplicationElement, | 19 MemberSignature, |
24 Name, | 20 MixinApplicationElement, |
25 PublicName; | 21 Name, |
| 22 PublicName; |
26 import '../util/util.dart'; | 23 import '../util/util.dart'; |
27 | 24 |
28 part 'member_impl.dart'; | 25 part 'member_impl.dart'; |
29 | 26 |
30 abstract class MembersCreator { | 27 abstract class MembersCreator { |
31 final ClassElement cls; | 28 final ClassElement cls; |
32 final Compiler compiler; | 29 final Compiler compiler; |
33 | 30 |
34 final Iterable<String> computedMemberNames; | 31 final Iterable<String> computedMemberNames; |
35 final Map<Name, Member> classMembers; | 32 final Map<Name, Member> classMembers; |
36 | 33 |
37 Map<dynamic/* Member | Element */, Set<MessageKind>> reportedMessages = | 34 Map<dynamic /* Member | Element */, Set<MessageKind>> reportedMessages = |
38 new Map<dynamic, Set<MessageKind>>(); | 35 new Map<dynamic, Set<MessageKind>>(); |
39 | 36 |
40 MembersCreator(Compiler this.compiler, | 37 MembersCreator( |
41 ClassElement this.cls, | 38 Compiler this.compiler, |
42 Iterable<String> this.computedMemberNames, | 39 ClassElement this.cls, |
43 Map<Name, Member> this.classMembers) { | 40 Iterable<String> this.computedMemberNames, |
| 41 Map<Name, Member> this.classMembers) { |
44 assert(invariant(cls, cls.isDeclaration, | 42 assert(invariant(cls, cls.isDeclaration, |
45 message: "Members may only be computed on declarations.")); | 43 message: "Members may only be computed on declarations.")); |
46 } | 44 } |
47 | 45 |
48 DiagnosticReporter get reporter => compiler.reporter; | 46 DiagnosticReporter get reporter => compiler.reporter; |
49 | 47 |
50 Resolution get resolution => compiler.resolution; | 48 Resolution get resolution => compiler.resolution; |
51 | 49 |
52 void reportMessage(var marker, MessageKind kind, report()) { | 50 void reportMessage(var marker, MessageKind kind, report()) { |
53 Set<MessageKind> messages = | 51 Set<MessageKind> messages = |
54 reportedMessages.putIfAbsent(marker, | 52 reportedMessages.putIfAbsent(marker, () => new Set<MessageKind>()); |
55 () => new Set<MessageKind>()); | |
56 if (messages.add(kind)) { | 53 if (messages.add(kind)) { |
57 report(); | 54 report(); |
58 } | 55 } |
59 } | 56 } |
60 | 57 |
61 bool shouldSkipMember(MemberSignature member) { | 58 bool shouldSkipMember(MemberSignature member) { |
62 return member == null || shouldSkipName(member.name.text); | 59 return member == null || shouldSkipName(member.name.text); |
63 | |
64 } | 60 } |
65 | 61 |
66 bool shouldSkipName(String name) { | 62 bool shouldSkipName(String name) { |
67 return computedMemberNames != null && | 63 return computedMemberNames != null && |
68 // 'call' is implicitly contained in [computedMemberNames]. | 64 // 'call' is implicitly contained in [computedMemberNames]. |
69 (name == Identifiers.call || computedMemberNames.contains(name)); | 65 (name == Identifiers.call || computedMemberNames.contains(name)); |
70 } | 66 } |
71 | 67 |
72 /// Compute all members of [cls] with the given names. | 68 /// Compute all members of [cls] with the given names. |
73 void computeMembersByName(String name, Setlet<Name> names) { | 69 void computeMembersByName(String name, Setlet<Name> names) { |
74 computeMembers(name, names); | 70 computeMembers(name, names); |
75 } | 71 } |
76 | 72 |
77 /// Compute all members of [cls] and checked that [cls] implements its | 73 /// Compute all members of [cls] and checked that [cls] implements its |
78 /// interface unless it is abstract or declares a `noSuchMethod` method. | 74 /// interface unless it is abstract or declares a `noSuchMethod` method. |
79 void computeAllMembers() { | 75 void computeAllMembers() { |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 // Abstract and static members are not mixed in. | 148 // Abstract and static members are not mixed in. |
153 DeclaredMember mixedInMember = | 149 DeclaredMember mixedInMember = |
154 member.inheritFrom(mixinApplication.mixinType); | 150 member.inheritFrom(mixinApplication.mixinType); |
155 DeclaredMember inherited = classMembers[name]; | 151 DeclaredMember inherited = classMembers[name]; |
156 classMembers[name] = mixedInMember; | 152 classMembers[name] = mixedInMember; |
157 checkValidOverride(mixedInMember, inherited); | 153 checkValidOverride(mixedInMember, inherited); |
158 } | 154 } |
159 } | 155 } |
160 | 156 |
161 if (names != null) { | 157 if (names != null) { |
162 _computeClassMember(compiler, mixinApplication.mixin, | 158 _computeClassMember( |
163 nameText, names); | 159 compiler, mixinApplication.mixin, nameText, names); |
164 for (Name memberName in names) { | 160 for (Name memberName in names) { |
165 inheritMixinMember( | 161 inheritMixinMember( |
166 mixinApplication.mixin.lookupClassMember(memberName)); | 162 mixinApplication.mixin.lookupClassMember(memberName)); |
167 } | 163 } |
168 } else { | 164 } else { |
169 computeAllClassMembers(compiler, mixinApplication.mixin); | 165 computeAllClassMembers(compiler, mixinApplication.mixin); |
170 mixinApplication.mixin.forEachClassMember(inheritMixinMember); | 166 mixinApplication.mixin.forEachClassMember(inheritMixinMember); |
171 } | 167 } |
172 } | 168 } |
173 } else { | 169 } else { |
174 LibraryElement library = cls.library; | 170 LibraryElement library = cls.library; |
175 InterfaceType thisType = cls.thisType; | 171 InterfaceType thisType = cls.thisType; |
176 | 172 |
177 void createMember(MemberElement element) { | 173 void createMember(MemberElement element) { |
178 if (element.isConstructor) return; | 174 if (element.isConstructor) return; |
179 String elementName = element.name; | 175 String elementName = element.name; |
180 if (shouldSkipName(elementName)) return; | 176 if (shouldSkipName(elementName)) return; |
181 if (nameText != null && elementName != nameText) return; | 177 if (nameText != null && elementName != nameText) return; |
182 | 178 |
183 void addDeclaredMember(Name name, | 179 void addDeclaredMember( |
184 DartType type, FunctionType functionType) { | 180 Name name, DartType type, FunctionType functionType) { |
185 DeclaredMember inherited = classMembers[name]; | 181 DeclaredMember inherited = classMembers[name]; |
186 DeclaredMember declared; | 182 DeclaredMember declared; |
187 if (element.isAbstract) { | 183 if (element.isAbstract) { |
188 declared = new DeclaredAbstractMember( | 184 declared = new DeclaredAbstractMember( |
189 name, element, thisType, type, functionType, | 185 name, element, thisType, type, functionType, inherited); |
190 inherited); | |
191 } else { | 186 } else { |
192 declared = | 187 declared = |
193 new DeclaredMember(name, element, thisType, type, functionType); | 188 new DeclaredMember(name, element, thisType, type, functionType); |
194 } | 189 } |
195 declaredMembers[name] = declared; | 190 declaredMembers[name] = declared; |
196 classMembers[name] = declared; | 191 classMembers[name] = declared; |
197 checkValidOverride(declared, inherited); | 192 checkValidOverride(declared, inherited); |
198 } | 193 } |
199 | 194 |
200 Name name = new Name(element.name, library); | 195 Name name = new Name(element.name, library); |
201 if (element.isField) { | 196 if (element.isField) { |
202 DartType type = element.computeType(resolution); | 197 DartType type = element.computeType(resolution); |
203 addDeclaredMember(name, type, new FunctionType.synthesized(type)); | 198 addDeclaredMember(name, type, new FunctionType.synthesized(type)); |
204 if (!element.isConst && !element.isFinal) { | 199 if (!element.isConst && !element.isFinal) { |
205 addDeclaredMember(name.setter, type, | 200 addDeclaredMember( |
| 201 name.setter, |
| 202 type, |
206 new FunctionType.synthesized( | 203 new FunctionType.synthesized( |
207 const VoidType(), | 204 const VoidType(), <DartType>[type])); |
208 <DartType>[type])); | |
209 } | 205 } |
210 } else if (element.isGetter) { | 206 } else if (element.isGetter) { |
211 FunctionType functionType = element.computeType(resolution); | 207 FunctionType functionType = element.computeType(resolution); |
212 DartType type = functionType.returnType; | 208 DartType type = functionType.returnType; |
213 addDeclaredMember(name, type, functionType); | 209 addDeclaredMember(name, type, functionType); |
214 } else if (element.isSetter) { | 210 } else if (element.isSetter) { |
215 FunctionType functionType = element.computeType(resolution); | 211 FunctionType functionType = element.computeType(resolution); |
216 DartType type; | 212 DartType type; |
217 if (!functionType.parameterTypes.isEmpty) { | 213 if (!functionType.parameterTypes.isEmpty) { |
218 type = functionType.parameterTypes.first; | 214 type = functionType.parameterTypes.first; |
(...skipping 16 matching lines...) Expand all Loading... |
235 createMember(element); | 231 createMember(element); |
236 } | 232 } |
237 }); | 233 }); |
238 } | 234 } |
239 } | 235 } |
240 | 236 |
241 return declaredMembers; | 237 return declaredMembers; |
242 } | 238 } |
243 | 239 |
244 /// Checks that [classMember] is a valid implementation for [interfaceMember]. | 240 /// Checks that [classMember] is a valid implementation for [interfaceMember]. |
245 void checkInterfaceMember(Name name, | 241 void checkInterfaceMember( |
246 MemberSignature interfaceMember, | 242 Name name, MemberSignature interfaceMember, Member classMember) { |
247 Member classMember) { | |
248 if (classMember != null) { | 243 if (classMember != null) { |
249 // TODO(johnniwinther): Check that the class member is a valid override | 244 // TODO(johnniwinther): Check that the class member is a valid override |
250 // of the interface member. | 245 // of the interface member. |
251 return; | 246 return; |
252 } | 247 } |
253 if (interfaceMember is DeclaredMember && | 248 if (interfaceMember is DeclaredMember && |
254 interfaceMember.declarer.element == cls) { | 249 interfaceMember.declarer.element == cls) { |
255 // Abstract method declared in [cls]. | 250 // Abstract method declared in [cls]. |
256 MessageKind kind = MessageKind.ABSTRACT_METHOD; | 251 MessageKind kind = MessageKind.ABSTRACT_METHOD; |
257 if (interfaceMember.isSetter) { | 252 if (interfaceMember.isSetter) { |
258 kind = MessageKind.ABSTRACT_SETTER; | 253 kind = MessageKind.ABSTRACT_SETTER; |
259 } else if (interfaceMember.isGetter) { | 254 } else if (interfaceMember.isGetter) { |
260 kind = MessageKind.ABSTRACT_GETTER; | 255 kind = MessageKind.ABSTRACT_GETTER; |
261 } | 256 } |
262 reportMessage( | 257 reportMessage(interfaceMember.element, MessageKind.ABSTRACT_METHOD, () { |
263 interfaceMember.element, MessageKind.ABSTRACT_METHOD, () { | 258 reporter.reportWarningMessage(interfaceMember.element, kind, |
264 reporter.reportWarningMessage( | |
265 interfaceMember.element, kind, | |
266 {'class': cls.name, 'name': name.text}); | 259 {'class': cls.name, 'name': name.text}); |
267 }); | 260 }); |
268 } else { | 261 } else { |
269 reportWarning(MessageKind singleKind, | 262 reportWarning(MessageKind singleKind, MessageKind multipleKind, |
270 MessageKind multipleKind, | 263 MessageKind explicitlyDeclaredKind, |
271 MessageKind explicitlyDeclaredKind, | 264 [MessageKind implicitlyDeclaredKind]) { |
272 [MessageKind implicitlyDeclaredKind]) { | |
273 Member inherited = interfaceMember.declarations.first; | 265 Member inherited = interfaceMember.declarations.first; |
274 reportMessage( | 266 reportMessage(interfaceMember, MessageKind.UNIMPLEMENTED_METHOD, () { |
275 interfaceMember, MessageKind.UNIMPLEMENTED_METHOD, () { | |
276 DiagnosticMessage warning = reporter.createMessage( | 267 DiagnosticMessage warning = reporter.createMessage( |
277 cls, | 268 cls, |
278 interfaceMember.declarations.length == 1 | 269 interfaceMember.declarations.length == 1 |
279 ? singleKind : multipleKind, | 270 ? singleKind |
280 {'class': cls.name, | 271 : multipleKind, |
281 'name': name.text, | 272 { |
282 'method': interfaceMember, | 273 'class': cls.name, |
283 'declarer': inherited.declarer}); | 274 'name': name.text, |
| 275 'method': interfaceMember, |
| 276 'declarer': inherited.declarer |
| 277 }); |
284 List<DiagnosticMessage> infos = <DiagnosticMessage>[]; | 278 List<DiagnosticMessage> infos = <DiagnosticMessage>[]; |
285 for (Member inherited in interfaceMember.declarations) { | 279 for (Member inherited in interfaceMember.declarations) { |
286 infos.add(reporter.createMessage( | 280 infos.add(reporter.createMessage( |
287 inherited.element, | 281 inherited.element, |
288 inherited.isDeclaredByField ? | 282 inherited.isDeclaredByField |
289 implicitlyDeclaredKind : explicitlyDeclaredKind, | 283 ? implicitlyDeclaredKind |
290 {'class': inherited.declarer.name, | 284 : explicitlyDeclaredKind, |
291 'name': name.text})); | 285 {'class': inherited.declarer.name, 'name': name.text})); |
292 } | 286 } |
293 reporter.reportWarning(warning, infos); | 287 reporter.reportWarning(warning, infos); |
294 }); | 288 }); |
295 } | 289 } |
296 if (interfaceMember.isSetter) { | 290 if (interfaceMember.isSetter) { |
297 reportWarning(MessageKind.UNIMPLEMENTED_SETTER_ONE, | 291 reportWarning( |
298 MessageKind.UNIMPLEMENTED_SETTER, | 292 MessageKind.UNIMPLEMENTED_SETTER_ONE, |
299 MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER, | 293 MessageKind.UNIMPLEMENTED_SETTER, |
300 MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER); | 294 MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER, |
| 295 MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER); |
301 } else if (interfaceMember.isGetter) { | 296 } else if (interfaceMember.isGetter) { |
302 reportWarning(MessageKind.UNIMPLEMENTED_GETTER_ONE, | 297 reportWarning( |
303 MessageKind.UNIMPLEMENTED_GETTER, | 298 MessageKind.UNIMPLEMENTED_GETTER_ONE, |
304 MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER, | 299 MessageKind.UNIMPLEMENTED_GETTER, |
305 MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER); | 300 MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER, |
| 301 MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER); |
306 } else if (interfaceMember.isMethod) { | 302 } else if (interfaceMember.isMethod) { |
307 reportWarning(MessageKind.UNIMPLEMENTED_METHOD_ONE, | 303 reportWarning( |
308 MessageKind.UNIMPLEMENTED_METHOD, | 304 MessageKind.UNIMPLEMENTED_METHOD_ONE, |
309 MessageKind.UNIMPLEMENTED_METHOD_CONT); | 305 MessageKind.UNIMPLEMENTED_METHOD, |
| 306 MessageKind.UNIMPLEMENTED_METHOD_CONT); |
310 } | 307 } |
311 } | 308 } |
312 // TODO(johnniwinther): If [cls] is not abstract, check that for all | 309 // TODO(johnniwinther): If [cls] is not abstract, check that for all |
313 // interface members, there is a class member whose type is a subtype of | 310 // interface members, there is a class member whose type is a subtype of |
314 // the interface member. | 311 // the interface member. |
315 } | 312 } |
316 | 313 |
317 /// Checks that [cls], if it implements Function, has defined call(). | 314 /// Checks that [cls], if it implements Function, has defined call(). |
318 void checkImplementsFunctionWithCall() { | 315 void checkImplementsFunctionWithCall() { |
319 assert(!cls.isAbstract); | 316 assert(!cls.isAbstract); |
320 | 317 |
321 ClassElement functionClass = compiler.coreClasses.functionClass; | 318 ClassElement functionClass = compiler.coreClasses.functionClass; |
322 if (cls.asInstanceOf(functionClass) == null) return; | 319 if (cls.asInstanceOf(functionClass) == null) return; |
323 if (cls.lookupMember(Identifiers.call) != null) return; | 320 if (cls.lookupMember(Identifiers.call) != null) return; |
324 // TODO(johnniwinther): Make separate methods for backend exceptions. | 321 // TODO(johnniwinther): Make separate methods for backend exceptions. |
325 // Avoid warnings on backend implementation classes for closures. | 322 // Avoid warnings on backend implementation classes for closures. |
326 if (compiler.backend.isBackendLibrary(cls.library)) return; | 323 if (compiler.backend.isBackendLibrary(cls.library)) return; |
327 | 324 |
328 reportMessage(functionClass, MessageKind.UNIMPLEMENTED_METHOD, () { | 325 reportMessage(functionClass, MessageKind.UNIMPLEMENTED_METHOD, () { |
329 reporter.reportWarningMessage( | 326 reporter.reportWarningMessage(cls, MessageKind.UNIMPLEMENTED_METHOD_ONE, { |
330 cls, | 327 'class': cls.name, |
331 MessageKind.UNIMPLEMENTED_METHOD_ONE, | 328 'name': Identifiers.call, |
332 {'class': cls.name, | 329 'method': Identifiers.call, |
333 'name': Identifiers.call, | 330 'declarer': functionClass.name |
334 'method': Identifiers.call, | 331 }); |
335 'declarer': functionClass.name}); | |
336 }); | 332 }); |
337 } | 333 } |
338 | 334 |
339 /// Checks that a class member exists for every interface member. | 335 /// Checks that a class member exists for every interface member. |
340 void checkInterfaceImplementation(); | 336 void checkInterfaceImplementation(); |
341 | 337 |
342 /// Check that [declared] is a valid override of [superMember]. | 338 /// Check that [declared] is a valid override of [superMember]. |
343 void checkValidOverride(Member declared, MemberSignature superMember) { | 339 void checkValidOverride(Member declared, MemberSignature superMember) { |
344 if (superMember == null) { | 340 if (superMember == null) { |
345 // No override. | 341 // No override. |
346 if (!declared.isStatic) { | 342 if (!declared.isStatic) { |
347 ClassElement superclass = cls.superclass; | 343 ClassElement superclass = cls.superclass; |
348 while (superclass != null) { | 344 while (superclass != null) { |
349 Member superMember = | 345 Member superMember = superclass.lookupClassMember(declared.name); |
350 superclass.lookupClassMember(declared.name); | |
351 if (superMember != null && superMember.isStatic) { | 346 if (superMember != null && superMember.isStatic) { |
352 reportMessage(superMember, MessageKind.INSTANCE_STATIC_SAME_NAME, | 347 reportMessage(superMember, MessageKind.INSTANCE_STATIC_SAME_NAME, |
353 () { | 348 () { |
354 reporter.reportWarning( | 349 reporter.reportWarning( |
355 reporter.createMessage( | 350 reporter.createMessage( |
356 declared.element, | 351 declared.element, MessageKind.INSTANCE_STATIC_SAME_NAME, { |
357 MessageKind.INSTANCE_STATIC_SAME_NAME, | 352 'memberName': declared.name, |
358 {'memberName': declared.name, | 353 'className': superclass.name |
359 'className': superclass.name}), | 354 }), |
360 <DiagnosticMessage>[ | 355 <DiagnosticMessage>[ |
361 reporter.createMessage( | 356 reporter.createMessage(superMember.element, |
362 superMember.element, | 357 MessageKind.INSTANCE_STATIC_SAME_NAME_CONT), |
363 MessageKind.INSTANCE_STATIC_SAME_NAME_CONT), | |
364 ]); | 358 ]); |
365 | |
366 }); | 359 }); |
367 break; | 360 break; |
368 } | 361 } |
369 superclass = superclass.superclass; | 362 superclass = superclass.superclass; |
370 } | 363 } |
371 } | 364 } |
372 } else { | 365 } else { |
373 assert(declared.name == superMember.name); | 366 assert(declared.name == superMember.name); |
374 | 367 |
375 if (declared.isStatic) { | 368 if (declared.isStatic) { |
376 for (Member inherited in superMember.declarations) { | 369 for (Member inherited in superMember.declarations) { |
377 if (cls == inherited.declarer.element) { | 370 if (cls == inherited.declarer.element) { |
378 // An error should already have been reported. | 371 // An error should already have been reported. |
379 assert(invariant(declared.element, compiler.compilationFailed)); | 372 assert(invariant(declared.element, compiler.compilationFailed)); |
380 continue; | 373 continue; |
381 } | 374 } |
382 | 375 |
383 reportMessage( | 376 reportMessage(inherited.element, MessageKind.NO_STATIC_OVERRIDE, () { |
384 inherited.element, MessageKind.NO_STATIC_OVERRIDE, () { | |
385 reportErrorWithContext( | 377 reportErrorWithContext( |
386 declared.element, MessageKind.NO_STATIC_OVERRIDE, | 378 declared.element, |
387 inherited.element, MessageKind.NO_STATIC_OVERRIDE_CONT); | 379 MessageKind.NO_STATIC_OVERRIDE, |
| 380 inherited.element, |
| 381 MessageKind.NO_STATIC_OVERRIDE_CONT); |
388 }); | 382 }); |
389 } | 383 } |
390 } | 384 } |
391 | 385 |
392 DartType declaredType = declared.functionType; | 386 DartType declaredType = declared.functionType; |
393 for (Member inherited in superMember.declarations) { | 387 for (Member inherited in superMember.declarations) { |
394 if (inherited.element == declared.element) { | 388 if (inherited.element == declared.element) { |
395 // TODO(ahe): For some reason, "call" elements are repeated in | 389 // TODO(ahe): For some reason, "call" elements are repeated in |
396 // superMember.declarations. Investigate why. | 390 // superMember.declarations. Investigate why. |
397 } else if (cls == inherited.declarer.element) { | 391 } else if (cls == inherited.declarer.element) { |
398 // An error should already have been reported. | 392 // An error should already have been reported. |
399 assert(invariant(declared.element, compiler.compilationFailed, | 393 assert(invariant(declared.element, compiler.compilationFailed, |
400 message: "Member $inherited inherited from its " | 394 message: "Member $inherited inherited from its " |
401 "declaring class: ${cls}.")); | 395 "declaring class: ${cls}.")); |
402 continue; | 396 continue; |
403 } | 397 } |
404 | 398 |
405 void reportError(MessageKind errorKind, MessageKind infoKind) { | 399 void reportError(MessageKind errorKind, MessageKind infoKind) { |
406 reportMessage( | 400 reportMessage(inherited.element, MessageKind.INVALID_OVERRIDE_METHOD, |
407 inherited.element, MessageKind.INVALID_OVERRIDE_METHOD, () { | 401 () { |
408 reporter.reportError( | 402 reporter.reportError( |
409 reporter.createMessage( | 403 reporter.createMessage(declared.element, errorKind, { |
410 declared.element, | 404 'name': declared.name.text, |
411 errorKind, | 405 'class': cls.thisType, |
412 {'name': declared.name.text, | 406 'inheritedClass': inherited.declarer |
413 'class': cls.thisType, | 407 }), |
414 'inheritedClass': inherited.declarer}), | |
415 <DiagnosticMessage>[ | 408 <DiagnosticMessage>[ |
416 reporter.createMessage( | 409 reporter.createMessage(inherited.element, infoKind, { |
417 inherited.element, | 410 'name': declared.name.text, |
418 infoKind, | 411 'class': inherited.declarer |
419 {'name': declared.name.text, | 412 }), |
420 'class': inherited.declarer}), | |
421 ]); | 413 ]); |
422 }); | 414 }); |
423 } | 415 } |
424 | 416 |
425 if (declared.isDeclaredByField && inherited.isMethod) { | 417 if (declared.isDeclaredByField && inherited.isMethod) { |
426 reportError(MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD, | 418 reportError(MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD, |
427 MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT); | 419 MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT); |
428 } else if (declared.isMethod && inherited.isDeclaredByField) { | 420 } else if (declared.isMethod && inherited.isDeclaredByField) { |
429 reportError(MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD, | 421 reportError(MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD, |
430 MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT); | 422 MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT); |
431 } else if (declared.isGetter && inherited.isMethod) { | 423 } else if (declared.isGetter && inherited.isMethod) { |
432 reportError(MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER, | 424 reportError(MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER, |
433 MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT); | 425 MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT); |
434 } else if (declared.isMethod && inherited.isGetter) { | 426 } else if (declared.isMethod && inherited.isGetter) { |
435 reportError(MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD, | 427 reportError(MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD, |
436 MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT); | 428 MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT); |
437 } else { | 429 } else { |
438 DartType inheritedType = inherited.functionType; | 430 DartType inheritedType = inherited.functionType; |
439 if (!compiler.types.isSubtype(declaredType, inheritedType)) { | 431 if (!compiler.types.isSubtype(declaredType, inheritedType)) { |
440 void reportWarning(var marker, | 432 void reportWarning( |
441 MessageKind warningKind, | 433 var marker, MessageKind warningKind, MessageKind infoKind) { |
442 MessageKind infoKind) { | |
443 reportMessage(marker, MessageKind.INVALID_OVERRIDE_METHOD, () { | 434 reportMessage(marker, MessageKind.INVALID_OVERRIDE_METHOD, () { |
444 reporter.reportWarning( | 435 reporter.reportWarning( |
445 reporter.createMessage( | 436 reporter.createMessage(declared.element, warningKind, { |
446 declared.element, | 437 'declaredType': declared.type, |
447 warningKind, | 438 'name': declared.name.text, |
448 {'declaredType': declared.type, | 439 'class': cls.thisType, |
449 'name': declared.name.text, | 440 'inheritedType': inherited.type, |
450 'class': cls.thisType, | 441 'inheritedClass': inherited.declarer |
451 'inheritedType': inherited.type, | 442 }), |
452 'inheritedClass': inherited.declarer}), | |
453 <DiagnosticMessage>[ | 443 <DiagnosticMessage>[ |
454 reporter.createMessage( | 444 reporter.createMessage(inherited.element, infoKind, { |
455 inherited.element, | 445 'name': declared.name.text, |
456 infoKind, | 446 'class': inherited.declarer |
457 {'name': declared.name.text, | 447 }), |
458 'class': inherited.declarer}), | |
459 ]); | 448 ]); |
460 }); | 449 }); |
461 } | 450 } |
462 if (declared.isDeclaredByField) { | 451 if (declared.isDeclaredByField) { |
463 if (inherited.isDeclaredByField) { | 452 if (inherited.isDeclaredByField) { |
464 reportWarning(inherited.element, | 453 reportWarning( |
465 MessageKind.INVALID_OVERRIDE_FIELD, | 454 inherited.element, |
466 MessageKind.INVALID_OVERRIDDEN_FIELD); | 455 MessageKind.INVALID_OVERRIDE_FIELD, |
| 456 MessageKind.INVALID_OVERRIDDEN_FIELD); |
467 } else if (inherited.isGetter) { | 457 } else if (inherited.isGetter) { |
468 reportWarning(inherited, | 458 reportWarning( |
469 MessageKind.INVALID_OVERRIDE_GETTER_WITH_FIELD, | 459 inherited, |
470 MessageKind.INVALID_OVERRIDDEN_GETTER); | 460 MessageKind.INVALID_OVERRIDE_GETTER_WITH_FIELD, |
| 461 MessageKind.INVALID_OVERRIDDEN_GETTER); |
471 } else if (inherited.isSetter) { | 462 } else if (inherited.isSetter) { |
472 reportWarning(inherited, | 463 reportWarning( |
473 MessageKind.INVALID_OVERRIDE_SETTER_WITH_FIELD, | 464 inherited, |
474 MessageKind.INVALID_OVERRIDDEN_SETTER); | 465 MessageKind.INVALID_OVERRIDE_SETTER_WITH_FIELD, |
| 466 MessageKind.INVALID_OVERRIDDEN_SETTER); |
475 } | 467 } |
476 } else if (declared.isGetter) { | 468 } else if (declared.isGetter) { |
477 if (inherited.isDeclaredByField) { | 469 if (inherited.isDeclaredByField) { |
478 reportWarning(inherited, | 470 reportWarning( |
479 MessageKind.INVALID_OVERRIDE_FIELD_WITH_GETTER, | 471 inherited, |
480 MessageKind.INVALID_OVERRIDDEN_FIELD); | 472 MessageKind.INVALID_OVERRIDE_FIELD_WITH_GETTER, |
| 473 MessageKind.INVALID_OVERRIDDEN_FIELD); |
481 } else { | 474 } else { |
482 reportWarning(inherited, | 475 reportWarning(inherited, MessageKind.INVALID_OVERRIDE_GETTER, |
483 MessageKind.INVALID_OVERRIDE_GETTER, | 476 MessageKind.INVALID_OVERRIDDEN_GETTER); |
484 MessageKind.INVALID_OVERRIDDEN_GETTER); | |
485 } | 477 } |
486 } else if (declared.isSetter) { | 478 } else if (declared.isSetter) { |
487 if (inherited.isDeclaredByField) { | 479 if (inherited.isDeclaredByField) { |
488 reportWarning(inherited, | 480 reportWarning( |
489 MessageKind.INVALID_OVERRIDE_FIELD_WITH_SETTER, | 481 inherited, |
490 MessageKind.INVALID_OVERRIDDEN_FIELD); | 482 MessageKind.INVALID_OVERRIDE_FIELD_WITH_SETTER, |
| 483 MessageKind.INVALID_OVERRIDDEN_FIELD); |
491 } else { | 484 } else { |
492 reportWarning(inherited, | 485 reportWarning(inherited, MessageKind.INVALID_OVERRIDE_SETTER, |
493 MessageKind.INVALID_OVERRIDE_SETTER, | 486 MessageKind.INVALID_OVERRIDDEN_SETTER); |
494 MessageKind.INVALID_OVERRIDDEN_SETTER); | |
495 } | 487 } |
496 } else { | 488 } else { |
497 reportWarning(inherited, | 489 reportWarning(inherited, MessageKind.INVALID_OVERRIDE_METHOD, |
498 MessageKind.INVALID_OVERRIDE_METHOD, | 490 MessageKind.INVALID_OVERRIDDEN_METHOD); |
499 MessageKind.INVALID_OVERRIDDEN_METHOD); | |
500 } | 491 } |
501 } | 492 } |
502 } | 493 } |
503 } | 494 } |
504 } | 495 } |
505 } | 496 } |
506 | 497 |
507 void reportErrorWithContext(Element errorneousElement, | 498 void reportErrorWithContext( |
508 MessageKind errorMessage, | 499 Element errorneousElement, |
509 Element contextElement, | 500 MessageKind errorMessage, |
510 MessageKind contextMessage) { | 501 Element contextElement, |
| 502 MessageKind contextMessage) { |
511 reporter.reportError( | 503 reporter.reportError( |
512 reporter.createMessage( | 504 reporter.createMessage(errorneousElement, errorMessage, { |
513 errorneousElement, | 505 'memberName': contextElement.name, |
514 errorMessage, | 506 'className': contextElement.enclosingClass.name |
515 {'memberName': contextElement.name, | 507 }), |
516 'className': contextElement.enclosingClass.name}), | |
517 <DiagnosticMessage>[ | 508 <DiagnosticMessage>[ |
518 reporter.createMessage(contextElement, contextMessage), | 509 reporter.createMessage(contextElement, contextMessage), |
519 ]); | 510 ]); |
520 } | 511 } |
521 | 512 |
522 /// Compute all class and interface names by the [name] in [cls]. | 513 /// Compute all class and interface names by the [name] in [cls]. |
523 static void computeClassMembersByName(Compiler compiler, | 514 static void computeClassMembersByName( |
524 ClassMemberMixin cls, | 515 Compiler compiler, ClassMemberMixin cls, String name) { |
525 String name) { | |
526 if (cls.isMemberComputed(name)) return; | 516 if (cls.isMemberComputed(name)) return; |
527 LibraryElement library = cls.library; | 517 LibraryElement library = cls.library; |
528 _computeClassMember(compiler, cls, name, | 518 _computeClassMember( |
529 new Setlet<Name>()..add(new Name(name, library)) | 519 compiler, |
530 ..add(new Name(name, library, isSetter: true))); | 520 cls, |
| 521 name, |
| 522 new Setlet<Name>() |
| 523 ..add(new Name(name, library)) |
| 524 ..add(new Name(name, library, isSetter: true))); |
531 } | 525 } |
532 | 526 |
533 static void _computeClassMember(Compiler compiler, | 527 static void _computeClassMember(Compiler compiler, ClassMemberMixin cls, |
534 ClassMemberMixin cls, | 528 String name, Setlet<Name> names) { |
535 String name, | |
536 Setlet<Name> names) { | |
537 cls.computeClassMember(compiler, name, names); | 529 cls.computeClassMember(compiler, name, names); |
538 } | 530 } |
539 | 531 |
540 /// Compute all class and interface names in [cls]. | 532 /// Compute all class and interface names in [cls]. |
541 static void computeAllClassMembers(Compiler compiler, ClassMemberMixin cls) { | 533 static void computeAllClassMembers(Compiler compiler, ClassMemberMixin cls) { |
542 cls.computeAllClassMembers(compiler); | 534 cls.computeAllClassMembers(compiler); |
543 } | 535 } |
544 } | 536 } |
545 | 537 |
546 /// Class member creator for classes where the interface members are known to | 538 /// Class member creator for classes where the interface members are known to |
547 /// be a subset of the class members. | 539 /// be a subset of the class members. |
548 class ClassMembersCreator extends MembersCreator { | 540 class ClassMembersCreator extends MembersCreator { |
549 ClassMembersCreator(Compiler compiler, | 541 ClassMembersCreator(Compiler compiler, ClassElement cls, |
550 ClassElement cls, | 542 Iterable<String> computedMemberNames, Map<Name, Member> classMembers) |
551 Iterable<String> computedMemberNames, | |
552 Map<Name, Member> classMembers) | |
553 : super(compiler, cls, computedMemberNames, classMembers); | 543 : super(compiler, cls, computedMemberNames, classMembers); |
554 | 544 |
555 Map<Name, Member> computeMembers(String name, Setlet<Name> names) { | 545 Map<Name, Member> computeMembers(String name, Setlet<Name> names) { |
556 computeSuperMembers(name, names); | 546 computeSuperMembers(name, names); |
557 return computeClassMembers(name, names); | 547 return computeClassMembers(name, names); |
558 } | 548 } |
559 | 549 |
560 void computeSuperMembers(String name, Setlet<Name> names) { | 550 void computeSuperMembers(String name, Setlet<Name> names) { |
561 computeSuperClassMembers(name, names); | 551 computeSuperClassMembers(name, names); |
562 } | 552 } |
563 | 553 |
564 void checkInterfaceImplementation() { | 554 void checkInterfaceImplementation() { |
565 LibraryElement library = cls.library; | 555 LibraryElement library = cls.library; |
566 classMembers.forEach((Name name, Member classMember) { | 556 classMembers.forEach((Name name, Member classMember) { |
567 if (!name.isAccessibleFrom(library)) return; | 557 if (!name.isAccessibleFrom(library)) return; |
568 checkInterfaceMember(name, classMember, classMember.implementation); | 558 checkInterfaceMember(name, classMember, classMember.implementation); |
569 }); | 559 }); |
570 } | 560 } |
571 } | 561 } |
572 | 562 |
573 /// Class Member creator for classes where the interface members might be | 563 /// Class Member creator for classes where the interface members might be |
574 /// different from the class members. | 564 /// different from the class members. |
575 class InterfaceMembersCreator extends MembersCreator { | 565 class InterfaceMembersCreator extends MembersCreator { |
576 final Map<Name, MemberSignature> interfaceMembers; | 566 final Map<Name, MemberSignature> interfaceMembers; |
577 | 567 |
578 InterfaceMembersCreator(Compiler compiler, | 568 InterfaceMembersCreator( |
579 ClassElement cls, | 569 Compiler compiler, |
580 Iterable<String> computedMemberNames, | 570 ClassElement cls, |
581 Map<Name, Member> classMembers, | 571 Iterable<String> computedMemberNames, |
582 Map<Name, MemberSignature> this.interfaceMembers) | 572 Map<Name, Member> classMembers, |
| 573 Map<Name, MemberSignature> this.interfaceMembers) |
583 : super(compiler, cls, computedMemberNames, classMembers); | 574 : super(compiler, cls, computedMemberNames, classMembers); |
584 | 575 |
585 Map<Name, Member> computeMembers(String name, Setlet<Name> names) { | 576 Map<Name, Member> computeMembers(String name, Setlet<Name> names) { |
586 Map<Name, Setlet<Member>> inheritedInterfaceMembers = | 577 Map<Name, Setlet<Member>> inheritedInterfaceMembers = |
587 computeSuperMembers(name, names); | 578 computeSuperMembers(name, names); |
588 Map<Name, Member> declaredMembers = computeClassMembers(name, names); | 579 Map<Name, Member> declaredMembers = computeClassMembers(name, names); |
589 computeInterfaceMembers(inheritedInterfaceMembers, declaredMembers); | 580 computeInterfaceMembers(inheritedInterfaceMembers, declaredMembers); |
590 return declaredMembers; | 581 return declaredMembers; |
591 } | 582 } |
592 | 583 |
593 /// Compute the members of the super type(s) of [cls]. The class members are | 584 /// Compute the members of the super type(s) of [cls]. The class members are |
594 /// stored if the [classMembers] map and the inherited interface members are | 585 /// stored if the [classMembers] map and the inherited interface members are |
595 /// returned. | 586 /// returned. |
596 /// | 587 /// |
597 /// If [name] and [names] are not null, the computation is restricted to | 588 /// If [name] and [names] are not null, the computation is restricted to |
598 /// members with these names. | 589 /// members with these names. |
599 Map<Name, Setlet<Member>> computeSuperMembers(String name, | 590 Map<Name, Setlet<Member>> computeSuperMembers( |
600 Setlet<Name> names) { | 591 String name, Setlet<Name> names) { |
601 computeSuperClassMembers(name, names); | 592 computeSuperClassMembers(name, names); |
602 return computeSuperInterfaceMembers(name, names); | 593 return computeSuperInterfaceMembers(name, names); |
603 } | 594 } |
604 | 595 |
605 Map<Name, Setlet<Member>> computeSuperInterfaceMembers(String name, | 596 Map<Name, Setlet<Member>> computeSuperInterfaceMembers( |
606 Setlet<Name> names) { | 597 String name, Setlet<Name> names) { |
607 | |
608 | |
609 InterfaceType supertype = cls.supertype; | 598 InterfaceType supertype = cls.supertype; |
610 assert(invariant(cls, supertype != null, | 599 assert(invariant(cls, supertype != null, |
611 message: "Interface members computed for $cls.")); | 600 message: "Interface members computed for $cls.")); |
612 ClassElement superclass = supertype.element; | 601 ClassElement superclass = supertype.element; |
613 | 602 |
614 Map<Name, Setlet<Member>> inheritedInterfaceMembers = | 603 Map<Name, Setlet<Member>> inheritedInterfaceMembers = |
615 new Map<Name, Setlet<Member>>(); | 604 new Map<Name, Setlet<Member>>(); |
616 | 605 |
617 void inheritInterfaceMember(InterfaceType supertype, | 606 void inheritInterfaceMember( |
618 MemberSignature member) { | 607 InterfaceType supertype, MemberSignature member) { |
619 if (shouldSkipMember(member)) return; | 608 if (shouldSkipMember(member)) return; |
620 Setlet<Member> members = | 609 Setlet<Member> members = inheritedInterfaceMembers.putIfAbsent( |
621 inheritedInterfaceMembers.putIfAbsent( | 610 member.name, () => new Setlet<Member>()); |
622 member.name, () => new Setlet<Member>()); | |
623 for (DeclaredMember declaredMember in member.declarations) { | 611 for (DeclaredMember declaredMember in member.declarations) { |
624 members.add(declaredMember.inheritFrom(supertype)); | 612 members.add(declaredMember.inheritFrom(supertype)); |
625 } | 613 } |
626 } | 614 } |
627 | 615 |
628 void inheritInterfaceMembers(InterfaceType supertype) { | 616 void inheritInterfaceMembers(InterfaceType supertype) { |
629 supertype.element.forEachInterfaceMember((MemberSignature member) { | 617 supertype.element.forEachInterfaceMember((MemberSignature member) { |
630 inheritInterfaceMember(supertype, member); | 618 inheritInterfaceMember(supertype, member); |
631 }); | 619 }); |
632 } | 620 } |
633 | 621 |
634 if (names != null) { | 622 if (names != null) { |
635 for (Name memberName in names) { | 623 for (Name memberName in names) { |
636 inheritInterfaceMember(supertype, | 624 inheritInterfaceMember( |
637 superclass.lookupInterfaceMember(memberName)); | 625 supertype, superclass.lookupInterfaceMember(memberName)); |
638 } | 626 } |
639 } else { | 627 } else { |
640 inheritInterfaceMembers(supertype); | 628 inheritInterfaceMembers(supertype); |
641 } | 629 } |
642 | 630 |
643 // Inherit interface members from superinterfaces. | 631 // Inherit interface members from superinterfaces. |
644 for (Link<DartType> link = cls.interfaces; | 632 for (Link<DartType> link = cls.interfaces; |
645 !link.isEmpty; | 633 !link.isEmpty; |
646 link = link.tail) { | 634 link = link.tail) { |
647 InterfaceType superinterface = link.head; | 635 InterfaceType superinterface = link.head; |
648 if (names != null) { | 636 if (names != null) { |
649 MembersCreator._computeClassMember( | 637 MembersCreator._computeClassMember( |
650 compiler, superinterface.element, name, names); | 638 compiler, superinterface.element, name, names); |
651 for (Name memberName in names) { | 639 for (Name memberName in names) { |
652 inheritInterfaceMember(superinterface, | 640 inheritInterfaceMember(superinterface, |
653 superinterface.element.lookupInterfaceMember(memberName)); | 641 superinterface.element.lookupInterfaceMember(memberName)); |
654 } | 642 } |
655 } else { | 643 } else { |
656 MembersCreator.computeAllClassMembers(compiler, superinterface.element); | 644 MembersCreator.computeAllClassMembers(compiler, superinterface.element); |
(...skipping 13 matching lines...) Expand all Loading... |
670 Member classMember = classMembers[name]; | 658 Member classMember = classMembers[name]; |
671 if (classMember != null) classMember = classMember.implementation; | 659 if (classMember != null) classMember = classMember.implementation; |
672 checkInterfaceMember(name, interfaceMember, classMember); | 660 checkInterfaceMember(name, interfaceMember, classMember); |
673 }); | 661 }); |
674 } | 662 } |
675 | 663 |
676 /// Compute the interface members of [cls] given the set of inherited | 664 /// Compute the interface members of [cls] given the set of inherited |
677 /// interface members [inheritedInterfaceMembers] and declared members | 665 /// interface members [inheritedInterfaceMembers] and declared members |
678 /// [declaredMembers]. The computed members are stored in [interfaceMembers]. | 666 /// [declaredMembers]. The computed members are stored in [interfaceMembers]. |
679 void computeInterfaceMembers( | 667 void computeInterfaceMembers( |
680 Map<Name, Setlet<Member>> inheritedInterfaceMembers, | 668 Map<Name, Setlet<Member>> inheritedInterfaceMembers, |
681 Map<Name, Member> declaredMembers) { | 669 Map<Name, Member> declaredMembers) { |
682 InterfaceType thisType = cls.thisType; | 670 InterfaceType thisType = cls.thisType; |
683 // Compute the interface members by overriding the inherited members with | 671 // Compute the interface members by overriding the inherited members with |
684 // a declared member or by computing a single, possibly synthesized, | 672 // a declared member or by computing a single, possibly synthesized, |
685 // inherited member. | 673 // inherited member. |
686 inheritedInterfaceMembers.forEach( | 674 inheritedInterfaceMembers |
687 (Name name, Setlet<Member> inheritedMembers) { | 675 .forEach((Name name, Setlet<Member> inheritedMembers) { |
688 Member declared = declaredMembers[name]; | 676 Member declared = declaredMembers[name]; |
689 if (declared != null) { | 677 if (declared != null) { |
690 // Check that [declaredMember] is a valid override | 678 // Check that [declaredMember] is a valid override |
691 for (Member inherited in inheritedMembers) { | 679 for (Member inherited in inheritedMembers) { |
692 checkValidOverride(declared, inherited); | 680 checkValidOverride(declared, inherited); |
693 } | 681 } |
694 if (!declared.isStatic) { | 682 if (!declared.isStatic) { |
695 interfaceMembers[name] = declared; | 683 interfaceMembers[name] = declared; |
696 } | 684 } |
697 } else if (inheritedMembers.length == 1) { | 685 } else if (inheritedMembers.length == 1) { |
698 interfaceMembers[name] = inheritedMembers.single; | 686 interfaceMembers[name] = inheritedMembers.single; |
699 } else { | 687 } else { |
700 bool someAreGetters = false; | 688 bool someAreGetters = false; |
701 bool allAreGetters = true; | 689 bool allAreGetters = true; |
702 Map<DartType, Setlet<Member>> subtypesOfAllInherited = | 690 Map<DartType, Setlet<Member>> subtypesOfAllInherited = |
703 new Map<DartType, Setlet<Member>>(); | 691 new Map<DartType, Setlet<Member>>(); |
704 outer: for (Member inherited in inheritedMembers) { | 692 outer: for (Member inherited in inheritedMembers) { |
705 if (inherited.isGetter) { | 693 if (inherited.isGetter) { |
706 someAreGetters = true; | 694 someAreGetters = true; |
707 if (!allAreGetters) break outer; | 695 if (!allAreGetters) break outer; |
708 } else { | 696 } else { |
709 allAreGetters = false; | 697 allAreGetters = false; |
710 if (someAreGetters) break outer; | 698 if (someAreGetters) break outer; |
711 } | 699 } |
712 for (MemberSignature other in inheritedMembers) { | 700 for (MemberSignature other in inheritedMembers) { |
713 if (!compiler.types.isSubtype(inherited.functionType, | 701 if (!compiler.types |
714 other.functionType)) { | 702 .isSubtype(inherited.functionType, other.functionType)) { |
715 continue outer; | 703 continue outer; |
716 } | 704 } |
717 } | 705 } |
718 subtypesOfAllInherited.putIfAbsent(inherited.functionType, | 706 subtypesOfAllInherited |
719 () => new Setlet<Member>()).add(inherited); | 707 .putIfAbsent(inherited.functionType, () => new Setlet<Member>()) |
| 708 .add(inherited); |
720 } | 709 } |
721 if (someAreGetters && !allAreGetters) { | 710 if (someAreGetters && !allAreGetters) { |
722 DiagnosticMessage warning = reporter.createMessage( | 711 DiagnosticMessage warning = reporter.createMessage( |
723 cls, | 712 cls, |
724 MessageKind.INHERIT_GETTER_AND_METHOD, | 713 MessageKind.INHERIT_GETTER_AND_METHOD, |
725 {'class': thisType, 'name': name.text }); | 714 {'class': thisType, 'name': name.text}); |
726 List<DiagnosticMessage> infos = <DiagnosticMessage>[]; | 715 List<DiagnosticMessage> infos = <DiagnosticMessage>[]; |
727 for (Member inherited in inheritedMembers) { | 716 for (Member inherited in inheritedMembers) { |
728 MessageKind kind; | 717 MessageKind kind; |
729 if (inherited.isMethod) { | 718 if (inherited.isMethod) { |
730 kind = MessageKind.INHERITED_METHOD; | 719 kind = MessageKind.INHERITED_METHOD; |
731 } else { | 720 } else { |
732 assert(invariant(cls, inherited.isGetter, | 721 assert(invariant(cls, inherited.isGetter, |
733 message: 'Conflicting member is neither a method nor a ' | 722 message: 'Conflicting member is neither a method nor a ' |
734 'getter.')); | 723 'getter.')); |
735 if (inherited.isDeclaredByField) { | 724 if (inherited.isDeclaredByField) { |
736 kind = MessageKind.INHERITED_IMPLICIT_GETTER; | 725 kind = MessageKind.INHERITED_IMPLICIT_GETTER; |
737 } else { | 726 } else { |
738 kind = MessageKind.INHERITED_EXPLICIT_GETTER; | 727 kind = MessageKind.INHERITED_EXPLICIT_GETTER; |
739 } | 728 } |
740 } | 729 } |
741 infos.add(reporter.createMessage( | 730 infos.add(reporter.createMessage(inherited.element, kind, |
742 inherited.element, | |
743 kind, | |
744 {'class': inherited.declarer, 'name': name.text})); | 731 {'class': inherited.declarer, 'name': name.text})); |
745 } | 732 } |
746 reporter.reportWarning(warning, infos); | 733 reporter.reportWarning(warning, infos); |
747 interfaceMembers[name] = new ErroneousMember(inheritedMembers); | 734 interfaceMembers[name] = new ErroneousMember(inheritedMembers); |
748 } else if (subtypesOfAllInherited.length == 1) { | 735 } else if (subtypesOfAllInherited.length == 1) { |
749 // All signatures have the same type. | 736 // All signatures have the same type. |
750 Setlet<Member> members = subtypesOfAllInherited.values.first; | 737 Setlet<Member> members = subtypesOfAllInherited.values.first; |
751 MemberSignature inherited = members.first; | 738 MemberSignature inherited = members.first; |
752 if (members.length != 1) { | 739 if (members.length != 1) { |
753 // Multiple signatures with the same type => return a | 740 // Multiple signatures with the same type => return a |
(...skipping 10 matching lines...) Expand all Loading... |
764 | 751 |
765 // Add the non-overriding instance methods to the interface members. | 752 // Add the non-overriding instance methods to the interface members. |
766 declaredMembers.forEach((Name name, Member member) { | 753 declaredMembers.forEach((Name name, Member member) { |
767 if (!member.isStatic) { | 754 if (!member.isStatic) { |
768 interfaceMembers.putIfAbsent(name, () => member); | 755 interfaceMembers.putIfAbsent(name, () => member); |
769 } | 756 } |
770 }); | 757 }); |
771 } | 758 } |
772 | 759 |
773 /// Create and inherit a synthesized member for [inheritedMembers]. | 760 /// Create and inherit a synthesized member for [inheritedMembers]. |
774 void _inheritedSynthesizedMember(Name name, | 761 void _inheritedSynthesizedMember(Name name, Setlet<Member> inheritedMembers) { |
775 Setlet<Member> inheritedMembers) { | |
776 // Multiple signatures with different types => create the synthesized | 762 // Multiple signatures with different types => create the synthesized |
777 // version. | 763 // version. |
778 int minRequiredParameters; | 764 int minRequiredParameters; |
779 int maxPositionalParameters; | 765 int maxPositionalParameters; |
780 Set<String> names = new Set<String>(); | 766 Set<String> names = new Set<String>(); |
781 for (MemberSignature member in inheritedMembers) { | 767 for (MemberSignature member in inheritedMembers) { |
782 int requiredParameters = 0; | 768 int requiredParameters = 0; |
783 int optionalParameters = 0; | 769 int optionalParameters = 0; |
784 if (member.isSetter) { | 770 if (member.isSetter) { |
785 requiredParameters = 1; | 771 requiredParameters = 1; |
786 } | 772 } |
787 if (member.type.isFunctionType) { | 773 if (member.type.isFunctionType) { |
788 FunctionType type = member.type; | 774 FunctionType type = member.type; |
789 type.namedParameters.forEach( | 775 type.namedParameters.forEach((String name) => names.add(name)); |
790 (String name) => names.add(name)); | |
791 requiredParameters = type.parameterTypes.length; | 776 requiredParameters = type.parameterTypes.length; |
792 optionalParameters = type.optionalParameterTypes.length; | 777 optionalParameters = type.optionalParameterTypes.length; |
793 } | 778 } |
794 int positionalParameters = requiredParameters + optionalParameters; | 779 int positionalParameters = requiredParameters + optionalParameters; |
795 if (minRequiredParameters == null || | 780 if (minRequiredParameters == null || |
796 minRequiredParameters > requiredParameters) { | 781 minRequiredParameters > requiredParameters) { |
797 minRequiredParameters = requiredParameters; | 782 minRequiredParameters = requiredParameters; |
798 } | 783 } |
799 if (maxPositionalParameters == null || | 784 if (maxPositionalParameters == null || |
800 maxPositionalParameters < positionalParameters) { | 785 maxPositionalParameters < positionalParameters) { |
801 maxPositionalParameters = positionalParameters; | 786 maxPositionalParameters = positionalParameters; |
802 } | 787 } |
803 } | 788 } |
804 int optionalParameters = | 789 int optionalParameters = maxPositionalParameters - minRequiredParameters; |
805 maxPositionalParameters - minRequiredParameters; | |
806 // TODO(johnniwinther): Support function types with both optional | 790 // TODO(johnniwinther): Support function types with both optional |
807 // and named parameters? | 791 // and named parameters? |
808 if (optionalParameters == 0 || names.isEmpty) { | 792 if (optionalParameters == 0 || names.isEmpty) { |
809 DartType dynamic = const DynamicType(); | 793 DartType dynamic = const DynamicType(); |
810 List<DartType> requiredParameterTypes = | 794 List<DartType> requiredParameterTypes = |
811 new List.filled(minRequiredParameters, dynamic); | 795 new List.filled(minRequiredParameters, dynamic); |
812 List<DartType> optionalParameterTypes = | 796 List<DartType> optionalParameterTypes = |
813 new List.filled(optionalParameters, dynamic); | 797 new List.filled(optionalParameters, dynamic); |
814 List<String> namedParameters = | 798 List<String> namedParameters = names.toList() |
815 names.toList()..sort((a, b) => a.compareTo(b)); | 799 ..sort((a, b) => a.compareTo(b)); |
816 List<DartType> namedParameterTypes = | 800 List<DartType> namedParameterTypes = |
817 new List.filled(namedParameters.length, dynamic); | 801 new List.filled(namedParameters.length, dynamic); |
818 FunctionType memberType = new FunctionType.synthesized( | 802 FunctionType memberType = new FunctionType.synthesized( |
819 const DynamicType(), | 803 const DynamicType(), |
820 requiredParameterTypes, | 804 requiredParameterTypes, |
821 optionalParameterTypes, | 805 optionalParameterTypes, |
822 namedParameters, namedParameterTypes); | 806 namedParameters, |
| 807 namedParameterTypes); |
823 DartType type = memberType; | 808 DartType type = memberType; |
824 if (inheritedMembers.first.isGetter || | 809 if (inheritedMembers.first.isGetter || inheritedMembers.first.isSetter) { |
825 inheritedMembers.first.isSetter) { | |
826 type = const DynamicType(); | 810 type = const DynamicType(); |
827 } | 811 } |
828 interfaceMembers[name] = | 812 interfaceMembers[name] = |
829 new SyntheticMember(inheritedMembers, type, memberType); | 813 new SyntheticMember(inheritedMembers, type, memberType); |
830 } | 814 } |
831 } | 815 } |
832 } | 816 } |
833 | 817 |
834 abstract class ClassMemberMixin implements ClassElement { | 818 abstract class ClassMemberMixin implements ClassElement { |
835 /// When [classMembers] and [interfaceMembers] have not been fully computed | 819 /// When [classMembers] and [interfaceMembers] have not been fully computed |
(...skipping 15 matching lines...) Expand all Loading... |
851 /// Creates the necessary maps and [MembersCreator] for compute members of | 835 /// Creates the necessary maps and [MembersCreator] for compute members of |
852 /// this class. | 836 /// this class. |
853 MembersCreator _prepareCreator(Compiler compiler) { | 837 MembersCreator _prepareCreator(Compiler compiler) { |
854 if (classMembers == null) { | 838 if (classMembers == null) { |
855 ensureResolved(compiler.resolution); | 839 ensureResolved(compiler.resolution); |
856 classMembers = new Map<Name, Member>(); | 840 classMembers = new Map<Name, Member>(); |
857 | 841 |
858 if (interfaceMembersAreClassMembers) { | 842 if (interfaceMembersAreClassMembers) { |
859 ClassMemberMixin superclass = this.superclass; | 843 ClassMemberMixin superclass = this.superclass; |
860 if ((superclass != null && | 844 if ((superclass != null && |
861 (!superclass.interfaceMembersAreClassMembers || | 845 (!superclass.interfaceMembersAreClassMembers || |
862 superclass.isMixinApplication)) || | 846 superclass.isMixinApplication)) || |
863 !interfaces.isEmpty) { | 847 !interfaces.isEmpty) { |
864 interfaceMembersAreClassMembers = false; | 848 interfaceMembersAreClassMembers = false; |
865 } | 849 } |
866 } | 850 } |
867 if (!interfaceMembersAreClassMembers) { | 851 if (!interfaceMembersAreClassMembers) { |
868 interfaceMembers = new Map<Name, MemberSignature>(); | 852 interfaceMembers = new Map<Name, MemberSignature>(); |
869 } | 853 } |
870 } | 854 } |
871 return interfaceMembersAreClassMembers | 855 return interfaceMembersAreClassMembers |
872 ? new ClassMembersCreator(compiler, this, | 856 ? new ClassMembersCreator( |
873 computedMemberNames, classMembers) | 857 compiler, this, computedMemberNames, classMembers) |
874 : new InterfaceMembersCreator(compiler, this, | 858 : new InterfaceMembersCreator(compiler, this, computedMemberNames, |
875 computedMemberNames, classMembers, interfaceMembers); | 859 classMembers, interfaceMembers); |
876 } | 860 } |
877 | 861 |
878 static Iterable<String> _EMPTY_MEMBERS_NAMES = const <String>[]; | 862 static Iterable<String> _EMPTY_MEMBERS_NAMES = const <String>[]; |
879 | 863 |
880 /// Compute the members by the name [name] for this class. [names] collects | 864 /// Compute the members by the name [name] for this class. [names] collects |
881 /// the set of possible variations of [name], including getter, setter and | 865 /// the set of possible variations of [name], including getter, setter and |
882 /// and private names. | 866 /// and private names. |
883 void computeClassMember(Compiler compiler, String name, Setlet<Name> names) { | 867 void computeClassMember(Compiler compiler, String name, Setlet<Name> names) { |
884 if (isMemberComputed(name)) return; | 868 if (isMemberComputed(name)) return; |
885 if (Name.isPrivateName(name)) { | 869 if (Name.isPrivateName(name)) { |
886 names..add(new Name(name, library)) | 870 names |
887 ..add(new Name(name, library, isSetter: true)); | 871 ..add(new Name(name, library)) |
| 872 ..add(new Name(name, library, isSetter: true)); |
888 } | 873 } |
889 MembersCreator creator = _prepareCreator(compiler); | 874 MembersCreator creator = _prepareCreator(compiler); |
890 creator.computeMembersByName(name, names); | 875 creator.computeMembersByName(name, names); |
891 if (computedMemberNames == null) { | 876 if (computedMemberNames == null) { |
892 computedMemberNames = _EMPTY_MEMBERS_NAMES; | 877 computedMemberNames = _EMPTY_MEMBERS_NAMES; |
893 } | 878 } |
894 if (name != Identifiers.call) { | 879 if (name != Identifiers.call) { |
895 Setlet<String> set; | 880 Setlet<String> set; |
896 if (identical(computedMemberNames, _EMPTY_MEMBERS_NAMES)) { | 881 if (identical(computedMemberNames, _EMPTY_MEMBERS_NAMES)) { |
897 computedMemberNames = set = new Setlet<String>(); | 882 computedMemberNames = set = new Setlet<String>(); |
(...skipping 13 matching lines...) Expand all Loading... |
911 } | 896 } |
912 | 897 |
913 bool areAllMembersComputed() { | 898 bool areAllMembersComputed() { |
914 return computedMemberNames == null && classMembers != null; | 899 return computedMemberNames == null && classMembers != null; |
915 } | 900 } |
916 | 901 |
917 bool isMemberComputed(String name) { | 902 bool isMemberComputed(String name) { |
918 if (computedMemberNames == null) { | 903 if (computedMemberNames == null) { |
919 return classMembers != null; | 904 return classMembers != null; |
920 } else { | 905 } else { |
921 return name == Identifiers.call || | 906 return name == Identifiers.call || computedMemberNames.contains(name); |
922 computedMemberNames.contains(name); | |
923 } | 907 } |
924 } | 908 } |
925 | 909 |
926 Member lookupClassMember(Name name) { | 910 Member lookupClassMember(Name name) { |
927 assert(invariant(this, | 911 assert(invariant(this, isMemberComputed(name.text), |
928 isMemberComputed(name.text), | |
929 message: "Member ${name} has not been computed for $this.")); | 912 message: "Member ${name} has not been computed for $this.")); |
930 return classMembers[name]; | 913 return classMembers[name]; |
931 } | 914 } |
932 | 915 |
933 void forEachClassMember(f(Member member)) { | 916 void forEachClassMember(f(Member member)) { |
934 assert(invariant(this, areAllMembersComputed(), | 917 assert(invariant(this, areAllMembersComputed(), |
935 message: "Members have not been fully computed for $this.")); | 918 message: "Members have not been fully computed for $this.")); |
936 classMembers.forEach((_, member) => f(member)); | 919 classMembers.forEach((_, member) => f(member)); |
937 } | 920 } |
938 | 921 |
(...skipping 13 matching lines...) Expand all Loading... |
952 message: "Members have not been fully computed for $this.")); | 935 message: "Members have not been fully computed for $this.")); |
953 if (interfaceMembersAreClassMembers) { | 936 if (interfaceMembersAreClassMembers) { |
954 classMembers.forEach((_, member) { | 937 classMembers.forEach((_, member) { |
955 if (!member.isStatic) f(member); | 938 if (!member.isStatic) f(member); |
956 }); | 939 }); |
957 } else { | 940 } else { |
958 interfaceMembers.forEach((_, member) => f(member)); | 941 interfaceMembers.forEach((_, member) => f(member)); |
959 } | 942 } |
960 } | 943 } |
961 } | 944 } |
OLD | NEW |