Add uncommited generation checking to all the gen tasks.

If checking="true" on them, they generate their code to a String instead of a file, and compare that
against existing output.  If any generation would produce changes, the build is failed.

As a side effect, generation will now only write files if it's going to modify them, which should
eliminate some spurious compiling.



git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6349 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Charlie Groves
2010-12-09 07:43:18 +00:00
parent 0b77c89fa7
commit 39405136e9
19 changed files with 190 additions and 169 deletions
+19 -16
View File
@@ -47,6 +47,8 @@
</target>
<target name="-preptools" depends="-prepare">
<!-- Turn off generation checking if enablegencheck hasn't already set this property -->
<property name="gencheck" value="false"/>
<javac srcdir="${src.dir}" destdir="${classes.dir}" includeAntRuntime="false"
debug="on" optimize="${build.optimize}" deprecation="on"
source="1.5" target="1.5" classpathref="compile.classpath">
@@ -214,6 +216,15 @@
</grecord>
</target>
<target name="enablegencheck"
description="Makes the code generators fail the build if they would produce new code">
<property name="gencheck" value="true"/>
</target>
<target name="gencheck" depends="enablegencheck,gencode"
description="Fails the build if any new code would be generated"/>
<target name="gencode" depends="gendobj,genservice,genreceiver,genstream"
description="Runs all code generators"/>
<target name="gendobj" depends="-preptools"
description="Generates additional methods for distributed object classes">
<!-- make sure the dobject class files are all compiled -->
@@ -223,7 +234,7 @@
<include name="**/*Object.java"/>
</javac>
<!-- now generate the associated files -->
<gendobj classpathref="built.classpath">
<gendobj classpathref="built.classpath" checking="${gencheck}">
<fileset dir="${src.dir}" includes="**/*Object.java"/>
</gendobj>
</target>
@@ -238,7 +249,8 @@
<exclude name="**/InvocationService.java"/>
</javac>
<!-- generate services with an actionscript counterpart-->
<genservice header="lib/SOURCE_HEADER" asroot="${asrc.dir}" classpathref="built.classpath">
<genservice header="lib/SOURCE_HEADER" asroot="${asrc.dir}" classpathref="built.classpath"
checking="${gencheck}">
<fileset dir="${src.dir}" includes="**/*Service.java">
<exclude name="**/RegistrationService.java"/>
<exclude name="**/InvocationService.java"/>
@@ -250,8 +262,7 @@
<providerless service="TimeBaseService"/>
</genservice>
<!-- generate java-only services -->
<genservice header="lib/SOURCE_HEADER" classpathref="built.classpath">
<fileset dir="${src.dir}" includes="**/RegistrationService.java"/>
<genservice header="lib/SOURCE_HEADER" classpathref="built.classpath" checking="${gencheck}">
<fileset dir="${src.dir}" includes="**/peer/**/*Service.java"/>
<fileset dir="${src.dir}" includes="**/admin/**/*Service.java"
excludes="**/gwt/ConfigService.java"/>
@@ -271,17 +282,16 @@
<exclude name="**/InvocationReceiver.java"/>
</javac>
<!-- now generate the associated files -->
<genreceiver header="lib/SOURCE_HEADER" classpathref="built.classpath">
<genreceiver header="lib/SOURCE_HEADER" classpathref="built.classpath" checking="${gencheck}">
<fileset dir="${src.dir}" includes="**/*Receiver.java"
excludes="**/InvocationReceiver.java"/>
excludes="**/InvocationReceiver.java,**/SignalReceiver.java"/>
</genreceiver>
</target>
<target name="genstream" depends="-preptools" description="Generates C++ streamable classes.">
<gencppstreamable classpathref="built.classpath" cpproot="src/cpp">
<gencppstreamable classpathref="built.classpath" cpproot="src/cpp" checking="${gencheck}">
<generate class="com.threerings.presents.client.InvocationReceiver$Registration"/>
<generate class="com.threerings.presents.data.ClientObject"/>
<generate class="com.threerings.presents.data.PermissionPolicy"/>
<generate class="com.threerings.presents.dobj.DEvent"/>
<generate class="com.threerings.presents.dobj.DObject"/>
<generate class="com.threerings.presents.dobj.EntryAddedEvent"/>
@@ -320,13 +330,6 @@
</instream>
</target>
<target name="genascript" depends="-preptools"
description="Generates ActionScript versions of our Streamable classes">
<genascript header="lib/SOURCE_HEADER" asroot="${asrc.dir}">
<fileset dir="${src.dir}" includes="**/data/*.java"/>
</genascript>
</target>
<target name="snapshot" description="Creates a zipfile with our source distribution">
<delete file="${deploy.dir}/${ant.project.name}-snapshot.zip"/>
<mkdir dir="${deploy.dir}/snapshot/${ant.project.name}"/>
@@ -349,7 +352,7 @@
</target>
<property name="maven.deploy.repo" value="file://${user.home}/.m2/repository"/>
<target name="maven-deploy" depends="dist,tests"
<target name="maven-deploy" depends="dist,tests"
description="Deploys our build artifacts to a Maven repository.">
<artifact:deploy file="${deploy.dir}/${ant.project.name}.jar" uniqueVersion="false">
<remoteRepository url="${maven.deploy.repo}"/>
-2
View File
@@ -10,7 +10,6 @@ void ClientObject::readObject (ObjectInputStream& in)
presents::dobj::DObject::readObject(in);
username = boost::static_pointer_cast<util::Name>(in.readObject());
receivers = boost::static_pointer_cast<presents::dobj::DSet>(in.readObject());
permPolicy = boost::static_pointer_cast<presents::data::PermissionPolicy>(in.readObject());
}
void ClientObject::writeObject (ObjectOutputStream& out) const
@@ -18,5 +17,4 @@ void ClientObject::writeObject (ObjectOutputStream& out) const
presents::dobj::DObject::writeObject(out);
out.writeObject(username);
out.writeObject(receivers);
out.writeObject(permPolicy);
}
-2
View File
@@ -5,7 +5,6 @@
#include "presents/ObjectOutputStream.h"
#include "presents/streamers/StreamableStreamer.h"
#include "presents/data/PermissionPolicy.h"
#include "presents/dobj/DObject.h"
#include "presents/dobj/DSet.h"
#include "util/Name.h"
@@ -18,7 +17,6 @@ public:
Shared<util::Name> username;
Shared<presents::dobj::DSet> receivers;
Shared<presents::data::PermissionPolicy> permPolicy;
virtual void readObject(ObjectInputStream& in);
virtual void writeObject(ObjectOutputStream& out) const;
@@ -120,7 +120,7 @@ public abstract class ConfigFieldEditor
resetField();
_box.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
public void onValueChange (ValueChangeEvent<Boolean> changeEvent) {
public void onValueChange (ValueChangeEvent<Boolean> changeEvent) {
updateModificationState();
}
});
@@ -152,11 +152,11 @@ public abstract class ConfigFieldEditor
_value = buildWidget(field);
_name = new Label(field.name);
_name.setStyleName("fieldName");
_name.setStyleName("fieldName");
_reset = new Label("X");
_reset.setStyleName("resetButton");
_reset.addClickHandler(new ClickHandler() {
_reset.setStyleName("resetButton");
_reset.addClickHandler(new ClickHandler() {
public void onClick (ClickEvent event) {
resetField();
updateModificationState();
@@ -203,5 +203,5 @@ public abstract class ConfigFieldEditor
protected Command _onChange;
protected Label _name, _reset;
protected Widget _value;
protected Widget _value;
}
@@ -91,7 +91,7 @@ public abstract class ConfigServlet extends RemoteServiceServlet
public ConfigurationRecord updateConfiguration (final String key, final ConfigField[] updates)
throws ServiceException
{
requireAdminUser();
requireAdminUser();
final ServletWaiter<ConfigurationRecord> waiter =
new ServletWaiter<ConfigurationRecord>("updateConfiguration");
@@ -156,11 +156,11 @@ public abstract class ConfigServlet extends RemoteServiceServlet
* Implemented on a project by project basis to provide a security fence for configuration
* editing powers.
*/
protected abstract void requireAdminUser ()
throws ServiceException;
protected abstract void requireAdminUser ()
throws ServiceException;
@Inject protected ConfigRegistry _confReg;
@Inject protected RootDObjectManager _omgr;
@Inject protected RootDObjectManager _omgr;
protected static Map<Class<?>, FieldType> TYPES = ImmutableMap.<Class<?>, FieldType>builder()
.put(Integer.class, FieldType.INTEGER)
@@ -21,11 +21,10 @@
package com.threerings.bureau.server;
import com.threerings.presents.data.ClientObject;
import com.threerings.presents.server.InvocationSender;
import com.threerings.bureau.client.BureauDecoder;
import com.threerings.bureau.client.BureauReceiver;
import com.threerings.presents.data.ClientObject;
import com.threerings.presents.server.InvocationSender;
/**
* Used to issue notifications to a {@link BureauReceiver} instance on a
@@ -21,11 +21,10 @@
package com.threerings.crowd.server;
import com.threerings.presents.data.ClientObject;
import com.threerings.presents.server.InvocationSender;
import com.threerings.crowd.client.LocationDecoder;
import com.threerings.crowd.client.LocationReceiver;
import com.threerings.presents.data.ClientObject;
import com.threerings.presents.server.InvocationSender;
/**
* Used to issue notifications to a {@link LocationReceiver} instance on a
@@ -34,7 +34,6 @@ import org.apache.tools.ant.Project;
import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.io.Files;
@@ -113,12 +112,8 @@ public class GenActionScriptStreamableTask extends GenTask
// Merge in the previously generated version
String existing = Files.toString(outputLocation, Charsets.UTF_8);
output = new GeneratedSourceMerger().merge(output, existing);
} else if (!outputLocation.getParentFile().exists()) {
// Make sure the directory exists before trying to write there
Preconditions.checkArgument(outputLocation.getParentFile().mkdirs(),
"Unable to create directory to write '%s'", outputLocation.getAbsolutePath());
}
Files.write(output, outputLocation, Charsets.UTF_8);
writeFile(outputLocation.getAbsolutePath(), output);
}
protected static class ASField
@@ -21,20 +21,17 @@
package com.threerings.presents.tools;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.io.File;
import com.google.common.collect.Lists;
import com.samskivert.util.StringUtil;
import com.threerings.presents.annotation.TransportHint;
import com.threerings.presents.dobj.DObject;
import com.threerings.presents.dobj.DSet;
@@ -165,7 +162,7 @@ public class GenDObjectTask extends GenTask
}
// now bolt everything back together into a class declaration
sfile.writeTo(source, fsection.toString(), msection.toString());
writeFile(source.getAbsolutePath(), sfile.generate(fsection.toString(), msection.toString()));
}
/** {@link DObject} resolved with the proper classloader so that we
@@ -114,11 +114,11 @@ public class GenReceiverTask extends InvocationTask
String mpath = source.getPath();
mpath = mpath.replace("Receiver", "Sender");
mpath = replacePath(mpath, "/client/", "/server/");
writeFile(mpath, mergeTemplate(SENDER_TMPL,
"name", name,
"package", spackage,
"methods", methods,
"imports", implist));
writeTemplate(SENDER_TMPL, mpath,
"name", name,
"package", spackage,
"methods", methods,
"imports", implist);
}
protected void generateDecoder (Class<?> receiver, File source, String rname, String rpackage,
@@ -136,12 +136,12 @@ public class GenReceiverTask extends InvocationTask
// determine the path to our sender file
String mpath = source.getPath();
mpath = mpath.replace("Receiver", "Decoder");
writeFile(mpath, mergeTemplate(DECODER_TMPL,
"name", name,
"receiver_code", rcode,
"package", rpackage,
"methods", methods,
"imports", implist));
writeTemplate(DECODER_TMPL, mpath,
"name", name,
"receiver_code", rcode,
"package", rpackage,
"methods", methods,
"imports", implist);
}
/** Specifies the path to the sender template. */
@@ -180,6 +180,14 @@ public class GenServiceTask extends InvocationTask
}
}
/**
* Configures to output extra information when generating code.
*/
public void setVerbose (boolean verbose)
{
_verbose = verbose;
}
/**
* Configures the path to our ActionScript source files.
*/
@@ -280,7 +288,7 @@ public class GenServiceTask extends InvocationTask
String mpath = source.getPath();
mpath = mpath.replace("Service", "Marshaller");
mpath = replacePath(mpath, "/client/", "/data/");
writeFile(mpath, mergeTemplate(MARSHALLER_TMPL, ctx));
writeTemplate(MARSHALLER_TMPL, mpath, ctx);
// if we're not configured with an ActionScript source root, don't generate the
// ActionScript versions
@@ -350,7 +358,7 @@ public class GenServiceTask extends InvocationTask
// generate an ActionScript version of our marshaller
String ampath = _asroot + File.separator + mppath + File.separator + mname + ".as";
writeFile(ampath, mergeTemplate(AS_MARSHALLER_TMPL, ctx));
writeTemplate(AS_MARSHALLER_TMPL, ampath, ctx);
// ----------- Part III - as listener marshallers
@@ -387,7 +395,7 @@ public class GenServiceTask extends InvocationTask
ctx.put("listener", listener);
String aslpath = _asroot + File.separator + mppath +
File.separator + mname + "_" + listener.getListenerName() + "Marshaller.as";
writeFile(aslpath, mergeTemplate(AS_LISTENER_MARSHALLER_TMPL, ctx));
writeTemplate(AS_LISTENER_MARSHALLER_TMPL, aslpath, ctx);
}
// ----------- Part IV - as service
@@ -434,7 +442,7 @@ public class GenServiceTask extends InvocationTask
// generate an ActionScript version of our service
String aspath = _asroot + File.separator + sppath + File.separator + sname + ".as";
writeFile(aspath, mergeTemplate(AS_SERVICE_TMPL, ctx));
writeTemplate(AS_SERVICE_TMPL, aspath, ctx);
// ----------- Part V - as service listeners
Class<?> isil = InvocationService.InvocationListener.class;
@@ -471,12 +479,12 @@ public class GenServiceTask extends InvocationTask
String aslpath = _asroot + File.separator + sppath + File.separator +
sname + "_" + listener.getListenerName() + "Listener.as";
writeFile(aslpath, mergeTemplate(AS_LISTENER_SERVICE_TMPL, ctx));
writeTemplate(AS_LISTENER_SERVICE_TMPL, aslpath, ctx);
if (_aslistenerAdapters.contains(sname)) {
String aslapath = _asroot + File.separator + sppath + File.separator +
sname + "_" + listener.getListenerName() + "ListenerAdapter.as";
writeFile(aslapath, mergeTemplate(AS_LISTENER_ADAPTER_SERVICE_TMPL, ctx));
writeTemplate(AS_LISTENER_ADAPTER_SERVICE_TMPL, aslapath, ctx);
}
}
}
@@ -531,12 +539,12 @@ public class GenServiceTask extends InvocationTask
String mpath = source.getPath();
mpath = mpath.replace("Service", "Dispatcher");
mpath = replacePath(mpath, "/client/", "/server/");
writeFile(mpath, mergeTemplate(DISPATCHER_TMPL,
"name", name,
"generated", getGeneratedAnnotation(name),
"package", dpackage,
"methods", sdesc.methods,
"imports", imports.toList()));
writeTemplate(DISPATCHER_TMPL, mpath,
"name", name,
"generated", getGeneratedAnnotation(name),
"package", dpackage,
"methods", sdesc.methods,
"imports", imports.toList());
}
protected void generateProvider (File source, ServiceDescription sdesc)
@@ -584,13 +592,13 @@ public class GenServiceTask extends InvocationTask
String mpath = source.getPath();
mpath = mpath.replace("Service", "Provider");
mpath = replacePath(mpath, "/client/", "/server/");
writeFile(mpath, mergeTemplate(PROVIDER_TMPL,
"name", name,
"generated", getGeneratedAnnotation(name),
"package", mpackage,
"methods", sdesc.methods,
"listeners", sdesc.listeners,
"imports", imports.toList()));
writeTemplate(PROVIDER_TMPL, mpath,
"name", name,
"generated", getGeneratedAnnotation(name),
"package", mpackage,
"methods", sdesc.methods,
"listeners", sdesc.listeners,
"imports", imports.toList());
}
/**
@@ -677,6 +685,9 @@ public class GenServiceTask extends InvocationTask
}
}
/** Show extra output if set. */
protected boolean _verbose;
/** The path to our ActionScript source files. */
protected File _asroot;
@@ -28,7 +28,6 @@ import java.io.File;
import java.io.IOException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.FileSet;
import com.google.common.collect.Lists;
@@ -42,13 +41,14 @@ import com.threerings.presents.dobj.DObject;
* Streamable} classes that have protected or private members so that they can be used in a
* sandboxed environment.
*/
public class GenStreamableTask extends Task
public class GenStreamableTask extends GenTask
{
/**
* Adds a nested &lt;fileset&gt; element which enumerates streamable source files.
* Adds a nested &lt;fileset&gt; element which enumerates streamable source
* files.
*/
public void addFileset (FileSet set)
{
@Override
public void addFileset(FileSet set) {
_filesets.add(set);
}
@@ -98,6 +98,7 @@ public class GenStreamableTask extends Task
/**
* Processes a resolved {@link Streamable} class instance.
*/
@Override
protected void processClass (File source, Class<?> sclass)
throws IOException
{
@@ -156,11 +157,7 @@ public class GenStreamableTask extends Task
System.err.println("Converting " + sclass.getName() + "...");
try {
sfile.writeTo(source, null, methods.toString());
} catch (IOException ioe) {
System.err.println("Error writing " + source + ": " + ioe);
}
writeFile(source.getAbsolutePath(), sfile.generate(null, methods.toString()));
}
protected String toReadObject (Field field)
@@ -21,28 +21,35 @@
package com.threerings.presents.tools;
import java.util.List;
import java.util.Map;
import static com.google.common.base.Charsets.UTF_8;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.tools.ant.AntClassLoader;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Reference;
import org.apache.tools.ant.util.ClasspathUtils;
import com.google.common.collect.Maps;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.io.Files;
import com.samskivert.io.StreamUtil;
import com.samskivert.mustache.Mustache;
public abstract class GenTask extends Task
{
/**
@@ -53,14 +60,6 @@ public abstract class GenTask extends Task
_filesets.add(set);
}
/**
* Configures to output extra information when generating code.
*/
public void setVerbose (boolean verbose)
{
_verbose = verbose;
}
/**
* Configures us with a header file that we'll prepend to all
* generated source files.
@@ -86,12 +85,24 @@ public abstract class GenTask extends Task
((AntClassLoader)_cloader).setParent(getClass().getClassLoader());
}
/**
* Fails the build if generation would change files rather than generating
* code.
*/
public void setChecking (boolean checking)
{
_checking = checking;
}
/**
* Performs the actual work of the task.
*/
@Override
public void execute ()
{
if (_checking) {
log("Only checking if generation would change files", Project.MSG_VERBOSE);
}
for (FileSet fs : _filesets) {
DirectoryScanner ds = fs.getDirectoryScanner(getProject());
File fromDir = fs.getDir(getProject());
@@ -105,6 +116,47 @@ public abstract class GenTask extends Task
}
}
}
if (_checking && !_modifiedPaths.isEmpty()) {
throw new BuildException("Generation would produce changes!");
}
}
protected void writeTemplate (String templatePath, String outputPath, Object... data)
throws IOException
{
writeTemplate(templatePath, outputPath, createMap(data));
}
protected void writeTemplate (String templatePath, String outputPath, Map<String, Object> data)
throws IOException
{
String output = mergeTemplate(templatePath, data);
if (_header != null) {
output = _header + output;
}
writeFile(outputPath, output);
}
protected void writeFile (String outputPath, String output) throws IOException
{
File dest = new File(outputPath);
if (dest.exists()) {
if (Files.toString(dest, UTF_8).equals(output)) {
log("Skipping '" + outputPath + "' as it hasn't changed", Project.MSG_VERBOSE);
return;
}
} else if (!dest.getParentFile().exists() && !dest.getParentFile().mkdirs()) {
throw new BuildException("Unable to create directory for '" + dest.getAbsolutePath() + "'");
}
_modifiedPaths.add(outputPath);
if (_checking) {
log("Generating '" + outputPath + "' would have produced changes!", Project.MSG_ERR);
return;
}
log("Writing file " + outputPath, Project.MSG_VERBOSE);
new PrintWriter(dest, "UTF-8").append(output).close();
}
/**
@@ -114,13 +166,9 @@ public abstract class GenTask extends Task
* be any object.
*/
protected String mergeTemplate (String template, Object... data)
throws Exception
throws IOException
{
Map<String, Object> ctx = Maps.newHashMap();
for (int ii = 0; ii < data.length; ii += 2) {
ctx.put((String)data[ii], data[ii+1]);
}
return mergeTemplate(template, ctx);
return mergeTemplate(template, createMap(data));
}
/**
@@ -129,10 +177,20 @@ public abstract class GenTask extends Task
* @return a string containing the merged text.
*/
protected String mergeTemplate (String template, Map<String, Object> data)
throws Exception
throws IOException
{
return Mustache.compiler().escapeHTML(false).compile(new InputStreamReader(
getClass().getClassLoader().getResourceAsStream(template), "UTF-8")).execute(data);
Reader reader =
new InputStreamReader(getClass().getClassLoader().getResourceAsStream(template), UTF_8);
return Mustache.compiler().escapeHTML(false).compile(reader).execute(data);
}
protected Map<String, Object> createMap (Object... data)
{
Map<String, Object> ctx = Maps.newHashMap();
for (int ii = 0; ii < data.length; ii += 2) {
ctx.put((String)data[ii], data[ii+1]);
}
return ctx;
}
/**
@@ -172,12 +230,12 @@ public abstract class GenTask extends Task
/** A list of filesets that contain java source to be processed. */
protected List<FileSet> _filesets = Lists.newArrayList();
/** Show extra output if set. */
protected boolean _verbose;
/** Used to do our own classpath business. */
protected ClassLoader _cloader;
/** A header to put on all generated source files. */
protected String _header;
protected boolean _checking;
protected Set<String> _modifiedPaths = Sets.newHashSet();
}
@@ -31,10 +31,6 @@ import java.util.Arrays;
import java.util.List;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import org.apache.tools.ant.BuildException;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
@@ -395,22 +391,6 @@ public abstract class InvocationTask extends GenTask
super.execute();
}
protected void writeFile (String path, String data)
throws IOException
{
if (_verbose) {
System.out.println("Writing file " + path);
}
if (_header != null) {
data = _header + data;
}
File dest = new File(path);
if (!dest.getParentFile().exists() && !dest.getParentFile().mkdirs()) {
throw new BuildException("Unable to create directory for " + dest.getAbsolutePath());
}
new PrintWriter(dest, "UTF-8").append(data).close();
}
protected static <T> void checkedAdd (List<T> list, T value)
{
if (!list.contains(value)) {
@@ -27,8 +27,8 @@ import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import com.google.common.collect.Lists;
@@ -129,11 +129,11 @@ public class SourceFile
* @param fsection the new "generated fields" to write to the file, or null.
* @param msection the new "generated methods" to write to the file, or null.
*/
public void writeTo (File dest, String fsection, String msection)
public String generate (String fsection, String msection)
throws IOException
{
BufferedWriter bout = new BufferedWriter(new FileWriter(dest));
StringWriter writer = new StringWriter();
BufferedWriter bout = new BufferedWriter(writer);
addOrRemoveGeneratedImport(StringUtil.deNull(fsection).contains("@Generated(") ||
StringUtil.deNull(msection).contains("@Generated("));
@@ -180,6 +180,7 @@ public class SourceFile
writeln(bout, _lines.get(ii));
}
bout.close();
return writer.toString();
}
/** Helper function for sanity checking marker existence. */
@@ -6,19 +6,10 @@ import java.lang.reflect.TypeVariable;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.google.common.io.Resources;
import com.samskivert.mustache.Mustache;
import com.threerings.presents.dobj.DSet;
public class CPPUtil
@@ -70,19 +61,6 @@ public class CPPUtil
}
}
public static void writeTemplate (String tmplPath, File root, String path,
Map<String, Object> ctx)
throws IOException
{
String tmpl =
Resources.toString(Resources.getResource(tmplPath), Charsets.UTF_8);
File file = new File(root, path);
file.getParentFile().mkdirs();
BufferedWriter out = new BufferedWriter(new FileWriter(file));
Mustache.compiler().escapeHTML(false).compile(tmpl).execute(ctx, out);
out.close();
}
public static String makeCPPName (Class<?> sclass)
{
return makeCPPName(makeNamespaces(sclass), sclass.getSimpleName());
@@ -103,6 +81,17 @@ public class CPPUtil
return Joiner.on(File.separator).join(namespaces) + File.separator + className+ ext;
}
public static String makePath (File root, Class<?> klass, String ext)
{
return new File(root, makePath(klass, ext)).getAbsolutePath();
}
public static String makePath (File root, List<String> namespaces, String className, String ext)
{
return new File(root, makePath(namespaces, className, ext)).getAbsolutePath();
}
public static List<String> makeNamespaces (String pack)
{
Iterable<String> split = Splitter.on(".").split(pack);
@@ -1,5 +1,7 @@
package com.threerings.presents.tools.cpp;
import static com.threerings.presents.tools.cpp.CPPUtil.makePath;
import java.lang.reflect.Type;
import java.util.Iterator;
@@ -39,8 +41,7 @@ public class GenCPPReceiverTask extends GenReceiverTask
ctx.put("receiverCode", rcode);
ctx.put("argbuilder", new CPPArgBuilder(false));
CPPUtil.writeTemplate(DECODER_HEADER_TMPL, _cpproot,
CPPUtil.makePath(namespaces, dname, ".h"), ctx);
writeTemplate(DECODER_HEADER_TMPL, makePath(_cpproot, namespaces, dname, ".h"), ctx);
Set<String> receiverHeaderIncludes = Sets.newTreeSet();
Set<String> decoderImplIncludes = Sets.newTreeSet();
@@ -60,13 +61,9 @@ public class GenCPPReceiverTask extends GenReceiverTask
}
ctx.put("includes", decoderImplIncludes);
CPPUtil.writeTemplate(DECODER_CPP_TMPL, _cpproot,
CPPUtil.makePath(namespaces, dname, ".cpp"), ctx);
writeTemplate(DECODER_CPP_TMPL, makePath(_cpproot, namespaces, dname, ".cpp"), ctx);
ctx.put("includes", receiverHeaderIncludes);
CPPUtil.writeTemplate(RECEIVER_HEADER_TMPL, _cpproot,
CPPUtil.makePath(namespaces, rname, ".h"), ctx);
writeTemplate(RECEIVER_HEADER_TMPL, makePath(_cpproot, namespaces, rname, ".h"), ctx);
super.generateDecoder(receiver, source, rname, rpackage, methods, imports, rcode);
}
@@ -15,7 +15,6 @@ import com.threerings.presents.tools.GenServiceTask;
import static com.threerings.presents.tools.cpp.CPPUtil.makeNamespaces;
import static com.threerings.presents.tools.cpp.CPPUtil.makePath;
import static com.threerings.presents.tools.cpp.CPPUtil.writeTemplate;
public class GenCPPServiceTask extends GenServiceTask
{
@@ -58,9 +57,9 @@ public class GenCPPServiceTask extends GenServiceTask
}
}
ctx.put("includes", implIncludes);
writeTemplate(CPP_TMPL, _cpproot, makePath(namespaces, name, ".cpp"), ctx);
writeTemplate(CPP_TMPL, makePath(_cpproot, namespaces, name, ".cpp"), ctx);
ctx.put("includes", includes);
writeTemplate(HEADER_TMPL, _cpproot, makePath(namespaces, name, ".h"), ctx);
writeTemplate(HEADER_TMPL, makePath(_cpproot, namespaces, name, ".h"), ctx);
super.generateMarshaller(source, sdesc);
}
@@ -134,10 +134,10 @@ public class GenCPPStreamableTask extends GenTask
// now write all that out to the target source file
ctx.put("includes", headerIncludes);
CPPUtil.writeTemplate(HEADER_TMPL, _cpproot, makePath(sclass, ".h"), ctx);
writeTemplate(HEADER_TMPL, makePath(_cpproot, sclass, ".h"), ctx);
ctx.put("includes", implIncludes);
CPPUtil.writeTemplate(CPP_TMPL, _cpproot, makePath(sclass, ".cpp"), ctx);
writeTemplate(CPP_TMPL, makePath(_cpproot, sclass, ".cpp"), ctx);
}
protected static void addInclude (Class<?> ftype, Set<String> includes)