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

Side by Side Diff: pkg/compiler/lib/src/resolution/resolution.dart

Issue 1859343004: dartfmt pkg/compiler (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 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) 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; 5 library dart2js.resolution;
6 6
7 import 'dart:collection' show Queue; 7 import 'dart:collection' show Queue;
8 8
9 import '../common.dart'; 9 import '../common.dart';
10 import '../common/names.dart' show 10 import '../common/names.dart' show Identifiers;
11 Identifiers; 11 import '../common/resolution.dart'
12 import '../common/resolution.dart' show 12 show Feature, Parsing, Resolution, ResolutionImpact;
13 Feature, 13 import '../common/tasks.dart' show CompilerTask, DeferredAction;
14 Parsing, 14 import '../compiler.dart' show Compiler;
15 Resolution, 15 import '../compile_time_constants.dart' show ConstantCompiler;
16 ResolutionImpact; 16 import '../constants/expressions.dart'
17 import '../common/tasks.dart' show 17 show
18 CompilerTask, 18 ConstantExpression,
19 DeferredAction; 19 ConstantExpressionKind,
20 import '../compiler.dart' show 20 ConstructedConstantExpression,
21 Compiler; 21 ErroneousConstantExpression;
22 import '../compile_time_constants.dart' show 22 import '../constants/values.dart' show ConstantValue;
23 ConstantCompiler; 23 import '../core_types.dart' show CoreClasses, CoreTypes;
24 import '../constants/expressions.dart' show
25 ConstantExpression,
26 ConstantExpressionKind,
27 ConstructedConstantExpression,
28 ErroneousConstantExpression;
29 import '../constants/values.dart' show
30 ConstantValue;
31 import '../core_types.dart' show
32 CoreClasses,
33 CoreTypes;
34 import '../dart_types.dart'; 24 import '../dart_types.dart';
35 import '../elements/elements.dart'; 25 import '../elements/elements.dart';
36 import '../elements/modelx.dart' show 26 import '../elements/modelx.dart'
37 BaseClassElementX, 27 show
38 BaseFunctionElementX, 28 BaseClassElementX,
39 ConstructorElementX, 29 BaseFunctionElementX,
40 FieldElementX, 30 ConstructorElementX,
41 FunctionElementX, 31 FieldElementX,
42 GetterElementX, 32 FunctionElementX,
43 MetadataAnnotationX, 33 GetterElementX,
44 MixinApplicationElementX, 34 MetadataAnnotationX,
45 ParameterMetadataAnnotation, 35 MixinApplicationElementX,
46 SetterElementX, 36 ParameterMetadataAnnotation,
47 TypedefElementX; 37 SetterElementX,
48 import '../tokens/token.dart' show 38 TypedefElementX;
49 isBinaryOperator, 39 import '../tokens/token.dart'
50 isMinusOperator, 40 show
51 isTernaryOperator, 41 isBinaryOperator,
52 isUnaryOperator, 42 isMinusOperator,
53 isUserDefinableOperator; 43 isTernaryOperator,
44 isUnaryOperator,
45 isUserDefinableOperator;
54 import '../tree/tree.dart'; 46 import '../tree/tree.dart';
55 import '../universe/call_structure.dart' show 47 import '../universe/call_structure.dart' show CallStructure;
56 CallStructure; 48 import '../universe/use.dart' show StaticUse, TypeUse;
57 import '../universe/use.dart' show 49 import '../universe/world_impact.dart' show WorldImpact;
58 StaticUse, 50 import '../util/util.dart' show Link, LinkBuilder, Setlet;
59 TypeUse;
60 import '../universe/world_impact.dart' show
61 WorldImpact;
62 import '../util/util.dart' show
63 Link,
64 LinkBuilder,
65 Setlet;
66 51
67 import 'class_hierarchy.dart'; 52 import 'class_hierarchy.dart';
68 import 'class_members.dart' show MembersCreator; 53 import 'class_members.dart' show MembersCreator;
69 import 'constructors.dart'; 54 import 'constructors.dart';
70 import 'members.dart'; 55 import 'members.dart';
71 import 'registry.dart'; 56 import 'registry.dart';
72 import 'signatures.dart'; 57 import 'signatures.dart';
73 import 'tree_elements.dart'; 58 import 'tree_elements.dart';
74 import 'typedefs.dart'; 59 import 'typedefs.dart';
75 60
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 return processMetadata(const ResolutionImpact()); 106 return processMetadata(const ResolutionImpact());
122 } else if (element.isTypedef) { 107 } else if (element.isTypedef) {
123 TypedefElement typdef = element; 108 TypedefElement typdef = element;
124 return processMetadata(resolveTypedef(typdef)); 109 return processMetadata(resolveTypedef(typdef));
125 } 110 }
126 111
127 compiler.unimplemented(element, "resolve($element)"); 112 compiler.unimplemented(element, "resolve($element)");
128 }); 113 });
129 } 114 }
130 115
131 void resolveRedirectingConstructor(InitializerResolver resolver, 116 void resolveRedirectingConstructor(InitializerResolver resolver, Node node,
132 Node node, 117 FunctionElement constructor, FunctionElement redirection) {
133 FunctionElement constructor,
134 FunctionElement redirection) {
135 assert(invariant(node, constructor.isImplementation, 118 assert(invariant(node, constructor.isImplementation,
136 message: 'Redirecting constructors must be resolved on implementation ' 119 message: 'Redirecting constructors must be resolved on implementation '
137 'elements.')); 120 'elements.'));
138 Setlet<FunctionElement> seen = new Setlet<FunctionElement>(); 121 Setlet<FunctionElement> seen = new Setlet<FunctionElement>();
139 seen.add(constructor); 122 seen.add(constructor);
140 while (redirection != null) { 123 while (redirection != null) {
141 // Ensure that we follow redirections through implementation elements. 124 // Ensure that we follow redirections through implementation elements.
142 redirection = redirection.implementation; 125 redirection = redirection.implementation;
143 if (redirection.isError) { 126 if (redirection.isError) {
144 break; 127 break;
145 } 128 }
146 if (seen.contains(redirection)) { 129 if (seen.contains(redirection)) {
147 reporter.reportErrorMessage( 130 reporter.reportErrorMessage(
148 node, MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE); 131 node, MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE);
149 return; 132 return;
150 } 133 }
151 seen.add(redirection); 134 seen.add(redirection);
152 redirection = resolver.visitor.resolveConstructorRedirection(redirection); 135 redirection = resolver.visitor.resolveConstructorRedirection(redirection);
153 } 136 }
154 } 137 }
155 138
156 static void processAsyncMarker(Compiler compiler, 139 static void processAsyncMarker(Compiler compiler,
157 BaseFunctionElementX element, 140 BaseFunctionElementX element, ResolutionRegistry registry) {
158 ResolutionRegistry registry) {
159 DiagnosticReporter reporter = compiler.reporter; 141 DiagnosticReporter reporter = compiler.reporter;
160 Resolution resolution = compiler.resolution; 142 Resolution resolution = compiler.resolution;
161 CoreClasses coreClasses = compiler.coreClasses; 143 CoreClasses coreClasses = compiler.coreClasses;
162 FunctionExpression functionExpression = element.node; 144 FunctionExpression functionExpression = element.node;
163 AsyncModifier asyncModifier = functionExpression.asyncModifier; 145 AsyncModifier asyncModifier = functionExpression.asyncModifier;
164 if (asyncModifier != null) { 146 if (asyncModifier != null) {
165
166 if (asyncModifier.isAsynchronous) { 147 if (asyncModifier.isAsynchronous) {
167 element.asyncMarker = asyncModifier.isYielding 148 element.asyncMarker = asyncModifier.isYielding
168 ? AsyncMarker.ASYNC_STAR : AsyncMarker.ASYNC; 149 ? AsyncMarker.ASYNC_STAR
150 : AsyncMarker.ASYNC;
169 } else { 151 } else {
170 element.asyncMarker = AsyncMarker.SYNC_STAR; 152 element.asyncMarker = AsyncMarker.SYNC_STAR;
171 } 153 }
172 if (element.isAbstract) { 154 if (element.isAbstract) {
173 reporter.reportErrorMessage( 155 reporter.reportErrorMessage(
174 asyncModifier, 156 asyncModifier,
175 MessageKind.ASYNC_MODIFIER_ON_ABSTRACT_METHOD, 157 MessageKind.ASYNC_MODIFIER_ON_ABSTRACT_METHOD,
176 {'modifier': element.asyncMarker}); 158 {'modifier': element.asyncMarker});
177 } else if (element.isConstructor) { 159 } else if (element.isConstructor) {
178 reporter.reportErrorMessage( 160 reporter.reportErrorMessage(
179 asyncModifier, 161 asyncModifier,
180 MessageKind.ASYNC_MODIFIER_ON_CONSTRUCTOR, 162 MessageKind.ASYNC_MODIFIER_ON_CONSTRUCTOR,
181 {'modifier': element.asyncMarker}); 163 {'modifier': element.asyncMarker});
182 } else { 164 } else {
183 if (element.isSetter) { 165 if (element.isSetter) {
184 reporter.reportErrorMessage( 166 reporter.reportErrorMessage(
185 asyncModifier, 167 asyncModifier,
186 MessageKind.ASYNC_MODIFIER_ON_SETTER, 168 MessageKind.ASYNC_MODIFIER_ON_SETTER,
187 {'modifier': element.asyncMarker}); 169 {'modifier': element.asyncMarker});
188
189 } 170 }
190 if (functionExpression.body.asReturn() != null && 171 if (functionExpression.body.asReturn() != null &&
191 element.asyncMarker.isYielding) { 172 element.asyncMarker.isYielding) {
192 reporter.reportErrorMessage( 173 reporter.reportErrorMessage(
193 asyncModifier, 174 asyncModifier,
194 MessageKind.YIELDING_MODIFIER_ON_ARROW_BODY, 175 MessageKind.YIELDING_MODIFIER_ON_ARROW_BODY,
195 {'modifier': element.asyncMarker}); 176 {'modifier': element.asyncMarker});
196 } 177 }
197 } 178 }
198 switch (element.asyncMarker) { 179 switch (element.asyncMarker) {
199 case AsyncMarker.ASYNC: 180 case AsyncMarker.ASYNC:
200 registry.registerFeature(Feature.ASYNC); 181 registry.registerFeature(Feature.ASYNC);
201 coreClasses.futureClass.ensureResolved(resolution); 182 coreClasses.futureClass.ensureResolved(resolution);
202 break; 183 break;
203 case AsyncMarker.ASYNC_STAR: 184 case AsyncMarker.ASYNC_STAR:
204 registry.registerFeature(Feature.ASYNC_STAR); 185 registry.registerFeature(Feature.ASYNC_STAR);
205 coreClasses.streamClass.ensureResolved(resolution); 186 coreClasses.streamClass.ensureResolved(resolution);
206 break; 187 break;
207 case AsyncMarker.SYNC_STAR: 188 case AsyncMarker.SYNC_STAR:
208 registry.registerFeature(Feature.SYNC_STAR); 189 registry.registerFeature(Feature.SYNC_STAR);
209 coreClasses.iterableClass.ensureResolved(resolution); 190 coreClasses.iterableClass.ensureResolved(resolution);
210 break; 191 break;
211 } 192 }
212 } 193 }
213 } 194 }
214 195
215 bool _isNativeClassOrExtendsNativeClass(ClassElement classElement) { 196 bool _isNativeClassOrExtendsNativeClass(ClassElement classElement) {
216 assert(classElement != null); 197 assert(classElement != null);
217 while (classElement != null) { 198 while (classElement != null) {
218 if (compiler.backend.isNative(classElement)) return true; 199 if (compiler.backend.isNative(classElement)) return true;
219 classElement = classElement.superclass; 200 classElement = classElement.superclass;
220 } 201 }
221 return false; 202 return false;
222 } 203 }
223 204
224 WorldImpact resolveMethodElementImplementation( 205 WorldImpact resolveMethodElementImplementation(
225 FunctionElement element, FunctionExpression tree) { 206 FunctionElement element, FunctionExpression tree) {
226 return reporter.withCurrentElement(element, () { 207 return reporter.withCurrentElement(element, () {
227 if (element.isExternal && tree.hasBody) { 208 if (element.isExternal && tree.hasBody) {
228 reporter.reportErrorMessage( 209 reporter.reportErrorMessage(element, MessageKind.EXTERNAL_WITH_BODY,
229 element,
230 MessageKind.EXTERNAL_WITH_BODY,
231 {'functionName': element.name}); 210 {'functionName': element.name});
232 } 211 }
233 if (element.isConstructor) { 212 if (element.isConstructor) {
234 if (tree.returnType != null) { 213 if (tree.returnType != null) {
235 reporter.reportErrorMessage( 214 reporter.reportErrorMessage(
236 tree, MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE); 215 tree, MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE);
237 } 216 }
238 if (tree.hasBody && element.isConst) { 217 if (tree.hasBody && element.isConst) {
239 if (element.isGenerativeConstructor) { 218 if (element.isGenerativeConstructor) {
240 reporter.reportErrorMessage( 219 reporter.reportErrorMessage(
241 tree, MessageKind.CONST_CONSTRUCTOR_WITH_BODY); 220 tree, MessageKind.CONST_CONSTRUCTOR_WITH_BODY);
242 } else if (!tree.isRedirectingFactory) { 221 } else if (!tree.isRedirectingFactory) {
243 reporter.reportErrorMessage( 222 reporter.reportErrorMessage(tree, MessageKind.CONST_FACTORY);
244 tree, MessageKind.CONST_FACTORY);
245 } 223 }
246 } 224 }
247 } 225 }
248 226
249 ResolverVisitor visitor = visitorFor(element); 227 ResolverVisitor visitor = visitorFor(element);
250 ResolutionRegistry registry = visitor.registry; 228 ResolutionRegistry registry = visitor.registry;
251 registry.defineFunction(tree, element); 229 registry.defineFunction(tree, element);
252 visitor.setupFunction(tree, element); 230 visitor.setupFunction(tree, element);
253 processAsyncMarker(compiler, element, registry); 231 processAsyncMarker(compiler, element, registry);
254 232
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 for (MixinApplicationElement mixinApplication in mixinUses) { 266 for (MixinApplicationElement mixinApplication in mixinUses) {
289 checkMixinSuperUses(resolutionTree, mixinApplication, mixin); 267 checkMixinSuperUses(resolutionTree, mixinApplication, mixin);
290 } 268 }
291 } 269 }
292 270
293 // TODO(9631): support noSuchMethod on native classes. 271 // TODO(9631): support noSuchMethod on native classes.
294 if (element.isFunction && 272 if (element.isFunction &&
295 element.isInstanceMember && 273 element.isInstanceMember &&
296 element.name == Identifiers.noSuchMethod_ && 274 element.name == Identifiers.noSuchMethod_ &&
297 _isNativeClassOrExtendsNativeClass(enclosingClass)) { 275 _isNativeClassOrExtendsNativeClass(enclosingClass)) {
298 reporter.reportErrorMessage( 276 reporter.reportErrorMessage(tree, MessageKind.NO_SUCH_METHOD_IN_NATIVE);
299 tree, MessageKind.NO_SUCH_METHOD_IN_NATIVE);
300 } 277 }
301 278
302 return registry.worldImpact; 279 return registry.worldImpact;
303 }); 280 });
304
305 } 281 }
306 282
307 WorldImpact resolveMethodElement(FunctionElementX element) { 283 WorldImpact resolveMethodElement(FunctionElementX element) {
308 assert(invariant(element, element.isDeclaration)); 284 assert(invariant(element, element.isDeclaration));
309 return reporter.withCurrentElement(element, () { 285 return reporter.withCurrentElement(element, () {
310 if (compiler.enqueuer.resolution.hasBeenProcessed(element)) { 286 if (compiler.enqueuer.resolution.hasBeenProcessed(element)) {
311 // TODO(karlklose): Remove the check for [isConstructor]. [elememts] 287 // TODO(karlklose): Remove the check for [isConstructor]. [elememts]
312 // should never be non-null, not even for constructors. 288 // should never be non-null, not even for constructors.
313 assert(invariant(element, element.isConstructor, 289 assert(invariant(element, element.isConstructor,
314 message: 'Non-constructor element $element ' 290 message: 'Non-constructor element $element '
315 'has already been analyzed.')); 291 'has already been analyzed.'));
316 return const ResolutionImpact(); 292 return const ResolutionImpact();
317 } 293 }
318 if (element.isSynthesized) { 294 if (element.isSynthesized) {
319 if (element.isGenerativeConstructor) { 295 if (element.isGenerativeConstructor) {
320 ResolutionRegistry registry = 296 ResolutionRegistry registry =
321 new ResolutionRegistry(compiler, _ensureTreeElements(element)); 297 new ResolutionRegistry(compiler, _ensureTreeElements(element));
322 ConstructorElement constructor = element.asFunctionElement(); 298 ConstructorElement constructor = element.asFunctionElement();
323 ConstructorElement target = constructor.definingConstructor; 299 ConstructorElement target = constructor.definingConstructor;
324 // Ensure the signature of the synthesized element is 300 // Ensure the signature of the synthesized element is
325 // resolved. This is the only place where the resolver is 301 // resolved. This is the only place where the resolver is
326 // seeing this element. 302 // seeing this element.
327 element.computeType(resolution); 303 element.computeType(resolution);
328 if (!target.isMalformed) { 304 if (!target.isMalformed) {
329 registry.registerStaticUse( 305 registry.registerStaticUse(new StaticUse.superConstructorInvoke(
330 new StaticUse.superConstructorInvoke( 306 target, CallStructure.NO_ARGS));
331 target, CallStructure.NO_ARGS));
332 } 307 }
333 return registry.worldImpact; 308 return registry.worldImpact;
334 } else { 309 } else {
335 assert(element.isDeferredLoaderGetter || element.isMalformed); 310 assert(element.isDeferredLoaderGetter || element.isMalformed);
336 _ensureTreeElements(element); 311 _ensureTreeElements(element);
337 return const ResolutionImpact(); 312 return const ResolutionImpact();
338 } 313 }
339 } else { 314 } else {
340 element.parseNode(resolution.parsing); 315 element.parseNode(resolution.parsing);
341 element.computeType(resolution); 316 element.computeType(resolution);
(...skipping 14 matching lines...) Expand all
356 /// This method should only be used by this library (or tests of 331 /// This method should only be used by this library (or tests of
357 /// this library). 332 /// this library).
358 ResolverVisitor visitorFor(Element element, {bool useEnclosingScope: false}) { 333 ResolverVisitor visitorFor(Element element, {bool useEnclosingScope: false}) {
359 return new ResolverVisitor(compiler, element, 334 return new ResolverVisitor(compiler, element,
360 new ResolutionRegistry(compiler, _ensureTreeElements(element)), 335 new ResolutionRegistry(compiler, _ensureTreeElements(element)),
361 useEnclosingScope: useEnclosingScope); 336 useEnclosingScope: useEnclosingScope);
362 } 337 }
363 338
364 WorldImpact resolveField(FieldElementX element) { 339 WorldImpact resolveField(FieldElementX element) {
365 VariableDefinitions tree = element.parseNode(parsing); 340 VariableDefinitions tree = element.parseNode(parsing);
366 if(element.modifiers.isStatic && element.isTopLevel) { 341 if (element.modifiers.isStatic && element.isTopLevel) {
367 reporter.reportErrorMessage( 342 reporter.reportErrorMessage(element.modifiers.getStatic(),
368 element.modifiers.getStatic(),
369 MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC); 343 MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC);
370 } 344 }
371 ResolverVisitor visitor = visitorFor(element); 345 ResolverVisitor visitor = visitorFor(element);
372 ResolutionRegistry registry = visitor.registry; 346 ResolutionRegistry registry = visitor.registry;
373 // TODO(johnniwinther): Maybe remove this when placeholderCollector migrates 347 // TODO(johnniwinther): Maybe remove this when placeholderCollector migrates
374 // to the backend ast. 348 // to the backend ast.
375 registry.defineElement(tree.definitions.nodes.head, element); 349 registry.defineElement(tree.definitions.nodes.head, element);
376 // TODO(johnniwinther): Share the resolved type between all variables 350 // TODO(johnniwinther): Share the resolved type between all variables
377 // declared in the same declaration. 351 // declared in the same declaration.
378 if (tree.type != null) { 352 if (tree.type != null) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 391
418 // Perform various checks as side effect of "computing" the type. 392 // Perform various checks as side effect of "computing" the type.
419 element.computeType(resolution); 393 element.computeType(resolution);
420 394
421 return registry.worldImpact; 395 return registry.worldImpact;
422 } 396 }
423 397
424 DartType resolveTypeAnnotation(Element element, TypeAnnotation annotation) { 398 DartType resolveTypeAnnotation(Element element, TypeAnnotation annotation) {
425 DartType type = resolveReturnType(element, annotation); 399 DartType type = resolveReturnType(element, annotation);
426 if (type.isVoid) { 400 if (type.isVoid) {
427 reporter.reportErrorMessage( 401 reporter.reportErrorMessage(annotation, MessageKind.VOID_NOT_ALLOWED);
428 annotation, MessageKind.VOID_NOT_ALLOWED);
429 } 402 }
430 return type; 403 return type;
431 } 404 }
432 405
433 DartType resolveReturnType(Element element, TypeAnnotation annotation) { 406 DartType resolveReturnType(Element element, TypeAnnotation annotation) {
434 if (annotation == null) return const DynamicType(); 407 if (annotation == null) return const DynamicType();
435 DartType result = visitorFor(element).resolveTypeAnnotation(annotation); 408 DartType result = visitorFor(element).resolveTypeAnnotation(annotation);
436 if (result == null) { 409 if (result == null) {
437 // TODO(karklose): warning. 410 // TODO(karklose): warning.
438 return const DynamicType(); 411 return const DynamicType();
439 } 412 }
440 return result; 413 return result;
441 } 414 }
442 415
443 void resolveRedirectionChain(ConstructorElementX constructor, 416 void resolveRedirectionChain(
444 Spannable node) { 417 ConstructorElementX constructor, Spannable node) {
445 ConstructorElementX target = constructor; 418 ConstructorElementX target = constructor;
446 InterfaceType targetType; 419 InterfaceType targetType;
447 List<Element> seen = new List<Element>(); 420 List<Element> seen = new List<Element>();
448 bool isMalformed = false; 421 bool isMalformed = false;
449 // Follow the chain of redirections and check for cycles. 422 // Follow the chain of redirections and check for cycles.
450 while (target.isRedirectingFactory || target.isPatched) { 423 while (target.isRedirectingFactory || target.isPatched) {
451 if (target.effectiveTargetInternal != null) { 424 if (target.effectiveTargetInternal != null) {
452 // We found a constructor that already has been processed. 425 // We found a constructor that already has been processed.
453 targetType = target.effectiveTargetType; 426 targetType = target.effectiveTargetType;
454 assert(invariant(target, targetType != null, 427 assert(invariant(target, targetType != null,
455 message: 'Redirection target type has not been computed for ' 428 message: 'Redirection target type has not been computed for '
456 '$target')); 429 '$target'));
457 target = target.effectiveTargetInternal; 430 target = target.effectiveTargetInternal;
458 break; 431 break;
459 } 432 }
460 433
461 Element nextTarget; 434 Element nextTarget;
462 if (target.isPatched) { 435 if (target.isPatched) {
463 nextTarget = target.patch; 436 nextTarget = target.patch;
464 } else { 437 } else {
465 nextTarget = target.immediateRedirectionTarget; 438 nextTarget = target.immediateRedirectionTarget;
466 } 439 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
514 * Load and resolve the supertypes of [cls]. 487 * Load and resolve the supertypes of [cls].
515 * 488 *
516 * Warning: do not call this method directly. It should only be 489 * Warning: do not call this method directly. It should only be
517 * called by [resolveClass] and [ClassSupertypeResolver]. 490 * called by [resolveClass] and [ClassSupertypeResolver].
518 */ 491 */
519 void loadSupertypes(BaseClassElementX cls, Spannable from) { 492 void loadSupertypes(BaseClassElementX cls, Spannable from) {
520 measure(() { 493 measure(() {
521 if (cls.supertypeLoadState == STATE_DONE) return; 494 if (cls.supertypeLoadState == STATE_DONE) return;
522 if (cls.supertypeLoadState == STATE_STARTED) { 495 if (cls.supertypeLoadState == STATE_STARTED) {
523 reporter.reportErrorMessage( 496 reporter.reportErrorMessage(
524 from, 497 from, MessageKind.CYCLIC_CLASS_HIERARCHY, {'className': cls.name});
525 MessageKind.CYCLIC_CLASS_HIERARCHY,
526 {'className': cls.name});
527 cls.supertypeLoadState = STATE_DONE; 498 cls.supertypeLoadState = STATE_DONE;
528 cls.hasIncompleteHierarchy = true; 499 cls.hasIncompleteHierarchy = true;
529 cls.allSupertypesAndSelf = 500 cls.allSupertypesAndSelf = coreClasses.objectClass.allSupertypesAndSelf
530 coreClasses.objectClass.allSupertypesAndSelf.extendClass( 501 .extendClass(cls.computeType(resolution));
531 cls.computeType(resolution));
532 cls.supertype = cls.allSupertypes.head; 502 cls.supertype = cls.allSupertypes.head;
533 assert(invariant(from, cls.supertype != null, 503 assert(invariant(from, cls.supertype != null,
534 message: 'Missing supertype on cyclic class $cls.')); 504 message: 'Missing supertype on cyclic class $cls.'));
535 cls.interfaces = const Link<DartType>(); 505 cls.interfaces = const Link<DartType>();
536 return; 506 return;
537 } 507 }
538 cls.supertypeLoadState = STATE_STARTED; 508 cls.supertypeLoadState = STATE_STARTED;
539 reporter.withCurrentElement(cls, () { 509 reporter.withCurrentElement(cls, () {
540 // TODO(ahe): Cache the node in cls. 510 // TODO(ahe): Cache the node in cls.
541 cls.parseNode(parsing).accept( 511 cls
542 new ClassSupertypeResolver(compiler, cls)); 512 .parseNode(parsing)
513 .accept(new ClassSupertypeResolver(compiler, cls));
543 if (cls.supertypeLoadState != STATE_DONE) { 514 if (cls.supertypeLoadState != STATE_DONE) {
544 cls.supertypeLoadState = STATE_DONE; 515 cls.supertypeLoadState = STATE_DONE;
545 } 516 }
546 }); 517 });
547 }); 518 });
548 } 519 }
549 520
550 // TODO(johnniwinther): Remove this queue when resolution has been split into 521 // TODO(johnniwinther): Remove this queue when resolution has been split into
551 // syntax and semantic resolution. 522 // syntax and semantic resolution.
552 TypeDeclarationElement currentlyResolvedTypeDeclaration; 523 TypeDeclarationElement currentlyResolvedTypeDeclaration;
553 Queue<ClassElement> pendingClassesToBeResolved = new Queue<ClassElement>(); 524 Queue<ClassElement> pendingClassesToBeResolved = new Queue<ClassElement>();
554 Queue<ClassElement> pendingClassesToBePostProcessed = 525 Queue<ClassElement> pendingClassesToBePostProcessed =
555 new Queue<ClassElement>(); 526 new Queue<ClassElement>();
556 527
557 /// Resolve [element] using [resolveTypeDeclaration]. 528 /// Resolve [element] using [resolveTypeDeclaration].
558 /// 529 ///
559 /// This methods ensure that class declarations encountered through type 530 /// This methods ensure that class declarations encountered through type
560 /// annotations during the resolution of [element] are resolved after 531 /// annotations during the resolution of [element] are resolved after
561 /// [element] has been resolved. 532 /// [element] has been resolved.
562 // TODO(johnniwinther): Encapsulate this functionality in a 533 // TODO(johnniwinther): Encapsulate this functionality in a
563 // 'TypeDeclarationResolver'. 534 // 'TypeDeclarationResolver'.
564 _resolveTypeDeclaration(TypeDeclarationElement element, 535 _resolveTypeDeclaration(
565 resolveTypeDeclaration()) { 536 TypeDeclarationElement element, resolveTypeDeclaration()) {
566 return reporter.withCurrentElement(element, () { 537 return reporter.withCurrentElement(element, () {
567 return measure(() { 538 return measure(() {
568 TypeDeclarationElement previousResolvedTypeDeclaration = 539 TypeDeclarationElement previousResolvedTypeDeclaration =
569 currentlyResolvedTypeDeclaration; 540 currentlyResolvedTypeDeclaration;
570 currentlyResolvedTypeDeclaration = element; 541 currentlyResolvedTypeDeclaration = element;
571 var result = resolveTypeDeclaration(); 542 var result = resolveTypeDeclaration();
572 if (previousResolvedTypeDeclaration == null) { 543 if (previousResolvedTypeDeclaration == null) {
573 do { 544 do {
574 while (!pendingClassesToBeResolved.isEmpty) { 545 while (!pendingClassesToBeResolved.isEmpty) {
575 pendingClassesToBeResolved.removeFirst() 546 pendingClassesToBeResolved
547 .removeFirst()
576 .ensureResolved(resolution); 548 .ensureResolved(resolution);
577 } 549 }
578 while (!pendingClassesToBePostProcessed.isEmpty) { 550 while (!pendingClassesToBePostProcessed.isEmpty) {
579 _postProcessClassElement( 551 _postProcessClassElement(
580 pendingClassesToBePostProcessed.removeFirst()); 552 pendingClassesToBePostProcessed.removeFirst());
581 } 553 }
582 } while (!pendingClassesToBeResolved.isEmpty); 554 } while (!pendingClassesToBeResolved.isEmpty);
583 assert(pendingClassesToBeResolved.isEmpty); 555 assert(pendingClassesToBeResolved.isEmpty);
584 assert(pendingClassesToBePostProcessed.isEmpty); 556 assert(pendingClassesToBePostProcessed.isEmpty);
585 } 557 }
(...skipping 25 matching lines...) Expand all
611 } 583 }
612 584
613 void ensureClassWillBeResolvedInternal(ClassElement element) { 585 void ensureClassWillBeResolvedInternal(ClassElement element) {
614 if (currentlyResolvedTypeDeclaration == null) { 586 if (currentlyResolvedTypeDeclaration == null) {
615 element.ensureResolved(resolution); 587 element.ensureResolved(resolution);
616 } else { 588 } else {
617 pendingClassesToBeResolved.add(element); 589 pendingClassesToBeResolved.add(element);
618 } 590 }
619 } 591 }
620 592
621 void resolveClassInternal(BaseClassElementX element, 593 void resolveClassInternal(
622 ResolutionRegistry registry) { 594 BaseClassElementX element, ResolutionRegistry registry) {
623 if (!element.isPatch) { 595 if (!element.isPatch) {
624 reporter.withCurrentElement(element, () => measure(() { 596 reporter.withCurrentElement(
625 assert(element.resolutionState == STATE_NOT_STARTED); 597 element,
626 element.resolutionState = STATE_STARTED; 598 () => measure(() {
627 Node tree = element.parseNode(parsing); 599 assert(element.resolutionState == STATE_NOT_STARTED);
628 loadSupertypes(element, tree); 600 element.resolutionState = STATE_STARTED;
601 Node tree = element.parseNode(parsing);
602 loadSupertypes(element, tree);
629 603
630 ClassResolverVisitor visitor = 604 ClassResolverVisitor visitor =
631 new ClassResolverVisitor(compiler, element, registry); 605 new ClassResolverVisitor(compiler, element, registry);
632 visitor.visit(tree); 606 visitor.visit(tree);
633 element.resolutionState = STATE_DONE; 607 element.resolutionState = STATE_DONE;
634 compiler.onClassResolved(element); 608 compiler.onClassResolved(element);
635 pendingClassesToBePostProcessed.add(element); 609 pendingClassesToBePostProcessed.add(element);
636 })); 610 }));
637 if (element.isPatched) { 611 if (element.isPatched) {
638 // Ensure handling patch after origin. 612 // Ensure handling patch after origin.
639 element.patch.ensureResolved(resolution); 613 element.patch.ensureResolved(resolution);
640 } 614 }
641 } else { // Handle patch classes: 615 } else {
616 // Handle patch classes:
642 element.resolutionState = STATE_STARTED; 617 element.resolutionState = STATE_STARTED;
643 // Ensure handling origin before patch. 618 // Ensure handling origin before patch.
644 element.origin.ensureResolved(resolution); 619 element.origin.ensureResolved(resolution);
645 // Ensure that the type is computed. 620 // Ensure that the type is computed.
646 element.computeType(resolution); 621 element.computeType(resolution);
647 // Copy class hierarchy from origin. 622 // Copy class hierarchy from origin.
648 element.supertype = element.origin.supertype; 623 element.supertype = element.origin.supertype;
649 element.interfaces = element.origin.interfaces; 624 element.interfaces = element.origin.interfaces;
650 element.allSupertypesAndSelf = element.origin.allSupertypesAndSelf; 625 element.allSupertypesAndSelf = element.origin.allSupertypesAndSelf;
651 // Stepwise assignment to ensure invariant. 626 // Stepwise assignment to ensure invariant.
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
715 690
716 // In case of cyclic mixin applications, the mixin chain will have 691 // In case of cyclic mixin applications, the mixin chain will have
717 // been cut. If so, we have already reported the error to the 692 // been cut. If so, we have already reported the error to the
718 // user so we just return from here. 693 // user so we just return from here.
719 ClassElement mixin = mixinApplication.mixin; 694 ClassElement mixin = mixinApplication.mixin;
720 if (mixin == null) return; 695 if (mixin == null) return;
721 696
722 // Check that we're not trying to use Object as a mixin. 697 // Check that we're not trying to use Object as a mixin.
723 if (mixin.superclass == null) { 698 if (mixin.superclass == null) {
724 reporter.reportErrorMessage( 699 reporter.reportErrorMessage(
725 mixinApplication, 700 mixinApplication, MessageKind.ILLEGAL_MIXIN_OBJECT);
726 MessageKind.ILLEGAL_MIXIN_OBJECT);
727 // Avoid reporting additional errors for the Object class. 701 // Avoid reporting additional errors for the Object class.
728 return; 702 return;
729 } 703 }
730 704
731 if (mixin.isEnumClass) { 705 if (mixin.isEnumClass) {
732 // Mixing in an enum has already caused a compile-time error. 706 // Mixing in an enum has already caused a compile-time error.
733 return; 707 return;
734 } 708 }
735 709
736 // Check that the mixed in class has Object as its superclass. 710 // Check that the mixed in class has Object as its superclass.
737 if (!mixin.superclass.isObject) { 711 if (!mixin.superclass.isObject) {
738 reporter.reportErrorMessage( 712 reporter.reportErrorMessage(mixin, MessageKind.ILLEGAL_MIXIN_SUPERCLASS);
739 mixin, MessageKind.ILLEGAL_MIXIN_SUPERCLASS);
740 } 713 }
741 714
742 // Check that the mixed in class doesn't have any constructors and 715 // Check that the mixed in class doesn't have any constructors and
743 // make sure we aren't mixing in methods that use 'super'. 716 // make sure we aren't mixing in methods that use 'super'.
744 mixin.forEachLocalMember((AstElement member) { 717 mixin.forEachLocalMember((AstElement member) {
745 if (member.isGenerativeConstructor && !member.isSynthesized) { 718 if (member.isGenerativeConstructor && !member.isSynthesized) {
746 reporter.reportErrorMessage( 719 reporter.reportErrorMessage(
747 member, MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR); 720 member, MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR);
748 } else { 721 } else {
749 // Get the resolution tree and check that the resolved member 722 // Get the resolution tree and check that the resolved member
750 // doesn't use 'super'. This is the part of the 'super' mixin 723 // doesn't use 'super'. This is the part of the 'super' mixin
751 // check that happens when a function is resolved before the 724 // check that happens when a function is resolved before the
752 // mixin application has been performed. 725 // mixin application has been performed.
753 // TODO(johnniwinther): Obtain the [TreeElements] for [member] 726 // TODO(johnniwinther): Obtain the [TreeElements] for [member]
754 // differently. 727 // differently.
755 if (compiler.enqueuer.resolution.hasBeenProcessed(member)) { 728 if (compiler.enqueuer.resolution.hasBeenProcessed(member)) {
756 checkMixinSuperUses( 729 checkMixinSuperUses(
757 member.resolvedAst.elements, 730 member.resolvedAst.elements, mixinApplication, mixin);
758 mixinApplication,
759 mixin);
760 } 731 }
761 } 732 }
762 }); 733 });
763 } 734 }
764 735
765 void checkMixinSuperUses(TreeElements resolutionTree, 736 void checkMixinSuperUses(TreeElements resolutionTree,
766 MixinApplicationElement mixinApplication, 737 MixinApplicationElement mixinApplication, ClassElement mixin) {
767 ClassElement mixin) {
768 // TODO(johnniwinther): Avoid the use of [TreeElements] here. 738 // TODO(johnniwinther): Avoid the use of [TreeElements] here.
769 if (resolutionTree == null) return; 739 if (resolutionTree == null) return;
770 Iterable<SourceSpan> superUses = resolutionTree.superUses; 740 Iterable<SourceSpan> superUses = resolutionTree.superUses;
771 if (superUses.isEmpty) return; 741 if (superUses.isEmpty) return;
772 DiagnosticMessage error = reporter.createMessage( 742 DiagnosticMessage error = reporter.createMessage(mixinApplication,
773 mixinApplication, 743 MessageKind.ILLEGAL_MIXIN_WITH_SUPER, {'className': mixin.name});
774 MessageKind.ILLEGAL_MIXIN_WITH_SUPER,
775 {'className': mixin.name});
776 // Show the user the problematic uses of 'super' in the mixin. 744 // Show the user the problematic uses of 'super' in the mixin.
777 List<DiagnosticMessage> infos = <DiagnosticMessage>[]; 745 List<DiagnosticMessage> infos = <DiagnosticMessage>[];
778 for (SourceSpan use in superUses) { 746 for (SourceSpan use in superUses) {
779 infos.add(reporter.createMessage( 747 infos.add(
780 use, 748 reporter.createMessage(use, MessageKind.ILLEGAL_MIXIN_SUPER_USE));
781 MessageKind.ILLEGAL_MIXIN_SUPER_USE));
782 } 749 }
783 reporter.reportError(error, infos); 750 reporter.reportError(error, infos);
784 } 751 }
785 752
786 void checkClassMembers(ClassElement cls) { 753 void checkClassMembers(ClassElement cls) {
787 assert(invariant(cls, cls.isDeclaration)); 754 assert(invariant(cls, cls.isDeclaration));
788 if (cls.isObject) return; 755 if (cls.isObject) return;
789 // TODO(johnniwinther): Should this be done on the implementation element as 756 // TODO(johnniwinther): Should this be done on the implementation element as
790 // well? 757 // well?
791 List<Element> constConstructors = <Element>[]; 758 List<Element> constConstructors = <Element>[];
792 List<Element> nonFinalInstanceFields = <Element>[]; 759 List<Element> nonFinalInstanceFields = <Element>[];
793 cls.forEachMember((holder, member) { 760 cls.forEachMember((holder, member) {
794 reporter.withCurrentElement(member, () { 761 reporter.withCurrentElement(member, () {
795 // Perform various checks as side effect of "computing" the type. 762 // Perform various checks as side effect of "computing" the type.
796 member.computeType(resolution); 763 member.computeType(resolution);
797 764
798 // Check modifiers. 765 // Check modifiers.
799 if (member.isFunction && member.modifiers.isFinal) { 766 if (member.isFunction && member.modifiers.isFinal) {
800 reporter.reportErrorMessage( 767 reporter.reportErrorMessage(
801 member, MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER); 768 member, MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER);
802 } 769 }
803 if (member.isConstructor) { 770 if (member.isConstructor) {
804 final mismatchedFlagsBits = 771 final mismatchedFlagsBits = member.modifiers.flags &
805 member.modifiers.flags &
806 (Modifiers.FLAG_STATIC | Modifiers.FLAG_ABSTRACT); 772 (Modifiers.FLAG_STATIC | Modifiers.FLAG_ABSTRACT);
807 if (mismatchedFlagsBits != 0) { 773 if (mismatchedFlagsBits != 0) {
808 final mismatchedFlags = 774 final mismatchedFlags =
809 new Modifiers.withFlags(null, mismatchedFlagsBits); 775 new Modifiers.withFlags(null, mismatchedFlagsBits);
810 reporter.reportErrorMessage( 776 reporter.reportErrorMessage(
811 member, 777 member,
812 MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS, 778 MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS,
813 {'modifiers': mismatchedFlags}); 779 {'modifiers': mismatchedFlags});
814 } 780 }
815 if (member.modifiers.isConst) { 781 if (member.modifiers.isConst) {
816 constConstructors.add(member); 782 constConstructors.add(member);
817 } 783 }
818 } 784 }
819 if (member.isField) { 785 if (member.isField) {
820 if (member.modifiers.isConst && !member.modifiers.isStatic) { 786 if (member.modifiers.isConst && !member.modifiers.isStatic) {
821 reporter.reportErrorMessage( 787 reporter.reportErrorMessage(
822 member, MessageKind.ILLEGAL_CONST_FIELD_MODIFIER); 788 member, MessageKind.ILLEGAL_CONST_FIELD_MODIFIER);
823 } 789 }
824 if (!member.modifiers.isStatic && !member.modifiers.isFinal) { 790 if (!member.modifiers.isStatic && !member.modifiers.isFinal) {
825 nonFinalInstanceFields.add(member); 791 nonFinalInstanceFields.add(member);
826 } 792 }
827 } 793 }
828 checkAbstractField(member); 794 checkAbstractField(member);
829 checkUserDefinableOperator(member); 795 checkUserDefinableOperator(member);
830 }); 796 });
831 }); 797 });
832 if (!constConstructors.isEmpty && !nonFinalInstanceFields.isEmpty) { 798 if (!constConstructors.isEmpty && !nonFinalInstanceFields.isEmpty) {
833 Spannable span = constConstructors.length > 1 799 Spannable span =
834 ? cls : constConstructors[0]; 800 constConstructors.length > 1 ? cls : constConstructors[0];
835 DiagnosticMessage error = reporter.createMessage( 801 DiagnosticMessage error = reporter.createMessage(
836 span, 802 span,
837 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS, 803 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS,
838 {'className': cls.name}); 804 {'className': cls.name});
839 List<DiagnosticMessage> infos = <DiagnosticMessage>[]; 805 List<DiagnosticMessage> infos = <DiagnosticMessage>[];
840 if (constConstructors.length > 1) { 806 if (constConstructors.length > 1) {
841 for (Element constructor in constConstructors) { 807 for (Element constructor in constConstructors) {
842 infos.add(reporter.createMessage( 808 infos.add(reporter.createMessage(constructor,
843 constructor,
844 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR)); 809 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR));
845 } 810 }
846 } 811 }
847 for (Element field in nonFinalInstanceFields) { 812 for (Element field in nonFinalInstanceFields) {
848 infos.add(reporter.createMessage( 813 infos.add(reporter.createMessage(
849 field, 814 field, MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD));
850 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD));
851 } 815 }
852 reporter.reportError(error, infos); 816 reporter.reportError(error, infos);
853 } 817 }
854 } 818 }
855 819
856 void checkAbstractField(Element member) { 820 void checkAbstractField(Element member) {
857 // Only check for getters. The test can only fail if there is both a setter 821 // Only check for getters. The test can only fail if there is both a setter
858 // and a getter with the same name, and we only need to check each abstract 822 // and a getter with the same name, and we only need to check each abstract
859 // field once, so we just ignore setters. 823 // field once, so we just ignore setters.
860 if (!member.isGetter) return; 824 if (!member.isGetter) return;
861 825
862 // Find the associated abstract field. 826 // Find the associated abstract field.
863 ClassElement classElement = member.enclosingClass; 827 ClassElement classElement = member.enclosingClass;
864 Element lookupElement = classElement.lookupLocalMember(member.name); 828 Element lookupElement = classElement.lookupLocalMember(member.name);
865 if (lookupElement == null) { 829 if (lookupElement == null) {
866 reporter.internalError(member, 830 reporter.internalError(member, "No abstract field for accessor");
867 "No abstract field for accessor");
868 } else if (!lookupElement.isAbstractField) { 831 } else if (!lookupElement.isAbstractField) {
869 if (lookupElement.isMalformed || lookupElement.isAmbiguous) return; 832 if (lookupElement.isMalformed || lookupElement.isAmbiguous) return;
870 reporter.internalError(member, 833 reporter.internalError(
871 "Inaccessible abstract field for accessor"); 834 member, "Inaccessible abstract field for accessor");
872 } 835 }
873 AbstractFieldElement field = lookupElement; 836 AbstractFieldElement field = lookupElement;
874 837
875 GetterElementX getter = field.getter; 838 GetterElementX getter = field.getter;
876 if (getter == null) return; 839 if (getter == null) return;
877 SetterElementX setter = field.setter; 840 SetterElementX setter = field.setter;
878 if (setter == null) return; 841 if (setter == null) return;
879 int getterFlags = getter.modifiers.flags | Modifiers.FLAG_ABSTRACT; 842 int getterFlags = getter.modifiers.flags | Modifiers.FLAG_ABSTRACT;
880 int setterFlags = setter.modifiers.flags | Modifiers.FLAG_ABSTRACT; 843 int setterFlags = setter.modifiers.flags | Modifiers.FLAG_ABSTRACT;
881 if (getterFlags != setterFlags) { 844 if (getterFlags != setterFlags) {
882 final mismatchedFlags = 845 final mismatchedFlags =
883 new Modifiers.withFlags(null, getterFlags ^ setterFlags); 846 new Modifiers.withFlags(null, getterFlags ^ setterFlags);
884 reporter.reportWarningMessage( 847 reporter.reportWarningMessage(field.getter, MessageKind.GETTER_MISMATCH,
885 field.getter,
886 MessageKind.GETTER_MISMATCH,
887 {'modifiers': mismatchedFlags}); 848 {'modifiers': mismatchedFlags});
888 reporter.reportWarningMessage( 849 reporter.reportWarningMessage(field.setter, MessageKind.SETTER_MISMATCH,
889 field.setter,
890 MessageKind.SETTER_MISMATCH,
891 {'modifiers': mismatchedFlags}); 850 {'modifiers': mismatchedFlags});
892 } 851 }
893 } 852 }
894 853
895 void checkUserDefinableOperator(Element member) { 854 void checkUserDefinableOperator(Element member) {
896 FunctionElement function = member.asFunctionElement(); 855 FunctionElement function = member.asFunctionElement();
897 if (function == null) return; 856 if (function == null) return;
898 String value = member.name; 857 String value = member.name;
899 if (value == null) return; 858 if (value == null) return;
900 if (!(isUserDefinableOperator(value) || identical(value, 'unary-'))) return; 859 if (!(isUserDefinableOperator(value) || identical(value, 'unary-'))) return;
(...skipping 13 matching lines...) Expand all
914 messageKind = MessageKind.UNARY_OPERATOR_BAD_ARITY; 873 messageKind = MessageKind.UNARY_OPERATOR_BAD_ARITY;
915 requiredParameterCount = 0; 874 requiredParameterCount = 0;
916 } else if (isBinaryOperator(value)) { 875 } else if (isBinaryOperator(value)) {
917 messageKind = MessageKind.BINARY_OPERATOR_BAD_ARITY; 876 messageKind = MessageKind.BINARY_OPERATOR_BAD_ARITY;
918 requiredParameterCount = 1; 877 requiredParameterCount = 1;
919 if (identical(value, '==')) checkOverrideHashCode(member); 878 if (identical(value, '==')) checkOverrideHashCode(member);
920 } else if (isTernaryOperator(value)) { 879 } else if (isTernaryOperator(value)) {
921 messageKind = MessageKind.TERNARY_OPERATOR_BAD_ARITY; 880 messageKind = MessageKind.TERNARY_OPERATOR_BAD_ARITY;
922 requiredParameterCount = 2; 881 requiredParameterCount = 2;
923 } else { 882 } else {
924 reporter.internalError(function, 883 reporter.internalError(
925 'Unexpected user defined operator $value'); 884 function, 'Unexpected user defined operator $value');
926 } 885 }
927 checkArity(function, requiredParameterCount, messageKind, isMinus); 886 checkArity(function, requiredParameterCount, messageKind, isMinus);
928 } 887 }
929 888
930 void checkOverrideHashCode(FunctionElement operatorEquals) { 889 void checkOverrideHashCode(FunctionElement operatorEquals) {
931 if (operatorEquals.isAbstract) return; 890 if (operatorEquals.isAbstract) return;
932 ClassElement cls = operatorEquals.enclosingClass; 891 ClassElement cls = operatorEquals.enclosingClass;
933 Element hashCodeImplementation = 892 Element hashCodeImplementation = cls.lookupLocalMember('hashCode');
934 cls.lookupLocalMember('hashCode');
935 if (hashCodeImplementation != null) return; 893 if (hashCodeImplementation != null) return;
936 reporter.reportHintMessage( 894 reporter.reportHintMessage(operatorEquals,
937 operatorEquals, MessageKind.OVERRIDE_EQUALS_NOT_HASH_CODE, 895 MessageKind.OVERRIDE_EQUALS_NOT_HASH_CODE, {'class': cls.name});
938 {'class': cls.name});
939 } 896 }
940 897
941 void checkArity(FunctionElement function, 898 void checkArity(FunctionElement function, int requiredParameterCount,
942 int requiredParameterCount, MessageKind messageKind, 899 MessageKind messageKind, bool isMinus) {
943 bool isMinus) {
944 FunctionExpression node = function.node; 900 FunctionExpression node = function.node;
945 FunctionSignature signature = function.functionSignature; 901 FunctionSignature signature = function.functionSignature;
946 if (signature.requiredParameterCount != requiredParameterCount) { 902 if (signature.requiredParameterCount != requiredParameterCount) {
947 Node errorNode = node; 903 Node errorNode = node;
948 if (node.parameters != null) { 904 if (node.parameters != null) {
949 if (isMinus || 905 if (isMinus ||
950 signature.requiredParameterCount < requiredParameterCount) { 906 signature.requiredParameterCount < requiredParameterCount) {
951 // If there are too few parameters, point to the whole parameter list. 907 // If there are too few parameters, point to the whole parameter list.
952 // For instance 908 // For instance
953 // 909 //
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
987 {'operatorName': function.name}); 943 {'operatorName': function.name});
988 } else { 944 } else {
989 reporter.reportErrorMessage( 945 reporter.reportErrorMessage(
990 errorNode, 946 errorNode,
991 MessageKind.OPERATOR_OPTIONAL_PARAMETERS, 947 MessageKind.OPERATOR_OPTIONAL_PARAMETERS,
992 {'operatorName': function.name}); 948 {'operatorName': function.name});
993 } 949 }
994 } 950 }
995 } 951 }
996 952
997 reportErrorWithContext(Element errorneousElement, 953 reportErrorWithContext(Element errorneousElement, MessageKind errorMessage,
998 MessageKind errorMessage, 954 Element contextElement, MessageKind contextMessage) {
999 Element contextElement,
1000 MessageKind contextMessage) {
1001 reporter.reportError( 955 reporter.reportError(
1002 reporter.createMessage( 956 reporter.createMessage(errorneousElement, errorMessage, {
1003 errorneousElement, 957 'memberName': contextElement.name,
1004 errorMessage, 958 'className': contextElement.enclosingClass.name
1005 {'memberName': contextElement.name, 959 }),
1006 'className': contextElement.enclosingClass.name}),
1007 <DiagnosticMessage>[ 960 <DiagnosticMessage>[
1008 reporter.createMessage(contextElement, contextMessage), 961 reporter.createMessage(contextElement, contextMessage),
1009 ]); 962 ]);
1010 } 963 }
1011 964
1012
1013 FunctionSignature resolveSignature(FunctionElementX element) { 965 FunctionSignature resolveSignature(FunctionElementX element) {
1014 MessageKind defaultValuesError = null; 966 MessageKind defaultValuesError = null;
1015 if (element.isFactoryConstructor) { 967 if (element.isFactoryConstructor) {
1016 FunctionExpression body = element.parseNode(parsing); 968 FunctionExpression body = element.parseNode(parsing);
1017 if (body.isRedirectingFactory) { 969 if (body.isRedirectingFactory) {
1018 defaultValuesError = MessageKind.REDIRECTING_FACTORY_WITH_DEFAULT; 970 defaultValuesError = MessageKind.REDIRECTING_FACTORY_WITH_DEFAULT;
1019 } 971 }
1020 } 972 }
1021 return reporter.withCurrentElement(element, () { 973 return reporter.withCurrentElement(element, () {
1022 FunctionExpression node = element.parseNode(parsing); 974 FunctionExpression node = element.parseNode(parsing);
1023 return measure(() => SignatureResolver.analyze( 975 return measure(() => SignatureResolver.analyze(
1024 compiler, node.parameters, node.returnType, element, 976 compiler,
977 node.parameters,
978 node.returnType,
979 element,
1025 new ResolutionRegistry(compiler, _ensureTreeElements(element)), 980 new ResolutionRegistry(compiler, _ensureTreeElements(element)),
1026 defaultValuesError: defaultValuesError, 981 defaultValuesError: defaultValuesError,
1027 createRealParameters: true)); 982 createRealParameters: true));
1028 }); 983 });
1029 } 984 }
1030 985
1031 WorldImpact resolveTypedef(TypedefElementX element) { 986 WorldImpact resolveTypedef(TypedefElementX element) {
1032 if (element.isResolved) return const ResolutionImpact(); 987 if (element.isResolved) return const ResolutionImpact();
1033 compiler.world.allTypedefs.add(element); 988 compiler.world.allTypedefs.add(element);
1034 return _resolveTypeDeclaration(element, () { 989 return _resolveTypeDeclaration(element, () {
1035 ResolutionRegistry registry = new ResolutionRegistry( 990 ResolutionRegistry registry =
1036 compiler, _ensureTreeElements(element)); 991 new ResolutionRegistry(compiler, _ensureTreeElements(element));
1037 return reporter.withCurrentElement(element, () { 992 return reporter.withCurrentElement(element, () {
1038 return measure(() { 993 return measure(() {
1039 assert(element.resolutionState == STATE_NOT_STARTED); 994 assert(element.resolutionState == STATE_NOT_STARTED);
1040 element.resolutionState = STATE_STARTED; 995 element.resolutionState = STATE_STARTED;
1041 Typedef node = element.parseNode(parsing); 996 Typedef node = element.parseNode(parsing);
1042 TypedefResolverVisitor visitor = 997 TypedefResolverVisitor visitor =
1043 new TypedefResolverVisitor(compiler, element, registry); 998 new TypedefResolverVisitor(compiler, element, registry);
1044 visitor.visit(node); 999 visitor.visit(node);
1045 element.resolutionState = STATE_DONE; 1000 element.resolutionState = STATE_DONE;
1046 return registry.worldImpact; 1001 return registry.worldImpact;
1047 }); 1002 });
1048 }); 1003 });
1049 }); 1004 });
1050 } 1005 }
1051 1006
1052 void resolveMetadataAnnotation(MetadataAnnotationX annotation) { 1007 void resolveMetadataAnnotation(MetadataAnnotationX annotation) {
1053 reporter.withCurrentElement(annotation.annotatedElement, () => measure(() { 1008 reporter.withCurrentElement(
1054 assert(annotation.resolutionState == STATE_NOT_STARTED); 1009 annotation.annotatedElement,
1055 annotation.resolutionState = STATE_STARTED; 1010 () => measure(() {
1011 assert(annotation.resolutionState == STATE_NOT_STARTED);
1012 annotation.resolutionState = STATE_STARTED;
1056 1013
1057 Node node = annotation.parseNode(parsing); 1014 Node node = annotation.parseNode(parsing);
1058 Element annotatedElement = annotation.annotatedElement; 1015 Element annotatedElement = annotation.annotatedElement;
1059 AnalyzableElement context = annotatedElement.analyzableElement; 1016 AnalyzableElement context = annotatedElement.analyzableElement;
1060 ClassElement classElement = annotatedElement.enclosingClass; 1017 ClassElement classElement = annotatedElement.enclosingClass;
1061 if (classElement != null) { 1018 if (classElement != null) {
1062 // The annotation is resolved in the scope of [classElement]. 1019 // The annotation is resolved in the scope of [classElement].
1063 classElement.ensureResolved(resolution); 1020 classElement.ensureResolved(resolution);
1064 } 1021 }
1065 assert(invariant(node, context != null, 1022 assert(invariant(node, context != null,
1066 message: "No context found for metadata annotation " 1023 message: "No context found for metadata annotation "
1067 "on $annotatedElement.")); 1024 "on $annotatedElement."));
1068 ResolverVisitor visitor = visitorFor(context, useEnclosingScope: true); 1025 ResolverVisitor visitor =
1069 ResolutionRegistry registry = visitor.registry; 1026 visitorFor(context, useEnclosingScope: true);
1070 node.accept(visitor); 1027 ResolutionRegistry registry = visitor.registry;
1071 // TODO(johnniwinther): Avoid passing the [TreeElements] to 1028 node.accept(visitor);
1072 // [compileMetadata]. 1029 // TODO(johnniwinther): Avoid passing the [TreeElements] to
1073 ConstantExpression constant = constantCompiler.compileMetadata( 1030 // [compileMetadata].
1074 annotation, node, registry.mapping); 1031 ConstantExpression constant = constantCompiler.compileMetadata(
1075 switch (constant.kind) { 1032 annotation, node, registry.mapping);
1076 case ConstantExpressionKind.CONSTRUCTED: 1033 switch (constant.kind) {
1077 ConstructedConstantExpression constructedConstant = constant; 1034 case ConstantExpressionKind.CONSTRUCTED:
1078 if (constructedConstant.type.isGeneric) { 1035 ConstructedConstantExpression constructedConstant = constant;
1079 // Const constructor calls cannot have type arguments. 1036 if (constructedConstant.type.isGeneric) {
1080 // TODO(24312): Remove this. 1037 // Const constructor calls cannot have type arguments.
1081 reporter.reportErrorMessage( 1038 // TODO(24312): Remove this.
1082 node, MessageKind.INVALID_METADATA_GENERIC); 1039 reporter.reportErrorMessage(
1083 constant = new ErroneousConstantExpression(); 1040 node, MessageKind.INVALID_METADATA_GENERIC);
1084 } 1041 constant = new ErroneousConstantExpression();
1085 break; 1042 }
1086 case ConstantExpressionKind.VARIABLE: 1043 break;
1087 case ConstantExpressionKind.ERRONEOUS: 1044 case ConstantExpressionKind.VARIABLE:
1088 break; 1045 case ConstantExpressionKind.ERRONEOUS:
1089 default: 1046 break;
1090 reporter.reportErrorMessage(node, MessageKind.INVALID_METADATA); 1047 default:
1091 constant = new ErroneousConstantExpression(); 1048 reporter.reportErrorMessage(
1092 break; 1049 node, MessageKind.INVALID_METADATA);
1093 } 1050 constant = new ErroneousConstantExpression();
1094 annotation.constant = constant; 1051 break;
1052 }
1053 annotation.constant = constant;
1095 1054
1096 constantCompiler.evaluate(annotation.constant); 1055 constantCompiler.evaluate(annotation.constant);
1097 // TODO(johnniwinther): Register the relation between the annotation 1056 // TODO(johnniwinther): Register the relation between the annotati on
1098 // and the annotated element instead. This will allow the backend to 1057 // and the annotated element instead. This will allow the backend to
1099 // retrieve the backend constant and only register metadata on the 1058 // retrieve the backend constant and only register metadata on the
1100 // elements for which it is needed. (Issue 17732). 1059 // elements for which it is needed. (Issue 17732).
1101 registry.registerMetadataConstant(annotation); 1060 registry.registerMetadataConstant(annotation);
1102 annotation.resolutionState = STATE_DONE; 1061 annotation.resolutionState = STATE_DONE;
1103 })); 1062 }));
1104 } 1063 }
1105 1064
1106 List<MetadataAnnotation> resolveMetadata(Element element, 1065 List<MetadataAnnotation> resolveMetadata(
1107 VariableDefinitions node) { 1066 Element element, VariableDefinitions node) {
1108 List<MetadataAnnotation> metadata = <MetadataAnnotation>[]; 1067 List<MetadataAnnotation> metadata = <MetadataAnnotation>[];
1109 for (Metadata annotation in node.metadata.nodes) { 1068 for (Metadata annotation in node.metadata.nodes) {
1110 ParameterMetadataAnnotation metadataAnnotation = 1069 ParameterMetadataAnnotation metadataAnnotation =
1111 new ParameterMetadataAnnotation(annotation); 1070 new ParameterMetadataAnnotation(annotation);
1112 metadataAnnotation.annotatedElement = element; 1071 metadataAnnotation.annotatedElement = element;
1113 metadata.add(metadataAnnotation.ensureResolved(resolution)); 1072 metadata.add(metadataAnnotation.ensureResolved(resolution));
1114 } 1073 }
1115 return metadata; 1074 return metadata;
1116 } 1075 }
1117 } 1076 }
1118 1077
1119 TreeElements _ensureTreeElements(AnalyzableElementX element) { 1078 TreeElements _ensureTreeElements(AnalyzableElementX element) {
1120 if (element._treeElements == null) { 1079 if (element._treeElements == null) {
1121 element._treeElements = new TreeElementMapping(element); 1080 element._treeElements = new TreeElementMapping(element);
1122 } 1081 }
1123 return element._treeElements; 1082 return element._treeElements;
1124 } 1083 }
1125 1084
1126 abstract class AnalyzableElementX implements AnalyzableElement { 1085 abstract class AnalyzableElementX implements AnalyzableElement {
1127 TreeElements _treeElements; 1086 TreeElements _treeElements;
1128 1087
1129 bool get hasTreeElements => _treeElements != null; 1088 bool get hasTreeElements => _treeElements != null;
1130 1089
1131 TreeElements get treeElements { 1090 TreeElements get treeElements {
1132 assert(invariant(this, _treeElements !=null, 1091 assert(invariant(this, _treeElements != null,
1133 message: "TreeElements have not been computed for $this.")); 1092 message: "TreeElements have not been computed for $this."));
1134 return _treeElements; 1093 return _treeElements;
1135 } 1094 }
1136 1095
1137 void reuseElement() { 1096 void reuseElement() {
1138 _treeElements = null; 1097 _treeElements = null;
1139 } 1098 }
1140 } 1099 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/resolution/registry.dart ('k') | pkg/compiler/lib/src/resolution/resolution_common.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698