<s> package org . eclipse . jdt . internal . compiler . parser ; import java . util . ArrayList ; import org . eclipse . jdt . core . Signature ; import org . eclipse . jdt . core . compiler . CharOperation ; import org . eclipse . jdt . internal . compiler . ast . ASTNode ; import org . eclipse . jdt . internal . compiler . ast . ArrayQualifiedTypeReference ; import org . eclipse . jdt . internal . compiler . ast . ArrayTypeReference ; import org . eclipse . jdt . internal . compiler . ast . ImportReference ; import org . eclipse . jdt . internal . compiler . ast . ParameterizedQualifiedTypeReference ; import org . eclipse . jdt . internal . compiler . ast . ParameterizedSingleTypeReference ; import org . eclipse . jdt . internal . compiler . ast . QualifiedTypeReference ; import org . eclipse . jdt . internal . compiler . ast . SingleTypeReference ; import org . eclipse . jdt . internal . compiler . ast . TypeParameter ; import org . eclipse . jdt . internal . compiler . ast . TypeReference ; import org . eclipse . jdt . internal . compiler . ast . Wildcard ; import org . eclipse . jdt . internal . compiler . classfmt . ClassFileConstants ; import org . eclipse . jdt . internal . compiler . lookup . TypeBinding ; import org . eclipse . jdt . internal . compiler . lookup . TypeConstants ; import org . eclipse . jdt . internal . compiler . problem . ProblemReporter ; public abstract class TypeConverter { int namePos ; protected ProblemReporter problemReporter ; protected boolean has1_5Compliance ; private char memberTypeSeparator ; protected TypeConverter ( ProblemReporter problemReporter , char memberTypeSeparator ) { this . problemReporter = problemReporter ; this . has1_5Compliance = problemReporter . options . originalComplianceLevel >= ClassFileConstants . JDK1_5 ; this . memberTypeSeparator = memberTypeSeparator ; } private void addIdentifiers ( String typeSignature , int start , int endExclusive , int identCount , ArrayList fragments ) { if ( identCount == 1 ) { char [ ] identifier ; typeSignature . getChars ( start , endExclusive , identifier = new char [ endExclusive - start ] , 0 ) ; fragments . add ( identifier ) ; } else fragments . add ( extractIdentifiers ( typeSignature , start , endExclusive - 1 , identCount ) ) ; } protected ImportReference createImportReference ( String [ ] importName , int start , int end , boolean onDemand , int modifiers ) { int length = importName . length ; long [ ] positions = new long [ length ] ; long position = ( ( long ) start << 32 ) + end ; char [ ] [ ] qImportName = new char [ length ] [ ] ; for ( int i = 0 ; i < length ; i ++ ) { qImportName [ i ] = importName [ i ] . toCharArray ( ) ; positions [ i ] = position ; } return new ImportReference ( qImportName , positions , onDemand , modifiers ) ; } protected TypeParameter createTypeParameter ( char [ ] typeParameterName , char [ ] [ ] typeParameterBounds , int start , int end ) { TypeParameter parameter = new TypeParameter ( ) ; parameter . name = typeParameterName ; parameter . sourceStart = start ; parameter . sourceEnd = end ; if ( typeParameterBounds != null ) { int length = typeParameterBounds . length ; if ( length > 0 ) { parameter . type = createTypeReference ( typeParameterBounds [ 0 ] , start , end ) ; if ( length > 1 ) { parameter . bounds = new TypeReference [ length - 1 ] ; for ( int i = 1 ; i < length ; i ++ ) { TypeReference bound = createTypeReference ( typeParameterBounds [ i ] , start , end ) ; bound . bits |= ASTNode . IsSuperType ; parameter . bounds [ i - 1 ] = bound ; } } } } return parameter ; } protected TypeReference createTypeReference ( char [ ] typeName , int start , int end , boolean includeGenericsAnyway ) { int length = typeName . length ; this . namePos = 0 ; return decodeType ( typeName , length , start , end , true ) ; } protected TypeReference createTypeReference ( char [ ] typeName , int start , int end ) { int length = typeName . length ; this . namePos = 0 ; return decodeType ( typeName , length , start , end , false ) ; } protected TypeReference createTypeReference ( String typeSignature , int start , int end ) { int length = typeSignature . length ( ) ; this . namePos = 0 ; return decodeType ( typeSignature , length , start , end ) ; } private TypeReference decodeType ( String typeSignature , int length , int start , int end ) { int identCount = 1 ; int dim = 0 ; int nameFragmentStart = this . namePos , nameFragmentEnd = - 1 ; boolean nameStarted = false ; ArrayList fragments = null ; typeLoop : while ( this . namePos < length ) { char currentChar = typeSignature . charAt ( this . namePos ) ; switch ( currentChar ) { case Signature . C_BOOLEAN : if ( ! nameStarted ) { this . namePos ++ ; if ( dim == 0 ) return new SingleTypeReference ( TypeBinding . BOOLEAN . simpleName , ( ( long ) start << 32 ) + end ) ; else return new ArrayTypeReference ( TypeBinding . BOOLEAN . simpleName , dim , ( ( long ) start << 32 ) + end ) ; } break ; case Signature . C_BYTE : if ( ! nameStarted ) { this . namePos ++ ; if ( dim == 0 ) return new SingleTypeReference ( TypeBinding . BYTE . simpleName , ( ( long ) start << 32 ) + end ) ; else return new ArrayTypeReference ( TypeBinding . BYTE . simpleName , dim , ( ( long ) start << 32 ) + end ) ; } break ; case Signature . C_CHAR : if ( ! nameStarted ) { this . namePos ++ ; if ( dim == 0 ) return new SingleTypeReference ( TypeBinding . CHAR . simpleName , ( ( long ) start << 32 ) + end ) ; else return new ArrayTypeReference ( TypeBinding . CHAR . simpleName , dim , ( ( long ) start << 32 ) + end ) ; } break ; case Signature . C_DOUBLE : if ( ! nameStarted ) { this . namePos ++ ; if ( dim == 0 ) return new SingleTypeReference ( TypeBinding . DOUBLE . simpleName , ( ( long ) start << 32 ) + end ) ; else return new ArrayTypeReference ( TypeBinding . DOUBLE . simpleName , dim , ( ( long ) start << 32 ) + end ) ; } break ; case Signature . C_FLOAT : if ( ! nameStarted ) { this . namePos ++ ; if ( dim == 0 ) return new SingleTypeReference ( TypeBinding . FLOAT . simpleName , ( ( long ) start << 32 ) + end ) ; else return new ArrayTypeReference ( TypeBinding . FLOAT . simpleName , dim , ( ( long ) start << 32 ) + end ) ; } break ; case Signature . C_INT : if ( ! nameStarted ) { this . namePos ++ ; if ( dim == 0 ) return new SingleTypeReference ( TypeBinding . INT . simpleName , ( ( long ) start << 32 ) + end ) ; else return new ArrayTypeReference ( TypeBinding . INT . simpleName , dim , ( ( long ) start << 32 ) + end ) ; } break ; case Signature . C_LONG : if ( ! nameStarted ) { this . namePos ++ ; if ( dim == 0 ) return new SingleTypeReference ( TypeBinding . LONG . simpleName , ( ( long ) start << 32 ) + end ) ; else return new ArrayTypeReference ( TypeBinding . LONG . simpleName , dim , ( ( long ) start << 32 ) + end ) ; } break ; case Signature . C_SHORT : if ( ! nameStarted ) { this . namePos ++ ; if ( dim == 0 ) return new SingleTypeReference ( TypeBinding . SHORT . simpleName , ( ( long ) start << 32 ) + end ) ; else return new ArrayTypeReference ( TypeBinding . SHORT . simpleName , dim , ( ( long ) start << 32 ) + end ) ; } break ; case Signature . C_VOID : if ( ! nameStarted ) { this . namePos ++ ; return new SingleTypeReference ( TypeBinding . VOID . simpleName , ( ( long ) start << 32 ) + end ) ; } break ; case Signature . C_RESOLVED : case Signature . C_UNRESOLVED : case Signature . C_TYPE_VARIABLE : if ( ! nameStarted ) { nameFragmentStart = this . namePos + 1 ; nameStarted = true ; } break ; case Signature . C_STAR : this . namePos ++ ; Wildcard result = new Wildcard ( Wildcard . UNBOUND ) ; result . sourceStart = start ; result . sourceEnd = end ; return result ; case Signature . C_EXTENDS : this . namePos ++ ; result = new Wildcard ( Wildcard . EXTENDS ) ; result . bound = decodeType ( typeSignature , length , start , end ) ; result . sourceStart = start ; result . sourceEnd = end ; return result ; case Signature . C_SUPER : this . namePos ++ ; result = new Wildcard ( Wildcard . SUPER ) ; result . bound = decodeType ( typeSignature , length , start , end ) ; result . sourceStart = start ; result . sourceEnd = end ; return result ; case Signature . C_ARRAY : dim ++ ; break ; case Signature . C_GENERIC_END : case Signature . C_SEMICOLON : nameFragmentEnd = this . namePos - 1 ; this . namePos ++ ; break typeLoop ; case Signature . C_DOLLAR : if ( this . memberTypeSeparator != Signature . C_DOLLAR ) break ; case Signature . C_DOT : if ( ! nameStarted ) { nameFragmentStart = this . namePos + 1 ; nameStarted = true ; } else if ( this . namePos > nameFragmentStart ) identCount ++ ; break ; case Signature . C_GENERIC_START : nameFragmentEnd = this . namePos - 1 ; if ( ! this . has1_5Compliance ) break typeLoop ; if ( fragments == null ) fragments = new ArrayList ( 2 ) ; addIdentifiers ( typeSignature , nameFragmentStart , nameFragmentEnd + 1 , identCount , fragments ) ; this . namePos ++ ; TypeReference [ ] arguments = decodeTypeArguments ( typeSignature , length , start , end ) ; fragments . add ( arguments ) ; identCount = 1 ; nameStarted = false ; break ; } this . namePos ++ ; } if ( fragments == null ) { if ( identCount == 1 ) { if ( dim == 0 ) { char [ ] nameFragment = new char [ nameFragmentEnd - nameFragmentStart + 1 ] ; typeSignature . getChars ( nameFragmentStart , nameFragmentEnd + 1 , nameFragment , 0 ) ; return new SingleTypeReference ( nameFragment , ( ( long ) start << 32 ) + end ) ; } else { char [ ] nameFragment = new char [ nameFragmentEnd - nameFragmentStart + 1 ] ; typeSignature . getChars ( nameFragmentStart , nameFragmentEnd + 1 , nameFragment , 0 ) ; return new ArrayTypeReference ( nameFragment , dim , ( ( long ) start << 32 ) + end ) ; } } else { long [ ] positions = new long [ identCount ] ; long pos = ( ( long ) start << 32 ) + end ; for ( int i = 0 ; i < identCount ; i ++ ) { positions [ i ] = pos ; } char [ ] [ ] identifiers = extractIdentifiers ( typeSignature , nameFragmentStart , nameFragmentEnd , identCount ) ; if ( dim == 0 ) { return new QualifiedTypeReference ( identifiers , positions ) ; } else { return new ArrayQualifiedTypeReference ( identifiers , dim , positions ) ; } } } else { if ( nameStarted ) { addIdentifiers ( typeSignature , nameFragmentStart , nameFragmentEnd + 1 , identCount , fragments ) ; } int fragmentLength = fragments . size ( ) ; if ( fragmentLength == 2 ) { Object firstFragment = fragments . get ( 0 ) ; if ( firstFragment instanceof char [ ] ) { return new ParameterizedSingleTypeReference ( ( char [ ] ) firstFragment , ( TypeReference [ ] ) fragments . get ( 1 ) , dim , ( ( long ) start << 32 ) + end ) ; } } identCount = 0 ; for ( int i = 0 ; i < fragmentLength ; i ++ ) { Object element = fragments . get ( i ) ; if ( element instanceof char [ ] [ ] ) { identCount += ( ( char [ ] [ ] ) element ) . length ; } else if ( element instanceof char [ ] ) identCount ++ ; } char [ ] [ ] tokens = new char [ identCount ] [ ] ; TypeReference [ ] [ ] arguments = new TypeReference [ identCount ] [ ] ; int index = 0 ; for ( int i = 0 ; i < fragmentLength ; i ++ ) { Object element = fragments . get ( i ) ; if ( element instanceof char [ ] [ ] ) { char [ ] [ ] fragmentTokens = ( char [ ] [ ] ) element ; int fragmentTokenLength = fragmentTokens . length ; System . arraycopy ( fragmentTokens , 0 , tokens , index , fragmentTokenLength ) ; index += fragmentTokenLength ; } else if ( element instanceof char [ ] ) { tokens [ index ++ ] = ( char [ ] ) element ; } else { arguments [ index - 1 ] = ( TypeReference [ ] ) element ; } } long [ ] positions = new long [ identCount ] ; long pos = ( ( long ) start << 32 ) + end ; for ( int i = 0 ; i < identCount ; i ++ ) { positions [ i ] = pos ; } return new ParameterizedQualifiedTypeReference ( tokens , arguments , dim , positions ) ; } } private TypeReference decodeType ( char [ ] typeName , int length , int start , int end , boolean includeGenericsAnyway ) { int identCount = 1 ; int dim = 0 ; int nameFragmentStart = this . namePos , nameFragmentEnd = - 1 ; ArrayList fragments = null ; typeLoop : while ( this . namePos < length ) { char currentChar = typeName [ this . namePos ] ; switch ( currentChar ) { case '?' : this . namePos ++ ; while ( typeName [ this . namePos ] == ' ' ) this . namePos ++ ; switch ( typeName [ this . namePos ] ) { case 's' : checkSuper : { int max = TypeConstants . WILDCARD_SUPER . length - 1 ; for ( int ahead = 1 ; ahead < max ; ahead ++ ) { if ( typeName [ this . namePos + ahead ] != TypeConstants . WILDCARD_SUPER [ ahead + 1 ] ) { break checkSuper ; } } this . namePos += max ; Wildcard result = new Wildcard ( Wildcard . SUPER ) ; result . bound = decodeType ( typeName , length , start , end , includeGenericsAnyway ) ; result . sourceStart = start ; result . sourceEnd = end ; return result ; } break ; case 'e' : checkExtends : { int max = TypeConstants . WILDCARD_EXTENDS . length - 1 ; for ( int ahead = 1 ; ahead < max ; ahead ++ ) { if ( typeName [ this . namePos + ahead ] != TypeConstants . WILDCARD_EXTENDS [ ahead + 1 ] ) { break checkExtends ; } } this . namePos += max ; Wildcard result = new Wildcard ( Wildcard . EXTENDS ) ; result . bound = decodeType ( typeName , length , start , end , includeGenericsAnyway ) ; result . sourceStart = start ; result . sourceEnd = end ; return result ; } break ; } Wildcard result = new Wildcard ( Wildcard . UNBOUND ) ; result . sourceStart = start ; result . sourceEnd = end ; return result ; case '[' : if ( dim == 0 && nameFragmentEnd < 0 ) nameFragmentEnd = this . namePos - 1 ; dim ++ ; break ; case ']' : break ; case '>' : case ',' : break typeLoop ; case '.' : if ( nameFragmentStart < 0 ) nameFragmentStart = this . namePos + 1 ; identCount ++ ; break ; case '<' : if ( this . has1_5Compliance || includeGenericsAnyway ) { if ( fragments == null ) fragments = new ArrayList ( 2 ) ; } nameFragmentEnd = this . namePos - 1 ; if ( this . has1_5Compliance || includeGenericsAnyway ) { char [ ] [ ] identifiers = CharOperation . splitOn ( '.' , typeName , nameFragmentStart , this . namePos ) ; fragments . add ( identifiers ) ; } this . namePos ++ ; TypeReference [ ] arguments = decodeTypeArguments ( typeName , length , start , end , includeGenericsAnyway ) ; if ( this . has1_5Compliance || includeGenericsAnyway ) { fragments . add ( arguments ) ; identCount = 0 ; nameFragmentStart = - 1 ; nameFragmentEnd = - 1 ; } break ; } this . namePos ++ ; } if ( nameFragmentEnd < 0 ) nameFragmentEnd = this . namePos - 1 ; if ( fragments == null ) { if ( identCount == 1 ) { if ( dim == 0 ) { char [ ] nameFragment ; if ( nameFragmentStart != 0 || nameFragmentEnd >= 0 ) { int nameFragmentLength = nameFragmentEnd - nameFragmentStart + 1 ; System . arraycopy ( typeName , nameFragmentStart , nameFragment = new char [ nameFragmentLength ] , 0 , nameFragmentLength ) ; } else { nameFragment = typeName ; } return new SingleTypeReference ( nameFragment , ( ( long ) start << 32 ) + end ) ; } else { int nameFragmentLength = nameFragmentEnd - nameFragmentStart + 1 ; char [ ] nameFragment = new char [ nameFragmentLength ] ; System . arraycopy ( typeName , nameFragmentStart , nameFragment , 0 , nameFragmentLength ) ; return new ArrayTypeReference ( nameFragment , dim , ( ( long ) start << 32 ) + end ) ; } } else { long [ ] positions = new long [ identCount ] ; long pos = ( ( long ) start << 32 ) + end ; for ( int i = 0 ; i < identCount ; i ++ ) { positions [ i ] = pos ; } char [ ] [ ] identifiers = CharOperation . splitOn ( '.' , typeName , nameFragmentStart , nameFragmentEnd + 1 ) ; if ( dim == 0 ) { return new QualifiedTypeReference ( identifiers , positions ) ; } else { return new ArrayQualifiedTypeReference ( identifiers , dim , positions ) ; } } } else { if ( nameFragmentStart > 0 && nameFragmentStart < length ) { char [ ] [ ] identifiers = CharOperation . splitOn ( '.' , typeName , nameFragmentStart , nameFragmentEnd + 1 ) ; fragments . add ( identifiers ) ; } int fragmentLength = fragments . size ( ) ; if ( fragmentLength == 2 ) { char [ ] [ ] firstFragment = ( char [ ] [ ] ) fragments . get ( 0 ) ; if ( firstFragment . length == 1 ) { return new ParameterizedSingleTypeReference ( firstFragment [ 0 ] , ( TypeReference [ ] ) fragments . get ( 1 ) , dim , ( ( long ) start << 32 ) + end ) ; } } identCount = 0 ; for ( int i = 0 ; i < fragmentLength ; i ++ ) { Object element = fragments . get ( i ) ; if ( element instanceof char [ ] [ ] ) { identCount += ( ( char [ ] [ ] ) element ) . length ; } } char [ ] [ ] tokens = new char [ identCount ] [ ] ; TypeReference [ ] [ ] arguments = new TypeReference [ identCount ] [ ] ; int index = 0 ; for ( int i = 0 ; i < fragmentLength ; i ++ ) { Object element = fragments . get ( i ) ; if ( element instanceof char [ ] [ ] ) { char [ ] [ ] fragmentTokens = ( char [ ] [ ] ) element ; int fragmentTokenLength = fragmentTokens . length ; System . arraycopy ( fragmentTokens , 0 , tokens , index , fragmentTokenLength ) ; index += fragmentTokenLength ; } else { arguments [ index - 1 ] = ( TypeReference [ ] ) element ; } } long [ ] positions = new long [ identCount ] ; long pos = ( ( long ) start << 32 ) + end ; for ( int i = 0 ; i < identCount ; i ++ ) { positions [ i ] = pos ; } return new ParameterizedQualifiedTypeReference ( tokens , arguments , dim , positions ) ; } } private TypeReference [ ] decodeTypeArguments ( char [ ] typeName , int length , int start , int end , boolean includeGenericsAnyway ) { ArrayList argumentList = new ArrayList ( 1 ) ; int count = 0 ; argumentsLoop : while ( this . namePos < length ) { TypeReference argument = decodeType ( typeName , length , start , end , includeGenericsAnyway ) ; count ++ ; argumentList . add ( argument ) ; if ( this . namePos >= length ) break argumentsLoop ; if ( typeName [ this . namePos ] == '>' ) { break argumentsLoop ; } this . namePos ++ ; } TypeReference [ ] typeArguments = new TypeReference [ count ] ; argumentList . toArray ( typeArguments ) ; return typeArguments ; } private TypeReference [ ] decodeTypeArguments ( String typeSignature , int length , int start , int end ) { ArrayList argumentList = new ArrayList ( 1 ) ; int count = 0 ; argumentsLoop : while ( this . namePos < length ) { TypeReference argument = decodeType ( typeSignature , length , start , end ) ; count ++ ; argumentList . add ( argument ) ; if ( this . namePos >= length ) break argumentsLoop ; if ( typeSignature . charAt ( this . namePos ) == Signature . C_GENERIC_END ) { break argumentsLoop ; } } TypeReference [ ] typeArguments = new TypeReference [ count ] ; argumentList . toArray ( typeArguments ) ; return typeArguments ; } private char [ ] [ ] extractIdentifiers ( String typeSignature , int start , int endInclusive , int identCount ) { char [ ] [ ] result = new char [ identCount ] [ ] ; int charIndex = start ; int i = 0 ; while ( charIndex < endInclusive ) { char currentChar ; if ( ( currentChar = typeSignature . charAt ( charIndex ) ) == this . memberTypeSeparator || currentChar == Signature . C_DOT ) { typeSignature . getChars ( start , charIndex , result [ i ++ ] = new char [ charIndex - start ] , 0 ) ; start = ++ charIndex ; } else charIndex ++ ; } typeSignature . getChars ( start , charIndex + 1 , result [ i ++ ] = new char [ charIndex - start + 1 ] , 0 ) ; return result ; } } </s>