001: /**************************************************************************/
002: /* N I C E */
003: /* A high-level object-oriented research language */
004: /* (c) Daniel Bonniot 2001 */
005: /* */
006: /* This program is free software; you can redistribute it and/or modify */
007: /* it under the terms of the GNU General Public License as published by */
008: /* the Free Software Foundation; either version 2 of the License, or */
009: /* (at your option) any later version. */
010: /* */
011: /**************************************************************************/package gnu.expr;
012:
013: import gnu.bytecode.*;
014:
015: import java.io.File;
016: import java.io.FileOutputStream;
017:
018: /**
019: A set of classes to generate as a java-like package.
020:
021: Extends expression to make it possible to walk the package.
022: The walk is performed on each class of the package.
023:
024: @version $Date: 2002/02/02 12:21:47 $
025: @author Daniel Bonniot (Daniel.Bonniot@inria.fr)
026: */
027:
028: public class Package extends Expression {
029: /** Create a Bytecode Package.
030:
031: @param name qualified name of the package (e.g. "my.package")
032: */
033: public Package(String name) {
034: this .name = name;
035: this .prefix = name.replace('.', '/') + "/";
036: }
037:
038: public void print(gnu.mapping.OutPort ps) {
039: ps.print("Package " + name);
040: }
041:
042: public void compile(Compilation comp, Target target) {
043: throw new Error("A package cannot be evaluated");
044: }
045:
046: protected void walkChildren(ExpWalker walker) {
047: for (LambdaExp c = firstClass; c != null; c = c.nextSibling)
048: c.walk(walker);
049: }
050:
051: public void addClass(ClassExp classe) {
052: classe.nextSibling = firstClass;
053: firstClass = classe;
054: }
055:
056: ClassExp firstClass;
057:
058: void addClass(ClassType c) {
059: classes.add(c);
060: }
061:
062: /** Search this package for a class with a given name.
063: * @param name the name of the class desired
064: * @return the matching ClassType, or null if none is found */
065: public ClassType findNamedClass(String name) {
066: for (int i = classes.size(); --i >= 0;) {
067: if (name.equals(((ClassType) classes.get(i)).getName()))
068: return (ClassType) classes.get(i);
069: }
070: return null;
071: }
072:
073: private java.util.Vector classes = new java.util.Vector(10);
074:
075: public Package next;
076:
077: /** Qualified name, e.g. "my.package". */
078: public final String name;
079:
080: /** "my/package/" */
081: public final String prefix;
082:
083: public File directory;
084:
085: public void compileToFiles() throws java.io.IOException {
086: Compilation comp = new Compilation();
087: comp.compile(this );
088:
089: for (Package p = this ; p != null; p = p.next)
090: p.writeClasses();
091: }
092:
093: private void writeClasses() throws java.io.IOException {
094: for (java.util.Iterator i = classes.iterator(); i.hasNext();) {
095: ClassType clas = (ClassType) i.next();
096: String name = clas.getName();
097: int lastDot = name.lastIndexOf('.');
098: if (lastDot != -1) {
099: if (!name.substring(0, lastDot).equals(this .name))
100: throw new Error(
101: "Class generated in the wrong package: "
102: + name + " was found in package "
103: + this .name);
104:
105: name = name.substring(lastDot + 1);
106: }
107:
108: File out = new File(directory, name + ".class");
109: out.getParentFile().mkdirs();
110: clas.writeToFile(out);
111: }
112: }
113: }
|