<s> package org . eclipse . jdt . internal . core ; import java . io . IOException ; import java . util . ArrayList ; import java . util . Collections ; import java . util . Comparator ; import java . util . Enumeration ; import java . util . HashMap ; import java . util . HashSet ; import java . util . Iterator ; import java . util . Map ; import java . util . Set ; import java . util . zip . ZipEntry ; import java . util . zip . ZipFile ; import org . codehaus . jdt . groovy . integration . LanguageSupportFactory ; import org . eclipse . core . resources . IContainer ; import org . eclipse . core . resources . IFile ; import org . eclipse . core . resources . IFolder ; import org . eclipse . core . resources . IProject ; 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 ; import org . eclipse . jdt . core . Flags ; import org . eclipse . jdt . core . IClassFile ; import org . eclipse . jdt . core . IField ; import org . eclipse . jdt . core . IJavaElement ; import org . eclipse . jdt . core . IJavaProject ; import org . eclipse . jdt . core . IMember ; import org . eclipse . jdt . core . IMethod ; import org . eclipse . jdt . core . IPackageFragmentRoot ; import org . eclipse . jdt . core . ISourceRange ; import org . eclipse . jdt . core . IType ; import org . eclipse . jdt . core . ITypeParameter ; import org . eclipse . jdt . core . JavaConventions ; import org . eclipse . jdt . core . JavaCore ; import org . eclipse . jdt . core . JavaModelException ; import org . eclipse . jdt . core . Signature ; import org . eclipse . jdt . core . SourceRange ; import org . eclipse . jdt . core . compiler . CategorizedProblem ; import org . eclipse . jdt . core . compiler . CharOperation ; import org . eclipse . jdt . internal . compiler . IProblemFactory ; import org . eclipse . jdt . internal . compiler . ISourceElementRequestor ; import org . eclipse . jdt . internal . compiler . SourceElementParser ; import org . eclipse . jdt . internal . compiler . ast . Expression ; import org . eclipse . jdt . internal . compiler . ast . ImportReference ; import org . eclipse . jdt . internal . compiler . env . IBinaryType ; import org . eclipse . jdt . internal . compiler . impl . CompilerOptions ; import org . eclipse . jdt . internal . compiler . problem . DefaultProblemFactory ; import org . eclipse . jdt . internal . compiler . util . SuffixConstants ; import org . eclipse . jdt . internal . compiler . util . Util ; import org . eclipse . jdt . internal . core . util . ReferenceInfoAdapter ; public class SourceMapper extends ReferenceInfoAdapter implements ISourceElementRequestor , SuffixConstants { public static boolean VERBOSE = false ; protected ArrayList rootPaths ; protected BinaryType binaryType ; protected IPath sourcePath ; protected String rootPath = "" ; protected HashMap parameterNames ; protected HashMap sourceRanges ; protected HashMap categories ; public static final SourceRange UNKNOWN_RANGE = new SourceRange ( - 1 , 0 ) ; protected int [ ] memberDeclarationStart ; protected SourceRange [ ] memberNameRange ; protected String [ ] memberName ; protected char [ ] [ ] [ ] methodParameterNames ; protected char [ ] [ ] [ ] methodParameterTypes ; protected IJavaElement searchedElement ; private HashMap importsTable ; private HashMap importsCounterTable ; IType [ ] types ; int [ ] typeDeclarationStarts ; SourceRange [ ] typeNameRanges ; int [ ] typeModifiers ; int typeDepth ; int anonymousCounter ; int anonymousClassName ; String encoding ; Map options ; private boolean areRootPathsComputed ; public SourceMapper ( ) { this . areRootPathsComputed = false ; } public SourceMapper ( IPath sourcePath , String rootPath , Map options ) { this . areRootPathsComputed = false ; this . options = options ; try { this . encoding = ResourcesPlugin . getWorkspace ( ) . getRoot ( ) . getDefaultCharset ( ) ; } catch ( CoreException e ) { } if ( rootPath != null ) { this . rootPaths = new ArrayList ( ) ; this . rootPaths . add ( rootPath ) ; } this . sourcePath = sourcePath ; this . sourceRanges = new HashMap ( ) ; this . parameterNames = new HashMap ( ) ; this . importsTable = new HashMap ( ) ; this . importsCounterTable = new HashMap ( ) ; } public void acceptImport ( int declarationStart , int declarationEnd , char [ ] [ ] tokens , boolean onDemand , int modifiers ) { char [ ] [ ] imports = ( char [ ] [ ] ) this . importsTable . get ( this . binaryType ) ; int importsCounter ; if ( imports == null ) { imports = new char [ 5 ] [ ] ; importsCounter = 0 ; } else { importsCounter = ( ( Integer ) this . importsCounterTable . get ( this . binaryType ) ) . 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 . importsTable . put ( this . binaryType , imports ) ; this . importsCounterTable . put ( this . binaryType , new Integer ( importsCounter ) ) ; } public void acceptLineSeparatorPositions ( int [ ] positions ) { } public void acceptPackage ( ImportReference importReference ) { } public void acceptProblem ( CategorizedProblem problem ) { } private void addCategories ( IJavaElement element , char [ ] [ ] elementCategories ) { if ( elementCategories == null ) return ; if ( this . categories == null ) this . categories = new HashMap ( ) ; this . categories . put ( element , CharOperation . toStrings ( elementCategories ) ) ; } public void close ( ) { this . sourceRanges = null ; this . parameterNames = null ; } private String [ ] convertTypeNamesToSigs ( char [ ] [ ] typeNames ) { if ( typeNames == null ) return CharOperation . NO_STRINGS ; int n = typeNames . length ; if ( n == 0 ) return CharOperation . NO_STRINGS ; String [ ] typeSigs = new String [ n ] ; for ( int i = 0 ; i < n ; ++ i ) { char [ ] typeSig = Signature . createCharArrayTypeSignature ( typeNames [ i ] , false ) ; StringBuffer simpleTypeSig = null ; int start = 0 ; int dot = - 1 ; int length = typeSig . length ; for ( int j = 0 ; j < length ; j ++ ) { switch ( typeSig [ j ] ) { case Signature . C_UNRESOLVED : if ( simpleTypeSig != null ) simpleTypeSig . append ( typeSig , start , j - start ) ; start = j ; break ; case Signature . C_DOT : dot = j ; break ; case Signature . C_GENERIC_START : case Signature . C_NAME_END : if ( dot > start ) { if ( simpleTypeSig == null ) simpleTypeSig = new StringBuffer ( ) . append ( typeSig , 0 , start ) ; simpleTypeSig . append ( Signature . C_UNRESOLVED ) ; simpleTypeSig . append ( typeSig , dot + 1 , j - dot - 1 ) ; start = j ; } break ; } } if ( simpleTypeSig == null ) { typeSigs [ i ] = new String ( typeSig ) ; } else { simpleTypeSig . append ( typeSig , start , length - start ) ; typeSigs [ i ] = simpleTypeSig . toString ( ) ; } } return typeSigs ; } private synchronized void computeAllRootPaths ( IType type ) { if ( this . areRootPathsComputed ) { return ; } IPackageFragmentRoot root = ( IPackageFragmentRoot ) type . getPackageFragment ( ) . getParent ( ) ; IPath pkgFragmentRootPath = root . getPath ( ) ; final HashSet tempRoots = new HashSet ( ) ; long time = 0 ; if ( VERBOSE ) { System . out . println ( "" + root . getElementName ( ) ) ; time = System . currentTimeMillis ( ) ; } final HashSet firstLevelPackageNames = new HashSet ( ) ; boolean containsADefaultPackage = false ; boolean containsJavaSource = ! pkgFragmentRootPath . equals ( this . sourcePath ) ; 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 = ( ZipEntry ) entries . 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 ( JavaCore . COMPILER_SOURCE , true ) ; complianceLevel = project . getOption ( JavaCore . COMPILER_COMPLIANCE , true ) ; } IStatus status = JavaConventions . validatePackageName ( firstLevelPackageName , sourceLevel , complianceLevel ) ; 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 ) { } finally { manager . closeZipFile ( zip ) ; } } 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 < max ; i ++ ) { IResource member = members [ i ] ; String resourceName = member . getName ( ) ; if ( member . getType ( ) == IResource . FOLDER ) { if ( sourceLevel == null ) { IJavaProject project = root . getJavaProject ( ) ; sourceLevel = project . getOption ( JavaCore . COMPILER_SOURCE , true ) ; complianceLevel = project . getOption ( JavaCore . COMPILER_COMPLIANCE , true ) ; } IStatus status = JavaConventions . validatePackageName ( resourceName , sourceLevel , complianceLevel ) ; 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 ) { } } } } if ( containsJavaSource ) { Object target = JavaModel . getTarget ( this . sourcePath , true ) ; if ( target instanceof IContainer ) { IContainer folder = ( IContainer ) target ; computeRootPath ( folder , firstLevelPackageNames , containsADefaultPackage , tempRoots , folder . getFullPath ( ) . segmentCount ( ) ) ; } else { JavaModelManager manager = JavaModelManager . getJavaModelManager ( ) ; ZipFile zip = null ; try { zip = manager . getZipFile ( this . sourcePath ) ; for ( Enumeration entries = zip . entries ( ) ; entries . hasMoreElements ( ) ; ) { ZipEntry entry = ( ZipEntry ) entries . 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 < max ; i ++ ) { if ( firstLevelPackageNames . contains ( path . segment ( i ) ) ) { tempRoots . add ( path . uptoSegment ( i ) ) ; } if ( i == max - 1 && containsADefaultPackage ) { tempRoots . add ( path . uptoSegment ( max ) ) ; } } } else if ( containsADefaultPackage ) { tempRoots . add ( new Path ( "" ) ) ; } } } } catch ( CoreException e ) { } finally { manager . closeZipFile ( zip ) ; } } } int size = tempRoots . size ( ) ; if ( this . rootPaths != null ) { for ( Iterator iterator = this . rootPaths . iterator ( ) ; iterator . hasNext ( ) ; ) { tempRoots . add ( new Path ( ( String ) iterator . next ( ) ) ) ; } this . rootPaths . clear ( ) ; } else { this . rootPaths = new ArrayList ( size ) ; } size = tempRoots . size ( ) ; if ( size > 0 ) { ArrayList sortedRoots = new ArrayList ( tempRoots ) ; if ( size > 1 ) { Collections . sort ( sortedRoots , new Comparator ( ) { public int compare ( Object o1 , Object 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 . rootPaths . add ( path . toString ( ) ) ; } } this . areRootPathsComputed = true ; if ( VERBOSE ) { System . out . println ( "Spent " + ( System . currentTimeMillis ( ) - time ) + "ms" ) ; System . out . println ( "Found " + size + " root paths" ) ; int i = 0 ; for ( Iterator iterator = this . rootPaths . iterator ( ) ; iterator . hasNext ( ) ; ) { System . out . println ( "root[" + i + "]=" + ( ( String ) iterator . next ( ) ) ) ; i ++ ; } } } private void computeRootPath ( IContainer container , HashSet firstLevelPackageNames , boolean hasDefaultPackage , Set set , int sourcePathSegmentCount ) { try { IResource [ ] resources = container . members ( ) ; for ( int i = 0 , max = resources . length ; i < max ; i ++ ) { 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 ) resource , firstLevelPackageNames , hasDefaultPackage , set , sourcePathSegmentCount ) ; } else { computeRootPath ( ( IFolder ) resource , firstLevelPackageNames , hasDefaultPackage , set , sourcePathSegmentCount ) ; } } if ( i == max - 1 && hasDefaultPackage ) { boolean hasJavaSourceFile = false ; for ( int j = 0 ; j < max ; j ++ ) { 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 ) { e . printStackTrace ( ) ; } } public void enterType ( TypeInfo typeInfo ) { this . typeDepth ++ ; if ( this . typeDepth == this . types . length ) { System . arraycopy ( this . types , 0 , this . types = new IType [ this . typeDepth * 2 ] , 0 , this . typeDepth ) ; System . arraycopy ( this . typeNameRanges , 0 , this . typeNameRanges = new SourceRange [ this . typeDepth * 2 ] , 0 , this . typeDepth ) ; System . arraycopy ( this . typeDeclarationStarts , 0 , this . typeDeclarationStarts = new int [ this . typeDepth * 2 ] , 0 , this . typeDepth ) ; System . arraycopy ( this . memberName , 0 , this . memberName = new String [ this . typeDepth * 2 ] , 0 , this . typeDepth ) ; System . arraycopy ( this . memberDeclarationStart , 0 , this . memberDeclarationStart = new int [ this . typeDepth * 2 ] , 0 , this . typeDepth ) ; System . arraycopy ( this . memberNameRange , 0 , this . memberNameRange = new SourceRange [ this . typeDepth * 2 ] , 0 , this . typeDepth ) ; System . arraycopy ( this . methodParameterTypes , 0 , this . methodParameterTypes = new char [ this . typeDepth * 2 ] [ ] [ ] , 0 , this . typeDepth ) ; System . arraycopy ( this . methodParameterNames , 0 , this . methodParameterNames = new char [ this . typeDepth * 2 ] [ ] [ ] , 0 , this . typeDepth ) ; System . arraycopy ( this . typeModifiers , 0 , this . typeModifiers = new int [ this . typeDepth * 2 ] , 0 , this . typeDepth ) ; } if ( typeInfo . name . length == 0 ) { this . anonymousCounter ++ ; if ( this . anonymousCounter == this . anonymousClassName ) { this . types [ this . typeDepth ] = getType ( this . binaryType . getElementName ( ) ) ; } else { this . types [ this . typeDepth ] = getType ( new String ( typeInfo . name ) ) ; } } else { this . types [ this . typeDepth ] = getType ( new String ( typeInfo . name ) ) ; } this . typeNameRanges [ this . typeDepth ] = new SourceRange ( typeInfo . nameSourceStart , typeInfo . nameSourceEnd - typeInfo . nameSourceStart + 1 ) ; this . typeDeclarationStarts [ this . typeDepth ] = typeInfo . declarationStart ; IType currentType = this . types [ this . typeDepth ] ; if ( typeInfo . typeParameters != null ) { for ( int i = 0 , length = typeInfo . typeParameters . length ; i < length ; i ++ ) { TypeParameterInfo typeParameterInfo = typeInfo . typeParameters [ i ] ; ITypeParameter typeParameter = currentType . getTypeParameter ( new String ( typeParameterInfo . name ) ) ; setSourceRange ( typeParameter , new SourceRange ( typeParameterInfo . declarationStart , typeParameterInfo . declarationEnd - typeParameterInfo . declarationStart + 1 ) , new SourceRange ( typeParameterInfo . nameSourceStart , typeParameterInfo . nameSourceEnd - typeParameterInfo . nameSourceStart + 1 ) ) ; } } this . typeModifiers [ this . typeDepth ] = typeInfo . modifiers ; addCategories ( currentType , typeInfo . categories ) ; } public void enterCompilationUnit ( ) { } public void enterConstructor ( MethodInfo methodInfo ) { enterAbstractMethod ( methodInfo ) ; } public void enterField ( FieldInfo fieldInfo ) { if ( this . typeDepth >= 0 ) { this . memberDeclarationStart [ this . typeDepth ] = fieldInfo . declarationStart ; this . memberNameRange [ this . typeDepth ] = new SourceRange ( fieldInfo . nameSourceStart , fieldInfo . nameSourceEnd - fieldInfo . nameSourceStart + 1 ) ; String fieldName = new String ( fieldInfo . name ) ; this . memberName [ this . typeDepth ] = fieldName ; IType currentType = this . types [ this . typeDepth ] ; IField field = currentType . getField ( fieldName ) ; addCategories ( field , fieldInfo . categories ) ; } } public void enterInitializer ( int declarationSourceStart , int modifiers ) { } public void enterMethod ( MethodInfo methodInfo ) { enterAbstractMethod ( methodInfo ) ; } private void enterAbstractMethod ( MethodInfo methodInfo ) { if ( this . typeDepth >= 0 ) { this . memberName [ this . typeDepth ] = new String ( methodInfo . name ) ; this . memberNameRange [ this . typeDepth ] = new SourceRange ( methodInfo . nameSourceStart , methodInfo . nameSourceEnd - methodInfo . nameSourceStart + 1 ) ; this . memberDeclarationStart [ this . typeDepth ] = methodInfo . declarationStart ; IType currentType = this . types [ this . typeDepth ] ; int currenTypeModifiers = this . typeModifiers [ this . typeDepth ] ; 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 . methodParameterTypes [ this . typeDepth ] = 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 . methodParameterTypes [ this . typeDepth ] = newParameterTypes ; } } else { this . methodParameterTypes [ this . typeDepth ] = parameterTypes ; } this . methodParameterNames [ this . typeDepth ] = methodInfo . parameterNames ; IMethod method = currentType . getMethod ( this . memberName [ this . typeDepth ] , convertTypeNamesToSigs ( this . methodParameterTypes [ this . typeDepth ] ) ) ; if ( methodInfo . typeParameters != null ) { for ( int i = 0 , length = methodInfo . typeParameters . length ; i < length ; i ++ ) { TypeParameterInfo typeParameterInfo = methodInfo . typeParameters [ i ] ; ITypeParameter typeParameter = method . getTypeParameter ( new String ( typeParameterInfo . name ) ) ; setSourceRange ( typeParameter , new SourceRange ( typeParameterInfo . declarationStart , typeParameterInfo . declarationEnd - typeParameterInfo . declarationStart + 1 ) , new SourceRange ( typeParameterInfo . nameSourceStart , typeParameterInfo . nameSourceEnd - typeParameterInfo . nameSourceStart + 1 ) ) ; } } addCategories ( method , methodInfo . categories ) ; } } public void exitType ( int declarationEnd ) { if ( this . typeDepth >= 0 ) { IType currentType = this . types [ this . typeDepth ] ; setSourceRange ( currentType , new SourceRange ( this . typeDeclarationStarts [ this . typeDepth ] , declarationEnd - this . typeDeclarationStarts [ this . typeDepth ] + 1 ) , this . typeNameRanges [ this . typeDepth ] ) ; this . typeDepth -- ; } } public void exitCompilationUnit ( int declarationEnd ) { } public void exitConstructor ( int declarationEnd ) { exitAbstractMethod ( declarationEnd ) ; } public void exitField ( int initializationStart , int declarationEnd , int declarationSourceEnd ) { if ( this . typeDepth >= 0 ) { IType currentType = this . types [ this . typeDepth ] ; setSourceRange ( currentType . getField ( this . memberName [ this . typeDepth ] ) , new SourceRange ( this . memberDeclarationStart [ this . typeDepth ] , declarationEnd - this . memberDeclarationStart [ this . typeDepth ] + 1 ) , this . memberNameRange [ this . typeDepth ] ) ; } } public void exitInitializer ( int declarationEnd ) { } public void exitMethod ( int declarationEnd , Expression defaultValue ) { exitAbstractMethod ( declarationEnd ) ; } private void exitAbstractMethod ( int declarationEnd ) { if ( this . typeDepth >= 0 ) { IType currentType = this . types [ this . typeDepth ] ; SourceRange sourceRange = new SourceRange ( this . memberDeclarationStart [ this . typeDepth ] , declarationEnd - this . memberDeclarationStart [ this . typeDepth ] + 1 ) ; IMethod method = currentType . getMethod ( this . memberName [ this . typeDepth ] , convertTypeNamesToSigs ( this . methodParameterTypes [ this . typeDepth ] ) ) ; setSourceRange ( method , sourceRange , this . memberNameRange [ this . typeDepth ] ) ; setMethodParameterNames ( method , this . methodParameterNames [ this . typeDepth ] ) ; } } public char [ ] findSource ( IType type , IBinaryType info ) { if ( ! type . isBinary ( ) ) { return null ; } String simpleSourceFileName = ( ( BinaryType ) type ) . getSourceFileName ( info ) ; if ( simpleSourceFileName == null ) { return null ; } return findSource ( type , simpleSourceFileName ) ; } public char [ ] findSource ( IType type , String simpleSourceFileName ) { long time = 0 ; if ( VERBOSE ) { time = System . currentTimeMillis ( ) ; } PackageFragment pkgFrag = ( PackageFragment ) type . getPackageFragment ( ) ; String name = org . eclipse . jdt . internal . core . util . Util . concatWith ( pkgFrag . names , simpleSourceFileName , '/' ) ; char [ ] source = null ; JavaModelManager javaModelManager = JavaModelManager . getJavaModelManager ( ) ; try { javaModelManager . cacheZipFiles ( this ) ; if ( this . rootPath != null ) { source = getSourceForRootPath ( this . rootPath , name ) ; } if ( source == null ) { computeAllRootPaths ( type ) ; if ( this . rootPaths != null ) { loop : for ( Iterator iterator = this . rootPaths . iterator ( ) ; iterator . hasNext ( ) ; ) { String currentRootPath = ( String ) iterator . next ( ) ; if ( ! currentRootPath . equals ( this . rootPath ) ) { source = getSourceForRootPath ( currentRootPath , name ) ; if ( source != null ) { this . rootPath = currentRootPath ; break loop ; } } } } } } finally { javaModelManager . flushZipFiles ( this ) ; } if ( VERBOSE ) { System . out . println ( "spent " + ( System . currentTimeMillis ( ) - time ) + "ms for " + type . getElementName ( ) ) ; } return source ; } private char [ ] getSourceForRootPath ( String currentRootPath , String name ) { String newFullName ; if ( ! currentRootPath . equals ( IPackageFragmentRoot . DEFAULT_PACKAGEROOT_PATH ) ) { if ( currentRootPath . endsWith ( "/" ) ) { 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 . sourcePath , true ) ; if ( target instanceof IContainer ) { IResource res = ( ( IContainer ) target ) . findMember ( fullName ) ; if ( res instanceof IFile ) { try { source = org . eclipse . jdt . internal . core . util . Util . getResourceContentsAsCharArray ( ( IFile ) res ) ; } catch ( JavaModelException e ) { } } } else { ZipEntry entry = null ; ZipFile zip = null ; JavaModelManager manager = JavaModelManager . getJavaModelManager ( ) ; try { zip = manager . getZipFile ( this . sourcePath ) ; entry = zip . getEntry ( fullName ) ; if ( entry != null ) { source = readSource ( entry , zip ) ; } } catch ( CoreException e ) { return null ; } finally { manager . closeZipFile ( zip ) ; } } return source ; } public SourceRange getNameRange ( IJavaElement element ) { switch ( element . getElementType ( ) ) { case IJavaElement . METHOD : if ( ( ( IMember ) element ) . isBinary ( ) ) { IJavaElement [ ] el = getUnqualifiedMethodHandle ( ( IMethod ) element , false ) ; if ( el [ 1 ] != null && this . sourceRanges . get ( el [ 0 ] ) == null ) { element = getUnqualifiedMethodHandle ( ( IMethod ) element , true ) [ 0 ] ; } else { element = el [ 0 ] ; } } break ; case IJavaElement . TYPE_PARAMETER : IJavaElement parent = element . getParent ( ) ; if ( parent . getElementType ( ) == IJavaElement . METHOD ) { IMethod method = ( IMethod ) parent ; if ( method . isBinary ( ) ) { IJavaElement [ ] el = getUnqualifiedMethodHandle ( method , false ) ; if ( el [ 1 ] != null && this . sourceRanges . get ( el [ 0 ] ) == null ) { method = ( IMethod ) getUnqualifiedMethodHandle ( method , true ) [ 0 ] ; } else { method = ( IMethod ) el [ 0 ] ; } element = method . getTypeParameter ( element . getElementName ( ) ) ; } } } SourceRange [ ] ranges = ( SourceRange [ ] ) this . sourceRanges . get ( element ) ; if ( ranges == null ) { return UNKNOWN_RANGE ; } else { return ranges [ 1 ] ; } } public char [ ] [ ] getMethodParameterNames ( IMethod method ) { if ( method . isBinary ( ) ) { IJavaElement [ ] el = getUnqualifiedMethodHandle ( method , false ) ; if ( el [ 1 ] != null && this . parameterNames . get ( el [ 0 ] ) == null ) { method = ( IMethod ) getUnqualifiedMethodHandle ( method , true ) [ 0 ] ; } else { method = ( IMethod ) el [ 0 ] ; } } char [ ] [ ] parameters = ( char [ ] [ ] ) this . parameterNames . get ( method ) ; if ( parameters == null ) { return null ; } else { return parameters ; } } public SourceRange getSourceRange ( IJavaElement element ) { switch ( element . getElementType ( ) ) { case IJavaElement . METHOD : if ( ( ( IMember ) element ) . isBinary ( ) ) { IJavaElement [ ] el = getUnqualifiedMethodHandle ( ( IMethod ) element , false ) ; if ( el [ 1 ] != null && this . sourceRanges . get ( el [ 0 ] ) == null ) { element = getUnqualifiedMethodHandle ( ( IMethod ) element , true ) [ 0 ] ; } else { element = el [ 0 ] ; } } break ; case IJavaElement . TYPE_PARAMETER : IJavaElement parent = element . getParent ( ) ; if ( parent . getElementType ( ) == IJavaElement . METHOD ) { IMethod method = ( IMethod ) parent ; if ( method . isBinary ( ) ) { IJavaElement [ ] el = getUnqualifiedMethodHandle ( method , false ) ; if ( el [ 1 ] != null && this . sourceRanges . get ( el [ 0 ] ) == null ) { method = ( IMethod ) getUnqualifiedMethodHandle ( method , true ) [ 0 ] ; } else { method = ( IMethod ) el [ 0 ] ; } element = method . getTypeParameter ( element . getElementName ( ) ) ; } } } SourceRange [ ] ranges = ( SourceRange [ ] ) this . sourceRanges . get ( element ) ; if ( ranges == null ) { return UNKNOWN_RANGE ; } else { return ranges [ 0 ] ; } } protected IType getType ( String typeName ) { if ( typeName . length ( ) == 0 ) { IJavaElement classFile = this . binaryType . getParent ( ) ; String classFileName = classFile . getElementName ( ) ; StringBuffer newClassFileName = new StringBuffer ( ) ; int lastDollar = classFileName . lastIndexOf ( '$' ) ; for ( int i = 0 ; i <= lastDollar ; i ++ ) newClassFileName . append ( classFileName . charAt ( i ) ) ; newClassFileName . append ( Integer . toString ( this . anonymousCounter ) ) ; PackageFragment pkg = ( PackageFragment ) classFile . getParent ( ) ; return new BinaryType ( new ClassFile ( pkg , newClassFileName . toString ( ) ) , typeName ) ; } else if ( this . binaryType . getElementName ( ) . equals ( typeName ) ) return this . binaryType ; else return this . binaryType . getType ( typeName ) ; } protected IJavaElement [ ] getUnqualifiedMethodHandle ( IMethod method , boolean noDollar ) { boolean hasDollar = false ; String [ ] qualifiedParameterTypes = method . getParameterTypes ( ) ; String [ ] unqualifiedParameterTypes = new String [ qualifiedParameterTypes . length ] ; for ( int i = 0 ; i < qualifiedParameterTypes . length ; i ++ ) { StringBuffer unqualifiedTypeSig = new StringBuffer ( ) ; getUnqualifiedTypeSignature ( qualifiedParameterTypes [ i ] , 0 , qualifiedParameterTypes [ i ] . length ( ) , unqualifiedTypeSig , noDollar ) ; unqualifiedParameterTypes [ i ] = unqualifiedTypeSig . toString ( ) ; hasDollar |= unqualifiedParameterTypes [ i ] . lastIndexOf ( '$' ) != - 1 ; } IJavaElement [ ] result = new IJavaElement [ 2 ] ; result [ 0 ] = ( ( IType ) method . getParent ( ) ) . getMethod ( method . getElementName ( ) , unqualifiedParameterTypes ) ; if ( hasDollar ) { result [ 1 ] = result [ 0 ] ; } return result ; } private int getUnqualifiedTypeSignature ( String qualifiedTypeSig , int start , int length , StringBuffer unqualifiedTypeSig , boolean noDollar ) { char firstChar = qualifiedTypeSig . charAt ( start ) ; int end = start + 1 ; boolean sigStart = false ; firstPass : for ( int i = start ; i < length ; i ++ ) { char current = qualifiedTypeSig . charAt ( i ) ; switch ( current ) { case Signature . C_ARRAY : case Signature . C_SUPER : case Signature . C_EXTENDS : unqualifiedTypeSig . append ( current ) ; start = i + 1 ; end = start + 1 ; firstChar = qualifiedTypeSig . charAt ( start ) ; break ; case Signature . C_RESOLVED : case Signature . C_UNRESOLVED : case Signature . C_TYPE_VARIABLE : if ( ! sigStart ) { start = ++ i ; sigStart = true ; } break ; case Signature . C_NAME_END : case Signature . C_GENERIC_START : end = i ; break firstPass ; case Signature . C_STAR : unqualifiedTypeSig . append ( current ) ; start = i + 1 ; end = start + 1 ; firstChar = qualifiedTypeSig . charAt ( start ) ; break ; case Signature . C_GENERIC_END : return i ; case Signature . C_DOT : start = ++ i ; break ; case Signature . C_BOOLEAN : case Signature . C_BYTE : case Signature . C_CHAR : case Signature . C_DOUBLE : case Signature . C_FLOAT : case Signature . C_INT : case Signature . C_LONG : case Signature . C_SHORT : if ( ! sigStart ) { unqualifiedTypeSig . append ( current ) ; return i + 1 ; } } } switch ( firstChar ) { case Signature . C_RESOLVED : case Signature . C_UNRESOLVED : case Signature . C_TYPE_VARIABLE : unqualifiedTypeSig . append ( Signature . C_UNRESOLVED ) ; if ( noDollar ) { int lastDollar = qualifiedTypeSig . lastIndexOf ( '$' , end ) ; if ( lastDollar > start ) start = lastDollar + 1 ; } for ( int i = start ; i < length ; i ++ ) { char current = qualifiedTypeSig . charAt ( i ) ; switch ( current ) { case Signature . C_GENERIC_START : unqualifiedTypeSig . append ( current ) ; i ++ ; do { i = getUnqualifiedTypeSignature ( qualifiedTypeSig , i , length , unqualifiedTypeSig , noDollar ) ; } while ( qualifiedTypeSig . charAt ( i ) != Signature . C_GENERIC_END ) ; unqualifiedTypeSig . append ( Signature . C_GENERIC_END ) ; break ; case Signature . C_NAME_END : unqualifiedTypeSig . append ( current ) ; return i + 1 ; default : unqualifiedTypeSig . append ( current ) ; break ; } } return length ; default : unqualifiedTypeSig . append ( qualifiedTypeSig . substring ( start , end ) ) ; return end ; } } public void mapSource ( IType type , char [ ] contents , IBinaryType info ) { this . mapSource ( type , contents , info , null ) ; } public synchronized ISourceRange mapSource ( IType type , char [ ] contents , IBinaryType info , IJavaElement elementToFind ) { this . binaryType = ( BinaryType ) type ; if ( this . sourceRanges . get ( type ) != null ) return ( elementToFind != null ) ? getNameRange ( elementToFind ) : null ; this . importsTable . remove ( this . binaryType ) ; this . importsCounterTable . remove ( this . binaryType ) ; this . searchedElement = elementToFind ; this . types = new IType [ 1 ] ; this . typeDeclarationStarts = new int [ 1 ] ; this . typeNameRanges = new SourceRange [ 1 ] ; this . typeModifiers = new int [ 1 ] ; this . typeDepth = - 1 ; this . memberDeclarationStart = new int [ 1 ] ; this . memberName = new String [ 1 ] ; this . memberNameRange = new SourceRange [ 1 ] ; this . methodParameterTypes = new char [ 1 ] [ ] [ ] ; this . methodParameterNames = new char [ 1 ] [ ] [ ] ; this . anonymousCounter = 0 ; HashMap oldSourceRanges = null ; if ( elementToFind != null ) { oldSourceRanges = ( HashMap ) this . sourceRanges . clone ( ) ; } try { IProblemFactory factory = new DefaultProblemFactory ( ) ; SourceElementParser parser = null ; this . anonymousClassName = 0 ; if ( info == null ) { try { info = ( IBinaryType ) this . binaryType . getElementInfo ( ) ; } catch ( JavaModelException e ) { return null ; } } boolean isAnonymousClass = info . isAnonymous ( ) ; char [ ] fullName = info . getName ( ) ; if ( isAnonymousClass ) { String eltName = this . binaryType . getParent ( ) . getElementName ( ) ; eltName = eltName . substring ( eltName . lastIndexOf ( '$' ) + 1 , eltName . length ( ) ) ; try { this . anonymousClassName = Integer . parseInt ( eltName ) ; } catch ( NumberFormatException e ) { } } boolean doFullParse = hasToRetrieveSourceRangesForLocalClass ( fullName ) ; parser = LanguageSupportFactory . getSourceElementParser ( this , factory , new CompilerOptions ( this . options ) , doFullParse , true , true ) ; parser . javadocParser . checkDocComment = false ; IJavaElement javaElement = this . binaryType . getCompilationUnit ( ) ; if ( javaElement == null ) javaElement = this . binaryType . getParent ( ) ; parser . parseCompilationUnit ( new BasicCompilationUnit ( contents , null , this . binaryType . sourceFileName ( info ) , javaElement ) , doFullParse , null ) ; IProject project = javaElement . getJavaProject ( ) . getProject ( ) ; if ( LanguageSupportFactory . isInterestingProject ( project ) && LanguageSupportFactory . isInterestingSourceFile ( this . binaryType . getSourceFileName ( info ) ) ) { LanguageSupportFactory . filterNonSourceMembers ( this . binaryType ) ; } if ( elementToFind != null ) { ISourceRange range = getNameRange ( elementToFind ) ; return range ; } else { return null ; } } finally { if ( elementToFind != null ) { this . sourceRanges = oldSourceRanges ; } this . binaryType = null ; this . searchedElement = null ; this . types = null ; this . typeDeclarationStarts = null ; this . typeNameRanges = null ; this . typeDepth = - 1 ; } } private char [ ] readSource ( ZipEntry entry , ZipFile zip ) { try { byte [ ] bytes = Util . getZipEntryByteContent ( entry , zip ) ; if ( bytes != null ) { return Util . bytesToChar ( bytes , this . encoding ) ; } } catch ( IOException e ) { } return null ; } protected void setMethodParameterNames ( IMethod method , char [ ] [ ] parameterNames ) { if ( parameterNames == null ) { parameterNames = CharOperation . NO_CHAR_CHAR ; } this . parameterNames . put ( method , parameterNames ) ; } protected void setSourceRange ( IJavaElement element , SourceRange sourceRange , SourceRange nameRange ) { this . sourceRanges . put ( element , new SourceRange [ ] { sourceRange , nameRange } ) ; } public char [ ] [ ] getImports ( BinaryType type ) { char [ ] [ ] imports = ( char [ ] [ ] ) this . importsTable . get ( type ) ; if ( imports != null ) { int importsCounter = ( ( Integer ) this . importsCounterTable . get ( type ) ) . intValue ( ) ; if ( imports . length != importsCounter ) { System . arraycopy ( imports , 0 , ( imports = new char [ importsCounter ] [ ] ) , 0 , importsCounter ) ; } this . importsTable . put ( type , imports ) ; } return imports ; } private boolean hasToRetrieveSourceRangesForLocalClass ( char [ ] eltName ) { if ( eltName == null ) return false ; int length = eltName . length ; int dollarIndex = CharOperation . indexOf ( '$' , eltName , 0 ) ; while ( dollarIndex != - 1 ) { int nameStart = dollarIndex + 1 ; if ( nameStart == length ) return false ; if ( Character . isDigit ( eltName [ nameStart ] ) ) return true ; dollarIndex = CharOperation . indexOf ( '$' , eltName , nameStart ) ; } return false ; } } </s>