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

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

Issue 1383483006: Extract DiagnosticReporter implementation from Compiler. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 5 years, 2 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/names.dart' show 9 import '../common/names.dart' show
10 Identifiers; 10 Identifiers;
11 import '../common/resolution.dart' show 11 import '../common/resolution.dart' show
12 Parsing, 12 Parsing,
13 Resolution; 13 Resolution;
14 import '../common/tasks.dart' show 14 import '../common/tasks.dart' show
15 CompilerTask, 15 CompilerTask,
16 DeferredAction; 16 DeferredAction;
17 import '../compiler.dart' show 17 import '../compiler.dart' show
18 Compiler; 18 Compiler;
19 import '../compile_time_constants.dart' show 19 import '../compile_time_constants.dart' show
20 ConstantCompiler; 20 ConstantCompiler;
21 import '../constants/values.dart' show 21 import '../constants/values.dart' show
22 ConstantValue; 22 ConstantValue;
23 import '../dart_types.dart'; 23 import '../dart_types.dart';
24 import '../diagnostics/diagnostic_listener.dart' show 24 import '../diagnostics/diagnostic_listener.dart' show
25 DiagnosticMessage; 25 DiagnosticMessage,
26 DiagnosticReporter;
26 import '../diagnostics/invariant.dart' show 27 import '../diagnostics/invariant.dart' show
27 invariant; 28 invariant;
28 import '../diagnostics/messages.dart' show 29 import '../diagnostics/messages.dart' show
29 MessageKind; 30 MessageKind;
30 import '../diagnostics/spannable.dart' show 31 import '../diagnostics/spannable.dart' show
31 Spannable; 32 Spannable;
32 import '../elements/elements.dart'; 33 import '../elements/elements.dart';
33 import '../elements/modelx.dart' show 34 import '../elements/modelx.dart' show
34 BaseClassElementX, 35 BaseClassElementX,
35 BaseFunctionElementX, 36 BaseFunctionElementX,
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 FunctionElement redirection) { 124 FunctionElement redirection) {
124 assert(invariant(node, constructor.isImplementation, 125 assert(invariant(node, constructor.isImplementation,
125 message: 'Redirecting constructors must be resolved on implementation ' 126 message: 'Redirecting constructors must be resolved on implementation '
126 'elements.')); 127 'elements.'));
127 Setlet<FunctionElement> seen = new Setlet<FunctionElement>(); 128 Setlet<FunctionElement> seen = new Setlet<FunctionElement>();
128 seen.add(constructor); 129 seen.add(constructor);
129 while (redirection != null) { 130 while (redirection != null) {
130 // Ensure that we follow redirections through implementation elements. 131 // Ensure that we follow redirections through implementation elements.
131 redirection = redirection.implementation; 132 redirection = redirection.implementation;
132 if (seen.contains(redirection)) { 133 if (seen.contains(redirection)) {
133 compiler.reportErrorMessage( 134 reporter.reportErrorMessage(
134 node, MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE); 135 node, MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE);
135 return; 136 return;
136 } 137 }
137 seen.add(redirection); 138 seen.add(redirection);
138 redirection = resolver.visitor.resolveConstructorRedirection(redirection); 139 redirection = resolver.visitor.resolveConstructorRedirection(redirection);
139 } 140 }
140 } 141 }
141 142
142 static void processAsyncMarker(Compiler compiler, 143 static void processAsyncMarker(Compiler compiler,
143 BaseFunctionElementX element, 144 BaseFunctionElementX element,
144 ResolutionRegistry registry) { 145 ResolutionRegistry registry) {
146 DiagnosticReporter reporter = compiler.reporter;
145 Resolution resolution = compiler.resolution; 147 Resolution resolution = compiler.resolution;
146 FunctionExpression functionExpression = element.node; 148 FunctionExpression functionExpression = element.node;
147 AsyncModifier asyncModifier = functionExpression.asyncModifier; 149 AsyncModifier asyncModifier = functionExpression.asyncModifier;
148 if (asyncModifier != null) { 150 if (asyncModifier != null) {
149 151
150 if (asyncModifier.isAsynchronous) { 152 if (asyncModifier.isAsynchronous) {
151 element.asyncMarker = asyncModifier.isYielding 153 element.asyncMarker = asyncModifier.isYielding
152 ? AsyncMarker.ASYNC_STAR : AsyncMarker.ASYNC; 154 ? AsyncMarker.ASYNC_STAR : AsyncMarker.ASYNC;
153 } else { 155 } else {
154 element.asyncMarker = AsyncMarker.SYNC_STAR; 156 element.asyncMarker = AsyncMarker.SYNC_STAR;
155 } 157 }
156 if (element.isAbstract) { 158 if (element.isAbstract) {
157 compiler.reportErrorMessage( 159 reporter.reportErrorMessage(
158 asyncModifier, 160 asyncModifier,
159 MessageKind.ASYNC_MODIFIER_ON_ABSTRACT_METHOD, 161 MessageKind.ASYNC_MODIFIER_ON_ABSTRACT_METHOD,
160 {'modifier': element.asyncMarker}); 162 {'modifier': element.asyncMarker});
161 } else if (element.isConstructor) { 163 } else if (element.isConstructor) {
162 compiler.reportErrorMessage( 164 reporter.reportErrorMessage(
163 asyncModifier, 165 asyncModifier,
164 MessageKind.ASYNC_MODIFIER_ON_CONSTRUCTOR, 166 MessageKind.ASYNC_MODIFIER_ON_CONSTRUCTOR,
165 {'modifier': element.asyncMarker}); 167 {'modifier': element.asyncMarker});
166 } else { 168 } else {
167 if (element.isSetter) { 169 if (element.isSetter) {
168 compiler.reportErrorMessage( 170 reporter.reportErrorMessage(
169 asyncModifier, 171 asyncModifier,
170 MessageKind.ASYNC_MODIFIER_ON_SETTER, 172 MessageKind.ASYNC_MODIFIER_ON_SETTER,
171 {'modifier': element.asyncMarker}); 173 {'modifier': element.asyncMarker});
172 174
173 } 175 }
174 if (functionExpression.body.asReturn() != null && 176 if (functionExpression.body.asReturn() != null &&
175 element.asyncMarker.isYielding) { 177 element.asyncMarker.isYielding) {
176 compiler.reportErrorMessage( 178 reporter.reportErrorMessage(
177 asyncModifier, 179 asyncModifier,
178 MessageKind.YIELDING_MODIFIER_ON_ARROW_BODY, 180 MessageKind.YIELDING_MODIFIER_ON_ARROW_BODY,
179 {'modifier': element.asyncMarker}); 181 {'modifier': element.asyncMarker});
180 } 182 }
181 } 183 }
182 registry.registerAsyncMarker(element); 184 registry.registerAsyncMarker(element);
183 switch (element.asyncMarker) { 185 switch (element.asyncMarker) {
184 case AsyncMarker.ASYNC: 186 case AsyncMarker.ASYNC:
185 compiler.futureClass.ensureResolved(resolution); 187 compiler.futureClass.ensureResolved(resolution);
186 break; 188 break;
(...skipping 11 matching lines...) Expand all
198 assert(classElement != null); 200 assert(classElement != null);
199 while (classElement != null) { 201 while (classElement != null) {
200 if (classElement.isNative) return true; 202 if (classElement.isNative) return true;
201 classElement = classElement.superclass; 203 classElement = classElement.superclass;
202 } 204 }
203 return false; 205 return false;
204 } 206 }
205 207
206 WorldImpact resolveMethodElementImplementation( 208 WorldImpact resolveMethodElementImplementation(
207 FunctionElement element, FunctionExpression tree) { 209 FunctionElement element, FunctionExpression tree) {
208 return compiler.withCurrentElement(element, () { 210 return reporter.withCurrentElement(element, () {
209 if (element.isExternal && tree.hasBody()) { 211 if (element.isExternal && tree.hasBody()) {
210 compiler.reportErrorMessage( 212 reporter.reportErrorMessage(
211 element, 213 element,
212 MessageKind.EXTERNAL_WITH_BODY, 214 MessageKind.EXTERNAL_WITH_BODY,
213 {'functionName': element.name}); 215 {'functionName': element.name});
214 } 216 }
215 if (element.isConstructor) { 217 if (element.isConstructor) {
216 if (tree.returnType != null) { 218 if (tree.returnType != null) {
217 compiler.reportErrorMessage( 219 reporter.reportErrorMessage(
218 tree, MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE); 220 tree, MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE);
219 } 221 }
220 if (element.isConst && 222 if (element.isConst &&
221 tree.hasBody() && 223 tree.hasBody() &&
222 !tree.isRedirectingFactory) { 224 !tree.isRedirectingFactory) {
223 compiler.reportErrorMessage( 225 reporter.reportErrorMessage(
224 tree, MessageKind.CONST_CONSTRUCTOR_HAS_BODY); 226 tree, MessageKind.CONST_CONSTRUCTOR_HAS_BODY);
225 } 227 }
226 } 228 }
227 229
228 ResolverVisitor visitor = visitorFor(element); 230 ResolverVisitor visitor = visitorFor(element);
229 ResolutionRegistry registry = visitor.registry; 231 ResolutionRegistry registry = visitor.registry;
230 registry.defineFunction(tree, element); 232 registry.defineFunction(tree, element);
231 visitor.setupFunction(tree, element); 233 visitor.setupFunction(tree, element);
232 processAsyncMarker(compiler, element, registry); 234 processAsyncMarker(compiler, element, registry);
233 235
234 if (element.isGenerativeConstructor) { 236 if (element.isGenerativeConstructor) {
235 // Even if there is no initializer list we still have to do the 237 // Even if there is no initializer list we still have to do the
236 // resolution in case there is an implicit super constructor call. 238 // resolution in case there is an implicit super constructor call.
237 InitializerResolver resolver = 239 InitializerResolver resolver =
238 new InitializerResolver(visitor, element, tree); 240 new InitializerResolver(visitor, element, tree);
239 FunctionElement redirection = resolver.resolveInitializers(); 241 FunctionElement redirection = resolver.resolveInitializers();
240 if (redirection != null) { 242 if (redirection != null) {
241 resolveRedirectingConstructor(resolver, tree, element, redirection); 243 resolveRedirectingConstructor(resolver, tree, element, redirection);
242 } 244 }
243 } else if (tree.initializers != null) { 245 } else if (tree.initializers != null) {
244 compiler.reportErrorMessage( 246 reporter.reportErrorMessage(
245 tree, MessageKind.FUNCTION_WITH_INITIALIZER); 247 tree, MessageKind.FUNCTION_WITH_INITIALIZER);
246 } 248 }
247 249
248 if (!compiler.analyzeSignaturesOnly || tree.isRedirectingFactory) { 250 if (!compiler.analyzeSignaturesOnly || tree.isRedirectingFactory) {
249 // We need to analyze the redirecting factory bodies to ensure that 251 // We need to analyze the redirecting factory bodies to ensure that
250 // we can analyze compile-time constants. 252 // we can analyze compile-time constants.
251 visitor.visit(tree.body); 253 visitor.visit(tree.body);
252 } 254 }
253 255
254 // Get the resolution tree and check that the resolved 256 // Get the resolution tree and check that the resolved
(...skipping 10 matching lines...) Expand all
265 ClassElement mixin = enclosingClass; 267 ClassElement mixin = enclosingClass;
266 for (MixinApplicationElement mixinApplication in mixinUses) { 268 for (MixinApplicationElement mixinApplication in mixinUses) {
267 checkMixinSuperUses(resolutionTree, mixinApplication, mixin); 269 checkMixinSuperUses(resolutionTree, mixinApplication, mixin);
268 } 270 }
269 } 271 }
270 272
271 // TODO(9631): support noSuchMethod on native classes. 273 // TODO(9631): support noSuchMethod on native classes.
272 if (Elements.isInstanceMethod(element) && 274 if (Elements.isInstanceMethod(element) &&
273 element.name == Identifiers.noSuchMethod_ && 275 element.name == Identifiers.noSuchMethod_ &&
274 _isNativeClassOrExtendsNativeClass(enclosingClass)) { 276 _isNativeClassOrExtendsNativeClass(enclosingClass)) {
275 compiler.reportErrorMessage( 277 reporter.reportErrorMessage(
276 tree, MessageKind.NO_SUCH_METHOD_IN_NATIVE); 278 tree, MessageKind.NO_SUCH_METHOD_IN_NATIVE);
277 } 279 }
278 280
279 return registry.worldImpact; 281 return registry.worldImpact;
280 }); 282 });
281 283
282 } 284 }
283 285
284 WorldImpact resolveMethodElement(FunctionElementX element) { 286 WorldImpact resolveMethodElement(FunctionElementX element) {
285 assert(invariant(element, element.isDeclaration)); 287 assert(invariant(element, element.isDeclaration));
286 return compiler.withCurrentElement(element, () { 288 return reporter.withCurrentElement(element, () {
287 if (compiler.enqueuer.resolution.hasBeenResolved(element)) { 289 if (compiler.enqueuer.resolution.hasBeenResolved(element)) {
288 // TODO(karlklose): Remove the check for [isConstructor]. [elememts] 290 // TODO(karlklose): Remove the check for [isConstructor]. [elememts]
289 // should never be non-null, not even for constructors. 291 // should never be non-null, not even for constructors.
290 assert(invariant(element, element.isConstructor, 292 assert(invariant(element, element.isConstructor,
291 message: 'Non-constructor element $element ' 293 message: 'Non-constructor element $element '
292 'has already been analyzed.')); 294 'has already been analyzed.'));
293 return const WorldImpact(); 295 return const WorldImpact();
294 } 296 }
295 if (element.isSynthesized) { 297 if (element.isSynthesized) {
296 if (element.isGenerativeConstructor) { 298 if (element.isGenerativeConstructor) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 /// this library). 335 /// this library).
334 ResolverVisitor visitorFor(Element element, {bool useEnclosingScope: false}) { 336 ResolverVisitor visitorFor(Element element, {bool useEnclosingScope: false}) {
335 return new ResolverVisitor(compiler, element, 337 return new ResolverVisitor(compiler, element,
336 new ResolutionRegistry(compiler, _ensureTreeElements(element)), 338 new ResolutionRegistry(compiler, _ensureTreeElements(element)),
337 useEnclosingScope: useEnclosingScope); 339 useEnclosingScope: useEnclosingScope);
338 } 340 }
339 341
340 WorldImpact resolveField(FieldElementX element) { 342 WorldImpact resolveField(FieldElementX element) {
341 VariableDefinitions tree = element.parseNode(parsing); 343 VariableDefinitions tree = element.parseNode(parsing);
342 if(element.modifiers.isStatic && element.isTopLevel) { 344 if(element.modifiers.isStatic && element.isTopLevel) {
343 compiler.reportErrorMessage( 345 reporter.reportErrorMessage(
344 element.modifiers.getStatic(), 346 element.modifiers.getStatic(),
345 MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC); 347 MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC);
346 } 348 }
347 ResolverVisitor visitor = visitorFor(element); 349 ResolverVisitor visitor = visitorFor(element);
348 ResolutionRegistry registry = visitor.registry; 350 ResolutionRegistry registry = visitor.registry;
349 // TODO(johnniwinther): Maybe remove this when placeholderCollector migrates 351 // TODO(johnniwinther): Maybe remove this when placeholderCollector migrates
350 // to the backend ast. 352 // to the backend ast.
351 registry.defineElement(tree.definitions.nodes.head, element); 353 registry.defineElement(tree.definitions.nodes.head, element);
352 // TODO(johnniwinther): Share the resolved type between all variables 354 // TODO(johnniwinther): Share the resolved type between all variables
353 // declared in the same declaration. 355 // declared in the same declaration.
354 if (tree.type != null) { 356 if (tree.type != null) {
355 element.variables.type = visitor.resolveTypeAnnotation(tree.type); 357 element.variables.type = visitor.resolveTypeAnnotation(tree.type);
356 } else { 358 } else {
357 element.variables.type = const DynamicType(); 359 element.variables.type = const DynamicType();
358 } 360 }
359 361
360 Expression initializer = element.initializer; 362 Expression initializer = element.initializer;
361 Modifiers modifiers = element.modifiers; 363 Modifiers modifiers = element.modifiers;
362 if (initializer != null) { 364 if (initializer != null) {
363 // TODO(johnniwinther): Avoid analyzing initializers if 365 // TODO(johnniwinther): Avoid analyzing initializers if
364 // [Compiler.analyzeSignaturesOnly] is set. 366 // [Compiler.analyzeSignaturesOnly] is set.
365 visitor.visit(initializer); 367 visitor.visit(initializer);
366 } else if (modifiers.isConst) { 368 } else if (modifiers.isConst) {
367 compiler.reportErrorMessage( 369 reporter.reportErrorMessage(
368 element, MessageKind.CONST_WITHOUT_INITIALIZER); 370 element, MessageKind.CONST_WITHOUT_INITIALIZER);
369 } else if (modifiers.isFinal && !element.isInstanceMember) { 371 } else if (modifiers.isFinal && !element.isInstanceMember) {
370 compiler.reportErrorMessage( 372 reporter.reportErrorMessage(
371 element, MessageKind.FINAL_WITHOUT_INITIALIZER); 373 element, MessageKind.FINAL_WITHOUT_INITIALIZER);
372 } else { 374 } else {
373 registry.registerInstantiatedClass(compiler.nullClass); 375 registry.registerInstantiatedClass(compiler.nullClass);
374 } 376 }
375 377
376 if (Elements.isStaticOrTopLevelField(element)) { 378 if (Elements.isStaticOrTopLevelField(element)) {
377 visitor.addDeferredAction(element, () { 379 visitor.addDeferredAction(element, () {
378 if (element.modifiers.isConst) { 380 if (element.modifiers.isConst) {
379 element.constant = constantCompiler.compileConstant(element); 381 element.constant = constantCompiler.compileConstant(element);
380 } else { 382 } else {
(...skipping 11 matching lines...) Expand all
392 394
393 // Perform various checks as side effect of "computing" the type. 395 // Perform various checks as side effect of "computing" the type.
394 element.computeType(resolution); 396 element.computeType(resolution);
395 397
396 return registry.worldImpact; 398 return registry.worldImpact;
397 } 399 }
398 400
399 DartType resolveTypeAnnotation(Element element, TypeAnnotation annotation) { 401 DartType resolveTypeAnnotation(Element element, TypeAnnotation annotation) {
400 DartType type = resolveReturnType(element, annotation); 402 DartType type = resolveReturnType(element, annotation);
401 if (type.isVoid) { 403 if (type.isVoid) {
402 compiler.reportErrorMessage( 404 reporter.reportErrorMessage(
403 annotation, MessageKind.VOID_NOT_ALLOWED); 405 annotation, MessageKind.VOID_NOT_ALLOWED);
404 } 406 }
405 return type; 407 return type;
406 } 408 }
407 409
408 DartType resolveReturnType(Element element, TypeAnnotation annotation) { 410 DartType resolveReturnType(Element element, TypeAnnotation annotation) {
409 if (annotation == null) return const DynamicType(); 411 if (annotation == null) return const DynamicType();
410 DartType result = visitorFor(element).resolveTypeAnnotation(annotation); 412 DartType result = visitorFor(element).resolveTypeAnnotation(annotation);
411 if (result == null) { 413 if (result == null) {
412 // TODO(karklose): warning. 414 // TODO(karklose): warning.
(...skipping 14 matching lines...) Expand all
427 targetType = target.effectiveTargetType; 429 targetType = target.effectiveTargetType;
428 assert(invariant(target, targetType != null, 430 assert(invariant(target, targetType != null,
429 message: 'Redirection target type has not been computed for ' 431 message: 'Redirection target type has not been computed for '
430 '$target')); 432 '$target'));
431 target = target.internalEffectiveTarget; 433 target = target.internalEffectiveTarget;
432 break; 434 break;
433 } 435 }
434 436
435 Element nextTarget = target.immediateRedirectionTarget; 437 Element nextTarget = target.immediateRedirectionTarget;
436 if (seen.contains(nextTarget)) { 438 if (seen.contains(nextTarget)) {
437 compiler.reportErrorMessage( 439 reporter.reportErrorMessage(
438 node, MessageKind.CYCLIC_REDIRECTING_FACTORY); 440 node, MessageKind.CYCLIC_REDIRECTING_FACTORY);
439 targetType = target.enclosingClass.thisType; 441 targetType = target.enclosingClass.thisType;
440 break; 442 break;
441 } 443 }
442 seen.add(target); 444 seen.add(target);
443 target = nextTarget; 445 target = nextTarget;
444 } 446 }
445 447
446 if (targetType == null) { 448 if (targetType == null) {
447 assert(!target.isRedirectingFactory); 449 assert(!target.isRedirectingFactory);
(...skipping 26 matching lines...) Expand all
474 } 476 }
475 } 477 }
476 478
477 /** 479 /**
478 * Load and resolve the supertypes of [cls]. 480 * Load and resolve the supertypes of [cls].
479 * 481 *
480 * Warning: do not call this method directly. It should only be 482 * Warning: do not call this method directly. It should only be
481 * called by [resolveClass] and [ClassSupertypeResolver]. 483 * called by [resolveClass] and [ClassSupertypeResolver].
482 */ 484 */
483 void loadSupertypes(BaseClassElementX cls, Spannable from) { 485 void loadSupertypes(BaseClassElementX cls, Spannable from) {
484 compiler.withCurrentElement(cls, () => measure(() { 486 reporter.withCurrentElement(cls, () => measure(() {
485 if (cls.supertypeLoadState == STATE_DONE) return; 487 if (cls.supertypeLoadState == STATE_DONE) return;
486 if (cls.supertypeLoadState == STATE_STARTED) { 488 if (cls.supertypeLoadState == STATE_STARTED) {
487 compiler.reportErrorMessage( 489 reporter.reportErrorMessage(
488 from, 490 from,
489 MessageKind.CYCLIC_CLASS_HIERARCHY, 491 MessageKind.CYCLIC_CLASS_HIERARCHY,
490 {'className': cls.name}); 492 {'className': cls.name});
491 cls.supertypeLoadState = STATE_DONE; 493 cls.supertypeLoadState = STATE_DONE;
492 cls.hasIncompleteHierarchy = true; 494 cls.hasIncompleteHierarchy = true;
493 cls.allSupertypesAndSelf = 495 cls.allSupertypesAndSelf =
494 compiler.objectClass.allSupertypesAndSelf.extendClass( 496 compiler.objectClass.allSupertypesAndSelf.extendClass(
495 cls.computeType(resolution)); 497 cls.computeType(resolution));
496 cls.supertype = cls.allSupertypes.head; 498 cls.supertype = cls.allSupertypes.head;
497 assert(invariant(from, cls.supertype != null, 499 assert(invariant(from, cls.supertype != null,
498 message: 'Missing supertype on cyclic class $cls.')); 500 message: 'Missing supertype on cyclic class $cls.'));
499 cls.interfaces = const Link<DartType>(); 501 cls.interfaces = const Link<DartType>();
500 return; 502 return;
501 } 503 }
502 cls.supertypeLoadState = STATE_STARTED; 504 cls.supertypeLoadState = STATE_STARTED;
503 compiler.withCurrentElement(cls, () { 505 reporter.withCurrentElement(cls, () {
504 // TODO(ahe): Cache the node in cls. 506 // TODO(ahe): Cache the node in cls.
505 cls.parseNode(parsing).accept( 507 cls.parseNode(parsing).accept(
506 new ClassSupertypeResolver(compiler, cls)); 508 new ClassSupertypeResolver(compiler, cls));
507 if (cls.supertypeLoadState != STATE_DONE) { 509 if (cls.supertypeLoadState != STATE_DONE) {
508 cls.supertypeLoadState = STATE_DONE; 510 cls.supertypeLoadState = STATE_DONE;
509 } 511 }
510 }); 512 });
511 })); 513 }));
512 } 514 }
513 515
514 // TODO(johnniwinther): Remove this queue when resolution has been split into 516 // TODO(johnniwinther): Remove this queue when resolution has been split into
515 // syntax and semantic resolution. 517 // syntax and semantic resolution.
516 TypeDeclarationElement currentlyResolvedTypeDeclaration; 518 TypeDeclarationElement currentlyResolvedTypeDeclaration;
517 Queue<ClassElement> pendingClassesToBeResolved = new Queue<ClassElement>(); 519 Queue<ClassElement> pendingClassesToBeResolved = new Queue<ClassElement>();
518 Queue<ClassElement> pendingClassesToBePostProcessed = 520 Queue<ClassElement> pendingClassesToBePostProcessed =
519 new Queue<ClassElement>(); 521 new Queue<ClassElement>();
520 522
521 /// Resolve [element] using [resolveTypeDeclaration]. 523 /// Resolve [element] using [resolveTypeDeclaration].
522 /// 524 ///
523 /// This methods ensure that class declarations encountered through type 525 /// This methods ensure that class declarations encountered through type
524 /// annotations during the resolution of [element] are resolved after 526 /// annotations during the resolution of [element] are resolved after
525 /// [element] has been resolved. 527 /// [element] has been resolved.
526 // TODO(johnniwinther): Encapsulate this functionality in a 528 // TODO(johnniwinther): Encapsulate this functionality in a
527 // 'TypeDeclarationResolver'. 529 // 'TypeDeclarationResolver'.
528 _resolveTypeDeclaration(TypeDeclarationElement element, 530 _resolveTypeDeclaration(TypeDeclarationElement element,
529 resolveTypeDeclaration()) { 531 resolveTypeDeclaration()) {
530 return compiler.withCurrentElement(element, () { 532 return reporter.withCurrentElement(element, () {
531 return measure(() { 533 return measure(() {
532 TypeDeclarationElement previousResolvedTypeDeclaration = 534 TypeDeclarationElement previousResolvedTypeDeclaration =
533 currentlyResolvedTypeDeclaration; 535 currentlyResolvedTypeDeclaration;
534 currentlyResolvedTypeDeclaration = element; 536 currentlyResolvedTypeDeclaration = element;
535 var result = resolveTypeDeclaration(); 537 var result = resolveTypeDeclaration();
536 if (previousResolvedTypeDeclaration == null) { 538 if (previousResolvedTypeDeclaration == null) {
537 do { 539 do {
538 while (!pendingClassesToBeResolved.isEmpty) { 540 while (!pendingClassesToBeResolved.isEmpty) {
539 pendingClassesToBeResolved.removeFirst().ensureResolved(resolution ); 541 pendingClassesToBeResolved.removeFirst().ensureResolved(resolution );
540 } 542 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
577 if (currentlyResolvedTypeDeclaration == null) { 579 if (currentlyResolvedTypeDeclaration == null) {
578 element.ensureResolved(resolution); 580 element.ensureResolved(resolution);
579 } else { 581 } else {
580 pendingClassesToBeResolved.add(element); 582 pendingClassesToBeResolved.add(element);
581 } 583 }
582 } 584 }
583 585
584 void resolveClassInternal(BaseClassElementX element, 586 void resolveClassInternal(BaseClassElementX element,
585 ResolutionRegistry registry) { 587 ResolutionRegistry registry) {
586 if (!element.isPatch) { 588 if (!element.isPatch) {
587 compiler.withCurrentElement(element, () => measure(() { 589 reporter.withCurrentElement(element, () => measure(() {
588 assert(element.resolutionState == STATE_NOT_STARTED); 590 assert(element.resolutionState == STATE_NOT_STARTED);
589 element.resolutionState = STATE_STARTED; 591 element.resolutionState = STATE_STARTED;
590 Node tree = element.parseNode(parsing); 592 Node tree = element.parseNode(parsing);
591 loadSupertypes(element, tree); 593 loadSupertypes(element, tree);
592 594
593 ClassResolverVisitor visitor = 595 ClassResolverVisitor visitor =
594 new ClassResolverVisitor(compiler, element, registry); 596 new ClassResolverVisitor(compiler, element, registry);
595 visitor.visit(tree); 597 visitor.visit(tree);
596 element.resolutionState = STATE_DONE; 598 element.resolutionState = STATE_DONE;
597 compiler.onClassResolved(element); 599 compiler.onClassResolved(element);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 } 632 }
631 } 633 }
632 634
633 // Force resolution of metadata on non-instance members since they may be 635 // Force resolution of metadata on non-instance members since they may be
634 // inspected by the backend while emitting. Metadata on instance members is 636 // inspected by the backend while emitting. Metadata on instance members is
635 // handled as a result of processing instantiated class members in the 637 // handled as a result of processing instantiated class members in the
636 // enqueuer. 638 // enqueuer.
637 // TODO(ahe): Avoid this eager resolution. 639 // TODO(ahe): Avoid this eager resolution.
638 element.forEachMember((_, Element member) { 640 element.forEachMember((_, Element member) {
639 if (!member.isInstanceMember) { 641 if (!member.isInstanceMember) {
640 compiler.withCurrentElement(member, () { 642 reporter.withCurrentElement(member, () {
641 for (MetadataAnnotation metadata in member.implementation.metadata) { 643 for (MetadataAnnotation metadata in member.implementation.metadata) {
642 metadata.ensureResolved(resolution); 644 metadata.ensureResolved(resolution);
643 } 645 }
644 }); 646 });
645 } 647 }
646 }); 648 });
647 649
648 computeClassMember(element, Identifiers.call); 650 computeClassMember(element, Identifiers.call);
649 } 651 }
650 652
(...skipping 12 matching lines...) Expand all
663 } else { 665 } else {
664 checkClassMembers(element); 666 checkClassMembers(element);
665 } 667 }
666 } 668 }
667 669
668 void checkMixinApplication(MixinApplicationElementX mixinApplication) { 670 void checkMixinApplication(MixinApplicationElementX mixinApplication) {
669 Modifiers modifiers = mixinApplication.modifiers; 671 Modifiers modifiers = mixinApplication.modifiers;
670 int illegalFlags = modifiers.flags & ~Modifiers.FLAG_ABSTRACT; 672 int illegalFlags = modifiers.flags & ~Modifiers.FLAG_ABSTRACT;
671 if (illegalFlags != 0) { 673 if (illegalFlags != 0) {
672 Modifiers illegalModifiers = new Modifiers.withFlags(null, illegalFlags); 674 Modifiers illegalModifiers = new Modifiers.withFlags(null, illegalFlags);
673 compiler.reportErrorMessage( 675 reporter.reportErrorMessage(
674 modifiers, 676 modifiers,
675 MessageKind.ILLEGAL_MIXIN_APPLICATION_MODIFIERS, 677 MessageKind.ILLEGAL_MIXIN_APPLICATION_MODIFIERS,
676 {'modifiers': illegalModifiers}); 678 {'modifiers': illegalModifiers});
677 } 679 }
678 680
679 // In case of cyclic mixin applications, the mixin chain will have 681 // In case of cyclic mixin applications, the mixin chain will have
680 // been cut. If so, we have already reported the error to the 682 // been cut. If so, we have already reported the error to the
681 // user so we just return from here. 683 // user so we just return from here.
682 ClassElement mixin = mixinApplication.mixin; 684 ClassElement mixin = mixinApplication.mixin;
683 if (mixin == null) return; 685 if (mixin == null) return;
684 686
685 // Check that we're not trying to use Object as a mixin. 687 // Check that we're not trying to use Object as a mixin.
686 if (mixin.superclass == null) { 688 if (mixin.superclass == null) {
687 compiler.reportErrorMessage( 689 reporter.reportErrorMessage(
688 mixinApplication, 690 mixinApplication,
689 MessageKind.ILLEGAL_MIXIN_OBJECT); 691 MessageKind.ILLEGAL_MIXIN_OBJECT);
690 // Avoid reporting additional errors for the Object class. 692 // Avoid reporting additional errors for the Object class.
691 return; 693 return;
692 } 694 }
693 695
694 if (mixin.isEnumClass) { 696 if (mixin.isEnumClass) {
695 // Mixing in an enum has already caused a compile-time error. 697 // Mixing in an enum has already caused a compile-time error.
696 return; 698 return;
697 } 699 }
698 700
699 // Check that the mixed in class has Object as its superclass. 701 // Check that the mixed in class has Object as its superclass.
700 if (!mixin.superclass.isObject) { 702 if (!mixin.superclass.isObject) {
701 compiler.reportErrorMessage( 703 reporter.reportErrorMessage(
702 mixin, MessageKind.ILLEGAL_MIXIN_SUPERCLASS); 704 mixin, MessageKind.ILLEGAL_MIXIN_SUPERCLASS);
703 } 705 }
704 706
705 // Check that the mixed in class doesn't have any constructors and 707 // Check that the mixed in class doesn't have any constructors and
706 // make sure we aren't mixing in methods that use 'super'. 708 // make sure we aren't mixing in methods that use 'super'.
707 mixin.forEachLocalMember((AstElement member) { 709 mixin.forEachLocalMember((AstElement member) {
708 if (member.isGenerativeConstructor && !member.isSynthesized) { 710 if (member.isGenerativeConstructor && !member.isSynthesized) {
709 compiler.reportErrorMessage( 711 reporter.reportErrorMessage(
710 member, MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR); 712 member, MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR);
711 } else { 713 } else {
712 // Get the resolution tree and check that the resolved member 714 // Get the resolution tree and check that the resolved member
713 // doesn't use 'super'. This is the part of the 'super' mixin 715 // doesn't use 'super'. This is the part of the 'super' mixin
714 // check that happens when a function is resolved before the 716 // check that happens when a function is resolved before the
715 // mixin application has been performed. 717 // mixin application has been performed.
716 // TODO(johnniwinther): Obtain the [TreeElements] for [member] 718 // TODO(johnniwinther): Obtain the [TreeElements] for [member]
717 // differently. 719 // differently.
718 if (compiler.enqueuer.resolution.hasBeenResolved(member)) { 720 if (compiler.enqueuer.resolution.hasBeenResolved(member)) {
719 checkMixinSuperUses( 721 checkMixinSuperUses(
720 member.resolvedAst.elements, 722 member.resolvedAst.elements,
721 mixinApplication, 723 mixinApplication,
722 mixin); 724 mixin);
723 } 725 }
724 } 726 }
725 }); 727 });
726 } 728 }
727 729
728 void checkMixinSuperUses(TreeElements resolutionTree, 730 void checkMixinSuperUses(TreeElements resolutionTree,
729 MixinApplicationElement mixinApplication, 731 MixinApplicationElement mixinApplication,
730 ClassElement mixin) { 732 ClassElement mixin) {
731 // TODO(johnniwinther): Avoid the use of [TreeElements] here. 733 // TODO(johnniwinther): Avoid the use of [TreeElements] here.
732 if (resolutionTree == null) return; 734 if (resolutionTree == null) return;
733 Iterable<Node> superUses = resolutionTree.superUses; 735 Iterable<Node> superUses = resolutionTree.superUses;
734 if (superUses.isEmpty) return; 736 if (superUses.isEmpty) return;
735 DiagnosticMessage error = compiler.createMessage( 737 DiagnosticMessage error = reporter.createMessage(
736 mixinApplication, 738 mixinApplication,
737 MessageKind.ILLEGAL_MIXIN_WITH_SUPER, 739 MessageKind.ILLEGAL_MIXIN_WITH_SUPER,
738 {'className': mixin.name}); 740 {'className': mixin.name});
739 // Show the user the problematic uses of 'super' in the mixin. 741 // Show the user the problematic uses of 'super' in the mixin.
740 List<DiagnosticMessage> infos = <DiagnosticMessage>[]; 742 List<DiagnosticMessage> infos = <DiagnosticMessage>[];
741 for (Node use in superUses) { 743 for (Node use in superUses) {
742 infos.add(compiler.createMessage( 744 infos.add(reporter.createMessage(
743 use, 745 use,
744 MessageKind.ILLEGAL_MIXIN_SUPER_USE)); 746 MessageKind.ILLEGAL_MIXIN_SUPER_USE));
745 } 747 }
746 compiler.reportError(error, infos); 748 reporter.reportError(error, infos);
747 } 749 }
748 750
749 void checkClassMembers(ClassElement cls) { 751 void checkClassMembers(ClassElement cls) {
750 assert(invariant(cls, cls.isDeclaration)); 752 assert(invariant(cls, cls.isDeclaration));
751 if (cls.isObject) return; 753 if (cls.isObject) return;
752 // TODO(johnniwinther): Should this be done on the implementation element as 754 // TODO(johnniwinther): Should this be done on the implementation element as
753 // well? 755 // well?
754 List<Element> constConstructors = <Element>[]; 756 List<Element> constConstructors = <Element>[];
755 List<Element> nonFinalInstanceFields = <Element>[]; 757 List<Element> nonFinalInstanceFields = <Element>[];
756 cls.forEachMember((holder, member) { 758 cls.forEachMember((holder, member) {
757 compiler.withCurrentElement(member, () { 759 reporter.withCurrentElement(member, () {
758 // Perform various checks as side effect of "computing" the type. 760 // Perform various checks as side effect of "computing" the type.
759 member.computeType(resolution); 761 member.computeType(resolution);
760 762
761 // Check modifiers. 763 // Check modifiers.
762 if (member.isFunction && member.modifiers.isFinal) { 764 if (member.isFunction && member.modifiers.isFinal) {
763 compiler.reportErrorMessage( 765 reporter.reportErrorMessage(
764 member, MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER); 766 member, MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER);
765 } 767 }
766 if (member.isConstructor) { 768 if (member.isConstructor) {
767 final mismatchedFlagsBits = 769 final mismatchedFlagsBits =
768 member.modifiers.flags & 770 member.modifiers.flags &
769 (Modifiers.FLAG_STATIC | Modifiers.FLAG_ABSTRACT); 771 (Modifiers.FLAG_STATIC | Modifiers.FLAG_ABSTRACT);
770 if (mismatchedFlagsBits != 0) { 772 if (mismatchedFlagsBits != 0) {
771 final mismatchedFlags = 773 final mismatchedFlags =
772 new Modifiers.withFlags(null, mismatchedFlagsBits); 774 new Modifiers.withFlags(null, mismatchedFlagsBits);
773 compiler.reportErrorMessage( 775 reporter.reportErrorMessage(
774 member, 776 member,
775 MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS, 777 MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS,
776 {'modifiers': mismatchedFlags}); 778 {'modifiers': mismatchedFlags});
777 } 779 }
778 if (member.modifiers.isConst) { 780 if (member.modifiers.isConst) {
779 constConstructors.add(member); 781 constConstructors.add(member);
780 } 782 }
781 } 783 }
782 if (member.isField) { 784 if (member.isField) {
783 if (member.modifiers.isConst && !member.modifiers.isStatic) { 785 if (member.modifiers.isConst && !member.modifiers.isStatic) {
784 compiler.reportErrorMessage( 786 reporter.reportErrorMessage(
785 member, MessageKind.ILLEGAL_CONST_FIELD_MODIFIER); 787 member, MessageKind.ILLEGAL_CONST_FIELD_MODIFIER);
786 } 788 }
787 if (!member.modifiers.isStatic && !member.modifiers.isFinal) { 789 if (!member.modifiers.isStatic && !member.modifiers.isFinal) {
788 nonFinalInstanceFields.add(member); 790 nonFinalInstanceFields.add(member);
789 } 791 }
790 } 792 }
791 checkAbstractField(member); 793 checkAbstractField(member);
792 checkUserDefinableOperator(member); 794 checkUserDefinableOperator(member);
793 }); 795 });
794 }); 796 });
795 if (!constConstructors.isEmpty && !nonFinalInstanceFields.isEmpty) { 797 if (!constConstructors.isEmpty && !nonFinalInstanceFields.isEmpty) {
796 Spannable span = constConstructors.length > 1 798 Spannable span = constConstructors.length > 1
797 ? cls : constConstructors[0]; 799 ? cls : constConstructors[0];
798 DiagnosticMessage error = compiler.createMessage( 800 DiagnosticMessage error = reporter.createMessage(
799 span, 801 span,
800 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS, 802 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS,
801 {'className': cls.name}); 803 {'className': cls.name});
802 List<DiagnosticMessage> infos = <DiagnosticMessage>[]; 804 List<DiagnosticMessage> infos = <DiagnosticMessage>[];
803 if (constConstructors.length > 1) { 805 if (constConstructors.length > 1) {
804 for (Element constructor in constConstructors) { 806 for (Element constructor in constConstructors) {
805 infos.add(compiler.createMessage( 807 infos.add(reporter.createMessage(
806 constructor, 808 constructor,
807 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR)); 809 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR));
808 } 810 }
809 } 811 }
810 for (Element field in nonFinalInstanceFields) { 812 for (Element field in nonFinalInstanceFields) {
811 infos.add(compiler.createMessage( 813 infos.add(reporter.createMessage(
812 field, 814 field,
813 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD)); 815 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD));
814 } 816 }
815 compiler.reportError(error, infos); 817 reporter.reportError(error, infos);
816 } 818 }
817 } 819 }
818 820
819 void checkAbstractField(Element member) { 821 void checkAbstractField(Element member) {
820 // Only check for getters. The test can only fail if there is both a setter 822 // Only check for getters. The test can only fail if there is both a setter
821 // and a getter with the same name, and we only need to check each abstract 823 // and a getter with the same name, and we only need to check each abstract
822 // field once, so we just ignore setters. 824 // field once, so we just ignore setters.
823 if (!member.isGetter) return; 825 if (!member.isGetter) return;
824 826
825 // Find the associated abstract field. 827 // Find the associated abstract field.
826 ClassElement classElement = member.enclosingClass; 828 ClassElement classElement = member.enclosingClass;
827 Element lookupElement = classElement.lookupLocalMember(member.name); 829 Element lookupElement = classElement.lookupLocalMember(member.name);
828 if (lookupElement == null) { 830 if (lookupElement == null) {
829 compiler.internalError(member, 831 reporter.internalError(member,
830 "No abstract field for accessor"); 832 "No abstract field for accessor");
831 } else if (!identical(lookupElement.kind, ElementKind.ABSTRACT_FIELD)) { 833 } else if (!identical(lookupElement.kind, ElementKind.ABSTRACT_FIELD)) {
832 if (lookupElement.isErroneous || lookupElement.isAmbiguous) return; 834 if (lookupElement.isErroneous || lookupElement.isAmbiguous) return;
833 compiler.internalError(member, 835 reporter.internalError(member,
834 "Inaccessible abstract field for accessor"); 836 "Inaccessible abstract field for accessor");
835 } 837 }
836 AbstractFieldElement field = lookupElement; 838 AbstractFieldElement field = lookupElement;
837 839
838 GetterElementX getter = field.getter; 840 GetterElementX getter = field.getter;
839 if (getter == null) return; 841 if (getter == null) return;
840 SetterElementX setter = field.setter; 842 SetterElementX setter = field.setter;
841 if (setter == null) return; 843 if (setter == null) return;
842 int getterFlags = getter.modifiers.flags | Modifiers.FLAG_ABSTRACT; 844 int getterFlags = getter.modifiers.flags | Modifiers.FLAG_ABSTRACT;
843 int setterFlags = setter.modifiers.flags | Modifiers.FLAG_ABSTRACT; 845 int setterFlags = setter.modifiers.flags | Modifiers.FLAG_ABSTRACT;
844 if (!identical(getterFlags, setterFlags)) { 846 if (!identical(getterFlags, setterFlags)) {
845 final mismatchedFlags = 847 final mismatchedFlags =
846 new Modifiers.withFlags(null, getterFlags ^ setterFlags); 848 new Modifiers.withFlags(null, getterFlags ^ setterFlags);
847 compiler.reportErrorMessage( 849 reporter.reportErrorMessage(
848 field.getter, 850 field.getter,
849 MessageKind.GETTER_MISMATCH, 851 MessageKind.GETTER_MISMATCH,
850 {'modifiers': mismatchedFlags}); 852 {'modifiers': mismatchedFlags});
851 compiler.reportErrorMessage( 853 reporter.reportErrorMessage(
852 field.setter, 854 field.setter,
853 MessageKind.SETTER_MISMATCH, 855 MessageKind.SETTER_MISMATCH,
854 {'modifiers': mismatchedFlags}); 856 {'modifiers': mismatchedFlags});
855 } 857 }
856 } 858 }
857 859
858 void checkUserDefinableOperator(Element member) { 860 void checkUserDefinableOperator(Element member) {
859 FunctionElement function = member.asFunctionElement(); 861 FunctionElement function = member.asFunctionElement();
860 if (function == null) return; 862 if (function == null) return;
861 String value = member.name; 863 String value = member.name;
(...skipping 15 matching lines...) Expand all
877 messageKind = MessageKind.UNARY_OPERATOR_BAD_ARITY; 879 messageKind = MessageKind.UNARY_OPERATOR_BAD_ARITY;
878 requiredParameterCount = 0; 880 requiredParameterCount = 0;
879 } else if (isBinaryOperator(value)) { 881 } else if (isBinaryOperator(value)) {
880 messageKind = MessageKind.BINARY_OPERATOR_BAD_ARITY; 882 messageKind = MessageKind.BINARY_OPERATOR_BAD_ARITY;
881 requiredParameterCount = 1; 883 requiredParameterCount = 1;
882 if (identical(value, '==')) checkOverrideHashCode(member); 884 if (identical(value, '==')) checkOverrideHashCode(member);
883 } else if (isTernaryOperator(value)) { 885 } else if (isTernaryOperator(value)) {
884 messageKind = MessageKind.TERNARY_OPERATOR_BAD_ARITY; 886 messageKind = MessageKind.TERNARY_OPERATOR_BAD_ARITY;
885 requiredParameterCount = 2; 887 requiredParameterCount = 2;
886 } else { 888 } else {
887 compiler.internalError(function, 889 reporter.internalError(function,
888 'Unexpected user defined operator $value'); 890 'Unexpected user defined operator $value');
889 } 891 }
890 checkArity(function, requiredParameterCount, messageKind, isMinus); 892 checkArity(function, requiredParameterCount, messageKind, isMinus);
891 } 893 }
892 894
893 void checkOverrideHashCode(FunctionElement operatorEquals) { 895 void checkOverrideHashCode(FunctionElement operatorEquals) {
894 if (operatorEquals.isAbstract) return; 896 if (operatorEquals.isAbstract) return;
895 ClassElement cls = operatorEquals.enclosingClass; 897 ClassElement cls = operatorEquals.enclosingClass;
896 Element hashCodeImplementation = 898 Element hashCodeImplementation =
897 cls.lookupLocalMember('hashCode'); 899 cls.lookupLocalMember('hashCode');
898 if (hashCodeImplementation != null) return; 900 if (hashCodeImplementation != null) return;
899 compiler.reportHintMessage( 901 reporter.reportHintMessage(
900 operatorEquals, MessageKind.OVERRIDE_EQUALS_NOT_HASH_CODE, 902 operatorEquals, MessageKind.OVERRIDE_EQUALS_NOT_HASH_CODE,
901 {'class': cls.name}); 903 {'class': cls.name});
902 } 904 }
903 905
904 void checkArity(FunctionElement function, 906 void checkArity(FunctionElement function,
905 int requiredParameterCount, MessageKind messageKind, 907 int requiredParameterCount, MessageKind messageKind,
906 bool isMinus) { 908 bool isMinus) {
907 FunctionExpression node = function.node; 909 FunctionExpression node = function.node;
908 FunctionSignature signature = function.functionSignature; 910 FunctionSignature signature = function.functionSignature;
909 if (signature.requiredParameterCount != requiredParameterCount) { 911 if (signature.requiredParameterCount != requiredParameterCount) {
(...skipping 20 matching lines...) Expand all
930 // int operator -(a, b) {} 932 // int operator -(a, b) {}
931 // ^ 933 // ^
932 // 934 //
933 // since the correction might not be to remove 'b' but instead to 935 // since the correction might not be to remove 'b' but instead to
934 // remove 'a, b'. 936 // remove 'a, b'.
935 errorNode = node.parameters; 937 errorNode = node.parameters;
936 } else { 938 } else {
937 errorNode = node.parameters.nodes.skip(requiredParameterCount).head; 939 errorNode = node.parameters.nodes.skip(requiredParameterCount).head;
938 } 940 }
939 } 941 }
940 compiler.reportErrorMessage( 942 reporter.reportErrorMessage(
941 errorNode, messageKind, {'operatorName': function.name}); 943 errorNode, messageKind, {'operatorName': function.name});
942 } 944 }
943 if (signature.optionalParameterCount != 0) { 945 if (signature.optionalParameterCount != 0) {
944 Node errorNode = 946 Node errorNode =
945 node.parameters.nodes.skip(signature.requiredParameterCount).head; 947 node.parameters.nodes.skip(signature.requiredParameterCount).head;
946 if (signature.optionalParametersAreNamed) { 948 if (signature.optionalParametersAreNamed) {
947 compiler.reportErrorMessage( 949 reporter.reportErrorMessage(
948 errorNode, 950 errorNode,
949 MessageKind.OPERATOR_NAMED_PARAMETERS, 951 MessageKind.OPERATOR_NAMED_PARAMETERS,
950 {'operatorName': function.name}); 952 {'operatorName': function.name});
951 } else { 953 } else {
952 compiler.reportErrorMessage( 954 reporter.reportErrorMessage(
953 errorNode, 955 errorNode,
954 MessageKind.OPERATOR_OPTIONAL_PARAMETERS, 956 MessageKind.OPERATOR_OPTIONAL_PARAMETERS,
955 {'operatorName': function.name}); 957 {'operatorName': function.name});
956 } 958 }
957 } 959 }
958 } 960 }
959 961
960 reportErrorWithContext(Element errorneousElement, 962 reportErrorWithContext(Element errorneousElement,
961 MessageKind errorMessage, 963 MessageKind errorMessage,
962 Element contextElement, 964 Element contextElement,
963 MessageKind contextMessage) { 965 MessageKind contextMessage) {
964 compiler.reportError( 966 reporter.reportError(
965 compiler.createMessage( 967 reporter.createMessage(
966 errorneousElement, 968 errorneousElement,
967 errorMessage, 969 errorMessage,
968 {'memberName': contextElement.name, 970 {'memberName': contextElement.name,
969 'className': contextElement.enclosingClass.name}), 971 'className': contextElement.enclosingClass.name}),
970 <DiagnosticMessage>[ 972 <DiagnosticMessage>[
971 compiler.createMessage(contextElement, contextMessage), 973 reporter.createMessage(contextElement, contextMessage),
972 ]); 974 ]);
973 } 975 }
974 976
975 977
976 FunctionSignature resolveSignature(FunctionElementX element) { 978 FunctionSignature resolveSignature(FunctionElementX element) {
977 MessageKind defaultValuesError = null; 979 MessageKind defaultValuesError = null;
978 if (element.isFactoryConstructor) { 980 if (element.isFactoryConstructor) {
979 FunctionExpression body = element.parseNode(parsing); 981 FunctionExpression body = element.parseNode(parsing);
980 if (body.isRedirectingFactory) { 982 if (body.isRedirectingFactory) {
981 defaultValuesError = MessageKind.REDIRECTING_FACTORY_WITH_DEFAULT; 983 defaultValuesError = MessageKind.REDIRECTING_FACTORY_WITH_DEFAULT;
982 } 984 }
983 } 985 }
984 return compiler.withCurrentElement(element, () { 986 return reporter.withCurrentElement(element, () {
985 FunctionExpression node = element.parseNode(parsing); 987 FunctionExpression node = element.parseNode(parsing);
986 return measure(() => SignatureResolver.analyze( 988 return measure(() => SignatureResolver.analyze(
987 compiler, node.parameters, node.returnType, element, 989 compiler, node.parameters, node.returnType, element,
988 new ResolutionRegistry(compiler, _ensureTreeElements(element)), 990 new ResolutionRegistry(compiler, _ensureTreeElements(element)),
989 defaultValuesError: defaultValuesError, 991 defaultValuesError: defaultValuesError,
990 createRealParameters: true)); 992 createRealParameters: true));
991 }); 993 });
992 } 994 }
993 995
994 WorldImpact resolveTypedef(TypedefElementX element) { 996 WorldImpact resolveTypedef(TypedefElementX element) {
995 if (element.isResolved) return const WorldImpact(); 997 if (element.isResolved) return const WorldImpact();
996 compiler.world.allTypedefs.add(element); 998 compiler.world.allTypedefs.add(element);
997 return _resolveTypeDeclaration(element, () { 999 return _resolveTypeDeclaration(element, () {
998 ResolutionRegistry registry = new ResolutionRegistry( 1000 ResolutionRegistry registry = new ResolutionRegistry(
999 compiler, _ensureTreeElements(element)); 1001 compiler, _ensureTreeElements(element));
1000 return compiler.withCurrentElement(element, () { 1002 return reporter.withCurrentElement(element, () {
1001 return measure(() { 1003 return measure(() {
1002 assert(element.resolutionState == STATE_NOT_STARTED); 1004 assert(element.resolutionState == STATE_NOT_STARTED);
1003 element.resolutionState = STATE_STARTED; 1005 element.resolutionState = STATE_STARTED;
1004 Typedef node = element.parseNode(parsing); 1006 Typedef node = element.parseNode(parsing);
1005 TypedefResolverVisitor visitor = 1007 TypedefResolverVisitor visitor =
1006 new TypedefResolverVisitor(compiler, element, registry); 1008 new TypedefResolverVisitor(compiler, element, registry);
1007 visitor.visit(node); 1009 visitor.visit(node);
1008 element.resolutionState = STATE_DONE; 1010 element.resolutionState = STATE_DONE;
1009 return registry.worldImpact; 1011 return registry.worldImpact;
1010 }); 1012 });
1011 }); 1013 });
1012 }); 1014 });
1013 } 1015 }
1014 1016
1015 void resolveMetadataAnnotation(MetadataAnnotationX annotation) { 1017 void resolveMetadataAnnotation(MetadataAnnotationX annotation) {
1016 compiler.withCurrentElement(annotation.annotatedElement, () => measure(() { 1018 reporter.withCurrentElement(annotation.annotatedElement, () => measure(() {
1017 assert(annotation.resolutionState == STATE_NOT_STARTED); 1019 assert(annotation.resolutionState == STATE_NOT_STARTED);
1018 annotation.resolutionState = STATE_STARTED; 1020 annotation.resolutionState = STATE_STARTED;
1019 1021
1020 Node node = annotation.parseNode(parsing); 1022 Node node = annotation.parseNode(parsing);
1021 Element annotatedElement = annotation.annotatedElement; 1023 Element annotatedElement = annotation.annotatedElement;
1022 AnalyzableElement context = annotatedElement.analyzableElement; 1024 AnalyzableElement context = annotatedElement.analyzableElement;
1023 ClassElement classElement = annotatedElement.enclosingClass; 1025 ClassElement classElement = annotatedElement.enclosingClass;
1024 if (classElement != null) { 1026 if (classElement != null) {
1025 // The annotation is resolved in the scope of [classElement]. 1027 // The annotation is resolved in the scope of [classElement].
1026 classElement.ensureResolved(resolution); 1028 classElement.ensureResolved(resolution);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1073 TreeElements get treeElements { 1075 TreeElements get treeElements {
1074 assert(invariant(this, _treeElements !=null, 1076 assert(invariant(this, _treeElements !=null,
1075 message: "TreeElements have not been computed for $this.")); 1077 message: "TreeElements have not been computed for $this."));
1076 return _treeElements; 1078 return _treeElements;
1077 } 1079 }
1078 1080
1079 void reuseElement() { 1081 void reuseElement() {
1080 _treeElements = null; 1082 _treeElements = null;
1081 } 1083 }
1082 } 1084 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698