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 Kelly Campbell <kellyc@google.com> - Hangs in SourceMapper during java proposals - https://bugs.eclipse.org/bugs/show_bug.cgi?id=281575 Stephan Herrmann - Contribution for Bug 380048 - error popup when navigating to source files /
  
  package org.eclipse.jdt.internal.core;
  
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.Map;
  import java.util.Set;
  
  import  org.eclipse.core.resources.IContainer;
  import  org.eclipse.core.resources.IFile;
  import  org.eclipse.core.resources.IFolder;
  import  org.eclipse.core.resources.IResource;
  import  org.eclipse.core.resources.ResourcesPlugin;
  import  org.eclipse.core.runtime.CoreException;
  import  org.eclipse.core.runtime.IPath;
  import  org.eclipse.core.runtime.IStatus;
  import  org.eclipse.core.runtime.Path;
A SourceMapper maps source code in a ZIP file to binary types in a JAR. The SourceMapper uses the fuzzy parser to identify source fragments in a .java file, and attempts to match the source code with children in a binary type. A SourceMapper is associated with a JarPackageFragment by an AttachSourceOperation.

See also:
org.eclipse.jdt.internal.core.JarPackageFragment
  
  public class SourceMapper
  
  	public static class LocalVariableElementKey {
  		String name;
  		
  		public LocalVariableElementKey(IJavaElement methodString name) {
  			StringBuffer buffer = new StringBuffer();
  			buffer
  				.append('#')
  				.append(method.getElementName())
  				.append('(');
  			if (method.getElementType() == .) {
  				String[] parameterTypes = ((IMethodmethod).getParameterTypes();
  				for (int i = 0, max = parameterTypes.lengthi < maxi++) {
  					if (i > 0) {
  						buffer.append(',');
  					}
  					buffer.append(Signature.getSignatureSimpleName(parameterTypes[i]));
  				}
  			}
 			buffer.append(')');
 			this. = String.valueOf(buffer);
 			this. = name;
 		}
 
 		public int hashCode() {
 			final int prime = 31;
 			int result = 1;
 			result = prime * result + ((this. == null) ? 0 : this..hashCode());
 			result = prime * result + ((this. == null) ? 0 : this..hashCode());
 			return result;
 		}
 
 		public boolean equals(Object obj) {
 			if (this == obj)
 				return true;
 			if (obj == null)
 				return false;
 			if (getClass() != obj.getClass())
 				return false;
 			if (this. == null) {
 				if (other.name != null)
 					return false;
 			} else if (!this..equals(other.name))
 				return false;
 			if (this. == null) {
 				if (other.parent != null)
 					return false;
 			} else if (!this..equals(other.parent))
 				return false;
 			return true;
 		}
 		public String toString() {
 			StringBuffer buffer = new StringBuffer();
 			buffer.append('(').append(this.).append('.').append(this.).append(')');
 			return String.valueOf(buffer);
 		}
 	}
 
 	public static boolean VERBOSE = false;
Specifies the location of the package fragment roots within the zip (empty specifies the default root). null is not a valid root path.
 
 	protected ArrayList rootPaths;

The binary type source is being mapped for
 
 	protected BinaryType binaryType;

The location of the zip file containing source.
 
 	protected IPath sourcePath;
Specifies the location of the package fragment root within the zip (empty specifies the default root). null is not a valid root path.
 
 	protected String rootPath = ""//$NON-NLS-1$
 
Table that maps a binary method to its parameter names. Keys are the method handles, entries are char[][].
 
 	protected HashMap parameterNames;

Table that maps a binary element to its SourceRanges. Keys are the element handles, entries are SourceRange[] which is a two element array; the first being source range, the second being name range.
 
 	protected HashMap sourceRanges;
 
 	/*
 	 * A map from IJavaElement to String[]
 	 */
 	protected HashMap categories;

Table that contains all source ranges for local variables. Keys are the special local variable elements, entries are char[][].
 
 	protected HashMap parametersRanges;

Set that contains all final local variables.
 
 	protected HashSet finalParameters;

The unknown source range {-1, 0}
 
 	public static final SourceRange UNKNOWN_RANGE = new SourceRange(-1, 0);

The position within the source of the start of the current member element, or -1 if we are outside a member.
 
 	protected int[] memberDeclarationStart;
The SourceRange of the name of the current member element.
 
 	protected SourceRange[] memberNameRange;
The name of the current member element.
 
 	protected String[] memberName;

The parameter names for the current member method element.
 
 	protected char[][][] methodParameterNames;

The parameter types for the current member method element.
 
 	protected char[][][] methodParameterTypes;


The element searched for
 
imports references
 
 	private HashMap importsTable;
Enclosing type information
 
 	int[] typeModifiers;
 	int typeDepth;

Anonymous counter in case we want to map the source of an anonymous class.
 
 
Options to be used
 
Use to handle root paths inference
 
 	private boolean areRootPathsComputed;
 
 	public SourceMapper() {
 		this. = false;
 	}
 
 	public SourceMapper(IPath sourcePathString rootPathMap options) {
 		this(sourcePathrootPathoptionsnull);
 	}
Creates a SourceMapper that locates source in the zip file at the given location in the specified package fragment root.
 
 	public SourceMapper(IPath sourcePathString rootPathMap optionsString encoding) {
 		this. = false;
 		this. = options;
 		this. = encoding;
 		try {
 			this. = ResourcesPlugin.getWorkspace().getRoot().getDefaultCharset();
 		} catch (CoreException e) {
 			// use no encoding
 		}
 		if (rootPath != null) {
 			this. = new ArrayList();
 			this..add(rootPath);
 		}
 		this. = sourcePath;
 		this. = new HashMap();
 		this. = new HashMap();
 		this. = new HashMap();
 		this. = new HashMap();
 		this. = new HashMap();
 	}

See also:
ISourceElementRequestor
 
 	public void acceptImport(
 			int declarationStart,
 			int declarationEnd,
 			int nameStart,
 			int nameEnd,
 			char[][] tokens,
 			boolean onDemand,
 			int modifiers) {
 		char[][] imports = (char[][]) this..get(this.);
 		int importsCounter;
 		if (imports == null) {
 			imports = new char[5][];
 			importsCounter = 0;
 		} else {
 			importsCounter = ((Integerthis..get(this.)).intValue();
 		}
 		if (imports.length == importsCounter) {
 			System.arraycopy(
 				imports,
 				0,
 				(imports = new char[importsCounter * 2][]),
 				0,
 				importsCounter);
 		}
 		char[] name = CharOperation.concatWith(tokens'.');
 		if (onDemand) {
 			int nameLength = name.length;
 			System.arraycopy(name, 0, (name = new char[nameLength + 2]), 0, nameLength);
 			name[nameLength] = '.';
 			name[nameLength + 1] = '*';
 		}
 		imports[importsCounter++] = name;
 		this..put(this.imports);
 		this..put(this.new Integer(importsCounter));
 	}

See also:
ISourceElementRequestor
 
 	public void acceptLineSeparatorPositions(int[] positions) {
 		//do nothing
 	}

See also:
ISourceElementRequestor
 
 	public void acceptPackage(ImportReference importReference) {
 		//do nothing
 	}

See also:
ISourceElementRequestor
 
 	public void acceptProblem(CategorizedProblem problem) {
 		//do nothing
 	}
 
 	private void addCategories(IJavaElement elementchar[][] elementCategories) {
 		if (elementCategories == nullreturn;
 		if (this. == null)
 			this. = new HashMap();
 		this..put(element, CharOperation.toStrings(elementCategories));
 	}

Closes this SourceMapper's zip file. Once this is done, this SourceMapper cannot be used again.
 
 	public void close() {
 		this. = null;
 		this. = null;
 		this. = null;
 		this. = null;
 	}

NOT API, public only for access by Unit tests. Converts these type names to unqualified signatures. This needs to be done in order to be consistent with the way the source range is retrieved.

See also:
SourceMapper.getUnqualifiedMethodHandle
Signature
 
 	public String[] convertTypeNamesToSigs(char[][] typeNames) {
 		if (typeNames == null)
 		int n = typeNames.length;
 		if (n == 0)
 		String[] typeSigs = new String[n];
 		for (int i = 0; i < n; ++i) {
 			char[] typeSig = Signature.createCharArrayTypeSignature(typeNames[i], false);
 
 			// transforms signatures that contains a qualification into unqualified signatures
 			// e.g. "QX<+QMap.Entry;>;" becomes "QX<+QEntry;>;"
 			StringBuffer simpleTypeSig = null;
 			int start = 0;
 			int dot = -1;
 			int length = typeSig.length;
 			for (int j = 0; j < lengthj++) {
 				switch (typeSig[j]) {
 						if (simpleTypeSig != null)
 							simpleTypeSig.append(typeSigstartj-start);
 						start = j;
 						break;
 						dot = j;
 						break;
 						int matchingEnd = findMatchingGenericEnd(typeSigj+1);
 						if (matchingEnd > 0 && matchingEnd+1 < length && typeSig[matchingEnd+1] == .) {
 							// found Head<Param>.Tail -> discard everything except Tail
 							if (simpleTypeSig == null)
 								simpleTypeSig = new StringBuffer().append(typeSig, 0, start);
 							simpleTypeSig.append(.);
 							start = j = matchingEnd+2;
 							break;
 						}
 						//$FALL-THROUGH$
 						if (dot > start) {
 							if (simpleTypeSig == null)
 								simpleTypeSig = new StringBuffer().append(typeSig, 0, start);
 							simpleTypeSig.append(.);
 							simpleTypeSig.append(typeSigdot+1, j-dot-1);
 							start = j;
 						}
 						break;
 				}
 			}
 			if (simpleTypeSig == null) {
 				typeSigs[i] = new String(typeSig);
 			} else {
 				simpleTypeSig.append(typeSigstartlength-start);
 				typeSigs[i] = simpleTypeSig.toString();
 			}
 		}
 		return typeSigs;
 	}
 
 	private int findMatchingGenericEnd(char[] sigint start) {
 		int nesting = 0;
 		int length = sig.length;
 		for (int i=starti < lengthi++) {
 			switch (sig[i]) {
 					nesting++;
 					break;
 					if (nesting == 0)
 						return i;
 					nesting--;
 					break;
 			}
 		}
 		return -1;
 	}
 
 	private synchronized void computeAllRootPaths(IType type) {
 		if (this.) {
 			return;
 		}
 		IPath pkgFragmentRootPath = root.getPath();
 		final HashSet tempRoots = new HashSet();
 		long time = 0;
 		if () {
 			..println("compute all root paths for " + root.getElementName()); //$NON-NLS-1$
 			time = System.currentTimeMillis();
 		}
 		final HashSet firstLevelPackageNames = new HashSet();
 		boolean containsADefaultPackage = false;
 		boolean containsJavaSource = !pkgFragmentRootPath.equals(this.); // used to optimize zip file reading only if source path and root path are equals, otherwise assume that attachment contains Java source
 
 		String sourceLevel = null;
 		String complianceLevel = null;
 		if (root.isArchive()) {
 			JavaModelManager manager = JavaModelManager.getJavaModelManager();
 			ZipFile zip = null;
 			try {
 				zip = manager.getZipFile(pkgFragmentRootPath);
 				for (Enumeration entries = zip.entries(); entries.hasMoreElements(); ) {
 					ZipEntry entry = (ZipEntryentries.nextElement();
 					String entryName = entry.getName();
 					if (!entry.isDirectory()) {
 						if (Util.isClassFileName(entryName)) {
 							int index = entryName.indexOf('/');
 							if (index != -1) {
 								String firstLevelPackageName = entryName.substring(0, index);
 								if (!firstLevelPackageNames.contains(firstLevelPackageName)) {
 									if (sourceLevel == null) {
 										IJavaProject project = root.getJavaProject();
 										sourceLevel = project.getOption(.true);
 										complianceLevel = project.getOption(.true);
 									}
 									IStatus status = JavaConventions.validatePackageName(firstLevelPackageNamesourceLevelcomplianceLevel);
 									if (status.isOK() || status.getSeverity() == IStatus.WARNING) {
 										firstLevelPackageNames.add(firstLevelPackageName);
 									}
 								}
 							} else {
 								containsADefaultPackage = true;
 							}
 						} else if (!containsJavaSource && org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(entryName)) {
 							containsJavaSource = true;
 						}
 					}
 				}
 			} catch (CoreException e) {
 				// ignore
 			} finally {
 				manager.closeZipFile(zip); // handle null case
 			}
 		} else {
 			Object target = JavaModel.getTarget(root.getPath(), true);
 			if (target instanceof IResource) {
 				IResource resource = (IResource) target;
 				if (resource instanceof IContainer) {
 					try {
 						IResource[] members = ((IContainer) resource).members();
 						for (int i = 0, max = members.length; i < maxi++) {
 							IResource member = members[i];
 							String resourceName = member.getName();
 							if (member.getType() == IResource.FOLDER) {
 								if (sourceLevel == null) {
 									IJavaProject project = root.getJavaProject();
 									sourceLevel = project.getOption(.true);
 									complianceLevel = project.getOption(.true);
 								}
 								IStatus status = JavaConventions.validatePackageName(resourceNamesourceLevelcomplianceLevel);
 								if (status.isOK() || status.getSeverity() == IStatus.WARNING) {
 									firstLevelPackageNames.add(resourceName);
 								}
 							} else if (Util.isClassFileName(resourceName)) {
 								containsADefaultPackage = true;
 							} else if (!containsJavaSource && org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(resourceName)) {
 								containsJavaSource = true;
 							}
 						}
 					} catch (CoreException e) {
 						// ignore
 					}
 				}
 			}
 		}
 
 		if (containsJavaSource) { // no need to read source attachment if it contains no Java source (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=190840 )
 			Object target = JavaModel.getTarget(this.true);
 			if (target instanceof IContainer) {
 				IContainer folder = (IContainer)target;
 				computeRootPath(folderfirstLevelPackageNamescontainsADefaultPackagetempRootsfolder.getFullPath().segmentCount()/*if external folder, this is the linked folder path*/);
 			} else {
 				JavaModelManager manager = JavaModelManager.getJavaModelManager();
 				ZipFile zip = null;
 				try {
 					zip = manager.getZipFile(this.);
 					for (Enumeration entries = zip.entries(); entries.hasMoreElements(); ) {
 						ZipEntry entry = (ZipEntryentries.nextElement();
 						String entryName;
 						if (!entry.isDirectory() && org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(entryName = entry.getName())) {
 							IPath path = new Path(entryName);
 							int segmentCount = path.segmentCount();
 							if (segmentCount > 1) {
 								for (int i = 0, max = path.segmentCount() - 1; i < maxi++) {
 									if (firstLevelPackageNames.contains(path.segment(i))) {
 										tempRoots.add(path.uptoSegment(i));
 										// don't break here as this path could contain other first level package names (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=74014)
 									}
 									if (i == max - 1 && containsADefaultPackage) {
 										tempRoots.add(path.uptoSegment(max));
 									}
 								}
 							} else if (containsADefaultPackage) {
 								tempRoots.add(new Path("")); //$NON-NLS-1$
 							}
 						}
 					}
 				} catch (CoreException e) {
 					// ignore
 				} finally {
 					manager.closeZipFile(zip); // handle null case
 				}
 			}
 		}
 		int size = tempRoots.size();
 		if (this. != null) {
 			for (Iterator iterator = this..iterator(); iterator.hasNext(); ) {
 				tempRoots.add(new Path((Stringiterator.next()));
 			}
 			this..clear();
 		} else {
 			this. = new ArrayList(size);
 		}
 		size = tempRoots.size();
 		if (size > 0) {
 			ArrayList sortedRoots = new ArrayList(tempRoots);
 			if (size > 1) {
 				Collections.sort(sortedRootsnew Comparator() {
 					public int compare(Object o1Object o2) {
 						IPath path1 = (IPath) o1;
 						IPath path2 = (IPath) o2;
 						return path1.segmentCount() - path2.segmentCount();
 					}
 				});
 			}
 			for (Iterator iter = sortedRoots.iterator(); iter.hasNext();) {
 				IPath path = (IPath) iter.next();
 				this..add(path.toString());
 			}
 		}
 		this. = true;
 		if () {
 			..println("Spent " + (System.currentTimeMillis() - time) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
 			..println("Found " + size + " root paths");	//$NON-NLS-1$ //$NON-NLS-2$
 			int i = 0;
 			for (Iterator iterator = this..iterator(); iterator.hasNext();) {
 				..println("root[" + i + "]=" + ((Stringiterator.next()));//$NON-NLS-1$ //$NON-NLS-2$
 				i++;
 			}
 		}
 	}
 
 	private void computeRootPath(IContainer containerHashSet firstLevelPackageNamesboolean hasDefaultPackageSet setint sourcePathSegmentCount) {
 		try {
 			IResource[] resources = container.members();
 			for (int i = 0, max = resources.length; i < maxi++) {
 				IResource resource = resources[i];
 				if (resource.getType() == IResource.FOLDER) {
 					if (firstLevelPackageNames.contains(resource.getName())) {
 						IPath fullPath = container.getFullPath();
 						IPath rootPathEntry = fullPath.removeFirstSegments(sourcePathSegmentCount).setDevice(null);
 						if (rootPathEntry.segmentCount() >= 1) {
 							set.add(rootPathEntry);
 						}
 						computeRootPath((IFolder) resourcefirstLevelPackageNameshasDefaultPackagesetsourcePathSegmentCount);
 					} else {
 						computeRootPath((IFolder) resourcefirstLevelPackageNameshasDefaultPackagesetsourcePathSegmentCount);
 					}
 				}
 				if (i == max - 1 && hasDefaultPackage) {
 					// check if one member is a .java file
 					boolean hasJavaSourceFile = false;
 					for (int j = 0; j < maxj++) {
 						if (org.eclipse.jdt.internal.core.util.Util.isJavaLikeFileName(resources[i].getName())) {
 							hasJavaSourceFile = true;
 							break;
 						}
 					}
 					if (hasJavaSourceFile) {
 						IPath fullPath = container.getFullPath();
 						IPath rootPathEntry = fullPath.removeFirstSegments(sourcePathSegmentCount).setDevice(null);
 						set.add(rootPathEntry);
 					}
 				}
 			}
 		} catch (CoreException e) {
 			// ignore
 			e.printStackTrace();
 		}
 	}

See also:
ISourceElementRequestor
 
 	public void enterType(TypeInfo typeInfo) {
 
 		this.++;
 		if (this. == this..length) { // need to grow
 			System.arraycopy(
 				this.,
 				0,
 				this. = new IType[this. * 2],
 				0,
 				this.);
 			System.arraycopy(
 				0,
 				this. = new SourceRange[this. * 2],
 				0,
 				this.);
 			System.arraycopy(
 				0,
 				this. = new int[this. * 2],
 				0,
 				this.);
 			System.arraycopy(
 				this.,
 				0,
 				this. = new String[this. * 2],
 				0,
 				this.);
 			System.arraycopy(
 				0,
 				this. = new int[this. * 2],
 				0,
 				this.);
 			System.arraycopy(
 				0,
 				this. = new SourceRange[this. * 2],
 				0,
 				this.);
 			System.arraycopy(
 				0,
 				this. = new char[this. * 2][][],
 				0,
 				this.);
 			System.arraycopy(
 				0,
 				this. = new char[this. * 2][][],
 				0,
 				this.);
 			System.arraycopy(
 				0,
 				this. = new int[this. * 2],
 				0,
 				this.);
 		}
 		if (typeInfo.name.length == 0) {
 			if (this. == this.) {
 			} else {
 				this.[this.] = getType(new String(typeInfo.name));
 			}
 		} else {
 			this.[this.] = getType(new String(typeInfo.name));
 		}
 		this.[this.] =
 			new SourceRange(typeInfo.nameSourceStarttypeInfo.nameSourceEnd - typeInfo.nameSourceStart + 1);
 		this.[this.] = typeInfo.declarationStart;
 
 		IType currentType = this.[this.];
 
 		// type parameters
 		if (typeInfo.typeParameters != null) {
 			for (int i = 0, length = typeInfo.typeParameters.lengthi < lengthi++) {
 				TypeParameterInfo typeParameterInfo = typeInfo.typeParameters[i];
 				ITypeParameter typeParameter = currentType.getTypeParameter(new String(typeParameterInfo.name));
 					typeParameter,
 						typeParameterInfo.declarationStart,
 						typeParameterInfo.declarationEnd - typeParameterInfo.declarationStart + 1),
 						typeParameterInfo.nameSourceStart,
 						typeParameterInfo.nameSourceEnd - typeParameterInfo.nameSourceStart + 1));
 			}
 		}
 
 		// type modifiers
 		this.[this.] = typeInfo.modifiers;
 
 		// categories
 		addCategories(currentTypetypeInfo.categories);
 	}

See also:
ISourceElementRequestor
 
 	public void enterCompilationUnit() {
 		// do nothing
 	}

See also:
ISourceElementRequestor
 
 	public void enterConstructor(MethodInfo methodInfo) {
 		enterAbstractMethod(methodInfo);
 	}

See also:
ISourceElementRequestor
 
 	public void enterField(FieldInfo fieldInfo) {
 		if (this. >= 0) {
 			this.[this.] = fieldInfo.declarationStart;
 			this.[this.] =
 				new SourceRange(fieldInfo.nameSourceStartfieldInfo.nameSourceEnd - fieldInfo.nameSourceStart + 1);
 			String fieldName = new String(fieldInfo.name);
 			this.[this.] = fieldName;
 
 			// categories
 			IType currentType = this.[this.];
 			IField field = currentType.getField(fieldName);
 			addCategories(fieldfieldInfo.categories);
 		}
 	}

See also:
ISourceElementRequestor
 
 	public void enterInitializer(
 		int declarationSourceStart,
 		int modifiers) {
 		//do nothing
 	}

See also:
ISourceElementRequestor
 
 	public void enterMethod(MethodInfo methodInfo) {
 		enterAbstractMethod(methodInfo);
 	}
 	private void enterAbstractMethod(MethodInfo methodInfo) {
 		if (this. >= 0) {
 			this.[this.] = new String(methodInfo.name);
 			this.[this.] =
 				new SourceRange(methodInfo.nameSourceStartmethodInfo.nameSourceEnd - methodInfo.nameSourceStart + 1);
 			this.[this.] = methodInfo.declarationStart;
 			IType currentType = this.[this.];
 			int currenTypeModifiers = this.[this.];
 			char[][] parameterTypes = methodInfo.parameterTypes;
 			if (methodInfo.isConstructor && currentType.getDeclaringType() != null && !Flags.isStatic(currenTypeModifiers)) {
 				IType declaringType = currentType.getDeclaringType();
 				String declaringTypeName = declaringType.getElementName();
 				if (declaringTypeName.length() == 0) {
 					IClassFile classFile = declaringType.getClassFile();
 					int length = parameterTypes != null ? parameterTypes.length : 0;
 					char[][] newParameterTypes = new char[length+1][];
 					declaringTypeName = classFile.getElementName();
 					declaringTypeName = declaringTypeName.substring(0, declaringTypeName.indexOf('.'));
 					newParameterTypes[0] = declaringTypeName.toCharArray();
 					if (length != 0) {
 						System.arraycopy(parameterTypes, 0, newParameterTypes, 1, length);
 					}
 					this.[this.] = newParameterTypes;
 				} else {
 					int length = parameterTypes != null ? parameterTypes.length : 0;
 					char[][] newParameterTypes = new char[length+1][];
 					newParameterTypes[0] = declaringTypeName.toCharArray();
 					if (length != 0) {
 						System.arraycopy(parameterTypes, 0, newParameterTypes, 1, length);
 					}
 					this.[this.] = newParameterTypes;
 				}
 			} else {
 				this.[this.] = parameterTypes;
 			}
 			this.[this.] = methodInfo.parameterNames;
 
 			IMethod method = currentType.getMethod(
 					this.[this.],
 
 			// type parameters
 			if (methodInfo.typeParameters != null) {
 				for (int i = 0, length = methodInfo.typeParameters.lengthi < lengthi++) {
 					TypeParameterInfo typeParameterInfo = methodInfo.typeParameters[i];
 					ITypeParameter typeParameter = method.getTypeParameter(new String(typeParameterInfo.name));
 						typeParameter,
 							typeParameterInfo.declarationStart,
 							typeParameterInfo.declarationEnd - typeParameterInfo.declarationStart + 1),
 							typeParameterInfo.nameSourceStart,
 							typeParameterInfo.nameSourceEnd - typeParameterInfo.nameSourceStart + 1));
 				}
 			}
 			// parameters infos
 			if (methodInfo.parameterInfos != null) {
 				for (int i = 0, length = methodInfo.parameterInfos.lengthi < lengthi++) {
 					ParameterInfo parameterInfo = methodInfo.parameterInfos[i];
 					LocalVariableElementKey key = new LocalVariableElementKey(methodnew String(parameterInfo.name));
 					SourceRange[] allRanges = new SourceRange[] {
 							parameterInfo.declarationStart,
 							parameterInfo.declarationEnd - parameterInfo.declarationStart + 1),
 							parameterInfo.nameSourceStart,
 							parameterInfo.nameSourceEnd - parameterInfo.nameSourceStart + 1)
 					};
 						key,
 						allRanges);
 					if (parameterInfo.modifiers != 0) {
 						if (this. == null) {
 							this. = new HashSet();
 						}
 						this..add(key);
 					}
 				}
 			}
 
 			// categories
 			addCategories(methodmethodInfo.categories);
 		}
 	}

