| Index: packages/analyzer/test/src/summary/summarize_ast_test.dart
|
| diff --git a/packages/analyzer/test/src/summary/summarize_ast_test.dart b/packages/analyzer/test/src/summary/summarize_ast_test.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..5338dc0f8b5a4f11bfe49f70b41ef7a258f2058d
|
| --- /dev/null
|
| +++ b/packages/analyzer/test/src/summary/summarize_ast_test.dart
|
| @@ -0,0 +1,341 @@
|
| +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
|
| +// for details. All rights reserved. Use of this source code is governed by a
|
| +// BSD-style license that can be found in the LICENSE file.
|
| +
|
| +library analyzer.test.src.summary.summarize_ast_test;
|
| +
|
| +import 'package:analyzer/analyzer.dart';
|
| +import 'package:analyzer/dart/ast/ast.dart';
|
| +import 'package:analyzer/dart/ast/token.dart';
|
| +import 'package:analyzer/error/listener.dart';
|
| +import 'package:analyzer/src/dart/scanner/reader.dart';
|
| +import 'package:analyzer/src/dart/scanner/scanner.dart';
|
| +import 'package:analyzer/src/generated/parser.dart';
|
| +import 'package:analyzer/src/generated/source.dart';
|
| +import 'package:analyzer/src/summary/format.dart';
|
| +import 'package:analyzer/src/summary/idl.dart';
|
| +import 'package:analyzer/src/summary/link.dart';
|
| +import 'package:analyzer/src/summary/package_bundle_reader.dart';
|
| +import 'package:analyzer/src/summary/summarize_ast.dart';
|
| +import 'package:analyzer/src/summary/summarize_elements.dart';
|
| +import 'package:test_reflective_loader/test_reflective_loader.dart';
|
| +import 'package:unittest/unittest.dart';
|
| +
|
| +import 'summary_common.dart';
|
| +
|
| +main() {
|
| + groupSep = ' | ';
|
| + defineReflectiveTests(LinkedSummarizeAstSpecTest);
|
| +}
|
| +
|
| +@reflectiveTest
|
| +class LinkedSummarizeAstSpecTest extends LinkedSummarizeAstTest {
|
| + @override
|
| + bool get strongMode => false;
|
| +
|
| + @override
|
| + @failingTest
|
| + test_bottom_reference_shared() {
|
| + super.test_bottom_reference_shared();
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + test_closure_executable_with_bottom_return_type() {
|
| + super.test_closure_executable_with_bottom_return_type();
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + test_closure_executable_with_imported_return_type() {
|
| + super.test_closure_executable_with_imported_return_type();
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + test_closure_executable_with_return_type_from_closure() {
|
| + super.test_closure_executable_with_return_type_from_closure();
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + test_closure_executable_with_unimported_return_type() {
|
| + super.test_closure_executable_with_unimported_return_type();
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + test_implicit_dependencies_follow_other_dependencies() {
|
| + super.test_implicit_dependencies_follow_other_dependencies();
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + test_initializer_executable_with_bottom_return_type() {
|
| + super.test_initializer_executable_with_bottom_return_type();
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + test_initializer_executable_with_imported_return_type() {
|
| + super.test_initializer_executable_with_imported_return_type();
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + test_initializer_executable_with_return_type_from_closure() {
|
| + super.test_initializer_executable_with_return_type_from_closure();
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + test_initializer_executable_with_return_type_from_closure_field() {
|
| + super.test_initializer_executable_with_return_type_from_closure_field();
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + test_initializer_executable_with_return_type_from_closure_local() {
|
| + super.test_initializer_executable_with_return_type_from_closure_local();
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + test_initializer_executable_with_unimported_return_type() {
|
| + super.test_initializer_executable_with_unimported_return_type();
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + test_syntheticFunctionType_inGenericClass() {
|
| + super.test_syntheticFunctionType_inGenericClass();
|
| + }
|
| +
|
| + @override
|
| + @failingTest
|
| + test_syntheticFunctionType_inGenericFunction() {
|
| + super.test_syntheticFunctionType_inGenericFunction();
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * Override of [SummaryTest] which creates linked summaries directly from the
|
| + * AST.
|
| + */
|
| +@reflectiveTest
|
| +abstract class LinkedSummarizeAstTest extends SummaryLinkerTest
|
| + with SummaryTest {
|
| + @override
|
| + LinkedLibrary linked;
|
| +
|
| + @override
|
| + List<UnlinkedUnit> unlinkedUnits;
|
| +
|
| + LinkerInputs linkerInputs;
|
| +
|
| + @override
|
| + bool get skipFullyLinkedData => false;
|
| +
|
| + @override
|
| + bool get skipNonConstInitializers => false;
|
| +
|
| + @override
|
| + void serializeLibraryText(String text, {bool allowErrors: false}) {
|
| + Map<String, UnlinkedUnitBuilder> uriToUnit = this._filesToLink.uriToUnit;
|
| + linkerInputs = createLinkerInputs(text);
|
| + linked = link(
|
| + linkerInputs.linkedLibraries,
|
| + linkerInputs.getDependency,
|
| + linkerInputs.getUnit,
|
| + (name) => null,
|
| + strongMode)[linkerInputs.testDartUri.toString()];
|
| + expect(linked, isNotNull);
|
| + validateLinkedLibrary(linked);
|
| + unlinkedUnits = <UnlinkedUnit>[linkerInputs.unlinkedDefiningUnit];
|
| + for (String relativeUri
|
| + in linkerInputs.unlinkedDefiningUnit.publicNamespace.parts) {
|
| + UnlinkedUnit unit = uriToUnit[
|
| + resolveRelativeUri(linkerInputs.testDartUri, Uri.parse(relativeUri))
|
| + .toString()];
|
| + if (unit == null) {
|
| + if (!allowMissingFiles) {
|
| + fail('Test referred to unknown unit $relativeUri');
|
| + }
|
| + } else {
|
| + unlinkedUnits.add(unit);
|
| + }
|
| + }
|
| + }
|
| +
|
| + test_class_no_superclass() {
|
| + UnlinkedClass cls = serializeClassText('part of dart.core; class Object {}',
|
| + className: 'Object');
|
| + expect(cls.supertype, isNull);
|
| + expect(cls.hasNoSupertype, isTrue);
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * Instances of the class [LinkerInputs] encapsulate the necessary information
|
| + * to pass to the summary linker.
|
| + */
|
| +class LinkerInputs {
|
| + final bool _allowMissingFiles;
|
| + final Map<String, UnlinkedUnit> _uriToUnit;
|
| + final Uri testDartUri;
|
| + final UnlinkedUnit unlinkedDefiningUnit;
|
| + final Map<String, LinkedLibrary> _dependentLinkedLibraries;
|
| + final Map<String, UnlinkedUnit> _dependentUnlinkedUnits;
|
| +
|
| + LinkerInputs(
|
| + this._allowMissingFiles,
|
| + this._uriToUnit,
|
| + this.testDartUri,
|
| + this.unlinkedDefiningUnit,
|
| + this._dependentLinkedLibraries,
|
| + this._dependentUnlinkedUnits);
|
| +
|
| + Set<String> get linkedLibraries => _uriToUnit.keys.toSet();
|
| +
|
| + String getDeclaredVariable(String name) {
|
| + return null;
|
| + }
|
| +
|
| + LinkedLibrary getDependency(String absoluteUri) {
|
| + Map<String, LinkedLibrary> sdkLibraries =
|
| + SerializedMockSdk.instance.uriToLinkedLibrary;
|
| + LinkedLibrary linkedLibrary =
|
| + sdkLibraries[absoluteUri] ?? _dependentLinkedLibraries[absoluteUri];
|
| + if (linkedLibrary == null && !_allowMissingFiles) {
|
| + Set<String> librariesAvailable = sdkLibraries.keys.toSet();
|
| + librariesAvailable.addAll(_dependentLinkedLibraries.keys);
|
| + fail('Linker unexpectedly requested LinkedLibrary for "$absoluteUri".'
|
| + ' Libraries available: ${librariesAvailable.toList()}');
|
| + }
|
| + return linkedLibrary;
|
| + }
|
| +
|
| + UnlinkedUnit getUnit(String absoluteUri) {
|
| + UnlinkedUnit unit = _uriToUnit[absoluteUri] ??
|
| + SerializedMockSdk.instance.uriToUnlinkedUnit[absoluteUri] ??
|
| + _dependentUnlinkedUnits[absoluteUri];
|
| + if (unit == null && !_allowMissingFiles) {
|
| + fail('Linker unexpectedly requested unit for "$absoluteUri".');
|
| + }
|
| + return unit;
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * Base class providing the ability to run the summary linker using summaries
|
| + * build from ASTs.
|
| + */
|
| +abstract class SummaryLinkerTest {
|
| + /**
|
| + * Information about the files to be linked.
|
| + */
|
| + _FilesToLink _filesToLink = new _FilesToLink();
|
| +
|
| + /**
|
| + * A test will set this to `true` if it contains `import`, `export`, or
|
| + * `part` declarations that deliberately refer to non-existent files.
|
| + */
|
| + bool get allowMissingFiles;
|
| +
|
| + /**
|
| + * Add the given package bundle as a dependency so that it may be referenced
|
| + * by the files under test.
|
| + */
|
| + void addBundle(String path, PackageBundle bundle) {
|
| + _filesToLink.summaryDataStore.addBundle(path, bundle);
|
| + }
|
| +
|
| + /**
|
| + * Add the given source file so that it may be referenced by the file under
|
| + * test.
|
| + */
|
| + Source addNamedSource(String filePath, String contents) {
|
| + CompilationUnit unit = _parseText(contents);
|
| + UnlinkedUnitBuilder unlinkedUnit = serializeAstUnlinked(unit);
|
| + _filesToLink.uriToUnit[absUri(filePath)] = unlinkedUnit;
|
| + // Tests using SummaryLinkerTest don't actually need the returned
|
| + // Source, so we can safely return `null`.
|
| + return null;
|
| + }
|
| +
|
| + LinkerInputs createLinkerInputs(String text,
|
| + {String path: '/test.dart', String uri}) {
|
| + uri ??= absUri(path);
|
| + Uri testDartUri = Uri.parse(uri);
|
| + CompilationUnit unit = _parseText(text);
|
| + UnlinkedUnitBuilder unlinkedDefiningUnit = serializeAstUnlinked(unit);
|
| + _filesToLink.uriToUnit[testDartUri.toString()] = unlinkedDefiningUnit;
|
| + LinkerInputs linkerInputs = new LinkerInputs(
|
| + allowMissingFiles,
|
| + _filesToLink.uriToUnit,
|
| + testDartUri,
|
| + unlinkedDefiningUnit,
|
| + _filesToLink.summaryDataStore.linkedMap,
|
| + _filesToLink.summaryDataStore.unlinkedMap);
|
| + // Reset _filesToLink in case the test needs to start a new package bundle.
|
| + _filesToLink = new _FilesToLink();
|
| + return linkerInputs;
|
| + }
|
| +
|
| + /**
|
| + * Link together the given file, along with any other files passed to
|
| + * [addNamedSource], to form a package bundle. Reset the state of the buffers
|
| + * accumulated by [addNamedSource] and [addBundle] so that further bundles
|
| + * can be created.
|
| + */
|
| + PackageBundleBuilder createPackageBundle(String text,
|
| + {String path: '/test.dart', String uri}) {
|
| + PackageBundleAssembler assembler = new PackageBundleAssembler();
|
| + assembler.recordDependencies(_filesToLink.summaryDataStore);
|
| + LinkerInputs linkerInputs = createLinkerInputs(text, path: path, uri: uri);
|
| + Map<String, LinkedLibraryBuilder> linkedLibraries = link(
|
| + linkerInputs.linkedLibraries,
|
| + linkerInputs.getDependency,
|
| + linkerInputs.getUnit,
|
| + linkerInputs.getDeclaredVariable,
|
| + true);
|
| + linkedLibraries.forEach(assembler.addLinkedLibrary);
|
| + linkerInputs._uriToUnit.forEach((String uri, UnlinkedUnit unit) {
|
| + // Note: it doesn't matter what we store for the hash because it isn't
|
| + // used in these tests.
|
| + assembler.addUnlinkedUnitWithHash(uri, unit, 'HASH');
|
| + });
|
| + return assembler.assemble();
|
| + }
|
| +
|
| + CompilationUnit _parseText(String text) {
|
| + CharSequenceReader reader = new CharSequenceReader(text);
|
| + Scanner scanner =
|
| + new Scanner(null, reader, AnalysisErrorListener.NULL_LISTENER);
|
| + Token token = scanner.tokenize();
|
| + Parser parser = new Parser(null, AnalysisErrorListener.NULL_LISTENER);
|
| + parser.parseGenericMethods = true;
|
| + CompilationUnit unit = parser.parseCompilationUnit(token);
|
| + unit.lineInfo = new LineInfo(scanner.lineStarts);
|
| + return unit;
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * [_FilesToLink] stores information about a set of files to be linked together.
|
| + * This information is grouped into a class to allow it to be reset easily when
|
| + * [SummaryLinkerTest.createLinkerInputs] is called.
|
| + */
|
| +class _FilesToLink {
|
| + /**
|
| + * Map from absolute URI to the [UnlinkedUnit] for each compilation unit
|
| + * passed to [addNamedSource].
|
| + */
|
| + Map<String, UnlinkedUnitBuilder> uriToUnit = <String, UnlinkedUnitBuilder>{};
|
| +
|
| + /**
|
| + * Information about summaries to be included in the link process.
|
| + */
|
| + SummaryDataStore summaryDataStore =
|
| + new SummaryDataStore([], recordDependencyInfo: true);
|
| +}
|
|
|