| 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 test.src.serialization.elements_test; | 5 library test.src.serialization.elements_test; |
| 6 | 6 |
| 7 import 'dart:convert'; |
| 8 |
| 7 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
| 8 import 'package:analyzer/dart/element/element.dart'; | 10 import 'package:analyzer/dart/element/element.dart'; |
| 9 import 'package:analyzer/dart/element/type.dart'; | 11 import 'package:analyzer/dart/element/type.dart'; |
| 12 import 'package:analyzer/src/dart/ast/ast.dart'; |
| 10 import 'package:analyzer/src/dart/element/element.dart'; | 13 import 'package:analyzer/src/dart/element/element.dart'; |
| 11 import 'package:analyzer/src/dart/element/member.dart'; | 14 import 'package:analyzer/src/dart/element/member.dart'; |
| 12 import 'package:analyzer/src/dart/element/type.dart'; | 15 import 'package:analyzer/src/dart/element/type.dart'; |
| 13 import 'package:analyzer/src/generated/element_handle.dart'; | 16 import 'package:analyzer/src/generated/element_handle.dart'; |
| 14 import 'package:analyzer/src/generated/engine.dart'; | 17 import 'package:analyzer/src/generated/engine.dart'; |
| 15 import 'package:analyzer/src/generated/resolver.dart' | 18 import 'package:analyzer/src/generated/resolver.dart' |
| 16 show Namespace, TypeProvider; | 19 show Namespace, TypeProvider; |
| 17 import 'package:analyzer/src/generated/source.dart'; | 20 import 'package:analyzer/src/generated/source.dart'; |
| 18 import 'package:analyzer/src/summary/idl.dart'; | 21 import 'package:analyzer/src/summary/idl.dart'; |
| 19 import 'package:analyzer/src/summary/resynthesize.dart'; | 22 import 'package:analyzer/src/summary/resynthesize.dart'; |
| 20 import 'package:analyzer/src/summary/summarize_elements.dart'; | 23 import 'package:analyzer/src/summary/summarize_elements.dart'; |
| 21 import 'package:unittest/unittest.dart'; | 24 import 'package:unittest/unittest.dart'; |
| 22 | 25 |
| 23 import '../../generated/resolver_test.dart'; | 26 import '../../generated/resolver_test.dart'; |
| 24 import '../../reflective_tests.dart'; | 27 import '../../reflective_tests.dart'; |
| 28 import 'summary_common.dart' show canonicalize; |
| 25 | 29 |
| 26 main() { | 30 main() { |
| 27 groupSep = ' | '; | 31 groupSep = ' | '; |
| 28 runReflectiveTests(ResynthTest); | 32 runReflectiveTests(ResynthTest); |
| 29 } | 33 } |
| 30 | 34 |
| 31 @reflectiveTest | 35 @reflectiveTest |
| 32 class ResynthTest extends ResolverTestCase { | 36 class ResynthTest extends ResolverTestCase { |
| 33 Set<Source> otherLibrarySources = new Set<Source>(); | 37 Set<Source> otherLibrarySources = new Set<Source>(); |
| 34 | 38 |
| 35 /** | 39 /** |
| 36 * Determine the analysis options that should be used for this test. | 40 * Determine the analysis options that should be used for this test. |
| 37 */ | 41 */ |
| 38 AnalysisOptionsImpl get options => | 42 AnalysisOptionsImpl get options => |
| 39 new AnalysisOptionsImpl()..enableGenericMethods = true; | 43 new AnalysisOptionsImpl()..enableGenericMethods = true; |
| 40 | 44 |
| 41 void addLibrary(String uri) { | 45 void addLibrary(String uri) { |
| 42 otherLibrarySources.add(analysisContext2.sourceFactory.forUri(uri)); | 46 otherLibrarySources.add(analysisContext2.sourceFactory.forUri(uri)); |
| 43 } | 47 } |
| 44 | 48 |
| 45 void addLibrarySource(String filePath, String contents) { | 49 void addLibrarySource(String filePath, String contents) { |
| 46 otherLibrarySources.add(addNamedSource(filePath, contents)); | 50 otherLibrarySources.add(addNamedSource(filePath, contents)); |
| 47 } | 51 } |
| 48 | 52 |
| 49 void checkLibrary(String text, {bool allowErrors: false}) { | 53 void checkLibrary(String text, |
| 54 {bool allowErrors: false, bool dumpSummaries: false}) { |
| 50 Source source = addSource(text); | 55 Source source = addSource(text); |
| 51 LibraryElementImpl original = resolve2(source); | 56 LibraryElementImpl original = resolve2(source); |
| 52 LibraryElementImpl resynthesized = resynthesizeLibraryElement( | 57 LibraryElementImpl resynthesized = resynthesizeLibraryElement( |
| 53 encodeLibrary(original, allowErrors: allowErrors), | 58 encodeLibrary(original, |
| 59 allowErrors: allowErrors, dumpSummaries: dumpSummaries), |
| 54 source.uri.toString(), | 60 source.uri.toString(), |
| 55 original); | 61 original); |
| 56 checkLibraryElements(original, resynthesized); | 62 checkLibraryElements(original, resynthesized); |
| 57 } | 63 } |
| 58 | 64 |
| 59 void checkLibraryElements( | 65 void checkLibraryElements( |
| 60 LibraryElementImpl original, LibraryElementImpl resynthesized) { | 66 LibraryElementImpl original, LibraryElementImpl resynthesized) { |
| 61 compareElements(resynthesized, original, '(library)'); | 67 compareElements(resynthesized, original, '(library)'); |
| 62 expect(resynthesized.displayName, original.displayName); | 68 expect(resynthesized.displayName, original.displayName); |
| 63 expect(original.enclosingElement, isNull); | 69 expect(original.enclosingElement, isNull); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 92 resynthesized.entryPoint, original.entryPoint, '(entry point)'); | 98 resynthesized.entryPoint, original.entryPoint, '(entry point)'); |
| 93 } | 99 } |
| 94 // The libraries `dart:core` and `dart:async` cannot create their | 100 // The libraries `dart:core` and `dart:async` cannot create their |
| 95 // `loadLibrary` functions until after both are created. | 101 // `loadLibrary` functions until after both are created. |
| 96 if (original.name != 'dart.core' && original.name != 'dart.async') { | 102 if (original.name != 'dart.core' && original.name != 'dart.async') { |
| 97 compareExecutableElements( | 103 compareExecutableElements( |
| 98 resynthesized.loadLibraryFunction as ExecutableElementImpl, | 104 resynthesized.loadLibraryFunction as ExecutableElementImpl, |
| 99 original.loadLibraryFunction as ExecutableElementImpl, | 105 original.loadLibraryFunction as ExecutableElementImpl, |
| 100 '(loadLibraryFunction)'); | 106 '(loadLibraryFunction)'); |
| 101 } | 107 } |
| 102 // TODO(paulberry): test metadata. | |
| 103 } | 108 } |
| 104 | 109 |
| 105 /** | 110 /** |
| 106 * Verify that the [resynthesizer] didn't do any unnecessary work when | 111 * Verify that the [resynthesizer] didn't do any unnecessary work when |
| 107 * resynthesizing [library]. | 112 * resynthesizing [library]. |
| 108 */ | 113 */ |
| 109 void checkMinimalResynthesisWork( | 114 void checkMinimalResynthesisWork( |
| 110 _TestSummaryResynthesizer resynthesizer, LibraryElement library) { | 115 _TestSummaryResynthesizer resynthesizer, LibraryElement library) { |
| 111 // Check that no other summaries needed to be resynthesized to resynthesize | 116 // Check that no other summaries needed to be resynthesized to resynthesize |
| 112 // the library element. | 117 // the library element. |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 expect(resynthesized.source, original.source); | 189 expect(resynthesized.source, original.source); |
| 185 expect(resynthesized.librarySource, original.librarySource); | 190 expect(resynthesized.librarySource, original.librarySource); |
| 186 expect(resynthesized.types.length, original.types.length); | 191 expect(resynthesized.types.length, original.types.length); |
| 187 for (int i = 0; i < resynthesized.types.length; i++) { | 192 for (int i = 0; i < resynthesized.types.length; i++) { |
| 188 compareClassElements( | 193 compareClassElements( |
| 189 resynthesized.types[i], original.types[i], original.types[i].name); | 194 resynthesized.types[i], original.types[i], original.types[i].name); |
| 190 } | 195 } |
| 191 expect(resynthesized.topLevelVariables.length, | 196 expect(resynthesized.topLevelVariables.length, |
| 192 original.topLevelVariables.length); | 197 original.topLevelVariables.length); |
| 193 for (int i = 0; i < resynthesized.topLevelVariables.length; i++) { | 198 for (int i = 0; i < resynthesized.topLevelVariables.length; i++) { |
| 199 String name = resynthesized.topLevelVariables[i].name; |
| 194 compareTopLevelVariableElements( | 200 compareTopLevelVariableElements( |
| 195 resynthesized.topLevelVariables[i], | 201 resynthesized.topLevelVariables[i], |
| 196 original.topLevelVariables[i], | 202 original.topLevelVariables |
| 197 'variable ${original.topLevelVariables[i].name}'); | 203 .singleWhere((TopLevelVariableElement e) => e.name == name), |
| 204 'variable $name'); |
| 198 } | 205 } |
| 199 expect(resynthesized.functions.length, original.functions.length); | 206 expect(resynthesized.functions.length, original.functions.length); |
| 200 for (int i = 0; i < resynthesized.functions.length; i++) { | 207 for (int i = 0; i < resynthesized.functions.length; i++) { |
| 201 compareFunctionElements(resynthesized.functions[i], original.functions[i], | 208 compareFunctionElements(resynthesized.functions[i], original.functions[i], |
| 202 'function ${original.functions[i].name}'); | 209 'function ${original.functions[i].name}'); |
| 203 } | 210 } |
| 204 expect(resynthesized.functionTypeAliases.length, | 211 expect(resynthesized.functionTypeAliases.length, |
| 205 original.functionTypeAliases.length); | 212 original.functionTypeAliases.length); |
| 206 for (int i = 0; i < resynthesized.functionTypeAliases.length; i++) { | 213 for (int i = 0; i < resynthesized.functionTypeAliases.length; i++) { |
| 207 compareFunctionTypeAliasElements( | 214 compareFunctionTypeAliasElements( |
| 208 resynthesized.functionTypeAliases[i], | 215 resynthesized.functionTypeAliases[i], |
| 209 original.functionTypeAliases[i], | 216 original.functionTypeAliases[i], |
| 210 original.functionTypeAliases[i].name); | 217 original.functionTypeAliases[i].name); |
| 211 } | 218 } |
| 212 expect(resynthesized.enums.length, original.enums.length); | 219 expect(resynthesized.enums.length, original.enums.length); |
| 213 for (int i = 0; i < resynthesized.enums.length; i++) { | 220 for (int i = 0; i < resynthesized.enums.length; i++) { |
| 214 compareClassElements( | 221 compareClassElements( |
| 215 resynthesized.enums[i], original.enums[i], original.enums[i].name); | 222 resynthesized.enums[i], original.enums[i], original.enums[i].name); |
| 216 } | 223 } |
| 217 expect(resynthesized.accessors.length, original.accessors.length); | 224 expect(resynthesized.accessors.length, original.accessors.length); |
| 218 for (int i = 0; i < resynthesized.accessors.length; i++) { | 225 for (int i = 0; i < resynthesized.accessors.length; i++) { |
| 226 String name = resynthesized.accessors[i].name; |
| 219 if (original.accessors[i].isGetter) { | 227 if (original.accessors[i].isGetter) { |
| 220 comparePropertyAccessorElements(resynthesized.accessors[i], | 228 comparePropertyAccessorElements( |
| 221 original.accessors[i], 'getter ${original.accessors[i].name}'); | 229 resynthesized.accessors[i], |
| 230 original.accessors |
| 231 .singleWhere((PropertyAccessorElement e) => e.name == name), |
| 232 'getter $name'); |
| 222 } else { | 233 } else { |
| 223 comparePropertyAccessorElements(resynthesized.accessors[i], | 234 comparePropertyAccessorElements( |
| 224 original.accessors[i], 'setter ${original.accessors[i].name}'); | 235 resynthesized.accessors[i], |
| 236 original.accessors |
| 237 .singleWhere((PropertyAccessorElement e) => e.name == name), |
| 238 'setter $name'); |
| 225 } | 239 } |
| 226 } | 240 } |
| 227 // TODO(paulberry): test metadata and offsetToElementMap. | 241 // TODO(paulberry): test metadata and offsetToElementMap. |
| 228 } | 242 } |
| 229 | 243 |
| 230 void compareConstantExpressions(Expression r, Expression o, String desc) { | 244 void compareConstantAsts(AstNode r, AstNode o, String desc) { |
| 231 void compareLists(List<Object> rItems, List<Object> oItems) { | 245 void compareLists(List<Object> rItems, List<Object> oItems) { |
| 232 if (rItems == null && oItems == null) { | 246 if (rItems == null && oItems == null) { |
| 233 return; | 247 return; |
| 234 } | 248 } |
| 235 expect(rItems != null && oItems != null, isTrue); | 249 expect(rItems != null && oItems != null, isTrue); |
| 236 expect(rItems, hasLength(oItems.length)); | 250 expect(rItems, hasLength(oItems.length)); |
| 237 for (int i = 0; i < oItems.length; i++) { | 251 for (int i = 0; i < oItems.length; i++) { |
| 238 Object rItem = rItems[i]; | 252 Object rItem = rItems[i]; |
| 239 Object oItem = oItems[i]; | 253 Object oItem = oItems[i]; |
| 240 if (rItem is Expression && oItem is Expression) { | 254 if (rItem is Expression && oItem is Expression) { |
| 241 compareConstantExpressions(rItem, oItem, desc); | 255 compareConstantAsts(rItem, oItem, desc); |
| 242 } else if (rItem is TypeName && oItem is TypeName) { | 256 } else if (rItem is TypeName && oItem is TypeName) { |
| 243 compareConstantExpressions(rItem.name, oItem.name, desc); | 257 compareConstantAsts(rItem.name, oItem.name, desc); |
| 244 } else if (rItem is InterpolationString && | 258 } else if (rItem is InterpolationString && |
| 245 oItem is InterpolationString) { | 259 oItem is InterpolationString) { |
| 246 expect(rItem.value, oItem.value); | 260 expect(rItem.value, oItem.value); |
| 247 } else if (rItem is InterpolationExpression && | 261 } else if (rItem is InterpolationExpression && |
| 248 oItem is InterpolationExpression) { | 262 oItem is InterpolationExpression) { |
| 249 compareConstantExpressions(rItem.expression, oItem.expression, desc); | 263 compareConstantAsts(rItem.expression, oItem.expression, desc); |
| 250 } else if (rItem is MapLiteralEntry && oItem is MapLiteralEntry) { | 264 } else if (rItem is MapLiteralEntry && oItem is MapLiteralEntry) { |
| 251 compareConstantExpressions(rItem.key, oItem.key, desc); | 265 compareConstantAsts(rItem.key, oItem.key, desc); |
| 252 compareConstantExpressions(rItem.value, oItem.value, desc); | 266 compareConstantAsts(rItem.value, oItem.value, desc); |
| 253 } else { | 267 } else { |
| 254 fail('$desc Incompatible item types: ' | 268 fail('$desc Incompatible item types: ' |
| 255 '${rItem.runtimeType} vs. ${oItem.runtimeType}'); | 269 '${rItem.runtimeType} vs. ${oItem.runtimeType}'); |
| 256 } | 270 } |
| 257 } | 271 } |
| 258 } | 272 } |
| 259 if (o == null) { | 273 if (o == null) { |
| 260 expect(r, isNull, reason: desc); | 274 expect(r, isNull, reason: desc); |
| 261 } else { | 275 } else { |
| 262 expect(r, isNotNull, reason: desc); | 276 expect(r, isNotNull, reason: desc); |
| 263 // ConstantAstCloner does not copy static types, and constant values | 277 // ConstantAstCloner does not copy static types, and constant values |
| 264 // computer does not use static types. So, we don't set them during | 278 // computer does not use static types. So, we don't set them during |
| 265 // resynthesis and should not check them here. | 279 // resynthesis and should not check them here. |
| 266 if (o is ParenthesizedExpression) { | 280 if (o is ParenthesizedExpression) { |
| 267 // We don't resynthesize parenthesis, so just ignore it. | 281 // We don't resynthesize parenthesis, so just ignore it. |
| 268 compareConstantExpressions(r, o.expression, desc); | 282 compareConstantAsts(r, o.expression, desc); |
| 269 } else if (o is SimpleIdentifier && r is SimpleIdentifier) { | 283 } else if (o is SimpleIdentifier && r is SimpleIdentifier) { |
| 270 expect(r.name, o.name, reason: desc); | 284 expect(r.name, o.name, reason: desc); |
| 271 compareElements(r.staticElement, o.staticElement, desc); | 285 compareElements(r.staticElement, o.staticElement, desc); |
| 272 } else if (o is PrefixedIdentifier && r is SimpleIdentifier) { | 286 } else if (o is PrefixedIdentifier && r is SimpleIdentifier) { |
| 273 // We don't resynthesize prefixed identifiers. | 287 // We often don't resynthesize prefixed identifiers. |
| 274 // We use simple identifiers with correct elements. | 288 // We use simple identifiers with correct elements. |
| 275 compareConstantExpressions(r, o.identifier, desc); | 289 compareConstantAsts(r, o.identifier, desc); |
| 290 } else if (o is PrefixedIdentifier && r is PrefixedIdentifier) { |
| 291 compareConstantAsts(r.prefix, o.prefix, desc); |
| 292 compareConstantAsts(r.identifier, o.identifier, desc); |
| 276 } else if (o is PropertyAccess && r is PropertyAccess) { | 293 } else if (o is PropertyAccess && r is PropertyAccess) { |
| 277 compareConstantExpressions(r.target, o.target, desc); | 294 compareConstantAsts(r.target, o.target, desc); |
| 278 expect(r.propertyName.name, o.propertyName.name, reason: desc); | 295 expect(r.propertyName.name, o.propertyName.name, reason: desc); |
| 279 compareElements( | 296 compareElements( |
| 280 r.propertyName.staticElement, o.propertyName.staticElement, desc); | 297 r.propertyName.staticElement, o.propertyName.staticElement, desc); |
| 281 } else if (o is PropertyAccess && r is SimpleIdentifier) { | 298 } else if (o is PropertyAccess && r is SimpleIdentifier) { |
| 282 // We don't resynthesize property access. | 299 // We don't resynthesize property access. |
| 283 // We use simple identifiers with correct elements. | 300 // We use simple identifiers with correct elements. |
| 284 compareConstantExpressions(r, o.propertyName, desc); | 301 compareConstantAsts(r, o.propertyName, desc); |
| 285 } else if (o is NullLiteral) { | 302 } else if (o is NullLiteral) { |
| 286 expect(r, new isInstanceOf<NullLiteral>(), reason: desc); | 303 expect(r, new isInstanceOf<NullLiteral>(), reason: desc); |
| 287 } else if (o is BooleanLiteral && r is BooleanLiteral) { | 304 } else if (o is BooleanLiteral && r is BooleanLiteral) { |
| 288 expect(r.value, o.value, reason: desc); | 305 expect(r.value, o.value, reason: desc); |
| 289 } else if (o is IntegerLiteral && r is IntegerLiteral) { | 306 } else if (o is IntegerLiteral && r is IntegerLiteral) { |
| 290 expect(r.value, o.value, reason: desc); | 307 expect(r.value, o.value, reason: desc); |
| 291 } else if (o is DoubleLiteral && r is DoubleLiteral) { | 308 } else if (o is DoubleLiteral && r is DoubleLiteral) { |
| 292 expect(r.value, o.value, reason: desc); | 309 expect(r.value, o.value, reason: desc); |
| 293 } else if (o is StringInterpolation && r is StringInterpolation) { | 310 } else if (o is StringInterpolation && r is StringInterpolation) { |
| 294 compareLists(r.elements, o.elements); | 311 compareLists(r.elements, o.elements); |
| 295 } else if (o is StringLiteral && r is StringLiteral) { | 312 } else if (o is StringLiteral && r is StringLiteral) { |
| 296 // We don't keep all the tokens of AdjacentStrings. | 313 // We don't keep all the tokens of AdjacentStrings. |
| 297 // So, we can compare only their values. | 314 // So, we can compare only their values. |
| 298 expect(r.stringValue, o.stringValue, reason: desc); | 315 expect(r.stringValue, o.stringValue, reason: desc); |
| 299 } else if (o is SymbolLiteral && r is SymbolLiteral) { | 316 } else if (o is SymbolLiteral && r is SymbolLiteral) { |
| 300 // We don't keep all the tokens of symbol literals. | 317 // We don't keep all the tokens of symbol literals. |
| 301 // So, we can compare only their values. | 318 // So, we can compare only their values. |
| 302 expect(r.components.map((t) => t.lexeme).join('.'), | 319 expect(r.components.map((t) => t.lexeme).join('.'), |
| 303 o.components.map((t) => t.lexeme).join('.'), | 320 o.components.map((t) => t.lexeme).join('.'), |
| 304 reason: desc); | 321 reason: desc); |
| 305 } else if (o is NamedExpression && r is NamedExpression) { | 322 } else if (o is NamedExpression && r is NamedExpression) { |
| 306 expect(r.name.label.name, o.name.label.name, reason: desc); | 323 expect(r.name.label.name, o.name.label.name, reason: desc); |
| 307 compareConstantExpressions(r.expression, o.expression, desc); | 324 compareConstantAsts(r.expression, o.expression, desc); |
| 308 } else if (o is BinaryExpression && r is BinaryExpression) { | 325 } else if (o is BinaryExpression && r is BinaryExpression) { |
| 309 expect(r.operator.lexeme, o.operator.lexeme, reason: desc); | 326 expect(r.operator.lexeme, o.operator.lexeme, reason: desc); |
| 310 compareConstantExpressions(r.leftOperand, o.leftOperand, desc); | 327 compareConstantAsts(r.leftOperand, o.leftOperand, desc); |
| 311 compareConstantExpressions(r.rightOperand, o.rightOperand, desc); | 328 compareConstantAsts(r.rightOperand, o.rightOperand, desc); |
| 312 } else if (o is PrefixExpression && r is PrefixExpression) { | 329 } else if (o is PrefixExpression && r is PrefixExpression) { |
| 313 expect(r.operator.lexeme, o.operator.lexeme, reason: desc); | 330 expect(r.operator.lexeme, o.operator.lexeme, reason: desc); |
| 314 compareConstantExpressions(r.operand, o.operand, desc); | 331 compareConstantAsts(r.operand, o.operand, desc); |
| 315 } else if (o is ConditionalExpression && r is ConditionalExpression) { | 332 } else if (o is ConditionalExpression && r is ConditionalExpression) { |
| 316 compareConstantExpressions(r.condition, o.condition, desc); | 333 compareConstantAsts(r.condition, o.condition, desc); |
| 317 compareConstantExpressions(r.thenExpression, o.thenExpression, desc); | 334 compareConstantAsts(r.thenExpression, o.thenExpression, desc); |
| 318 compareConstantExpressions(r.elseExpression, o.elseExpression, desc); | 335 compareConstantAsts(r.elseExpression, o.elseExpression, desc); |
| 319 } else if (o is ListLiteral && r is ListLiteral) { | 336 } else if (o is ListLiteral && r is ListLiteral) { |
| 320 compareLists(r.typeArguments?.arguments, o.typeArguments?.arguments); | 337 compareLists(r.typeArguments?.arguments, o.typeArguments?.arguments); |
| 321 compareLists(r.elements, o.elements); | 338 compareLists(r.elements, o.elements); |
| 322 } else if (o is MapLiteral && r is MapLiteral) { | 339 } else if (o is MapLiteral && r is MapLiteral) { |
| 323 compareLists(r.typeArguments?.arguments, o.typeArguments?.arguments); | 340 compareLists(r.typeArguments?.arguments, o.typeArguments?.arguments); |
| 324 compareLists(r.entries, o.entries); | 341 compareLists(r.entries, o.entries); |
| 325 } else if (o is InstanceCreationExpression && | 342 } else if (o is InstanceCreationExpression && |
| 326 r is InstanceCreationExpression) { | 343 r is InstanceCreationExpression) { |
| 327 compareElements(r.staticElement, o.staticElement, desc); | 344 compareElements(r.staticElement, o.staticElement, desc); |
| 328 ConstructorName oConstructor = o.constructorName; | 345 ConstructorName oConstructor = o.constructorName; |
| 329 ConstructorName rConstructor = r.constructorName; | 346 ConstructorName rConstructor = r.constructorName; |
| 330 expect(oConstructor, isNotNull, reason: desc); | 347 expect(oConstructor, isNotNull, reason: desc); |
| 331 expect(rConstructor, isNotNull, reason: desc); | 348 expect(rConstructor, isNotNull, reason: desc); |
| 332 compareElements( | 349 compareElements( |
| 333 rConstructor.staticElement, oConstructor.staticElement, desc); | 350 rConstructor.staticElement, oConstructor.staticElement, desc); |
| 334 TypeName oType = oConstructor.type; | 351 TypeName oType = oConstructor.type; |
| 335 TypeName rType = rConstructor.type; | 352 TypeName rType = rConstructor.type; |
| 336 expect(oType, isNotNull, reason: desc); | 353 expect(oType, isNotNull, reason: desc); |
| 337 expect(rType, isNotNull, reason: desc); | 354 expect(rType, isNotNull, reason: desc); |
| 338 compareConstantExpressions(rType.name, oType.name, desc); | 355 compareConstantAsts(rType.name, oType.name, desc); |
| 339 compareConstantExpressions(rConstructor.name, oConstructor.name, desc); | 356 compareConstantAsts(rConstructor.name, oConstructor.name, desc); |
| 340 compareLists( | 357 compareLists( |
| 341 rType.typeArguments?.arguments, oType.typeArguments?.arguments); | 358 rType.typeArguments?.arguments, oType.typeArguments?.arguments); |
| 342 compareLists(r.argumentList.arguments, o.argumentList.arguments); | 359 compareLists(r.argumentList.arguments, o.argumentList.arguments); |
| 360 } else if (o is AnnotationImpl && r is AnnotationImpl) { |
| 361 expect(o.atSign.lexeme, r.atSign.lexeme, reason: desc); |
| 362 Identifier rName = r.name; |
| 363 Identifier oName = o.name; |
| 364 if (oName is PrefixedIdentifier && o.constructorName != null) { |
| 365 // E.g. `@prefix.cls.ctor`. This gets resynthesized as `@cls.ctor`, |
| 366 // with `cls.ctor` represented as a PrefixedIdentifier. |
| 367 expect(rName, new isInstanceOf<PrefixedIdentifier>(), reason: desc); |
| 368 if (rName is PrefixedIdentifier) { |
| 369 compareConstantAsts(rName.prefix, oName.identifier, desc); |
| 370 expect(rName.period.lexeme, '.', reason: desc); |
| 371 compareConstantAsts(rName.identifier, o.constructorName, desc); |
| 372 expect(r.period, isNull, reason: desc); |
| 373 expect(r.constructorName, isNull, reason: desc); |
| 374 } |
| 375 } else { |
| 376 compareConstantAsts(r.name, o.name, desc); |
| 377 expect(r.period?.lexeme, o.period?.lexeme, reason: desc); |
| 378 compareConstantAsts(r.constructorName, o.constructorName, desc); |
| 379 } |
| 380 compareLists(r.arguments?.arguments, o.arguments?.arguments); |
| 381 Element expectedElement = o.element; |
| 382 if (oName is PrefixedIdentifier && o.constructorName != null) { |
| 383 // Due to dartbug.com/25706, [o.element] incorrectly points to the |
| 384 // class rather than the named constructor. Hack around this. |
| 385 // TODO(paulberry): when dartbug.com/25706 is fixed, remove this. |
| 386 expectedElement = (expectedElement as ClassElement) |
| 387 .getNamedConstructor(o.constructorName.name); |
| 388 expect(expectedElement, isNotNull, reason: desc); |
| 389 } |
| 390 compareElements(r.element, expectedElement, desc); |
| 391 // elementAnnotation should be null; it is only used in the full AST. |
| 392 expect(o.elementAnnotation, isNull); |
| 393 expect(r.elementAnnotation, isNull); |
| 343 } else if (o is ConstructorName && r is ConstructorName) { | 394 } else if (o is ConstructorName && r is ConstructorName) { |
| 344 fail('Not implemented for ${r.runtimeType} vs. ${o.runtimeType}'); | 395 fail('Not implemented for ${r.runtimeType} vs. ${o.runtimeType}'); |
| 345 } else { | 396 } else { |
| 346 fail('Not implemented for ${r.runtimeType} vs. ${o.runtimeType}'); | 397 fail('Not implemented for ${r.runtimeType} vs. ${o.runtimeType}'); |
| 347 } | 398 } |
| 348 } | 399 } |
| 349 } | 400 } |
| 350 | 401 |
| 351 void compareConstructorElements(ConstructorElementImpl resynthesized, | 402 void compareConstructorElements(ConstructorElementImpl resynthesized, |
| 352 ConstructorElementImpl original, String desc) { | 403 ConstructorElementImpl original, String desc) { |
| 353 compareExecutableElements(resynthesized, original, desc); | 404 compareExecutableElements(resynthesized, original, desc); |
| 354 // TODO(paulberry): test redirectedConstructor and constantInitializers | 405 // TODO(paulberry): test redirectedConstructor and constantInitializers |
| 355 } | 406 } |
| 356 | 407 |
| 408 void compareElementAnnotations(ElementAnnotationImpl resynthesized, |
| 409 ElementAnnotationImpl original, String desc) { |
| 410 expect(resynthesized.element, isNotNull, reason: desc); |
| 411 expect(resynthesized.element.kind, original.element.kind, reason: desc); |
| 412 expect(resynthesized.element.location, original.element.location, |
| 413 reason: desc); |
| 414 expect(resynthesized.compilationUnit, isNotNull, reason: desc); |
| 415 expect(resynthesized.compilationUnit.location, |
| 416 original.compilationUnit.location, |
| 417 reason: desc); |
| 418 expect(resynthesized.annotationAst, isNotNull, reason: desc); |
| 419 compareConstantAsts( |
| 420 resynthesized.annotationAst, original.annotationAst, desc); |
| 421 } |
| 422 |
| 357 void compareElements(Element resynthesized, Element original, String desc) { | 423 void compareElements(Element resynthesized, Element original, String desc) { |
| 358 expect(resynthesized, isNotNull); | 424 expect(resynthesized, isNotNull); |
| 359 expect(resynthesized.kind, original.kind); | 425 expect(resynthesized.kind, original.kind); |
| 360 expect(resynthesized.location, original.location, reason: desc); | 426 expect(resynthesized.location, original.location, reason: desc); |
| 361 expect(resynthesized.name, original.name); | 427 expect(resynthesized.name, original.name); |
| 362 expect(resynthesized.nameOffset, original.nameOffset, reason: desc); | 428 expect(resynthesized.nameOffset, original.nameOffset, reason: desc); |
| 363 expect(resynthesized.documentationComment, original.documentationComment, | 429 expect(resynthesized.documentationComment, original.documentationComment, |
| 364 reason: desc); | 430 reason: desc); |
| 365 expect(resynthesized.docRange, original.docRange, reason: desc); | 431 expect(resynthesized.docRange, original.docRange, reason: desc); |
| 432 compareMetadata(resynthesized.metadata, original.metadata, desc); |
| 366 // Modifiers are a pain to test via handles. So just test them via the | 433 // Modifiers are a pain to test via handles. So just test them via the |
| 367 // actual element. | 434 // actual element. |
| 368 ElementImpl actualResynthesized = getActualElement(resynthesized, desc); | 435 ElementImpl actualResynthesized = getActualElement(resynthesized, desc); |
| 369 ElementImpl actualOriginal = getActualElement(original, desc); | 436 ElementImpl actualOriginal = getActualElement(original, desc); |
| 370 for (Modifier modifier in Modifier.values) { | 437 for (Modifier modifier in Modifier.values) { |
| 371 bool got = actualResynthesized.hasModifier(modifier); | 438 bool got = actualResynthesized.hasModifier(modifier); |
| 372 bool want = actualOriginal.hasModifier(modifier); | 439 bool want = actualOriginal.hasModifier(modifier); |
| 373 expect(got, want, | 440 expect(got, want, |
| 374 reason: 'Mismatch in $desc.$modifier: got $got, want $want'); | 441 reason: 'Mismatch in $desc.$modifier: got $got, want $want'); |
| 375 } | 442 } |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 463 comparePrefixElements( | 530 comparePrefixElements( |
| 464 resynthesized.prefix, original.prefix, original.prefix.name); | 531 resynthesized.prefix, original.prefix, original.prefix.name); |
| 465 } | 532 } |
| 466 expect(resynthesized.combinators.length, original.combinators.length); | 533 expect(resynthesized.combinators.length, original.combinators.length); |
| 467 for (int i = 0; i < resynthesized.combinators.length; i++) { | 534 for (int i = 0; i < resynthesized.combinators.length; i++) { |
| 468 compareNamespaceCombinators( | 535 compareNamespaceCombinators( |
| 469 resynthesized.combinators[i], original.combinators[i]); | 536 resynthesized.combinators[i], original.combinators[i]); |
| 470 } | 537 } |
| 471 } | 538 } |
| 472 | 539 |
| 540 void compareMetadata(List<ElementAnnotation> resynthesized, |
| 541 List<ElementAnnotation> original, String desc) { |
| 542 expect(resynthesized, hasLength(original.length), reason: desc); |
| 543 for (int i = 0; i < original.length; i++) { |
| 544 compareElementAnnotations( |
| 545 resynthesized[i], original[i], '$desc annotation $i'); |
| 546 } |
| 547 } |
| 548 |
| 473 void compareMethodElements(MethodElementImpl resynthesized, | 549 void compareMethodElements(MethodElementImpl resynthesized, |
| 474 MethodElementImpl original, String desc) { | 550 MethodElementImpl original, String desc) { |
| 475 // TODO(paulberry): do we need to deal with | 551 // TODO(paulberry): do we need to deal with |
| 476 // MultiplyInheritedMethodElementImpl? | 552 // MultiplyInheritedMethodElementImpl? |
| 477 compareExecutableElements(resynthesized, original, desc); | 553 compareExecutableElements(resynthesized, original, desc); |
| 478 } | 554 } |
| 479 | 555 |
| 480 void compareNamespaceCombinators( | 556 void compareNamespaceCombinators( |
| 481 NamespaceCombinator resynthesized, NamespaceCombinator original) { | 557 NamespaceCombinator resynthesized, NamespaceCombinator original) { |
| 482 if (original is ShowElementCombinatorImpl && | 558 if (original is ShowElementCombinatorImpl && |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 663 expect(resynthesized.uri, original.uri); | 739 expect(resynthesized.uri, original.uri); |
| 664 expect(resynthesized.uriOffset, original.uriOffset, reason: desc); | 740 expect(resynthesized.uriOffset, original.uriOffset, reason: desc); |
| 665 expect(resynthesized.uriEnd, original.uriEnd, reason: desc); | 741 expect(resynthesized.uriEnd, original.uriEnd, reason: desc); |
| 666 } | 742 } |
| 667 | 743 |
| 668 void compareVariableElements(VariableElementImpl resynthesized, | 744 void compareVariableElements(VariableElementImpl resynthesized, |
| 669 VariableElementImpl original, String desc) { | 745 VariableElementImpl original, String desc) { |
| 670 compareElements(resynthesized, original, desc); | 746 compareElements(resynthesized, original, desc); |
| 671 compareTypes(resynthesized.type, original.type, desc); | 747 compareTypes(resynthesized.type, original.type, desc); |
| 672 if (original is ConstVariableElement) { | 748 if (original is ConstVariableElement) { |
| 673 compareConstantExpressions(resynthesized.constantInitializer, | 749 compareConstantAsts(resynthesized.constantInitializer, |
| 674 original.constantInitializer, desc); | 750 original.constantInitializer, desc); |
| 675 } | 751 } |
| 676 } | 752 } |
| 677 | 753 |
| 678 /** | 754 /** |
| 679 * Serialize the given [library] into a summary. Then create a | 755 * Serialize the given [library] into a summary. Then create a |
| 680 * [_TestSummaryResynthesizer] which can deserialize it, along with any | 756 * [_TestSummaryResynthesizer] which can deserialize it, along with any |
| 681 * references it makes to `dart:core`. | 757 * references it makes to `dart:core`. |
| 682 * | 758 * |
| 683 * Errors will lead to a test failure unless [allowErrors] is `true`. | 759 * Errors will lead to a test failure unless [allowErrors] is `true`. |
| 684 */ | 760 */ |
| 685 _TestSummaryResynthesizer encodeLibrary(LibraryElementImpl library, | 761 _TestSummaryResynthesizer encodeLibrary(LibraryElementImpl library, |
| 686 {bool allowErrors: false}) { | 762 {bool allowErrors: false, bool dumpSummaries: false}) { |
| 687 if (!allowErrors) { | 763 if (!allowErrors) { |
| 688 assertNoErrors(library.source); | 764 assertNoErrors(library.source); |
| 689 } | 765 } |
| 690 addLibrary('dart:core'); | 766 addLibrary('dart:core'); |
| 691 return encodeLibraryElement(library); | 767 return encodeLibraryElement(library, dumpSummaries: dumpSummaries); |
| 692 } | 768 } |
| 693 | 769 |
| 694 /** | 770 /** |
| 695 * Convert the library element [library] into a summary, and then create a | 771 * Convert the library element [library] into a summary, and then create a |
| 696 * [_TestSummaryResynthesizer] which can deserialize it. | 772 * [_TestSummaryResynthesizer] which can deserialize it. |
| 697 * | 773 * |
| 698 * Caller is responsible for checking the library for errors, and adding any | 774 * Caller is responsible for checking the library for errors, and adding any |
| 699 * dependent libraries using [addLibrary]. | 775 * dependent libraries using [addLibrary]. |
| 700 */ | 776 */ |
| 701 _TestSummaryResynthesizer encodeLibraryElement(LibraryElementImpl library) { | 777 _TestSummaryResynthesizer encodeLibraryElement(LibraryElementImpl library, |
| 778 {bool dumpSummaries: false}) { |
| 702 Map<String, UnlinkedUnit> unlinkedSummaries = <String, UnlinkedUnit>{}; | 779 Map<String, UnlinkedUnit> unlinkedSummaries = <String, UnlinkedUnit>{}; |
| 703 LinkedLibrary getLinkedSummaryFor(LibraryElement lib) { | 780 LinkedLibrary getLinkedSummaryFor(LibraryElement lib) { |
| 704 LibrarySerializationResult serialized = serializeLibrary( | 781 LibrarySerializationResult serialized = serializeLibrary( |
| 705 lib, typeProvider, analysisContext.analysisOptions.strongMode); | 782 lib, typeProvider, analysisContext.analysisOptions.strongMode); |
| 706 for (int i = 0; i < serialized.unlinkedUnits.length; i++) { | 783 for (int i = 0; i < serialized.unlinkedUnits.length; i++) { |
| 707 unlinkedSummaries[serialized.unitUris[i]] = | 784 unlinkedSummaries[serialized.unitUris[i]] = |
| 708 new UnlinkedUnit.fromBuffer(serialized.unlinkedUnits[i].toBuffer()); | 785 new UnlinkedUnit.fromBuffer(serialized.unlinkedUnits[i].toBuffer()); |
| 709 } | 786 } |
| 710 return new LinkedLibrary.fromBuffer(serialized.linked.toBuffer()); | 787 return new LinkedLibrary.fromBuffer(serialized.linked.toBuffer()); |
| 711 } | 788 } |
| 712 Map<String, LinkedLibrary> linkedSummaries = <String, LinkedLibrary>{ | 789 Map<String, LinkedLibrary> linkedSummaries = <String, LinkedLibrary>{ |
| 713 library.source.uri.toString(): getLinkedSummaryFor(library) | 790 library.source.uri.toString(): getLinkedSummaryFor(library) |
| 714 }; | 791 }; |
| 715 for (Source source in otherLibrarySources) { | 792 for (Source source in otherLibrarySources) { |
| 716 LibraryElement original = resolve2(source); | 793 LibraryElement original = resolve2(source); |
| 717 String uri = source.uri.toString(); | 794 String uri = source.uri.toString(); |
| 718 linkedSummaries[uri] = getLinkedSummaryFor(original); | 795 linkedSummaries[uri] = getLinkedSummaryFor(original); |
| 719 } | 796 } |
| 797 if (dumpSummaries) { |
| 798 unlinkedSummaries.forEach((String path, UnlinkedUnit unit) { |
| 799 print('Unlinked $path: ${JSON.encode(canonicalize(unit))}'); |
| 800 }); |
| 801 linkedSummaries.forEach((String path, LinkedLibrary lib) { |
| 802 print('Linked $path: ${JSON.encode(canonicalize(lib))}'); |
| 803 }); |
| 804 } |
| 720 return new _TestSummaryResynthesizer( | 805 return new _TestSummaryResynthesizer( |
| 721 null, | 806 null, |
| 722 analysisContext, | 807 analysisContext, |
| 723 analysisContext.typeProvider, | 808 analysisContext.typeProvider, |
| 724 analysisContext.sourceFactory, | 809 analysisContext.sourceFactory, |
| 725 unlinkedSummaries, | 810 unlinkedSummaries, |
| 726 linkedSummaries, | 811 linkedSummaries, |
| 727 options.strongMode); | 812 options.strongMode); |
| 728 } | 813 } |
| 729 | 814 |
| (...skipping 1403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2133 | 2218 |
| 2134 test_main_variable() { | 2219 test_main_variable() { |
| 2135 checkLibrary('var main;'); | 2220 checkLibrary('var main;'); |
| 2136 } | 2221 } |
| 2137 | 2222 |
| 2138 test_main_variable_via_export() { | 2223 test_main_variable_via_export() { |
| 2139 addLibrarySource('/a.dart', 'var main;'); | 2224 addLibrarySource('/a.dart', 'var main;'); |
| 2140 checkLibrary('export "a.dart";'); | 2225 checkLibrary('export "a.dart";'); |
| 2141 } | 2226 } |
| 2142 | 2227 |
| 2228 test_metadata_classDeclaration() { |
| 2229 checkLibrary('const a = null; @a class C {}'); |
| 2230 } |
| 2231 |
| 2232 test_metadata_classTypeAlias() { |
| 2233 checkLibrary( |
| 2234 'const a = null; @a class C = D with E; class D {} class E {}'); |
| 2235 } |
| 2236 |
| 2237 test_metadata_constructor_call_named() { |
| 2238 checkLibrary('class A { const A.named(); } @A.named() class C {}'); |
| 2239 } |
| 2240 |
| 2241 test_metadata_constructor_call_named_prefixed() { |
| 2242 addLibrarySource('/foo.dart', 'class A { const A.named(); }'); |
| 2243 checkLibrary('import "foo.dart" as foo; @foo.A.named() class C {}'); |
| 2244 } |
| 2245 |
| 2246 test_metadata_constructor_call_unnamed() { |
| 2247 checkLibrary('class A { const A(); } @A() class C {}'); |
| 2248 } |
| 2249 |
| 2250 test_metadata_constructor_call_unnamed_prefixed() { |
| 2251 addLibrarySource('/foo.dart', 'class A { const A(); }'); |
| 2252 checkLibrary('import "foo.dart" as foo; @foo.A() class C {}'); |
| 2253 } |
| 2254 |
| 2255 test_metadata_constructor_call_with_args() { |
| 2256 checkLibrary('class A { const A(x); } @A(null) class C {}'); |
| 2257 } |
| 2258 |
| 2259 test_metadata_constructorDeclaration_named() { |
| 2260 checkLibrary('const a = null; class C { @a C.named(); }'); |
| 2261 } |
| 2262 |
| 2263 test_metadata_constructorDeclaration_unnamed() { |
| 2264 checkLibrary('const a = null; class C { @a C(); }'); |
| 2265 } |
| 2266 |
| 2267 test_metadata_enumDeclaration() { |
| 2268 checkLibrary('const a = null; @a enum E { v }'); |
| 2269 } |
| 2270 |
| 2271 test_metadata_exportDirective() { |
| 2272 addLibrarySource('/foo.dart', ''); |
| 2273 checkLibrary('@a export "foo.dart"; const a = null;'); |
| 2274 } |
| 2275 |
| 2276 test_metadata_fieldDeclaration() { |
| 2277 checkLibrary('const a = null; class C { @a int x; }'); |
| 2278 } |
| 2279 |
| 2280 test_metadata_fieldFormalParameter() { |
| 2281 checkLibrary('const a = null; class C { var x; C(@a this.x); }'); |
| 2282 } |
| 2283 |
| 2284 test_metadata_fieldFormalParameter_withDefault() { |
| 2285 checkLibrary('const a = null; class C { var x; C([@a this.x = null]); }'); |
| 2286 } |
| 2287 |
| 2288 test_metadata_functionDeclaration_function() { |
| 2289 checkLibrary('const a = null; @a f() {}'); |
| 2290 } |
| 2291 |
| 2292 test_metadata_functionDeclaration_getter() { |
| 2293 checkLibrary('const a = null; @a get f => null;'); |
| 2294 } |
| 2295 |
| 2296 test_metadata_functionDeclaration_setter() { |
| 2297 checkLibrary('const a = null; @a set f(value) {}'); |
| 2298 } |
| 2299 |
| 2300 test_metadata_functionTypeAlias() { |
| 2301 checkLibrary('const a = null; @a typedef F();'); |
| 2302 } |
| 2303 |
| 2304 test_metadata_functionTypedFormalParameter() { |
| 2305 checkLibrary('const a = null; f(@a g()) {}'); |
| 2306 } |
| 2307 |
| 2308 test_metadata_functionTypedFormalParameter_withDefault() { |
| 2309 checkLibrary('const a = null; f([@a g() = null]) {}'); |
| 2310 } |
| 2311 |
| 2312 test_metadata_importDirective() { |
| 2313 addLibrarySource('/foo.dart', 'const b = null;'); |
| 2314 checkLibrary('@a import "foo.dart"; const a = b;'); |
| 2315 } |
| 2316 |
| 2317 test_metadata_libraryDirective() { |
| 2318 checkLibrary('@a library L; const a = null;'); |
| 2319 } |
| 2320 |
| 2321 test_metadata_methodDeclaration_getter() { |
| 2322 checkLibrary('const a = null; class C { @a get m => null; }'); |
| 2323 } |
| 2324 |
| 2325 test_metadata_methodDeclaration_method() { |
| 2326 checkLibrary('const a = null; class C { @a m() {} }'); |
| 2327 } |
| 2328 |
| 2329 test_metadata_methodDeclaration_setter() { |
| 2330 checkLibrary('const a = null; class C { @a set m(value) {} }'); |
| 2331 } |
| 2332 |
| 2333 test_metadata_partDirective() { |
| 2334 addNamedSource('/foo.dart', 'part of L;'); |
| 2335 checkLibrary('library L; @a part "foo.dart"; const a = null;'); |
| 2336 } |
| 2337 |
| 2338 test_metadata_prefixed_variable() { |
| 2339 addLibrarySource('/a.dart', 'const b = null;'); |
| 2340 checkLibrary('import "a.dart" as a; @a.b class C {}'); |
| 2341 } |
| 2342 |
| 2343 test_metadata_simpleFormalParameter() { |
| 2344 checkLibrary('const a = null; f(@a x) {}'); |
| 2345 } |
| 2346 |
| 2347 test_metadata_simpleFormalParameter_withDefault() { |
| 2348 checkLibrary('const a = null; f([@a x = null]) {}'); |
| 2349 } |
| 2350 |
| 2351 test_metadata_topLevelVariableDeclaration() { |
| 2352 checkLibrary('const a = null; @a int v;'); |
| 2353 } |
| 2354 |
| 2355 test_metadata_typeParameter_ofClass() { |
| 2356 checkLibrary('const a = null; class C<@a T> {}'); |
| 2357 } |
| 2358 |
| 2359 test_metadata_typeParameter_ofClassTypeAlias() { |
| 2360 checkLibrary( |
| 2361 'const a = null; class C<@a T> = D with E; class D {} class E {}'); |
| 2362 } |
| 2363 |
| 2364 test_metadata_typeParameter_ofFunction() { |
| 2365 checkLibrary('const a = null; f<@a T>() {}'); |
| 2366 } |
| 2367 |
| 2368 test_metadata_typeParameter_ofTypedef() { |
| 2369 checkLibrary('const a = null; typedef F<@a T>();'); |
| 2370 } |
| 2371 |
| 2143 test_method_documented() { | 2372 test_method_documented() { |
| 2144 checkLibrary(''' | 2373 checkLibrary(''' |
| 2145 class C { | 2374 class C { |
| 2146 /** | 2375 /** |
| 2147 * Docs | 2376 * Docs |
| 2148 */ | 2377 */ |
| 2149 f() {} | 2378 f() {} |
| 2150 }'''); | 2379 }'''); |
| 2151 } | 2380 } |
| 2152 | 2381 |
| (...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2608 fail('Unexpectedly tried to get unlinked summary for $uri'); | 2837 fail('Unexpectedly tried to get unlinked summary for $uri'); |
| 2609 } | 2838 } |
| 2610 return serializedUnit; | 2839 return serializedUnit; |
| 2611 } | 2840 } |
| 2612 | 2841 |
| 2613 @override | 2842 @override |
| 2614 bool hasLibrarySummary(String uri) { | 2843 bool hasLibrarySummary(String uri) { |
| 2615 return true; | 2844 return true; |
| 2616 } | 2845 } |
| 2617 } | 2846 } |
| OLD | NEW |