Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(418)

Unified Diff: pkg/compiler/lib/src/dart_backend/outputter.dart

Issue 2213673002: Delete dart_backend from compiler. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/compiler/lib/src/dart_backend/outputter.dart
diff --git a/pkg/compiler/lib/src/dart_backend/outputter.dart b/pkg/compiler/lib/src/dart_backend/outputter.dart
deleted file mode 100644
index ce9022afe009326af0e269327da520c675426c0f..0000000000000000000000000000000000000000
--- a/pkg/compiler/lib/src/dart_backend/outputter.dart
+++ /dev/null
@@ -1,576 +0,0 @@
-// Copyright (c) 2014, 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.
-
-part of dart_backend;
-
-typedef bool IsSafeToRemoveTypeDeclarations(
- Map<ClassElement, Iterable<Element>> classMembers);
-typedef void ElementCallback<E>(E element);
-typedef void ElementPostProcessFunction(
- AstElement element,
- ElementAst elementAst,
- ElementCallback<TypedefElement> typedefCallback,
- ElementCallback<ClassElement> classCallback);
-typedef ElementAst ComputeElementAstFunction(AstElement element);
-typedef bool ElementFilter(Element element);
-typedef List<Element> ElementSorter(Iterable<Element> elements);
-
-/// Output engine for dart2dart that is shared between the dart2js and the
-/// analyzer implementations of dart2dart.
-class DartOutputter {
- final DiagnosticReporter reporter;
- final CompilerOutputProvider outputProvider;
- final bool forceStripTypes;
-
- // TODO(antonm): make available from command-line options.
- final bool outputAst = false;
- final bool enableMinification;
-
- /// If `true`, libraries are generated into separate files.
- final bool multiFile;
-
- /// Internal structures accessible for tests and logging.
- // TODO(johnniwinther): Clean this up.
- PlaceholderRenamer renamer;
- MainOutputGenerator output;
- LibraryInfo libraryInfo;
- ElementInfo elementInfo;
-
- // TODO(johnniwinther): Support recompilation.
- DartOutputter(this.reporter, this.outputProvider,
- {bool this.forceStripTypes: false,
- bool this.enableMinification: false,
- bool this.multiFile: false});
-
- /// Generate Dart code for the program starting at [mainFunction].
- ///
- /// [libraries] is the set of all libraries (user/package/sdk) that are
- /// referenced in the program.
- ///
- /// [instantiatedClasses] is the set of classes that are potentially
- /// instantiated in the program.
- ///
- /// [resolvedElements] is the set of methods, constructors, and fields that
- /// are potentially accessed/called in the program.
- ///
- /// The [sortElements] function is used to sort [instantiatedClasses] and
- /// [resolvedElements] in the generated output.
- ///
- /// Returns the total size of the generated code.
- int assembleProgram(
- {MirrorRenamer mirrorRenamer: const MirrorRenamer(),
- Iterable<LibraryElement> libraries,
- Iterable<Element> instantiatedClasses,
- Iterable<Element> resolvedElements,
- Iterable<ClassElement> usedTypeLiterals: const <ClassElement>[],
- FunctionElement mainFunction,
- Uri outputUri,
- ElementPostProcessFunction postProcessElementAst,
- ComputeElementAstFunction computeElementAst,
- ElementFilter shouldOutput,
- IsSafeToRemoveTypeDeclarations isSafeToRemoveTypeDeclarations,
- ElementSorter sortElements}) {
- assert(invariant(NO_LOCATION_SPANNABLE, libraries != null,
- message: "'libraries' must be non-null."));
- assert(invariant(NO_LOCATION_SPANNABLE, instantiatedClasses != null,
- message: "'instantiatedClasses' must be non-null."));
- assert(invariant(NO_LOCATION_SPANNABLE, resolvedElements != null,
- message: "'resolvedElements' must be non-null."));
- assert(invariant(NO_LOCATION_SPANNABLE, mainFunction != null,
- message: "'mainFunction' must be non-null."));
- assert(invariant(NO_LOCATION_SPANNABLE, computeElementAst != null,
- message: "'computeElementAst' must be non-null."));
- assert(invariant(NO_LOCATION_SPANNABLE, shouldOutput != null,
- message: "'shouldOutput' must be non-null."));
- assert(invariant(
- NO_LOCATION_SPANNABLE, isSafeToRemoveTypeDeclarations != null,
- message: "'isSafeToRemoveTypeDeclarations' must be non-null."));
-
- if (sortElements == null) {
- // Ensure deterministic output order.
- sortElements = (Iterable<Element> elements) {
- List<Element> list = elements.toList();
- list.sort((Element a, Element b) => a.name.compareTo(b.name));
- return list;
- };
- }
-
- libraryInfo =
- LibraryInfo.processLibraries(reporter, libraries, resolvedElements);
-
- elementInfo = ElementInfoProcessor.createElementInfo(
- instantiatedClasses, resolvedElements, usedTypeLiterals,
- postProcessElementAst: postProcessElementAst,
- parseElementAst: computeElementAst,
- shouldOutput: shouldOutput,
- sortElements: sortElements);
-
- PlaceholderCollector collector = collectPlaceholders(
- reporter, mirrorRenamer, mainFunction, libraryInfo, elementInfo);
-
- renamer = createRenamer(collector, libraryInfo, elementInfo,
- enableMinification: enableMinification,
- forceStripTypes: forceStripTypes,
- isSafeToRemoveTypeDeclarations: isSafeToRemoveTypeDeclarations);
-
- if (outputAst) {
- String code = astOutput(reporter, elementInfo);
- outputProvider("", "dart")
- ..add(code)
- ..close();
- return code.length;
- } else {
- output = new MainOutputGenerator();
- return output.generateCode(libraryInfo, elementInfo, collector, renamer,
- mainFunction, outputUri, outputProvider, mirrorRenamer,
- multiFile: multiFile,
- forceStripTypes: forceStripTypes,
- enableMinification: enableMinification);
- }
- }
-
- static PlaceholderCollector collectPlaceholders(
- DiagnosticReporter reporter,
- MirrorRenamer mirrorRenamer,
- FunctionElement mainFunction,
- LibraryInfo libraryInfo,
- ElementInfo elementInfo) {
- // Create all necessary placeholders.
- PlaceholderCollector collector = new PlaceholderCollector(
- reporter,
- mirrorRenamer,
- libraryInfo.fixedDynamicNames,
- elementInfo.elementAsts,
- mainFunction);
-
- makePlaceholders(element) {
- collector.collect(element);
-
- if (element.isClass && !element.isEnumClass) {
- elementInfo.classMembers[element].forEach(makePlaceholders);
- }
- }
- elementInfo.topLevelElements.forEach(makePlaceholders);
- return collector;
- }
-
- static PlaceholderRenamer createRenamer(PlaceholderCollector collector,
- LibraryInfo libraryInfo, ElementInfo elementInfo,
- {bool enableMinification: false,
- bool forceStripTypes: false,
- isSafeToRemoveTypeDeclarations}) {
- // Create renames.
- bool shouldCutDeclarationTypes = forceStripTypes ||
- (enableMinification &&
- isSafeToRemoveTypeDeclarations(elementInfo.classMembers));
-
- PlaceholderRenamer placeholderRenamer = new PlaceholderRenamer(
- libraryInfo.fixedDynamicNames,
- libraryInfo.fixedStaticNames,
- libraryInfo.reexportingLibraries,
- cutDeclarationTypes: shouldCutDeclarationTypes,
- enableMinification: enableMinification);
-
- placeholderRenamer.computeRenames(collector);
- return placeholderRenamer;
- }
-
- static String astOutput(
- DiagnosticReporter reporter, ElementInfo elementInfo) {
- // TODO(antonm): Ideally XML should be a separate backend.
- // TODO(antonm): obey renames and minification, at least as an option.
- StringBuffer sb = new StringBuffer();
- outputElement(element) {
- sb.write(element.parseNode(reporter).toDebugString());
- }
-
- // Emit XML for AST instead of the program.
- for (Element topLevel in elementInfo.topLevelElements) {
- if (topLevel.isClass &&
- !elementInfo.emitNoMembersFor.contains(topLevel)) {
- // TODO(antonm): add some class info.
- elementInfo.classMembers[topLevel].forEach(outputElement);
- } else {
- outputElement(topLevel);
- }
- }
- return '<Program>\n$sb</Program>\n';
- }
-}
-
-class LibraryInfo {
- final Set<String> fixedStaticNames;
- final Set<String> fixedDynamicNames;
- final Map<Element, LibraryElement> reexportingLibraries;
- final List<LibraryElement> userLibraries;
-
- LibraryInfo(this.fixedStaticNames, this.fixedDynamicNames,
- this.reexportingLibraries, this.userLibraries);
-
- static LibraryInfo processLibraries(
- DiagnosticReporter reporter,
- Iterable<LibraryElement> libraries,
- Iterable<AstElement> resolvedElements) {
- Set<String> fixedStaticNames = new Set<String>();
- Set<String> fixedDynamicNames = new Set<String>();
- Map<Element, LibraryElement> reexportingLibraries =
- <Element, LibraryElement>{};
- List<LibraryElement> userLibraries = <LibraryElement>[];
- // Conservatively traverse all platform libraries and collect member names.
- // TODO(antonm): ideally we should only collect names of used members,
- // however as of today there are problems with names of some core library
- // interfaces, most probably for interfaces of literals.
-
- for (LibraryElement library in libraries) {
- if (!library.isPlatformLibrary) {
- userLibraries.add(library);
- continue;
- }
- library.forEachLocalMember((Element element) {
- if (element.isClass) {
- ClassElement classElement = element;
- assert(invariant(classElement, classElement.isResolved,
- message: "Unresolved platform class."));
- classElement.forEachLocalMember((member) {
- if (member.isInstanceMember) {
- fixedDynamicNames.add(member.name);
- } else {
- fixedStaticNames.add(member.name);
- }
- });
- }
- // Even class names are added due to a delicate problem we have:
- // if one imports dart:core with a prefix, we cannot tell prefix.name
- // from dynamic invocation (alas!). So we'd better err on preserving
- // those names.
- fixedStaticNames.add(element.name);
- });
-
- library.forEachExport((Element export) {
- if (!library.isInternalLibrary && export.library.isInternalLibrary) {
- // If an element of an internal library is reexported by a platform
- // library, we have to import the reexporting library instead of the
- // internal library, because the internal library is an
- // implementation detail of dart2js.
- reexportingLibraries[export] = library;
- }
- });
- }
-
- // Map to keep track of names of enum classes. Since these cannot be renamed
- // we ensure that they are unique.
- Map<String, ClassElement> enumClassMap = <String, ClassElement>{};
-
- // As of now names of named optionals are not renamed. Therefore add all
- // field names used as named optionals into [fixedMemberNames].
- for (final element in resolvedElements) {
- if (!element.isConstructor) continue;
- for (ParameterElement parameter in element.parameters) {
- if (parameter.isInitializingFormal && parameter.isNamed) {
- fixedDynamicNames.add(parameter.name);
- }
- }
- ClassElement cls = element.enclosingClass;
- if (cls != null && cls.isEnumClass) {
- fixedDynamicNames.add('index');
-
- ClassElement existingEnumClass =
- enumClassMap.putIfAbsent(cls.name, () => cls);
- if (existingEnumClass != cls) {
- reporter.reportError(
- reporter.createMessage(cls, MessageKind.GENERIC, {
- 'text': "Duplicate enum names are not supported "
- "in dart2dart."
- }),
- <DiagnosticMessage>[
- reporter.createMessage(existingEnumClass, MessageKind.GENERIC, {
- 'text': "This is the other declaration of '${cls.name}'."
- }),
- ]);
- }
- }
- }
-
- fixedStaticNames.addAll(enumClassMap.keys);
-
- // The VM will automatically invoke the call method of objects
- // that are invoked as functions. Make sure to not rename that.
- fixedDynamicNames.add('call');
-
- return new LibraryInfo(fixedStaticNames, fixedDynamicNames,
- reexportingLibraries, userLibraries);
- }
-}
-
-class ElementInfo {
- final Map<Element, ElementAst> elementAsts;
- final Iterable<Element> topLevelElements;
- final Map<ClassElement, Iterable<Element>> classMembers;
- final Iterable<ClassElement> emitNoMembersFor;
-
- ElementInfo(this.elementAsts, this.topLevelElements, this.classMembers,
- this.emitNoMembersFor);
-}
-
-class ElementInfoProcessor implements ElementInfo {
- final Map<Element, ElementAst> elementAsts = new Map<Element, ElementAst>();
- final Set<Element> topLevelElements = new Set<Element>();
- final Map<ClassElement, Set<Element>> classMembers =
- new Map<ClassElement, Set<Element>>();
- final Set<ClassElement> emitNoMembersFor = new Set<ClassElement>();
- final ElementPostProcessFunction postProcessElementAst;
- final ComputeElementAstFunction parseElementAst;
- final ElementFilter shouldOutput;
-
- ElementInfoProcessor(
- {this.postProcessElementAst, this.parseElementAst, this.shouldOutput});
-
- static ElementInfo createElementInfo(
- Iterable<ClassElement> instantiatedClasses,
- Iterable<AstElement> resolvedElements,
- Iterable<ClassElement> usedTypeLiterals,
- {ElementPostProcessFunction postProcessElementAst,
- ComputeElementAstFunction parseElementAst,
- ElementFilter shouldOutput,
- ElementSorter sortElements}) {
- ElementInfoProcessor processor = new ElementInfoProcessor(
- postProcessElementAst: postProcessElementAst,
- parseElementAst: parseElementAst,
- shouldOutput: shouldOutput);
- return processor.process(
- instantiatedClasses, resolvedElements, usedTypeLiterals,
- sortElements: sortElements);
- }
-
- ElementInfo process(
- Iterable<ClassElement> instantiatedClasses,
- Iterable<AstElement> resolvedElements,
- Iterable<ClassElement> usedTypeLiterals,
- {ElementSorter sortElements}) {
- // Build all top level elements to emit and necessary class members.
- instantiatedClasses.where(shouldOutput).forEach(addClass);
- resolvedElements.where(shouldOutput).forEach(addMember);
- usedTypeLiterals.forEach((ClassElement element) {
- if (shouldOutput(element)) {
- if (!topLevelElements.contains(element)) {
- // The class is only referenced by type literals.
- emitNoMembersFor.add(element);
- }
- addClass(element);
- }
- });
-
- // Sort elements.
- List<Element> sortedTopLevels = sortElements(topLevelElements);
- Map<ClassElement, List<Element>> sortedClassMembers =
- new Map<ClassElement, List<Element>>();
- classMembers.forEach((classElement, members) {
- sortedClassMembers[classElement] = sortElements(members);
- });
-
- return new ElementInfo(
- elementAsts, sortedTopLevels, sortedClassMembers, emitNoMembersFor);
- }
-
- void processElement(Element element, ElementAst elementAst) {
- if (postProcessElementAst != null) {
- postProcessElementAst(element, elementAst, newTypedefElementCallback,
- newClassElementCallback);
- }
- elementAsts[element] = elementAst;
- }
-
- void addTopLevel(AstElement element, ElementAst elementAst) {
- if (topLevelElements.contains(element)) return;
- topLevelElements.add(element);
- processElement(element, elementAst);
- }
-
- void addClass(ClassElement classElement) {
- TreeElements treeElements = new TreeElementMapping(classElement);
- backend2frontend.TreePrinter treePrinter =
- new backend2frontend.TreePrinter(treeElements);
- Node node = treePrinter.makeNodeForClassElement(classElement);
- addTopLevel(classElement, new ElementAst(node, treeElements));
- classMembers.putIfAbsent(classElement, () => new Set());
- }
-
- void newTypedefElementCallback(TypedefElement element) {
- if (!shouldOutput(element)) return;
- TreeElements treeElements = new TreeElementMapping(element);
- backend2frontend.TreePrinter treePrinter =
- new backend2frontend.TreePrinter(treeElements);
- Node node = treePrinter.makeTypedef(element);
- addTopLevel(element, new ElementAst(node, treeElements));
- }
-
- void newClassElementCallback(ClassElement classElement) {
- if (!shouldOutput(classElement)) return;
- addClass(classElement);
- }
-
- void addMember(element) {
- if (element.isClassMember) {
- ClassElement enclosingClass = element.enclosingClass;
- assert(enclosingClass.isClass);
- assert(shouldOutput(enclosingClass));
- addClass(enclosingClass);
- classMembers[enclosingClass].add(element);
- if (enclosingClass.isEnumClass) return;
- processElement(element, parseElementAst(element));
- } else {
- if (element.isTopLevel) {
- addTopLevel(element, parseElementAst(element));
- }
- }
- }
-}
-
-/// Main output generator for [DartOutputter] that emits dart code through a
-/// [CompilerOutputProvider].
-class MainOutputGenerator {
- final Map<ClassNode, List<Node>> memberNodes =
- new Map<ClassNode, List<Node>>();
- final List<Node> topLevelNodes = <Node>[];
-
- /// Generates the code and returns the total size.
- int generateCode(
- LibraryInfo libraryInfo,
- ElementInfo elementInfo,
- PlaceholderCollector collector,
- PlaceholderRenamer placeholderRenamer,
- FunctionElement mainFunction,
- Uri outputUri,
- CompilerOutputProvider outputProvider,
- MirrorRenamer mirrorRenamer,
- {bool multiFile: false,
- bool forceStripTypes: false,
- bool enableMinification: false}) {
- for (Element element in elementInfo.topLevelElements) {
- topLevelNodes.add(elementInfo.elementAsts[element].ast);
- if (element.isClass) {
- ClassElement cls = element;
- if (cls.isMixinApplication || cls.isEnumClass) {
- continue;
- }
- final members = <Node>[];
- for (Element member in elementInfo.classMembers[cls]) {
- members.add(elementInfo.elementAsts[member].ast);
- }
- memberNodes[elementInfo.elementAsts[cls].ast] = members;
- }
- }
-
- mirrorRenamer.addRenames(
- placeholderRenamer.renames, topLevelNodes, collector);
-
- Map<LibraryElement, String> outputPaths = new Map<LibraryElement, String>();
- Map<LibraryElement, EmitterUnparser> unparsers =
- new Map<LibraryElement, EmitterUnparser>();
-
- // The single unparser used if we collect all the output in one file.
- EmitterUnparser mainUnparser = multiFile
- ? null
- : new EmitterUnparser(placeholderRenamer.renames,
- stripTypes: forceStripTypes, minify: enableMinification);
-
- if (multiFile) {
- // TODO(sigurdm): Factor handling of library-paths out from emitting.
- String mainName = outputUri.pathSegments.last;
- String mainBaseName = mainName.endsWith(".dart")
- ? mainName.substring(0, mainName.length - 5)
- : mainName;
- // Map each library to a path based on the uri of the original
- // library and [compiler.options.outputUri].
- Set<String> usedLibraryPaths = new Set<String>();
- for (LibraryElement library in libraryInfo.userLibraries) {
- if (library == mainFunction.library) {
- outputPaths[library] = mainBaseName;
- } else {
- List<String> names =
- library.canonicalUri.pathSegments.last.split(".");
- if (names.last == "dart") {
- names = names.sublist(0, names.length - 1);
- }
- outputPaths[library] =
- "$mainBaseName.${makeUnique(names.join("."), usedLibraryPaths)}";
- }
- }
-
- /// Rewrites imports/exports to refer to the paths given in [outputPaths].
- for (LibraryElement outputLibrary in libraryInfo.userLibraries) {
- EmitterUnparser unparser = new EmitterUnparser(
- placeholderRenamer.renames,
- stripTypes: forceStripTypes,
- minify: enableMinification);
- unparsers[outputLibrary] = unparser;
- if (outputLibrary.hasLibraryName) {
- unparser.unparseLibraryName(outputLibrary.libraryName);
- }
- for (ImportElement import in outputLibrary.imports) {
- LibraryElement libraryElement = import.importedLibrary;
- String uri = outputPaths.containsKey(libraryElement)
- ? "${outputPaths[libraryElement]}.dart"
- : libraryElement.canonicalUri.toString();
- unparser.unparseImportTag(uri);
- }
- for (ExportElement export in outputLibrary.exports) {
- LibraryElement libraryElement = export.exportedLibrary;
- String uri = outputPaths.containsKey(libraryElement)
- ? "${outputPaths[libraryElement]}.dart"
- : libraryElement.canonicalUri.toString();
- unparser.unparseExportTag(uri);
- }
- }
- } else {
- placeholderRenamer.platformImports
- .forEach((LibraryElement library, String prefix) {
- assert(library.isPlatformLibrary && !library.isInternalLibrary);
- mainUnparser.unparseImportTag(library.canonicalUri.toString());
- if (prefix != null) {
- // Adding a prefixed import because (some) top-level access need
- // it to avoid shadowing.
- // TODO(johnniwinther): Avoid prefix-less import if not needed.
- mainUnparser.unparseImportTag(library.canonicalUri.toString(),
- prefix: prefix);
- }
- });
- }
-
- for (int i = 0; i < elementInfo.topLevelElements.length; i++) {
- Element element = elementInfo.topLevelElements.elementAt(i);
- Node node = topLevelNodes[i];
- Unparser unparser = multiFile ? unparsers[element.library] : mainUnparser;
- if (node is ClassNode) {
- // TODO(smok): Filter out default constructors here.
- unparser.unparseClassWithBody(node, memberNodes[node]);
- } else {
- unparser.unparse(node);
- }
- unparser.newline();
- }
-
- int totalSize = 0;
- if (multiFile) {
- for (LibraryElement outputLibrary in libraryInfo.userLibraries) {
- // TODO(sigurdm): Make the unparser output directly into the buffer
- // instead of caching in `.result`.
- String code = unparsers[outputLibrary].result;
- totalSize += code.length;
- outputProvider(outputPaths[outputLibrary], "dart")
- ..add(code)
- ..close();
- }
- } else {
- String code = mainUnparser.result;
- outputProvider("", "dart")
- ..add(code)
- ..close();
-
- totalSize = code.length;
- }
-
- return totalSize;
- }
-}
« no previous file with comments | « pkg/compiler/lib/src/dart_backend/dart_backend.dart ('k') | pkg/compiler/lib/src/dart_backend/placeholder_collector.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698