blob: 8b54d774fe6aebc0065232fc998e8593b894cadb [file] [log] [blame]
// 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.
// Partial test that the closed world computed from [WorldImpact]s derived from
// kernel is equivalent to the original computed from resolution.
library dart2js.kernel.closed_world2_test;
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/closure.dart';
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/common.dart';
import 'package:compiler/src/common_elements.dart';
import 'package:compiler/src/common/backend_api.dart';
import 'package:compiler/src/common/resolution.dart';
import 'package:compiler/src/common/work.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/deferred_load.dart';
import 'package:compiler/src/elements/resolution_types.dart';
import 'package:compiler/src/elements/elements.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/elements/types.dart';
import 'package:compiler/src/enqueue.dart';
import 'package:compiler/src/js_backend/backend.dart';
import 'package:compiler/src/js_backend/backend_impact.dart';
import 'package:compiler/src/js_backend/backend_usage.dart';
import 'package:compiler/src/js_backend/custom_elements_analysis.dart';
import 'package:compiler/src/js_backend/native_data.dart';
import 'package:compiler/src/js_backend/impact_transformer.dart';
import 'package:compiler/src/js_backend/interceptor_data.dart';
import 'package:compiler/src/js_backend/lookup_map_analysis.dart';
import 'package:compiler/src/js_backend/mirrors_analysis.dart';
import 'package:compiler/src/js_backend/mirrors_data.dart';
import 'package:compiler/src/js_backend/no_such_method_registry.dart';
import 'package:compiler/src/js_backend/resolution_listener.dart';
import 'package:compiler/src/js_backend/type_variable_handler.dart';
import 'package:compiler/src/native/enqueue.dart';
import 'package:compiler/src/kernel/world_builder.dart';
import 'package:compiler/src/options.dart';
import 'package:compiler/src/universe/world_builder.dart';
import 'package:compiler/src/universe/world_impact.dart';
import 'package:compiler/src/world.dart';
import '../memory_compiler.dart';
import '../serialization/helper.dart';
import 'closed_world_test.dart';
main(List<String> args) {
Arguments arguments = new Arguments.from(args);
Uri entryPoint;
Map<String, String> memorySourceFiles;
if (arguments.uri != null) {
entryPoint = arguments.uri;
memorySourceFiles = const <String, String>{};
} else {
entryPoint = Uri.parse('memory:main.dart');
memorySourceFiles = SOURCE;
}
asyncTest(() async {
enableDebugMode();
Compiler compiler = compilerFor(
entryPoint: entryPoint,
memorySourceFiles: memorySourceFiles,
options: [
Flags.analyzeAll,
Flags.useKernel,
Flags.enableAssertMessage
]);
ElementResolutionWorldBuilder.useInstantiationMap = true;
compiler.resolution.retainCachesForTesting = true;
await compiler.run(entryPoint);
compiler.resolutionWorldBuilder.closeWorld(compiler.reporter);
KernelWorldBuilder worldBuilder = new KernelWorldBuilder(
compiler.reporter, compiler.backend.kernelTask.program);
List list = createKernelResolutionEnqueuerListener(compiler.options,
compiler.reporter, compiler.deferredLoadTask, worldBuilder);
ResolutionEnqueuerListener resolutionEnqueuerListener = list[0];
ImpactTransformer impactTransformer = list[1];
ResolutionEnqueuer enqueuer = new ResolutionEnqueuer(
compiler.enqueuer,
compiler.options,
compiler.reporter,
const TreeShakingEnqueuerStrategy(),
resolutionEnqueuerListener,
new KernelResolutionWorldBuilder(
worldBuilder.elementEnvironment,
worldBuilder.commonElements,
new NativeBasicDataImpl(),
const OpenWorldStrategy()),
new KernelWorkItemBuilder(worldBuilder, impactTransformer),
'enqueuer from kelements');
computeClosedWorld(
compiler.reporter, enqueuer, worldBuilder.elementEnvironment);
});
}
List createKernelResolutionEnqueuerListener(
CompilerOptions options,
DiagnosticReporter reporter,
DeferredLoadTask deferredLoadTask,
KernelWorldBuilder worldBuilder) {
ElementEnvironment elementEnvironment = worldBuilder.elementEnvironment;
CommonElements commonElements = worldBuilder.commonElements;
BackendImpacts impacts = new BackendImpacts(options, commonElements);
// TODO(johnniwinther): Create Kernel based implementations for these:
NativeBasicData nativeBasicData = new NativeBasicDataImpl();
RuntimeTypesNeedBuilder rtiNeedBuilder = new RuntimeTypesNeedBuilderImpl();
MirrorsDataBuilder mirrorsDataBuilder = new MirrorsDataBuilderImpl();
CustomElementsResolutionAnalysis customElementsResolutionAnalysis =
new CustomElementsResolutionAnalysisImpl();
MirrorsResolutionAnalysis mirrorsResolutionAnalysis =
new MirrorsResolutionAnalysisImpl();
LookupMapResolutionAnalysis lookupMapResolutionAnalysis =
new LookupMapResolutionAnalysis(reporter, elementEnvironment);
InterceptorDataBuilder interceptorDataBuilder =
new InterceptorDataBuilderImpl(
nativeBasicData, elementEnvironment, commonElements);
BackendUsageBuilder backendUsageBuilder =
new BackendUsageBuilderImpl(commonElements);
NoSuchMethodRegistry noSuchMethodRegistry = new NoSuchMethodRegistry(
commonElements, new KernelNoSuchMethodResolver(worldBuilder));
NativeResolutionEnqueuer nativeResolutionEnqueuer =
new NativeResolutionEnqueuer(options, elementEnvironment, commonElements,
backendUsageBuilder, new KernelNativeClassResolver(worldBuilder));
ResolutionEnqueuerListener listener = new ResolutionEnqueuerListener(
options,
elementEnvironment,
commonElements,
impacts,
nativeBasicData,
interceptorDataBuilder,
backendUsageBuilder,
rtiNeedBuilder,
mirrorsDataBuilder,
noSuchMethodRegistry,
customElementsResolutionAnalysis,
lookupMapResolutionAnalysis,
mirrorsResolutionAnalysis,
new TypeVariableResolutionAnalysis(
elementEnvironment, impacts, backendUsageBuilder),
nativeResolutionEnqueuer,
deferredLoadTask);
ImpactTransformer transformer = new JavaScriptImpactTransformer(
options,
elementEnvironment,
commonElements,
impacts,
nativeBasicData,
nativeResolutionEnqueuer,
backendUsageBuilder,
mirrorsDataBuilder,
customElementsResolutionAnalysis,
rtiNeedBuilder);
return [listener, transformer];
}
class NativeBasicDataImpl implements NativeBasicData {
@override
bool isNativeClass(ClassEntity element) {
// TODO(johnniwinther): Implement this.
return false;
}
@override
bool isJsInteropClass(ClassEntity element) {
throw new UnimplementedError('NativeBasicDataImpl.isJsInteropClass');
}
@override
bool isJsInteropLibrary(LibraryEntity element) {
throw new UnimplementedError('NativeBasicDataImpl.isJsInteropLibrary');
}
@override
bool isNativeOrExtendsNative(ClassEntity element) {
// TODO(johnniwinther): Implement this.
return false;
}
@override
bool hasNativeTagsForcedNonLeaf(ClassEntity cls) {
throw new UnimplementedError(
'NativeBasicDataImpl.hasNativeTagsForcedNonLeaf');
}
@override
List<String> getNativeTagsOfClass(ClassEntity cls) {
throw new UnimplementedError('NativeBasicDataImpl.getNativeTagsOfClass');
}
}
class RuntimeTypesNeedBuilderImpl implements RuntimeTypesNeedBuilder {
@override
void registerClassUsingTypeVariableExpression(ClassEntity cls) {}
@override
RuntimeTypesNeed computeRuntimeTypesNeed(
ResolutionWorldBuilder resolutionWorldBuilder,
ClosedWorld closedWorld,
DartTypes types,
CommonElements commonElements,
BackendUsage backendUsage,
{bool enableTypeAssertions}) {
throw new UnimplementedError(
'RuntimeTypesNeedBuilderImpl.computeRuntimeTypesNeed');
}
@override
void registerRtiDependency(ClassEntity element, ClassEntity dependency) {}
}
class MirrorsDataBuilderImpl implements MirrorsDataBuilder {
@override
void registerUsedMember(MemberEntity member) {}
@override
void computeMembersNeededForReflection(
ResolutionWorldBuilder worldBuilder, ClosedWorld closedWorld) {}
@override
void maybeMarkClosureAsNeededForReflection(
ClosureClassElement globalizedElement,
FunctionElement callFunction,
FunctionElement function) {}
@override
void registerConstSymbol(String name) {}
@override
void registerMirrorUsage(
Set<String> symbols, Set<Element> targets, Set<Element> metaTargets) {}
}
class CustomElementsResolutionAnalysisImpl
implements CustomElementsResolutionAnalysis {
@override
CustomElementsAnalysisJoin get join {
throw new UnimplementedError('CustomElementsResolutionAnalysisImpl.join');
}
@override
WorldImpact flush() {
// TODO(johnniwinther): Implement this.
return const WorldImpact();
}
@override
void registerStaticUse(MemberEntity element) {}
@override
void registerInstantiatedClass(ClassEntity classElement) {}
@override
void registerTypeLiteral(DartType type) {}
}
class MirrorsResolutionAnalysisImpl implements MirrorsResolutionAnalysis {
@override
void onQueueEmpty(Enqueuer enqueuer, Iterable<ClassEntity> recentClasses) {}
@override
MirrorsCodegenAnalysis close() {
throw new UnimplementedError('MirrorsResolutionAnalysisImpl.close');
}
@override
void onResolutionComplete() {}
}
class KernelWorkItemBuilder implements WorkItemBuilder {
final KernelWorldBuilder _worldBuilder;
final ImpactTransformer _impactTransformer;
KernelWorkItemBuilder(this._worldBuilder, this._impactTransformer);
@override
WorkItem createWorkItem(MemberEntity entity) {
return new KernelWorkItem(_worldBuilder, _impactTransformer, entity);
}
}
class KernelWorkItem implements ResolutionWorkItem {
final KernelWorldBuilder _worldBuilder;
final ImpactTransformer _impactTransformer;
final MemberEntity element;
KernelWorkItem(this._worldBuilder, this._impactTransformer, this.element);
@override
WorldImpact run() {
ResolutionImpact impact = _worldBuilder.computeWorldImpact(element);
return _impactTransformer.transformResolutionImpact(impact);
}
}