Implements an undocumented symbol-dumping feature.
Useful for third party tools that want to examine the AST of a GWT module textually.
Suggested by: danielvd
Review by: spoon
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@4945 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/Compiler.java b/dev/core/src/com/google/gwt/dev/Compiler.java
index ffac60d..be43d78 100644
--- a/dev/core/src/com/google/gwt/dev/Compiler.java
+++ b/dev/core/src/com/google/gwt/dev/Compiler.java
@@ -173,7 +173,8 @@
if (options.isValidateOnly()) {
if (!Precompile.validate(logger, options, module,
- options.getGenDir(), compilerWorkDir)) {
+ options.getGenDir(), compilerWorkDir,
+ options.getDumpSignatureFile())) {
return false;
}
} else {
@@ -182,7 +183,8 @@
+ moduleName);
Precompilation precompilation = Precompile.precompile(logger,
- options, module, options.getGenDir(), compilerWorkDir);
+ options, module, options.getGenDir(), compilerWorkDir,
+ options.getDumpSignatureFile());
if (precompilation == null) {
return false;
diff --git a/dev/core/src/com/google/gwt/dev/GWTCompiler.java b/dev/core/src/com/google/gwt/dev/GWTCompiler.java
index 5f9e30e..a2d8be7 100644
--- a/dev/core/src/com/google/gwt/dev/GWTCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/GWTCompiler.java
@@ -175,7 +175,8 @@
if (options.isValidateOnly()) {
if (!Precompile.validate(logger, options, module,
- options.getGenDir(), compilerWorkDir)) {
+ options.getGenDir(), compilerWorkDir,
+ options.getDumpSignatureFile())) {
return false;
}
} else {
@@ -184,7 +185,8 @@
+ moduleName);
Precompilation precompilation = Precompile.precompile(logger,
- options, module, options.getGenDir(), compilerWorkDir);
+ options, module, options.getGenDir(), compilerWorkDir,
+ options.getDumpSignatureFile());
if (precompilation == null) {
return false;
diff --git a/dev/core/src/com/google/gwt/dev/Precompile.java b/dev/core/src/com/google/gwt/dev/Precompile.java
index b477267..fb64d94 100644
--- a/dev/core/src/com/google/gwt/dev/Precompile.java
+++ b/dev/core/src/com/google/gwt/dev/Precompile.java
@@ -46,13 +46,15 @@
import com.google.gwt.dev.util.arg.ArgHandlerDisableAggressiveOptimization;
import com.google.gwt.dev.util.arg.ArgHandlerDisableClassMetadata;
import com.google.gwt.dev.util.arg.ArgHandlerDisableRunAsync;
-import com.google.gwt.dev.util.arg.ArgHandlerDraftCompile;
import com.google.gwt.dev.util.arg.ArgHandlerDisableUpdateCheck;
+import com.google.gwt.dev.util.arg.ArgHandlerDraftCompile;
+import com.google.gwt.dev.util.arg.ArgHandlerDumpSignatures;
import com.google.gwt.dev.util.arg.ArgHandlerEnableAssertions;
import com.google.gwt.dev.util.arg.ArgHandlerGenDir;
import com.google.gwt.dev.util.arg.ArgHandlerScriptStyle;
import com.google.gwt.dev.util.arg.ArgHandlerValidateOnlyFlag;
import com.google.gwt.dev.util.arg.OptionDisableUpdateCheck;
+import com.google.gwt.dev.util.arg.OptionDumpSignatures;
import com.google.gwt.dev.util.arg.OptionGenDir;
import com.google.gwt.dev.util.arg.OptionValidateOnly;
@@ -74,7 +76,8 @@
* The set of options for the precompiler.
*/
public interface PrecompileOptions extends JJSOptions, CompileTaskOptions,
- OptionGenDir, OptionValidateOnly, OptionDisableUpdateCheck {
+ OptionGenDir, OptionValidateOnly, OptionDisableUpdateCheck,
+ OptionDumpSignatures {
}
static class ArgProcessor extends CompileArgProcessor {
@@ -89,6 +92,7 @@
registerHandler(new ArgHandlerDisableRunAsync(options));
registerHandler(new ArgHandlerDraftCompile(options));
registerHandler(new ArgHandlerDisableUpdateCheck(options));
+ registerHandler(new ArgHandlerDumpSignatures(options));
}
@Override
@@ -100,6 +104,7 @@
static class PrecompileOptionsImpl extends CompileTaskOptionsImpl implements
PrecompileOptions {
private boolean disableUpdateCheck;
+ private File dumpFile;
private File genDir;
private final JJSOptionsImpl jjsOptions = new JJSOptionsImpl();
private boolean validateOnly;
@@ -117,10 +122,15 @@
jjsOptions.copyFrom(other);
setDisableUpdateCheck(other.isUpdateCheckDisabled());
+ setDumpSignatureFile(other.getDumpSignatureFile());
setGenDir(other.getGenDir());
setValidateOnly(other.isValidateOnly());
}
+ public File getDumpSignatureFile() {
+ return dumpFile;
+ }
+
public File getGenDir() {
return genDir;
}
@@ -177,6 +187,10 @@
jjsOptions.setDraftCompile(draft);
}
+ public void setDumpSignatureFile(File dumpFile) {
+ this.dumpFile = dumpFile;
+ }
+
public void setEnableAssertions(boolean enableAssertions) {
jjsOptions.setEnableAssertions(enableAssertions);
}
@@ -317,9 +331,14 @@
*/
public static Precompilation precompile(TreeLogger logger,
JJSOptions jjsOptions, ModuleDef module, File genDir,
- File generatorResourcesDir) {
+ File generatorResourcesDir, File dumpSignatureFile) {
try {
CompilationState compilationState = module.getCompilationState(logger);
+ if (dumpSignatureFile != null) {
+ // Dump early to avoid generated types.
+ SignatureDumper.dumpSignatures(logger, module.getTypeOracle(logger),
+ dumpSignatureFile);
+ }
String[] declEntryPts = module.getEntryPointTypeNames();
if (declEntryPts.length == 0) {
@@ -377,9 +396,15 @@
* @param generatorResourcesDir required directory to dump generator resources
*/
public static boolean validate(TreeLogger logger, JJSOptions jjsOptions,
- ModuleDef module, File genDir, File generatorResourcesDir) {
+ ModuleDef module, File genDir, File generatorResourcesDir,
+ File dumpSignatureFile) {
try {
CompilationState compilationState = module.getCompilationState(logger);
+ if (dumpSignatureFile != null) {
+ // Dump early to avoid generated types.
+ SignatureDumper.dumpSignatures(logger, module.getTypeOracle(logger),
+ dumpSignatureFile);
+ }
String[] declEntryPts = module.getEntryPointTypeNames();
String[] additionalRootTypes = null;
@@ -435,7 +460,7 @@
TreeLogger branch = logger.branch(TreeLogger.INFO,
"Validating compilation " + module.getName());
if (!validate(branch, options, module, options.getGenDir(),
- compilerWorkDir)) {
+ compilerWorkDir, options.getDumpSignatureFile())) {
branch.log(TreeLogger.ERROR, "Validation failed");
return false;
}
@@ -444,7 +469,8 @@
TreeLogger branch = logger.branch(TreeLogger.INFO,
"Precompiling module " + module.getName());
Precompilation precompilation = precompile(branch, options, module,
- options.getGenDir(), compilerWorkDir);
+ options.getGenDir(), compilerWorkDir,
+ options.getDumpSignatureFile());
if (precompilation == null) {
branch.log(TreeLogger.ERROR, "Precompilation failed");
return false;
diff --git a/dev/core/src/com/google/gwt/dev/SignatureDumper.java b/dev/core/src/com/google/gwt/dev/SignatureDumper.java
new file mode 100644
index 0000000..51164db
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/SignatureDumper.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.typeinfo.JAbstractMethod;
+import com.google.gwt.core.ext.typeinfo.JClassType;
+import com.google.gwt.core.ext.typeinfo.JConstructor;
+import com.google.gwt.core.ext.typeinfo.JField;
+import com.google.gwt.core.ext.typeinfo.JMethod;
+import com.google.gwt.core.ext.typeinfo.JParameter;
+import com.google.gwt.core.ext.typeinfo.TypeOracle;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+class SignatureDumper {
+
+ public static void dumpSignatures(TreeLogger logger, TypeOracle typeOracle,
+ File outFile) {
+ try {
+ PrintWriter out = new PrintWriter(new FileWriter(outFile));
+ out.println("# Contains all signatures dumped from the GWT compiler");
+ out.println("FileVersion 1");
+ out.println("GwtVersion " + About.GWT_VERSION_NUM);
+ out.print(dumpAllSignatures(typeOracle));
+ out.close();
+ logger.log(TreeLogger.INFO, "Signatures dumped into " + outFile, null);
+ } catch (IOException ex) {
+ logger.log(TreeLogger.ERROR, "Could not dump signatures: IOError", null);
+ }
+ }
+
+ private static void addMethods(JAbstractMethod[] methods, StringBuilder result) {
+ for (JAbstractMethod currentMeth : methods) {
+ if (currentMeth.isConstructor() != null) {
+ result.append(" method <init>");
+ } else if (currentMeth.isMethod() != null) {
+ result.append(" method ");
+ if (currentMeth.isMethod().isStatic()) {
+ result.append("static ");
+ }
+ result.append(currentMeth.getName());
+ } else {
+ continue;
+ }
+ result.append(" (");
+ for (JParameter currentParam : currentMeth.getParameters()) {
+ result.append(currentParam.getType().getJNISignature());
+ }
+ result.append(')');
+ if (currentMeth.isConstructor() != null) {
+ result.append('V');
+ } else {
+ result.append(((JMethod) currentMeth).getReturnType().getJNISignature());
+ }
+ result.append('\n');
+ }
+ }
+
+ /**
+ * Dumps the signatures within this typeOracle. Singatures may appear multiple
+ * times.
+ */
+ private static String dumpAllSignatures(TypeOracle typeOracle) {
+ StringBuilder result = new StringBuilder();
+ for (JClassType current : typeOracle.getTypes()) {
+ if (current.isInterface() != null) {
+ result.append("interface ");
+ } else {
+ result.append("class ");
+ }
+ result.append(current.getJNISignature());
+ if (current.getSuperclass() != null) {
+ result.append(" extends ");
+ result.append(current.getSuperclass().getJNISignature());
+ }
+ for (JClassType currentInterface : current.getImplementedInterfaces()) {
+ result.append(" implements ");
+ result.append(currentInterface.getJNISignature());
+ }
+ result.append('\n');
+
+ result.append(" method static <clinit> ()V\n");
+ JConstructor[] constructors = current.getConstructors();
+ if (constructors.length == 0) {
+ result.append(" method <init> ()V\n");
+ } else {
+ addMethods(constructors, result);
+ }
+ addMethods(current.getMethods(), result);
+ for (JField currentField : current.getFields()) {
+ result.append(" field ");
+ if (currentField.isStatic()) {
+ result.append("static ");
+ }
+ result.append(currentField.getName());
+ result.append(' ');
+ result.append(currentField.getType().getJNISignature());
+ result.append('\n');
+ }
+ }
+ return result.toString();
+ }
+
+}
diff --git a/dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerDumpSignatures.java b/dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerDumpSignatures.java
new file mode 100644
index 0000000..620db3b
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerDumpSignatures.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.util.arg;
+
+import com.google.gwt.util.tools.ArgHandlerFile;
+
+import java.io.File;
+
+/**
+ * Argument handler for processing the script style flag.
+ */
+public final class ArgHandlerDumpSignatures extends ArgHandlerFile {
+
+ private final OptionDumpSignatures option;
+
+ public ArgHandlerDumpSignatures(OptionDumpSignatures option) {
+ this.option = option;
+ }
+
+ public String getPurpose() {
+ return "Dump the singatures all loaded types and their members";
+ }
+
+ public String getTag() {
+ return "-dumpSignatures";
+ }
+
+ public String[] getTagArgs() {
+ return new String[] {"style"};
+ }
+
+ @Override
+ public boolean isUndocumented() {
+ return true;
+ }
+
+ @Override
+ public void setFile(File file) {
+ option.setDumpSignatureFile(file);
+ }
+}
\ No newline at end of file
diff --git a/dev/core/src/com/google/gwt/dev/util/arg/OptionDumpSignatures.java b/dev/core/src/com/google/gwt/dev/util/arg/OptionDumpSignatures.java
new file mode 100644
index 0000000..3d9b9ff
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/util/arg/OptionDumpSignatures.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.dev.util.arg;
+
+import java.io.File;
+
+/**
+ * Option to set the output directory.
+ */
+public interface OptionDumpSignatures {
+
+ /**
+ * Returns the signature dump file.
+ */
+ File getDumpSignatureFile();
+
+ /**
+ * Sets the signature dump file.
+ */
+ void setDumpSignatureFile(File dumpFile);
+}
diff --git a/dev/core/src/com/google/gwt/util/tools/ArgHandlerFile.java b/dev/core/src/com/google/gwt/util/tools/ArgHandlerFile.java
new file mode 100644
index 0000000..7aad819
--- /dev/null
+++ b/dev/core/src/com/google/gwt/util/tools/ArgHandlerFile.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2006 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.util.tools;
+
+import java.io.File;
+
+/**
+ * Argument handler for arguments that are directories.
+ */
+public abstract class ArgHandlerFile extends ArgHandler {
+
+ public String[] getDefaultArgs() {
+ return null;
+ }
+
+ public abstract String getPurpose();
+
+ public abstract String getTag();
+
+ public String[] getTagArgs() {
+ return new String[]{"file"};
+ }
+
+ public int handle(String[] args, int startIndex) {
+ if (startIndex + 1 < args.length) {
+ setFile(new File(args[startIndex + 1]));
+ return 1;
+ }
+
+ System.err.println(getTag()
+ + " should be followed by the name of a file");
+ return -1;
+ }
+
+ public abstract void setFile(File file);
+
+}