blob: 5ec807e35754b90e5ec61c16c21eed09255878cc [file] [log] [blame]
// 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 test.src.summary.summary_sdk_test;
import 'dart:io';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/generated/engine.dart'
show AnalysisContext, CacheState;
import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/summary_sdk.dart';
import 'package:analyzer/src/task/dart.dart';
import 'package:analyzer/task/dart.dart';
import 'package:analyzer/task/model.dart' show AnalysisContextTarget;
import 'package:analyzer/task/model.dart';
import 'package:path/path.dart' as pathos;
import 'package:unittest/unittest.dart';
import '../../generated/test_support.dart';
import '../../reflective_tests.dart';
main() {
groupSep = ' | ';
runReflectiveTests(SummarySdkAnalysisContextTest);
}
@reflectiveTest
class SummarySdkAnalysisContextTest {
static String _analyzerPackagePath;
static bool _analyzerPackagePathInitialized = false;
static SdkBundle sdkBundle;
SummarySdkAnalysisContext context;
void setUp() {
_initializeSdkContext();
}
test_libraryResults() {
if (context == null) {
return;
}
// verify that there are at least some interesting libraries in the bundle
expect(sdkBundle.prelinkedLibraryUris, contains('dart:core'));
expect(sdkBundle.prelinkedLibraryUris, contains('dart:async'));
expect(sdkBundle.prelinkedLibraryUris, contains('dart:html'));
// verify every library
for (String uri in sdkBundle.prelinkedLibraryUris) {
// TODO(scheglov) breaks at _LibraryResynthesizer.buildImplicitTopLevelVariable
if (uri == 'dart:io' || uri == 'dart:_isolate_helper') {
continue;
}
_assertLibraryResults(uri);
}
}
test_sourceKind() {
if (context == null) {
return;
}
// libraries
_assertHasSourceKind('dart:core', SourceKind.LIBRARY);
_assertHasSourceKind('dart:async', SourceKind.LIBRARY);
_assertHasSourceKind('dart:math', SourceKind.LIBRARY);
// parts
_assertHasSourceKind('dart:core/bool.dart', SourceKind.PART);
_assertHasSourceKind('dart:async/future.dart', SourceKind.PART);
// unknown
_assertHasSourceKind('dart:no_such_library.dart', null);
_assertHasSourceKind('dart:core/no_such_part.dart', null);
}
test_typeProvider() {
if (context == null) {
return;
}
AnalysisContextTarget target = AnalysisContextTarget.request;
CacheEntry cacheEntry = context.getCacheEntry(target);
bool hasResult = context.aboutToComputeResult(cacheEntry, TYPE_PROVIDER);
expect(hasResult, isTrue);
expect(cacheEntry.getState(TYPE_PROVIDER), CacheState.VALID);
TypeProvider typeProvider = cacheEntry.getValue(TYPE_PROVIDER);
expect(typeProvider.objectType, isNotNull);
expect(typeProvider.boolType, isNotNull);
expect(typeProvider.intType, isNotNull);
expect(typeProvider.futureType, isNotNull);
expect(typeProvider.futureDynamicType, isNotNull);
expect(typeProvider.streamType, isNotNull);
expect(typeProvider.streamDynamicType, isNotNull);
}
void _assertHasLibraryElement(CacheEntry cacheEntry,
ResultDescriptor<LibraryElement> resultDescriptor) {
bool hasResult = context.aboutToComputeResult(cacheEntry, resultDescriptor);
expect(hasResult, isTrue);
expect(cacheEntry.getState(resultDescriptor), CacheState.VALID);
LibraryElement library = cacheEntry.getValue(resultDescriptor);
expect(library, isNotNull);
}
void _assertHasSourceKind(String uri, SourceKind expectedValue) {
Source target = context.sourceFactory.forUri(uri);
CacheEntry cacheEntry = context.getCacheEntry(target);
ResultDescriptor<SourceKind> resultDescriptor = SOURCE_KIND;
bool hasResult = context.aboutToComputeResult(cacheEntry, resultDescriptor);
if (expectedValue == null) {
expect(hasResult, isFalse);
expect(cacheEntry.getState(resultDescriptor), CacheState.INVALID);
} else {
expect(hasResult, isTrue);
expect(cacheEntry.getState(resultDescriptor), CacheState.VALID);
SourceKind value = cacheEntry.getValue(resultDescriptor);
expect(value, expectedValue);
}
}
void _assertIsLibraryElementReady(
CacheEntry cacheEntry, ResultDescriptor<bool> resultDescriptor) {
bool hasResult = context.aboutToComputeResult(cacheEntry, resultDescriptor);
expect(hasResult, isTrue);
expect(cacheEntry.getState(resultDescriptor), CacheState.VALID);
bool ready = cacheEntry.getValue(resultDescriptor);
expect(ready, isTrue);
}
void _assertLibraryResults(String uri) {
Source target = context.sourceFactory.forUri(uri);
CacheEntry cacheEntry = context.getCacheEntry(target);
_assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT1);
_assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT2);
_assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT3);
_assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT4);
_assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT5);
_assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT6);
_assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT7);
_assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT8);
_assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT);
_assertIsLibraryElementReady(cacheEntry, READY_LIBRARY_ELEMENT2);
_assertIsLibraryElementReady(cacheEntry, READY_LIBRARY_ELEMENT5);
_assertIsLibraryElementReady(cacheEntry, READY_LIBRARY_ELEMENT6);
}
void _initializeSdkBundle() {
if (sdkBundle != null) {
return;
}
// prepare analyzer path
String analyzerPath = getAnalyzerPackagePath();
if (analyzerPath == null) {
return;
}
// prepare summary path
String sdkSummaryPath = pathos.join(
analyzerPath, 'test', 'src', 'summary', 'sdk_analysis_summary');
File file = new File(sdkSummaryPath);
if (!file.existsSync()) {
return;
}
// load SdkBundle
List<int> bytes = file.readAsBytesSync();
sdkBundle = new SdkBundle.fromBuffer(bytes);
}
void _initializeSdkContext() {
_initializeSdkBundle();
if (sdkBundle == null) {
return;
}
context = new _TestSummarySdkAnalysisContext(sdkBundle);
DartSdk sdk = new _TestSummaryDartSdk();
context.sourceFactory = new SourceFactory([new DartUriResolver(sdk)]);
}
static String getAnalyzerPackagePath() {
if (!_analyzerPackagePathInitialized) {
_analyzerPackagePathInitialized = true;
_analyzerPackagePath = _computeAnalyzerPackagePath();
}
return _analyzerPackagePath;
}
/**
* Return the path to the `analyzer` package root, or `null` if it cannot
* be determined.
*
* This method expects that one of the `analyzer` tests was run, so
* [Platform.script] is inside of the `analyzer/test` folder.
*/
static String _computeAnalyzerPackagePath() {
Uri uri = Platform.script;
if (uri == null || uri.scheme != 'file') {
return null;
}
String path = pathos.fromUri(uri);
List<String> segments = pathos.split(path);
while (segments.length > 2) {
if (segments[segments.length - 1] == 'test' &&
segments[segments.length - 2] == 'analyzer') {
segments.removeLast();
return pathos.joinAll(segments);
}
segments.removeLast();
}
return null;
}
}
class _TestSummaryDartSdk implements DartSdk {
@override
Source mapDartUri(String uriStr) {
Uri uri = Uri.parse(uriStr);
List<String> segments = uri.pathSegments;
if (segments.length == 1) {
String libraryName = segments.first;
String path = '/sdk/$libraryName/$libraryName.dart';
return new _TestSummarySdkSource(path, uri);
} else {
String path = '/sdk/' + segments.join('/');
return new _TestSummarySdkSource(path, uri);
}
}
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
/**
* [SummarySdkAnalysisContext] with simplified cache creation.
*/
class _TestSummarySdkAnalysisContext extends SummarySdkAnalysisContext {
_TestSummarySdkAnalysisContext(SdkBundle bundle) : super(bundle);
@override
AnalysisCache createCacheFromSourceFactory(SourceFactory factory) {
return new AnalysisCache(<CachePartition>[new SdkCachePartition(this)]);
}
}
class _TestSummarySdkSource extends TestSourceWithUri {
_TestSummarySdkSource(String path, Uri uri) : super(path, uri);
@override
bool get isInSystemLibrary => true;
@override
Uri resolveRelativeUri(Uri relativeUri) {
Uri baseUri = uri;
if (uri.scheme == 'dart') {
String libraryName = uri.path;
baseUri = Uri.parse('dart:$libraryName/$libraryName.dart');
}
return baseUri.resolveUri(relativeUri);
}
}