blob: 9f8d909e0c998b4605a97b4b5ea02d53e7d315f1 [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.
/// Source information strategy that concurrently builds sourcemaps for each of
/// child strategies.
library dart2js.dual_source_information;
import '../common.dart';
import '../elements/entities.dart';
import '../js/js_source_mapping.dart';
import '../js/js.dart' as js;
import 'code_output.dart' show BufferedCodeOutput;
import 'source_information.dart';
class MultiSourceInformationStrategy<T>
implements JavaScriptSourceInformationStrategy<T> {
final List<JavaScriptSourceInformationStrategy<T>> strategies;
const MultiSourceInformationStrategy(this.strategies);
@override
SourceInformationBuilder<T> createBuilderForContext(MemberEntity member) {
return new MultiSourceInformationBuilder<T>(
strategies.map((s) => s.createBuilderForContext(member)).toList());
}
@override
void onComplete() {
strategies.forEach((s) => s.onComplete());
}
@override
SourceInformation buildSourceMappedMarker() {
return new MultiSourceInformation(
strategies.map((s) => s.buildSourceMappedMarker()).toList());
}
@override
SourceInformationProcessor createProcessor(
SourceMapperProvider sourceMapperProvider,
SourceInformationReader reader) {
return new MultiSourceInformationProcessor(
new List<SourceInformationProcessor>.generate(strategies.length,
(int index) {
return strategies[index].createProcessor(sourceMapperProvider,
new MultiSourceInformationReader(reader, index));
}));
}
}
class MultiSourceInformationProcessor implements SourceInformationProcessor {
final List<SourceInformationProcessor> processors;
MultiSourceInformationProcessor(this.processors);
@override
void onStartPosition(js.Node node, int startPosition) {
processors.forEach((p) => p.onStartPosition(node, startPosition));
}
@override
void onPositions(
js.Node node, int startPosition, int endPosition, int closingPosition) {
processors.forEach((p) =>
p.onPositions(node, startPosition, endPosition, closingPosition));
}
@override
void process(js.Node node, BufferedCodeOutput code) {
processors.forEach((p) => p.process(node, code));
}
}
class MultiSourceInformationBuilder<T> implements SourceInformationBuilder<T> {
final List<SourceInformationBuilder<T>> builders;
MultiSourceInformationBuilder(this.builders);
@override
SourceInformationBuilder forContext(MemberEntity member) {
return new MultiSourceInformationBuilder(
builders.map((b) => b.forContext(member)).toList());
}
@override
SourceInformation buildSwitchCase(T node) {
return new MultiSourceInformation(
builders.map((b) => b.buildSwitchCase(node)).toList());
}
@override
SourceInformation buildSwitch(T node) {
return new MultiSourceInformation(
builders.map((b) => b.buildSwitch(node)).toList());
}
@override
SourceInformation buildAs(T node) {
return new MultiSourceInformation(
builders.map((b) => b.buildAs(node)).toList());
}
@override
SourceInformation buildIs(T node) {
return new MultiSourceInformation(
builders.map((b) => b.buildIs(node)).toList());
}
@override
SourceInformation buildTry(T node) {
return new MultiSourceInformation(
builders.map((b) => b.buildTry(node)).toList());
}
@override
SourceInformation buildCatch(T node) {
return new MultiSourceInformation(
builders.map((b) => b.buildCatch(node)).toList());
}
@override
SourceInformation buildBinary(T node) {
return new MultiSourceInformation(
builders.map((b) => b.buildBinary(node)).toList());
}
@override
SourceInformation buildUnary(T node) {
return new MultiSourceInformation(
builders.map((b) => b.buildUnary(node)).toList());
}
@override
SourceInformation buildIndexSet(T node) {
return new MultiSourceInformation(
builders.map((b) => b.buildIndexSet(node)).toList());
}
@override
SourceInformation buildIndex(T node) {
return new MultiSourceInformation(
builders.map((b) => b.buildIndex(node)).toList());
}
@override
SourceInformation buildForInSet(T node) {
return new MultiSourceInformation(
builders.map((b) => b.buildForInSet(node)).toList());
}
@override
SourceInformation buildForInCurrent(T node) {
return new MultiSourceInformation(
builders.map((b) => b.buildForInCurrent(node)).toList());
}
@override
SourceInformation buildForInMoveNext(T node) {
return new MultiSourceInformation(
builders.map((b) => b.buildForInMoveNext(node)).toList());
}
@override
SourceInformation buildForInIterator(T node) {
return new MultiSourceInformation(
builders.map((b) => b.buildForInIterator(node)).toList());
}
@override
SourceInformation buildStringInterpolation(T node) {
return new MultiSourceInformation(
builders.map((b) => b.buildStringInterpolation(node)).toList());
}
@override
SourceInformation buildForeignCode(T node) {
return new MultiSourceInformation(
builders.map((b) => b.buildForeignCode(node)).toList());
}
@override
SourceInformation buildVariableDeclaration() {
return new MultiSourceInformation(
builders.map((b) => b.buildVariableDeclaration()).toList());
}
@override
SourceInformation buildAwait(T node) {
return new MultiSourceInformation(
builders.map((b) => b.buildAwait(node)).toList());
}
@override
SourceInformation buildYield(T node) {
return new MultiSourceInformation(
builders.map((b) => b.buildYield(node)).toList());
}
@override
SourceInformation buildAsyncBody() {
return new MultiSourceInformation(
builders.map((b) => b.buildAsyncBody()).toList());
}
@override
SourceInformation buildAsyncExit() {
return new MultiSourceInformation(
builders.map((b) => b.buildAsyncExit()).toList());
}
@override
SourceInformation buildAssignment(T node) {
return new MultiSourceInformation(
builders.map((b) => b.buildAssignment(node)).toList());
}
@override
SourceInformation buildThrow(T node) {
return new MultiSourceInformation(
builders.map((b) => b.buildThrow(node)).toList());
}
@override
SourceInformation buildNew(T node) {
return new MultiSourceInformation(
builders.map((b) => b.buildNew(node)).toList());
}
@override
SourceInformation buildIf(T node) {
return new MultiSourceInformation(
builders.map((b) => b.buildIf(node)).toList());
}
@override
SourceInformation buildCall(T receiver, T call) {
return new MultiSourceInformation(
builders.map((b) => b.buildCall(receiver, call)).toList());
}
@override
SourceInformation buildGet(T node) {
return new MultiSourceInformation(
builders.map((b) => b.buildGet(node)).toList());
}
@override
SourceInformation buildLoop(T node) {
return new MultiSourceInformation(
builders.map((b) => b.buildLoop(node)).toList());
}
@override
SourceInformation buildImplicitReturn(MemberEntity element) {
return new MultiSourceInformation(
builders.map((b) => b.buildImplicitReturn(element)).toList());
}
@override
SourceInformation buildReturn(T node) {
return new MultiSourceInformation(
builders.map((b) => b.buildReturn(node)).toList());
}
@override
SourceInformation buildCreate(T node) {
return new MultiSourceInformation(
builders.map((b) => b.buildCreate(node)).toList());
}
@override
SourceInformation buildListLiteral(T node) {
return new MultiSourceInformation(
builders.map((b) => b.buildListLiteral(node)).toList());
}
@override
SourceInformation buildGeneric(T node) {
return new MultiSourceInformation(
builders.map((b) => b.buildGeneric(node)).toList());
}
@override
SourceInformation buildDeclaration(MemberEntity member) {
return new MultiSourceInformation(
builders.map((b) => b.buildDeclaration(member)).toList());
}
@override
SourceInformation buildGoto(T node) {
return new MultiSourceInformation(
builders.map((b) => b.buildGoto(node)).toList());
}
}
class MultiSourceInformation implements SourceInformation {
final List<SourceInformation> infos;
MultiSourceInformation(this.infos);
@override
String get shortText => infos.first?.shortText;
@override
List<SourceLocation> get sourceLocations => infos.first?.sourceLocations;
@override
SourceLocation get endPosition => infos.first?.endPosition;
@override
SourceLocation get closingPosition => infos.first?.closingPosition;
@override
SourceLocation get startPosition => infos.first?.startPosition;
@override
SourceSpan get sourceSpan => infos.first?.sourceSpan;
String toString() => '$infos';
}
class MultiSourceInformationReader implements SourceInformationReader {
final SourceInformationReader reader;
final int index;
MultiSourceInformationReader(this.reader, this.index);
@override
SourceInformation getSourceInformation(js.Node node) {
MultiSourceInformation sourceInformation =
reader.getSourceInformation(node);
if (sourceInformation == null) return null;
return sourceInformation.infos[index];
}
}