mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 15:21:54 +00:00
Simplify how patch files are specified to analyzer.
After discussion with kmillikin@, sigmund@, and scheglov@, we decided that specifying the patch files in libraries.dart is more complex (and less flexible) than we'd like. This CL changes things so that the patch files are specified in analysis options using a simple map from library name (e.g. "dart:core") to a list of patch file paths. Clients are now allowed to put patch files wherever they want; they don't need to be inside the sdk directory. Note that we no longer include the patch configuration in encodeCrossContextOptions. This should be ok, since we don't have any use case in which a single instance of analyzer needs to accommodate multiple patch configurations. R=scheglov@google.com Review-Url: https://codereview.chromium.org/2560323002 .
This commit is contained in:
parent
d217b21ca6
commit
02fe40c6f7
|
@ -439,7 +439,4 @@ class MockSdkLibrary implements SdkLibrary {
|
|||
bool get isVmLibrary => throw unimplemented;
|
||||
|
||||
UnimplementedError get unimplemented => new UnimplementedError();
|
||||
|
||||
@override
|
||||
List<String> getPatches(int platform) => const <String>[];
|
||||
}
|
||||
|
|
|
@ -301,7 +301,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
|||
this._options.enableStrictCallChecks !=
|
||||
options.enableStrictCallChecks ||
|
||||
this._options.enableSuperMixins != options.enableSuperMixins ||
|
||||
this._options.patchPlatform != options.patchPlatform;
|
||||
!_samePatchPaths(this._options.patchPaths, options.patchPaths);
|
||||
this._options.analyzeFunctionBodiesPredicate =
|
||||
options.analyzeFunctionBodiesPredicate;
|
||||
this._options.generateImplicitErrors = options.generateImplicitErrors;
|
||||
|
@ -329,7 +329,7 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
|||
this._options.trackCacheDependencies = options.trackCacheDependencies;
|
||||
this._options.disableCacheFlushing = options.disableCacheFlushing;
|
||||
this._options.finerGrainedInvalidation = options.finerGrainedInvalidation;
|
||||
this._options.patchPlatform = options.patchPlatform;
|
||||
this._options.patchPaths = options.patchPaths;
|
||||
if (options is AnalysisOptionsImpl) {
|
||||
this._options.strongModeHints = options.strongModeHints;
|
||||
this._options.implicitCasts = options.implicitCasts;
|
||||
|
@ -1967,6 +1967,21 @@ class AnalysisContextImpl implements InternalAnalysisContext {
|
|||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
static bool _samePatchPaths(
|
||||
Map<String, List<String>> a, Map<String, List<String>> b) {
|
||||
if (a.length != b.length) return false;
|
||||
for (var key in a.keys) {
|
||||
if (!b.containsKey(key)) return false;
|
||||
var aValue = a[key];
|
||||
var bValue = b[key];
|
||||
if (aValue.length != bValue.length) return false;
|
||||
for (var i = 0; i < aValue.length; i++) {
|
||||
if (aValue[i] != bValue[i]) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -10,12 +10,9 @@ import 'package:analyzer/error/listener.dart';
|
|||
import 'package:analyzer/file_system/file_system.dart';
|
||||
import 'package:analyzer/src/dart/scanner/reader.dart';
|
||||
import 'package:analyzer/src/dart/scanner/scanner.dart';
|
||||
import 'package:analyzer/src/dart/sdk/sdk.dart';
|
||||
import 'package:analyzer/src/generated/parser.dart';
|
||||
import 'package:analyzer/src/generated/sdk.dart';
|
||||
import 'package:analyzer/src/generated/source.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:path/src/context.dart';
|
||||
|
||||
/**
|
||||
* [SdkPatcher] applies patches to SDK [CompilationUnit].
|
||||
|
@ -28,12 +25,13 @@ class SdkPatcher {
|
|||
|
||||
/**
|
||||
* Patch the given [unit] of a SDK [source] with the patches defined in
|
||||
* the [sdk] for the given [platform]. Throw [ArgumentError] if a patch
|
||||
* [allPatchPaths]. Throw [ArgumentError] if a patch
|
||||
* file cannot be read, or the contents violates rules for patch files.
|
||||
*/
|
||||
void patch(
|
||||
FolderBasedDartSdk sdk,
|
||||
int platform,
|
||||
ResourceProvider resourceProvider,
|
||||
bool strongMode,
|
||||
Map<String, List<String>> allPatchPaths,
|
||||
AnalysisErrorListener errorListener,
|
||||
Source source,
|
||||
CompilationUnit unit) {
|
||||
|
@ -53,21 +51,10 @@ class SdkPatcher {
|
|||
_allowNewPublicNames = libraryName == '_internal';
|
||||
}
|
||||
// Prepare the patch files to apply.
|
||||
List<String> patchPaths;
|
||||
{
|
||||
SdkLibrary sdkLibrary = sdk.getSdkLibrary(libraryUriStr);
|
||||
if (sdkLibrary == null) {
|
||||
throw new ArgumentError(
|
||||
'The library $libraryUriStr is not defined in the SDK.');
|
||||
}
|
||||
patchPaths = sdkLibrary.getPatches(platform);
|
||||
}
|
||||
List<String> patchPaths = allPatchPaths[libraryUriStr];
|
||||
|
||||
bool strongMode = sdk.context.analysisOptions.strongMode;
|
||||
Context pathContext = sdk.resourceProvider.pathContext;
|
||||
for (String path in patchPaths) {
|
||||
String pathInLib = pathContext.joinAll(path.split('/'));
|
||||
File patchFile = sdk.libraryDirectory.getChildAssumingFile(pathInLib);
|
||||
File patchFile = resourceProvider.getFile(path);
|
||||
if (!patchFile.exists) {
|
||||
throw new ArgumentError(
|
||||
'The patch file ${patchFile.path} for $source does not exist.');
|
||||
|
|
|
@ -1131,7 +1131,7 @@ abstract class AnalysisOptions {
|
|||
/**
|
||||
* The length of the list returned by [encodeCrossContextOptions].
|
||||
*/
|
||||
static const int crossContextOptionsLength = 2;
|
||||
static const int crossContextOptionsLength = 1;
|
||||
|
||||
/**
|
||||
* Function that returns `true` if analysis is to parse and analyze function
|
||||
|
@ -1296,10 +1296,10 @@ abstract class AnalysisOptions {
|
|||
List<Linter> get lintRules;
|
||||
|
||||
/**
|
||||
* Return the "platform" bit mask which should be used to apply patch files,
|
||||
* or `0` if no patch files should be applied.
|
||||
* A mapping from Dart SDK library name (e.g. "dart:core") to a list of paths
|
||||
* to patch files that should be applied to the library.
|
||||
*/
|
||||
int get patchPlatform;
|
||||
Map<String, List<String>> get patchPaths;
|
||||
|
||||
/**
|
||||
* Return `true` if analysis is to parse comments.
|
||||
|
@ -1453,8 +1453,7 @@ class AnalysisOptionsImpl implements AnalysisOptions {
|
|||
*/
|
||||
List<Linter> _lintRules;
|
||||
|
||||
@override
|
||||
int patchPlatform = 0;
|
||||
Map<String, List<String>> patchPaths = {};
|
||||
|
||||
@override
|
||||
bool preserveComments = true;
|
||||
|
@ -1544,7 +1543,7 @@ class AnalysisOptionsImpl implements AnalysisOptions {
|
|||
trackCacheDependencies = options.trackCacheDependencies;
|
||||
disableCacheFlushing = options.disableCacheFlushing;
|
||||
finerGrainedInvalidation = options.finerGrainedInvalidation;
|
||||
patchPlatform = options.patchPlatform;
|
||||
patchPaths = options.patchPaths;
|
||||
}
|
||||
|
||||
bool get analyzeFunctionBodies {
|
||||
|
@ -1655,7 +1654,7 @@ class AnalysisOptionsImpl implements AnalysisOptions {
|
|||
(enableSuperMixins ? ENABLE_SUPER_MIXINS_FLAG : 0) |
|
||||
(strongMode ? ENABLE_STRONG_MODE_FLAG : 0) |
|
||||
(strongModeHints ? ENABLE_STRONG_MODE_HINTS_FLAG : 0);
|
||||
return <int>[flags, patchPlatform];
|
||||
return <int>[flags];
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -1682,7 +1681,7 @@ class AnalysisOptionsImpl implements AnalysisOptions {
|
|||
lint = false;
|
||||
_lintRules = null;
|
||||
nonnullableTypes = NONNULLABLE_TYPES;
|
||||
patchPlatform = 0;
|
||||
patchPaths = {};
|
||||
preserveComments = true;
|
||||
strongMode = false;
|
||||
strongModeHints = false;
|
||||
|
@ -1698,7 +1697,6 @@ class AnalysisOptionsImpl implements AnalysisOptions {
|
|||
if (options is AnalysisOptionsImpl) {
|
||||
strongModeHints = options.strongModeHints;
|
||||
}
|
||||
patchPlatform = options.patchPlatform;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,7 +7,6 @@ library analyzer.src.generated.sdk;
|
|||
import 'dart:collection';
|
||||
|
||||
import 'package:analyzer/dart/ast/ast.dart';
|
||||
import 'package:analyzer/dart/ast/token.dart';
|
||||
import 'package:analyzer/dart/ast/visitor.dart';
|
||||
import 'package:analyzer/src/generated/engine.dart'
|
||||
show AnalysisContext, AnalysisOptions, AnalysisOptionsImpl;
|
||||
|
@ -290,11 +289,6 @@ class SdkLibrariesReader_LibraryBuilder extends RecursiveAstVisitor<Object> {
|
|||
*/
|
||||
static String _DART2JS_PATH = "dart2jsPath";
|
||||
|
||||
/**
|
||||
* The name of the `dart2js` platform.
|
||||
*/
|
||||
static String _DART2JS_PLATFORM = 'DART2JS_PLATFORM';
|
||||
|
||||
/**
|
||||
* The name of the optional parameter used to indicate whether the library is
|
||||
* documented.
|
||||
|
@ -307,12 +301,6 @@ class SdkLibrariesReader_LibraryBuilder extends RecursiveAstVisitor<Object> {
|
|||
*/
|
||||
static String _CATEGORIES = "categories";
|
||||
|
||||
/**
|
||||
* The name of the optional parameter used to specify the patches for
|
||||
* the library.
|
||||
*/
|
||||
static String _PATCHES = "patches";
|
||||
|
||||
/**
|
||||
* The name of the optional parameter used to specify the platforms on which
|
||||
* the library can be used.
|
||||
|
@ -391,30 +379,6 @@ class SdkLibrariesReader_LibraryBuilder extends RecursiveAstVisitor<Object> {
|
|||
library._implementation = (expression as BooleanLiteral).value;
|
||||
} else if (name == _DOCUMENTED) {
|
||||
library.documented = (expression as BooleanLiteral).value;
|
||||
} else if (name == _PATCHES) {
|
||||
if (expression is MapLiteral) {
|
||||
expression.entries.forEach((MapLiteralEntry entry) {
|
||||
int platforms = _convertPlatforms(entry.key);
|
||||
Expression pathsListLiteral = entry.value;
|
||||
if (pathsListLiteral is ListLiteral) {
|
||||
List<String> paths = <String>[];
|
||||
pathsListLiteral.elements.forEach((Expression pathExpr) {
|
||||
if (pathExpr is SimpleStringLiteral) {
|
||||
String path = pathExpr.value;
|
||||
_validatePatchPath(path);
|
||||
paths.add(path);
|
||||
} else {
|
||||
throw new ArgumentError(
|
||||
'The "patch" argument items must be simple strings.');
|
||||
}
|
||||
});
|
||||
library.setPatchPaths(platforms, paths);
|
||||
} else {
|
||||
throw new ArgumentError(
|
||||
'The "patch" argument values must be list literals.');
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if (name == _PLATFORMS) {
|
||||
if (expression is SimpleIdentifier) {
|
||||
String identifier = expression.name;
|
||||
|
@ -435,61 +399,6 @@ class SdkLibrariesReader_LibraryBuilder extends RecursiveAstVisitor<Object> {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the given [path] to a patch file. Throw [ArgumentError] if not a
|
||||
* valid path: is absolute, or contains `..`.
|
||||
*/
|
||||
void _validatePatchPath(String path) {
|
||||
if (path.contains(r'\')) {
|
||||
throw new ArgumentError('The path to a patch file must be posix: $path');
|
||||
}
|
||||
if (path.contains('..')) {
|
||||
throw new ArgumentError(
|
||||
'The path to a patch file cannot contain "..": $path');
|
||||
}
|
||||
if (path.startsWith('/')) {
|
||||
throw new ArgumentError(
|
||||
'The path to a patch file cannot be absolute: $path');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the platform constant value for the given [expr].
|
||||
* Throw [ArgumentError] if not a valid platform name given.
|
||||
*/
|
||||
static int _convertPlatform(Expression expr) {
|
||||
if (expr is SimpleIdentifier) {
|
||||
String name = expr.name;
|
||||
if (name == _DART2JS_PLATFORM) {
|
||||
return SdkLibraryImpl.DART2JS_PLATFORM;
|
||||
}
|
||||
if (name == _VM_PLATFORM) {
|
||||
return SdkLibraryImpl.VM_PLATFORM;
|
||||
}
|
||||
throw new ArgumentError('Invalid platform name: $name');
|
||||
}
|
||||
throw new ArgumentError('Invalid platform type: ${expr.runtimeType}');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the platforms combination value for the [expr], which should be
|
||||
* either `name1 | name2` or `name`. Throw [ArgumentError] if any of the
|
||||
* names is not a valid platform name.
|
||||
*/
|
||||
static int _convertPlatforms(Expression expr) {
|
||||
if (expr is BinaryExpression) {
|
||||
TokenType operator = expr.operator?.type;
|
||||
if (operator == TokenType.BAR) {
|
||||
return _convertPlatforms(expr.leftOperand) |
|
||||
_convertPlatforms(expr.rightOperand);
|
||||
} else {
|
||||
throw new ArgumentError('Invalid platforms combination: $operator');
|
||||
}
|
||||
} else {
|
||||
return _convertPlatform(expr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -542,12 +451,6 @@ abstract class SdkLibrary {
|
|||
* including `dart:`.
|
||||
*/
|
||||
String get shortName;
|
||||
|
||||
/**
|
||||
* Return the list of paths to the patch files that should be applied
|
||||
* to this library for the given [platform], not `null`.
|
||||
*/
|
||||
List<String> getPatches(int platform);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -599,14 +502,6 @@ class SdkLibraryImpl implements SdkLibrary {
|
|||
*/
|
||||
int _platforms = 0;
|
||||
|
||||
/**
|
||||
* The mapping from the platform combination to the list of paths (relative
|
||||
* to the `sdk/lib` folder) of patches that should be applied to this library
|
||||
* on every platform in the combination.
|
||||
*/
|
||||
final Map<int, List<String>> _platformsToPatchPaths =
|
||||
new HashMap<int, List<String>>();
|
||||
|
||||
/**
|
||||
* Initialize a newly created library to represent the library with the given
|
||||
* [name].
|
||||
|
@ -638,17 +533,6 @@ class SdkLibraryImpl implements SdkLibrary {
|
|||
@override
|
||||
bool get isVmLibrary => (_platforms & VM_PLATFORM) != 0;
|
||||
|
||||
@override
|
||||
List<String> getPatches(int platform) {
|
||||
List<String> paths = <String>[];
|
||||
_platformsToPatchPaths.forEach((int platforms, List<String> value) {
|
||||
if ((platforms & platform) != 0) {
|
||||
paths.addAll(value);
|
||||
}
|
||||
});
|
||||
return paths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Record that this library can be compiled to JavaScript by dart2js.
|
||||
*/
|
||||
|
@ -656,14 +540,6 @@ class SdkLibraryImpl implements SdkLibrary {
|
|||
_platforms |= DART2JS_PLATFORM;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new patch with the given [path] that should be applied for the
|
||||
* given [platforms].
|
||||
*/
|
||||
void setPatchPaths(int platforms, List<String> paths) {
|
||||
_platformsToPatchPaths[platforms] = paths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Record that this library can be run on the VM.
|
||||
*/
|
||||
|
|
|
@ -25,6 +25,7 @@ import 'package:analyzer/src/dart/resolver/inheritance_manager.dart';
|
|||
import 'package:analyzer/src/dart/scanner/reader.dart';
|
||||
import 'package:analyzer/src/dart/scanner/scanner.dart';
|
||||
import 'package:analyzer/src/dart/sdk/patch.dart';
|
||||
import 'package:analyzer/src/dart/sdk/sdk.dart';
|
||||
import 'package:analyzer/src/error/codes.dart';
|
||||
import 'package:analyzer/src/error/pending_error.dart';
|
||||
import 'package:analyzer/src/generated/constant.dart';
|
||||
|
@ -4061,9 +4062,17 @@ class ParseDartTask extends SourceBasedAnalysisTask {
|
|||
CompilationUnit unit = parser.parseCompilationUnit(tokenStream);
|
||||
unit.lineInfo = lineInfo;
|
||||
|
||||
if (options.patchPlatform != 0 && _source.uri.scheme == 'dart') {
|
||||
new SdkPatcher().patch(context.sourceFactory.dartSdk,
|
||||
options.patchPlatform, errorListener, _source, unit);
|
||||
if (options.patchPaths.isNotEmpty && _source.uri.scheme == 'dart') {
|
||||
var resourceProvider =
|
||||
(context.sourceFactory.dartSdk as FolderBasedDartSdk)
|
||||
.resourceProvider;
|
||||
new SdkPatcher().patch(
|
||||
resourceProvider,
|
||||
context.analysisOptions.strongMode,
|
||||
context.analysisOptions.patchPaths,
|
||||
errorListener,
|
||||
_source,
|
||||
unit);
|
||||
}
|
||||
|
||||
bool hasNonPartOfDirective = false;
|
||||
|
|
|
@ -58,7 +58,9 @@ class AnalysisOptionsImplTest {
|
|||
modifiedOptions.incrementalValidation = true;
|
||||
modifiedOptions.lint = true;
|
||||
modifiedOptions.lintRules = [null];
|
||||
modifiedOptions.patchPlatform = 3;
|
||||
modifiedOptions.patchPaths = {
|
||||
'dart:core': ['/dart_core.patch.dart']
|
||||
};
|
||||
modifiedOptions.preserveComments = false;
|
||||
modifiedOptions.strongMode = true;
|
||||
modifiedOptions.trackCacheDependencies = false;
|
||||
|
@ -91,7 +93,7 @@ class AnalysisOptionsImplTest {
|
|||
defaultOptions.incrementalValidation);
|
||||
expect(modifiedOptions.lint, defaultOptions.lint);
|
||||
expect(modifiedOptions.lintRules, defaultOptions.lintRules);
|
||||
expect(modifiedOptions.patchPlatform, defaultOptions.patchPlatform);
|
||||
expect(modifiedOptions.patchPaths, defaultOptions.patchPaths);
|
||||
expect(modifiedOptions.preserveComments, defaultOptions.preserveComments);
|
||||
expect(modifiedOptions.strongMode, defaultOptions.strongMode);
|
||||
expect(modifiedOptions.trackCacheDependencies,
|
||||
|
|
|
@ -521,9 +521,6 @@ class _MockSdkLibrary implements SdkLibrary {
|
|||
|
||||
@override
|
||||
bool get isVmLibrary => throw new UnimplementedError();
|
||||
|
||||
@override
|
||||
List<String> getPatches(int platform) => const <String>[];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -9,7 +9,6 @@ import 'package:analyzer/file_system/memory_file_system.dart';
|
|||
import 'package:analyzer/src/dart/sdk/patch.dart';
|
||||
import 'package:analyzer/src/dart/sdk/sdk.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/util/fast_uri.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
@ -453,30 +452,21 @@ import 'c.dart';
|
|||
"import 'a.dart'; part 'b.dart'; import 'c.dart'; int bar() => 0;");
|
||||
}
|
||||
|
||||
test_fail_noSuchLibrary() {
|
||||
expect(() {
|
||||
_setSdkLibraries('const LIBRARIES = const {};');
|
||||
_createSdk();
|
||||
File file = provider.newFile(_p('/sdk/lib/test/test.dart'), '');
|
||||
Source source = file.createSource(FastUri.parse('dart:test'));
|
||||
CompilationUnit unit = SdkPatcher.parse(source, true, listener);
|
||||
patcher.patch(sdk, SdkLibraryImpl.VM_PLATFORM, listener, source, unit);
|
||||
}, throwsArgumentError);
|
||||
}
|
||||
|
||||
test_fail_patchFileDoesNotExist() {
|
||||
expect(() {
|
||||
_setSdkLibraries(r'''
|
||||
final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
|
||||
'test' : const LibraryInfo(
|
||||
'test/test.dart',
|
||||
patches: {VM_PLATFORM: ['does_not_exists.dart']}),
|
||||
'test/test.dart'),
|
||||
};''');
|
||||
_createSdk();
|
||||
var patchPaths = {
|
||||
'dart:test': [_p('/sdk/lib/does_not_exist.dart')]
|
||||
};
|
||||
File file = provider.newFile(_p('/sdk/lib/test/test.dart'), '');
|
||||
Source source = file.createSource(FastUri.parse('dart:test'));
|
||||
CompilationUnit unit = SdkPatcher.parse(source, true, listener);
|
||||
patcher.patch(sdk, SdkLibraryImpl.VM_PLATFORM, listener, source, unit);
|
||||
patcher.patch(provider, true, patchPaths, listener, source, unit);
|
||||
}, throwsArgumentError);
|
||||
}
|
||||
|
||||
|
@ -484,9 +474,11 @@ final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
|
|||
_setSdkLibraries(r'''
|
||||
final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
|
||||
'_internal' : const LibraryInfo(
|
||||
'internal/internal.dart',
|
||||
patches: {VM_PLATFORM: ['internal/internal_patch.dart']}),
|
||||
'internal/internal.dart'),
|
||||
};''');
|
||||
var patchPaths = {
|
||||
'dart:_internal': [_p('/sdk/lib/internal/internal_patch.dart')]
|
||||
};
|
||||
File file = provider.newFile(
|
||||
_p('/sdk/lib/internal/internal.dart'),
|
||||
r'''
|
||||
|
@ -513,7 +505,7 @@ int newFunction() => 2;
|
|||
|
||||
Source source = file.createSource(FastUri.parse('dart:_internal'));
|
||||
CompilationUnit unit = SdkPatcher.parse(source, true, listener);
|
||||
patcher.patch(sdk, SdkLibraryImpl.VM_PLATFORM, listener, source, unit);
|
||||
patcher.patch(provider, true, patchPaths, listener, source, unit);
|
||||
_assertUnitCode(
|
||||
unit,
|
||||
'library dart._internal; class A {} '
|
||||
|
@ -537,6 +529,9 @@ final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
|
|||
'test/test.dart',
|
||||
patches: {VM_PLATFORM: ['test/test_patch.dart']}),
|
||||
};''');
|
||||
var patchPaths = {
|
||||
'dart:test': [_p('/sdk/lib/test/test_patch.dart')]
|
||||
};
|
||||
File fileLib = provider.newFile(_p('/sdk/lib/test/test.dart'), baseLibCode);
|
||||
File filePart =
|
||||
provider.newFile(_p('/sdk/lib/test/test_part.dart'), basePartCode);
|
||||
|
@ -564,7 +559,7 @@ class _C {}
|
|||
Uri uri = FastUri.parse('dart:test');
|
||||
Source source = fileLib.createSource(uri);
|
||||
CompilationUnit unit = SdkPatcher.parse(source, true, listener);
|
||||
patcher.patch(sdk, SdkLibraryImpl.VM_PLATFORM, listener, source, unit);
|
||||
patcher.patch(provider, true, patchPaths, listener, source, unit);
|
||||
_assertUnitCode(
|
||||
unit,
|
||||
"library test; part 'test_part.dart'; import 'foo.dart'; "
|
||||
|
@ -575,7 +570,7 @@ class _C {}
|
|||
Uri uri = FastUri.parse('dart:test/test_part.dart');
|
||||
Source source = filePart.createSource(uri);
|
||||
CompilationUnit unit = SdkPatcher.parse(source, true, listener);
|
||||
patcher.patch(sdk, SdkLibraryImpl.VM_PLATFORM, listener, source, unit);
|
||||
patcher.patch(provider, true, patchPaths, listener, source, unit);
|
||||
_assertUnitCode(unit, "part of test; class B {int _b() => 1;}");
|
||||
}
|
||||
}
|
||||
|
@ -621,20 +616,6 @@ class B {}
|
|||
}, throwsArgumentError);
|
||||
}
|
||||
|
||||
test_topLevel_topLevelVariable_append() {
|
||||
CompilationUnit unit = _doTopLevelPatching(
|
||||
r'''
|
||||
int foo() => 0;
|
||||
''',
|
||||
r'''
|
||||
int _bar;
|
||||
''');
|
||||
_assertUnitCode(unit, 'int foo() => 0; int _bar;');
|
||||
FunctionDeclaration a = unit.declarations[0];
|
||||
TopLevelVariableDeclaration b = unit.declarations[1];
|
||||
_assertPrevNextToken(a.endToken, b.beginToken);
|
||||
}
|
||||
|
||||
test_topLevel_function_append() {
|
||||
CompilationUnit unit = _doTopLevelPatching(
|
||||
r'''
|
||||
|
@ -798,6 +779,20 @@ void set foo(int val) {}
|
|||
_assertUnitCode(unit, 'void set foo(int val) {} int bar() => 2;');
|
||||
}
|
||||
|
||||
test_topLevel_topLevelVariable_append() {
|
||||
CompilationUnit unit = _doTopLevelPatching(
|
||||
r'''
|
||||
int foo() => 0;
|
||||
''',
|
||||
r'''
|
||||
int _bar;
|
||||
''');
|
||||
_assertUnitCode(unit, 'int foo() => 0; int _bar;');
|
||||
FunctionDeclaration a = unit.declarations[0];
|
||||
TopLevelVariableDeclaration b = unit.declarations[1];
|
||||
_assertPrevNextToken(a.endToken, b.beginToken);
|
||||
}
|
||||
|
||||
void _assertUnitCode(CompilationUnit unit, String expectedCode) {
|
||||
expect(unit.toSource(), expectedCode);
|
||||
}
|
||||
|
@ -811,9 +806,11 @@ void set foo(int val) {}
|
|||
_setSdkLibraries(r'''
|
||||
final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
|
||||
'test' : const LibraryInfo(
|
||||
'test/test.dart',
|
||||
patches: {VM_PLATFORM: ['test/test_patch.dart']}),
|
||||
'test/test.dart'),
|
||||
};''');
|
||||
var patchPaths = {
|
||||
'dart:test': [_p('/sdk/lib/test/test_patch.dart')]
|
||||
};
|
||||
File file = provider.newFile(_p('/sdk/lib/test/test.dart'), baseCode);
|
||||
provider.newFile(_p('/sdk/lib/test/test_patch.dart'), patchCode);
|
||||
|
||||
|
@ -821,7 +818,7 @@ final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
|
|||
|
||||
Source source = file.createSource(FastUri.parse('dart:test'));
|
||||
CompilationUnit unit = SdkPatcher.parse(source, true, listener);
|
||||
patcher.patch(sdk, SdkLibraryImpl.VM_PLATFORM, listener, source, unit);
|
||||
patcher.patch(provider, true, patchPaths, listener, source, unit);
|
||||
return unit;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@ main() {
|
|||
defineReflectiveTests(FolderBasedDartSdkTest);
|
||||
defineReflectiveTests(SdkExtensionFinderTest);
|
||||
defineReflectiveTests(SdkLibrariesReaderTest);
|
||||
defineReflectiveTests(SdkLibraryImplTest);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -474,148 +473,4 @@ final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
|
|||
expect(second.isImplementation, true);
|
||||
expect(second.isVmLibrary, false);
|
||||
}
|
||||
|
||||
void test_readFrom_patches() {
|
||||
LibraryMap libraryMap = new SdkLibrariesReader(false).readFromFile(
|
||||
resourceProvider.getFile('/libs.dart'),
|
||||
r'''
|
||||
final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
|
||||
'foo' : const LibraryInfo(
|
||||
'foo/foo.dart',
|
||||
patches: {
|
||||
DART2JS_PLATFORM | VM_PLATFORM: ['a', 'b'],
|
||||
DART2JS_PLATFORM: ['c', 'd'],
|
||||
VM_PLATFORM: ['e']}),
|
||||
};''');
|
||||
expect(libraryMap, isNotNull);
|
||||
expect(libraryMap.size(), 1);
|
||||
SdkLibrary library = libraryMap.getLibrary('dart:foo');
|
||||
expect(library, isNotNull);
|
||||
expect(library.path, 'foo/foo.dart');
|
||||
expect(library.shortName, 'dart:foo');
|
||||
expect(library.getPatches(SdkLibraryImpl.DART2JS_PLATFORM),
|
||||
unorderedEquals(['a', 'b', 'c', 'd']));
|
||||
expect(library.getPatches(SdkLibraryImpl.VM_PLATFORM),
|
||||
unorderedEquals(['a', 'b', 'e']));
|
||||
}
|
||||
|
||||
void test_readFrom_patches_invalid_notList() {
|
||||
expect(() {
|
||||
new SdkLibrariesReader(false).readFromFile(
|
||||
resourceProvider.getFile('/libs.dart'),
|
||||
r'''
|
||||
final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
|
||||
'foo' : const LibraryInfo(
|
||||
'foo/foo.dart',
|
||||
patches: {
|
||||
VM_PLATFORM: 'X'}),
|
||||
};''');
|
||||
}, throwsArgumentError);
|
||||
}
|
||||
|
||||
void test_readFrom_patches_invalid_notString_inList() {
|
||||
expect(() {
|
||||
new SdkLibrariesReader(false).readFromFile(
|
||||
resourceProvider.getFile('/libs.dart'),
|
||||
r'''
|
||||
final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
|
||||
'foo' : const LibraryInfo(
|
||||
'foo/foo.dart',
|
||||
patches: {
|
||||
VM_PLATFORM: [42]}),
|
||||
};''');
|
||||
}, throwsArgumentError);
|
||||
}
|
||||
|
||||
void test_readFrom_patches_invalid_path_hasDotDot() {
|
||||
_assertPatchPathIsInvalid('foo/../bar.dart');
|
||||
_assertPatchPathIsInvalid('../foo/bar.dart');
|
||||
_assertPatchPathIsInvalid('foo/bar..dart');
|
||||
}
|
||||
|
||||
void test_readFrom_patches_invalid_path_isAbsolute() {
|
||||
_assertPatchPathIsInvalid('/foo.dart');
|
||||
_assertPatchPathIsInvalid('/foo/bar.dart');
|
||||
}
|
||||
|
||||
void test_readFrom_patches_invalid_path_notPosix() {
|
||||
_assertPatchPathIsInvalid(r'foo\bar.dart');
|
||||
}
|
||||
|
||||
void test_readFrom_patches_invalid_platformCombinator() {
|
||||
expect(() {
|
||||
new SdkLibrariesReader(false).readFromFile(
|
||||
resourceProvider.getFile('/libs.dart'),
|
||||
r'''
|
||||
final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
|
||||
'foo' : const LibraryInfo(
|
||||
'foo/foo.dart',
|
||||
patches: {
|
||||
DART2JS_PLATFORM + VM_PLATFORM: ['X']}),
|
||||
};''');
|
||||
}, throwsArgumentError);
|
||||
}
|
||||
|
||||
void test_readFrom_patches_invalid_unknownPlatform() {
|
||||
expect(() {
|
||||
new SdkLibrariesReader(false).readFromFile(
|
||||
resourceProvider.getFile('/libs.dart'),
|
||||
r'''
|
||||
final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
|
||||
'foo' : const LibraryInfo(
|
||||
'foo/foo.dart',
|
||||
patches: {
|
||||
MY_UNKNOWN_PLATFORM: ['foo/bar_patch.dart']}),
|
||||
};''');
|
||||
}, throwsArgumentError);
|
||||
}
|
||||
|
||||
void test_readFrom_patches_no() {
|
||||
LibraryMap libraryMap = new SdkLibrariesReader(false).readFromFile(
|
||||
resourceProvider.getFile('/libs.dart'),
|
||||
r'''
|
||||
final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
|
||||
'my' : const LibraryInfo('my/my.dart')
|
||||
};''');
|
||||
expect(libraryMap, isNotNull);
|
||||
expect(libraryMap.size(), 1);
|
||||
SdkLibrary library = libraryMap.getLibrary('dart:my');
|
||||
expect(library, isNotNull);
|
||||
expect(library.path, 'my/my.dart');
|
||||
expect(library.shortName, 'dart:my');
|
||||
expect(library.getPatches(SdkLibraryImpl.VM_PLATFORM), isEmpty);
|
||||
expect(library.getPatches(SdkLibraryImpl.DART2JS_PLATFORM), isEmpty);
|
||||
}
|
||||
|
||||
void _assertPatchPathIsInvalid(String patchPath) {
|
||||
expect(() {
|
||||
new SdkLibrariesReader(false).readFromFile(
|
||||
resourceProvider.getFile('/libs.dart'),
|
||||
'''
|
||||
final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
|
||||
'foo' : const LibraryInfo(
|
||||
'foo/foo.dart',
|
||||
patches: {
|
||||
VM_PLATFORM: [r'$patchPath']}),
|
||||
};''');
|
||||
}, throwsArgumentError);
|
||||
}
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class SdkLibraryImplTest extends EngineTestCase {
|
||||
void test_patches() {
|
||||
SdkLibraryImpl library = new SdkLibraryImpl('dart:foo');
|
||||
// Set patches.
|
||||
library.setPatchPaths(
|
||||
SdkLibraryImpl.DART2JS_PLATFORM | SdkLibraryImpl.VM_PLATFORM,
|
||||
['a', 'b']);
|
||||
library.setPatchPaths(SdkLibraryImpl.DART2JS_PLATFORM, ['c', 'd']);
|
||||
library.setPatchPaths(SdkLibraryImpl.VM_PLATFORM, ['e']);
|
||||
// Get patches.
|
||||
expect(library.getPatches(SdkLibraryImpl.DART2JS_PLATFORM),
|
||||
unorderedEquals(['a', 'b', 'c', 'd']));
|
||||
expect(library.getPatches(SdkLibraryImpl.VM_PLATFORM),
|
||||
unorderedEquals(['a', 'b', 'e']));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue