| OLD | NEW |
| (Empty) | |
| 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 |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 library analyzer.test.src.summary.summarize_ast_test; |
| 6 |
| 7 import 'package:analyzer/analyzer.dart'; |
| 8 import 'package:analyzer/dart/ast/ast.dart'; |
| 9 import 'package:analyzer/dart/ast/token.dart'; |
| 10 import 'package:analyzer/error/listener.dart'; |
| 11 import 'package:analyzer/src/dart/scanner/reader.dart'; |
| 12 import 'package:analyzer/src/dart/scanner/scanner.dart'; |
| 13 import 'package:analyzer/src/generated/parser.dart'; |
| 14 import 'package:analyzer/src/generated/source.dart'; |
| 15 import 'package:analyzer/src/summary/format.dart'; |
| 16 import 'package:analyzer/src/summary/idl.dart'; |
| 17 import 'package:analyzer/src/summary/link.dart'; |
| 18 import 'package:analyzer/src/summary/package_bundle_reader.dart'; |
| 19 import 'package:analyzer/src/summary/summarize_ast.dart'; |
| 20 import 'package:analyzer/src/summary/summarize_elements.dart'; |
| 21 import 'package:test_reflective_loader/test_reflective_loader.dart'; |
| 22 import 'package:unittest/unittest.dart'; |
| 23 |
| 24 import 'summary_common.dart'; |
| 25 |
| 26 main() { |
| 27 groupSep = ' | '; |
| 28 defineReflectiveTests(LinkedSummarizeAstSpecTest); |
| 29 } |
| 30 |
| 31 @reflectiveTest |
| 32 class LinkedSummarizeAstSpecTest extends LinkedSummarizeAstTest { |
| 33 @override |
| 34 bool get strongMode => false; |
| 35 |
| 36 @override |
| 37 @failingTest |
| 38 test_bottom_reference_shared() { |
| 39 super.test_bottom_reference_shared(); |
| 40 } |
| 41 |
| 42 @override |
| 43 @failingTest |
| 44 test_closure_executable_with_bottom_return_type() { |
| 45 super.test_closure_executable_with_bottom_return_type(); |
| 46 } |
| 47 |
| 48 @override |
| 49 @failingTest |
| 50 test_closure_executable_with_imported_return_type() { |
| 51 super.test_closure_executable_with_imported_return_type(); |
| 52 } |
| 53 |
| 54 @override |
| 55 @failingTest |
| 56 test_closure_executable_with_return_type_from_closure() { |
| 57 super.test_closure_executable_with_return_type_from_closure(); |
| 58 } |
| 59 |
| 60 @override |
| 61 @failingTest |
| 62 test_closure_executable_with_unimported_return_type() { |
| 63 super.test_closure_executable_with_unimported_return_type(); |
| 64 } |
| 65 |
| 66 @override |
| 67 @failingTest |
| 68 test_implicit_dependencies_follow_other_dependencies() { |
| 69 super.test_implicit_dependencies_follow_other_dependencies(); |
| 70 } |
| 71 |
| 72 @override |
| 73 @failingTest |
| 74 test_initializer_executable_with_bottom_return_type() { |
| 75 super.test_initializer_executable_with_bottom_return_type(); |
| 76 } |
| 77 |
| 78 @override |
| 79 @failingTest |
| 80 test_initializer_executable_with_imported_return_type() { |
| 81 super.test_initializer_executable_with_imported_return_type(); |
| 82 } |
| 83 |
| 84 @override |
| 85 @failingTest |
| 86 test_initializer_executable_with_return_type_from_closure() { |
| 87 super.test_initializer_executable_with_return_type_from_closure(); |
| 88 } |
| 89 |
| 90 @override |
| 91 @failingTest |
| 92 test_initializer_executable_with_return_type_from_closure_field() { |
| 93 super.test_initializer_executable_with_return_type_from_closure_field(); |
| 94 } |
| 95 |
| 96 @override |
| 97 @failingTest |
| 98 test_initializer_executable_with_return_type_from_closure_local() { |
| 99 super.test_initializer_executable_with_return_type_from_closure_local(); |
| 100 } |
| 101 |
| 102 @override |
| 103 @failingTest |
| 104 test_initializer_executable_with_unimported_return_type() { |
| 105 super.test_initializer_executable_with_unimported_return_type(); |
| 106 } |
| 107 |
| 108 @override |
| 109 @failingTest |
| 110 test_syntheticFunctionType_inGenericClass() { |
| 111 super.test_syntheticFunctionType_inGenericClass(); |
| 112 } |
| 113 |
| 114 @override |
| 115 @failingTest |
| 116 test_syntheticFunctionType_inGenericFunction() { |
| 117 super.test_syntheticFunctionType_inGenericFunction(); |
| 118 } |
| 119 } |
| 120 |
| 121 /** |
| 122 * Override of [SummaryTest] which creates linked summaries directly from the |
| 123 * AST. |
| 124 */ |
| 125 @reflectiveTest |
| 126 abstract class LinkedSummarizeAstTest extends SummaryLinkerTest |
| 127 with SummaryTest { |
| 128 @override |
| 129 LinkedLibrary linked; |
| 130 |
| 131 @override |
| 132 List<UnlinkedUnit> unlinkedUnits; |
| 133 |
| 134 LinkerInputs linkerInputs; |
| 135 |
| 136 @override |
| 137 bool get skipFullyLinkedData => false; |
| 138 |
| 139 @override |
| 140 bool get skipNonConstInitializers => false; |
| 141 |
| 142 @override |
| 143 void serializeLibraryText(String text, {bool allowErrors: false}) { |
| 144 Map<String, UnlinkedUnitBuilder> uriToUnit = this._filesToLink.uriToUnit; |
| 145 linkerInputs = createLinkerInputs(text); |
| 146 linked = link( |
| 147 linkerInputs.linkedLibraries, |
| 148 linkerInputs.getDependency, |
| 149 linkerInputs.getUnit, |
| 150 (name) => null, |
| 151 strongMode)[linkerInputs.testDartUri.toString()]; |
| 152 expect(linked, isNotNull); |
| 153 validateLinkedLibrary(linked); |
| 154 unlinkedUnits = <UnlinkedUnit>[linkerInputs.unlinkedDefiningUnit]; |
| 155 for (String relativeUri |
| 156 in linkerInputs.unlinkedDefiningUnit.publicNamespace.parts) { |
| 157 UnlinkedUnit unit = uriToUnit[ |
| 158 resolveRelativeUri(linkerInputs.testDartUri, Uri.parse(relativeUri)) |
| 159 .toString()]; |
| 160 if (unit == null) { |
| 161 if (!allowMissingFiles) { |
| 162 fail('Test referred to unknown unit $relativeUri'); |
| 163 } |
| 164 } else { |
| 165 unlinkedUnits.add(unit); |
| 166 } |
| 167 } |
| 168 } |
| 169 |
| 170 test_class_no_superclass() { |
| 171 UnlinkedClass cls = serializeClassText('part of dart.core; class Object {}', |
| 172 className: 'Object'); |
| 173 expect(cls.supertype, isNull); |
| 174 expect(cls.hasNoSupertype, isTrue); |
| 175 } |
| 176 } |
| 177 |
| 178 /** |
| 179 * Instances of the class [LinkerInputs] encapsulate the necessary information |
| 180 * to pass to the summary linker. |
| 181 */ |
| 182 class LinkerInputs { |
| 183 final bool _allowMissingFiles; |
| 184 final Map<String, UnlinkedUnit> _uriToUnit; |
| 185 final Uri testDartUri; |
| 186 final UnlinkedUnit unlinkedDefiningUnit; |
| 187 final Map<String, LinkedLibrary> _dependentLinkedLibraries; |
| 188 final Map<String, UnlinkedUnit> _dependentUnlinkedUnits; |
| 189 |
| 190 LinkerInputs( |
| 191 this._allowMissingFiles, |
| 192 this._uriToUnit, |
| 193 this.testDartUri, |
| 194 this.unlinkedDefiningUnit, |
| 195 this._dependentLinkedLibraries, |
| 196 this._dependentUnlinkedUnits); |
| 197 |
| 198 Set<String> get linkedLibraries => _uriToUnit.keys.toSet(); |
| 199 |
| 200 String getDeclaredVariable(String name) { |
| 201 return null; |
| 202 } |
| 203 |
| 204 LinkedLibrary getDependency(String absoluteUri) { |
| 205 Map<String, LinkedLibrary> sdkLibraries = |
| 206 SerializedMockSdk.instance.uriToLinkedLibrary; |
| 207 LinkedLibrary linkedLibrary = |
| 208 sdkLibraries[absoluteUri] ?? _dependentLinkedLibraries[absoluteUri]; |
| 209 if (linkedLibrary == null && !_allowMissingFiles) { |
| 210 Set<String> librariesAvailable = sdkLibraries.keys.toSet(); |
| 211 librariesAvailable.addAll(_dependentLinkedLibraries.keys); |
| 212 fail('Linker unexpectedly requested LinkedLibrary for "$absoluteUri".' |
| 213 ' Libraries available: ${librariesAvailable.toList()}'); |
| 214 } |
| 215 return linkedLibrary; |
| 216 } |
| 217 |
| 218 UnlinkedUnit getUnit(String absoluteUri) { |
| 219 UnlinkedUnit unit = _uriToUnit[absoluteUri] ?? |
| 220 SerializedMockSdk.instance.uriToUnlinkedUnit[absoluteUri] ?? |
| 221 _dependentUnlinkedUnits[absoluteUri]; |
| 222 if (unit == null && !_allowMissingFiles) { |
| 223 fail('Linker unexpectedly requested unit for "$absoluteUri".'); |
| 224 } |
| 225 return unit; |
| 226 } |
| 227 } |
| 228 |
| 229 /** |
| 230 * Base class providing the ability to run the summary linker using summaries |
| 231 * build from ASTs. |
| 232 */ |
| 233 abstract class SummaryLinkerTest { |
| 234 /** |
| 235 * Information about the files to be linked. |
| 236 */ |
| 237 _FilesToLink _filesToLink = new _FilesToLink(); |
| 238 |
| 239 /** |
| 240 * A test will set this to `true` if it contains `import`, `export`, or |
| 241 * `part` declarations that deliberately refer to non-existent files. |
| 242 */ |
| 243 bool get allowMissingFiles; |
| 244 |
| 245 /** |
| 246 * Add the given package bundle as a dependency so that it may be referenced |
| 247 * by the files under test. |
| 248 */ |
| 249 void addBundle(String path, PackageBundle bundle) { |
| 250 _filesToLink.summaryDataStore.addBundle(path, bundle); |
| 251 } |
| 252 |
| 253 /** |
| 254 * Add the given source file so that it may be referenced by the file under |
| 255 * test. |
| 256 */ |
| 257 Source addNamedSource(String filePath, String contents) { |
| 258 CompilationUnit unit = _parseText(contents); |
| 259 UnlinkedUnitBuilder unlinkedUnit = serializeAstUnlinked(unit); |
| 260 _filesToLink.uriToUnit[absUri(filePath)] = unlinkedUnit; |
| 261 // Tests using SummaryLinkerTest don't actually need the returned |
| 262 // Source, so we can safely return `null`. |
| 263 return null; |
| 264 } |
| 265 |
| 266 LinkerInputs createLinkerInputs(String text, |
| 267 {String path: '/test.dart', String uri}) { |
| 268 uri ??= absUri(path); |
| 269 Uri testDartUri = Uri.parse(uri); |
| 270 CompilationUnit unit = _parseText(text); |
| 271 UnlinkedUnitBuilder unlinkedDefiningUnit = serializeAstUnlinked(unit); |
| 272 _filesToLink.uriToUnit[testDartUri.toString()] = unlinkedDefiningUnit; |
| 273 LinkerInputs linkerInputs = new LinkerInputs( |
| 274 allowMissingFiles, |
| 275 _filesToLink.uriToUnit, |
| 276 testDartUri, |
| 277 unlinkedDefiningUnit, |
| 278 _filesToLink.summaryDataStore.linkedMap, |
| 279 _filesToLink.summaryDataStore.unlinkedMap); |
| 280 // Reset _filesToLink in case the test needs to start a new package bundle. |
| 281 _filesToLink = new _FilesToLink(); |
| 282 return linkerInputs; |
| 283 } |
| 284 |
| 285 /** |
| 286 * Link together the given file, along with any other files passed to |
| 287 * [addNamedSource], to form a package bundle. Reset the state of the buffers |
| 288 * accumulated by [addNamedSource] and [addBundle] so that further bundles |
| 289 * can be created. |
| 290 */ |
| 291 PackageBundleBuilder createPackageBundle(String text, |
| 292 {String path: '/test.dart', String uri}) { |
| 293 PackageBundleAssembler assembler = new PackageBundleAssembler(); |
| 294 assembler.recordDependencies(_filesToLink.summaryDataStore); |
| 295 LinkerInputs linkerInputs = createLinkerInputs(text, path: path, uri: uri); |
| 296 Map<String, LinkedLibraryBuilder> linkedLibraries = link( |
| 297 linkerInputs.linkedLibraries, |
| 298 linkerInputs.getDependency, |
| 299 linkerInputs.getUnit, |
| 300 linkerInputs.getDeclaredVariable, |
| 301 true); |
| 302 linkedLibraries.forEach(assembler.addLinkedLibrary); |
| 303 linkerInputs._uriToUnit.forEach((String uri, UnlinkedUnit unit) { |
| 304 // Note: it doesn't matter what we store for the hash because it isn't |
| 305 // used in these tests. |
| 306 assembler.addUnlinkedUnitWithHash(uri, unit, 'HASH'); |
| 307 }); |
| 308 return assembler.assemble(); |
| 309 } |
| 310 |
| 311 CompilationUnit _parseText(String text) { |
| 312 CharSequenceReader reader = new CharSequenceReader(text); |
| 313 Scanner scanner = |
| 314 new Scanner(null, reader, AnalysisErrorListener.NULL_LISTENER); |
| 315 Token token = scanner.tokenize(); |
| 316 Parser parser = new Parser(null, AnalysisErrorListener.NULL_LISTENER); |
| 317 parser.parseGenericMethods = true; |
| 318 CompilationUnit unit = parser.parseCompilationUnit(token); |
| 319 unit.lineInfo = new LineInfo(scanner.lineStarts); |
| 320 return unit; |
| 321 } |
| 322 } |
| 323 |
| 324 /** |
| 325 * [_FilesToLink] stores information about a set of files to be linked together. |
| 326 * This information is grouped into a class to allow it to be reset easily when |
| 327 * [SummaryLinkerTest.createLinkerInputs] is called. |
| 328 */ |
| 329 class _FilesToLink { |
| 330 /** |
| 331 * Map from absolute URI to the [UnlinkedUnit] for each compilation unit |
| 332 * passed to [addNamedSource]. |
| 333 */ |
| 334 Map<String, UnlinkedUnitBuilder> uriToUnit = <String, UnlinkedUnitBuilder>{}; |
| 335 |
| 336 /** |
| 337 * Information about summaries to be included in the link process. |
| 338 */ |
| 339 SummaryDataStore summaryDataStore = |
| 340 new SummaryDataStore([], recordDependencyInfo: true); |
| 341 } |
| OLD | NEW |