]> source.dussan.org Git - aspectj.git/blob
0af411be361fd15d3d08e66ae6f61bb971de7337
[aspectj.git] /
1 /* *******************************************************************
2  * Copyright (c) 2002 IBM and other contributors
3  * All rights reserved.
4  * This program and the accompanying materials are made available
5  * under the terms of the Eclipse Public License v 2.0
6  * which accompanies this distribution and is available at
7  * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
8  *
9  * Contributors:
10  *     Palo Alto Research Center, Incorporated (PARC)
11  *     Andy Clement
12  * ******************************************************************/
13
14 package org.aspectj.ajdt.internal.core.builder;
15
16 import java.io.File;
17 import java.io.IOException;
18 import java.util.Collections;
19 import java.util.HashMap;
20 import java.util.HashSet;
21 import java.util.Map;
22 import java.util.Set;
23
24 import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation;
25 import org.aspectj.org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
26 import org.aspectj.org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
27 import org.aspectj.org.eclipse.jdt.internal.compiler.env.IBinaryType;
28 import org.aspectj.org.eclipse.jdt.internal.compiler.env.IModule;
29 import org.aspectj.org.eclipse.jdt.internal.compiler.env.IModuleAwareNameEnvironment;
30 import org.aspectj.org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer;
31 import org.aspectj.util.FileUtil;
32
33 public class StatefulNameEnvironment implements IModuleAwareNameEnvironment {
34         private Map<String,File> classesFromName;
35         private Map<String,NameEnvironmentAnswer> inflatedClassFilesCache;
36         private Set<String> packageNames;
37         private AjState state;
38         private IModuleAwareNameEnvironment baseEnvironment;
39
40         public StatefulNameEnvironment(IModuleAwareNameEnvironment baseEnvironment, Map<String,File> classesFromName, AjState state) {
41                 this.classesFromName = classesFromName;
42                 this.inflatedClassFilesCache = new HashMap<>();
43                 this.baseEnvironment = baseEnvironment;
44                 this.state = state;
45                 packageNames = new HashSet<>();
46                 for (String className: classesFromName.keySet()) {
47                         addAllPackageNames(className);
48                 }
49         }
50
51         private void addAllPackageNames(String className) {
52                 int dot = className.indexOf('.');
53                 while (dot != -1) {
54                         packageNames.add(className.substring(0, dot));
55                         dot = className.indexOf('.', dot + 1);
56                 }
57         }
58
59         private NameEnvironmentAnswer findType(String name) {
60                 // pr133532 - ask the state for the type first
61                 IBinaryType seenOnPreviousBuild = state.checkPreviousBuild(name);
62                 if (seenOnPreviousBuild != null) {
63                         return new NameEnvironmentAnswer(seenOnPreviousBuild, null);
64                 }
65                 if (this.inflatedClassFilesCache.containsKey(name)) {
66                         return this.inflatedClassFilesCache.get(name);
67                 } else {
68                         File fileOnDisk = classesFromName.get(name);
69                         // System.err.println("find: " + name + " found: " + cf);
70                         if (fileOnDisk == null) {
71                                 return null;
72                         }
73                         try {
74                                 // System.out.println("from cache: " + name);
75                                 byte[] bytes = FileUtil.readAsByteArray(fileOnDisk);
76                                 NameEnvironmentAnswer ret = new NameEnvironmentAnswer(new ClassFileReader(bytes, fileOnDisk.getAbsolutePath()
77                                                 .toCharArray()), null /* no access restriction */);
78                                 this.inflatedClassFilesCache.put(name, ret);
79                                 return ret;
80                         } catch (ClassFormatException e) {
81                                 return null; // !!! seems to match FileSystem behavior
82                         } catch (IOException ex) {
83                                 return null; // see above...
84                         }
85                 }
86         }
87
88         @Override
89         public void cleanup() {
90                 baseEnvironment.cleanup();
91                 this.classesFromName = Collections.emptyMap();
92                 this.packageNames.clear();
93         }
94
95         @Override
96         public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName) {
97                 NameEnvironmentAnswer ret = findType(new String(CharOperation.concatWith(packageName, typeName, '.')));
98                 if (ret != null) {
99                         return ret;
100                 }
101                 return baseEnvironment.findType(typeName, packageName);
102         }
103
104         @Override
105         public NameEnvironmentAnswer findType(char[][] compoundName) {
106                 NameEnvironmentAnswer ret = findType(new String(CharOperation.concatWith(compoundName, '.')));
107                 if (ret != null) {
108                         return ret;
109                 }
110                 return baseEnvironment.findType(compoundName);
111         }
112
113         @Override
114         public boolean isPackage(char[][] parentPackageName, char[] packageName) {
115                 if (baseEnvironment.isPackage(parentPackageName, packageName)) {
116                         return true;
117                 }
118                 String fullPackageName = new String(CharOperation.concatWith(parentPackageName, packageName, '.'));
119                 return packageNames.contains(fullPackageName);
120         }
121
122         /**
123          * Needs to be told about changes. The 'added' set is a subset of classNameToFileMap consisting of just those names added during
124          * this build - to reduce any impact on incremental compilation times.
125          */
126         public void update(Map<String,File> classNameToFileMap, Set<String> added) {
127                 for (String className: added) {
128                         addAllPackageNames(className);
129                 }
130                 this.classesFromName = classNameToFileMap;
131         }
132
133         @Override
134         public NameEnvironmentAnswer findType(char[][] compoundName, char[] moduleName) {
135                 return baseEnvironment.findType(compoundName, moduleName);
136         }
137
138         @Override
139         public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName, char[] moduleName) {
140                 return baseEnvironment.findType(typeName, packageName, moduleName);
141         }
142
143
144         @Override
145         public boolean hasCompilationUnit(char[][] qualifiedPackageName, char[] moduleName, boolean checkCUs) {
146                 return baseEnvironment.hasCompilationUnit(qualifiedPackageName, moduleName, checkCUs);
147         }
148
149         @Override
150         public IModule getModule(char[] moduleName) {
151                 return baseEnvironment.getModule(moduleName);
152         }
153
154         @Override
155         public char[][] getAllAutomaticModules() {
156                 return baseEnvironment.getAllAutomaticModules();
157         }
158
159         @Override
160         public char[][] getModulesDeclaringPackage(char[][] arg0, char[] arg1) {
161                 return baseEnvironment.getModulesDeclaringPackage(arg0, arg1);
162         }
163
164         @Override
165         public char[][] listPackages(char[] arg0) {
166                 return baseEnvironment.listPackages(arg0);
167         }
168
169 }