aboutsummaryrefslogtreecommitdiffstats
path: root/trunk/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/jsc/Main.java
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/jsc/Main.java')
-rw-r--r--trunk/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/jsc/Main.java395
1 files changed, 395 insertions, 0 deletions
diff --git a/trunk/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/jsc/Main.java b/trunk/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/jsc/Main.java
new file mode 100644
index 0000000..2da4f2f
--- /dev/null
+++ b/trunk/infrastructure/rhino1_7R1/toolsrc/org/mozilla/javascript/tools/jsc/Main.java
@@ -0,0 +1,395 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Christine Begle
+ * Norris Boyd
+ * Roger Lawrence
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License Version 2 or later (the "GPL"), in which
+ * case the provisions of the GPL are applicable instead of those above. If
+ * you wish to allow use of your version of this file only under the terms of
+ * the GPL and not to allow others to use your version of this file under the
+ * MPL, indicate your decision by deleting the provisions above and replacing
+ * them with the notice and other provisions required by the GPL. If you do
+ * not delete the provisions above, a recipient may use your version of this
+ * file under either the MPL or the GPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package org.mozilla.javascript.tools.jsc;
+
+import java.io.*;
+import java.util.*;
+import org.mozilla.javascript.*;
+import org.mozilla.javascript.optimizer.ClassCompiler;
+import org.mozilla.javascript.tools.ToolErrorReporter;
+
+/**
+ * @author Norris Boyd
+ */
+public class Main {
+
+ /**
+ * Main entry point.
+ *
+ * Process arguments as would a normal Java program.
+ * Then set up the execution environment and begin to
+ * compile scripts.
+ */
+ public static void main(String args[])
+ {
+ Main main = new Main();
+ args = main.processOptions(args);
+ if (args == null) {
+ if (main.printHelp) {
+ System.out.println(ToolErrorReporter.getMessage(
+ "msg.jsc.usage", Main.class.getName()));
+ System.exit(0);
+ }
+ System.exit(1);
+ }
+ if (!main.reporter.hasReportedError()) {
+ main.processSource(args);
+ }
+ }
+
+ public Main()
+ {
+ reporter = new ToolErrorReporter(true);
+ compilerEnv = new CompilerEnvirons();
+ compilerEnv.setErrorReporter(reporter);
+ compiler = new ClassCompiler(compilerEnv);
+ }
+
+ /**
+ * Parse arguments.
+ *
+ */
+ public String[] processOptions(String args[])
+ {
+ targetPackage = ""; // default to no package
+ compilerEnv.setGenerateDebugInfo(false); // default to no symbols
+ for (int i=0; i < args.length; i++) {
+ String arg = args[i];
+ if (!arg.startsWith("-")) {
+ int tail = args.length - i;
+ if (targetName != null && tail > 1) {
+ addError("msg.multiple.js.to.file", targetName);
+ return null;
+ }
+ String[] result = new String[tail];
+ for (int j = 0; j != tail; ++j) {
+ result[j] = args[i + j];
+ }
+ return result;
+ }
+ if (arg.equals("-help") || arg.equals("-h")
+ || arg.equals("--help"))
+ {
+ printHelp = true;
+ return null;
+ }
+
+ try {
+ if (arg.equals("-version") && ++i < args.length) {
+ int version = Integer.parseInt(args[i]);
+ compilerEnv.setLanguageVersion(version);
+ continue;
+ }
+ if ((arg.equals("-opt") || arg.equals("-O")) &&
+ ++i < args.length)
+ {
+ int optLevel = Integer.parseInt(args[i]);
+ compilerEnv.setOptimizationLevel(optLevel);
+ continue;
+ }
+ }
+ catch (NumberFormatException e) {
+ badUsage(args[i]);
+ return null;
+ }
+ if (arg.equals("-nosource")) {
+ compilerEnv.setGeneratingSource(false);
+ continue;
+ }
+ if (arg.equals("-debug") || arg.equals("-g")) {
+ compilerEnv.setGenerateDebugInfo(true);
+ continue;
+ }
+ if (arg.equals("-main-method-class") && ++i < args.length) {
+ compiler.setMainMethodClass(args[i]);
+ continue;
+ }
+ if (arg.equals("-o") && ++i < args.length) {
+ String name = args[i];
+ int end = name.length();
+ if (end == 0
+ || !Character.isJavaIdentifierStart(name.charAt(0)))
+ {
+ addError("msg.invalid.classfile.name", name);
+ continue;
+ }
+ for (int j = 1; j < end; j++) {
+ char c = name.charAt(j);
+ if (!Character.isJavaIdentifierPart(c)) {
+ if (c == '.') {
+ // check if it is the dot in .class
+ if (j == end - 6 && name.endsWith(".class")) {
+ name = name.substring(0, j);
+ break;
+ }
+ }
+ addError("msg.invalid.classfile.name", name);
+ break;
+ }
+ }
+ targetName = name;
+ continue;
+ }
+ if (arg.equals("-observe-instruction-count")) {
+ compilerEnv.setGenerateObserverCount(true);
+ }
+ if (arg.equals("-package") && ++i < args.length) {
+ String pkg = args[i];
+ int end = pkg.length();
+ for (int j = 0; j != end; ++j) {
+ char c = pkg.charAt(j);
+ if (Character.isJavaIdentifierStart(c)) {
+ for (++j; j != end; ++j) {
+ c = pkg.charAt(j);
+ if (!Character.isJavaIdentifierPart(c)) {
+ break;
+ }
+ }
+ if (j == end) {
+ break;
+ }
+ if (c == '.' && j != end - 1) {
+ continue;
+ }
+ }
+ addError("msg.package.name", targetPackage);
+ return null;
+ }
+ targetPackage = pkg;
+ continue;
+ }
+ if (arg.equals("-extends") && ++i < args.length) {
+ String targetExtends = args[i];
+ Class superClass;
+ try {
+ superClass = Class.forName(targetExtends);
+ } catch (ClassNotFoundException e) {
+ throw new Error(e.toString()); // TODO: better error
+ }
+ compiler.setTargetExtends(superClass);
+ continue;
+ }
+ if (arg.equals("-implements") && ++i < args.length) {
+ // TODO: allow for multiple comma-separated interfaces.
+ String targetImplements = args[i];
+ StringTokenizer st = new StringTokenizer(targetImplements,
+ ",");
+ Vector v = new Vector();
+ while (st.hasMoreTokens()) {
+ String className = st.nextToken();
+ try {
+ v.addElement(Class.forName(className));
+ } catch (ClassNotFoundException e) {
+ throw new Error(e.toString()); // TODO: better error
+ }
+ }
+ Class[] implementsClasses = new Class[v.size()];
+ v.copyInto(implementsClasses);
+ compiler.setTargetImplements(implementsClasses);
+ continue;
+ }
+ if (arg.equals("-d") && ++i < args.length) {
+ destinationDir = args[i];
+ continue;
+ }
+ badUsage(arg);
+ return null;
+ }
+ // no file name
+ p(ToolErrorReporter.getMessage("msg.no.file"));
+ return null;
+ }
+ /**
+ * Print a usage message.
+ */
+ private static void badUsage(String s) {
+ System.err.println(ToolErrorReporter.getMessage(
+ "msg.jsc.bad.usage", Main.class.getName(), s));
+ }
+
+ /**
+ * Compile JavaScript source.
+ *
+ */
+ public void processSource(String[] filenames)
+ {
+ for (int i = 0; i != filenames.length; ++i) {
+ String filename = filenames[i];
+ if (!filename.endsWith(".js")) {
+ addError("msg.extension.not.js", filename);
+ return;
+ }
+ File f = new File(filename);
+ String source = readSource(f);
+ if (source == null) return;
+
+ String mainClassName = targetName;
+ if (mainClassName == null) {
+ String name = f.getName();
+ String nojs = name.substring(0, name.length() - 3);
+ mainClassName = getClassName(nojs);
+ }
+ if (targetPackage.length() != 0) {
+ mainClassName = targetPackage+"."+mainClassName;
+ }
+
+ Object[] compiled
+ = compiler.compileToClassFiles(source, filename, 1,
+ mainClassName);
+ if (compiled == null || compiled.length == 0) {
+ return;
+ }
+
+ File targetTopDir = null;
+ if (destinationDir != null) {
+ targetTopDir = new File(destinationDir);
+ } else {
+ String parent = f.getParent();
+ if (parent != null) {
+ targetTopDir = new File(parent);
+ }
+ }
+ for (int j = 0; j != compiled.length; j += 2) {
+ String className = (String)compiled[j];
+ byte[] bytes = (byte[])compiled[j + 1];
+ File outfile = getOutputFile(targetTopDir, className);
+ try {
+ FileOutputStream os = new FileOutputStream(outfile);
+ try {
+ os.write(bytes);
+ } finally {
+ os.close();
+ }
+ } catch (IOException ioe) {
+ addFormatedError(ioe.toString());
+ }
+ }
+ }
+ }
+
+ private String readSource(File f)
+ {
+ if (!f.exists()) {
+ addError("msg.jsfile.not.found", f.getAbsolutePath());
+ return null;
+ }
+ try {
+ Reader in = new FileReader(f);
+ try {
+ return Kit.readReader(in);
+ } finally {
+ in.close();
+ }
+ } catch (FileNotFoundException ex) {
+ addError("msg.couldnt.open", f.getAbsolutePath());
+ } catch (IOException ioe) {
+ addFormatedError(ioe.toString());
+ }
+ return null;
+ }
+
+ private File getOutputFile(File parentDir, String className)
+ {
+ String path = className.replace('.', File.separatorChar);
+ path = path.concat(".class");
+ File f = new File(parentDir, path);
+ String dirPath = f.getParent();
+ if (dirPath != null) {
+ File dir = new File(dirPath);
+ if (!dir.exists()) {
+ dir.mkdirs();
+ }
+ }
+ return f;
+ }
+
+ /**
+ * Verify that class file names are legal Java identifiers. Substitute
+ * illegal characters with underscores, and prepend the name with an
+ * underscore if the file name does not begin with a JavaLetter.
+ */
+
+ String getClassName(String name) {
+ char[] s = new char[name.length()+1];
+ char c;
+ int j = 0;
+
+ if (!Character.isJavaIdentifierStart(name.charAt(0))) {
+ s[j++] = '_';
+ }
+ for (int i=0; i < name.length(); i++, j++) {
+ c = name.charAt(i);
+ if ( Character.isJavaIdentifierPart(c) ) {
+ s[j] = c;
+ } else {
+ s[j] = '_';
+ }
+ }
+ return (new String(s)).trim();
+ }
+
+ private static void p(String s) {
+ System.out.println(s);
+ }
+
+ private void addError(String messageId, String arg)
+ {
+ String msg;
+ if (arg == null) {
+ msg = ToolErrorReporter.getMessage(messageId);
+ } else {
+ msg = ToolErrorReporter.getMessage(messageId, arg);
+ }
+ addFormatedError(msg);
+ }
+
+ private void addFormatedError(String message)
+ {
+ reporter.error(message, null, -1, null, -1);
+ }
+
+ private boolean printHelp;
+ private ToolErrorReporter reporter;
+ private CompilerEnvirons compilerEnv;
+ private ClassCompiler compiler;
+ private String targetName;
+ private String targetPackage;
+ private String destinationDir;
+}
+