<s> package org . eclipse . jdt . internal . core . builder ; import org . eclipse . core . resources . * ; import org . eclipse . core . runtime . * ; import org . eclipse . jdt . core . * ; import org . eclipse . jdt . core . compiler . CharOperation ; import org . eclipse . jdt . internal . compiler . env . * ; import org . eclipse . jdt . internal . compiler . problem . AbortCompilation ; import org . eclipse . jdt . internal . compiler . util . SimpleLookupTable ; import org . eclipse . jdt . internal . compiler . util . SimpleSet ; import org . eclipse . jdt . internal . compiler . util . SuffixConstants ; import org . eclipse . jdt . internal . core . * ; import java . io . * ; import java . util . * ; public class NameEnvironment implements INameEnvironment , SuffixConstants { boolean isIncrementalBuild ; ClasspathMultiDirectory [ ] sourceLocations ; ClasspathLocation [ ] binaryLocations ; BuildNotifier notifier ; SimpleSet initialTypeNames ; SimpleLookupTable additionalUnits ; NameEnvironment ( IWorkspaceRoot root , JavaProject javaProject , SimpleLookupTable binaryLocationsPerProject , BuildNotifier notifier ) throws CoreException { this . isIncrementalBuild = false ; this . notifier = notifier ; computeClasspathLocations ( root , javaProject , binaryLocationsPerProject ) ; setNames ( null , null ) ; } public NameEnvironment ( IJavaProject javaProject ) { this . isIncrementalBuild = false ; try { computeClasspathLocations ( javaProject . getProject ( ) . getWorkspace ( ) . getRoot ( ) , ( JavaProject ) javaProject , null ) ; } catch ( CoreException e ) { this . sourceLocations = new ClasspathMultiDirectory [ 0 ] ; this . binaryLocations = new ClasspathLocation [ 0 ] ; } setNames ( null , null ) ; } private void computeClasspathLocations ( IWorkspaceRoot root , JavaProject javaProject , SimpleLookupTable binaryLocationsPerProject ) throws CoreException { IMarker cycleMarker = javaProject . getCycleMarker ( ) ; if ( cycleMarker != null ) { int severity = JavaCore . ERROR . equals ( javaProject . getOption ( JavaCore . CORE_CIRCULAR_CLASSPATH , true ) ) ? IMarker . SEVERITY_ERROR : IMarker . SEVERITY_WARNING ; if ( severity != cycleMarker . getAttribute ( IMarker . SEVERITY , severity ) ) cycleMarker . setAttribute ( IMarker . SEVERITY , severity ) ; } IClasspathEntry [ ] classpathEntries = javaProject . getExpandedClasspath ( ) ; ArrayList sLocations = new ArrayList ( classpathEntries . length ) ; ArrayList bLocations = new ArrayList ( classpathEntries . length ) ; nextEntry : for ( int i = 0 , l = classpathEntries . length ; i < l ; i ++ ) { ClasspathEntry entry = ( ClasspathEntry ) classpathEntries [ i ] ; IPath path = entry . getPath ( ) ; Object target = JavaModel . getTarget ( path , true ) ; if ( target == null ) continue nextEntry ; switch ( entry . getEntryKind ( ) ) { case IClasspathEntry . CPE_SOURCE : if ( ! ( target instanceof IContainer ) ) continue nextEntry ; IPath outputPath = entry . getOutputLocation ( ) != null ? entry . getOutputLocation ( ) : javaProject . getOutputLocation ( ) ; IContainer outputFolder ; if ( outputPath . segmentCount ( ) == 1 ) { outputFolder = javaProject . getProject ( ) ; } else { outputFolder = root . getFolder ( outputPath ) ; if ( ! outputFolder . exists ( ) ) createOutputFolder ( outputFolder ) ; } sLocations . add ( ClasspathLocation . forSourceFolder ( ( IContainer ) target , outputFolder , entry . fullInclusionPatternChars ( ) , entry . fullExclusionPatternChars ( ) ) ) ; continue nextEntry ; case IClasspathEntry . CPE_PROJECT : if ( ! ( target instanceof IProject ) ) continue nextEntry ; IProject prereqProject = ( IProject ) target ; if ( ! JavaProject . hasJavaNature ( prereqProject ) ) continue nextEntry ; JavaProject prereqJavaProject = ( JavaProject ) JavaCore . create ( prereqProject ) ; IClasspathEntry [ ] prereqClasspathEntries = prereqJavaProject . getRawClasspath ( ) ; ArrayList seen = new ArrayList ( ) ; nextPrereqEntry : for ( int j = 0 , m = prereqClasspathEntries . length ; j < m ; j ++ ) { IClasspathEntry prereqEntry = prereqClasspathEntries [ j ] ; if ( prereqEntry . getEntryKind ( ) == IClasspathEntry . CPE_SOURCE ) { Object prereqTarget = JavaModel . getTarget ( prereqEntry . getPath ( ) , true ) ; if ( ! ( prereqTarget instanceof IContainer ) ) continue nextPrereqEntry ; IPath prereqOutputPath = prereqEntry . getOutputLocation ( ) != null ? prereqEntry . getOutputLocation ( ) : prereqJavaProject . getOutputLocation ( ) ; IContainer binaryFolder = prereqOutputPath . segmentCount ( ) == 1 ? ( IContainer ) prereqProject : ( IContainer ) root . getFolder ( prereqOutputPath ) ; if ( binaryFolder . exists ( ) && ! seen . contains ( binaryFolder ) ) { seen . add ( binaryFolder ) ; ClasspathLocation bLocation = ClasspathLocation . forBinaryFolder ( binaryFolder , true , entry . getAccessRuleSet ( ) ) ; bLocations . add ( bLocation ) ; if ( binaryLocationsPerProject != null ) { ClasspathLocation [ ] existingLocations = ( ClasspathLocation [ ] ) binaryLocationsPerProject . get ( prereqProject ) ; if ( existingLocations == null ) { existingLocations = new ClasspathLocation [ ] { bLocation } ; } else { int size = existingLocations . length ; System . arraycopy ( existingLocations , 0 , existingLocations = new ClasspathLocation [ size + 1 ] , 0 , size ) ; existingLocations [ size ] = bLocation ; } binaryLocationsPerProject . put ( prereqProject , existingLocations ) ; } } } } continue nextEntry ; case IClasspathEntry . CPE_LIBRARY : if ( target instanceof IResource ) { IResource resource = ( IResource ) target ; ClasspathLocation bLocation = null ; if ( resource instanceof IFile ) { AccessRuleSet accessRuleSet = ( JavaCore . IGNORE . equals ( javaProject . getOption ( JavaCore . COMPILER_PB_FORBIDDEN_REFERENCE , true ) ) && JavaCore . IGNORE . equals ( javaProject . getOption ( JavaCore . COMPILER_PB_DISCOURAGED_REFERENCE , true ) ) ) ? null : entry . getAccessRuleSet ( ) ; bLocation = ClasspathLocation . forLibrary ( ( IFile ) resource , accessRuleSet ) ; } else if ( resource instanceof IContainer ) { AccessRuleSet accessRuleSet = ( JavaCore . IGNORE . equals ( javaProject . getOption ( JavaCore . COMPILER_PB_FORBIDDEN_REFERENCE , true ) ) && JavaCore . IGNORE . equals ( javaProject . getOption ( JavaCore . COMPILER_PB_DISCOURAGED_REFERENCE , true ) ) ) ? null : entry . getAccessRuleSet ( ) ; bLocation = ClasspathLocation . forBinaryFolder ( ( IContainer ) target , false , accessRuleSet ) ; } bLocations . add ( bLocation ) ; if ( binaryLocationsPerProject != null ) { IProject p = resource . getProject ( ) ; ClasspathLocation [ ] existingLocations = ( ClasspathLocation [ ] ) binaryLocationsPerProject . get ( p ) ; if ( existingLocations == null ) { existingLocations = new ClasspathLocation [ ] { bLocation } ; } else { int size = existingLocations . length ; System . arraycopy ( existingLocations , 0 , existingLocations = new ClasspathLocation [ size + 1 ] , 0 , size ) ; existingLocations [ size ] = bLocation ; } binaryLocationsPerProject . put ( p , existingLocations ) ; } } else if ( target instanceof File ) { AccessRuleSet accessRuleSet = ( JavaCore . IGNORE . equals ( javaProject . getOption ( JavaCore . COMPILER_PB_FORBIDDEN_REFERENCE , true ) ) && JavaCore . IGNORE . equals ( javaProject . getOption ( JavaCore . COMPILER_PB_DISCOURAGED_REFERENCE , true ) ) ) ? null : entry . getAccessRuleSet ( ) ; bLocations . add ( ClasspathLocation . forLibrary ( path . toString ( ) , accessRuleSet ) ) ; } continue nextEntry ; } } ArrayList outputFolders = new ArrayList ( 1 ) ; this . sourceLocations = new ClasspathMultiDirectory [ sLocations . size ( ) ] ; if ( ! sLocations . isEmpty ( ) ) { sLocations . toArray ( this . sourceLocations ) ; next : for ( int i = 0 , l = this . sourceLocations . length ; i < l ; i ++ ) { ClasspathMultiDirectory md = this . sourceLocations [ i ] ; IPath outputPath = md . binaryFolder . getFullPath ( ) ; for ( int j = 0 ; j < i ; j ++ ) { if ( outputPath . equals ( this . sourceLocations [ j ] . binaryFolder . getFullPath ( ) ) ) { md . hasIndependentOutputFolder = this . sourceLocations [ j ] . hasIndependentOutputFolder ; continue next ; } } outputFolders . add ( md ) ; for ( int j = 0 , m = this . sourceLocations . length ; j < m ; j ++ ) if ( outputPath . equals ( this . sourceLocations [ j ] . sourceFolder . getFullPath ( ) ) ) continue next ; md . hasIndependentOutputFolder = true ; } } this . binaryLocations = new ClasspathLocation [ outputFolders . size ( ) + bLocations . size ( ) ] ; int index = 0 ; for ( int i = 0 , l = outputFolders . size ( ) ; i < l ; i ++ ) this . binaryLocations [ index ++ ] = ( ClasspathLocation ) outputFolders . get ( i ) ; for ( int i = 0 , l = bLocations . size ( ) ; i < l ; i ++ ) this . binaryLocations [ index ++ ] = ( ClasspathLocation ) bLocations . get ( i ) ; } public void cleanup ( ) { this . initialTypeNames = null ; this . additionalUnits = null ; for ( int i = 0 , l = this . sourceLocations . length ; i < l ; i ++ ) this . sourceLocations [ i ] . cleanup ( ) ; for ( int i = 0 , l = this . binaryLocations . length ; i < l ; i ++ ) this . binaryLocations [ i ] . cleanup ( ) ; } private void createOutputFolder ( IContainer outputFolder ) throws CoreException { createParentFolder ( outputFolder . getParent ( ) ) ; ( ( IFolder ) outputFolder ) . create ( IResource . FORCE | IResource . DERIVED , true , null ) ; } private void createParentFolder ( IContainer parent ) throws CoreException { if ( ! parent . exists ( ) ) { createParentFolder ( parent . getParent ( ) ) ; ( ( IFolder ) parent ) . create ( true , true , null ) ; } } private NameEnvironmentAnswer findClass ( String qualifiedTypeName , char [ ] typeName ) { if ( this . notifier != null ) this . notifier . checkCancelWithinCompiler ( ) ; if ( this . initialTypeNames != null && this . initialTypeNames . includes ( qualifiedTypeName ) ) { if ( this . isIncrementalBuild ) throw new AbortCompilation ( true , new AbortIncrementalBuildException ( qualifiedTypeName ) ) ; return null ; } if ( this . additionalUnits != null && this . sourceLocations . length > 0 ) { SourceFile unit = ( SourceFile ) this . additionalUnits . get ( qualifiedTypeName ) ; if ( unit != null ) return new NameEnvironmentAnswer ( unit , null ) ; } String qBinaryFileName = qualifiedTypeName + SUFFIX_STRING_class ; String binaryFileName = qBinaryFileName ; String qPackageName = "" ; if ( qualifiedTypeName . length ( ) > typeName . length ) { int typeNameStart = qBinaryFileName . length ( ) - typeName . length - 6 ; qPackageName = qBinaryFileName . substring ( 0 , typeNameStart - 1 ) ; binaryFileName = qBinaryFileName . substring ( typeNameStart ) ; } NameEnvironmentAnswer suggestedAnswer = null ; for ( int i = 0 , l = this . binaryLocations . length ; i < l ; i ++ ) { NameEnvironmentAnswer answer = this . binaryLocations [ i ] . findClass ( binaryFileName , qPackageName , qBinaryFileName ) ; if ( answer != null ) { if ( ! answer . ignoreIfBetter ( ) ) { if ( answer . isBetter ( suggestedAnswer ) ) return answer ; } else if ( answer . isBetter ( suggestedAnswer ) ) suggestedAnswer = answer ; } } if ( suggestedAnswer != null ) return suggestedAnswer ; return null ; } public NameEnvironmentAnswer findType ( char [ ] [ ] compoundName ) { if ( compoundName != null ) return findClass ( new String ( CharOperation . concatWith ( compoundName , '/' ) ) , compoundName [ compoundName . length - 1 ] ) ; return null ; } public NameEnvironmentAnswer findType ( char [ ] typeName , char [ ] [ ] packageName ) { if ( typeName != null ) return findClass ( new String ( CharOperation . concatWith ( packageName , typeName , '/' ) ) , typeName ) ; return null ; } public boolean isPackage ( char [ ] [ ] compoundName , char [ ] packageName ) { return isPackage ( new String ( CharOperation . concatWith ( compoundName , packageName , '/' ) ) ) ; } public boolean isPackage ( String qualifiedPackageName ) { for ( int i = 0 , l = this . binaryLocations . length ; i < l ; i ++ ) if ( this . binaryLocations [ i ] . isPackage ( qualifiedPackageName ) ) return true ; return false ; } void setNames ( String [ ] typeNames , SourceFile [ ] additionalFiles ) { if ( typeNames == null ) { this . initialTypeNames = null ; } else { this . initialTypeNames = new SimpleSet ( typeNames . length ) ; for ( int i = 0 , l = typeNames . length ; i < l ; i ++ ) this . initialTypeNames . add ( typeNames [ i ] ) ; } if ( additionalFiles == null ) { this . additionalUnits = null ; } else { this . additionalUnits = new SimpleLookupTable ( additionalFiles . length ) ; for ( int i = 0 , l = additionalFiles . length ; i < l ; i ++ ) { SourceFile additionalUnit = additionalFiles [ i ] ; if ( additionalUnit != null ) this . additionalUnits . put ( additionalUnit . initialTypeName , additionalFiles [ i ] ) ; } } for ( int i = 0 , l = this . sourceLocations . length ; i < l ; i ++ ) this . sourceLocations [ i ] . reset ( ) ; for ( int i = 0 , l = this . binaryLocations . length ; i < l ; i ++ ) this . binaryLocations [ i ] . reset ( ) ; } } </s>