001 /* 002 * $Id: CompileUnit.java,v 1.17 2005/11/21 00:40:00 blackdrag Exp $ 003 * 004 * Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved. 005 * 006 * Redistribution and use of this software and associated documentation 007 * ("Software"), with or without modification, are permitted provided that the 008 * following conditions are met: 009 * 1. Redistributions of source code must retain copyright statements and 010 * notices. Redistributions must also contain a copy of this document. 011 * 2. Redistributions in binary form must reproduce the above copyright 012 * notice, this list of conditions and the following disclaimer in the 013 * documentation and/or other materials provided with the distribution. 014 * 3. The name "groovy" must not be used to endorse or promote products 015 * derived from this Software without prior written permission of The Codehaus. 016 * For written permission, please contact info@codehaus.org. 017 * 4. Products derived from this Software may not be called "groovy" nor may 018 * "groovy" appear in their names without prior written permission of The 019 * Codehaus. "groovy" is a registered trademark of The Codehaus. 020 * 5. Due credit should be given to The Codehaus - http://groovy.codehaus.org/ 021 * 022 * THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS ``AS IS'' AND ANY 023 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 024 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 025 * DISCLAIMED. IN NO EVENT SHALL THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR 026 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 027 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 028 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 029 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 030 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 031 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 032 * DAMAGE. 033 * 034 */ 035 package org.codehaus.groovy.ast; 036 037 import groovy.lang.GroovyClassLoader; 038 039 import java.security.CodeSource; 040 import java.util.ArrayList; 041 import java.util.HashMap; 042 import java.util.Iterator; 043 import java.util.List; 044 import java.util.Map; 045 046 import org.codehaus.groovy.control.CompilerConfiguration; 047 048 /** 049 * Represents the entire contents of a compilation step which consists of one 050 * or more {@link ModuleNode}instances 051 * 052 * @author <a href="mailto:james@coredevelopers.net">James Strachan </a> 053 * @version $Revision: 1.17 $ 054 */ 055 public class CompileUnit { 056 057 private List modules = new ArrayList(); 058 private Map classes = new HashMap(); 059 private CompilerConfiguration config; 060 private GroovyClassLoader classLoader; 061 private CodeSource codeSource; 062 private Map classesToCompile = new HashMap(); 063 064 public CompileUnit(GroovyClassLoader classLoader, CompilerConfiguration config) { 065 this(classLoader, null, config); 066 } 067 068 public CompileUnit(GroovyClassLoader classLoader, CodeSource codeSource, CompilerConfiguration config) { 069 this.classLoader = classLoader; 070 this.config = config; 071 this.codeSource = codeSource; 072 } 073 074 public List getModules() { 075 return modules; 076 } 077 078 public void addModule(ModuleNode node) { 079 // node==null means a compilation error prevented 080 // groovy from building an ast 081 if (node==null) return; 082 modules.add(node); 083 node.setUnit(this); 084 addClasses(node.getClasses()); 085 } 086 087 /** 088 * @return the ClassNode for the given qualified name or returns null if 089 * the name does not exist in the current compilation unit 090 * (ignoring the .class files on the classpath) 091 */ 092 public ClassNode getClass(String name) { 093 ClassNode cn = (ClassNode) classes.get(name); 094 if (cn!=null) return cn; 095 return (ClassNode) classesToCompile.get(name); 096 } 097 098 /** 099 * @return a list of all the classes in each module in the compilation unit 100 */ 101 public List getClasses() { 102 List answer = new ArrayList(); 103 for (Iterator iter = modules.iterator(); iter.hasNext();) { 104 ModuleNode module = (ModuleNode) iter.next(); 105 answer.addAll(module.getClasses()); 106 } 107 return answer; 108 } 109 110 public CompilerConfiguration getConfig() { 111 return config; 112 } 113 114 public GroovyClassLoader getClassLoader() { 115 return classLoader; 116 } 117 118 public CodeSource getCodeSource() { 119 return codeSource; 120 } 121 122 /** 123 * Appends all of the fully qualified class names in this 124 * module into the given map 125 */ 126 void addClasses(List classList) { 127 for (Iterator iter = classList.iterator(); iter.hasNext();) { 128 addClass((ClassNode) iter.next()); 129 } 130 } 131 132 /** 133 * Adds a class to the unit. 134 */ 135 public void addClass(ClassNode node) { 136 node = node.redirect(); 137 String name = node.getName(); 138 Object stored = classes.get(name); 139 if (stored != null && stored != node) { 140 throw new RuntimeException( 141 "Error: duplicate class declaration for name: " + name + " and class: " + node); 142 } 143 classes.put(name, node); 144 145 if (classesToCompile.containsKey(name)) { 146 ClassNode cn = (ClassNode) classesToCompile.get(name); 147 cn.setRedirect(node); 148 classesToCompile.remove(name); 149 } 150 } 151 152 /** 153 * this emthod actually does not compile a class. It's only 154 * a marker that this type has to be compiled by the CompilationUnit 155 * at the end of a parse step no node should be be left. 156 */ 157 public void addClassNodeToCompile(ClassNode node) { 158 classesToCompile.put(node.getName(),node); 159 } 160 161 public boolean hasClassNodeToCompile(){ 162 return classesToCompile.size()!=0; 163 } 164 }