Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 serialization.elements; | 5 library serialization.elements; |
| 6 | 6 |
| 7 import 'package:analyzer/dart/element/element.dart'; | 7 import 'package:analyzer/dart/element/element.dart'; |
| 8 import 'package:analyzer/dart/element/type.dart'; | 8 import 'package:analyzer/dart/element/type.dart'; |
| 9 import 'package:analyzer/src/dart/element/element.dart'; | 9 import 'package:analyzer/src/dart/element/element.dart'; |
| 10 import 'package:analyzer/src/dart/element/member.dart'; | 10 import 'package:analyzer/src/dart/element/member.dart'; |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 154 */ | 154 */ |
| 155 final List<_SerializeTypeRef> deferredLinkedTypes = <_SerializeTypeRef>[]; | 155 final List<_SerializeTypeRef> deferredLinkedTypes = <_SerializeTypeRef>[]; |
| 156 | 156 |
| 157 /** | 157 /** |
| 158 * Index into the "references table" representing an unresolved reference, if | 158 * Index into the "references table" representing an unresolved reference, if |
| 159 * such an index exists. `null` if no such entry has been made in the | 159 * such an index exists. `null` if no such entry has been made in the |
| 160 * references table yet. | 160 * references table yet. |
| 161 */ | 161 */ |
| 162 int unresolvedReferenceIndex = null; | 162 int unresolvedReferenceIndex = null; |
| 163 | 163 |
| 164 /** | |
| 165 * Index into the "references table" representing the "bottom" type, if such | |
| 166 * an index exists. `null` if no such entry has been made in the references | |
| 167 * table yet. | |
| 168 */ | |
| 169 int bottomReferenceIndex = null; | |
| 170 | |
| 164 _CompilationUnitSerializer( | 171 _CompilationUnitSerializer( |
| 165 this.librarySerializer, this.compilationUnit, this.unitNum); | 172 this.librarySerializer, this.compilationUnit, this.unitNum); |
| 166 | 173 |
| 167 /** | 174 /** |
| 168 * Add all classes, enums, typedefs, executables, and top level variables | 175 * Add all classes, enums, typedefs, executables, and top level variables |
| 169 * from the given compilation unit [element] to the compilation unit summary. | 176 * from the given compilation unit [element] to the compilation unit summary. |
| 170 * [unitNum] indicates the ordinal position of this compilation unit in the | 177 * [unitNum] indicates the ordinal position of this compilation unit in the |
| 171 * library. | 178 * library. |
| 172 */ | 179 */ |
| 173 void addCompilationUnitElements() { | 180 void addCompilationUnitElements() { |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 350 return const <UnlinkedConstBuilder>[]; | 357 return const <UnlinkedConstBuilder>[]; |
| 351 } | 358 } |
| 352 return element.metadata.map((ElementAnnotationImpl a) { | 359 return element.metadata.map((ElementAnnotationImpl a) { |
| 353 _ConstExprSerializer serializer = new _ConstExprSerializer(this, null); | 360 _ConstExprSerializer serializer = new _ConstExprSerializer(this, null); |
| 354 serializer.serializeAnnotation(a.annotationAst); | 361 serializer.serializeAnnotation(a.annotationAst); |
| 355 return serializer.toBuilder(); | 362 return serializer.toBuilder(); |
| 356 }).toList(); | 363 }).toList(); |
| 357 } | 364 } |
| 358 | 365 |
| 359 /** | 366 /** |
| 367 * Return the index of the entry in the references table | |
| 368 * ([LinkedLibrary.references]) used for the "bottom" type. A new entry is | |
| 369 * added to the table if necessary to satisfy the request. | |
| 370 */ | |
| 371 int serializeBottomReference() { | |
| 372 if (bottomReferenceIndex == null) { | |
| 373 // References to the "bottom" type are always implicit, since there is no | |
| 374 // way to explicitly refer to the "bottom" type. Therefore they should | |
| 375 // be stored only in the linked references table. | |
| 376 int index = linkedReferences.length; | |
| 377 linkedReferences.add(new LinkedReferenceBuilder( | |
| 378 name: '*bottom*', kind: ReferenceKind.classOrEnum)); | |
| 379 return index; | |
|
scheglov
2016/02/18 18:11:44
Also maybe remove this statement and fall through.
Paul Berry
2016/02/18 18:18:15
Good catch, thanks! Fixed both here and in serial
| |
| 380 } | |
| 381 return bottomReferenceIndex; | |
| 382 } | |
| 383 | |
| 384 /** | |
| 360 * Serialize the given [classElement], creating an [UnlinkedClass]. | 385 * Serialize the given [classElement], creating an [UnlinkedClass]. |
| 361 */ | 386 */ |
| 362 UnlinkedClassBuilder serializeClass(ClassElement classElement) { | 387 UnlinkedClassBuilder serializeClass(ClassElement classElement) { |
| 363 UnlinkedClassBuilder b = new UnlinkedClassBuilder(); | 388 UnlinkedClassBuilder b = new UnlinkedClassBuilder(); |
| 364 b.name = classElement.name; | 389 b.name = classElement.name; |
| 365 b.nameOffset = classElement.nameOffset; | 390 b.nameOffset = classElement.nameOffset; |
| 366 b.typeParameters = | 391 b.typeParameters = |
| 367 classElement.typeParameters.map(serializeTypeParam).toList(); | 392 classElement.typeParameters.map(serializeTypeParam).toList(); |
| 368 if (classElement.supertype == null) { | 393 if (classElement.supertype == null) { |
| 369 b.hasNoSupertype = true; | 394 b.hasNoSupertype = true; |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 515 } | 540 } |
| 516 | 541 |
| 517 /** | 542 /** |
| 518 * Serialize the given [executableElement], creating an [UnlinkedExecutable]. | 543 * Serialize the given [executableElement], creating an [UnlinkedExecutable]. |
| 519 */ | 544 */ |
| 520 UnlinkedExecutableBuilder serializeExecutable( | 545 UnlinkedExecutableBuilder serializeExecutable( |
| 521 ExecutableElement executableElement) { | 546 ExecutableElement executableElement) { |
| 522 UnlinkedExecutableBuilder b = new UnlinkedExecutableBuilder(); | 547 UnlinkedExecutableBuilder b = new UnlinkedExecutableBuilder(); |
| 523 b.name = executableElement.name; | 548 b.name = executableElement.name; |
| 524 b.nameOffset = executableElement.nameOffset; | 549 b.nameOffset = executableElement.nameOffset; |
| 525 if (executableElement.enclosingElement is VariableElement) { | 550 if (executableElement is! ConstructorElement) { |
| 526 // TODO(scheglov) remove this check and serialize initializer types | |
| 527 // Note that for code like `var v = null` w need to support Bottom. | |
| 528 } else if (executableElement is! ConstructorElement) { | |
| 529 if (!executableElement.hasImplicitReturnType) { | 551 if (!executableElement.hasImplicitReturnType) { |
| 530 b.returnType = serializeTypeRef( | 552 b.returnType = serializeTypeRef( |
| 531 executableElement.type.returnType, executableElement); | 553 executableElement.type.returnType, executableElement); |
| 532 } else if (!executableElement.isStatic) { | 554 } else if (!executableElement.isStatic) { |
| 533 b.inferredReturnTypeSlot = | 555 b.inferredReturnTypeSlot = |
| 534 storeInferredType(executableElement.returnType, executableElement); | 556 storeInferredType(executableElement.returnType, executableElement); |
| 535 } | 557 } |
| 536 } | 558 } |
| 537 b.typeParameters = | 559 b.typeParameters = |
| 538 executableElement.typeParameters.map(serializeTypeParam).toList(); | 560 executableElement.typeParameters.map(serializeTypeParam).toList(); |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 731 /** | 753 /** |
| 732 * Compute the reference index which should be stored in a [EntityRef]. | 754 * Compute the reference index which should be stored in a [EntityRef]. |
| 733 * | 755 * |
| 734 * If [linked] is true, and a new reference has to be created, the reference | 756 * If [linked] is true, and a new reference has to be created, the reference |
| 735 * will only be stored in [linkedReferences]. | 757 * will only be stored in [linkedReferences]. |
| 736 */ | 758 */ |
| 737 int serializeReferenceForType(DartType type, bool linked) { | 759 int serializeReferenceForType(DartType type, bool linked) { |
| 738 Element element = type.element; | 760 Element element = type.element; |
| 739 LibraryElement dependentLibrary = element?.library; | 761 LibraryElement dependentLibrary = element?.library; |
| 740 if (dependentLibrary == null) { | 762 if (dependentLibrary == null) { |
| 763 if (type.isBottom) { | |
| 764 // References to the "bottom" type are always implicit, since there is | |
| 765 // no way to explicitly refer to the "bottom" type. Therefore they | |
| 766 // should always be linked. | |
| 767 assert(linked); | |
| 768 return serializeBottomReference(); | |
| 769 } | |
| 741 assert(type.isDynamic || type.isVoid); | 770 assert(type.isDynamic || type.isVoid); |
| 742 if (type is UndefinedTypeImpl) { | 771 if (type is UndefinedTypeImpl) { |
| 743 return serializeUnresolvedReference(); | 772 return serializeUnresolvedReference(); |
| 744 } | 773 } |
| 745 // Note: for a type which is truly `dynamic` or `void`, fall through to | 774 // Note: for a type which is truly `dynamic` or `void`, fall through to |
| 746 // use [_getElementReferenceId]. | 775 // use [_getElementReferenceId]. |
| 747 } | 776 } |
| 748 return _getElementReferenceId(element, linked: linked); | 777 return _getElementReferenceId(element, linked: linked); |
| 749 } | 778 } |
| 750 | 779 |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 925 } | 954 } |
| 926 // TODO(scheglov) VariableMember.initializer is not implemented | 955 // TODO(scheglov) VariableMember.initializer is not implemented |
| 927 if (variable is! VariableMember && variable.initializer != null) { | 956 if (variable is! VariableMember && variable.initializer != null) { |
| 928 b.initializer = serializeExecutable(variable.initializer); | 957 b.initializer = serializeExecutable(variable.initializer); |
| 929 } | 958 } |
| 930 return b; | 959 return b; |
| 931 } | 960 } |
| 932 | 961 |
| 933 /** | 962 /** |
| 934 * Create a slot id for the given [type] (which is an inferred type). If | 963 * Create a slot id for the given [type] (which is an inferred type). If |
| 935 * strong mode is enabled and [type] is not `dynamic`, it is stored in | 964 * [type] is not `dynamic`, it is stored in [linkedTypes] so that once the |
| 936 * [linkedTypes] so that once the compilation unit has been fully visited, it | 965 * compilation unit has been fully visited, it will be serialized into |
| 937 * will be serialized into [LinkedUnit.types]. | 966 * [LinkedUnit.types]. |
| 938 * | 967 * |
| 939 * [context] is the element within which the slot id will appear; this is | 968 * [context] is the element within which the slot id will appear; this is |
| 940 * used to serialize type parameters. | 969 * used to serialize type parameters. |
| 941 */ | 970 */ |
| 942 int storeInferredType(DartType type, Element context) { | 971 int storeInferredType(DartType type, Element context) { |
| 943 return storeLinkedType( | 972 return storeLinkedType(type.isDynamic ? null : type, context); |
| 944 librarySerializer.strongMode && !type.isDynamic ? type : null, context); | |
| 945 } | 973 } |
| 946 | 974 |
| 947 /** | 975 /** |
| 948 * Create a slot id for the given [type] (which may be either a propagated | 976 * Create a slot id for the given [type] (which may be either a propagated |
| 949 * type or an inferred type). If [type] is not `null`, it is stored in | 977 * type or an inferred type). If [type] is not `null`, it is stored in |
| 950 * [linkedTypes] so that once the compilation unit has been fully visited, | 978 * [linkedTypes] so that once the compilation unit has been fully visited, |
| 951 * it will be serialized to [LinkedUnit.types]. | 979 * it will be serialized to [LinkedUnit.types]. |
| 952 * | 980 * |
| 953 * [context] is the element within which the slot id will appear; this is | 981 * [context] is the element within which the slot id will appear; this is |
| 954 * used to serialize type parameters. | 982 * used to serialize type parameters. |
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1363 exportNames.add(new LinkedExportNameBuilder( | 1391 exportNames.add(new LinkedExportNameBuilder( |
| 1364 name: name, | 1392 name: name, |
| 1365 dependency: serializeDependency(dependentLibrary), | 1393 dependency: serializeDependency(dependentLibrary), |
| 1366 unit: unit, | 1394 unit: unit, |
| 1367 kind: kind)); | 1395 kind: kind)); |
| 1368 } | 1396 } |
| 1369 pb.exportNames = exportNames; | 1397 pb.exportNames = exportNames; |
| 1370 return pb; | 1398 return pb; |
| 1371 } | 1399 } |
| 1372 } | 1400 } |
| OLD | NEW |