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

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

Issue 1363993004: Report info messages together with their error, warning, or hint. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Updated cf. comment. Created 5 years, 3 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/tasks.dart' show 11 import '../common/tasks.dart' show
12 CompilerTask, 12 CompilerTask,
13 DeferredAction; 13 DeferredAction;
14 import '../compiler.dart' show 14 import '../compiler.dart' show
15 Compiler; 15 Compiler;
16 import '../compile_time_constants.dart' show 16 import '../compile_time_constants.dart' show
17 ConstantCompiler; 17 ConstantCompiler;
18 import '../constants/values.dart' show 18 import '../constants/values.dart' show
19 ConstantValue; 19 ConstantValue;
20 import '../dart_types.dart'; 20 import '../dart_types.dart';
21 import '../diagnostics/diagnostic_listener.dart' show
22 DiagnosticMessage;
21 import '../diagnostics/invariant.dart' show 23 import '../diagnostics/invariant.dart' show
22 invariant; 24 invariant;
23 import '../diagnostics/messages.dart' show 25 import '../diagnostics/messages.dart' show
24 MessageKind; 26 MessageKind;
25 import '../diagnostics/spannable.dart' show 27 import '../diagnostics/spannable.dart' show
26 Spannable; 28 Spannable;
27 import '../elements/elements.dart'; 29 import '../elements/elements.dart';
28 import '../elements/modelx.dart' show 30 import '../elements/modelx.dart' show
29 BaseClassElementX, 31 BaseClassElementX,
30 BaseFunctionElementX, 32 BaseFunctionElementX,
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 FunctionElement redirection) { 116 FunctionElement redirection) {
115 assert(invariant(node, constructor.isImplementation, 117 assert(invariant(node, constructor.isImplementation,
116 message: 'Redirecting constructors must be resolved on implementation ' 118 message: 'Redirecting constructors must be resolved on implementation '
117 'elements.')); 119 'elements.'));
118 Setlet<FunctionElement> seen = new Setlet<FunctionElement>(); 120 Setlet<FunctionElement> seen = new Setlet<FunctionElement>();
119 seen.add(constructor); 121 seen.add(constructor);
120 while (redirection != null) { 122 while (redirection != null) {
121 // Ensure that we follow redirections through implementation elements. 123 // Ensure that we follow redirections through implementation elements.
122 redirection = redirection.implementation; 124 redirection = redirection.implementation;
123 if (seen.contains(redirection)) { 125 if (seen.contains(redirection)) {
124 resolver.visitor.error(node, MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE); 126 compiler.reportErrorMessage(
127 node, MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE);
125 return; 128 return;
126 } 129 }
127 seen.add(redirection); 130 seen.add(redirection);
128 redirection = resolver.visitor.resolveConstructorRedirection(redirection); 131 redirection = resolver.visitor.resolveConstructorRedirection(redirection);
129 } 132 }
130 } 133 }
131 134
132 static void processAsyncMarker(Compiler compiler, 135 static void processAsyncMarker(Compiler compiler,
133 BaseFunctionElementX element, 136 BaseFunctionElementX element,
134 ResolutionRegistry registry) { 137 ResolutionRegistry registry) {
135 FunctionExpression functionExpression = element.node; 138 FunctionExpression functionExpression = element.node;
136 AsyncModifier asyncModifier = functionExpression.asyncModifier; 139 AsyncModifier asyncModifier = functionExpression.asyncModifier;
137 if (asyncModifier != null) { 140 if (asyncModifier != null) {
138 141
139 if (asyncModifier.isAsynchronous) { 142 if (asyncModifier.isAsynchronous) {
140 element.asyncMarker = asyncModifier.isYielding 143 element.asyncMarker = asyncModifier.isYielding
141 ? AsyncMarker.ASYNC_STAR : AsyncMarker.ASYNC; 144 ? AsyncMarker.ASYNC_STAR : AsyncMarker.ASYNC;
142 } else { 145 } else {
143 element.asyncMarker = AsyncMarker.SYNC_STAR; 146 element.asyncMarker = AsyncMarker.SYNC_STAR;
144 } 147 }
145 if (element.isAbstract) { 148 if (element.isAbstract) {
146 compiler.reportError(asyncModifier, 149 compiler.reportErrorMessage(
150 asyncModifier,
147 MessageKind.ASYNC_MODIFIER_ON_ABSTRACT_METHOD, 151 MessageKind.ASYNC_MODIFIER_ON_ABSTRACT_METHOD,
148 {'modifier': element.asyncMarker}); 152 {'modifier': element.asyncMarker});
149 } else if (element.isConstructor) { 153 } else if (element.isConstructor) {
150 compiler.reportError(asyncModifier, 154 compiler.reportErrorMessage(
155 asyncModifier,
151 MessageKind.ASYNC_MODIFIER_ON_CONSTRUCTOR, 156 MessageKind.ASYNC_MODIFIER_ON_CONSTRUCTOR,
152 {'modifier': element.asyncMarker}); 157 {'modifier': element.asyncMarker});
153 } else { 158 } else {
154 if (element.isSetter) { 159 if (element.isSetter) {
155 compiler.reportError(asyncModifier, 160 compiler.reportErrorMessage(
161 asyncModifier,
156 MessageKind.ASYNC_MODIFIER_ON_SETTER, 162 MessageKind.ASYNC_MODIFIER_ON_SETTER,
157 {'modifier': element.asyncMarker}); 163 {'modifier': element.asyncMarker});
158 164
159 } 165 }
160 if (functionExpression.body.asReturn() != null && 166 if (functionExpression.body.asReturn() != null &&
161 element.asyncMarker.isYielding) { 167 element.asyncMarker.isYielding) {
162 compiler.reportError(asyncModifier, 168 compiler.reportErrorMessage(
169 asyncModifier,
163 MessageKind.YIELDING_MODIFIER_ON_ARROW_BODY, 170 MessageKind.YIELDING_MODIFIER_ON_ARROW_BODY,
164 {'modifier': element.asyncMarker}); 171 {'modifier': element.asyncMarker});
165 } 172 }
166 } 173 }
167 registry.registerAsyncMarker(element); 174 registry.registerAsyncMarker(element);
168 switch (element.asyncMarker) { 175 switch (element.asyncMarker) {
169 case AsyncMarker.ASYNC: 176 case AsyncMarker.ASYNC:
170 compiler.futureClass.ensureResolved(compiler); 177 compiler.futureClass.ensureResolved(compiler);
171 break; 178 break;
172 case AsyncMarker.ASYNC_STAR: 179 case AsyncMarker.ASYNC_STAR:
(...skipping 12 matching lines...) Expand all
185 if (classElement.isNative) return true; 192 if (classElement.isNative) return true;
186 classElement = classElement.superclass; 193 classElement = classElement.superclass;
187 } 194 }
188 return false; 195 return false;
189 } 196 }
190 197
191 WorldImpact resolveMethodElementImplementation( 198 WorldImpact resolveMethodElementImplementation(
192 FunctionElement element, FunctionExpression tree) { 199 FunctionElement element, FunctionExpression tree) {
193 return compiler.withCurrentElement(element, () { 200 return compiler.withCurrentElement(element, () {
194 if (element.isExternal && tree.hasBody()) { 201 if (element.isExternal && tree.hasBody()) {
195 error(element, 202 compiler.reportErrorMessage(
203 element,
196 MessageKind.EXTERNAL_WITH_BODY, 204 MessageKind.EXTERNAL_WITH_BODY,
197 {'functionName': element.name}); 205 {'functionName': element.name});
198 } 206 }
199 if (element.isConstructor) { 207 if (element.isConstructor) {
200 if (tree.returnType != null) { 208 if (tree.returnType != null) {
201 error(tree, MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE); 209 compiler.reportErrorMessage(
210 tree, MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE);
202 } 211 }
203 if (element.isConst && 212 if (element.isConst &&
204 tree.hasBody() && 213 tree.hasBody() &&
205 !tree.isRedirectingFactory) { 214 !tree.isRedirectingFactory) {
206 error(tree, MessageKind.CONST_CONSTRUCTOR_HAS_BODY); 215 compiler.reportErrorMessage(
216 tree, MessageKind.CONST_CONSTRUCTOR_HAS_BODY);
207 } 217 }
208 } 218 }
209 219
210 ResolverVisitor visitor = visitorFor(element); 220 ResolverVisitor visitor = visitorFor(element);
211 ResolutionRegistry registry = visitor.registry; 221 ResolutionRegistry registry = visitor.registry;
212 registry.defineFunction(tree, element); 222 registry.defineFunction(tree, element);
213 visitor.setupFunction(tree, element); 223 visitor.setupFunction(tree, element);
214 processAsyncMarker(compiler, element, registry); 224 processAsyncMarker(compiler, element, registry);
215 225
216 if (element.isGenerativeConstructor) { 226 if (element.isGenerativeConstructor) {
217 // Even if there is no initializer list we still have to do the 227 // Even if there is no initializer list we still have to do the
218 // resolution in case there is an implicit super constructor call. 228 // resolution in case there is an implicit super constructor call.
219 InitializerResolver resolver = 229 InitializerResolver resolver =
220 new InitializerResolver(visitor, element, tree); 230 new InitializerResolver(visitor, element, tree);
221 FunctionElement redirection = resolver.resolveInitializers(); 231 FunctionElement redirection = resolver.resolveInitializers();
222 if (redirection != null) { 232 if (redirection != null) {
223 resolveRedirectingConstructor(resolver, tree, element, redirection); 233 resolveRedirectingConstructor(resolver, tree, element, redirection);
224 } 234 }
225 } else if (tree.initializers != null) { 235 } else if (tree.initializers != null) {
226 error(tree, MessageKind.FUNCTION_WITH_INITIALIZER); 236 compiler.reportErrorMessage(
237 tree, MessageKind.FUNCTION_WITH_INITIALIZER);
227 } 238 }
228 239
229 if (!compiler.analyzeSignaturesOnly || tree.isRedirectingFactory) { 240 if (!compiler.analyzeSignaturesOnly || tree.isRedirectingFactory) {
230 // We need to analyze the redirecting factory bodies to ensure that 241 // We need to analyze the redirecting factory bodies to ensure that
231 // we can analyze compile-time constants. 242 // we can analyze compile-time constants.
232 visitor.visit(tree.body); 243 visitor.visit(tree.body);
233 } 244 }
234 245
235 // Get the resolution tree and check that the resolved 246 // Get the resolution tree and check that the resolved
236 // function doesn't use 'super' if it is mixed into another 247 // function doesn't use 'super' if it is mixed into another
237 // class. This is the part of the 'super' mixin check that 248 // class. This is the part of the 'super' mixin check that
238 // happens when a function is resolved after the mixin 249 // happens when a function is resolved after the mixin
239 // application has been performed. 250 // application has been performed.
240 TreeElements resolutionTree = registry.mapping; 251 TreeElements resolutionTree = registry.mapping;
241 ClassElement enclosingClass = element.enclosingClass; 252 ClassElement enclosingClass = element.enclosingClass;
242 if (enclosingClass != null) { 253 if (enclosingClass != null) {
243 // TODO(johnniwinther): Find another way to obtain mixin uses. 254 // TODO(johnniwinther): Find another way to obtain mixin uses.
244 Iterable<MixinApplicationElement> mixinUses = 255 Iterable<MixinApplicationElement> mixinUses =
245 compiler.world.allMixinUsesOf(enclosingClass); 256 compiler.world.allMixinUsesOf(enclosingClass);
246 ClassElement mixin = enclosingClass; 257 ClassElement mixin = enclosingClass;
247 for (MixinApplicationElement mixinApplication in mixinUses) { 258 for (MixinApplicationElement mixinApplication in mixinUses) {
248 checkMixinSuperUses(resolutionTree, mixinApplication, mixin); 259 checkMixinSuperUses(resolutionTree, mixinApplication, mixin);
249 } 260 }
250 } 261 }
251 262
252 // TODO(9631): support noSuchMethod on native classes. 263 // TODO(9631): support noSuchMethod on native classes.
253 if (Elements.isInstanceMethod(element) && 264 if (Elements.isInstanceMethod(element) &&
254 element.name == Identifiers.noSuchMethod_ && 265 element.name == Identifiers.noSuchMethod_ &&
255 _isNativeClassOrExtendsNativeClass(enclosingClass)) { 266 _isNativeClassOrExtendsNativeClass(enclosingClass)) {
256 error(tree, MessageKind.NO_SUCH_METHOD_IN_NATIVE); 267 compiler.reportErrorMessage(
268 tree, MessageKind.NO_SUCH_METHOD_IN_NATIVE);
257 } 269 }
258 270
259 return registry.worldImpact; 271 return registry.worldImpact;
260 }); 272 });
261 273
262 } 274 }
263 275
264 WorldImpact resolveMethodElement(FunctionElementX element) { 276 WorldImpact resolveMethodElement(FunctionElementX element) {
265 assert(invariant(element, element.isDeclaration)); 277 assert(invariant(element, element.isDeclaration));
266 return compiler.withCurrentElement(element, () { 278 return compiler.withCurrentElement(element, () {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 /// this library). 325 /// this library).
314 ResolverVisitor visitorFor(Element element, {bool useEnclosingScope: false}) { 326 ResolverVisitor visitorFor(Element element, {bool useEnclosingScope: false}) {
315 return new ResolverVisitor(compiler, element, 327 return new ResolverVisitor(compiler, element,
316 new ResolutionRegistry(compiler, _ensureTreeElements(element)), 328 new ResolutionRegistry(compiler, _ensureTreeElements(element)),
317 useEnclosingScope: useEnclosingScope); 329 useEnclosingScope: useEnclosingScope);
318 } 330 }
319 331
320 WorldImpact resolveField(FieldElementX element) { 332 WorldImpact resolveField(FieldElementX element) {
321 VariableDefinitions tree = element.parseNode(compiler); 333 VariableDefinitions tree = element.parseNode(compiler);
322 if(element.modifiers.isStatic && element.isTopLevel) { 334 if(element.modifiers.isStatic && element.isTopLevel) {
323 error(element.modifiers.getStatic(), 335 compiler.reportErrorMessage(
324 MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC); 336 element.modifiers.getStatic(),
337 MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC);
325 } 338 }
326 ResolverVisitor visitor = visitorFor(element); 339 ResolverVisitor visitor = visitorFor(element);
327 ResolutionRegistry registry = visitor.registry; 340 ResolutionRegistry registry = visitor.registry;
328 // TODO(johnniwinther): Maybe remove this when placeholderCollector migrates 341 // TODO(johnniwinther): Maybe remove this when placeholderCollector migrates
329 // to the backend ast. 342 // to the backend ast.
330 registry.defineElement(tree.definitions.nodes.head, element); 343 registry.defineElement(tree.definitions.nodes.head, element);
331 // TODO(johnniwinther): Share the resolved type between all variables 344 // TODO(johnniwinther): Share the resolved type between all variables
332 // declared in the same declaration. 345 // declared in the same declaration.
333 if (tree.type != null) { 346 if (tree.type != null) {
334 element.variables.type = visitor.resolveTypeAnnotation(tree.type); 347 element.variables.type = visitor.resolveTypeAnnotation(tree.type);
335 } else { 348 } else {
336 element.variables.type = const DynamicType(); 349 element.variables.type = const DynamicType();
337 } 350 }
338 351
339 Expression initializer = element.initializer; 352 Expression initializer = element.initializer;
340 Modifiers modifiers = element.modifiers; 353 Modifiers modifiers = element.modifiers;
341 if (initializer != null) { 354 if (initializer != null) {
342 // TODO(johnniwinther): Avoid analyzing initializers if 355 // TODO(johnniwinther): Avoid analyzing initializers if
343 // [Compiler.analyzeSignaturesOnly] is set. 356 // [Compiler.analyzeSignaturesOnly] is set.
344 visitor.visit(initializer); 357 visitor.visit(initializer);
345 } else if (modifiers.isConst) { 358 } else if (modifiers.isConst) {
346 compiler.reportError(element, MessageKind.CONST_WITHOUT_INITIALIZER); 359 compiler.reportErrorMessage(
360 element, MessageKind.CONST_WITHOUT_INITIALIZER);
347 } else if (modifiers.isFinal && !element.isInstanceMember) { 361 } else if (modifiers.isFinal && !element.isInstanceMember) {
348 compiler.reportError(element, MessageKind.FINAL_WITHOUT_INITIALIZER); 362 compiler.reportErrorMessage(
363 element, MessageKind.FINAL_WITHOUT_INITIALIZER);
349 } else { 364 } else {
350 registry.registerInstantiatedClass(compiler.nullClass); 365 registry.registerInstantiatedClass(compiler.nullClass);
351 } 366 }
352 367
353 if (Elements.isStaticOrTopLevelField(element)) { 368 if (Elements.isStaticOrTopLevelField(element)) {
354 visitor.addDeferredAction(element, () { 369 visitor.addDeferredAction(element, () {
355 if (element.modifiers.isConst) { 370 if (element.modifiers.isConst) {
356 element.constant = constantCompiler.compileConstant(element); 371 element.constant = constantCompiler.compileConstant(element);
357 } else { 372 } else {
358 constantCompiler.compileVariable(element); 373 constantCompiler.compileVariable(element);
(...skipping 10 matching lines...) Expand all
369 384
370 // Perform various checks as side effect of "computing" the type. 385 // Perform various checks as side effect of "computing" the type.
371 element.computeType(compiler); 386 element.computeType(compiler);
372 387
373 return registry.worldImpact; 388 return registry.worldImpact;
374 } 389 }
375 390
376 DartType resolveTypeAnnotation(Element element, TypeAnnotation annotation) { 391 DartType resolveTypeAnnotation(Element element, TypeAnnotation annotation) {
377 DartType type = resolveReturnType(element, annotation); 392 DartType type = resolveReturnType(element, annotation);
378 if (type.isVoid) { 393 if (type.isVoid) {
379 error(annotation, MessageKind.VOID_NOT_ALLOWED); 394 compiler.reportErrorMessage(
395 annotation, MessageKind.VOID_NOT_ALLOWED);
380 } 396 }
381 return type; 397 return type;
382 } 398 }
383 399
384 DartType resolveReturnType(Element element, TypeAnnotation annotation) { 400 DartType resolveReturnType(Element element, TypeAnnotation annotation) {
385 if (annotation == null) return const DynamicType(); 401 if (annotation == null) return const DynamicType();
386 DartType result = visitorFor(element).resolveTypeAnnotation(annotation); 402 DartType result = visitorFor(element).resolveTypeAnnotation(annotation);
387 if (result == null) { 403 if (result == null) {
388 // TODO(karklose): warning. 404 // TODO(karklose): warning.
389 return const DynamicType(); 405 return const DynamicType();
(...skipping 13 matching lines...) Expand all
403 targetType = target.effectiveTargetType; 419 targetType = target.effectiveTargetType;
404 assert(invariant(target, targetType != null, 420 assert(invariant(target, targetType != null,
405 message: 'Redirection target type has not been computed for ' 421 message: 'Redirection target type has not been computed for '
406 '$target')); 422 '$target'));
407 target = target.internalEffectiveTarget; 423 target = target.internalEffectiveTarget;
408 break; 424 break;
409 } 425 }
410 426
411 Element nextTarget = target.immediateRedirectionTarget; 427 Element nextTarget = target.immediateRedirectionTarget;
412 if (seen.contains(nextTarget)) { 428 if (seen.contains(nextTarget)) {
413 error(node, MessageKind.CYCLIC_REDIRECTING_FACTORY); 429 compiler.reportErrorMessage(
430 node, MessageKind.CYCLIC_REDIRECTING_FACTORY);
414 targetType = target.enclosingClass.thisType; 431 targetType = target.enclosingClass.thisType;
415 break; 432 break;
416 } 433 }
417 seen.add(target); 434 seen.add(target);
418 target = nextTarget; 435 target = nextTarget;
419 } 436 }
420 437
421 if (targetType == null) { 438 if (targetType == null) {
422 assert(!target.isRedirectingFactory); 439 assert(!target.isRedirectingFactory);
423 targetType = target.enclosingClass.thisType; 440 targetType = target.enclosingClass.thisType;
(...skipping 28 matching lines...) Expand all
452 /** 469 /**
453 * Load and resolve the supertypes of [cls]. 470 * Load and resolve the supertypes of [cls].
454 * 471 *
455 * Warning: do not call this method directly. It should only be 472 * Warning: do not call this method directly. It should only be
456 * called by [resolveClass] and [ClassSupertypeResolver]. 473 * called by [resolveClass] and [ClassSupertypeResolver].
457 */ 474 */
458 void loadSupertypes(BaseClassElementX cls, Spannable from) { 475 void loadSupertypes(BaseClassElementX cls, Spannable from) {
459 compiler.withCurrentElement(cls, () => measure(() { 476 compiler.withCurrentElement(cls, () => measure(() {
460 if (cls.supertypeLoadState == STATE_DONE) return; 477 if (cls.supertypeLoadState == STATE_DONE) return;
461 if (cls.supertypeLoadState == STATE_STARTED) { 478 if (cls.supertypeLoadState == STATE_STARTED) {
462 compiler.reportError(from, MessageKind.CYCLIC_CLASS_HIERARCHY, 479 compiler.reportErrorMessage(
463 {'className': cls.name}); 480 from,
481 MessageKind.CYCLIC_CLASS_HIERARCHY,
482 {'className': cls.name});
464 cls.supertypeLoadState = STATE_DONE; 483 cls.supertypeLoadState = STATE_DONE;
465 cls.hasIncompleteHierarchy = true; 484 cls.hasIncompleteHierarchy = true;
466 cls.allSupertypesAndSelf = 485 cls.allSupertypesAndSelf =
467 compiler.objectClass.allSupertypesAndSelf.extendClass( 486 compiler.objectClass.allSupertypesAndSelf.extendClass(
468 cls.computeType(compiler)); 487 cls.computeType(compiler));
469 cls.supertype = cls.allSupertypes.head; 488 cls.supertype = cls.allSupertypes.head;
470 assert(invariant(from, cls.supertype != null, 489 assert(invariant(from, cls.supertype != null,
471 message: 'Missing supertype on cyclic class $cls.')); 490 message: 'Missing supertype on cyclic class $cls.'));
472 cls.interfaces = const Link<DartType>(); 491 cls.interfaces = const Link<DartType>();
473 return; 492 return;
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
636 } else { 655 } else {
637 checkClassMembers(element); 656 checkClassMembers(element);
638 } 657 }
639 } 658 }
640 659
641 void checkMixinApplication(MixinApplicationElementX mixinApplication) { 660 void checkMixinApplication(MixinApplicationElementX mixinApplication) {
642 Modifiers modifiers = mixinApplication.modifiers; 661 Modifiers modifiers = mixinApplication.modifiers;
643 int illegalFlags = modifiers.flags & ~Modifiers.FLAG_ABSTRACT; 662 int illegalFlags = modifiers.flags & ~Modifiers.FLAG_ABSTRACT;
644 if (illegalFlags != 0) { 663 if (illegalFlags != 0) {
645 Modifiers illegalModifiers = new Modifiers.withFlags(null, illegalFlags); 664 Modifiers illegalModifiers = new Modifiers.withFlags(null, illegalFlags);
646 compiler.reportError( 665 compiler.reportErrorMessage(
647 modifiers, 666 modifiers,
648 MessageKind.ILLEGAL_MIXIN_APPLICATION_MODIFIERS, 667 MessageKind.ILLEGAL_MIXIN_APPLICATION_MODIFIERS,
649 {'modifiers': illegalModifiers}); 668 {'modifiers': illegalModifiers});
650 } 669 }
651 670
652 // In case of cyclic mixin applications, the mixin chain will have 671 // In case of cyclic mixin applications, the mixin chain will have
653 // been cut. If so, we have already reported the error to the 672 // been cut. If so, we have already reported the error to the
654 // user so we just return from here. 673 // user so we just return from here.
655 ClassElement mixin = mixinApplication.mixin; 674 ClassElement mixin = mixinApplication.mixin;
656 if (mixin == null) return; 675 if (mixin == null) return;
657 676
658 // Check that we're not trying to use Object as a mixin. 677 // Check that we're not trying to use Object as a mixin.
659 if (mixin.superclass == null) { 678 if (mixin.superclass == null) {
660 compiler.reportError(mixinApplication, 679 compiler.reportErrorMessage(
661 MessageKind.ILLEGAL_MIXIN_OBJECT); 680 mixinApplication,
681 MessageKind.ILLEGAL_MIXIN_OBJECT);
662 // Avoid reporting additional errors for the Object class. 682 // Avoid reporting additional errors for the Object class.
663 return; 683 return;
664 } 684 }
665 685
666 if (mixin.isEnumClass) { 686 if (mixin.isEnumClass) {
667 // Mixing in an enum has already caused a compile-time error. 687 // Mixing in an enum has already caused a compile-time error.
668 return; 688 return;
669 } 689 }
670 690
671 // Check that the mixed in class has Object as its superclass. 691 // Check that the mixed in class has Object as its superclass.
672 if (!mixin.superclass.isObject) { 692 if (!mixin.superclass.isObject) {
673 compiler.reportError(mixin, MessageKind.ILLEGAL_MIXIN_SUPERCLASS); 693 compiler.reportErrorMessage(
694 mixin, MessageKind.ILLEGAL_MIXIN_SUPERCLASS);
674 } 695 }
675 696
676 // Check that the mixed in class doesn't have any constructors and 697 // Check that the mixed in class doesn't have any constructors and
677 // make sure we aren't mixing in methods that use 'super'. 698 // make sure we aren't mixing in methods that use 'super'.
678 mixin.forEachLocalMember((AstElement member) { 699 mixin.forEachLocalMember((AstElement member) {
679 if (member.isGenerativeConstructor && !member.isSynthesized) { 700 if (member.isGenerativeConstructor && !member.isSynthesized) {
680 compiler.reportError(member, MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR); 701 compiler.reportErrorMessage(
702 member, MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR);
681 } else { 703 } else {
682 // Get the resolution tree and check that the resolved member 704 // Get the resolution tree and check that the resolved member
683 // doesn't use 'super'. This is the part of the 'super' mixin 705 // doesn't use 'super'. This is the part of the 'super' mixin
684 // check that happens when a function is resolved before the 706 // check that happens when a function is resolved before the
685 // mixin application has been performed. 707 // mixin application has been performed.
686 // TODO(johnniwinther): Obtain the [TreeElements] for [member] 708 // TODO(johnniwinther): Obtain the [TreeElements] for [member]
687 // differently. 709 // differently.
688 if (compiler.enqueuer.resolution.hasBeenResolved(member)) { 710 if (compiler.enqueuer.resolution.hasBeenResolved(member)) {
689 checkMixinSuperUses( 711 checkMixinSuperUses(
690 member.resolvedAst.elements, 712 member.resolvedAst.elements,
691 mixinApplication, 713 mixinApplication,
692 mixin); 714 mixin);
693 } 715 }
694 } 716 }
695 }); 717 });
696 } 718 }
697 719
698 void checkMixinSuperUses(TreeElements resolutionTree, 720 void checkMixinSuperUses(TreeElements resolutionTree,
699 MixinApplicationElement mixinApplication, 721 MixinApplicationElement mixinApplication,
700 ClassElement mixin) { 722 ClassElement mixin) {
701 // TODO(johnniwinther): Avoid the use of [TreeElements] here. 723 // TODO(johnniwinther): Avoid the use of [TreeElements] here.
702 if (resolutionTree == null) return; 724 if (resolutionTree == null) return;
703 Iterable<Node> superUses = resolutionTree.superUses; 725 Iterable<Node> superUses = resolutionTree.superUses;
704 if (superUses.isEmpty) return; 726 if (superUses.isEmpty) return;
705 compiler.reportError(mixinApplication, 727 DiagnosticMessage error = compiler.createMessage(
706 MessageKind.ILLEGAL_MIXIN_WITH_SUPER, 728 mixinApplication,
707 {'className': mixin.name}); 729 MessageKind.ILLEGAL_MIXIN_WITH_SUPER,
730 {'className': mixin.name});
708 // Show the user the problematic uses of 'super' in the mixin. 731 // Show the user the problematic uses of 'super' in the mixin.
732 List<DiagnosticMessage> infos = <DiagnosticMessage>[];
709 for (Node use in superUses) { 733 for (Node use in superUses) {
710 compiler.reportInfo( 734 infos.add(compiler.createMessage(
711 use, 735 use,
712 MessageKind.ILLEGAL_MIXIN_SUPER_USE); 736 MessageKind.ILLEGAL_MIXIN_SUPER_USE));
713 } 737 }
738 compiler.reportError(error, infos);
714 } 739 }
715 740
716 void checkClassMembers(ClassElement cls) { 741 void checkClassMembers(ClassElement cls) {
717 assert(invariant(cls, cls.isDeclaration)); 742 assert(invariant(cls, cls.isDeclaration));
718 if (cls.isObject) return; 743 if (cls.isObject) return;
719 // TODO(johnniwinther): Should this be done on the implementation element as 744 // TODO(johnniwinther): Should this be done on the implementation element as
720 // well? 745 // well?
721 List<Element> constConstructors = <Element>[]; 746 List<Element> constConstructors = <Element>[];
722 List<Element> nonFinalInstanceFields = <Element>[]; 747 List<Element> nonFinalInstanceFields = <Element>[];
723 cls.forEachMember((holder, member) { 748 cls.forEachMember((holder, member) {
724 compiler.withCurrentElement(member, () { 749 compiler.withCurrentElement(member, () {
725 // Perform various checks as side effect of "computing" the type. 750 // Perform various checks as side effect of "computing" the type.
726 member.computeType(compiler); 751 member.computeType(compiler);
727 752
728 // Check modifiers. 753 // Check modifiers.
729 if (member.isFunction && member.modifiers.isFinal) { 754 if (member.isFunction && member.modifiers.isFinal) {
730 compiler.reportError( 755 compiler.reportErrorMessage(
731 member, MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER); 756 member, MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER);
732 } 757 }
733 if (member.isConstructor) { 758 if (member.isConstructor) {
734 final mismatchedFlagsBits = 759 final mismatchedFlagsBits =
735 member.modifiers.flags & 760 member.modifiers.flags &
736 (Modifiers.FLAG_STATIC | Modifiers.FLAG_ABSTRACT); 761 (Modifiers.FLAG_STATIC | Modifiers.FLAG_ABSTRACT);
737 if (mismatchedFlagsBits != 0) { 762 if (mismatchedFlagsBits != 0) {
738 final mismatchedFlags = 763 final mismatchedFlags =
739 new Modifiers.withFlags(null, mismatchedFlagsBits); 764 new Modifiers.withFlags(null, mismatchedFlagsBits);
740 compiler.reportError( 765 compiler.reportErrorMessage(
741 member, 766 member,
742 MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS, 767 MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS,
743 {'modifiers': mismatchedFlags}); 768 {'modifiers': mismatchedFlags});
744 } 769 }
745 if (member.modifiers.isConst) { 770 if (member.modifiers.isConst) {
746 constConstructors.add(member); 771 constConstructors.add(member);
747 } 772 }
748 } 773 }
749 if (member.isField) { 774 if (member.isField) {
750 if (member.modifiers.isConst && !member.modifiers.isStatic) { 775 if (member.modifiers.isConst && !member.modifiers.isStatic) {
751 compiler.reportError( 776 compiler.reportErrorMessage(
752 member, MessageKind.ILLEGAL_CONST_FIELD_MODIFIER); 777 member, MessageKind.ILLEGAL_CONST_FIELD_MODIFIER);
753 } 778 }
754 if (!member.modifiers.isStatic && !member.modifiers.isFinal) { 779 if (!member.modifiers.isStatic && !member.modifiers.isFinal) {
755 nonFinalInstanceFields.add(member); 780 nonFinalInstanceFields.add(member);
756 } 781 }
757 } 782 }
758 checkAbstractField(member); 783 checkAbstractField(member);
759 checkUserDefinableOperator(member); 784 checkUserDefinableOperator(member);
760 }); 785 });
761 }); 786 });
762 if (!constConstructors.isEmpty && !nonFinalInstanceFields.isEmpty) { 787 if (!constConstructors.isEmpty && !nonFinalInstanceFields.isEmpty) {
763 Spannable span = constConstructors.length > 1 788 Spannable span = constConstructors.length > 1
764 ? cls : constConstructors[0]; 789 ? cls : constConstructors[0];
765 compiler.reportError(span, 790 DiagnosticMessage error = compiler.createMessage(
791 span,
766 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS, 792 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS,
767 {'className': cls.name}); 793 {'className': cls.name});
794 List<DiagnosticMessage> infos = <DiagnosticMessage>[];
768 if (constConstructors.length > 1) { 795 if (constConstructors.length > 1) {
769 for (Element constructor in constConstructors) { 796 for (Element constructor in constConstructors) {
770 compiler.reportInfo(constructor, 797 infos.add(compiler.createMessage(
771 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR); 798 constructor,
799 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR));
772 } 800 }
773 } 801 }
774 for (Element field in nonFinalInstanceFields) { 802 for (Element field in nonFinalInstanceFields) {
775 compiler.reportInfo(field, 803 infos.add(compiler.createMessage(
776 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD); 804 field,
805 MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD));
777 } 806 }
807 compiler.reportError(error, infos);
778 } 808 }
779 } 809 }
780 810
781 void checkAbstractField(Element member) { 811 void checkAbstractField(Element member) {
782 // Only check for getters. The test can only fail if there is both a setter 812 // Only check for getters. The test can only fail if there is both a setter
783 // and a getter with the same name, and we only need to check each abstract 813 // and a getter with the same name, and we only need to check each abstract
784 // field once, so we just ignore setters. 814 // field once, so we just ignore setters.
785 if (!member.isGetter) return; 815 if (!member.isGetter) return;
786 816
787 // Find the associated abstract field. 817 // Find the associated abstract field.
(...skipping 11 matching lines...) Expand all
799 829
800 GetterElementX getter = field.getter; 830 GetterElementX getter = field.getter;
801 if (getter == null) return; 831 if (getter == null) return;
802 SetterElementX setter = field.setter; 832 SetterElementX setter = field.setter;
803 if (setter == null) return; 833 if (setter == null) return;
804 int getterFlags = getter.modifiers.flags | Modifiers.FLAG_ABSTRACT; 834 int getterFlags = getter.modifiers.flags | Modifiers.FLAG_ABSTRACT;
805 int setterFlags = setter.modifiers.flags | Modifiers.FLAG_ABSTRACT; 835 int setterFlags = setter.modifiers.flags | Modifiers.FLAG_ABSTRACT;
806 if (!identical(getterFlags, setterFlags)) { 836 if (!identical(getterFlags, setterFlags)) {
807 final mismatchedFlags = 837 final mismatchedFlags =
808 new Modifiers.withFlags(null, getterFlags ^ setterFlags); 838 new Modifiers.withFlags(null, getterFlags ^ setterFlags);
809 compiler.reportError( 839 compiler.reportErrorMessage(
810 field.getter, 840 field.getter,
811 MessageKind.GETTER_MISMATCH, 841 MessageKind.GETTER_MISMATCH,
812 {'modifiers': mismatchedFlags}); 842 {'modifiers': mismatchedFlags});
813 compiler.reportError( 843 compiler.reportErrorMessage(
814 field.setter, 844 field.setter,
815 MessageKind.SETTER_MISMATCH, 845 MessageKind.SETTER_MISMATCH,
816 {'modifiers': mismatchedFlags}); 846 {'modifiers': mismatchedFlags});
817 } 847 }
818 } 848 }
819 849
820 void checkUserDefinableOperator(Element member) { 850 void checkUserDefinableOperator(Element member) {
821 FunctionElement function = member.asFunctionElement(); 851 FunctionElement function = member.asFunctionElement();
822 if (function == null) return; 852 if (function == null) return;
823 String value = member.name; 853 String value = member.name;
(...skipping 27 matching lines...) Expand all
851 } 881 }
852 checkArity(function, requiredParameterCount, messageKind, isMinus); 882 checkArity(function, requiredParameterCount, messageKind, isMinus);
853 } 883 }
854 884
855 void checkOverrideHashCode(FunctionElement operatorEquals) { 885 void checkOverrideHashCode(FunctionElement operatorEquals) {
856 if (operatorEquals.isAbstract) return; 886 if (operatorEquals.isAbstract) return;
857 ClassElement cls = operatorEquals.enclosingClass; 887 ClassElement cls = operatorEquals.enclosingClass;
858 Element hashCodeImplementation = 888 Element hashCodeImplementation =
859 cls.lookupLocalMember('hashCode'); 889 cls.lookupLocalMember('hashCode');
860 if (hashCodeImplementation != null) return; 890 if (hashCodeImplementation != null) return;
861 compiler.reportHint( 891 compiler.reportHintMessage(
862 operatorEquals, MessageKind.OVERRIDE_EQUALS_NOT_HASH_CODE, 892 operatorEquals, MessageKind.OVERRIDE_EQUALS_NOT_HASH_CODE,
863 {'class': cls.name}); 893 {'class': cls.name});
864 } 894 }
865 895
866 void checkArity(FunctionElement function, 896 void checkArity(FunctionElement function,
867 int requiredParameterCount, MessageKind messageKind, 897 int requiredParameterCount, MessageKind messageKind,
868 bool isMinus) { 898 bool isMinus) {
869 FunctionExpression node = function.node; 899 FunctionExpression node = function.node;
870 FunctionSignature signature = function.functionSignature; 900 FunctionSignature signature = function.functionSignature;
871 if (signature.requiredParameterCount != requiredParameterCount) { 901 if (signature.requiredParameterCount != requiredParameterCount) {
(...skipping 20 matching lines...) Expand all
892 // int operator -(a, b) {} 922 // int operator -(a, b) {}
893 // ^ 923 // ^
894 // 924 //
895 // since the correction might not be to remove 'b' but instead to 925 // since the correction might not be to remove 'b' but instead to
896 // remove 'a, b'. 926 // remove 'a, b'.
897 errorNode = node.parameters; 927 errorNode = node.parameters;
898 } else { 928 } else {
899 errorNode = node.parameters.nodes.skip(requiredParameterCount).head; 929 errorNode = node.parameters.nodes.skip(requiredParameterCount).head;
900 } 930 }
901 } 931 }
902 compiler.reportError( 932 compiler.reportErrorMessage(
903 errorNode, messageKind, {'operatorName': function.name}); 933 errorNode, messageKind, {'operatorName': function.name});
904 } 934 }
905 if (signature.optionalParameterCount != 0) { 935 if (signature.optionalParameterCount != 0) {
906 Node errorNode = 936 Node errorNode =
907 node.parameters.nodes.skip(signature.requiredParameterCount).head; 937 node.parameters.nodes.skip(signature.requiredParameterCount).head;
908 if (signature.optionalParametersAreNamed) { 938 if (signature.optionalParametersAreNamed) {
909 compiler.reportError( 939 compiler.reportErrorMessage(
910 errorNode, 940 errorNode,
911 MessageKind.OPERATOR_NAMED_PARAMETERS, 941 MessageKind.OPERATOR_NAMED_PARAMETERS,
912 {'operatorName': function.name}); 942 {'operatorName': function.name});
913 } else { 943 } else {
914 compiler.reportError( 944 compiler.reportErrorMessage(
915 errorNode, 945 errorNode,
916 MessageKind.OPERATOR_OPTIONAL_PARAMETERS, 946 MessageKind.OPERATOR_OPTIONAL_PARAMETERS,
917 {'operatorName': function.name}); 947 {'operatorName': function.name});
918 } 948 }
919 } 949 }
920 } 950 }
921 951
922 reportErrorWithContext(Element errorneousElement, 952 reportErrorWithContext(Element errorneousElement,
923 MessageKind errorMessage, 953 MessageKind errorMessage,
924 Element contextElement, 954 Element contextElement,
925 MessageKind contextMessage) { 955 MessageKind contextMessage) {
926 compiler.reportError( 956 compiler.reportError(
927 errorneousElement, 957 compiler.createMessage(
928 errorMessage, 958 errorneousElement,
929 {'memberName': contextElement.name, 959 errorMessage,
930 'className': contextElement.enclosingClass.name}); 960 {'memberName': contextElement.name,
931 compiler.reportInfo(contextElement, contextMessage); 961 'className': contextElement.enclosingClass.name}),
962 <DiagnosticMessage>[
963 compiler.createMessage(contextElement, contextMessage),
964 ]);
932 } 965 }
933 966
934 967
935 FunctionSignature resolveSignature(FunctionElementX element) { 968 FunctionSignature resolveSignature(FunctionElementX element) {
936 MessageKind defaultValuesError = null; 969 MessageKind defaultValuesError = null;
937 if (element.isFactoryConstructor) { 970 if (element.isFactoryConstructor) {
938 FunctionExpression body = element.parseNode(compiler); 971 FunctionExpression body = element.parseNode(compiler);
939 if (body.isRedirectingFactory) { 972 if (body.isRedirectingFactory) {
940 defaultValuesError = MessageKind.REDIRECTING_FACTORY_WITH_DEFAULT; 973 defaultValuesError = MessageKind.REDIRECTING_FACTORY_WITH_DEFAULT;
941 } 974 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
999 constantCompiler.evaluate(annotation.constant); 1032 constantCompiler.evaluate(annotation.constant);
1000 // TODO(johnniwinther): Register the relation between the annotation 1033 // TODO(johnniwinther): Register the relation between the annotation
1001 // and the annotated element instead. This will allow the backend to 1034 // and the annotated element instead. This will allow the backend to
1002 // retrieve the backend constant and only register metadata on the 1035 // retrieve the backend constant and only register metadata on the
1003 // elements for which it is needed. (Issue 17732). 1036 // elements for which it is needed. (Issue 17732).
1004 registry.registerMetadataConstant(annotation, annotatedElement); 1037 registry.registerMetadataConstant(annotation, annotatedElement);
1005 annotation.resolutionState = STATE_DONE; 1038 annotation.resolutionState = STATE_DONE;
1006 })); 1039 }));
1007 } 1040 }
1008 1041
1009 error(Spannable node, MessageKind kind, [arguments = const {}]) {
1010 compiler.reportError(node, kind, arguments);
1011 }
1012
1013 List<MetadataAnnotation> resolveMetadata(Element element, 1042 List<MetadataAnnotation> resolveMetadata(Element element,
1014 VariableDefinitions node) { 1043 VariableDefinitions node) {
1015 List<MetadataAnnotation> metadata = <MetadataAnnotation>[]; 1044 List<MetadataAnnotation> metadata = <MetadataAnnotation>[];
1016 for (Metadata annotation in node.metadata.nodes) { 1045 for (Metadata annotation in node.metadata.nodes) {
1017 ParameterMetadataAnnotation metadataAnnotation = 1046 ParameterMetadataAnnotation metadataAnnotation =
1018 new ParameterMetadataAnnotation(annotation); 1047 new ParameterMetadataAnnotation(annotation);
1019 metadataAnnotation.annotatedElement = element; 1048 metadataAnnotation.annotatedElement = element;
1020 metadata.add(metadataAnnotation.ensureResolved(compiler)); 1049 metadata.add(metadataAnnotation.ensureResolved(compiler));
1021 } 1050 }
1022 return metadata; 1051 return metadata;
(...skipping 15 matching lines...) Expand all
1038 TreeElements get treeElements { 1067 TreeElements get treeElements {
1039 assert(invariant(this, _treeElements !=null, 1068 assert(invariant(this, _treeElements !=null,
1040 message: "TreeElements have not been computed for $this.")); 1069 message: "TreeElements have not been computed for $this."));
1041 return _treeElements; 1070 return _treeElements;
1042 } 1071 }
1043 1072
1044 void reuseElement() { 1073 void reuseElement() {
1045 _treeElements = null; 1074 _treeElements = null;
1046 } 1075 }
1047 } 1076 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/resolution/members.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