| Index: pkg/analyzer_plugin/test/support/mock_sdk.dart
|
| diff --git a/pkg/analyzer_plugin/test/support/mock_sdk.dart b/pkg/analyzer_plugin/test/support/mock_sdk.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..8575bcc00c3fc0bcc80d4badc42721279d488a17
|
| --- /dev/null
|
| +++ b/pkg/analyzer_plugin/test/support/mock_sdk.dart
|
| @@ -0,0 +1,463 @@
|
| +// Copyright (c) 2017, 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/file_system/file_system.dart' as resource;
|
| +import 'package:analyzer/file_system/memory_file_system.dart' as resource;
|
| +import 'package:analyzer/src/context/context.dart';
|
| +import 'package:analyzer/src/generated/engine.dart';
|
| +import 'package:analyzer/src/generated/sdk.dart';
|
| +import 'package:analyzer/src/generated/source.dart';
|
| +import 'package:analyzer/src/summary/idl.dart' show PackageBundle;
|
| +import 'package:analyzer/src/summary/summary_file_builder.dart';
|
| +
|
| +/**
|
| + * A utility class that will create a Mock SDK on the virtual disk managed by a
|
| + * memory resource provider.
|
| + */
|
| +class MockSdk implements DartSdk {
|
| + static const MockSdkLibrary LIB_CORE = const MockSdkLibrary(
|
| + 'dart:core',
|
| + '/lib/core/core.dart',
|
| + '''
|
| +library dart.core;
|
| +
|
| +import 'dart:async';
|
| +import 'dart:_internal';
|
| +
|
| +class Object {
|
| + const Object() {}
|
| + bool operator ==(other) => identical(this, other);
|
| + String toString() => 'a string';
|
| + int get hashCode => 0;
|
| + Type get runtimeType => null;
|
| + dynamic noSuchMethod(Invocation invocation) => null;
|
| +}
|
| +
|
| +class Function {}
|
| +class StackTrace {}
|
| +class Symbol {}
|
| +class Type {}
|
| +
|
| +abstract class Comparable<T> {
|
| + int compareTo(T other);
|
| +}
|
| +
|
| +abstract class String implements Comparable<String> {
|
| + external factory String.fromCharCodes(Iterable<int> charCodes,
|
| + [int start = 0, int end]);
|
| + bool get isEmpty => false;
|
| + bool get isNotEmpty => false;
|
| + int get length => 0;
|
| + String toUpperCase();
|
| + List<int> get codeUnits;
|
| +}
|
| +
|
| +class bool extends Object {}
|
| +
|
| +abstract class num implements Comparable<num> {
|
| + bool operator <(num other);
|
| + bool operator <=(num other);
|
| + bool operator >(num other);
|
| + bool operator >=(num other);
|
| + num operator +(num other);
|
| + num operator -(num other);
|
| + num operator *(num other);
|
| + num operator /(num other);
|
| + int operator ^(int other);
|
| + int operator &(int other);
|
| + int operator |(int other);
|
| + int operator <<(int other);
|
| + int operator >>(int other);
|
| + int operator ~/(num other);
|
| + num operator %(num other);
|
| + int operator ~();
|
| + int toInt();
|
| + double toDouble();
|
| + num abs();
|
| + int round();
|
| +}
|
| +
|
| +abstract class int extends num {
|
| + bool get isEven => false;
|
| + int operator -();
|
| + external static int parse(String source,
|
| + { int radix,
|
| + int onError(String source) });
|
| +}
|
| +
|
| +abstract class double extends num {
|
| + static const double NAN = 0.0 / 0.0;
|
| + static const double INFINITY = 1.0 / 0.0;
|
| + static const double NEGATIVE_INFINITY = -INFINITY;
|
| + static const double MIN_POSITIVE = 5e-324;
|
| + static const double MAX_FINITE = 1.7976931348623157e+308;
|
| +
|
| + double remainder(num other);
|
| + double operator +(num other);
|
| + double operator -(num other);
|
| + double operator *(num other);
|
| + double operator %(num other);
|
| + double operator /(num other);
|
| + int operator ~/(num other);
|
| + double operator -();
|
| + double abs();
|
| + double get sign;
|
| + int round();
|
| + int floor();
|
| + int ceil();
|
| + int truncate();
|
| + double roundToDouble();
|
| + double floorToDouble();
|
| + double ceilToDouble();
|
| + double truncateToDouble();
|
| + external static double parse(String source,
|
| + [double onError(String source)]);
|
| +}
|
| +
|
| +class DateTime extends Object {}
|
| +class Null extends Object {}
|
| +
|
| +class Deprecated extends Object {
|
| + final String expires;
|
| + const Deprecated(this.expires);
|
| +}
|
| +const Object deprecated = const Deprecated("next release");
|
| +
|
| +class Iterator<E> {
|
| + bool moveNext();
|
| + E get current;
|
| +}
|
| +
|
| +abstract class Iterable<E> {
|
| + Iterator<E> get iterator;
|
| + bool get isEmpty;
|
| + Iterable/*<R>*/ map/*<R>*/(/*=R*/ f(E e));
|
| +}
|
| +
|
| +class List<E> implements Iterable<E> {
|
| + List();
|
| + void add(E value) {}
|
| + void addAll(Iterable<E> iterable) {}
|
| + E operator [](int index) => null;
|
| + void operator []=(int index, E value) {}
|
| + Iterator<E> get iterator => null;
|
| + void clear() {}
|
| +
|
| + bool get isEmpty => false;
|
| + E get first => null;
|
| + E get last => null;
|
| +
|
| + Iterable/*<R>*/ map/*<R>*/(/*=R*/ f(E e)) => null;
|
| +
|
| + /*=R*/ fold/*<R>*/(/*=R*/ initialValue,
|
| + /*=R*/ combine(/*=R*/ previousValue, E element)) => null;
|
| +
|
| +}
|
| +
|
| +abstract class Map<K, V> extends Object {
|
| + bool containsKey(Object key);
|
| + Iterable<K> get keys;
|
| +}
|
| +
|
| +external bool identical(Object a, Object b);
|
| +
|
| +void print(Object object) {}
|
| +
|
| +class Uri {
|
| + static List<int> parseIPv6Address(String host, [int start = 0, int end]) {
|
| + int parseHex(int start, int end) {
|
| + return 0;
|
| + }
|
| + return null;
|
| + }
|
| +}
|
| +''');
|
| +
|
| + static const MockSdkLibrary LIB_ASYNC = const MockSdkLibrary(
|
| + 'dart:async',
|
| + '/lib/async/async.dart',
|
| + '''
|
| +library dart.async;
|
| +
|
| +import 'dart:math';
|
| +
|
| +class Future<T> {
|
| + factory Future(computation()) => null;
|
| + factory Future.delayed(Duration duration, [T computation()]) => null;
|
| + factory Future.value([value]) => null;
|
| + static Future wait(List<Future> futures) => null;
|
| +}
|
| +
|
| +class FutureOr<T> {}
|
| +
|
| +class Stream<T> {}
|
| +abstract class StreamTransformer<S, T> {}
|
| +''');
|
| +
|
| + static const MockSdkLibrary LIB_COLLECTION = const MockSdkLibrary(
|
| + 'dart:collection',
|
| + '/lib/collection/collection.dart',
|
| + '''
|
| +library dart.collection;
|
| +
|
| +abstract class HashMap<K, V> implements Map<K, V> {}
|
| +abstract class LinkedHashMap<K, V> implements Map<K, V> {}
|
| +''');
|
| +
|
| + static const MockSdkLibrary LIB_CONVERT = const MockSdkLibrary(
|
| + 'dart:convert',
|
| + '/lib/convert/convert.dart',
|
| + '''
|
| +library dart.convert;
|
| +
|
| +import 'dart:async';
|
| +
|
| +abstract class Converter<S, T> implements StreamTransformer {}
|
| +class JsonDecoder extends Converter<String, Object> {}
|
| +''');
|
| +
|
| + static const MockSdkLibrary LIB_MATH = const MockSdkLibrary(
|
| + 'dart:math',
|
| + '/lib/math/math.dart',
|
| + '''
|
| +library dart.math;
|
| +const double E = 2.718281828459045;
|
| +const double PI = 3.1415926535897932;
|
| +const double LN10 = 2.302585092994046;
|
| +T min<T extends num>(T a, T b) => null;
|
| +T max<T extends num>(T a, T b) => null;
|
| +external double cos(num radians);
|
| +external num pow(num x, num exponent);
|
| +external double sin(num radians);
|
| +external double sqrt(num x);
|
| +class Random {
|
| + bool nextBool() => true;
|
| + double nextDouble() => 2.0;
|
| + int nextInt() => 1;
|
| +}
|
| +''');
|
| +
|
| + static const MockSdkLibrary LIB_HTML = const MockSdkLibrary(
|
| + 'dart:html',
|
| + '/lib/html/dartium/html_dartium.dart',
|
| + '''
|
| +library dart.html;
|
| +class HtmlElement {}
|
| +''');
|
| +
|
| + static const MockSdkLibrary LIB_INTERNAL = const MockSdkLibrary(
|
| + 'dart:_internal',
|
| + '/lib/internal/internal.dart',
|
| + '''
|
| +library dart._internal;
|
| +external void printToConsole(String line);
|
| +''');
|
| +
|
| + static const List<SdkLibrary> LIBRARIES = const [
|
| + LIB_CORE,
|
| + LIB_ASYNC,
|
| + LIB_COLLECTION,
|
| + LIB_CONVERT,
|
| + LIB_MATH,
|
| + LIB_HTML,
|
| + LIB_INTERNAL,
|
| + ];
|
| +
|
| + static const String librariesContent = r'''
|
| +const Map<String, LibraryInfo> libraries = const {
|
| + "async": const LibraryInfo("async/async.dart"),
|
| + "collection": const LibraryInfo("collection/collection.dart"),
|
| + "convert": const LibraryInfo("convert/convert.dart"),
|
| + "core": const LibraryInfo("core/core.dart"),
|
| + "html": const LibraryInfo("html/dartium/html_dartium.dart"),
|
| + "math": const LibraryInfo("math/math.dart"),
|
| + "_internal": const LibraryInfo("internal/internal.dart"),
|
| +};
|
| +''';
|
| +
|
| + final resource.MemoryResourceProvider provider;
|
| +
|
| + /**
|
| + * The [AnalysisContext] which is used for all of the sources.
|
| + */
|
| + InternalAnalysisContext _analysisContext;
|
| +
|
| + /**
|
| + * The cached linked bundle of the SDK.
|
| + */
|
| + PackageBundle _bundle;
|
| +
|
| + MockSdk(
|
| + {bool generateSummaryFiles: false,
|
| + resource.ResourceProvider resourceProvider})
|
| + : provider = resourceProvider ?? new resource.MemoryResourceProvider() {
|
| + LIBRARIES.forEach((SdkLibrary library) {
|
| + provider.newFile(library.path, (library as MockSdkLibrary).content);
|
| + });
|
| + provider.newFile(
|
| + provider.convertPath(
|
| + '/lib/_internal/sdk_library_metadata/lib/libraries.dart'),
|
| + librariesContent);
|
| + if (generateSummaryFiles) {
|
| + List<int> bytes = _computeLinkedBundleBytes();
|
| + provider.newFileWithBytes(
|
| + provider.convertPath('/lib/_internal/spec.sum'), bytes);
|
| + provider.newFileWithBytes(
|
| + provider.convertPath('/lib/_internal/strong.sum'), bytes);
|
| + }
|
| + }
|
| +
|
| + @override
|
| + AnalysisContext get context {
|
| + if (_analysisContext == null) {
|
| + _analysisContext = new SdkAnalysisContext(null);
|
| + SourceFactory factory = new SourceFactory([new DartUriResolver(this)]);
|
| + _analysisContext.sourceFactory = factory;
|
| + }
|
| + return _analysisContext;
|
| + }
|
| +
|
| + @override
|
| + List<SdkLibrary> get sdkLibraries => LIBRARIES;
|
| +
|
| + @override
|
| + String get sdkVersion => throw unimplemented;
|
| +
|
| + UnimplementedError get unimplemented => new UnimplementedError();
|
| +
|
| + @override
|
| + List<String> get uris {
|
| + List<String> uris = <String>[];
|
| + for (SdkLibrary library in LIBRARIES) {
|
| + uris.add(library.shortName);
|
| + }
|
| + return uris;
|
| + }
|
| +
|
| + @override
|
| + Source fromFileUri(Uri uri) {
|
| + String filePath = provider.pathContext.fromUri(uri);
|
| + for (SdkLibrary library in sdkLibraries) {
|
| + String libraryPath = provider.convertPath(library.path);
|
| + if (filePath == libraryPath) {
|
| + try {
|
| + resource.File file = provider.getResource(filePath);
|
| + Uri dartUri = Uri.parse(library.shortName);
|
| + return file.createSource(dartUri);
|
| + } catch (exception) {
|
| + return null;
|
| + }
|
| + }
|
| + String libraryRootPath = provider.pathContext.dirname(libraryPath) +
|
| + provider.pathContext.separator;
|
| + if (filePath.startsWith(libraryRootPath)) {
|
| + String pathInLibrary = filePath.substring(libraryRootPath.length);
|
| + String uriStr = '${library.shortName}/$pathInLibrary';
|
| + try {
|
| + resource.File file = provider.getResource(filePath);
|
| + Uri dartUri = Uri.parse(uriStr);
|
| + return file.createSource(dartUri);
|
| + } catch (exception) {
|
| + return null;
|
| + }
|
| + }
|
| + }
|
| + return null;
|
| + }
|
| +
|
| + @override
|
| + PackageBundle getLinkedBundle() {
|
| + if (_bundle == null) {
|
| + resource.File summaryFile =
|
| + provider.getFile(provider.convertPath('/lib/_internal/spec.sum'));
|
| + List<int> bytes;
|
| + if (summaryFile.exists) {
|
| + bytes = summaryFile.readAsBytesSync();
|
| + } else {
|
| + bytes = _computeLinkedBundleBytes();
|
| + }
|
| + _bundle = new PackageBundle.fromBuffer(bytes);
|
| + }
|
| + return _bundle;
|
| + }
|
| +
|
| + @override
|
| + SdkLibrary getSdkLibrary(String dartUri) {
|
| + // getSdkLibrary() is only used to determine whether a library is internal
|
| + // to the SDK. The mock SDK doesn't have any internals, so it's safe to
|
| + // return null.
|
| + return null;
|
| + }
|
| +
|
| + @override
|
| + Source mapDartUri(String dartUri) {
|
| + const Map<String, String> uriToPath = const {
|
| + "dart:core": "/lib/core/core.dart",
|
| + "dart:html": "/lib/html/dartium/html_dartium.dart",
|
| + "dart:async": "/lib/async/async.dart",
|
| + "dart:collection": "/lib/collection/collection.dart",
|
| + "dart:convert": "/lib/convert/convert.dart",
|
| + "dart:math": "/lib/math/math.dart",
|
| + "dart:_internal": "/lib/internal/internal.dart",
|
| + };
|
| +
|
| + String path = uriToPath[dartUri];
|
| + if (path != null) {
|
| + resource.File file = provider.getResource(path);
|
| + Uri uri = new Uri(scheme: 'dart', path: dartUri.substring(5));
|
| + return file.createSource(uri);
|
| + }
|
| +
|
| + // If we reach here then we tried to use a dartUri that's not in the
|
| + // table above.
|
| + return null;
|
| + }
|
| +
|
| + /**
|
| + * Compute the bytes of the linked bundle associated with this SDK.
|
| + */
|
| + List<int> _computeLinkedBundleBytes() {
|
| + List<Source> librarySources = sdkLibraries
|
| + .map((SdkLibrary library) => mapDartUri(library.shortName))
|
| + .toList();
|
| + return new SummaryBuilder(
|
| + librarySources, context, context.analysisOptions.strongMode)
|
| + .build();
|
| + }
|
| +}
|
| +
|
| +class MockSdkLibrary implements SdkLibrary {
|
| + @override
|
| + final String shortName;
|
| +
|
| + @override
|
| + final String path;
|
| +
|
| + final String content;
|
| +
|
| + const MockSdkLibrary(this.shortName, this.path, this.content);
|
| +
|
| + @override
|
| + String get category => throw unimplemented;
|
| +
|
| + @override
|
| + bool get isDart2JsLibrary => throw unimplemented;
|
| +
|
| + @override
|
| + bool get isDocumented => throw unimplemented;
|
| +
|
| + @override
|
| + bool get isImplementation => false;
|
| +
|
| + @override
|
| + bool get isInternal => shortName.startsWith('dart:_');
|
| +
|
| + @override
|
| + bool get isShared => throw unimplemented;
|
| +
|
| + @override
|
| + bool get isVmLibrary => throw unimplemented;
|
| +
|
| + UnimplementedError get unimplemented => new UnimplementedError();
|
| +}
|
|
|