| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2015, 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 linter.src.sdk; | |
| 6 | |
| 7 import 'package:analyzer/file_system/file_system.dart' as resource; | |
| 8 import 'package:analyzer/file_system/memory_file_system.dart' as resource; | |
| 9 import 'package:analyzer/src/context/cache.dart' | |
| 10 show AnalysisCache, CachePartition; | |
| 11 import 'package:analyzer/src/context/context.dart' show AnalysisContextImpl; | |
| 12 import 'package:analyzer/src/generated/engine.dart' | |
| 13 show AnalysisEngine, ChangeSet; | |
| 14 import 'package:analyzer/src/generated/sdk.dart' show DartSdk, SdkLibrary; | |
| 15 import 'package:analyzer/src/generated/source.dart' | |
| 16 show DartUriResolver, Source, SourceFactory; | |
| 17 import 'package:analyzer/src/summary/idl.dart'; | |
| 18 | |
| 19 /// Mock SDK for testing purposes. | |
| 20 class MockSdk implements DartSdk { | |
| 21 static const _MockSdkLibrary LIB_CORE = const _MockSdkLibrary( | |
| 22 'dart:core', | |
| 23 '/lib/core/core.dart', | |
| 24 ''' | |
| 25 library dart.core; | |
| 26 | |
| 27 import 'dart:async'; | |
| 28 | |
| 29 class Object { | |
| 30 bool operator ==(other) => identical(this, other); | |
| 31 String toString() => 'a string'; | |
| 32 int get hashCode => 0; | |
| 33 } | |
| 34 | |
| 35 class Function {} | |
| 36 class StackTrace {} | |
| 37 class Symbol {} | |
| 38 class Type {} | |
| 39 | |
| 40 abstract class Comparable<T> { | |
| 41 int compareTo(T other); | |
| 42 } | |
| 43 | |
| 44 abstract class String implements Comparable<String> { | |
| 45 external factory String.fromCharCodes(Iterable<int> charCodes, | |
| 46 [int start = 0, int end]); | |
| 47 bool get isEmpty => false; | |
| 48 bool get isNotEmpty => false; | |
| 49 int get length => 0; | |
| 50 String toUpperCase(); | |
| 51 List<int> get codeUnits; | |
| 52 } | |
| 53 | |
| 54 class bool extends Object {} | |
| 55 abstract class num implements Comparable<num> { | |
| 56 bool operator <(num other); | |
| 57 bool operator <=(num other); | |
| 58 bool operator >(num other); | |
| 59 bool operator >=(num other); | |
| 60 num operator +(num other); | |
| 61 num operator -(num other); | |
| 62 num operator *(num other); | |
| 63 num operator /(num other); | |
| 64 int toInt(); | |
| 65 num abs(); | |
| 66 int round(); | |
| 67 } | |
| 68 abstract class int extends num { | |
| 69 bool get isEven => false; | |
| 70 int operator -(); | |
| 71 external static int parse(String source, | |
| 72 { int radix, | |
| 73 int onError(String source) }); | |
| 74 } | |
| 75 class double extends num {} | |
| 76 class DateTime extends Object {} | |
| 77 class Null extends Object {} | |
| 78 | |
| 79 class Deprecated extends Object { | |
| 80 final String expires; | |
| 81 const Deprecated(this.expires); | |
| 82 } | |
| 83 const Object deprecated = const Deprecated("next release"); | |
| 84 | |
| 85 class Iterator<E> { | |
| 86 bool moveNext(); | |
| 87 E get current; | |
| 88 } | |
| 89 | |
| 90 abstract class Iterable<E> { | |
| 91 Iterator<E> get iterator; | |
| 92 bool get isEmpty; | |
| 93 bool get isNotEmpty; | |
| 94 } | |
| 95 | |
| 96 abstract class List<E> implements Iterable<E> { | |
| 97 void add(E value); | |
| 98 E operator [](int index); | |
| 99 void operator []=(int index, E value); | |
| 100 Iterator<E> get iterator => null; | |
| 101 void clear(); | |
| 102 bool get isEmpty; | |
| 103 bool get isNotEmpty; | |
| 104 } | |
| 105 | |
| 106 abstract class Map<K, V> extends Object { | |
| 107 Iterable<K> get keys; | |
| 108 bool get isEmpty; | |
| 109 bool get isNotEmpty; | |
| 110 } | |
| 111 | |
| 112 external bool identical(Object a, Object b); | |
| 113 | |
| 114 void print(Object object) {} | |
| 115 | |
| 116 class _Override { | |
| 117 const _Override(); | |
| 118 } | |
| 119 const Object override = const _Override(); | |
| 120 | |
| 121 | |
| 122 abstract class RegExp { | |
| 123 external factory RegExp(String source, {bool multiLine: false, | |
| 124 bool caseSensitive: true}); | |
| 125 '''); | |
| 126 | |
| 127 static const _MockSdkLibrary LIB_ASYNC = const _MockSdkLibrary( | |
| 128 'dart:async', | |
| 129 '/lib/async/async.dart', | |
| 130 ''' | |
| 131 library dart.async; | |
| 132 | |
| 133 import 'dart:math'; | |
| 134 | |
| 135 part 'stream.dart'; | |
| 136 | |
| 137 class Future<T> { | |
| 138 factory Future.delayed(Duration duration, [T computation()]) => null; | |
| 139 factory Future.value([value]) => null; | |
| 140 static Future wait(List<Future> futures) => null; | |
| 141 } | |
| 142 ''', | |
| 143 const <_MockSdkFile>[ | |
| 144 const _MockSdkFile( | |
| 145 '/lib/async/stream.dart', | |
| 146 r''' | |
| 147 part of dart.async; | |
| 148 class Stream<T> {} | |
| 149 abstract class StreamTransformer<S, T> {} | |
| 150 ''') | |
| 151 ]); | |
| 152 | |
| 153 static const _MockSdkLibrary LIB_COLLECTION = const _MockSdkLibrary( | |
| 154 'dart:collection', | |
| 155 '/lib/collection/collection.dart', | |
| 156 ''' | |
| 157 library dart.collection; | |
| 158 | |
| 159 abstract class HashMap<K, V> implements Map<K, V> {} | |
| 160 '''); | |
| 161 | |
| 162 static const _MockSdkLibrary LIB_CONVERT = const _MockSdkLibrary( | |
| 163 'dart:convert', | |
| 164 '/lib/convert/convert.dart', | |
| 165 ''' | |
| 166 library dart.convert; | |
| 167 | |
| 168 import 'dart:async'; | |
| 169 | |
| 170 abstract class Converter<S, T> implements StreamTransformer {} | |
| 171 class JsonDecoder extends Converter<String, Object> {} | |
| 172 '''); | |
| 173 | |
| 174 static const _MockSdkLibrary LIB_MATH = const _MockSdkLibrary( | |
| 175 'dart:math', | |
| 176 '/lib/math/math.dart', | |
| 177 ''' | |
| 178 library dart.math; | |
| 179 const double E = 2.718281828459045; | |
| 180 const double PI = 3.1415926535897932; | |
| 181 const double LN10 = 2.302585092994046; | |
| 182 num min(num a, num b) => 0; | |
| 183 num max(num a, num b) => 0; | |
| 184 external double cos(num x); | |
| 185 external double sin(num x); | |
| 186 external double sqrt(num x); | |
| 187 class Random { | |
| 188 bool nextBool() => true; | |
| 189 double nextDouble() => 2.0; | |
| 190 int nextInt() => 1; | |
| 191 } | |
| 192 '''); | |
| 193 | |
| 194 static const _MockSdkLibrary LIB_HTML = const _MockSdkLibrary( | |
| 195 'dart:html', | |
| 196 '/lib/html/dartium/html_dartium.dart', | |
| 197 ''' | |
| 198 library dart.html; | |
| 199 class HtmlElement {} | |
| 200 '''); | |
| 201 | |
| 202 static const List<SdkLibrary> LIBRARIES = const [ | |
| 203 LIB_CORE, | |
| 204 LIB_ASYNC, | |
| 205 LIB_COLLECTION, | |
| 206 LIB_CONVERT, | |
| 207 LIB_MATH, | |
| 208 LIB_HTML, | |
| 209 ]; | |
| 210 | |
| 211 final resource.MemoryResourceProvider provider = | |
| 212 new resource.MemoryResourceProvider(); | |
| 213 | |
| 214 /// The [AnalysisContextImpl] which is used for all of the sources. | |
| 215 AnalysisContextImpl _analysisContext; | |
| 216 | |
| 217 MockSdk() { | |
| 218 LIBRARIES.forEach((SdkLibrary library) { | |
| 219 if (library is _MockSdkLibrary) { | |
| 220 provider.newFile(library.path, library.content); | |
| 221 library.parts.forEach((file) { | |
| 222 provider.newFile(file.path, file.content); | |
| 223 }); | |
| 224 } | |
| 225 }); | |
| 226 } | |
| 227 | |
| 228 @override | |
| 229 AnalysisContextImpl get context { | |
| 230 if (_analysisContext == null) { | |
| 231 _analysisContext = new _SdkAnalysisContext(this); | |
| 232 SourceFactory factory = new SourceFactory([new DartUriResolver(this)]); | |
| 233 _analysisContext.sourceFactory = factory; | |
| 234 ChangeSet changeSet = new ChangeSet(); | |
| 235 for (String uri in uris) { | |
| 236 Source source = factory.forUri(uri); | |
| 237 changeSet.addedSource(source); | |
| 238 } | |
| 239 _analysisContext.applyChanges(changeSet); | |
| 240 } | |
| 241 return _analysisContext; | |
| 242 } | |
| 243 | |
| 244 @override | |
| 245 List<SdkLibrary> get sdkLibraries => LIBRARIES; | |
| 246 | |
| 247 @override | |
| 248 String get sdkVersion => throw unimplemented; | |
| 249 | |
| 250 UnimplementedError get unimplemented => new UnimplementedError(); | |
| 251 | |
| 252 @override | |
| 253 List<String> get uris { | |
| 254 List<String> uris = <String>[]; | |
| 255 for (SdkLibrary library in LIBRARIES) { | |
| 256 uris.add(library.shortName); | |
| 257 } | |
| 258 return uris; | |
| 259 } | |
| 260 | |
| 261 @override | |
| 262 Source fromFileUri(Uri uri) { | |
| 263 String filePath = uri.path; | |
| 264 String libPath = '/lib'; | |
| 265 if (!filePath.startsWith("$libPath/")) { | |
| 266 return null; | |
| 267 } | |
| 268 for (SdkLibrary library in LIBRARIES) { | |
| 269 String libraryPath = library.path; | |
| 270 if (filePath.replaceAll('\\', '/') == libraryPath) { | |
| 271 try { | |
| 272 resource.File file = provider.getResource(uri.path); | |
| 273 Uri dartUri = Uri.parse(library.shortName); | |
| 274 return file.createSource(dartUri); | |
| 275 } catch (exception) { | |
| 276 return null; | |
| 277 } | |
| 278 } | |
| 279 if (filePath.startsWith("$libraryPath/")) { | |
| 280 String pathInLibrary = filePath.substring(libraryPath.length + 1); | |
| 281 String path = '${library.shortName}/$pathInLibrary'; | |
| 282 try { | |
| 283 resource.File file = provider.getResource(uri.path); | |
| 284 Uri dartUri = new Uri(scheme: 'dart', path: path); | |
| 285 return file.createSource(dartUri); | |
| 286 } catch (exception) { | |
| 287 return null; | |
| 288 } | |
| 289 } | |
| 290 } | |
| 291 return null; | |
| 292 } | |
| 293 | |
| 294 @override | |
| 295 PackageBundle getLinkedBundle() => null; | |
| 296 | |
| 297 @override | |
| 298 SdkLibrary getSdkLibrary(String dartUri) { | |
| 299 // getSdkLibrary() is only used to determine whether a library is internal | |
| 300 // to the SDK. The mock SDK doesn't have any internals, so it's safe to | |
| 301 // return null. | |
| 302 return null; | |
| 303 } | |
| 304 | |
| 305 @override | |
| 306 Source mapDartUri(String dartUri) { | |
| 307 const Map<String, String> uriToPath = const { | |
| 308 "dart:core": "/lib/core/core.dart", | |
| 309 "dart:html": "/lib/html/dartium/html_dartium.dart", | |
| 310 "dart:async": "/lib/async/async.dart", | |
| 311 "dart:async/stream.dart": "/lib/async/stream.dart", | |
| 312 "dart:collection": "/lib/collection/collection.dart", | |
| 313 "dart:convert": "/lib/convert/convert.dart", | |
| 314 "dart:math": "/lib/math/math.dart" | |
| 315 }; | |
| 316 | |
| 317 String path = uriToPath[dartUri]; | |
| 318 if (path != null) { | |
| 319 resource.File file = provider.getResource(path); | |
| 320 Uri uri = new Uri(scheme: 'dart', path: dartUri.substring(5)); | |
| 321 return file.createSource(uri); | |
| 322 } | |
| 323 | |
| 324 // If we reach here then we tried to use a dartUri that's not in the | |
| 325 // table above. | |
| 326 return null; | |
| 327 } | |
| 328 } | |
| 329 | |
| 330 class _MockSdkFile { | |
| 331 final String path; | |
| 332 final String content; | |
| 333 | |
| 334 const _MockSdkFile(this.path, this.content); | |
| 335 } | |
| 336 | |
| 337 class _MockSdkLibrary implements SdkLibrary { | |
| 338 @override | |
| 339 final String shortName; | |
| 340 @override | |
| 341 final String path; | |
| 342 final String content; | |
| 343 final List<_MockSdkFile> parts; | |
| 344 | |
| 345 const _MockSdkLibrary(this.shortName, this.path, this.content, | |
| 346 [this.parts = const <_MockSdkFile>[]]); | |
| 347 | |
| 348 @override | |
| 349 String get category => throw unimplemented; | |
| 350 | |
| 351 @override | |
| 352 bool get isDart2JsLibrary => throw unimplemented; | |
| 353 | |
| 354 @override | |
| 355 bool get isDocumented => throw unimplemented; | |
| 356 | |
| 357 @override | |
| 358 bool get isImplementation => throw unimplemented; | |
| 359 | |
| 360 @override | |
| 361 bool get isInternal => throw unimplemented; | |
| 362 | |
| 363 @override | |
| 364 bool get isShared => throw unimplemented; | |
| 365 | |
| 366 @override | |
| 367 bool get isVmLibrary => throw unimplemented; | |
| 368 | |
| 369 UnimplementedError get unimplemented => new UnimplementedError(); | |
| 370 } | |
| 371 | |
| 372 /// An [AnalysisContextImpl] that only contains sources for a Dart SDK. | |
| 373 class _SdkAnalysisContext extends AnalysisContextImpl { | |
| 374 final DartSdk sdk; | |
| 375 | |
| 376 _SdkAnalysisContext(this.sdk); | |
| 377 | |
| 378 @override | |
| 379 AnalysisCache createCacheFromSourceFactory(SourceFactory factory) { | |
| 380 if (factory == null) { | |
| 381 return super.createCacheFromSourceFactory(factory); | |
| 382 } | |
| 383 return new AnalysisCache( | |
| 384 <CachePartition>[AnalysisEngine.instance.partitionManager.forSdk(sdk)]); | |
| 385 } | |
| 386 } | |
| OLD | NEW |