OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE.md file. | 3 // BSD-style license that can be found in the LICENSE.md file. |
4 | 4 |
5 import 'dart:async'; | 5 import 'dart:async'; |
6 import 'dart:collection' show Queue; | 6 import 'dart:collection' show Queue; |
7 | 7 |
8 import 'package:kernel/ast.dart' as ir; | 8 import 'package:kernel/ast.dart' as ir; |
9 import 'package:kernel/verifier.dart' show CheckParentPointers; | 9 import 'package:kernel/verifier.dart' show CheckParentPointers; |
10 | 10 |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 library = library.declaration; | 145 library = library.declaration; |
146 return libraries.putIfAbsent(library, () { | 146 return libraries.putIfAbsent(library, () { |
147 String name = library.hasLibraryName ? library.libraryName : null; | 147 String name = library.hasLibraryName ? library.libraryName : null; |
148 ir.Library libraryNode = new ir.Library(library.canonicalUri, | 148 ir.Library libraryNode = new ir.Library(library.canonicalUri, |
149 name: name, classes: null, procedures: null, fields: null); | 149 name: name, classes: null, procedures: null, fields: null); |
150 addWork(library, () { | 150 addWork(library, () { |
151 Queue<ir.Class> classes = new Queue<ir.Class>(); | 151 Queue<ir.Class> classes = new Queue<ir.Class>(); |
152 Queue<ir.Member> members = new Queue<ir.Member>(); | 152 Queue<ir.Member> members = new Queue<ir.Member>(); |
153 library.implementation.forEachLocalMember((Element e) { | 153 library.implementation.forEachLocalMember((Element e) { |
154 if (e.isClass) { | 154 if (e.isClass) { |
155 classes.addFirst(classToIr(e)); | 155 ClassElement cls = e; |
| 156 if (!cls.isResolved) return; |
| 157 classes.addFirst(classToIr(cls)); |
156 } else if (e.isFunction || e.isAccessor) { | 158 } else if (e.isFunction || e.isAccessor) { |
| 159 if (!compiler.resolution.hasBeenResolved(e) && !e.isMalformed) { |
| 160 return; |
| 161 } |
157 members.addFirst(functionToIr(e)); | 162 members.addFirst(functionToIr(e)); |
158 } else if (e.isField) { | 163 } else if (e.isField) { |
| 164 if (!compiler.resolution.hasBeenResolved(e) && !e.isMalformed) { |
| 165 return; |
| 166 } |
159 members.addFirst(fieldToIr(e)); | 167 members.addFirst(fieldToIr(e)); |
160 } else if (e.isTypedef) { | 168 } else if (e.isTypedef) { |
161 // Ignored, typedefs are unaliased on use. | 169 // Ignored, typedefs are unaliased on use. |
162 } else { | 170 } else { |
163 internalError(e, "Unhandled library member: $e"); | 171 internalError(e, "Unhandled library member: $e"); |
164 } | 172 } |
165 }); | 173 }); |
166 // The elements were inserted in reverse order as forEachLocalMember | 174 // The elements were inserted in reverse order as forEachLocalMember |
167 // above gives them in reversed order. | 175 // above gives them in reversed order. |
168 classes.forEach(libraryNode.addClass); | 176 classes.forEach(libraryNode.addClass); |
(...skipping 12 matching lines...) Expand all Loading... |
181 Map<String, int> mixinApplicationNames = mixinApplicationNamesByLibrary | 189 Map<String, int> mixinApplicationNames = mixinApplicationNamesByLibrary |
182 .putIfAbsent(cls.library.implementation, () => <String, int>{}); | 190 .putIfAbsent(cls.library.implementation, () => <String, int>{}); |
183 int count = mixinApplicationNames.putIfAbsent(name, () => 0); | 191 int count = mixinApplicationNames.putIfAbsent(name, () => 0); |
184 mixinApplicationNames[name] = count + 1; | 192 mixinApplicationNames[name] = count + 1; |
185 return "$name#$count"; | 193 return "$name#$count"; |
186 } | 194 } |
187 | 195 |
188 ir.Class classToIr(ClassElement cls) { | 196 ir.Class classToIr(ClassElement cls) { |
189 cls = cls.declaration; | 197 cls = cls.declaration; |
190 return classes.putIfAbsent(cls, () { | 198 return classes.putIfAbsent(cls, () { |
191 cls.ensureResolved(compiler.resolution); | 199 assert(cls.isResolved); |
192 compiler.enqueuer.resolution.emptyDeferredQueueForTesting(); | |
193 String name = computeName(cls); | 200 String name = computeName(cls); |
194 ir.Class classNode = new ir.Class( | 201 ir.Class classNode = new ir.Class( |
195 name: name, | 202 name: name, |
196 isAbstract: cls.isAbstract, | 203 isAbstract: cls.isAbstract, |
197 typeParameters: null, | 204 typeParameters: null, |
198 implementedTypes: null, | 205 implementedTypes: null, |
199 constructors: null, | 206 constructors: null, |
200 procedures: null, | 207 procedures: null, |
201 fields: null); | 208 fields: null); |
202 addWork(cls, () { | 209 addWork(cls, () { |
203 if (cls.supertype != null) { | 210 if (cls.supertype != null) { |
204 classNode.supertype = supertypeToIr(cls.supertype); | 211 classNode.supertype = supertypeToIr(cls.supertype); |
205 } | 212 } |
206 if (cls.isMixinApplication) { | 213 if (cls.isMixinApplication) { |
207 MixinApplicationElement mixinApplication = cls; | 214 MixinApplicationElement mixinApplication = cls; |
208 classNode.mixedInType = supertypeToIr(mixinApplication.mixinType); | 215 classNode.mixedInType = supertypeToIr(mixinApplication.mixinType); |
209 } | 216 } |
210 classNode.parent = libraryToIr(cls.library); | 217 classNode.parent = libraryToIr(cls.library); |
211 if (cls.isUnnamedMixinApplication) { | 218 if (cls.isUnnamedMixinApplication) { |
212 classNode.enclosingLibrary.addClass(classNode); | 219 classNode.enclosingLibrary.addClass(classNode); |
213 } | 220 } |
214 cls.implementation | 221 cls.implementation |
215 .forEachMember((ClassElement enclosingClass, Element member) { | 222 .forEachMember((ClassElement enclosingClass, Element member) { |
| 223 if (!compiler.resolution.hasBeenResolved(member) |
| 224 && !member.isMalformed) { |
| 225 return; |
| 226 } |
216 if (member.enclosingClass.declaration != cls) { | 227 if (member.enclosingClass.declaration != cls) { |
217 // TODO(het): figure out why impact_test triggers this | 228 // TODO(het): figure out why impact_test triggers this |
218 //internalError(cls, "`$member` isn't mine."); | 229 //internalError(cls, "`$member` isn't mine."); |
219 } else if (member.isConstructor) { | 230 } else if (member.isConstructor) { |
220 ConstructorElement constructor = member; | 231 ConstructorElement constructor = member; |
221 ir.Member memberNode = functionToIr(member); | 232 ir.Member memberNode = functionToIr(member); |
222 if (!constructor.isRedirectingFactory) { | 233 if (!constructor.isRedirectingFactory) { |
223 classNode.addMember(memberNode); | 234 classNode.addMember(memberNode); |
224 } | 235 } |
225 } else if (member.isFunction || member.isAccessor) { | 236 } else if (member.isFunction || member.isAccessor) { |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 internalError(function, "Deferred loader."); | 413 internalError(function, "Deferred loader."); |
403 } | 414 } |
404 if (function.isLocal) { | 415 if (function.isLocal) { |
405 internalError(function, "Local function."); | 416 internalError(function, "Local function."); |
406 } | 417 } |
407 if (isSyntheticError(function)) { | 418 if (isSyntheticError(function)) { |
408 internalError(function, "Synthetic error function: $function."); | 419 internalError(function, "Synthetic error function: $function."); |
409 } | 420 } |
410 function = function.declaration; | 421 function = function.declaration; |
411 return functions.putIfAbsent(function, () { | 422 return functions.putIfAbsent(function, () { |
412 compiler.resolution.ensureResolved(function); | 423 assert(compiler.resolution.hasBeenResolved(function) || |
413 compiler.enqueuer.resolution.emptyDeferredQueueForTesting(); | 424 function.isMalformed); |
414 function = function.implementation; | 425 function = function.implementation; |
415 ir.Member member; | 426 ir.Member member; |
416 ir.Constructor constructor; | 427 ir.Constructor constructor; |
417 ir.Procedure procedure; | 428 ir.Procedure procedure; |
418 ir.Name name = irName(function.name, function); | 429 ir.Name name = irName(function.name, function); |
419 bool isNative = isNativeMethod(function); | 430 bool isNative = isNativeMethod(function); |
420 if (function.isGenerativeConstructor) { | 431 if (function.isGenerativeConstructor) { |
421 member = constructor = new ir.Constructor(null, | 432 member = constructor = new ir.Constructor(null, |
422 name: name, | 433 name: name, |
423 isConst: function.isConst, | 434 isConst: function.isConst, |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
502 void endFactoryScope(FunctionElement function) { | 513 void endFactoryScope(FunctionElement function) { |
503 factoryTypeParameters.clear(); | 514 factoryTypeParameters.clear(); |
504 } | 515 } |
505 | 516 |
506 ir.Field fieldToIr(FieldElement field) { | 517 ir.Field fieldToIr(FieldElement field) { |
507 if (isSyntheticError(field)) { | 518 if (isSyntheticError(field)) { |
508 internalError(field, "Synthetic error field: $field."); | 519 internalError(field, "Synthetic error field: $field."); |
509 } | 520 } |
510 field = field.declaration; | 521 field = field.declaration; |
511 return fields.putIfAbsent(field, () { | 522 return fields.putIfAbsent(field, () { |
| 523 // TODO(sigmund): remove `ensureResolved` here. It appears we hit this |
| 524 // case only in metadata: when a constant has a field that is never read, |
| 525 // but it is initialized in the constant constructor. |
512 compiler.resolution.ensureResolved(field); | 526 compiler.resolution.ensureResolved(field); |
513 compiler.enqueuer.resolution.emptyDeferredQueueForTesting(); | 527 compiler.enqueuer.resolution.emptyDeferredQueueForTesting(); |
| 528 assert(compiler.resolution.hasBeenResolved(field) || field.isMalformed); |
| 529 |
514 field = field.implementation; | 530 field = field.implementation; |
515 ir.DartType type = | 531 ir.DartType type = |
516 field.isMalformed ? const ir.InvalidType() : typeToIr(field.type); | 532 field.isMalformed ? const ir.InvalidType() : typeToIr(field.type); |
517 ir.Field fieldNode = new ir.Field(irName(field.memberName.text, field), | 533 ir.Field fieldNode = new ir.Field(irName(field.memberName.text, field), |
518 type: type, | 534 type: type, |
519 initializer: null, | 535 initializer: null, |
520 isFinal: field.isFinal, | 536 isFinal: field.isFinal, |
521 isStatic: field.isStatic || field.isTopLevel, | 537 isStatic: field.isStatic || field.isTopLevel, |
522 isConst: field.isConst); | 538 isConst: field.isConst); |
523 addWork(field, () { | 539 addWork(field, () { |
(...skipping 21 matching lines...) Expand all Loading... |
545 | 561 |
546 ir.TypeParameter typeVariableToIr(TypeVariableElement variable) { | 562 ir.TypeParameter typeVariableToIr(TypeVariableElement variable) { |
547 variable = variable.declaration; | 563 variable = variable.declaration; |
548 ir.TypeParameter parameter = factoryTypeParameters[variable]; | 564 ir.TypeParameter parameter = factoryTypeParameters[variable]; |
549 if (parameter != null) return parameter; | 565 if (parameter != null) return parameter; |
550 return typeParameters.putIfAbsent(variable, () { | 566 return typeParameters.putIfAbsent(variable, () { |
551 ir.TypeParameter parameter = new ir.TypeParameter(variable.name, null); | 567 ir.TypeParameter parameter = new ir.TypeParameter(variable.name, null); |
552 addWork(variable, () { | 568 addWork(variable, () { |
553 if (variable.typeDeclaration.isClass) { | 569 if (variable.typeDeclaration.isClass) { |
554 ClassElement cls = variable.typeDeclaration; | 570 ClassElement cls = variable.typeDeclaration; |
555 cls.ensureResolved(compiler.resolution); | 571 assert(cls.isResolved); |
556 parameter.parent = classToIr(cls); | 572 parameter.parent = classToIr(cls); |
557 } else { | 573 } else { |
558 FunctionElement method = variable.typeDeclaration; | 574 FunctionElement method = variable.typeDeclaration; |
559 parameter.parent = functionToIr(method).function; | 575 parameter.parent = functionToIr(method).function; |
560 } | 576 } |
561 parameter.bound = typeToIr(variable.bound); | 577 parameter.bound = typeToIr(variable.bound); |
562 }); | 578 }); |
563 return parameter; | 579 return parameter; |
564 }); | 580 }); |
565 } | 581 } |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
681 return true; | 697 return true; |
682 } | 698 } |
683 return false; | 699 return false; |
684 } | 700 } |
685 | 701 |
686 ir.Constructor getDartCoreConstructor( | 702 ir.Constructor getDartCoreConstructor( |
687 String className, String constructorName) { | 703 String className, String constructorName) { |
688 LibraryElement library = | 704 LibraryElement library = |
689 compiler.libraryLoader.lookupLibrary(Uris.dart_core); | 705 compiler.libraryLoader.lookupLibrary(Uris.dart_core); |
690 ClassElement cls = library.implementation.localLookup(className); | 706 ClassElement cls = library.implementation.localLookup(className); |
| 707 cls.ensureResolved(compiler.resolution); |
691 assert(invariant(CURRENT_ELEMENT_SPANNABLE, cls != null, | 708 assert(invariant(CURRENT_ELEMENT_SPANNABLE, cls != null, |
692 message: 'dart:core class $className not found.')); | 709 message: 'dart:core class $className not found.')); |
693 ConstructorElement constructor = cls.lookupConstructor(constructorName); | 710 ConstructorElement constructor = cls.lookupConstructor(constructorName); |
694 assert(invariant(CURRENT_ELEMENT_SPANNABLE, constructor != null, | 711 assert(invariant(CURRENT_ELEMENT_SPANNABLE, constructor != null, |
695 message: "Constructor '$constructorName' not found " | 712 message: "Constructor '$constructorName' not found " |
696 "in class '$className'.")); | 713 "in class '$className'.")); |
| 714 compiler.resolution.ensureResolved(constructor); |
697 return functionToIr(constructor); | 715 return functionToIr(constructor); |
698 } | 716 } |
699 | 717 |
700 ir.Procedure getDartCoreMethod(String name) { | 718 ir.Procedure getDartCoreMethod(String name) { |
701 LibraryElement library = | 719 LibraryElement library = |
702 compiler.libraryLoader.lookupLibrary(Uris.dart_core); | 720 compiler.libraryLoader.lookupLibrary(Uris.dart_core); |
703 Element function = library.implementation.localLookup(name); | 721 Element function = library.implementation.localLookup(name); |
704 assert(invariant(CURRENT_ELEMENT_SPANNABLE, function != null, | 722 assert(invariant(CURRENT_ELEMENT_SPANNABLE, function != null, |
705 message: "dart:core method '$name' not found.")); | 723 message: "dart:core method '$name' not found.")); |
| 724 compiler.resolution.ensureResolved(function); |
706 return functionToIr(function); | 725 return functionToIr(function); |
707 } | 726 } |
708 | 727 |
709 ir.Procedure getMalformedTypeErrorBuilder() { | 728 ir.Procedure getMalformedTypeErrorBuilder() { |
710 return getDartCoreMethod('_malformedTypeError'); | 729 return getDartCoreMethod('_malformedTypeError'); |
711 } | 730 } |
712 | 731 |
713 ir.Procedure getUnresolvedConstructorBuilder() { | 732 ir.Procedure getUnresolvedConstructorBuilder() { |
714 return getDartCoreMethod('_unresolvedConstructorError'); | 733 return getDartCoreMethod('_unresolvedConstructorError'); |
715 } | 734 } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
760 } | 779 } |
761 | 780 |
762 class ConstructorTarget { | 781 class ConstructorTarget { |
763 final ConstructorElement element; | 782 final ConstructorElement element; |
764 final DartType type; | 783 final DartType type; |
765 | 784 |
766 ConstructorTarget(this.element, this.type); | 785 ConstructorTarget(this.element, this.type); |
767 | 786 |
768 String toString() => "ConstructorTarget($element, $type)"; | 787 String toString() => "ConstructorTarget($element, $type)"; |
769 } | 788 } |
OLD | NEW |