See also:
ISourceElementRequestor
 
 	public void exitType(int declarationEnd) {
 		if (this. >= 0) {
 			IType currentType = this.[this.];
 				currentType,
 					declarationEnd - this.[this.] + 1),
 			this.--;
 		}
 	}

See also:
ISourceElementRequestor
 
 	public void exitCompilationUnit(int declarationEnd) {
 		//do nothing
 	}

See also:
ISourceElementRequestor
 
 	public void exitConstructor(int declarationEnd) {
 		exitAbstractMethod(declarationEnd);
 	}

See also:
ISourceElementRequestor
 
 	public void exitField(int initializationStartint declarationEndint declarationSourceEnd) {
 		if (this. >= 0) {
 			IType currentType = this.[this.];
 				currentType.getField(this.[this.]),
 					declarationEnd - this.[this.] + 1),
 		}
 	}

See also:
ISourceElementRequestor
 
 	public void exitInitializer(int declarationEnd) {
 		// implements abstract method
 	}

See also:
ISourceElementRequestor
 
 	public void exitMethod(int declarationEndExpression defaultValue) {
 		exitAbstractMethod(declarationEnd);
 	}
 	private void exitAbstractMethod(int declarationEnd) {
 		if (this. >= 0) {
 			IType currentType = this.[this.];
 			SourceRange sourceRange =
 					declarationEnd - this.[this.] + 1);
 			IMethod method = currentType.getMethod(
 					this.[this.],
 				method,
 				sourceRange,
 				method,
 		}
 	}

