LCOV - code coverage report
Current view: top level - source_maps-0.10.4/lib - printer.dart (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 0 65 0.0 %
Date: 2017-10-10 20:17:03 Functions: 0 0 -

          Line data    Source code
       1             : // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
       2             : // for details. All rights reserved. Use of this source code is governed by a
       3             : // BSD-style license that can be found in the LICENSE file.
       4             : 
       5             : /// Contains a code printer that generates code by recording the source maps.
       6             : library source_maps.printer;
       7             : 
       8             : import 'package:source_span/source_span.dart';
       9             : 
      10             : import 'builder.dart';
      11             : import 'src/source_map_span.dart';
      12             : 
      13             : const int _LF = 10;
      14             : const int _CR = 13;
      15             : 
      16             : /// A simple printer that keeps track of offset locations and records source
      17             : /// maps locations.
      18             : class Printer {
      19             :   final String filename;
      20             :   final StringBuffer _buff = new StringBuffer();
      21             :   final SourceMapBuilder _maps = new SourceMapBuilder();
      22           0 :   String get text => _buff.toString();
      23           0 :   String get map => _maps.toJson(filename);
      24             : 
      25             :   /// Current source location mapping.
      26             :   SourceLocation _loc;
      27             : 
      28             :   /// Current line in the buffer;
      29             :   int _line = 0;
      30             : 
      31             :   /// Current column in the buffer.
      32             :   int _column = 0;
      33             : 
      34           0 :   Printer(this.filename);
      35             : 
      36             :   /// Add [str] contents to the output, tracking new lines to track correct
      37             :   /// positions for span locations. When [projectMarks] is true, this method
      38             :   /// adds a source map location on each new line, projecting that every new
      39             :   /// line in the target file (printed here) corresponds to a new line in the
      40             :   /// source file.
      41             :   void add(String str, {projectMarks: false}) {
      42           0 :     var chars = str.runes.toList();
      43           0 :     var length = chars.length;
      44           0 :     for (int i = 0; i < length; i++) {
      45           0 :       var c = chars[i];
      46           0 :       if (c == _LF || (c == _CR && (i + 1 == length || chars[i + 1] != _LF))) {
      47             :         // Return not followed by line-feed is treated as a new line.
      48           0 :         _line++;
      49           0 :         _column = 0;
      50           0 :         if (projectMarks && _loc != null) {
      51           0 :           if (_loc is FileLocation) {
      52           0 :             var file = (_loc as FileLocation).file;
      53           0 :             mark(file.location(file.getOffset(_loc.line + 1)));
      54             :           } else {
      55           0 :             mark(new SourceLocation(0,
      56           0 :                 sourceUrl: _loc.sourceUrl, line: _loc.line + 1, column: 0));
      57             :           }
      58             :         }
      59             :       } else {
      60           0 :         _column++;
      61             :       }
      62             :     }
      63           0 :     _buff.write(str);
      64             :   }
      65             : 
      66             : 
      67             :   /// Append a [total] number of spaces in the target file. Typically used for
      68             :   /// formatting indentation.
      69             :   void addSpaces(int total) {
      70           0 :     for (int i = 0; i < total; i++) _buff.write(' ');
      71           0 :     _column += total;
      72             :   }
      73             : 
      74             :   /// Marks that the current point in the target file corresponds to the [mark]
      75             :   /// in the source file, which can be either a [SourceLocation] or a
      76             :   /// [SourceSpan]. When the mark is a [SourceMapSpan] with `isIdentifier` set,
      77             :   /// this also records the name of the identifier in the source map
      78             :   /// information.
      79             :   void mark(mark) {
      80             :     var loc;
      81             :     var identifier = null;
      82           0 :     if (mark is SourceLocation) {
      83             :       loc = mark;
      84           0 :     } else if (mark is SourceSpan) {
      85           0 :       loc = mark.start;
      86           0 :       if (mark is SourceMapSpan && mark.isIdentifier) identifier = mark.text;
      87             :     }
      88           0 :     _maps.addLocation(
      89             :         loc,
      90           0 :         new SourceLocation(_buff.length, line: _line, column: _column),
      91             :         identifier);
      92           0 :     _loc = loc;
      93             :   }
      94             : }
      95             : 
      96             : /// A more advanced printer that keeps track of offset locations to record
      97             : /// source maps, but additionally allows nesting of different kind of items,
      98             : /// including [NestedPrinter]s, and it let's you automatically indent text.
      99             : ///
     100             : /// This class is especially useful when doing code generation, where different
     101             : /// peices of the code are generated independently on separate printers, and are
     102             : /// finally put together in the end.
     103             : class NestedPrinter implements NestedItem {
     104             : 
     105             :   /// Items recoded by this printer, which can be [String] literals,
     106             :   /// [NestedItem]s, and source map information like [SourceLocation] and
     107             :   /// [SourceSpan].
     108             :   List _items = [];
     109             : 
     110             :   /// Internal buffer to merge consecutive strings added to this printer.
     111             :   StringBuffer _buff;
     112             : 
     113             :   /// Current indentation, which can be updated from outside this class.
     114             :   int indent;
     115             : 
     116             :   /// Item used to indicate that the following item is copied from the original
     117             :   /// source code, and hence we should preserve source-maps on every new line.
     118             :   static final _ORIGINAL = new Object();
     119             : 
     120           0 :   NestedPrinter([this.indent = 0]);
     121             : 
     122             :   /// Adds [object] to this printer. [object] can be a [String],
     123             :   /// [NestedPrinter], or anything implementing [NestedItem]. If [object] is a
     124             :   /// [String], the value is appended directly, without doing any formatting
     125             :   /// changes. If you wish to add a line of code with automatic indentation, use
     126             :   /// [addLine] instead.  [NestedPrinter]s and [NestedItem]s are not processed
     127             :   /// until [build] gets called later on. We ensure that [build] emits every
     128             :   /// object in the order that they were added to this printer.
     129             :   ///
     130             :   /// The [location] and [span] parameters indicate the corresponding source map
     131             :   /// location of [object] in the original input. Only one, [location] or
     132             :   /// [span], should be provided at a time.
     133             :   ///
     134             :   /// Indicate [isOriginal] when [object] is copied directly from the user code.
     135             :   /// Setting [isOriginal] will make this printer propagate source map locations
     136             :   /// on every line-break.
     137             :   void add(object, {SourceLocation location, SourceSpan span,
     138             :       bool isOriginal: false}) {
     139           0 :     if (object is! String || location != null || span != null || isOriginal) {
     140           0 :       _flush();
     141             :       assert(location == null || span == null);
     142           0 :       if (location != null) _items.add(location);
     143           0 :       if (span != null) _items.add(span);
     144           0 :       if (isOriginal) _items.add(_ORIGINAL);
     145             :     }
     146             : 
     147           0 :     if (object is String) {
     148           0 :       _appendString(object);
     149             :     } else {
     150           0 :       _items.add(object);
     151             :     }
     152             :   }
     153             : 
     154             :   /// Append `2 * indent` spaces to this printer.
     155           0 :   void insertIndent() => _indent(indent);
     156             : 
     157             :   /// Add a [line], autoindenting to the current value of [indent]. Note,
     158             :   /// indentation is not inferred from the contents added to this printer. If a
     159             :   /// line starts or ends an indentation block, you need to also update [indent]
     160             :   /// accordingly. Also, indentation is not adapted for nested printers. If
     161             :   /// you add a [NestedPrinter] to this printer, its indentation is set
     162             :   /// separately and will not include any the indentation set here.
     163             :   ///
     164             :   /// The [location] and [span] parameters indicate the corresponding source map
     165             :   /// location of [object] in the original input. Only one, [location] or
     166             :   /// [span], should be provided at a time.
     167             :   void addLine(String line, {SourceLocation location, SourceSpan span}) {
     168             :     if (location != null || span != null) {
     169           0 :       _flush();
     170             :       assert(location == null || span == null);
     171           0 :       if (location != null) _items.add(location);
     172           0 :       if (span != null) _items.add(span);
     173             :     }
     174             :     if (line == null) return;
     175           0 :     if (line != '') {
     176             :       // We don't indent empty lines.
     177           0 :       _indent(indent);
     178           0 :       _appendString(line);
     179             :     }
     180           0 :     _appendString('\n');
     181             :   }
     182             : 
     183             :   /// Appends a string merging it with any previous strings, if possible.
     184             :   void _appendString(String s) {
     185           0 :     if (_buff == null) _buff = new StringBuffer();
     186           0 :     _buff.write(s);
     187             :   }
     188             : 
     189             :   /// Adds all of the current [_buff] contents as a string item.
     190             :   void _flush() {
     191           0 :     if (_buff != null) {
     192           0 :       _items.add(_buff.toString());
     193           0 :       _buff = null;
     194             :     }
     195             :   }
     196             : 
     197             :   void _indent(int indent) {
     198           0 :     for (int i = 0; i < indent; i++) _appendString('  ');
     199             :   }
     200             : 
     201             :   /// Returns a string representation of all the contents appended to this
     202             :   /// printer, including source map location tokens.
     203             :   String toString() {
     204           0 :     _flush();
     205           0 :     return (new StringBuffer()..writeAll(_items)).toString();
     206             :   }
     207             : 
     208             :   /// [Printer] used during the last call to [build], if any.
     209             :   Printer printer;
     210             : 
     211             :   /// Returns the text produced after calling [build].
     212           0 :   String get text => printer.text;
     213             : 
     214             :   /// Returns the source-map information produced after calling [build].
     215           0 :   String get map => printer.map;
     216             : 
     217             :   /// Builds the output of this printer and source map information. After
     218             :   /// calling this function, you can use [text] and [map] to retrieve the
     219             :   /// geenrated code and source map information, respectively.
     220             :   void build(String filename) {
     221           0 :     writeTo(printer = new Printer(filename));
     222             :   }
     223             : 
     224             :   /// Implements the [NestedItem] interface.
     225             :   void writeTo(Printer printer) {
     226           0 :     _flush();
     227             :     bool propagate = false;
     228           0 :     for (var item in _items) {
     229           0 :       if (item is NestedItem) {
     230           0 :         item.writeTo(printer);
     231           0 :       } else if (item is String) {
     232           0 :         printer.add(item, projectMarks: propagate);
     233             :         propagate = false;
     234           0 :       } else if (item is SourceLocation || item is SourceSpan) {
     235           0 :         printer.mark(item);
     236           0 :       } else if (item == _ORIGINAL) {
     237             :         // we insert booleans when we are about to quote text that was copied
     238             :         // from the original source. In such case, we will propagate marks on
     239             :         // every new-line.
     240             :         propagate = true;
     241             :       } else {
     242           0 :         throw new UnsupportedError('Unknown item type: $item');
     243             :       }
     244             :     }
     245             :   }
     246             : }
     247             : 
     248             : /// An item added to a [NestedPrinter].
     249             : abstract class NestedItem {
     250             :   /// Write the contents of this item into [printer].
     251             :   void writeTo(Printer printer);
     252             : }

Generated by: LCOV version 1.13