Version 2.12.0-161.0.dev
Merge commit 'b606a183cbc7ec3b28c75df69a1e052347f01d8f' into 'dev'
diff --git a/pkg/analyzer/lib/src/workspace/bazel.dart b/pkg/analyzer/lib/src/workspace/bazel.dart
index d32be7a..cb5b7cc 100644
--- a/pkg/analyzer/lib/src/workspace/bazel.dart
+++ b/pkg/analyzer/lib/src/workspace/bazel.dart
@@ -359,6 +359,10 @@
/// The absolute path to the `bazel-genfiles` folder.
final String genfiles;
+ /// The cache of packages. The key is the directory path, the value is
+ /// the corresponding package.
+ final Map<String, BazelWorkspacePackage> _directoryToPackage = {};
+
final _bazelCandidateFiles =
StreamController<BazelFileNotification>.broadcast();
@@ -441,7 +445,14 @@
@override
WorkspacePackage findPackageFor(String filePath) {
path.Context context = provider.pathContext;
- Folder folder = provider.getFolder(context.dirname(filePath));
+ var directoryPath = context.dirname(filePath);
+
+ var cachedPackage = _directoryToPackage[directoryPath];
+ if (cachedPackage != null) {
+ return cachedPackage;
+ }
+
+ Folder folder = provider.getFolder(directoryPath);
if (!context.isWithin(root, folder.path)) {
return null;
}
@@ -471,11 +482,13 @@
BazelWorkspacePackage packageRootedHere() {
List<String> uriParts = (packageUriResolver as BazelPackageUriResolver)
._restoreUriParts(root, '${folder.path}/lib/__fake__.dart');
- if (uriParts == null || uriParts.isEmpty) {
- return BazelWorkspacePackage(null, folder.path, this);
- } else {
- return BazelWorkspacePackage(uriParts[0], folder.path, this);
+ String packageName;
+ if (uriParts != null && uriParts.isNotEmpty) {
+ packageName = uriParts[0];
}
+ var package = BazelWorkspacePackage(packageName, folder.path, this);
+ _directoryToPackage[directoryPath] = package;
+ return package;
}
// In some distributed build environments, BUILD files are not preserved.
diff --git a/pkg/compiler/lib/src/elements/entities.dart b/pkg/compiler/lib/src/elements/entities.dart
index ccd058d..f136327 100644
--- a/pkg/compiler/lib/src/elements/entities.dart
+++ b/pkg/compiler/lib/src/elements/entities.dart
@@ -282,21 +282,62 @@
/// The number of type parameters.
final int typeParameters;
- const ParameterStructure(
+ static const ParameterStructure getter =
+ ParameterStructure._(0, 0, [], {}, 0);
+
+ static const ParameterStructure setter =
+ ParameterStructure._(1, 1, [], {}, 0);
+
+ static const ParameterStructure zeroArguments =
+ ParameterStructure._(0, 0, [], {}, 0);
+
+ static const List<ParameterStructure> _simple = [
+ ParameterStructure._(0, 0, [], {}, 0),
+ ParameterStructure._(1, 1, [], {}, 0),
+ ParameterStructure._(2, 2, [], {}, 0),
+ ParameterStructure._(3, 3, [], {}, 0),
+ ParameterStructure._(4, 4, [], {}, 0),
+ ParameterStructure._(5, 5, [], {}, 0),
+ ];
+
+ const ParameterStructure._(
this.requiredPositionalParameters,
this.positionalParameters,
this.namedParameters,
this.requiredNamedParameters,
this.typeParameters);
- const ParameterStructure.getter()
- : this(0, 0, const <String>[], const <String>{}, 0);
+ factory ParameterStructure(
+ int requiredPositionalParameters,
+ int positionalParameters,
+ List<String> namedParameters,
+ Set<String> requiredNamedParameters,
+ int typeParameters) {
+ // This simple canonicalization reduces the number of ParameterStructure
+ // objects by over 90%.
+ if (requiredPositionalParameters == positionalParameters &&
+ namedParameters.isEmpty &&
+ requiredNamedParameters.isEmpty &&
+ typeParameters == 0 &&
+ positionalParameters < _simple.length) {
+ return _simple[positionalParameters];
+ }
- const ParameterStructure.setter()
- : this(1, 1, const <String>[], const <String>{}, 0);
+ // Force sharing of empty collections.
+ if (namedParameters.isEmpty) namedParameters = const [];
+ if (requiredNamedParameters.isEmpty) requiredNamedParameters = const {};
+
+ return ParameterStructure._(
+ requiredPositionalParameters,
+ positionalParameters,
+ namedParameters,
+ requiredNamedParameters,
+ typeParameters,
+ );
+ }
factory ParameterStructure.fromType(FunctionType type) {
- return new ParameterStructure(
+ return ParameterStructure(
type.parameterTypes.length,
type.parameterTypes.length + type.optionalParameterTypes.length,
type.namedParameters,
@@ -314,7 +355,7 @@
source.readStrings(emptyAsNull: true)?.toSet() ?? const <String>{};
int typeParameters = source.readInt();
source.end(tag);
- return new ParameterStructure(
+ return ParameterStructure(
requiredPositionalParameters,
positionalParameters,
namedParameters,
@@ -344,7 +385,7 @@
/// Returns the [CallStructure] corresponding to a call site passing all
/// parameters both required and optional.
CallStructure get callStructure {
- return new CallStructure(totalParameters, namedParameters, typeParameters);
+ return CallStructure(totalParameters, namedParameters, typeParameters);
}
@override
@@ -382,7 +423,7 @@
/// Short textual representation use for testing.
String get shortText {
- StringBuffer sb = new StringBuffer();
+ StringBuffer sb = StringBuffer();
if (typeParameters != 0) {
sb.write('<');
sb.write(typeParameters);
@@ -401,7 +442,7 @@
@override
String toString() {
- StringBuffer sb = new StringBuffer();
+ StringBuffer sb = StringBuffer();
sb.write('ParameterStructure(');
sb.write('requiredPositionalParameters=$requiredPositionalParameters,');
sb.write('positionalParameters=$positionalParameters,');
diff --git a/pkg/compiler/lib/src/js_model/elements.dart b/pkg/compiler/lib/src/js_model/elements.dart
index 05a965f..38337b4 100644
--- a/pkg/compiler/lib/src/js_model/elements.dart
+++ b/pkg/compiler/lib/src/js_model/elements.dart
@@ -506,7 +506,7 @@
JGetter(JLibrary library, JClass enclosingClass, Name name,
AsyncMarker asyncMarker,
{bool isStatic, bool isExternal, this.isAbstract})
- : super(library, enclosingClass, name, const ParameterStructure.getter(),
+ : super(library, enclosingClass, name, ParameterStructure.getter,
asyncMarker,
isStatic: isStatic, isExternal: isExternal);
@@ -571,7 +571,7 @@
JSetter(JLibrary library, JClass enclosingClass, Name name,
{bool isStatic, bool isExternal, this.isAbstract})
- : super(library, enclosingClass, name, const ParameterStructure.setter(),
+ : super(library, enclosingClass, name, ParameterStructure.setter,
AsyncMarker.SYNC,
isStatic: isStatic, isExternal: isExternal);
@@ -733,15 +733,9 @@
static const String tag = 'signature-method';
JSignatureMethod(ClassEntity enclosingClass)
- : super(
- enclosingClass.library,
- enclosingClass,
- Names.signature,
- const ParameterStructure(0, 0, const [], const {}, 0),
- AsyncMarker.SYNC,
- isStatic: false,
- isExternal: false,
- isAbstract: false);
+ : super(enclosingClass.library, enclosingClass, Names.signature,
+ ParameterStructure.zeroArguments, AsyncMarker.SYNC,
+ isStatic: false, isExternal: false, isAbstract: false);
factory JSignatureMethod.readFromDataSource(DataSource source) {
source.begin(tag);
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index e1afb79..8246f0b 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -853,7 +853,7 @@
requiredNamedParameters.add(variable.name);
}
}
- return new ParameterStructure(
+ return ParameterStructure(
requiredPositionalParameters,
positionalParameters,
namedParameters,
diff --git a/pkg/compiler/lib/src/kernel/kelements.dart b/pkg/compiler/lib/src/kernel/kelements.dart
index 8356cb5..886ccbf 100644
--- a/pkg/compiler/lib/src/kernel/kelements.dart
+++ b/pkg/compiler/lib/src/kernel/kelements.dart
@@ -202,7 +202,7 @@
KGetter(KLibrary library, KClass enclosingClass, Name name,
AsyncMarker asyncMarker,
{bool isStatic, bool isExternal, this.isAbstract})
- : super(library, enclosingClass, name, const ParameterStructure.getter(),
+ : super(library, enclosingClass, name, ParameterStructure.getter,
asyncMarker,
isStatic: isStatic, isExternal: isExternal);
@@ -219,7 +219,7 @@
KSetter(KLibrary library, KClass enclosingClass, Name name,
{bool isStatic, bool isExternal, this.isAbstract})
- : super(library, enclosingClass, name, const ParameterStructure.setter(),
+ : super(library, enclosingClass, name, ParameterStructure.setter,
AsyncMarker.SYNC,
isStatic: isStatic, isExternal: isExternal);
diff --git a/pkg/compiler/test/serialization/serialization_test_helper.dart b/pkg/compiler/test/serialization/serialization_test_helper.dart
index a3d44ea..b429960 100644
--- a/pkg/compiler/test/serialization/serialization_test_helper.dart
+++ b/pkg/compiler/test/serialization/serialization_test_helper.dart
@@ -6,6 +6,7 @@
import 'package:compiler/compiler_new.dart';
import 'package:compiler/src/compiler.dart';
+import 'package:compiler/src/js_model/js_world.dart';
import 'package:compiler/src/inferrer/types.dart';
import 'package:compiler/src/serialization/strategies.dart';
import 'package:expect/expect.dart';
@@ -20,55 +21,33 @@
'"toJsonDuration":'
];
-runTest(
- {Uri entryPoint,
- Map<String, String> memorySourceFiles: const <String, String>{},
- Uri packageConfig,
- Uri librariesSpecificationUri,
- List<String> options,
- SerializationStrategy strategy: const BytesInMemorySerializationStrategy(),
- bool useDataKinds: false}) async {
- OutputCollector collector1 = new OutputCollector();
- CompilationResult result1 = await runCompiler(
- entryPoint: entryPoint,
- memorySourceFiles: memorySourceFiles,
- packageConfig: packageConfig,
- librariesSpecificationUri: librariesSpecificationUri,
- options: options,
- outputProvider: collector1,
- beforeRun: (Compiler compiler) {
- compiler.kernelLoader.forceSerialization = true;
- });
- Expect.isTrue(result1.isSuccess);
+void finishCompileAndCompare(
+ Map<OutputType, Map<String, String>> expectedOutput,
+ OutputCollector actualOutputCollector,
+ Compiler compiler,
+ SerializationStrategy strategy,
+ {bool stoppedAfterClosedWorld = false,
+ bool stoppedAfterTypeInference = false}) {
+ if (stoppedAfterClosedWorld) {
+ JsClosedWorld closedWorld = compiler.backendClosedWorldForTesting;
+ JsClosedWorld newClosedWorld =
+ cloneClosedWorld(compiler, closedWorld, strategy);
+ compiler.performGlobalTypeInference(newClosedWorld);
+ }
- OutputCollector collector2 = new OutputCollector();
- CompilationResult result = await runCompiler(
- entryPoint: entryPoint,
- memorySourceFiles: memorySourceFiles,
- packageConfig: packageConfig,
- librariesSpecificationUri: librariesSpecificationUri,
- options: options,
- outputProvider: collector2,
- beforeRun: (Compiler compiler) {
- compiler.kernelLoader.forceSerialization = true;
- compiler.stopAfterTypeInference = true;
- });
- Expect.isTrue(result.isSuccess);
- Compiler compiler = result.compiler;
- GlobalTypeInferenceResults globalInferenceResults =
- compiler.globalInference.resultsForTesting;
- GlobalTypeInferenceResults newGlobalInferenceResults =
- cloneInferenceResults(compiler, globalInferenceResults, strategy);
+ if (stoppedAfterClosedWorld || stoppedAfterTypeInference) {
+ GlobalTypeInferenceResults globalInferenceResults =
+ compiler.globalInference.resultsForTesting;
+ GlobalTypeInferenceResults newGlobalInferenceResults =
+ cloneInferenceResults(compiler, globalInferenceResults, strategy);
+ compiler.generateJavaScriptCode(newGlobalInferenceResults);
+ }
+ var actualOutput = actualOutputCollector.clear();
+ Expect.setEquals(
+ expectedOutput.keys, actualOutput.keys, "Output type mismatch.");
- Map<OutputType, Map<String, String>> output = collector1.clear();
-
- compiler.generateJavaScriptCode(newGlobalInferenceResults);
- Map<OutputType, Map<String, String>> newOutput = collector2.clear();
-
- Expect.setEquals(output.keys, newOutput.keys, "Output type mismatch.");
-
- output.forEach((OutputType outputType, Map<String, String> fileMap) {
- Map<String, String> newFileMap = newOutput[outputType];
+ void check(OutputType outputType, Map<String, String> fileMap) {
+ Map<String, String> newFileMap = actualOutput[outputType];
Expect.setEquals(fileMap.keys, newFileMap.keys,
"File mismatch for output type $outputType.");
fileMap.forEach((String fileName, String code) {
@@ -96,14 +75,117 @@
"Output mismatch at line $failureLine in "
"file '${fileName}' of type ${outputType}.");
});
- });
+ }
+
+ expectedOutput.forEach(check);
+}
+
+runTest(
+ {Uri entryPoint,
+ Map<String, String> memorySourceFiles: const <String, String>{},
+ Uri packageConfig,
+ Uri librariesSpecificationUri,
+ List<String> options,
+ SerializationStrategy strategy: const BytesInMemorySerializationStrategy(),
+ bool useDataKinds: false}) async {
+ OutputCollector collector = new OutputCollector();
+ CompilationResult result = await runCompiler(
+ entryPoint: entryPoint,
+ memorySourceFiles: memorySourceFiles,
+ packageConfig: packageConfig,
+ librariesSpecificationUri: librariesSpecificationUri,
+ options: options,
+ outputProvider: collector,
+ beforeRun: (Compiler compiler) {
+ compiler.kernelLoader.forceSerialization = true;
+ });
+ Expect.isTrue(result.isSuccess);
+ Map<OutputType, Map<String, String>> expectedOutput = collector.clear();
+
+ OutputCollector collector2 = new OutputCollector();
+ CompilationResult result2 = await runCompiler(
+ entryPoint: entryPoint,
+ memorySourceFiles: memorySourceFiles,
+ packageConfig: packageConfig,
+ librariesSpecificationUri: librariesSpecificationUri,
+ options: options,
+ outputProvider: collector2,
+ beforeRun: (Compiler compiler) {
+ compiler.kernelLoader.forceSerialization = true;
+ compiler.stopAfterClosedWorld = true;
+ });
+ Expect.isTrue(result2.isSuccess);
+
+ OutputCollector collector3 = new OutputCollector();
+ CompilationResult result3 = await runCompiler(
+ entryPoint: entryPoint,
+ memorySourceFiles: memorySourceFiles,
+ packageConfig: packageConfig,
+ librariesSpecificationUri: librariesSpecificationUri,
+ options: options,
+ outputProvider: collector3,
+ beforeRun: (Compiler compiler) {
+ compiler.kernelLoader.forceSerialization = true;
+ compiler.stopAfterTypeInference = true;
+ });
+ Expect.isTrue(result3.isSuccess);
+
+ finishCompileAndCompare(
+ expectedOutput, collector2, result2.compiler, strategy,
+ stoppedAfterClosedWorld: true);
+ finishCompileAndCompare(
+ expectedOutput, collector3, result3.compiler, strategy,
+ stoppedAfterTypeInference: true);
+}
+
+void checkData(List<int> data, List<int> newData) {
+ Expect.equals(
+ data.length, newData.length, "Reserialization data length mismatch.");
+ for (int i = 0; i < data.length; i++) {
+ if (data[i] != newData[i]) {
+ print('Reserialization data mismatch at offset $i:');
+ for (int j = i - 50; j < i + 50; j++) {
+ if (0 <= j && j <= data.length) {
+ String text;
+ if (data[j] == newData[j]) {
+ text = '${data[j]}';
+ } else {
+ text = '${data[j]} <> ${newData[j]}';
+ }
+ print('${j == i ? '> ' : ' '}$j: $text');
+ }
+ }
+ break;
+ }
+ }
+ Expect.listEquals(data, newData);
+}
+
+JsClosedWorld cloneClosedWorld(Compiler compiler, JsClosedWorld closedWorld,
+ SerializationStrategy strategy) {
+ ir.Component component = closedWorld.elementMap.programEnv.mainComponent;
+ List<int> irData = strategy.serializeComponent(component);
+ List<int> closedWorldData = strategy.serializeClosedWorld(closedWorld);
+ print('data size: ${closedWorldData.length}');
+
+ ir.Component newComponent = strategy.deserializeComponent(irData);
+ JsClosedWorld newClosedWorld = strategy.deserializeClosedWorld(
+ compiler.options,
+ compiler.reporter,
+ compiler.environment,
+ compiler.abstractValueStrategy,
+ newComponent,
+ closedWorldData);
+ List<int> newClosedWorldData = strategy.serializeClosedWorld(newClosedWorld);
+ checkData(closedWorldData, newClosedWorldData);
+ return newClosedWorld;
}
GlobalTypeInferenceResults cloneInferenceResults(Compiler compiler,
GlobalTypeInferenceResults results, SerializationStrategy strategy) {
List<int> irData = strategy.unpackAndSerializeComponent(results);
- List worldData = strategy.serializeGlobalTypeInferenceResults(results);
+ List<int> worldData = strategy.serializeGlobalTypeInferenceResults(results);
print('data size: ${worldData.length}');
ir.Component newComponent = strategy.deserializeComponent(irData);
@@ -115,27 +197,8 @@
compiler.abstractValueStrategy,
newComponent,
worldData);
- List newWorldData = strategy.serializeGlobalTypeInferenceResults(newResults);
- Expect.equals(worldData.length, newWorldData.length,
- "Reserialization data length mismatch.");
- for (int i = 0; i < worldData.length; i++) {
- if (worldData[i] != newWorldData[i]) {
- print('Reserialization data mismatch at offset $i:');
- for (int j = i - 50; j < i + 50; j++) {
- if (0 <= j && j <= worldData.length) {
- String text;
- if (worldData[j] == newWorldData[j]) {
- text = '${worldData[j]}';
- } else {
- text = '${worldData[j]} <> ${newWorldData[j]}';
- }
- print('${j == i ? '> ' : ' '}$j: $text');
- }
- }
- break;
- }
- }
- Expect.listEquals(worldData, newWorldData);
-
+ List<int> newWorldData =
+ strategy.serializeGlobalTypeInferenceResults(newResults);
+ checkData(worldData, newWorldData);
return newResults;
}
diff --git a/tools/VERSION b/tools/VERSION
index 6bda5c1..dab9525 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 12
PATCH 0
-PRERELEASE 160
+PRERELEASE 161
PRERELEASE_PATCH 0
\ No newline at end of file