Locates and returns source code for the given (binary) type, in this SourceMapper's ZIP file, or returns null if source code cannot be found.
 
 	public char[] findSource(IType typeIBinaryType info) {
 		if (!type.isBinary()) {
 			return null;
 		}
 		String simpleSourceFileName = ((BinaryTypetype).getSourceFileName(info);
 		if (simpleSourceFileName == null) {
 			return null;
 		}
 		return findSource(typesimpleSourceFileName);
 	}

Locates and returns source code for the given (binary) type, in this SourceMapper's ZIP file, or returns null if source code cannot be found. The given simpleSourceFileName is the .java file name (without the enclosing folder) used to create the given type (e.g. "A.java" for x/y/A$Inner.class)
 
 	public char[] findSource(IType typeString simpleSourceFileName) {
 		long time = 0;
 		if () {
 			time = System.currentTimeMillis();
 		}
 		String name = org.eclipse.jdt.internal.core.util.Util.concatWith(pkgFrag.namessimpleSourceFileName'/');
		char[] source = null;
		JavaModelManager javaModelManager = JavaModelManager.getJavaModelManager();
		try {
			javaModelManager.cacheZipFiles(this); // Cache any zip files we open during this operation
			if (this. != null) {
				source = getSourceForRootPath(this.name);
			if (source == null) {
				if (this. != null) {
					loop: for (Iterator iterator = this..iterator(); iterator.hasNext(); ) {
						String currentRootPath = (Stringiterator.next();
						if (!currentRootPath.equals(this.)) {
							source = getSourceForRootPath(currentRootPathname);
							if (source != null) {
								// remember right root path
								this. = currentRootPath;
								break loop;
finally {
			javaModelManager.flushZipFiles(this); // clean up cached zip files.
		if () {
			..println("spent " + (System.currentTimeMillis() - time) + "ms for " + type.getElementName()); //$NON-NLS-1$ //$NON-NLS-2$
		return source;
	private char[] getSourceForRootPath(String currentRootPathString name) {
		String newFullName;
			if (currentRootPath.endsWith("/")) { //$NON-NLS-1$
				newFullName = currentRootPath + name;
else {
				newFullName = currentRootPath + '/' + name;
else {
			newFullName = name;
		return this.findSource(newFullName);
	public char[] findSource(String fullName) {
		char[] source = null;
		Object target = JavaModel.getTarget(this.true);
		String charSet = null;
		if (target instanceof IContainer) {
			IResource res = ((IContainer)target).findMember(fullName);
			if (res instanceof IFile) {
				try {
					// Order of preference: charSet supplied, this.encoding or this.defaultEncoding in that order
					try {
						// Use the implicit encoding only when the source attachment's encoding hasn't been explicitly set.
						charSet = ((IFile) res).getCharset(this. == null);
catch (CoreException e) {
						// Ignore
					source = org.eclipse.jdt.internal.core.util.Util.getResourceContentsAsCharArray((IFile) res,
									charSet == null ? (this. == null ? this. : this.) : charSet);
catch (JavaModelException e) {
					// Ignore
else {
			try {
				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=303511
				// For a resource inside the workspace, use the encoding set on the resource
				if (target instanceof IFile)
					charSet = ((IFile)target).getCharset(this. == null);
catch (CoreException e) {
				// Ignore
			// try to get the entry
			ZipEntry entry = null;
			ZipFile zip = null;
			JavaModelManager manager = JavaModelManager.getJavaModelManager();
			try {
				zip = manager.getZipFile(this.);
				entry = zip.getEntry(fullName);
				if (entry != null) {
					// now read the source code
					source = readSource(entryzipcharSet);
catch (CoreException e) {
				return null;
finally {
				manager.closeZipFile(zip); // handle null case
		return source;
	public int getFlags(IJavaElement element) {
		switch(element.getElementType()) {
				if (this. != null && this..contains(key)) {
		return 0;
	}

Returns the SourceRange for the name of the given element, or {-1, -1} if no source range is known for the name of the element.
		switch(element.getElementType()) {
				if (((IMemberelement).isBinary()) {
					IJavaElement[] el = getUnqualifiedMethodHandle((IMethodelementfalse);
					if(el[1] != null && this..get(el[0]) == null) {
						element = getUnqualifiedMethodHandle((IMethodelementtrue)[0];
else {
						element = el[0];
				break;
				IJavaElement parent = element.getParent();
				if (parent.getElementType() == .) {
					IMethod method = (IMethodparent;
					if (method.isBinary()) {
						IJavaElement[] el = getUnqualifiedMethodHandle(methodfalse);
						if(el[1] != null && this..get(el[0]) == null) {
							method = (IMethodgetUnqualifiedMethodHandle(methodtrue)[0];
else {
							method = (IMethodel[0];
						element = method.getTypeParameter(element.getElementName());
				break;
				SourceRange[] ranges = (SourceRange[]) this..get(key);
				if (ranges == null) {
else {
					return ranges[1];
		SourceRange[] ranges = (SourceRange[]) this..get(element);
		if (ranges == null) {
else {
			return ranges[1];
	}

Returns parameters names for the given method, or null if no parameter names are known for the method.
	public char[][] getMethodParameterNames(IMethod method) {
		if (method.isBinary()) {
			IJavaElement[] el = getUnqualifiedMethodHandle(methodfalse);
			if(el[1] != null && this..get(el[0]) == null) {
				method = (IMethodgetUnqualifiedMethodHandle(methodtrue)[0];
else {
				method = (IMethodel[0];
		char[][] parameters = (char[][]) this..get(method);
		if (parameters == null) {
			return null;
else {
			return parameters;
	}

Returns the SourceRange for the given element, or {-1, -1} if no source range is known for the element.
		switch(element.getElementType()) {
				if (((IMemberelement).isBinary()) {
					IJavaElement[] el = getUnqualifiedMethodHandle((IMethodelementfalse);
					if(el[1] != null && this..get(el[0]) == null) {
						element = getUnqualifiedMethodHandle((IMethodelementtrue)[0];
else {
						element = el[0];
				break;
				IJavaElement parent = element.getParent();
				if (parent.getElementType() == .) {
					IMethod method = (IMethodparent;
					if (method.isBinary()) {
						IJavaElement[] el = getUnqualifiedMethodHandle(methodfalse);
						if(el[1] != null && this..get(el[0]) == null) {
							method = (IMethodgetUnqualifiedMethodHandle(methodtrue)[0];
else {
							method = (IMethodel[0];