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 file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library serialization.summarize_ast; | 5 library serialization.summarize_ast; |
6 | 6 |
7 import 'package:analyzer/dart/ast/ast.dart'; | 7 import 'package:analyzer/dart/ast/ast.dart'; |
8 import 'package:analyzer/dart/ast/token.dart'; | 8 import 'package:analyzer/dart/ast/token.dart'; |
9 import 'package:analyzer/dart/ast/visitor.dart'; | 9 import 'package:analyzer/dart/ast/visitor.dart'; |
10 import 'package:analyzer/dart/element/type.dart' show DartType; | 10 import 'package:analyzer/dart/element/type.dart' show DartType; |
(...skipping 25 matching lines...) Expand all Loading... |
36 * siblings. | 36 * siblings. |
37 */ | 37 */ |
38 final Map<int, int> localClosureIndexMap; | 38 final Map<int, int> localClosureIndexMap; |
39 | 39 |
40 /** | 40 /** |
41 * If the expression being serialized appears inside a function body, the name
s | 41 * If the expression being serialized appears inside a function body, the name
s |
42 * of parameters that are in scope. Otherwise `null`. | 42 * of parameters that are in scope. Otherwise `null`. |
43 */ | 43 */ |
44 final Set<String> parameterNames; | 44 final Set<String> parameterNames; |
45 | 45 |
46 _ConstExprSerializer( | 46 _ConstExprSerializer(bool forConst, this.visitor, this.localClosureIndexMap, |
47 this.visitor, this.localClosureIndexMap, this.parameterNames); | 47 this.parameterNames) |
| 48 : super(forConst); |
48 | 49 |
49 @override | 50 @override |
50 bool isParameterName(String name) { | 51 bool isParameterName(String name) { |
51 return parameterNames?.contains(name) ?? false; | 52 return parameterNames?.contains(name) ?? false; |
52 } | 53 } |
53 | 54 |
54 @override | 55 @override |
55 void serializeAnnotation(Annotation annotation) { | 56 void serializeAnnotation(Annotation annotation) { |
56 Identifier name = annotation.name; | 57 Identifier name = annotation.name; |
57 EntityRefBuilder constructor; | 58 EntityRefBuilder constructor; |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 List<UnlinkedExprBuilder> serializeAnnotations( | 407 List<UnlinkedExprBuilder> serializeAnnotations( |
407 NodeList<Annotation> annotations) { | 408 NodeList<Annotation> annotations) { |
408 if (annotations == null || annotations.isEmpty) { | 409 if (annotations == null || annotations.isEmpty) { |
409 return const <UnlinkedExprBuilder>[]; | 410 return const <UnlinkedExprBuilder>[]; |
410 } | 411 } |
411 return annotations.map((Annotation a) { | 412 return annotations.map((Annotation a) { |
412 // Closures can't appear inside annotations, so we don't need a | 413 // Closures can't appear inside annotations, so we don't need a |
413 // localClosureIndexMap. | 414 // localClosureIndexMap. |
414 Map<int, int> localClosureIndexMap = null; | 415 Map<int, int> localClosureIndexMap = null; |
415 _ConstExprSerializer serializer = | 416 _ConstExprSerializer serializer = |
416 new _ConstExprSerializer(this, localClosureIndexMap, null); | 417 new _ConstExprSerializer(true, this, localClosureIndexMap, null); |
417 try { | 418 try { |
418 serializer.serializeAnnotation(a); | 419 serializer.serializeAnnotation(a); |
419 } on StateError { | 420 } on StateError { |
420 return new UnlinkedExprBuilder()..isValidConst = false; | 421 return new UnlinkedExprBuilder()..isValidConst = false; |
421 } | 422 } |
422 return serializer.toBuilder(); | 423 return serializer.toBuilder(); |
423 }).toList(); | 424 }).toList(); |
424 } | 425 } |
425 | 426 |
426 /** | 427 /** |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
542 b.variables = variables; | 543 b.variables = variables; |
543 b.publicNamespace = computePublicNamespace(compilationUnit); | 544 b.publicNamespace = computePublicNamespace(compilationUnit); |
544 _computeApiSignature(b); | 545 _computeApiSignature(b); |
545 return b; | 546 return b; |
546 } | 547 } |
547 | 548 |
548 /** | 549 /** |
549 * Serialize the given [expression], creating an [UnlinkedExprBuilder]. | 550 * Serialize the given [expression], creating an [UnlinkedExprBuilder]. |
550 */ | 551 */ |
551 UnlinkedExprBuilder serializeConstExpr( | 552 UnlinkedExprBuilder serializeConstExpr( |
552 Map<int, int> localClosureIndexMap, Expression expression, | 553 bool forConst, Map<int, int> localClosureIndexMap, Expression expression, |
553 [Set<String> parameterNames]) { | 554 [Set<String> parameterNames]) { |
554 _ConstExprSerializer serializer = | 555 _ConstExprSerializer serializer = new _ConstExprSerializer( |
555 new _ConstExprSerializer(this, localClosureIndexMap, parameterNames); | 556 forConst, this, localClosureIndexMap, parameterNames); |
556 serializer.serialize(expression); | 557 serializer.serialize(expression); |
557 return serializer.toBuilder(); | 558 return serializer.toBuilder(); |
558 } | 559 } |
559 | 560 |
560 /** | 561 /** |
561 * Serialize the given [declaredIdentifier] into [UnlinkedVariable], and | 562 * Serialize the given [declaredIdentifier] into [UnlinkedVariable], and |
562 * store it in [variables]. | 563 * store it in [variables]. |
563 */ | 564 */ |
564 void serializeDeclaredIdentifier( | 565 void serializeDeclaredIdentifier( |
565 AstNode scopeNode, | 566 AstNode scopeNode, |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
685 } | 686 } |
686 b.visibleOffset = enclosingBlock?.offset; | 687 b.visibleOffset = enclosingBlock?.offset; |
687 b.visibleLength = enclosingBlock?.length; | 688 b.visibleLength = enclosingBlock?.length; |
688 Set<String> oldParameterNames = _parameterNames; | 689 Set<String> oldParameterNames = _parameterNames; |
689 if (formalParameters != null && formalParameters.parameters.isNotEmpty) { | 690 if (formalParameters != null && formalParameters.parameters.isNotEmpty) { |
690 _parameterNames = | 691 _parameterNames = |
691 _parameterNames == null ? new Set<String>() : _parameterNames.toSet(); | 692 _parameterNames == null ? new Set<String>() : _parameterNames.toSet(); |
692 _parameterNames.addAll(formalParameters.parameters | 693 _parameterNames.addAll(formalParameters.parameters |
693 .map((FormalParameter p) => p.identifier.name)); | 694 .map((FormalParameter p) => p.identifier.name)); |
694 } | 695 } |
695 serializeFunctionBody(b, null, body, serializeBodyExpr, serializeBody); | 696 serializeFunctionBody( |
| 697 b, null, body, serializeBodyExpr, serializeBody, false); |
696 _parameterNames = oldParameterNames; | 698 _parameterNames = oldParameterNames; |
697 scopes.removeLast(); | 699 scopes.removeLast(); |
698 assert(scopes.length == oldScopesLength); | 700 assert(scopes.length == oldScopesLength); |
699 return b; | 701 return b; |
700 } | 702 } |
701 | 703 |
702 /** | 704 /** |
703 * Record local functions and variables into the given executable. The given | 705 * Record local functions and variables into the given executable. The given |
704 * [body] is usually an actual [FunctionBody], but may be an [Expression] | 706 * [body] is usually an actual [FunctionBody], but may be an [Expression] |
705 * when we process a synthetic variable initializer function. | 707 * when we process a synthetic variable initializer function. |
706 * | 708 * |
707 * If [initializers] is non-`null`, closures occurring inside the initializers | 709 * If [initializers] is non-`null`, closures occurring inside the initializers |
708 * are serialized first. | 710 * are serialized first. |
709 * | 711 * |
710 * If [serializeBodyExpr] is `true`, then the function definition is stored | 712 * If [serializeBodyExpr] is `true`, then the function definition is stored |
711 * in [UnlinkedExecutableBuilder.bodyExpr], and closures occurring inside | 713 * in [UnlinkedExecutableBuilder.bodyExpr], and closures occurring inside |
712 * [initializers] and [body] have their function bodies serialized as well. | 714 * [initializers] and [body] have their function bodies serialized as well. |
713 * | 715 * |
714 * The return value is a map whose keys are the offsets of local function | 716 * The return value is a map whose keys are the offsets of local function |
715 * nodes representing closures inside [initializers] and [body], and whose | 717 * nodes representing closures inside [initializers] and [body], and whose |
716 * values are the indices of those local functions relative to their siblings. | 718 * values are the indices of those local functions relative to their siblings. |
717 */ | 719 */ |
718 Map<int, int> serializeFunctionBody( | 720 Map<int, int> serializeFunctionBody( |
719 UnlinkedExecutableBuilder b, | 721 UnlinkedExecutableBuilder b, |
720 List<ConstructorInitializer> initializers, | 722 List<ConstructorInitializer> initializers, |
721 AstNode body, | 723 AstNode body, |
722 bool serializeBodyExpr, | 724 bool serializeBodyExpr, |
723 bool serializeBody) { | 725 bool serializeBody, |
| 726 bool forConst) { |
724 if (body is BlockFunctionBody || body is ExpressionFunctionBody) { | 727 if (body is BlockFunctionBody || body is ExpressionFunctionBody) { |
725 for (UnlinkedParamBuilder parameter in b.parameters) { | 728 for (UnlinkedParamBuilder parameter in b.parameters) { |
726 if (!parameter.isInitializingFormal) { | 729 if (!parameter.isInitializingFormal) { |
727 parameter.visibleOffset = body.offset; | 730 parameter.visibleOffset = body.offset; |
728 parameter.visibleLength = body.length; | 731 parameter.visibleLength = body.length; |
729 } | 732 } |
730 } | 733 } |
731 } | 734 } |
732 List<UnlinkedExecutableBuilder> oldExecutables = executables; | 735 List<UnlinkedExecutableBuilder> oldExecutables = executables; |
733 List<UnlinkedLabelBuilder> oldLabels = labels; | 736 List<UnlinkedLabelBuilder> oldLabels = labels; |
734 List<UnlinkedVariableBuilder> oldVariables = variables; | 737 List<UnlinkedVariableBuilder> oldVariables = variables; |
735 Map<int, int> oldLocalClosureIndexMap = _localClosureIndexMap; | 738 Map<int, int> oldLocalClosureIndexMap = _localClosureIndexMap; |
736 bool oldSerializeClosureBodyExprs = _serializeClosureBodyExprs; | 739 bool oldSerializeClosureBodyExprs = _serializeClosureBodyExprs; |
737 executables = <UnlinkedExecutableBuilder>[]; | 740 executables = <UnlinkedExecutableBuilder>[]; |
738 labels = <UnlinkedLabelBuilder>[]; | 741 labels = <UnlinkedLabelBuilder>[]; |
739 variables = <UnlinkedVariableBuilder>[]; | 742 variables = <UnlinkedVariableBuilder>[]; |
740 _localClosureIndexMap = <int, int>{}; | 743 _localClosureIndexMap = <int, int>{}; |
741 _serializeClosureBodyExprs = serializeBodyExpr; | 744 _serializeClosureBodyExprs = serializeBodyExpr; |
742 if (initializers != null) { | 745 if (initializers != null) { |
743 for (ConstructorInitializer initializer in initializers) { | 746 for (ConstructorInitializer initializer in initializers) { |
744 initializer.accept(this); | 747 initializer.accept(this); |
745 } | 748 } |
746 } | 749 } |
747 if (serializeBody) { | 750 if (serializeBody) { |
748 body.accept(this); | 751 body.accept(this); |
749 } | 752 } |
750 if (serializeBodyExpr) { | 753 if (serializeBodyExpr) { |
751 if (body is Expression) { | 754 if (body is Expression) { |
752 b.bodyExpr = | 755 b.bodyExpr = serializeConstExpr( |
753 serializeConstExpr(_localClosureIndexMap, body, _parameterNames); | 756 forConst, _localClosureIndexMap, body, _parameterNames); |
754 } else if (body is ExpressionFunctionBody) { | 757 } else if (body is ExpressionFunctionBody) { |
755 b.bodyExpr = serializeConstExpr( | 758 b.bodyExpr = serializeConstExpr( |
756 _localClosureIndexMap, body.expression, _parameterNames); | 759 forConst, _localClosureIndexMap, body.expression, _parameterNames); |
757 } else { | 760 } else { |
758 // TODO(paulberry): serialize other types of function bodies. | 761 // TODO(paulberry): serialize other types of function bodies. |
759 } | 762 } |
760 } | 763 } |
761 b.localFunctions = executables; | 764 b.localFunctions = executables; |
762 b.localLabels = labels; | 765 b.localLabels = labels; |
763 b.localVariables = variables; | 766 b.localVariables = variables; |
764 Map<int, int> localClosureIndexMap = _localClosureIndexMap; | 767 Map<int, int> localClosureIndexMap = _localClosureIndexMap; |
765 executables = oldExecutables; | 768 executables = oldExecutables; |
766 labels = oldLabels; | 769 labels = oldLabels; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
809 } | 812 } |
810 | 813 |
811 /** | 814 /** |
812 * If the given [expression] is not `null`, serialize it as an | 815 * If the given [expression] is not `null`, serialize it as an |
813 * [UnlinkedExecutableBuilder], otherwise return `null`. | 816 * [UnlinkedExecutableBuilder], otherwise return `null`. |
814 * | 817 * |
815 * If [serializeBodyExpr] is `true`, then the initializer expression is stored | 818 * If [serializeBodyExpr] is `true`, then the initializer expression is stored |
816 * in [UnlinkedExecutableBuilder.bodyExpr]. | 819 * in [UnlinkedExecutableBuilder.bodyExpr]. |
817 */ | 820 */ |
818 UnlinkedExecutableBuilder serializeInitializerFunction( | 821 UnlinkedExecutableBuilder serializeInitializerFunction( |
819 Expression expression, bool serializeBodyExpr) { | 822 Expression expression, bool serializeBodyExpr, bool forConst) { |
820 if (expression == null) { | 823 if (expression == null) { |
821 return null; | 824 return null; |
822 } | 825 } |
823 UnlinkedExecutableBuilder initializer = | 826 UnlinkedExecutableBuilder initializer = |
824 new UnlinkedExecutableBuilder(nameOffset: expression.offset); | 827 new UnlinkedExecutableBuilder(nameOffset: expression.offset); |
825 serializeFunctionBody( | 828 serializeFunctionBody( |
826 initializer, null, expression, serializeBodyExpr, true); | 829 initializer, null, expression, serializeBodyExpr, true, forConst); |
827 initializer.inferredReturnTypeSlot = assignSlot(); | 830 initializer.inferredReturnTypeSlot = assignSlot(); |
828 return initializer; | 831 return initializer; |
829 } | 832 } |
830 | 833 |
831 /** | 834 /** |
832 * Serialize a [FieldFormalParameter], [FunctionTypedFormalParameter], or | 835 * Serialize a [FieldFormalParameter], [FunctionTypedFormalParameter], or |
833 * [SimpleFormalParameter] into an [UnlinkedParam]. | 836 * [SimpleFormalParameter] into an [UnlinkedParam]. |
834 */ | 837 */ |
835 UnlinkedParamBuilder serializeParameter(NormalFormalParameter node) { | 838 UnlinkedParamBuilder serializeParameter(NormalFormalParameter node) { |
836 UnlinkedParamBuilder b = new UnlinkedParamBuilder(); | 839 UnlinkedParamBuilder b = new UnlinkedParamBuilder(); |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1016 b.isStatic = isDeclaredStatic; | 1019 b.isStatic = isDeclaredStatic; |
1017 b.name = variable.name.name; | 1020 b.name = variable.name.name; |
1018 b.nameOffset = variable.name.offset; | 1021 b.nameOffset = variable.name.offset; |
1019 b.type = serializeTypeName(variables.type); | 1022 b.type = serializeTypeName(variables.type); |
1020 b.documentationComment = serializeDocumentation(documentationComment); | 1023 b.documentationComment = serializeDocumentation(documentationComment); |
1021 b.annotations = serializeAnnotations(annotations); | 1024 b.annotations = serializeAnnotations(annotations); |
1022 b.codeRange = serializeCodeRange(variables.parent); | 1025 b.codeRange = serializeCodeRange(variables.parent); |
1023 bool serializeBodyExpr = variable.isConst || | 1026 bool serializeBodyExpr = variable.isConst || |
1024 variable.isFinal && isField && !isDeclaredStatic || | 1027 variable.isFinal && isField && !isDeclaredStatic || |
1025 variables.type == null; | 1028 variables.type == null; |
1026 b.initializer = | 1029 b.initializer = serializeInitializerFunction( |
1027 serializeInitializerFunction(variable.initializer, serializeBodyExpr); | 1030 variable.initializer, serializeBodyExpr, b.isConst); |
1028 if (isField && !isDeclaredStatic && !variables.isFinal) { | 1031 if (isField && !isDeclaredStatic && !variables.isFinal) { |
1029 b.inheritsCovariantSlot = assignSlot(); | 1032 b.inheritsCovariantSlot = assignSlot(); |
1030 } | 1033 } |
1031 if (variable.initializer != null && | 1034 if (variable.initializer != null && |
1032 (variables.isFinal || variables.isConst)) { | 1035 (variables.isFinal || variables.isConst)) { |
1033 b.propagatedTypeSlot = assignSlot(); | 1036 b.propagatedTypeSlot = assignSlot(); |
1034 } | 1037 } |
1035 bool isSemanticallyStatic = !isField || isDeclaredStatic; | 1038 bool isSemanticallyStatic = !isField || isDeclaredStatic; |
1036 if (variables.type == null && | 1039 if (variables.type == null && |
1037 (variable.initializer != null || !isSemanticallyStatic)) { | 1040 (variable.initializer != null || !isSemanticallyStatic)) { |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1119 b.kind = UnlinkedExecutableKind.constructor; | 1122 b.kind = UnlinkedExecutableKind.constructor; |
1120 if (node.factoryKeyword != null) { | 1123 if (node.factoryKeyword != null) { |
1121 b.isFactory = true; | 1124 b.isFactory = true; |
1122 if (node.redirectedConstructor != null) { | 1125 if (node.redirectedConstructor != null) { |
1123 b.isRedirectedConstructor = true; | 1126 b.isRedirectedConstructor = true; |
1124 TypeName typeName = node.redirectedConstructor.type; | 1127 TypeName typeName = node.redirectedConstructor.type; |
1125 // Closures can't appear inside factory constructor redirections, so we | 1128 // Closures can't appear inside factory constructor redirections, so we |
1126 // don't need a localClosureIndexMap. | 1129 // don't need a localClosureIndexMap. |
1127 Map<int, int> localClosureIndexMap = null; | 1130 Map<int, int> localClosureIndexMap = null; |
1128 b.redirectedConstructor = | 1131 b.redirectedConstructor = |
1129 new _ConstExprSerializer(this, localClosureIndexMap, null) | 1132 new _ConstExprSerializer(true, this, localClosureIndexMap, null) |
1130 .serializeConstructorRef(null, typeName.name, | 1133 .serializeConstructorRef(null, typeName.name, |
1131 typeName.typeArguments, node.redirectedConstructor.name); | 1134 typeName.typeArguments, node.redirectedConstructor.name); |
1132 } | 1135 } |
1133 } else { | 1136 } else { |
1134 for (ConstructorInitializer initializer in node.initializers) { | 1137 for (ConstructorInitializer initializer in node.initializers) { |
1135 if (initializer is RedirectingConstructorInvocation) { | 1138 if (initializer is RedirectingConstructorInvocation) { |
1136 b.isRedirectedConstructor = true; | 1139 b.isRedirectedConstructor = true; |
1137 b.redirectedConstructorName = initializer.constructorName?.name; | 1140 b.redirectedConstructorName = initializer.constructorName?.name; |
1138 } | 1141 } |
1139 } | 1142 } |
1140 } | 1143 } |
1141 if (node.constKeyword != null) { | 1144 if (node.constKeyword != null) { |
1142 b.isConst = true; | 1145 b.isConst = true; |
1143 b.constCycleSlot = assignSlot(); | 1146 b.constCycleSlot = assignSlot(); |
1144 } | 1147 } |
1145 b.isExternal = | 1148 b.isExternal = |
1146 node.externalKeyword != null || node.body is NativeFunctionBody; | 1149 node.externalKeyword != null || node.body is NativeFunctionBody; |
1147 b.documentationComment = serializeDocumentation(node.documentationComment); | 1150 b.documentationComment = serializeDocumentation(node.documentationComment); |
1148 b.annotations = serializeAnnotations(node.metadata); | 1151 b.annotations = serializeAnnotations(node.metadata); |
1149 b.codeRange = serializeCodeRange(node); | 1152 b.codeRange = serializeCodeRange(node); |
1150 Map<int, int> localClosureIndexMap = serializeFunctionBody( | 1153 Map<int, int> localClosureIndexMap = serializeFunctionBody(b, |
1151 b, node.initializers, node.body, node.constKeyword != null, false); | 1154 node.initializers, node.body, node.constKeyword != null, false, false); |
1152 if (node.constKeyword != null) { | 1155 if (node.constKeyword != null) { |
1153 Set<String> constructorParameterNames = | 1156 Set<String> constructorParameterNames = |
1154 node.parameters.parameters.map((p) => p.identifier.name).toSet(); | 1157 node.parameters.parameters.map((p) => p.identifier.name).toSet(); |
1155 b.constantInitializers = node.initializers | 1158 b.constantInitializers = node.initializers |
1156 .map((ConstructorInitializer initializer) => | 1159 .map((ConstructorInitializer initializer) => |
1157 serializeConstructorInitializer(initializer, (Expression expr) { | 1160 serializeConstructorInitializer(initializer, (Expression expr) { |
1158 return serializeConstExpr( | 1161 return serializeConstExpr(true, localClosureIndexMap, expr, |
1159 localClosureIndexMap, expr, constructorParameterNames); | 1162 constructorParameterNames); |
1160 })) | 1163 })) |
1161 .toList(); | 1164 .toList(); |
1162 } | 1165 } |
1163 executables.add(b); | 1166 executables.add(b); |
1164 } | 1167 } |
1165 | 1168 |
1166 @override | 1169 @override |
1167 UnlinkedParamBuilder visitDefaultFormalParameter( | 1170 UnlinkedParamBuilder visitDefaultFormalParameter( |
1168 DefaultFormalParameter node) { | 1171 DefaultFormalParameter node) { |
1169 UnlinkedParamBuilder b = | 1172 UnlinkedParamBuilder b = |
1170 node.parameter.accept(this) as UnlinkedParamBuilder; | 1173 node.parameter.accept(this) as UnlinkedParamBuilder; |
1171 b.initializer = serializeInitializerFunction(node.defaultValue, true); | 1174 b.initializer = serializeInitializerFunction(node.defaultValue, true, true); |
1172 if (node.defaultValue != null) { | 1175 if (node.defaultValue != null) { |
1173 b.defaultValueCode = node.defaultValue.toSource(); | 1176 b.defaultValueCode = node.defaultValue.toSource(); |
1174 } | 1177 } |
1175 b.codeRange = serializeCodeRange(node); | 1178 b.codeRange = serializeCodeRange(node); |
1176 return b; | 1179 return b; |
1177 } | 1180 } |
1178 | 1181 |
1179 @override | 1182 @override |
1180 void visitEnumDeclaration(EnumDeclaration node) { | 1183 void visitEnumDeclaration(EnumDeclaration node) { |
1181 UnlinkedEnumBuilder b = new UnlinkedEnumBuilder(); | 1184 UnlinkedEnumBuilder b = new UnlinkedEnumBuilder(); |
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1483 /** | 1486 /** |
1484 * A [_TypeParameterScope] is a [_Scope] which defines [_ScopedTypeParameter]s. | 1487 * A [_TypeParameterScope] is a [_Scope] which defines [_ScopedTypeParameter]s. |
1485 */ | 1488 */ |
1486 class _TypeParameterScope extends _Scope { | 1489 class _TypeParameterScope extends _Scope { |
1487 /** | 1490 /** |
1488 * Get the number of [_ScopedTypeParameter]s defined in this | 1491 * Get the number of [_ScopedTypeParameter]s defined in this |
1489 * [_TypeParameterScope]. | 1492 * [_TypeParameterScope]. |
1490 */ | 1493 */ |
1491 int get length => _definedNames.length; | 1494 int get length => _definedNames.length; |
1492 } | 1495 } |
OLD | NEW |