1 11 package org.eclipse.jdt.internal.core.builder; 12 13 import org.eclipse.core.resources.*; 14 import org.eclipse.core.runtime.*; 15 16 import org.eclipse.jdt.core.*; 17 import org.eclipse.jdt.core.compiler.CharOperation; 18 import org.eclipse.jdt.internal.compiler.env.*; 19 import org.eclipse.jdt.internal.compiler.problem.AbortCompilation; 20 import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable; 21 import org.eclipse.jdt.internal.compiler.util.SimpleSet; 22 import org.eclipse.jdt.internal.compiler.util.SuffixConstants; 23 import org.eclipse.jdt.internal.core.*; 24 25 import java.io.*; 26 import java.util.*; 27 28 public class NameEnvironment implements INameEnvironment, SuffixConstants { 29 30 boolean isIncrementalBuild; 31 ClasspathMultiDirectory[] sourceLocations; 32 ClasspathLocation[] binaryLocations; 33 BuildNotifier notifier; 34 35 SimpleSet initialTypeNames; SimpleLookupTable additionalUnits; 37 38 NameEnvironment(IWorkspaceRoot root, JavaProject javaProject, SimpleLookupTable binaryLocationsPerProject, BuildNotifier notifier) throws CoreException { 39 this.isIncrementalBuild = false; 40 this.notifier = notifier; 41 computeClasspathLocations(root, javaProject, binaryLocationsPerProject); 42 setNames(null, null); 43 } 44 45 public NameEnvironment(IJavaProject javaProject) { 46 this.isIncrementalBuild = false; 47 try { 48 computeClasspathLocations(javaProject.getProject().getWorkspace().getRoot(), (JavaProject) javaProject, null); 49 } catch(CoreException e) { 50 this.sourceLocations = new ClasspathMultiDirectory[0]; 51 this.binaryLocations = new ClasspathLocation[0]; 52 } 53 setNames(null, null); 54 } 55 56 78 private void computeClasspathLocations( 79 IWorkspaceRoot root, 80 JavaProject javaProject, 81 SimpleLookupTable binaryLocationsPerProject) throws CoreException { 82 83 84 IMarker cycleMarker = javaProject.getCycleMarker(); 85 if (cycleMarker != null) { 86 int severity = JavaCore.ERROR.equals(javaProject.getOption(JavaCore.CORE_CIRCULAR_CLASSPATH, true)) 87 ? IMarker.SEVERITY_ERROR 88 : IMarker.SEVERITY_WARNING; 89 if (severity != cycleMarker.getAttribute(IMarker.SEVERITY, severity)) 90 cycleMarker.setAttribute(IMarker.SEVERITY, severity); 91 } 92 93 IClasspathEntry[] classpathEntries = javaProject.getExpandedClasspath(); 94 ArrayList sLocations = new ArrayList(classpathEntries.length); 95 ArrayList bLocations = new ArrayList(classpathEntries.length); 96 nextEntry : for (int i = 0, l = classpathEntries.length; i < l; i++) { 97 ClasspathEntry entry = (ClasspathEntry) classpathEntries[i]; 98 IPath path = entry.getPath(); 99 Object target = JavaModel.getTarget(root, path, true); 100 if (target == null) continue nextEntry; 101 102 switch(entry.getEntryKind()) { 103 case IClasspathEntry.CPE_SOURCE : 104 if (!(target instanceof IContainer)) continue nextEntry; 105 IPath outputPath = entry.getOutputLocation() != null 106 ? entry.getOutputLocation() 107 : javaProject.getOutputLocation(); 108 IContainer outputFolder; 109 if (outputPath.segmentCount() == 1) { 110 outputFolder = javaProject.getProject(); 111 } else { 112 outputFolder = root.getFolder(outputPath); 113 if (!outputFolder.exists()) 114 createOutputFolder(outputFolder); 115 } 116 sLocations.add( 117 ClasspathLocation.forSourceFolder((IContainer) target, outputFolder, entry.fullInclusionPatternChars(), entry.fullExclusionPatternChars())); 118 continue nextEntry; 119 120 case IClasspathEntry.CPE_PROJECT : 121 if (!(target instanceof IProject)) continue nextEntry; 122 IProject prereqProject = (IProject) target; 123 if (!JavaProject.hasJavaNature(prereqProject)) continue nextEntry; 125 JavaProject prereqJavaProject = (JavaProject) JavaCore.create(prereqProject); 126 IClasspathEntry[] prereqClasspathEntries = prereqJavaProject.getRawClasspath(); 127 ArrayList seen = new ArrayList(); 128 nextPrereqEntry: for (int j = 0, m = prereqClasspathEntries.length; j < m; j++) { 129 IClasspathEntry prereqEntry = prereqClasspathEntries[j]; 130 if (prereqEntry.getEntryKind() == IClasspathEntry.CPE_SOURCE) { 131 Object prereqTarget = JavaModel.getTarget(root, prereqEntry.getPath(), true); 132 if (!(prereqTarget instanceof IContainer)) continue nextPrereqEntry; 133 IPath prereqOutputPath = prereqEntry.getOutputLocation() != null 134 ? prereqEntry.getOutputLocation() 135 : prereqJavaProject.getOutputLocation(); 136 IContainer binaryFolder = prereqOutputPath.segmentCount() == 1 137 ? (IContainer) prereqProject 138 : (IContainer) root.getFolder(prereqOutputPath); 139 if (binaryFolder.exists() && !seen.contains(binaryFolder)) { 140 seen.add(binaryFolder); 141 ClasspathLocation bLocation = ClasspathLocation.forBinaryFolder(binaryFolder, true, entry.getAccessRuleSet()); 142 bLocations.add(bLocation); 143 if (binaryLocationsPerProject != null) { ClasspathLocation[] existingLocations = (ClasspathLocation[]) binaryLocationsPerProject.get(prereqProject); 145 if (existingLocations == null) { 146 existingLocations = new ClasspathLocation[] {bLocation}; 147 } else { 148 int size = existingLocations.length; 149 System.arraycopy(existingLocations, 0, existingLocations = new ClasspathLocation[size + 1], 0, size); 150 existingLocations[size] = bLocation; 151 } 152 binaryLocationsPerProject.put(prereqProject, existingLocations); 153 } 154 } 155 } 156 } 157 continue nextEntry; 158 159 case IClasspathEntry.CPE_LIBRARY : 160 if (target instanceof IResource) { 161 IResource resource = (IResource) target; 162 ClasspathLocation bLocation = null; 163 if (resource instanceof IFile) { 164 if (!(org.eclipse.jdt.internal.compiler.util.Util.isArchiveFileName(path.lastSegment()))) 165 continue nextEntry; 166 AccessRuleSet accessRuleSet = 167 (JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE, true)) 168 && JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.COMPILER_PB_DISCOURAGED_REFERENCE, true))) 169 ? null 170 : entry.getAccessRuleSet(); 171 bLocation = ClasspathLocation.forLibrary((IFile) resource, accessRuleSet); 172 } else if (resource instanceof IContainer) { 173 AccessRuleSet accessRuleSet = 174 (JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE, true)) 175 && JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.COMPILER_PB_DISCOURAGED_REFERENCE, true))) 176 ? null 177 : entry.getAccessRuleSet(); 178 bLocation = ClasspathLocation.forBinaryFolder((IContainer) target, false, accessRuleSet); } 180 bLocations.add(bLocation); 181 if (binaryLocationsPerProject != null) { IProject p = resource.getProject(); ClasspathLocation[] existingLocations = (ClasspathLocation[]) binaryLocationsPerProject.get(p); 184 if (existingLocations == null) { 185 existingLocations = new ClasspathLocation[] {bLocation}; 186 } else { 187 int size = existingLocations.length; 188 System.arraycopy(existingLocations, 0, existingLocations = new ClasspathLocation[size + 1], 0, size); 189 existingLocations[size] = bLocation; 190 } 191 binaryLocationsPerProject.put(p, existingLocations); 192 } 193 } else if (target instanceof File) { 194 if (!(org.eclipse.jdt.internal.compiler.util.Util.isArchiveFileName(path.lastSegment()))) 195 continue nextEntry; 196 AccessRuleSet accessRuleSet = 197 (JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.COMPILER_PB_FORBIDDEN_REFERENCE, true)) 198 && JavaCore.IGNORE.equals(javaProject.getOption(JavaCore.COMPILER_PB_DISCOURAGED_REFERENCE, true))) 199 ? null 200 : entry.getAccessRuleSet(); 201 bLocations.add(ClasspathLocation.forLibrary(path.toString(), accessRuleSet)); 202 } 203 continue nextEntry; 204 } 205 } 206 207 ArrayList outputFolders = new ArrayList(1); 209 this.sourceLocations = new ClasspathMultiDirectory[sLocations.size()]; 210 if (!sLocations.isEmpty()) { 211 sLocations.toArray(this.sourceLocations); 212 213 next : for (int i = 0, l = sourceLocations.length; i < l; i++) { 215 ClasspathMultiDirectory md = sourceLocations[i]; 216 IPath outputPath = md.binaryFolder.getFullPath(); 217 for (int j = 0; j < i; j++) { if (outputPath.equals(sourceLocations[j].binaryFolder.getFullPath())) { 219 md.hasIndependentOutputFolder = sourceLocations[j].hasIndependentOutputFolder; 220 continue next; 221 } 222 } 223 outputFolders.add(md); 224 225 for (int j = 0, m = sourceLocations.length; j < m; j++) 227 if (outputPath.equals(sourceLocations[j].sourceFolder.getFullPath())) 228 continue next; 229 md.hasIndependentOutputFolder = true; 230 } 231 } 232 233 this.binaryLocations = new ClasspathLocation[outputFolders.size() + bLocations.size()]; 235 int index = 0; 236 for (int i = 0, l = outputFolders.size(); i < l; i++) 237 this.binaryLocations[index++] = (ClasspathLocation) outputFolders.get(i); 238 for (int i = 0, l = bLocations.size(); i < l; i++) 239 this.binaryLocations[index++] = (ClasspathLocation) bLocations.get(i); 240 } 241 242 public void cleanup() { 243 this.initialTypeNames = null; 244 this.additionalUnits = null; 245 for (int i = 0, l = sourceLocations.length; i < l; i++) 246 sourceLocations[i].cleanup(); 247 for (int i = 0, l = binaryLocations.length; i < l; i++) 248 binaryLocations[i].cleanup(); 249 } 250 251 private void createOutputFolder(IContainer outputFolder) throws CoreException { 252 createParentFolder(outputFolder.getParent()); 253 ((IFolder) outputFolder).create(IResource.FORCE | IResource.DERIVED, true, null); 254 } 255 256 private void createParentFolder(IContainer parent) throws CoreException { 257 if (!parent.exists()) { 258 createParentFolder(parent.getParent()); 259 ((IFolder) parent).create(true, true, null); 260 } 261 } 262 263 private NameEnvironmentAnswer findClass(String qualifiedTypeName, char[] typeName) { 264 if (this.notifier != null) 265 this.notifier.checkCancelWithinCompiler(); 266 267 if (this.initialTypeNames != null && this.initialTypeNames.includes(qualifiedTypeName)) { 268 if (isIncrementalBuild) 269 throw new AbortCompilation(true, new AbortIncrementalBuildException(qualifiedTypeName)); 271 return null; } 273 274 if (this.additionalUnits != null && this.sourceLocations.length > 0) { 275 SourceFile unit = (SourceFile) this.additionalUnits.get(qualifiedTypeName); if (unit != null) 280 return new NameEnvironmentAnswer(unit, null ); 281 } 282 283 String qBinaryFileName = qualifiedTypeName + SUFFIX_STRING_class; 284 String binaryFileName = qBinaryFileName; 285 String qPackageName = ""; if (qualifiedTypeName.length() > typeName.length) { 287 int typeNameStart = qBinaryFileName.length() - typeName.length - 6; qPackageName = qBinaryFileName.substring(0, typeNameStart - 1); 289 binaryFileName = qBinaryFileName.substring(typeNameStart); 290 } 291 292 NameEnvironmentAnswer suggestedAnswer = null; 294 for (int i = 0, l = binaryLocations.length; i < l; i++) { 295 NameEnvironmentAnswer answer = binaryLocations[i].findClass(binaryFileName, qPackageName, qBinaryFileName); 296 if (answer != null) { 297 if (!answer.ignoreIfBetter()) { 298 if (answer.isBetter(suggestedAnswer)) 299 return answer; 300 } else if (answer.isBetter(suggestedAnswer)) 301 suggestedAnswer = answer; 303 } 304 } 305 if (suggestedAnswer != null) 306 return suggestedAnswer; 308 return null; 309 } 310 311 public NameEnvironmentAnswer findType(char[][] compoundName) { 312 if (compoundName != null) 313 return findClass( 314 new String (CharOperation.concatWith(compoundName, '/')), 315 compoundName[compoundName.length - 1]); 316 return null; 317 } 318 319 public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName) { 320 if (typeName != null) 321 return findClass( 322 new String (CharOperation.concatWith(packageName, typeName, '/')), 323 typeName); 324 return null; 325 } 326 327 public boolean isPackage(char[][] compoundName, char[] packageName) { 328 return isPackage(new String (CharOperation.concatWith(compoundName, packageName, '/'))); 329 } 330 331 public boolean isPackage(String qualifiedPackageName) { 332 for (int i = 0, l = binaryLocations.length; i < l; i++) 334 if (binaryLocations[i].isPackage(qualifiedPackageName)) 335 return true; 336 return false; 337 } 338 339 void setNames(String [] typeNames, SourceFile[] additionalFiles) { 340 if (typeNames == null) { 342 this.initialTypeNames = null; 343 } else { 344 this.initialTypeNames = new SimpleSet(typeNames.length); 345 for (int i = 0, l = typeNames.length; i < l; i++) 346 this.initialTypeNames.add(typeNames[i]); 347 } 348 if (additionalFiles == null) { 350 this.additionalUnits = null; 351 } else { 352 this.additionalUnits = new SimpleLookupTable(additionalFiles.length); 353 for (int i = 0, l = additionalFiles.length; i < l; i++) { 354 SourceFile additionalUnit = additionalFiles[i]; 355 if (additionalUnit != null) 356 this.additionalUnits.put(additionalUnit.initialTypeName, additionalFiles[i]); 357 } 358 } 359 360 for (int i = 0, l = sourceLocations.length; i < l; i++) 361 sourceLocations[i].reset(); 362 for (int i = 0, l = binaryLocations.length; i < l; i++) 363 binaryLocations[i].reset(); 364 } 365 } 366 | Popular Tags |