001    package org.extendj.ast;
002    
003    import java.util.HashSet;
004    import java.io.File;
005    import java.util.Set;
006    import java.util.Collections;
007    import java.util.Collection;
008    import java.util.ArrayList;
009    import beaver.*;
010    import java.util.*;
011    import java.io.ByteArrayOutputStream;
012    import java.io.PrintStream;
013    import java.lang.reflect.InvocationTargetException;
014    import java.lang.reflect.Method;
015    import org.jastadd.util.*;
016    import java.util.zip.*;
017    import java.io.*;
018    import org.jastadd.util.PrettyPrintable;
019    import org.jastadd.util.PrettyPrinter;
020    import java.io.FileNotFoundException;
021    import java.io.BufferedInputStream;
022    import java.io.DataInputStream;
023    /**
024     * @ast class
025     * @aspect PathPart
026     * @declaredat /home/jesper/git/extendj/java4/frontend/PathPart.jadd:46
027     */
028    public abstract class ClassSource extends java.lang.Object {
029      
030        protected final PathPart sourcePath;
031    
032      
033    
034        /**
035         * Used to represent an non-existent compilation unit source file.
036         *
037         * <p>This class source should never be used to attempt to load a class, it
038         * is simply used as a marker to indicate failure to find a compilation
039         * unit.
040         */
041        public static final ClassSource NONE = new ClassSource(null) {
042          @Override
043          public long lastModified() {
044            return 0;
045          }
046          @Override
047          public InputStream openInputStream() {
048            throw new UnsupportedOperationException(
049                "ClassSource.NONE can not open an input stream!");
050          }
051          @Override
052          public String pathName() {
053            return "<Unknown Source>";
054          }
055        };
056    
057      
058    
059        public ClassSource(PathPart sourcePath) {
060          this.sourcePath = sourcePath;
061        }
062    
063      
064    
065        public PathPart getSourcePath() {
066          return sourcePath;
067        }
068    
069      
070    
071        /**
072         * @return Last modification time of the class source.
073         */
074        abstract public long lastModified();
075    
076      
077    
078        /**
079         * @return Input stream pointing to the class source.
080         */
081        abstract public InputStream openInputStream() throws IOException;
082    
083      
084    
085        /**
086         * It is sufficient to only overload pathName if sourceName=pathName
087         * @return the full name of the class source (e.g. file path).
088         */
089        public String sourceName() {
090          return pathName();
091        }
092    
093      
094    
095        /**
096         * @return the path to the source file or the enclosing jar file
097         */
098        abstract public String pathName();
099    
100      
101    
102        /**
103         * It is sufficient to only overload pathName if relativeName = pathName
104         * @return the path to the source file, or the path to the file inside a
105         * jar file
106         */
107        public String relativeName() {
108          return pathName();
109        }
110    
111      
112    
113        @Override
114        public String toString() {
115          return sourceName();
116        }
117    
118      
119    
120        /**
121         * Parses the compilation unit from this class source.
122         *
123         * NB only call this once! The input stream is closed after the compilation
124         * unit is parsed.
125         *
126         * @return parsed compilation unit, or {@code null} if something failed
127         */
128        public CompilationUnit parseCompilationUnit(Program program) throws IOException {
129          InputStream is = openInputStream();
130          try {
131            if (program.options().verbose()) {
132              System.out.print("Loading " + sourceName());
133            }
134    
135            long start = System.nanoTime();
136            CompilationUnit u = program.javaParser.parse(is, sourceName());
137            long elapsed = System.nanoTime() - start;
138            program.javaParseTime += elapsed;
139            program.numJavaFiles += 1;
140    
141            u.setFromSource(true);
142            u.setClassSource(this);
143    
144            if (program.options().verbose()) {
145              System.out.println(" in " + (elapsed / 1000000) + " ms");
146            }
147            return u;
148          } catch (Exception e) {
149            System.err.println("Unexpected error of kind " + e.getClass().getName());
150            throw new Error(sourceName() + ": " + e.getMessage(), e);
151          } finally {
152            if (is != null) {
153              try {
154                is.close();
155              } catch (IOException e) {
156              }
157            }
158          }
159        }
160    
161    
162    }