Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Copyright (c) 2000, 2012 IBM Corporation and others. All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html Contributors: IBM Corporation - initial API and implementation Terry Parker <tparker@google.com> - Contribution for https://bugs.eclipse.org/bugs/show_bug.cgi?id=372418 - Another problem with inner classes referenced from jars or class folders: "The type ... cannot be resolved" Stephan Herrmann - Contribution for Bug 392727 - Cannot compile project when a java file contains $ in its file name /
 
 package org.eclipse.jdt.internal.core.builder;
 
 import  org.eclipse.core.resources.*;
 import  org.eclipse.core.runtime.*;
 
 
 import java.io.*;
 import java.util.*;
 
 public class NameEnvironment implements INameEnvironmentSuffixConstants {
 
 
 SimpleSet initialTypeNames// assumed that each name is of the form "a/b/ClassName"
 
 NameEnvironment(IWorkspaceRoot rootJavaProject javaProjectSimpleLookupTable binaryLocationsPerProjectBuildNotifier notifierthrows CoreException {
 	this. = false;
 	this. = notifier;
 	computeClasspathLocations(rootjavaProjectbinaryLocationsPerProject);
 	setNames(nullnull);
 }
 
 public NameEnvironment(IJavaProject javaProject) {
 	this. = false;
 	try {
 		computeClasspathLocations(javaProject.getProject().getWorkspace().getRoot(), (JavaProjectjavaProjectnull);
 	} catch(CoreException e) {
 	}
 	setNames(nullnull);
 }
 
 /* Some examples of resolved class path entries.
 * Remember to search class path in the order that it was defined.
 *
 * 1a. typical project with no source folders:
 *   /Test[CPE_SOURCE][K_SOURCE] -> D:/eclipse.test/Test
 * 1b. project with source folders:
 *   /Test/src1[CPE_SOURCE][K_SOURCE] -> D:/eclipse.test/Test/src1
 *   /Test/src2[CPE_SOURCE][K_SOURCE] -> D:/eclipse.test/Test/src2
 *  NOTE: These can be in any order & separated by prereq projects or libraries
 * 1c. project external to workspace (only detectable using getLocation()):
 *   /Test/src[CPE_SOURCE][K_SOURCE] -> d:/eclipse.zzz/src
 *  Need to search source folder & output folder
 *
 * 2. zip files:
 *   D:/j9/lib/jclMax/classes.zip[CPE_LIBRARY][K_BINARY][sourcePath:d:/j9/lib/jclMax/source/source.zip]
 *      -> D:/j9/lib/jclMax/classes.zip
 *  ALWAYS want to take the library path as is
 *
 * 3a. prereq project (regardless of whether it has a source or output folder):
 *   /Test[CPE_PROJECT][K_SOURCE] -> D:/eclipse.test/Test
 *  ALWAYS want to append the output folder & ONLY search for .class files
 */
 private void computeClasspathLocations(
 	IWorkspaceRoot root,
 	JavaProject javaProject,
 	SimpleLookupTable binaryLocationsPerProjectthrows CoreException {
 
 	/* Update cycle marker */
 	IMarker cycleMarker = javaProject.getCycleMarker();
 	if (cycleMarker != null) {
 		int severity = ..equals(javaProject.getOption(.true))
 			? IMarker.SEVERITY_ERROR
 			: IMarker.SEVERITY_WARNING;
 		if (severity != cycleMarker.getAttribute(IMarker.SEVERITY, severity))
 			cycleMarker.setAttribute(IMarker.SEVERITY, severity);
 	}
 
 	IClasspathEntry[] classpathEntries = javaProject.getExpandedClasspath();
 	ArrayList sLocations = new ArrayList(classpathEntries.length);
	ArrayList bLocations = new ArrayList(classpathEntries.length);
	nextEntry : for (int i = 0, l = classpathEntries.lengthi < li++) {
		ClasspathEntry entry = (ClasspathEntryclasspathEntries[i];
		IPath path = entry.getPath();
		Object target = JavaModel.getTarget(pathtrue);
		if (target == nullcontinue nextEntry;
		switch(entry.getEntryKind()) {
				if (!(target instanceof IContainer)) continue nextEntry;
				IPath outputPath = entry.getOutputLocation() != null
javaProject.getOutputLocation();
				IContainer outputFolder;
				if (outputPath.segmentCount() == 1) {
					outputFolder = javaProject.getProject();
else {
					outputFolder = root.getFolder(outputPath);
					if (!outputFolder.exists())
						createOutputFolder(outputFolder);
				}
				sLocations.add(
					ClasspathLocation.forSourceFolder((IContainer) targetoutputFolderentry.fullInclusionPatternChars(), entry.fullExclusionPatternChars(), entry.ignoreOptionalProblems()));
				continue nextEntry;
				if (!(target instanceof IProject)) continue nextEntry;
				IProject prereqProject = (IProject) target;
				if (!JavaProject.hasJavaNature(prereqProject)) continue nextEntry; // if project doesn't have java nature or is not accessible
				JavaProject prereqJavaProject = (JavaProject) JavaCore.create(prereqProject);
				IClasspathEntry[] prereqClasspathEntries = prereqJavaProject.getRawClasspath();
				ArrayList seen = new ArrayList();
				nextPrereqEntry: for (int j = 0, m = prereqClasspathEntries.lengthj < mj++) {
					IClasspathEntry prereqEntry = prereqClasspathEntries[j];
					if (prereqEntry.getEntryKind() == .) {
						Object prereqTarget = JavaModel.getTarget(prereqEntry.getPath(), true);
						if (!(prereqTarget instanceof IContainer)) continue nextPrereqEntry;
						IPath prereqOutputPath = prereqEntry.getOutputLocation() != null
prereqEntry.getOutputLocation()
prereqJavaProject.getOutputLocation();
						IContainer binaryFolder = prereqOutputPath.segmentCount() == 1
							? (IContainer) prereqProject
							: (IContainer) root.getFolder(prereqOutputPath);
						if (binaryFolder.exists() && !seen.contains(binaryFolder)) {
							seen.add(binaryFolder);
							ClasspathLocation bLocation = ClasspathLocation.forBinaryFolder(binaryFoldertrueentry.getAccessRuleSet());
							bLocations.add(bLocation);
							if (binaryLocationsPerProject != null) { // normal builder mode
								ClasspathLocation[] existingLocations = (ClasspathLocation[]) binaryLocationsPerProject.get(prereqProject);
								if (existingLocations == null) {
									existingLocations = new ClasspathLocation[] {bLocation};
else {
									int size = existingLocations.length;
									System.arraycopy(existingLocations, 0, existingLocations = new ClasspathLocation[size + 1], 0, size);
									existingLocations[size] = bLocation;
								}
								binaryLocationsPerProject.put(prereqProjectexistingLocations);
							}
						}
					}
				}
				continue nextEntry;
				if (target instanceof IResource) {
					IResource resource = (IResource) target;
					ClasspathLocation bLocation = null;
					if (resource instanceof IFile) {
						AccessRuleSet accessRuleSet =
null
entry.getAccessRuleSet();
						bLocation = ClasspathLocation.forLibrary((IFile) resourceaccessRuleSet);
else if (resource instanceof IContainer) {
						AccessRuleSet accessRuleSet =
null
entry.getAccessRuleSet();
						bLocation = ClasspathLocation.forBinaryFolder((IContainer) targetfalseaccessRuleSet);	 // is library folder not output folder
					}
					bLocations.add(bLocation);
					if (binaryLocationsPerProject != null) { // normal builder mode
						IProject p = resource.getProject(); // can be the project being built
						ClasspathLocation[] existingLocations = (ClasspathLocation[]) binaryLocationsPerProject.get(p);
						if (existingLocations == null) {
							existingLocations = new ClasspathLocation[] {bLocation};
else {
							int size = existingLocations.length;
							System.arraycopy(existingLocations, 0, existingLocations = new ClasspathLocation[size + 1], 0, size);
							existingLocations[size] = bLocation;
						}
						binaryLocationsPerProject.put(pexistingLocations);
					}
else if (target instanceof File) {
					AccessRuleSet accessRuleSet =
null
entry.getAccessRuleSet();
					bLocations.add(ClasspathLocation.forLibrary(path.toString(), accessRuleSet));
				}
				continue nextEntry;
		}
	}
	// now split the classpath locations... place the output folders ahead of the other .class file folders & jars
	ArrayList outputFolders = new ArrayList(1);
	this. = new ClasspathMultiDirectory[sLocations.size()];
	if (!sLocations.isEmpty()) {
		sLocations.toArray(this.);
		// collect the output folders, skipping duplicates
		next : for (int i = 0, l = this..lengthi < li++) {
			IPath outputPath = md.binaryFolder.getFullPath();
			for (int j = 0; j < ij++) { // compare against previously walked source folders
				if (outputPath.equals(this.[j]..getFullPath())) {
					md.hasIndependentOutputFolder = this.[j].;
					continue next;
				}
			}
			outputFolders.add(md);
			// also tag each source folder whose output folder is an independent folder & is not also a source folder
			for (int j = 0, m = this..lengthj < mj++)
				if (outputPath.equals(this.[j]..getFullPath()))
					continue next;
			md.hasIndependentOutputFolder = true;
		}
	}
	// combine the output folders with the binary folders & jars... place the output folders before other .class file folders & jars
	this. = new ClasspathLocation[outputFolders.size() + bLocations.size()];
	int index = 0;
	for (int i = 0, l = outputFolders.size(); i < li++)
		this.[index++] = (ClasspathLocationoutputFolders.get(i);
	for (int i = 0, l = bLocations.size(); i < li++)
		this.[index++] = (ClasspathLocationbLocations.get(i);
public void cleanup() {
	this. = null;
	this. = null;
	for (int i = 0, l = this..lengthi < li++)
	for (int i = 0, l = this..lengthi < li++)
private void createOutputFolder(IContainer outputFolderthrows CoreException {
	createParentFolder(outputFolder.getParent());
	((IFolder) outputFolder).create(IResource.FORCE | IResource.DERIVED, truenull);
private void createParentFolder(IContainer parentthrows CoreException {
	if (!parent.exists()) {
		createParentFolder(parent.getParent());
		((IFolder) parent).create(truetruenull);
	}
private NameEnvironmentAnswer findClass(String qualifiedTypeNamechar[] typeName) {
	if (this. != null)
	if (this. != null && this..includes(qualifiedTypeName)) {
			// catch the case that a type inside a source file has been renamed but other class files are looking for it
			throw new AbortCompilation(truenew AbortIncrementalBuildException(qualifiedTypeName));
		return null// looking for a file which we know was provided at the beginning of the compilation
	}
	if (this. != null && this..length > 0) {
		// if an additional source file is waiting to be compiled, answer it BUT not if this is a secondary type search
		// if we answer X.java & it no longer defines Y then the binary type looking for Y will think the class path is wrong
		// let the recompile loop fix up dependents when the secondary type Y has been deleted from X.java
		// Only enclosing type names are present in the additional units table, so strip off inner class specifications
		// when doing the lookup (https://bugs.eclipse.org/372418). 
		// Also take care of $ in the name of the class (https://bugs.eclipse.org/377401)
		// and prefer name with '$' if unit exists rather than failing to search for nested class (https://bugs.eclipse.org/392727)
		SourceFile unit = (SourceFilethis..get(qualifiedTypeName); // doesn't have file extension
		if (unit != null)
			return new NameEnvironmentAnswer(unitnull /*no access restriction*/);
		int index = qualifiedTypeName.indexOf('$');
		if (index > 0) {
			String enclosingTypeName = qualifiedTypeName.substring(0, index);
			unit = (SourceFilethis..get(enclosingTypeName); // doesn't have file extension
			if (unit != null)
				return new NameEnvironmentAnswer(unitnull /*no access restriction*/);
		}
	}
	String qBinaryFileName = qualifiedTypeName + ;
	String binaryFileName = qBinaryFileName;
	String qPackageName =  ""//$NON-NLS-1$
	if (qualifiedTypeName.length() > typeName.length) {
		int typeNameStart = qBinaryFileName.length() - typeName.length - 6; // size of ".class"
		qPackageName =  qBinaryFileName.substring(0, typeNameStart - 1);
		binaryFileName = qBinaryFileName.substring(typeNameStart);
	}
	// NOTE: the output folders are added at the beginning of the binaryLocations
	NameEnvironmentAnswer suggestedAnswer = null;
	for (int i = 0, l = this..lengthi < li++) {
		NameEnvironmentAnswer answer = this.[i].findClass(binaryFileNameqPackageNameqBinaryFileName);
		if (answer != null) {
			if (!answer.ignoreIfBetter()) {
				if (answer.isBetter(suggestedAnswer))
					return answer;
else if (answer.isBetter(suggestedAnswer))
				// remember suggestion and keep looking
				suggestedAnswer = answer;
		}
	}
	if (suggestedAnswer != null)
		// no better answer was found
		return suggestedAnswer;
	return null;
public NameEnvironmentAnswer findType(char[][] compoundName) {
	if (compoundName != null)
		return findClass(
			new String(CharOperation.concatWith(compoundName'/')),
			compoundName[compoundName.length - 1]);
	return null;
public NameEnvironmentAnswer findType(char[] typeNamechar[][] packageName) {
	if (typeName != null)
		return findClass(
			new String(CharOperation.concatWith(packageNametypeName'/')),
			typeName);
	return null;
public boolean isPackage(char[][] compoundNamechar[] packageName) {
	return isPackage(new String(CharOperation.concatWith(compoundNamepackageName'/')));
public boolean isPackage(String qualifiedPackageName) {
	// NOTE: the output folders are added at the beginning of the binaryLocations
	for (int i = 0, l = this..lengthi < li++)
		if (this.[i].isPackage(qualifiedPackageName))
			return true;
	return false;
void setNames(String[] typeNamesSourceFile[] additionalFiles) {
	// convert the initial typeNames to a set
	if (typeNames == null) {
		this. = null;
else {
		this. = new SimpleSet(typeNames.length);
		for (int i = 0, l = typeNames.lengthi < li++)
			this..add(typeNames[i]);
	}
	// map the additional source files by qualified type name
	if (additionalFiles == null) {
		this. = null;
else {
		this. = new SimpleLookupTable(additionalFiles.length);
		for (int i = 0, l = additionalFiles.lengthi < li++) {
			SourceFile additionalUnit = additionalFiles[i];
			if (additionalUnit != null)
				this..put(additionalUnit.initialTypeNameadditionalFiles[i]);
		}
	}
	for (int i = 0, l = this..lengthi < li++)
	for (int i = 0, l = this..lengthi < li++)
New to GrepCode? Check out our FAQ X