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/type.dart'; | 10 import 'package:analyzer/src/dart/element/type.dart'; |
| 11 import 'package:analyzer/src/generated/ast.dart'; | |
| 10 import 'package:analyzer/src/generated/resolver.dart'; | 12 import 'package:analyzer/src/generated/resolver.dart'; |
| 13 import 'package:analyzer/src/generated/scanner.dart'; | |
| 11 import 'package:analyzer/src/generated/utilities_dart.dart'; | 14 import 'package:analyzer/src/generated/utilities_dart.dart'; |
| 12 import 'package:analyzer/src/summary/format.dart'; | 15 import 'package:analyzer/src/summary/format.dart'; |
| 13 import 'package:analyzer/src/summary/name_filter.dart'; | 16 import 'package:analyzer/src/summary/name_filter.dart'; |
| 14 | 17 |
| 15 /** | 18 /** |
| 16 * Serialize all the elements in [lib] to a summary using [ctx] as the context | 19 * Serialize all the elements in [lib] to a summary using [ctx] as the context |
| 17 * for building the summary, and using [typeProvider] to find built-in types. | 20 * for building the summary, and using [typeProvider] to find built-in types. |
| 18 */ | 21 */ |
| 19 LibrarySerializationResult serializeLibrary( | 22 LibrarySerializationResult serializeLibrary( |
| 20 LibraryElement lib, TypeProvider typeProvider) { | 23 LibraryElement lib, TypeProvider typeProvider) { |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 43 | 46 |
| 44 /** | 47 /** |
| 45 * Absolute URI of each compilation unit appearing in the library. | 48 * Absolute URI of each compilation unit appearing in the library. |
| 46 */ | 49 */ |
| 47 final List<String> unitUris; | 50 final List<String> unitUris; |
| 48 | 51 |
| 49 LibrarySerializationResult(this.linked, this.unlinkedUnits, this.unitUris); | 52 LibrarySerializationResult(this.linked, this.unlinkedUnits, this.unitUris); |
| 50 } | 53 } |
| 51 | 54 |
| 52 /** | 55 /** |
| 56 * Error that described a problem during a constant expression serialization. | |
|
Paul Berry
2016/01/19 20:02:10
s/described/describes/
scheglov
2016/01/19 20:59:28
Done.
| |
| 57 */ | |
| 58 class _ConstExprSerializationError { | |
| 59 final String message; | |
| 60 | |
| 61 _ConstExprSerializationError(this.message); | |
| 62 | |
| 63 @override | |
| 64 String toString() => message; | |
| 65 } | |
| 66 | |
| 67 /** | |
| 53 * Instances of this class keep track of intermediate state during | 68 * Instances of this class keep track of intermediate state during |
| 54 * serialization of a single library.` | 69 * serialization of a single constant [Expression]. |
| 70 */ | |
| 71 class _ConstExprSerializer { | |
| 72 final _LibrarySerializer serializer; | |
| 73 | |
| 74 /** | |
| 75 * See [UnlinkedConstBuilder.operations]. | |
| 76 */ | |
| 77 final List<UnlinkedConstOperation> operations = <UnlinkedConstOperation>[]; | |
| 78 | |
| 79 /** | |
| 80 * See [UnlinkedConstBuilder.ints]. | |
| 81 */ | |
| 82 final List<int> ints = <int>[]; | |
| 83 | |
| 84 /** | |
| 85 * See [UnlinkedConstBuilder.doubles]. | |
| 86 */ | |
| 87 final List<double> doubles = <double>[]; | |
| 88 | |
| 89 /** | |
| 90 * See [UnlinkedConstBuilder.strings]. | |
| 91 */ | |
| 92 final List<String> strings = <String>[]; | |
| 93 | |
| 94 /** | |
| 95 * See [UnlinkedConstBuilder.references]. | |
| 96 */ | |
| 97 final List<UnlinkedTypeRefBuilder> references = <UnlinkedTypeRefBuilder>[]; | |
| 98 | |
| 99 _ConstExprSerializer(this.serializer); | |
| 100 | |
| 101 /** | |
| 102 * Serialize the given [expr] expression into this serializer state. | |
| 103 */ | |
| 104 void serialize(Expression expr) { | |
| 105 if (expr is IntegerLiteral) { | |
| 106 _pushInt(expr.value); | |
| 107 } else if (expr is DoubleLiteral) { | |
| 108 operations.add(UnlinkedConstOperation.pushDouble); | |
| 109 doubles.add(expr.value); | |
| 110 } else if (expr is BooleanLiteral) { | |
| 111 if (expr.value) { | |
| 112 operations.add(UnlinkedConstOperation.pushTrue); | |
| 113 } else { | |
| 114 operations.add(UnlinkedConstOperation.pushFalse); | |
| 115 } | |
| 116 } else if (expr is StringLiteral) { | |
| 117 _serializeString(expr); | |
| 118 } else if (expr is SymbolLiteral) { | |
| 119 for (Token component in expr.components) { | |
|
Paul Berry
2016/01/19 20:02:10
Nit: why not just concatenate all the components t
scheglov
2016/01/19 20:59:28
Done.
| |
| 120 operations.add(UnlinkedConstOperation.pushString); | |
| 121 strings.add(component.lexeme); | |
| 122 } | |
| 123 operations.add(UnlinkedConstOperation.makeSymbol); | |
| 124 ints.add(expr.components.length); | |
| 125 } else if (expr is NullLiteral) { | |
| 126 operations.add(UnlinkedConstOperation.pushNull); | |
| 127 } else if (expr is Identifier) { | |
| 128 Element element = expr.staticElement; | |
| 129 assert(element != null); | |
| 130 // TODO(scheglov) how to serialize element references? | |
|
Paul Berry
2016/01/19 20:02:10
Is this TODO still applicable? At first glance it
scheglov
2016/01/19 20:59:28
Yes, I don't like how we do this.
We discussed thi
| |
| 131 operations.add(UnlinkedConstOperation.pushReference); | |
| 132 references.add(_serializeIdentifier(element)); | |
| 133 } else if (expr is InstanceCreationExpression) { | |
| 134 _serializeInstanceCreation(expr); | |
| 135 } else if (expr is ListLiteral) { | |
| 136 _serializeListLiteral(expr); | |
| 137 } else if (expr is MapLiteral) { | |
| 138 _serializeMapLiteral(expr); | |
| 139 } else if (expr is MethodInvocation) { | |
| 140 String name = expr.methodName.name; | |
| 141 assert(name == 'identical'); | |
|
Paul Berry
2016/01/19 20:02:10
Add a TODO noting that these assertions will fail
scheglov
2016/01/19 20:59:28
I've added checks that throw _ConstExprSerializati
| |
| 142 assert(expr.argumentList != null); | |
| 143 assert(expr.argumentList.arguments.length == 2); | |
| 144 expr.argumentList.arguments.forEach(serialize); | |
| 145 operations.add(UnlinkedConstOperation.identical); | |
| 146 } else if (expr is BinaryExpression) { | |
| 147 _serializeBinaryExpression(expr); | |
| 148 } else if (expr is ConditionalExpression) { | |
| 149 serialize(expr.condition); | |
| 150 serialize(expr.thenExpression); | |
| 151 serialize(expr.elseExpression); | |
| 152 operations.add(UnlinkedConstOperation.conditional); | |
| 153 } else if (expr is PrefixExpression) { | |
| 154 _serializePrefixExpression(expr); | |
| 155 } else if (expr is PropertyAccess && expr.propertyName.name == 'length') { | |
| 156 serialize(expr.target); | |
| 157 operations.add(UnlinkedConstOperation.length); | |
| 158 } else if (expr is ParenthesizedExpression) { | |
| 159 serialize(expr.expression); | |
| 160 } else { | |
| 161 throw new _ConstExprSerializationError('Unknown expression type: $expr'); | |
| 162 } | |
| 163 } | |
| 164 | |
| 165 /** | |
| 166 * Return the [UnlinkedConstBuilder] that corresponds to the state of this | |
| 167 * serializer. | |
| 168 */ | |
| 169 UnlinkedConstBuilder toBuilder() { | |
| 170 return new UnlinkedConstBuilder( | |
| 171 operations: operations, | |
| 172 ints: ints, | |
| 173 doubles: doubles, | |
| 174 strings: strings, | |
| 175 references: references); | |
| 176 } | |
| 177 | |
| 178 void _pushInt(int value) { | |
| 179 if (value >= (2 << 32)) { | |
|
Paul Berry
2016/01/19 20:02:10
I don't think this code handles all possible ints
scheglov
2016/01/19 20:59:28
Done.
| |
| 180 _pushInt(value >> 32); | |
| 181 operations.add(UnlinkedConstOperation.shiftOr); | |
| 182 ints.add(value & 0xFFFFFFFF); | |
| 183 } else { | |
| 184 operations.add(UnlinkedConstOperation.pushInt); | |
| 185 ints.add(value & 0xFFFFFFFF); | |
| 186 } | |
| 187 } | |
| 188 | |
| 189 void _serializeBinaryExpression(BinaryExpression expr) { | |
| 190 serialize(expr.leftOperand); | |
| 191 serialize(expr.rightOperand); | |
| 192 TokenType operator = expr.operator.type; | |
| 193 if (operator == TokenType.EQ_EQ) { | |
| 194 operations.add(UnlinkedConstOperation.equal); | |
| 195 } else if (operator == TokenType.BANG_EQ) { | |
| 196 operations.add(UnlinkedConstOperation.equal); | |
| 197 operations.add(UnlinkedConstOperation.not); | |
| 198 } else if (operator == TokenType.AMPERSAND_AMPERSAND) { | |
| 199 operations.add(UnlinkedConstOperation.and); | |
| 200 } else if (operator == TokenType.BAR_BAR) { | |
| 201 operations.add(UnlinkedConstOperation.or); | |
| 202 } else if (operator == TokenType.CARET) { | |
| 203 operations.add(UnlinkedConstOperation.bitXor); | |
| 204 } else if (operator == TokenType.AMPERSAND) { | |
| 205 operations.add(UnlinkedConstOperation.bitAnd); | |
| 206 } else if (operator == TokenType.BAR) { | |
| 207 operations.add(UnlinkedConstOperation.bitOr); | |
| 208 } else if (operator == TokenType.GT_GT) { | |
| 209 operations.add(UnlinkedConstOperation.bitShiftRight); | |
| 210 } else if (operator == TokenType.LT_LT) { | |
| 211 operations.add(UnlinkedConstOperation.bitShiftLeft); | |
| 212 } else if (operator == TokenType.PLUS) { | |
| 213 operations.add(UnlinkedConstOperation.add); | |
| 214 } else if (operator == TokenType.MINUS) { | |
| 215 operations.add(UnlinkedConstOperation.subtract); | |
| 216 } else if (operator == TokenType.STAR) { | |
| 217 operations.add(UnlinkedConstOperation.multiply); | |
| 218 } else if (operator == TokenType.SLASH) { | |
| 219 operations.add(UnlinkedConstOperation.divide); | |
| 220 } else if (operator == TokenType.TILDE_SLASH) { | |
| 221 operations.add(UnlinkedConstOperation.floorDivide); | |
| 222 } else if (operator == TokenType.GT) { | |
| 223 operations.add(UnlinkedConstOperation.greater); | |
| 224 } else if (operator == TokenType.LT) { | |
| 225 operations.add(UnlinkedConstOperation.less); | |
| 226 } else if (operator == TokenType.GT_EQ) { | |
| 227 operations.add(UnlinkedConstOperation.greaterEqual); | |
| 228 } else if (operator == TokenType.LT_EQ) { | |
| 229 operations.add(UnlinkedConstOperation.lessEqual); | |
| 230 } else if (operator == TokenType.PERCENT) { | |
| 231 operations.add(UnlinkedConstOperation.modulo); | |
| 232 } else { | |
| 233 throw new _ConstExprSerializationError('Unknown operator: $operator'); | |
| 234 } | |
| 235 } | |
| 236 | |
| 237 UnlinkedTypeRefBuilder _serializeIdentifier(Element element) { | |
| 238 return new UnlinkedTypeRefBuilder( | |
| 239 reference: serializer._getElementReferenceId(element)); | |
| 240 } | |
| 241 | |
| 242 void _serializeInstanceCreation(InstanceCreationExpression expr) { | |
| 243 List<Expression> arguments = expr.argumentList.arguments; | |
| 244 arguments.forEach(serialize); | |
| 245 ConstructorElement element = expr.staticElement; | |
| 246 assert(element != null); | |
| 247 operations.add(UnlinkedConstOperation.invokeConstructor); | |
| 248 references.add(serializer.serializeTypeRef(element.returnType, null)); | |
| 249 strings.add(element.name); | |
| 250 // TODO(scheglov) named arguments? | |
|
Paul Berry
2016/01/19 20:02:10
Oh yeah, good catch. Let me know if you want to b
| |
| 251 ints.add(arguments.length); | |
| 252 } | |
| 253 | |
| 254 void _serializeListLiteral(ListLiteral expr) { | |
| 255 List<Expression> elements = expr.elements; | |
| 256 elements.forEach(serialize); | |
| 257 DartType typeArgument; | |
| 258 if (expr.typeArguments != null && | |
| 259 expr.typeArguments.arguments.length == 1) { | |
| 260 typeArgument = expr.typeArguments.arguments[0].type; | |
| 261 } else { | |
| 262 typeArgument = serializer.typeProvider.dynamicType; | |
| 263 } | |
| 264 references.add(serializer.serializeTypeRef(typeArgument, null)); | |
| 265 ints.add(elements.length); | |
| 266 operations.add(UnlinkedConstOperation.makeList); | |
| 267 } | |
| 268 | |
| 269 void _serializeMapLiteral(MapLiteral expr) { | |
| 270 for (MapLiteralEntry entry in expr.entries) { | |
| 271 serialize(entry.key); | |
| 272 serialize(entry.value); | |
| 273 } | |
| 274 DartType keyTypeArgument; | |
| 275 DartType valueTypeArgument; | |
| 276 if (expr.typeArguments != null && | |
| 277 expr.typeArguments.arguments.length == 2) { | |
| 278 keyTypeArgument = expr.typeArguments.arguments[0].type; | |
| 279 valueTypeArgument = expr.typeArguments.arguments[1].type; | |
| 280 } else { | |
| 281 keyTypeArgument = serializer.typeProvider.dynamicType; | |
| 282 valueTypeArgument = serializer.typeProvider.dynamicType; | |
| 283 } | |
| 284 references.add(serializer.serializeTypeRef(keyTypeArgument, null)); | |
| 285 references.add(serializer.serializeTypeRef(valueTypeArgument, null)); | |
| 286 ints.add(expr.entries.length); | |
| 287 operations.add(UnlinkedConstOperation.makeMap); | |
| 288 } | |
| 289 | |
| 290 void _serializePrefixExpression(PrefixExpression expr) { | |
| 291 serialize(expr.operand); | |
| 292 TokenType operator = expr.operator.type; | |
| 293 if (operator == TokenType.BANG) { | |
| 294 operations.add(UnlinkedConstOperation.not); | |
| 295 } else if (operator == TokenType.TILDE) { | |
| 296 operations.add(UnlinkedConstOperation.complement); | |
| 297 } else { | |
| 298 throw new _ConstExprSerializationError('Unknown operator: $operator'); | |
| 299 } | |
| 300 } | |
| 301 | |
| 302 void _serializeString(StringLiteral expr) { | |
| 303 if (expr is AdjacentStrings) { | |
| 304 operations.add(UnlinkedConstOperation.pushString); | |
|
Paul Berry
2016/01/19 20:02:10
I think this does the wrong thing if one or more o
scheglov
2016/01/19 20:59:28
Done.
| |
| 305 strings.add(expr.stringValue); | |
| 306 } else if (expr is SimpleStringLiteral) { | |
| 307 operations.add(UnlinkedConstOperation.pushString); | |
| 308 strings.add(expr.value); | |
| 309 } else { | |
| 310 StringInterpolation interpolation = expr as StringInterpolation; | |
| 311 for (InterpolationElement element in interpolation.elements) { | |
| 312 if (element is InterpolationString) { | |
| 313 operations.add(UnlinkedConstOperation.pushString); | |
| 314 strings.add(element.value); | |
| 315 } else { | |
| 316 serialize((element as InterpolationExpression).expression); | |
| 317 } | |
| 318 } | |
| 319 operations.add(UnlinkedConstOperation.concatenate); | |
| 320 ints.add(interpolation.elements.length); | |
| 321 } | |
| 322 } | |
| 323 } | |
| 324 | |
| 325 /** | |
| 326 * Instances of this class keep track of intermediate state during | |
| 327 * serialization of a single library. | |
| 55 */ | 328 */ |
| 56 class _LibrarySerializer { | 329 class _LibrarySerializer { |
| 57 /** | 330 /** |
| 58 * The library to be serialized. | 331 * The library to be serialized. |
| 59 */ | 332 */ |
| 60 final LibraryElement libraryElement; | 333 final LibraryElement libraryElement; |
| 61 | 334 |
| 62 /** | 335 /** |
| 63 * The type provider. This is used to locate the library for `dart:core`. | 336 * The type provider. This is used to locate the library for `dart:core`. |
| 64 */ | 337 */ |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 378 UnlinkedCombinatorBuilder b = new UnlinkedCombinatorBuilder(); | 651 UnlinkedCombinatorBuilder b = new UnlinkedCombinatorBuilder(); |
| 379 if (combinator is ShowElementCombinator) { | 652 if (combinator is ShowElementCombinator) { |
| 380 b.shows = combinator.shownNames; | 653 b.shows = combinator.shownNames; |
| 381 } else if (combinator is HideElementCombinator) { | 654 } else if (combinator is HideElementCombinator) { |
| 382 b.hides = combinator.hiddenNames; | 655 b.hides = combinator.hiddenNames; |
| 383 } | 656 } |
| 384 return b; | 657 return b; |
| 385 } | 658 } |
| 386 | 659 |
| 387 /** | 660 /** |
| 661 * Serialize the given [expression], creating an [UnlinkedConstBuilder]. | |
| 662 */ | |
| 663 UnlinkedConstBuilder serializeConstExpr(Expression expression) { | |
| 664 _ConstExprSerializer serializer = new _ConstExprSerializer(this); | |
| 665 serializer.serialize(expression); | |
| 666 return serializer.toBuilder(); | |
| 667 } | |
| 668 | |
| 669 /** | |
| 388 * Return the index of the entry in the dependency table | 670 * Return the index of the entry in the dependency table |
| 389 * ([LinkedLibrary.dependencies]) for the given [dependentLibrary]. A new | 671 * ([LinkedLibrary.dependencies]) for the given [dependentLibrary]. A new |
| 390 * entry is added to the table if necessary to satisfy the request. | 672 * entry is added to the table if necessary to satisfy the request. |
| 391 */ | 673 */ |
| 392 int serializeDependency(LibraryElement dependentLibrary) { | 674 int serializeDependency(LibraryElement dependentLibrary) { |
| 393 return dependencyMap.putIfAbsent(dependentLibrary, () { | 675 return dependencyMap.putIfAbsent(dependentLibrary, () { |
| 394 int index = dependencies.length; | 676 int index = dependencies.length; |
| 395 List<String> parts = dependentLibrary.parts | 677 List<String> parts = dependentLibrary.parts |
| 396 .map((CompilationUnitElement e) => e.source.uri.toString()) | 678 .map((CompilationUnitElement e) => e.source.uri.toString()) |
| 397 .toList(); | 679 .toList(); |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 557 for (String name in exportedNames) { | 839 for (String name in exportedNames) { |
| 558 if (libraryElement.publicNamespace.definedNames.containsKey(name)) { | 840 if (libraryElement.publicNamespace.definedNames.containsKey(name)) { |
| 559 continue; | 841 continue; |
| 560 } | 842 } |
| 561 Element element = libraryElement.exportNamespace.get(name); | 843 Element element = libraryElement.exportNamespace.get(name); |
| 562 LibraryElement dependentLibrary = element.library; | 844 LibraryElement dependentLibrary = element.library; |
| 563 CompilationUnitElement unitElement = | 845 CompilationUnitElement unitElement = |
| 564 element.getAncestor((Element e) => e is CompilationUnitElement); | 846 element.getAncestor((Element e) => e is CompilationUnitElement); |
| 565 int unit = dependentLibrary.units.indexOf(unitElement); | 847 int unit = dependentLibrary.units.indexOf(unitElement); |
| 566 assert(unit != -1); | 848 assert(unit != -1); |
| 567 ReferenceKind kind; | 849 ReferenceKind kind = _getReferenceKind(element); |
| 568 if (element is PropertyAccessorElement) { | |
| 569 kind = ReferenceKind.topLevelPropertyAccessor; | |
| 570 } else if (element is FunctionTypeAliasElement) { | |
| 571 kind = ReferenceKind.typedef; | |
| 572 } else if (element is ClassElement) { | |
| 573 kind = ReferenceKind.classOrEnum; | |
| 574 } else if (element is FunctionElement) { | |
| 575 kind = ReferenceKind.topLevelFunction; | |
| 576 } else { | |
| 577 throw new Exception('Unexpected element kind: ${element.runtimeType}'); | |
| 578 } | |
| 579 exportNames.add(new LinkedExportNameBuilder( | 850 exportNames.add(new LinkedExportNameBuilder( |
| 580 name: name, | 851 name: name, |
| 581 dependency: serializeDependency(dependentLibrary), | 852 dependency: serializeDependency(dependentLibrary), |
| 582 unit: unit, | 853 unit: unit, |
| 583 kind: kind)); | 854 kind: kind)); |
| 584 } | 855 } |
| 585 pb.exportNames = exportNames; | 856 pb.exportNames = exportNames; |
| 586 return pb; | 857 return pb; |
| 587 } | 858 } |
| 588 | 859 |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 687 Element element = type.element; | 958 Element element = type.element; |
| 688 LibraryElement dependentLibrary = element.library; | 959 LibraryElement dependentLibrary = element.library; |
| 689 if (dependentLibrary == null) { | 960 if (dependentLibrary == null) { |
| 690 assert(type.isDynamic); | 961 assert(type.isDynamic); |
| 691 if (type is UndefinedTypeImpl) { | 962 if (type is UndefinedTypeImpl) { |
| 692 b.reference = serializeUnresolvedReference(); | 963 b.reference = serializeUnresolvedReference(); |
| 693 } else { | 964 } else { |
| 694 b.reference = serializeDynamicReference(); | 965 b.reference = serializeDynamicReference(); |
| 695 } | 966 } |
| 696 } else { | 967 } else { |
| 697 b.reference = referenceMap.putIfAbsent(element, () { | 968 b.reference = _getElementReferenceId(element); |
| 698 assert(unlinkedReferences.length == linkedReferences.length); | |
| 699 CompilationUnitElement unitElement = | |
| 700 element.getAncestor((Element e) => e is CompilationUnitElement); | |
| 701 int unit = dependentLibrary.units.indexOf(unitElement); | |
| 702 assert(unit != -1); | |
| 703 int numTypeParameters = 0; | |
| 704 if (element is TypeParameterizedElement) { | |
| 705 numTypeParameters = element.typeParameters.length; | |
| 706 } | |
| 707 // Figure out a prefix that may be used to refer to the given type. | |
| 708 // TODO(paulberry): to avoid subtle relinking inconsistencies we | |
| 709 // should use the actual prefix from the AST (a given type may be | |
| 710 // reachable via multiple prefixes), but sadly, this information is | |
| 711 // not recorded in the element model. | |
| 712 int prefixReference = 0; | |
| 713 PrefixElement prefix = prefixMap[element]; | |
| 714 if (prefix != null) { | |
| 715 prefixReference = serializePrefix(prefix); | |
| 716 } | |
| 717 int index = unlinkedReferences.length; | |
| 718 unlinkedReferences.add(new UnlinkedReferenceBuilder( | |
| 719 name: element.name, prefixReference: prefixReference)); | |
| 720 linkedReferences.add(new LinkedReferenceBuilder( | |
| 721 dependency: serializeDependency(dependentLibrary), | |
| 722 kind: element is FunctionTypeAliasElement | |
| 723 ? ReferenceKind.typedef | |
| 724 : ReferenceKind.classOrEnum, | |
| 725 unit: unit, | |
| 726 numTypeParameters: numTypeParameters)); | |
| 727 return index; | |
| 728 }); | |
| 729 } | 969 } |
| 730 List<DartType> typeArguments; | 970 List<DartType> typeArguments; |
| 731 if (type is InterfaceType) { | 971 if (type is InterfaceType) { |
| 732 typeArguments = type.typeArguments; | 972 typeArguments = type.typeArguments; |
| 733 } else if (type is FunctionType) { | 973 } else if (type is FunctionType) { |
| 734 typeArguments = type.typeArguments; | 974 typeArguments = type.typeArguments; |
| 735 } | 975 } |
| 736 if (typeArguments != null && | 976 if (typeArguments != null && |
| 737 typeArguments.any((DartType argument) => !argument.isDynamic)) { | 977 typeArguments.any((DartType argument) => !argument.isDynamic)) { |
| 738 b.typeArguments = typeArguments | 978 b.typeArguments = typeArguments |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 771 UnlinkedVariableBuilder serializeVariable(PropertyInducingElement variable) { | 1011 UnlinkedVariableBuilder serializeVariable(PropertyInducingElement variable) { |
| 772 UnlinkedVariableBuilder b = new UnlinkedVariableBuilder(); | 1012 UnlinkedVariableBuilder b = new UnlinkedVariableBuilder(); |
| 773 b.name = variable.name; | 1013 b.name = variable.name; |
| 774 b.nameOffset = variable.nameOffset; | 1014 b.nameOffset = variable.nameOffset; |
| 775 b.type = serializeTypeRef(variable.type, variable); | 1015 b.type = serializeTypeRef(variable.type, variable); |
| 776 b.isStatic = variable.isStatic && variable.enclosingElement is ClassElement; | 1016 b.isStatic = variable.isStatic && variable.enclosingElement is ClassElement; |
| 777 b.isFinal = variable.isFinal; | 1017 b.isFinal = variable.isFinal; |
| 778 b.isConst = variable.isConst; | 1018 b.isConst = variable.isConst; |
| 779 b.hasImplicitType = variable.hasImplicitType; | 1019 b.hasImplicitType = variable.hasImplicitType; |
| 780 b.documentationComment = serializeDocumentation(variable); | 1020 b.documentationComment = serializeDocumentation(variable); |
| 1021 if (variable.isConst && variable is ConstVariableElement) { | |
| 1022 ConstVariableElement constVariable = variable as ConstVariableElement; | |
| 1023 Expression initializer = constVariable.constantInitializer; | |
| 1024 if (initializer != null) { | |
| 1025 b.constExpr = serializeConstExpr(initializer); | |
| 1026 } | |
| 1027 } | |
| 781 return b; | 1028 return b; |
| 782 } | 1029 } |
| 1030 | |
| 1031 int _getElementReferenceId(Element element) { | |
| 1032 LibraryElement dependentLibrary = element.library; | |
| 1033 return referenceMap.putIfAbsent(element, () { | |
| 1034 assert(unlinkedReferences.length == linkedReferences.length); | |
| 1035 CompilationUnitElement unitElement = | |
| 1036 element.getAncestor((Element e) => e is CompilationUnitElement); | |
| 1037 int unit = dependentLibrary.units.indexOf(unitElement); | |
| 1038 assert(unit != -1); | |
| 1039 int numTypeParameters = 0; | |
| 1040 if (element is TypeParameterizedElement) { | |
| 1041 numTypeParameters = element.typeParameters.length; | |
| 1042 } | |
| 1043 // Figure out a prefix that may be used to refer to the given type. | |
| 1044 // TODO(paulberry): to avoid subtle relinking inconsistencies we | |
| 1045 // should use the actual prefix from the AST (a given type may be | |
| 1046 // reachable via multiple prefixes), but sadly, this information is | |
| 1047 // not recorded in the element model. | |
| 1048 int prefixReference = 0; | |
| 1049 PrefixElement prefix = prefixMap[element]; | |
| 1050 if (prefix != null) { | |
| 1051 prefixReference = serializePrefix(prefix); | |
| 1052 } | |
| 1053 int index = unlinkedReferences.length; | |
| 1054 unlinkedReferences.add(new UnlinkedReferenceBuilder( | |
| 1055 name: element.name, prefixReference: prefixReference)); | |
| 1056 linkedReferences.add(new LinkedReferenceBuilder( | |
| 1057 dependency: serializeDependency(dependentLibrary), | |
| 1058 kind: _getReferenceKind(element), | |
| 1059 unit: unit, | |
| 1060 numTypeParameters: numTypeParameters)); | |
| 1061 return index; | |
| 1062 }); | |
| 1063 } | |
| 1064 | |
| 1065 ReferenceKind _getReferenceKind(Element element) { | |
| 1066 ReferenceKind kind; | |
| 1067 if (element is PropertyAccessorElement) { | |
| 1068 kind = ReferenceKind.topLevelPropertyAccessor; | |
| 1069 } else if (element is FunctionTypeAliasElement) { | |
| 1070 kind = ReferenceKind.typedef; | |
| 1071 } else if (element is ClassElement) { | |
| 1072 kind = ReferenceKind.classOrEnum; | |
| 1073 } else if (element is FunctionElement) { | |
| 1074 kind = ReferenceKind.topLevelFunction; | |
| 1075 } else { | |
| 1076 throw new Exception('Unexpected element kind: ${element.runtimeType}'); | |
| 1077 } | |
| 1078 return kind; | |
| 1079 } | |
| 783 } | 1080 } |
| OLD | NEW |