blob: e54f587aa83b0c19aade9d46d73492d57a78cae7 [file] [log] [blame]
// Copyright (c) 2015, 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.
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/file_system/file_system.dart' show ResourceProvider;
import 'package:analyzer/src/context/context.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/constant.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart'
show DartUriResolver, Source, SourceFactory;
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/package_bundle_reader.dart';
/**
* An implementation of [DartSdk] which provides analysis results for `dart:`
* libraries from the given summary file. This implementation is limited and
* suitable only for command-line tools, but not for IDEs - it does not
* implement [sdkLibraries], [sdkVersion], [uris] and [fromFileUri].
*/
class SummaryBasedDartSdk implements DartSdk {
SummaryDataStore _dataStore;
InSummaryUriResolver _uriResolver;
PackageBundle _bundle;
ResourceProvider resourceProvider;
/**
* The [AnalysisContext] which is used for all of the sources in this sdk.
*/
InternalAnalysisContext _analysisContext;
SummaryBasedDartSdk(String summaryPath, bool _, {this.resourceProvider}) {
_dataStore = new SummaryDataStore(<String>[summaryPath],
resourceProvider: resourceProvider);
_uriResolver = new InSummaryUriResolver(resourceProvider, _dataStore);
_bundle = _dataStore.bundles.single;
}
SummaryBasedDartSdk.fromBundle(bool _, PackageBundle bundle,
{this.resourceProvider}) {
_dataStore = new SummaryDataStore([], resourceProvider: resourceProvider);
_dataStore.addBundle('dart_sdk.sum', bundle);
_uriResolver = new InSummaryUriResolver(resourceProvider, _dataStore);
_bundle = bundle;
}
/**
* Return the [PackageBundle] for this SDK, not `null`.
*/
PackageBundle get bundle => _bundle;
@override
AnalysisContext get context {
if (_analysisContext == null) {
AnalysisOptionsImpl analysisOptions = new AnalysisOptionsImpl();
_analysisContext = new SdkAnalysisContext(analysisOptions);
SourceFactory factory = new SourceFactory(
[new DartUriResolver(this)], null, resourceProvider);
_analysisContext.sourceFactory = factory;
}
return _analysisContext;
}
@override
List<SdkLibrary> get sdkLibraries {
throw new UnimplementedError();
}
@override
String get sdkVersion {
throw new UnimplementedError();
}
bool get strongMode => true;
@override
List<String> get uris {
throw new UnimplementedError();
}
@override
Source fromFileUri(Uri uri) {
return null;
}
@override
PackageBundle getLinkedBundle() => _bundle;
@override
SdkLibrary getSdkLibrary(String uri) {
// This is not quite correct, but currently it's used only in
// to report errors on importing or exporting of internal libraries.
return null;
}
@override
Source mapDartUri(String uriStr) {
Uri uri = Uri.parse(uriStr);
return _uriResolver.resolveAbsolute(uri);
}
}
/**
* Implementation of [TypeProvider] which can be initialized separately with
* `dart:core` and `dart:async` libraries.
*/
class SummaryTypeProvider extends TypeProviderBase {
LibraryElement _coreLibrary;
LibraryElement _asyncLibrary;
InterfaceType _boolType;
InterfaceType _deprecatedType;
InterfaceType _doubleType;
InterfaceType _functionType;
InterfaceType _futureDynamicType;
InterfaceType _futureNullType;
InterfaceType _futureOrNullType;
InterfaceType _futureOrType;
InterfaceType _futureType;
InterfaceType _intType;
InterfaceType _iterableDynamicType;
InterfaceType _iterableObjectType;
InterfaceType _iterableType;
InterfaceType _listType;
InterfaceType _mapType;
InterfaceType _mapObjectObjectType;
DartObjectImpl _nullObject;
InterfaceType _nullType;
InterfaceType _numType;
InterfaceType _objectType;
InterfaceType _setType;
InterfaceType _stackTraceType;
InterfaceType _streamDynamicType;
InterfaceType _streamType;
InterfaceType _stringType;
InterfaceType _symbolType;
InterfaceType _typeType;
@override
InterfaceType get boolType {
assert(_coreLibrary != null);
_boolType ??= _getType(_coreLibrary, "bool");
return _boolType;
}
@override
DartType get bottomType => BottomTypeImpl.instanceLegacy;
@override
InterfaceType get deprecatedType {
assert(_coreLibrary != null);
_deprecatedType ??= _getType(_coreLibrary, "Deprecated");
return _deprecatedType;
}
@override
InterfaceType get doubleType {
assert(_coreLibrary != null);
_doubleType ??= _getType(_coreLibrary, "double");
return _doubleType;
}
@override
DartType get dynamicType => DynamicTypeImpl.instance;
@override
InterfaceType get functionType {
assert(_coreLibrary != null);
_functionType ??= _getType(_coreLibrary, "Function");
return _functionType;
}
@override
InterfaceType get futureDynamicType {
assert(_asyncLibrary != null);
_futureDynamicType ??= futureType.instantiate(<DartType>[dynamicType]);
return _futureDynamicType;
}
@override
InterfaceType get futureNullType {
assert(_asyncLibrary != null);
_futureNullType ??= futureType.instantiate(<DartType>[nullType]);
return _futureNullType;
}
@override
InterfaceType get futureOrNullType {
assert(_asyncLibrary != null);
_futureOrNullType ??= futureOrType.instantiate(<DartType>[nullType]);
return _futureOrNullType;
}
@override
InterfaceType get futureOrType {
assert(_asyncLibrary != null);
try {
_futureOrType ??= _getType(_asyncLibrary, "FutureOr");
} on StateError {
// FutureOr<T> is still fairly new, so if we're analyzing an SDK that
// doesn't have it yet, create an element for it.
_futureOrType =
TypeProviderImpl.createPlaceholderFutureOr(futureType, objectType);
}
return _futureOrType;
}
@override
InterfaceType get futureType {
assert(_asyncLibrary != null);
_futureType ??= _getType(_asyncLibrary, "Future");
return _futureType;
}
@override
InterfaceType get intType {
assert(_coreLibrary != null);
_intType ??= _getType(_coreLibrary, "int");
return _intType;
}
@override
InterfaceType get iterableDynamicType {
assert(_coreLibrary != null);
_iterableDynamicType ??= iterableType.instantiate(<DartType>[dynamicType]);
return _iterableDynamicType;
}
@override
InterfaceType get iterableObjectType {
assert(_coreLibrary != null);
_iterableObjectType ??= iterableType.instantiate(<DartType>[objectType]);
return _iterableObjectType;
}
@override
InterfaceType get iterableType {
assert(_coreLibrary != null);
_iterableType ??= _getType(_coreLibrary, "Iterable");
return _iterableType;
}
@override
InterfaceType get listType {
assert(_coreLibrary != null);
_listType ??= _getType(_coreLibrary, "List");
return _listType;
}
@override
InterfaceType get mapObjectObjectType {
assert(_coreLibrary != null);
return _mapObjectObjectType ??=
mapType.instantiate(<DartType>[objectType, objectType]);
}
@override
InterfaceType get mapType {
assert(_coreLibrary != null);
_mapType ??= _getType(_coreLibrary, "Map");
return _mapType;
}
@override
DartType get neverType => BottomTypeImpl.instance;
@override
DartObjectImpl get nullObject {
if (_nullObject == null) {
_nullObject = new DartObjectImpl(nullType, NullState.NULL_STATE);
}
return _nullObject;
}
@override
InterfaceType get nullType {
assert(_coreLibrary != null);
_nullType ??= _getType(_coreLibrary, "Null");
return _nullType;
}
@override
InterfaceType get numType {
assert(_coreLibrary != null);
_numType ??= _getType(_coreLibrary, "num");
return _numType;
}
@override
InterfaceType get objectType {
assert(_coreLibrary != null);
_objectType ??= _getType(_coreLibrary, "Object");
return _objectType;
}
@override
InterfaceType get setType {
assert(_coreLibrary != null);
return _setType ??= _getType(_coreLibrary, "Set");
}
@override
InterfaceType get stackTraceType {
assert(_coreLibrary != null);
_stackTraceType ??= _getType(_coreLibrary, "StackTrace");
return _stackTraceType;
}
@override
InterfaceType get streamDynamicType {
assert(_asyncLibrary != null);
_streamDynamicType ??= streamType.instantiate(<DartType>[dynamicType]);
return _streamDynamicType;
}
@override
InterfaceType get streamType {
assert(_asyncLibrary != null);
_streamType ??= _getType(_asyncLibrary, "Stream");
return _streamType;
}
@override
InterfaceType get stringType {
assert(_coreLibrary != null);
_stringType ??= _getType(_coreLibrary, "String");
return _stringType;
}
@override
InterfaceType get symbolType {
assert(_coreLibrary != null);
_symbolType ??= _getType(_coreLibrary, "Symbol");
return _symbolType;
}
@override
InterfaceType get typeType {
assert(_coreLibrary != null);
_typeType ??= _getType(_coreLibrary, "Type");
return _typeType;
}
/**
* Initialize the `dart:async` types provided by this type provider.
*/
void initializeAsync(LibraryElement library) {
assert(_coreLibrary != null);
assert(_asyncLibrary == null);
_asyncLibrary = library;
}
/**
* Initialize the `dart:core` types provided by this type provider.
*/
void initializeCore(LibraryElement library) {
assert(_coreLibrary == null);
assert(_asyncLibrary == null);
_coreLibrary = library;
}
/**
* Return the type with the given [name] from the given [library], or
* throw a [StateError] if there is no class with the given name.
*/
InterfaceType _getType(LibraryElement library, String name) {
Element element = library.getType(name);
if (element == null) {
throw new StateError("No definition of type $name");
}
return (element as ClassElement).type;
}
}