<s> package org . eclipse . jdt . internal . compiler . util ; import java . io . BufferedInputStream ; import java . io . BufferedOutputStream ; import java . io . BufferedReader ; import java . io . ByteArrayInputStream ; import java . io . File ; import java . io . FileInputStream ; import java . io . FileOutputStream ; import java . io . IOException ; import java . io . InputStream ; import java . io . InputStreamReader ; import java . io . PrintWriter ; import java . io . StringWriter ; import java . io . UnsupportedEncodingException ; import java . util . HashSet ; import java . util . List ; import java . util . StringTokenizer ; import java . util . zip . ZipEntry ; import java . util . zip . ZipFile ; import org . eclipse . jdt . core . compiler . CharOperation ; import org . eclipse . jdt . internal . compiler . ClassFile ; import org . eclipse . jdt . internal . compiler . ast . TypeDeclaration ; import org . eclipse . jdt . internal . compiler . batch . FileSystem ; import org . eclipse . jdt . internal . compiler . batch . Main ; import org . eclipse . jdt . internal . compiler . classfmt . ClassFileConstants ; import org . eclipse . jdt . internal . compiler . lookup . ExtraCompilerModifiers ; import org . eclipse . jdt . internal . compiler . lookup . ParameterizedTypeBinding ; import org . eclipse . jdt . internal . compiler . lookup . ReferenceBinding ; import org . eclipse . jdt . internal . compiler . lookup . TagBits ; import org . eclipse . jdt . internal . compiler . lookup . TypeBinding ; import org . eclipse . jdt . internal . compiler . lookup . TypeVariableBinding ; import org . eclipse . jdt . internal . compiler . lookup . WildcardBinding ; public class Util implements SuffixConstants { public static final char C_BOOLEAN = 'Z' ; public static final char C_BYTE = 'B' ; public static final char C_CHAR = 'C' ; public static final char C_DOUBLE = 'D' ; public static final char C_FLOAT = 'F' ; public static final char C_INT = 'I' ; public static final char C_SEMICOLON = ';' ; public static final char C_COLON = ':' ; public static final char C_LONG = 'J' ; public static final char C_SHORT = 'S' ; public static final char C_VOID = 'V' ; public static final char C_TYPE_VARIABLE = 'T' ; public static final char C_STAR = '*' ; public static final char C_EXCEPTION_START = '^' ; public static final char C_EXTENDS = '+' ; public static final char C_SUPER = '-' ; public static final char C_DOT = '.' ; public static final char C_DOLLAR = '$' ; public static final char C_ARRAY = '[' ; public static final char C_RESOLVED = 'L' ; public static final char C_UNRESOLVED = 'Q' ; public static final char C_NAME_END = ';' ; public static final char C_PARAM_START = '(' ; public static final char C_PARAM_END = ')' ; public static final char C_GENERIC_START = '<' ; public static final char C_GENERIC_END = '>' ; public static final char C_CAPTURE = '!' ; public interface Displayable { String displayString ( Object o ) ; } private static final int DEFAULT_READING_SIZE = 8192 ; private static final int DEFAULT_WRITING_SIZE = 1024 ; public final static String UTF_8 = "UTF-8" ; public static final String LINE_SEPARATOR = System . getProperty ( "" ) ; public static final String EMPTY_STRING = new String ( CharOperation . NO_CHAR ) ; public static final int [ ] EMPTY_INT_ARRAY = new int [ 0 ] ; public static String buildAllDirectoriesInto ( String outputPath , String relativeFileName ) throws IOException { char fileSeparatorChar = File . separatorChar ; String fileSeparator = File . separator ; File f ; outputPath = outputPath . replace ( '/' , fileSeparatorChar ) ; relativeFileName = relativeFileName . replace ( '/' , fileSeparatorChar ) ; String outputDirPath , fileName ; int separatorIndex = relativeFileName . lastIndexOf ( fileSeparatorChar ) ; if ( separatorIndex == - 1 ) { if ( outputPath . endsWith ( fileSeparator ) ) { outputDirPath = outputPath . substring ( 0 , outputPath . length ( ) - 1 ) ; fileName = outputPath + relativeFileName ; } else { outputDirPath = outputPath ; fileName = outputPath + fileSeparator + relativeFileName ; } } else { if ( outputPath . endsWith ( fileSeparator ) ) { outputDirPath = outputPath + relativeFileName . substring ( 0 , separatorIndex ) ; fileName = outputPath + relativeFileName ; } else { outputDirPath = outputPath + fileSeparator + relativeFileName . substring ( 0 , separatorIndex ) ; fileName = outputPath + fileSeparator + relativeFileName ; } } f = new File ( outputDirPath ) ; f . mkdirs ( ) ; if ( f . isDirectory ( ) ) { return fileName ; } else { if ( outputPath . endsWith ( fileSeparator ) ) { outputPath = outputPath . substring ( 0 , outputPath . length ( ) - 1 ) ; } f = new File ( outputPath ) ; boolean checkFileType = false ; if ( f . exists ( ) ) { checkFileType = true ; } else { if ( ! f . mkdirs ( ) ) { if ( f . exists ( ) ) { checkFileType = true ; } else { throw new IOException ( Messages . bind ( Messages . output_notValidAll , f . getAbsolutePath ( ) ) ) ; } } } if ( checkFileType ) { if ( ! f . isDirectory ( ) ) { throw new IOException ( Messages . bind ( Messages . output_isFile , f . getAbsolutePath ( ) ) ) ; } } StringBuffer outDir = new StringBuffer ( outputPath ) ; outDir . append ( fileSeparator ) ; StringTokenizer tokenizer = new StringTokenizer ( relativeFileName , fileSeparator ) ; String token = tokenizer . nextToken ( ) ; while ( tokenizer . hasMoreTokens ( ) ) { f = new File ( outDir . append ( token ) . append ( fileSeparator ) . toString ( ) ) ; checkFileType = false ; if ( f . exists ( ) ) { checkFileType = true ; } else { if ( ! f . mkdir ( ) ) { if ( f . exists ( ) ) { checkFileType = true ; } else { throw new IOException ( Messages . bind ( Messages . output_notValid , outDir . substring ( outputPath . length ( ) + 1 , outDir . length ( ) - 1 ) , outputPath ) ) ; } } } if ( checkFileType ) { if ( ! f . isDirectory ( ) ) { throw new IOException ( Messages . bind ( Messages . output_isFile , f . getAbsolutePath ( ) ) ) ; } } token = tokenizer . nextToken ( ) ; } return outDir . append ( token ) . toString ( ) ; } } public static char [ ] bytesToChar ( byte [ ] bytes , String encoding ) throws IOException { return getInputStreamAsCharArray ( new ByteArrayInputStream ( bytes ) , bytes . length , encoding ) ; } public static int computeOuterMostVisibility ( TypeDeclaration typeDeclaration , int visibility ) { while ( typeDeclaration != null ) { switch ( typeDeclaration . modifiers & ExtraCompilerModifiers . AccVisibilityMASK ) { case ClassFileConstants . AccPrivate : visibility = ClassFileConstants . AccPrivate ; break ; case ClassFileConstants . AccDefault : if ( visibility != ClassFileConstants . AccPrivate ) { visibility = ClassFileConstants . AccDefault ; } break ; case ClassFileConstants . AccProtected : if ( visibility == ClassFileConstants . AccPublic ) { visibility = ClassFileConstants . AccProtected ; } break ; } typeDeclaration = typeDeclaration . enclosingType ; } return visibility ; } public static byte [ ] getFileByteContent ( File file ) throws IOException { InputStream stream = null ; try { stream = new BufferedInputStream ( new FileInputStream ( file ) ) ; return getInputStreamAsByteArray ( stream , ( int ) file . length ( ) ) ; } finally { if ( stream != null ) { try { stream . close ( ) ; } catch ( IOException e ) { } } } } public static char [ ] getFileCharContent ( File file , String encoding ) throws IOException { InputStream stream = null ; try { stream = new FileInputStream ( file ) ; return getInputStreamAsCharArray ( stream , ( int ) file . length ( ) , encoding ) ; } finally { if ( stream != null ) { try { stream . close ( ) ; } catch ( IOException e ) { } } } } private static FileOutputStream getFileOutputStream ( boolean generatePackagesStructure , String outputPath , String relativeFileName ) throws IOException { if ( generatePackagesStructure ) { return new FileOutputStream ( new File ( buildAllDirectoriesInto ( outputPath , relativeFileName ) ) ) ; } else { String fileName = null ; char fileSeparatorChar = File . separatorChar ; String fileSeparator = File . separator ; outputPath = outputPath . replace ( '/' , fileSeparatorChar ) ; int indexOfPackageSeparator = relativeFileName . lastIndexOf ( fileSeparatorChar ) ; if ( indexOfPackageSeparator == - 1 ) { if ( outputPath . endsWith ( fileSeparator ) ) { fileName = outputPath + relativeFileName ; } else { fileName = outputPath + fileSeparator + relativeFileName ; } } else { int length = relativeFileName . length ( ) ; if ( outputPath . endsWith ( fileSeparator ) ) { fileName = outputPath + relativeFileName . substring ( indexOfPackageSeparator + 1 , length ) ; } else { fileName = outputPath + fileSeparator + relativeFileName . substring ( indexOfPackageSeparator + 1 , length ) ; } } return new FileOutputStream ( new File ( fileName ) ) ; } } public static byte [ ] getInputStreamAsByteArray ( InputStream stream , int length ) throws IOException { byte [ ] contents ; if ( length == - 1 ) { contents = new byte [ 0 ] ; int contentsLength = 0 ; int amountRead = - 1 ; do { int amountRequested = Math . max ( stream . available ( ) , DEFAULT_READING_SIZE ) ; if ( contentsLength + amountRequested > contents . length ) { System . arraycopy ( contents , 0 , contents = new byte [ contentsLength + amountRequested ] , 0 , contentsLength ) ; } amountRead = stream . read ( contents , contentsLength , amountRequested ) ; if ( amountRead > 0 ) { contentsLength += amountRead ; } } while ( amountRead != - 1 ) ; if ( contentsLength < contents . length ) { System . arraycopy ( contents , 0 , contents = new byte [ contentsLength ] , 0 , contentsLength ) ; } } else { contents = new byte [ length ] ; int len = 0 ; int readSize = 0 ; while ( ( readSize != - 1 ) && ( len != length ) ) { len += readSize ; readSize = stream . read ( contents , len , length - len ) ; } } return contents ; } public static char [ ] getInputStreamAsCharArray ( InputStream stream , int length , String encoding ) throws IOException { BufferedReader reader = null ; try { reader = encoding == null ? new BufferedReader ( new InputStreamReader ( stream ) ) : new BufferedReader ( new InputStreamReader ( stream , encoding ) ) ; } catch ( UnsupportedEncodingException e ) { reader = new BufferedReader ( new InputStreamReader ( stream ) ) ; } char [ ] contents ; int totalRead = 0 ; if ( length == - 1 ) { contents = CharOperation . NO_CHAR ; } else { contents = new char [ length ] ; } while ( true ) { int amountRequested ; if ( totalRead < length ) { amountRequested = length - totalRead ; } else { int current = reader . read ( ) ; if ( current < 0 ) break ; amountRequested = Math . max ( stream . available ( ) , DEFAULT_READING_SIZE ) ; if ( totalRead + 1 + amountRequested > contents . length ) System . arraycopy ( contents , 0 , contents = new char [ totalRead + 1 + amountRequested ] , 0 , totalRead ) ; contents [ totalRead ++ ] = ( char ) current ; } int amountRead = reader . read ( contents , totalRead , amountRequested ) ; if ( amountRead < 0 ) break ; totalRead += amountRead ; } int start = 0 ; if ( totalRead > 0 && UTF_8 . equals ( encoding ) ) { if ( contents [ 0 ] == 0xFEFF ) { totalRead -- ; start = 1 ; } } if ( totalRead < contents . length ) System . arraycopy ( contents , start , contents = new char [ totalRead ] , 0 , totalRead ) ; return contents ; } public static String getExceptionSummary ( Throwable exception ) { StringWriter stringWriter = new StringWriter ( ) ; exception . printStackTrace ( new PrintWriter ( stringWriter ) ) ; StringBuffer buffer = stringWriter . getBuffer ( ) ; StringBuffer exceptionBuffer = new StringBuffer ( 50 ) ; exceptionBuffer . append ( exception . toString ( ) ) ; lookupLine2 : for ( int i = 0 , lineSep = 0 , max = buffer . length ( ) , line2Start = 0 ; i < max ; i ++ ) { switch ( buffer . charAt ( i ) ) { case '\n' : case '\r' : if ( line2Start > 0 ) { exceptionBuffer . append ( ' ' ) . append ( buffer . substring ( line2Start , i ) ) ; break lookupLine2 ; } lineSep ++ ; break ; case ' ' : case '\t' : break ; default : if ( lineSep > 0 ) { line2Start = i ; lineSep = 0 ; } break ; } } return exceptionBuffer . toString ( ) ; } public static int getLineNumber ( int position , int [ ] lineEnds , int g , int d ) { if ( lineEnds == null ) return 1 ; if ( d == - 1 ) return 1 ; int m = g , start ; while ( g <= d ) { m = g + ( d - g ) / 2 ; if ( position < ( start = lineEnds [ m ] ) ) { d = m - 1 ; } else if ( position > start ) { g = m + 1 ; } else { return m + 1 ; } } if ( position < lineEnds [ m ] ) { return m + 1 ; } return m + 2 ; } public static byte [ ] getZipEntryByteContent ( ZipEntry ze , ZipFile zip ) throws IOException { InputStream stream = null ; try { InputStream inputStream = zip . getInputStream ( ze ) ; if ( inputStream == null ) throw new IOException ( "" + ze . getName ( ) ) ; stream = new BufferedInputStream ( inputStream ) ; return getInputStreamAsByteArray ( stream , ( int ) ze . getSize ( ) ) ; } finally { if ( stream != null ) { try { stream . close ( ) ; } catch ( IOException e ) { } } } } public static int hashCode ( Object [ ] array ) { int prime = 31 ; if ( array == null ) { return 0 ; } int result = 1 ; for ( int index = 0 ; index < array . length ; index ++ ) { result = prime * result + ( array [ index ] == null ? 0 : array [ index ] . hashCode ( ) ) ; } return result ; } public final static boolean isPotentialZipArchive ( String name ) { int lastDot = name . lastIndexOf ( '.' ) ; if ( lastDot == - 1 ) return false ; if ( name . lastIndexOf ( File . separatorChar ) > lastDot ) return false ; int length = name . length ( ) ; int extensionLength = length - lastDot - 1 ; if ( extensionLength == EXTENSION_java . length ( ) ) { for ( int i = extensionLength - 1 ; i >= 0 ; i -- ) { if ( Character . toLowerCase ( name . charAt ( length - extensionLength + i ) ) != EXTENSION_java . charAt ( i ) ) { break ; } if ( i == 0 ) { return false ; } } } if ( extensionLength == EXTENSION_class . length ( ) ) { for ( int i = extensionLength - 1 ; i >= 0 ; i -- ) { if ( Character . toLowerCase ( name . charAt ( length - extensionLength + i ) ) != EXTENSION_class . charAt ( i ) ) { return true ; } } return false ; } return true ; } public final static boolean isClassFileName ( char [ ] name ) { int nameLength = name == null ? 0 : name . length ; int suffixLength = SUFFIX_CLASS . length ; if ( nameLength < suffixLength ) return false ; for ( int i = 0 , offset = nameLength - suffixLength ; i < suffixLength ; i ++ ) { char c = name [ offset + i ] ; if ( c != SUFFIX_class [ i ] && c != SUFFIX_CLASS [ i ] ) return false ; } return true ; } public final static boolean isClassFileName ( String name ) { int nameLength = name == null ? 0 : name . length ( ) ; int suffixLength = SUFFIX_CLASS . length ; if ( nameLength < suffixLength ) return false ; for ( int i = 0 ; i < suffixLength ; i ++ ) { char c = name . charAt ( nameLength - i - 1 ) ; int suffixIndex = suffixLength - i - 1 ; if ( c != SUFFIX_class [ suffixIndex ] && c != SUFFIX_CLASS [ suffixIndex ] ) return false ; } return true ; } public final static boolean isExcluded ( char [ ] path , char [ ] [ ] inclusionPatterns , char [ ] [ ] exclusionPatterns , boolean isFolderPath ) { if ( inclusionPatterns == null && exclusionPatterns == null ) return false ; inclusionCheck : if ( inclusionPatterns != null ) { for ( int i = 0 , length = inclusionPatterns . length ; i < length ; i ++ ) { char [ ] pattern = inclusionPatterns [ i ] ; char [ ] folderPattern = pattern ; if ( isFolderPath ) { int lastSlash = CharOperation . lastIndexOf ( '/' , pattern ) ; if ( lastSlash != - 1 && lastSlash != pattern . length - 1 ) { int star = CharOperation . indexOf ( '*' , pattern , lastSlash ) ; if ( ( star == - 1 || star >= pattern . length - 1 || pattern [ star + 1 ] != '*' ) ) { folderPattern = CharOperation . subarray ( pattern , 0 , lastSlash ) ; } } } if ( CharOperation . pathMatch ( folderPattern , path , true , '/' ) ) { break inclusionCheck ; } } return true ; } if ( isFolderPath ) { path = CharOperation . concat ( path , new char [ ] { '*' } , '/' ) ; } if ( exclusionPatterns != null ) { for ( int i = 0 , length = exclusionPatterns . length ; i < length ; i ++ ) { if ( CharOperation . pathMatch ( exclusionPatterns [ i ] , path , true , '/' ) ) { return true ; } } } return false ; } public final static boolean isJavaFileName ( char [ ] name ) { int nameLength = name == null ? 0 : name . length ; int suffixLength = SUFFIX_JAVA . length ; if ( nameLength < suffixLength ) return false ; for ( int i = 0 , offset = nameLength - suffixLength ; i < suffixLength ; i ++ ) { char c = name [ offset + i ] ; if ( c != SUFFIX_java [ i ] && c != SUFFIX_JAVA [ i ] ) return false ; } return true ; } public final static boolean isJavaFileName ( String name ) { int nameLength = name == null ? 0 : name . length ( ) ; int suffixLength = SUFFIX_JAVA . length ; if ( nameLength < suffixLength ) return false ; for ( int i = 0 ; i < suffixLength ; i ++ ) { char c = name . charAt ( nameLength - i - 1 ) ; int suffixIndex = suffixLength - i - 1 ; if ( c != SUFFIX_java [ suffixIndex ] && c != SUFFIX_JAVA [ suffixIndex ] ) return false ; } return true ; } public static void reverseQuickSort ( char [ ] [ ] list , int left , int right ) { int original_left = left ; int original_right = right ; char [ ] mid = list [ left + ( ( right - left ) / 2 ) ] ; do { while ( CharOperation . compareTo ( list [ left ] , mid ) > 0 ) { left ++ ; } while ( CharOperation . compareTo ( mid , list [ right ] ) > 0 ) { right -- ; } if ( left <= right ) { char [ ] tmp = list [ left ] ; list [ left ] = list [ right ] ; list [ right ] = tmp ; left ++ ; right -- ; } } while ( left <= right ) ; if ( original_left < right ) { reverseQuickSort ( list , original_left , right ) ; } if ( left < original_right ) { reverseQuickSort ( list , left , original_right ) ; } } public static void reverseQuickSort ( char [ ] [ ] list , int left , int right , int [ ] result ) { int original_left = left ; int original_right = right ; char [ ] mid = list [ left + ( ( right - left ) / 2 ) ] ; do { while ( CharOperation . compareTo ( list [ left ] , mid ) > 0 ) { left ++ ; } while ( CharOperation . compareTo ( mid , list [ right ] ) > 0 ) { right -- ; } if ( left <= right ) { char [ ] tmp = list [ left ] ; list [ left ] = list [ right ] ; list [ right ] = tmp ; int temp = result [ left ] ; result [ left ] = result [ right ] ; result [ right ] = temp ; left ++ ; right -- ; } } while ( left <= right ) ; if ( original_left < right ) { reverseQuickSort ( list , original_left , right , result ) ; } if ( left < original_right ) { reverseQuickSort ( list , left , original_right , result ) ; } } public static final int searchColumnNumber ( int [ ] startLineIndexes , int lineNumber , int position ) { switch ( lineNumber ) { case 1 : return position + 1 ; case 2 : return position - startLineIndexes [ 0 ] ; default : int line = lineNumber - 2 ; int length = startLineIndexes . length ; if ( line >= length ) { return position - startLineIndexes [ length - 1 ] ; } return position - startLineIndexes [ line ] ; } } public static Boolean toBoolean ( boolean bool ) { if ( bool ) { return Boolean . TRUE ; } else { return Boolean . FALSE ; } } public static String toString ( Object [ ] objects ) { return toString ( objects , new Displayable ( ) { public String displayString ( Object o ) { if ( o == null ) return "null" ; return o . toString ( ) ; } } ) ; } public static String toString ( Object [ ] objects , Displayable renderer ) { if ( objects == null ) return "" ; StringBuffer buffer = new StringBuffer ( 10 ) ; for ( int i = 0 ; i < objects . length ; i ++ ) { if ( i > 0 ) buffer . append ( ", " ) ; buffer . append ( renderer . displayString ( objects [ i ] ) ) ; } return buffer . toString ( ) ; } public static void writeToDisk ( boolean generatePackagesStructure , String outputPath , String relativeFileName , ClassFile classFile ) throws IOException { FileOutputStream file = getFileOutputStream ( generatePackagesStructure , outputPath , relativeFileName ) ; BufferedOutputStream output = new BufferedOutputStream ( file , DEFAULT_WRITING_SIZE ) ; try { output . write ( classFile . header , 0 , classFile . headerOffset ) ; output . write ( classFile . contents , 0 , classFile . contentsOffset ) ; output . flush ( ) ; } catch ( IOException e ) { throw e ; } finally { output . close ( ) ; } } public static void recordNestedType ( ClassFile classFile , TypeBinding typeBinding ) { if ( classFile . visitedTypes == null ) { classFile . visitedTypes = new HashSet ( 3 ) ; } else if ( classFile . visitedTypes . contains ( typeBinding ) ) { return ; } classFile . visitedTypes . add ( typeBinding ) ; if ( typeBinding . isParameterizedType ( ) && ( ( typeBinding . tagBits & TagBits . ContainsNestedTypeReferences ) != 0 ) ) { ParameterizedTypeBinding parameterizedTypeBinding = ( ParameterizedTypeBinding ) typeBinding ; ReferenceBinding genericType = parameterizedTypeBinding . genericType ( ) ; if ( ( genericType . tagBits & TagBits . ContainsNestedTypeReferences ) != 0 ) { recordNestedType ( classFile , genericType ) ; } TypeBinding [ ] arguments = parameterizedTypeBinding . arguments ; if ( arguments != null ) { for ( int j = 0 , max2 = arguments . length ; j < max2 ; j ++ ) { TypeBinding argument = arguments [ j ] ; if ( argument . isWildcard ( ) ) { WildcardBinding wildcardBinding = ( WildcardBinding ) argument ; TypeBinding bound = wildcardBinding . bound ; if ( bound != null && ( ( bound . tagBits & TagBits . ContainsNestedTypeReferences ) != 0 ) ) { recordNestedType ( classFile , bound ) ; } ReferenceBinding superclass = wildcardBinding . superclass ( ) ; if ( superclass != null && ( ( superclass . tagBits & TagBits . ContainsNestedTypeReferences ) != 0 ) ) { recordNestedType ( classFile , superclass ) ; } ReferenceBinding [ ] superInterfaces = wildcardBinding . superInterfaces ( ) ; if ( superInterfaces != null ) { for ( int k = 0 , max3 = superInterfaces . length ; k < max3 ; k ++ ) { ReferenceBinding superInterface = superInterfaces [ k ] ; if ( ( superInterface . tagBits & TagBits . ContainsNestedTypeReferences ) != 0 ) { recordNestedType ( classFile , superInterface ) ; } } } } else if ( ( argument . tagBits & TagBits . ContainsNestedTypeReferences ) != 0 ) { recordNestedType ( classFile , argument ) ; } } } } else if ( typeBinding . isTypeVariable ( ) && ( ( typeBinding . tagBits & TagBits . ContainsNestedTypeReferences ) != 0 ) ) { TypeVariableBinding typeVariableBinding = ( TypeVariableBinding ) typeBinding ; TypeBinding upperBound = typeVariableBinding . upperBound ( ) ; if ( upperBound != null && ( ( upperBound . tagBits & TagBits . ContainsNestedTypeReferences ) != 0 ) ) { recordNestedType ( classFile , upperBound ) ; } TypeBinding [ ] upperBounds = typeVariableBinding . otherUpperBounds ( ) ; if ( upperBounds != null ) { for ( int k = 0 , max3 = upperBounds . length ; k < max3 ; k ++ ) { TypeBinding otherUpperBound = upperBounds [ k ] ; if ( ( otherUpperBound . tagBits & TagBits . ContainsNestedTypeReferences ) != 0 ) { recordNestedType ( classFile , otherUpperBound ) ; } } } } else if ( typeBinding . isNestedType ( ) ) { classFile . recordInnerClasses ( typeBinding ) ; } } public static File getJavaHome ( ) { String javaHome = System . getProperty ( "java.home" ) ; if ( javaHome != null ) { File javaHomeFile = new File ( javaHome ) ; if ( javaHomeFile . exists ( ) ) { return javaHomeFile ; } } return null ; } public static void collectRunningVMBootclasspath ( List bootclasspaths ) { String javaversion = System . getProperty ( "java.version" ) ; if ( javaversion != null && javaversion . equalsIgnoreCase ( "1.1.8" ) ) { throw new IllegalStateException ( ) ; } String bootclasspathProperty = System . getProperty ( "" ) ; if ( ( bootclasspathProperty == null ) || ( bootclasspathProperty . length ( ) == 0 ) ) { bootclasspathProperty = System . getProperty ( "" ) ; if ( ( bootclasspathProperty == null ) || ( bootclasspathProperty . length ( ) == 0 ) ) { bootclasspathProperty = System . getProperty ( "" ) ; } } if ( ( bootclasspathProperty != null ) && ( bootclasspathProperty . length ( ) != 0 ) ) { StringTokenizer tokenizer = new StringTokenizer ( bootclasspathProperty , File . pathSeparator ) ; String token ; while ( tokenizer . hasMoreTokens ( ) ) { token = tokenizer . nextToken ( ) ; FileSystem . Classpath currentClasspath = FileSystem . getClasspath ( token , null , null ) ; if ( currentClasspath != null ) { bootclasspaths . add ( currentClasspath ) ; } } } else { final File javaHome = getJavaHome ( ) ; if ( javaHome != null ) { File [ ] directoriesToCheck = null ; if ( System . getProperty ( "os.name" ) . startsWith ( "Mac" ) ) { directoriesToCheck = new File [ ] { new File ( javaHome , "../Classes" ) , } ; } else { directoriesToCheck = new File [ ] { new File ( javaHome , "lib" ) } ; } File [ ] [ ] systemLibrariesJars = Main . getLibrariesFiles ( directoriesToCheck ) ; if ( systemLibrariesJars != null ) { for ( int i = 0 , max = systemLibrariesJars . length ; i < max ; i ++ ) { File [ ] current = systemLibrariesJars [ i ] ; if ( current != null ) { for ( int j = 0 , max2 = current . length ; j < max2 ; j ++ ) { FileSystem . Classpath classpath = FileSystem . getClasspath ( current [ j ] . getAbsolutePath ( ) , null , false , null , null ) ; if ( classpath != null ) { bootclasspaths . add ( classpath ) ; } } } } } } } } public static int getParameterCount ( char [ ] methodSignature ) { try { int count = 0 ; int i = CharOperation . indexOf ( C_PARAM_START , methodSignature ) ; if ( i < 0 ) { throw new IllegalArgumentException ( ) ; } else { i ++ ; } for ( ; ; ) { if ( methodSignature [ i ] == C_PARAM_END ) { return count ; } int e = Util . scanTypeSignature ( methodSignature , i ) ; if ( e < 0 ) { throw new IllegalArgumentException ( ) ; } else { i = e + 1 ; } count ++ ; } } catch ( ArrayIndexOutOfBoundsException e ) { throw new IllegalArgumentException ( ) ; } } public static int scanTypeSignature ( char [ ] string , int start ) { if ( start >= string . length ) { throw new IllegalArgumentException ( ) ; } char c = string [ start ] ; switch ( c ) { case C_ARRAY : return scanArrayTypeSignature ( string , start ) ; case C_RESOLVED : case C_UNRESOLVED : return scanClassTypeSignature ( string , start ) ; case C_TYPE_VARIABLE : return scanTypeVariableSignature ( string , start ) ; case C_BOOLEAN : case C_BYTE : case C_CHAR : case C_DOUBLE : case C_FLOAT : case C_INT : case C_LONG : case C_SHORT : case C_VOID : return scanBaseTypeSignature ( string , start ) ; case C_CAPTURE : return scanCaptureTypeSignature ( string , start ) ; case C_EXTENDS : case C_SUPER : case C_STAR : return scanTypeBoundSignature ( string , start ) ; default : throw new IllegalArgumentException ( ) ; } } public static int scanBaseTypeSignature ( char [ ] string , int start ) { if ( start >= string . length ) { throw new IllegalArgumentException ( ) ; } char c = string [ start ] ; if ( "BCDFIJSVZ" . indexOf ( c ) >= 0 ) { return start ; } else { throw new IllegalArgumentException ( ) ; } } public static int scanArrayTypeSignature ( char [ ] string , int start ) { int length = string . length ; if ( start >= length - 1 ) { throw new IllegalArgumentException ( ) ; } char c = string [ start ] ; if ( c != C_ARRAY ) { throw new IllegalArgumentException ( ) ; } c = string [ ++ start ] ; while ( c == C_ARRAY ) { if ( start >= length - 1 ) { throw new IllegalArgumentException ( ) ; } c = string [ ++ start ] ; } return scanTypeSignature ( string , start ) ; } public static int scanCaptureTypeSignature ( char [ ] string , int start ) { if ( start >= string . length - 1 ) { throw new IllegalArgumentException ( ) ; } char c = string [ start ] ; if ( c != C_CAPTURE ) { throw new IllegalArgumentException ( ) ; } return scanTypeBoundSignature ( string , start + 1 ) ; } public static int scanTypeVariableSignature ( char [ ] string , int start ) { if ( start >= string . length - 2 ) { throw new IllegalArgumentException ( ) ; } char c = string [ start ] ; if ( c != C_TYPE_VARIABLE ) { throw new IllegalArgumentException ( ) ; } int id = scanIdentifier ( string , start + 1 ) ; c = string [ id + 1 ] ; if ( c == C_SEMICOLON ) { return id + 1 ; } else { throw new IllegalArgumentException ( ) ; } } public static int scanIdentifier ( char [ ] string , int start ) { if ( start >= string . length ) { throw new IllegalArgumentException ( ) ; } int p = start ; while ( true ) { char c = string [ p ] ; if ( c == '<' || c == '>' || c == ':' || c == ';' || c == '.' || c == '/' ) { return p - 1 ; } p ++ ; if ( p == string . length ) { return p - 1 ; } } } public static int scanClassTypeSignature ( char [ ] string , int start ) { if ( start >= string . length - 2 ) { throw new IllegalArgumentException ( ) ; } char c = string [ start ] ; if ( c != C_RESOLVED && c != C_UNRESOLVED ) { return - 1 ; } int p = start + 1 ; while ( true ) { if ( p >= string . length ) { throw new IllegalArgumentException ( ) ; } c = string [ p ] ; if ( c == C_SEMICOLON ) { return p ; } else if ( c == C_GENERIC_START ) { int e = scanTypeArgumentSignatures ( string , p ) ; p = e ; } else if ( c == C_DOT || c == '/' ) { int id = scanIdentifier ( string , p + 1 ) ; p = id ; } p ++ ; } } public static int scanTypeBoundSignature ( char [ ] string , int start ) { if ( start >= string . length ) { throw new IllegalArgumentException ( ) ; } char c = string [ start ] ; switch ( c ) { case C_STAR : return start ; case C_SUPER : case C_EXTENDS : if ( start >= string . length - 2 ) { throw new IllegalArgumentException ( ) ; } break ; default : throw new IllegalArgumentException ( ) ; } c = string [ ++ start ] ; switch ( c ) { case C_CAPTURE : return scanCaptureTypeSignature ( string , start ) ; case C_SUPER : case C_EXTENDS : return scanTypeBoundSignature ( string , start ) ; case C_RESOLVED : case C_UNRESOLVED : return scanClassTypeSignature ( string , start ) ; case C_TYPE_VARIABLE : return scanTypeVariableSignature ( string , start ) ; case C_ARRAY : return scanArrayTypeSignature ( string , start ) ; case C_STAR : return start ; default : throw new IllegalArgumentException ( ) ; } } public static int scanTypeArgumentSignatures ( char [ ] string , int start ) { if ( start >= string . length - 1 ) { throw new IllegalArgumentException ( ) ; } char c = string [ start ] ; if ( c != C_GENERIC_START ) { throw new IllegalArgumentException ( ) ; } int p = start + 1 ; while ( true ) { if ( p >= string . length ) { throw new IllegalArgumentException ( ) ; } c = string [ p ] ; if ( c == C_GENERIC_END ) { return p ; } int e = scanTypeArgumentSignature ( string , p ) ; p = e + 1 ; } } public static int scanTypeArgumentSignature ( char [ ] string , int start ) { if ( start >= string . length ) { throw new IllegalArgumentException ( ) ; } char c = string [ start ] ; switch ( c ) { case C_STAR : return start ; case C_EXTENDS : case C_SUPER : return scanTypeBoundSignature ( string , start ) ; default : return scanTypeSignature ( string , start ) ; } } } </s>