/* * This file is part of the X10 project (http://x10-lang.org). * * This file is licensed to You under the Eclipse Public License (EPL); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.opensource.org/licenses/eclipse-1.0.php * * (C) Copyright IBM Corporation 2006-2010. */ package x10.util; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; import java.util.Vector; import polyglot.ast.SourceFile; import polyglot.frontend.Job; import polyglot.frontend.TargetFactory; import polyglot.util.SimpleCodeWriter; import polyglot.util.CollectionUtil; import x10.util.CollectionFactory; import x10cpp.visit.X10CPPTranslator; /** * This class represents a collection of output streams. Each stream has an associated * type, specified by the extension string. * Operations are provided to create a new stream of a given type (see getNewStream), * and to commit all streams. Committing causes the contents of all streams of a given * type to be written out to the file associated with that type, in the order in which * the streams of that type were created. * * @author nvk * @author vj -- Moved out to its own separate class * @author igor -- completely rewritten */ public class WriterStreams { private Map<String, SimpleCodeWriter> codeWriters; private Vector<ClassifiedStream> streams; private Job job; private TargetFactory targetFactory; private String pkg; private String className; public WriterStreams(String className, String pkg, Job job, TargetFactory targetFactory) throws IOException { streams = new Vector<ClassifiedStream>(); codeWriters = new TreeMap<String,SimpleCodeWriter>(); this.targetFactory = targetFactory; this.job = job; this.pkg = pkg; this.className = className; } /** * Write out all the streams associated with this object to their corresponding files. * Note that all streams of the same type are written to the same file, their contents * concatenated in the order in which the streams were created, as indicated by the * prepend argument to {@link #getNewStream(String, boolean)}. * @throws IOException */ public void commitStreams() throws IOException { Set<String> extensions = new TreeSet<String>(); for (ClassifiedStream s : streams) { extensions.add(s.ext); } for (String ext : extensions) { final File file = X10CPPTranslator.outputFile(job.extensionInfo().getOptions(), pkg, className, ext); codeWriters.put(ext, new SimpleCodeWriter(targetFactory.outputWriter(file), job.compiler().outputWidth())); } Map<String, Integer> startLineOffsets = CollectionFactory.newHashMap(); for (ClassifiedStream s : streams) { int startLineOffset = startLineOffsets.containsKey(s.ext) ? startLineOffsets.get(s.ext) : 0; s.commit(codeWriters.get(s.ext), startLineOffset); startLineOffset += s.getStreamLineNumber()-1; startLineOffsets.put(s.ext, startLineOffset); } for (String ext : extensions) { SimpleCodeWriter w = codeWriters.get(ext); w.flush(); w.close(); } } /** * Create and return a new stream of type ext. * @param ext * @return a new stream of type ext */ public ClassifiedStream getNewStream(String ext) { return getNewStream(ext, true); } /** * Create and return a new stream of type ext, inserting it either at the beginning * or at the end of the stream list. * @param ext * @param prepend Whether to prepend the new stream to all streams of its class (true) * or append it (false) * @return a new stream of type ext */ public ClassifiedStream getNewStream(String ext, boolean prepend) { ClassifiedStream cs = new ClassifiedStream(ext, job.compiler().outputWidth()); if (prepend) { streams.add(0, cs); } else { streams.add(cs); } return cs; } /** * Create and return a new stream of type ext, inserting it either before or after * a given stream s. * @param ext * @param s * @param prepend Whether to prepend the new stream (true) or append it (false) * @return a new stream of type ext */ public ClassifiedStream getNewStream(String ext, ClassifiedStream s, boolean prepend) { ClassifiedStream cs = new ClassifiedStream(ext, job.compiler().outputWidth()); int i = streams.indexOf(s); if (prepend) { streams.add(i, cs); } else { streams.add(i+1, cs); } return cs; } /** * Return the name of the file for stream type ext. * @param ext * @return the name of the file */ public String getStreamName(String ext) { return X10CPPTranslator.outputFileName(pkg, className, ext); } } // vim:tabstop=4:shiftwidth=4:expandtab