EMMA Coverage Report (generated Mon Nov 01 16:48:29 PDT 2010)
[all classes][com.google.caja.parser.js]

COVERAGE SUMMARY FOR SOURCE FILE [Minify.java]

nameclass, %method, %block, %line, %
Minify.java0%   (0/2)0%   (0/6)0%   (0/257)0%   (0/42)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Minify0%   (0/1)0%   (0/4)0%   (0/238)0%   (0/39)
Minify (): void 0%   (0/1)0%   (0/3)0%   (0/1)
checkInputs (String []): List 0%   (0/1)0%   (0/55)0%   (0/7)
main (String []): void 0%   (0/1)0%   (0/21)0%   (0/4)
minify (Iterable, Writer, PrintWriter): boolean 0%   (0/1)0%   (0/159)0%   (0/27)
     
class Minify$10%   (0/1)0%   (0/2)0%   (0/19)0%   (0/3)
Minify$1 (MessageQueue): void 0%   (0/1)0%   (0/6)0%   (0/1)
handle (IOException): void 0%   (0/1)0%   (0/13)0%   (0/2)

1// Copyright (C) 2008 Google Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14 
15package com.google.caja.parser.js;
16 
17import com.google.caja.lexer.CharProducer;
18import com.google.caja.lexer.InputSource;
19import com.google.caja.lexer.JsLexer;
20import com.google.caja.lexer.JsTokenQueue;
21import com.google.caja.lexer.ParseException;
22import com.google.caja.render.Concatenator;
23import com.google.caja.render.JsMinimalPrinter;
24import com.google.caja.reporting.EchoingMessageQueue;
25import com.google.caja.reporting.Message;
26import com.google.caja.reporting.MessageContext;
27import com.google.caja.reporting.MessageLevel;
28import com.google.caja.reporting.MessagePart;
29import com.google.caja.reporting.MessageQueue;
30import com.google.caja.reporting.MessageType;
31import com.google.caja.reporting.RenderContext;
32import com.google.caja.util.Callback;
33import com.google.caja.util.Charsets;
34import com.google.caja.util.Pair;
35 
36import java.io.File;
37import java.io.FileInputStream;
38import java.io.IOException;
39import java.io.InputStreamReader;
40import java.io.Writer;
41import java.io.PrintWriter;
42import java.util.ArrayList;
43import java.util.List;
44 
45/**
46 * An executable that compresses the input javascript.
47 * Usage
48 * <pre>
49 * java com.google.caja.parser.js.Minify file1.js file2.js ... > minified.js
50 * </pre>
51 *
52 * <p>This parses and renders JS so guarantees valid output, but does not
53 * otherwise change the structure.  The output is semantically the same even
54 * in the presence of aliased eval.
55 *
56 * <p>It does strip comments and unnecessary whitespace.</p>
57 *
58 * <p>It does not rename local variables, inline constants or functions,
59 * eliminate dead code, or zip content.</p>
60 *
61 * @author mikesamuel@gmail.com
62 */
63public class Minify {
64  public static void main(String[] jsFilePaths) throws IOException {
65    List<Pair<InputSource, File>> inputs = checkInputs(jsFilePaths);
66    boolean passed = minify(inputs, new PrintWriter(System.out),
67                            new PrintWriter(System.err));
68    System.exit(passed ? 0 : -1);
69  }
70 
71  /** Called before opening files to checks that all input are readable. */
72  private static List<Pair<InputSource, File>> checkInputs(String... jsFiles)
73      throws IOException {
74    List<Pair<InputSource, File>> inputs
75        = new ArrayList<Pair<InputSource, File>>();
76    for (String jsFile : jsFiles) {
77      File f = new File(jsFile);
78      if (!f.canRead()) { throw new IOException("Cannot read " + jsFile); }
79      InputSource is = new InputSource(f.getAbsoluteFile().toURI());
80      inputs.add(Pair.pair(is, f));
81    }
82    return inputs;
83  }
84 
85  public static boolean minify(Iterable<Pair<InputSource, File>> inputs,
86                               Writer out, PrintWriter err)
87      throws IOException {
88    MessageContext mc = new MessageContext();
89    for (Pair<InputSource, File> input : inputs) {
90      mc.addInputSource(input.a);
91    }
92    final MessageQueue errs = new EchoingMessageQueue(
93        err, mc, false);
94    RenderContext rc = new RenderContext(
95        new JsMinimalPrinter(new Concatenator(out, new Callback<IOException>() {
96          public void handle(IOException ex) {
97            errs.addMessage(
98                MessageType.IO_ERROR,
99                MessagePart.Factory.valueOf(ex.getMessage()));
100          }
101        })));
102 
103    for (Pair<InputSource, File> input : inputs) {
104      CharProducer cp = CharProducer.Factory.create(
105          new InputStreamReader(new FileInputStream(input.b), 
106              Charsets.UTF_8.name()),
107          input.a);
108      JsLexer lexer = new JsLexer(cp);
109      JsTokenQueue tq = new JsTokenQueue(lexer, input.a);
110      Parser p = new Parser(tq, errs);
111      try {
112        while (!tq.isEmpty()) {
113          Block b = p.parse();
114          for (Statement topLevelStmt : b.children()) {
115            topLevelStmt.render(rc);
116            if (!topLevelStmt.isTerminal()) { rc.getOut().consume(";"); }
117          }
118        }
119      } catch (ParseException ex) {
120        ex.toMessageQueue(errs);
121      }
122    }
123    rc.getOut().noMoreTokens();
124    out.flush();
125 
126    MessageLevel maxMessageLevel = MessageLevel.values()[0];
127    for (Message msg : errs.getMessages()) {
128      if (msg.getMessageLevel().compareTo(maxMessageLevel) >= 0) {
129        maxMessageLevel = msg.getMessageLevel();
130      }
131    }
132    return maxMessageLevel.compareTo(MessageLevel.ERROR) < 0;
133  }
134}

[all classes][com.google.caja.parser.js]
EMMA 2.0.5312 (C) Vladimir Roubtsov