KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > aspectj > compiler > base > CodeGenerator


1 /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  *
3  * This file is part of the compiler and core tools for the AspectJ(tm)
4  * programming language; see http://aspectj.org
5  *
6  * The contents of this file are subject to the Mozilla Public License
7  * Version 1.1 (the "License"); you may not use this file except in
8  * compliance with the License. You may obtain a copy of the License at
9  * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
10  *
11  * Software distributed under the License is distributed on an "AS IS" basis,
12  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13  * for the specific language governing rights and limitations under the
14  * License.
15  *
16  * The Original Code is AspectJ.
17  *
18  * The Initial Developer of the Original Code is Xerox Corporation. Portions
19  * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
20  * All Rights Reserved.
21  *
22  * Contributor(s):
23  */

24
25 package org.aspectj.compiler.base;
26 import org.aspectj.compiler.base.ast.*;
27
28 import org.aspectj.tools.ide.SymbolManager;
29
30
31 import java.util.*;
32 import java.io.*;
33
34 public class CodeGenerator extends AbstractCompilerPass implements WorldPass, CompilationUnitPass {
35
36     public CodeGenerator(JavaCompiler compiler) {
37         super(compiler);
38     }
39
40     public String JavaDoc getDisplayName() {
41         return "generating Java sources";
42     }
43
44     public void clearState() {
45     }
46
47     public void addFileToCompile(File f) {
48         getCompiler().addFileToCompile(f);
49     }
50
51     public void transform(CompilationUnit cu) {
52         File outputDir = getOptions().workingDir;
53         try {
54             unparseCompilationUnit(outputDir, cu);
55         } catch (IOException ioe) {
56             getCompiler().internalError(ioe, cu);
57             return;
58         }
59     }
60
61
62     public void unparseCompilationUnit(File outputdir, CompilationUnit cu)
63       throws IOException
64     {
65         Decs decs = cu.getDecs();
66         final int N = decs.size();
67         for(int i=0; i<N; i++) {
68             Dec dec = decs.get(i);
69             unparseTypeDec(outputdir, (TypeDec)dec);
70         }
71     }
72
73     final int FILE_SIZE_GUESS = 32*1024;
74
75     private void unparseTypeDec(File outputdir, TypeDec typeDec) throws IOException {
76         getCompiler().showMessage(this, typeDec.toShortString());
77
78         File sourceFile = typeDec.getCompilationUnit().getSourceFile();
79         File inputdir;
80         if (sourceFile.getParent() == null) inputdir = new File(".");
81         else inputdir = new File(sourceFile.getParent());
82         String JavaDoc filename = typeDec.getId()+".java";
83         String JavaDoc packagename = typeDec.getPackageName();
84
85         Set topLevelTypes = getTopLevelTypes(typeDec);
86
87         //ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
88
//Writer writer = new org.aspectj.util.UnicodeEscapeWriter(byteStream);
89

90         File packagedir = typeDec.getPackageDir(outputdir);
91         packagedir.mkdirs();
92
93         File clsDir = packagename == null ? getOptions().outputDir
94                                           : new File(getOptions().outputDir, packagename);
95         File clsFile = new File(clsDir, typeDec.getId()+".class");
96         //getCompiler().getProject().addBytecodeFile(sourceFile,clsFile);
97

98         File outFile = new File(packagedir, filename);
99
100         // maybe wrap this in a try/catch to print a partial stream on failure
101
// LineMap lineMap = null;
102
// if (!getOptions().nosymbols) {
103
// lineMap = new LineMap(outFile, getWorld().getOutputToSourceLineMap(),
104
// getWorld().getSourceToOutputLineMap());
105
// }
106

107         CodeWriter unparser = new CodeWriter(getCompiler(), FILE_SIZE_GUESS, null); //lineMap);
108
unparser.writeHeader();
109         if (typeDec.getCompilationUnit().getPackageName() != null) {
110             unparser.write("package ");
111             unparser.write(typeDec.getCompilationUnit().getPackageName());
112             unparser.writeln(";");
113         }
114
115         // write imports for all top-level types
116
for(Iterator iter = topLevelTypes.iterator(); iter.hasNext(); ) {
117             Type topType = (Type)iter.next();
118             if (!topType.isInnerType() &&
119                 (topType.isClass() || topType.isInterface()) &&
120                 !(topType == getTypeManager().TYPE_NOT_FOUND) &&
121                 !(topType.getString().startsWith("<"))) {
122                 unparser.writeln("import "+topType.getString()+";");
123             }
124         }
125
126         unparser.write(typeDec.getCompilationUnit().getImports());
127         
128         try {
129             unparser.write(typeDec);
130         } catch (RuntimeException JavaDoc e) {
131             //writer.flush();
132
e.printStackTrace();
133             unparser.writeTo(System.out);
134             throw e;
135         }
136         //writer.flush();
137

138         if (outputdir == null) {
139             // maybe do some chunking on this one to reduce memory overhead?
140
unparser.writeTo(System.out);
141         } else {
142             // make package dir for sources
143
if (outFile.exists()) {
144                 if (outFile.getCanonicalPath().equals(sourceFile.getCanonicalPath())) {
145                     //XXX error -- writing result file over original
146
}
147             }
148             FileOutputStream fileStream = new FileOutputStream(outFile);
149             try {
150                 unparser.writeTo(fileStream);
151             } finally {
152                 fileStream.close();
153             }
154             addFileToCompile(outFile);
155         }
156     }
157
158     private Set getTopLevelTypes(ASTObject typeDec) {
159         Set topTypesSet = new HashSet();
160         // only generate these imports in non-top-level cu's
161
if (typeDec.getCompilationUnit().getPackageName() == null) return topTypesSet;
162         
163         TopTypesFinder ttFinder = new TopTypesFinder(getCompiler(),topTypesSet);
164         ttFinder.process(typeDec);
165         return topTypesSet;
166     }
167 }
168
169 class TopTypesFinder extends Walker {
170     private Set topTypesSet;
171
172     public TopTypesFinder(JavaCompiler compiler, Set topTypesSet) {
173         super(compiler);
174         this.topTypesSet = topTypesSet;
175     }
176
177     public void postProcess(ASTObject obj) {
178         if (obj instanceof TypeD) {
179             Type type = ((TypeD)obj).getType();
180             if (type.getPackageName() == null) {
181                 topTypesSet.add(type);
182             }
183         } else if (obj instanceof FieldAccessExpr) {
184             FieldAccessExpr fae = (FieldAccessExpr)obj;
185             if (fae.getField() == null) return;
186             if (fae.getField().isStatic()) {
187                 Type type = fae.getField().getDeclaringType();
188                 if (type != null && type.getPackageName() == null) {
189                     topTypesSet.add(type);
190                 }
191                 return;
192             }
193         }
194     }
195 }
196
Popular Tags