/** * Returns whether elements of the given project or jar can see the given focus (an IJavaProject * or a JarPackageFragmentRot) either because the focus is part of the project or the jar, or * because it is accessible throught the project's classpath */ public static boolean canSeeFocus(SearchPattern pattern, IPath projectOrJarPath) { try { IJavaModel model = JavaModelManager.getJavaModelManager().getJavaModel(); IJavaProject project = getJavaProject(projectOrJarPath, model); IJavaElement[] focuses = getFocusedElementsAndTypes(pattern, project, null); if (focuses.length == 0) return false; if (project != null) { return canSeeFocus(focuses, (JavaProject) project, null); } // projectOrJarPath is a jar // it can see the focus only if it is on the classpath of a project that can see the focus IJavaProject[] allProjects = model.getJavaProjects(); for (int i = 0, length = allProjects.length; i < length; i++) { JavaProject otherProject = (JavaProject) allProjects[i]; IClasspathEntry entry = otherProject.getClasspathEntryFor(projectOrJarPath); if (entry != null && entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) { if (canSeeFocus(focuses, otherProject, null)) { return true; } } } return false; } catch (JavaModelException e) { return false; } }
/** * Bug 68993: [Preferences] IAE when opening project preferences * * @see "http://bugs.eclipse.org/bugs/show_bug.cgi?id=68993" */ public void testBug68993() throws CoreException, BackingStoreException { try { JavaProject projectA = (JavaProject) this.createJavaProject( "A", new String[] {}, // source folders new String[] {}, // lib folders new String[] {}, // projects ""); // set all project options as custom ones: this is what happens when user select // "Use project settings" in project 'Java Compiler' preferences page... Hashtable options = new Hashtable(projectA.getOptions(true)); projectA.setOptions(options); // reset all project custom options: this is what happens when user select // "Use workspace settings" in project 'Java Compiler' preferences page... options = new Hashtable(); options.put("internal.default.compliance", JavaCore.DEFAULT); projectA.setOptions(options); // verify that project preferences have been reset assertEquals( "projA: We should not have any custom options!", 0, projectA.getEclipsePreferences().keys().length); } finally { this.deleteProject("A"); } }
/** * @bug 152578: [prefs] IJavaProject.setOption(Object,Object) wrongly removes key when value is * equals to JavaCore one * @test Verify that setting an option to workspace value does not remove it from project * preferences * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=152578" */ public void testBug152578() throws CoreException { Hashtable wkspOptions = JavaCore.getOptions(); String wkspCompilerSource = (String) wkspOptions.get(JavaCore.COMPILER_SOURCE); String compilerSource = wkspCompilerSource.equals(JavaCore.VERSION_1_5) ? JavaCore.VERSION_1_6 : JavaCore.VERSION_1_5; try { JavaProject project = (JavaProject) createJavaProject("P"); project.setOption(JavaCore.COMPILER_SOURCE, wkspCompilerSource); String option = project.getOption(JavaCore.COMPILER_SOURCE, true); if (!option.equals(wkspCompilerSource)) { System.err.println( "Unexpected option value: " + option + " instead of: " + wkspCompilerSource); } Hashtable newOptions = JavaCore.getOptions(); newOptions.put(JavaCore.COMPILER_SOURCE, compilerSource); JavaCore.setOptions(newOptions); option = project.getOption(JavaCore.COMPILER_SOURCE, false); assertNotNull("Project should still have the option set!", option); } finally { deleteProject("P"); JavaCore.setOptions(wkspOptions); } }
private static boolean canSeeFocus( IJavaElement focus, JavaProject javaProject, char[][][] focusQualifiedNames) { try { if (focus == null) return false; if (focus.equals(javaProject)) return true; if (focus instanceof JarPackageFragmentRoot) { // focus is part of a jar IPath focusPath = focus.getPath(); IClasspathEntry[] entries = javaProject.getExpandedClasspath(); for (int i = 0, length = entries.length; i < length; i++) { IClasspathEntry entry = entries[i]; if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY && entry.getPath().equals(focusPath)) return true; } return false; } // look for dependent projects IPath focusPath = ((JavaProject) focus).getProject().getFullPath(); IClasspathEntry[] entries = javaProject.getExpandedClasspath(); for (int i = 0, length = entries.length; i < length; i++) { IClasspathEntry entry = entries[i]; if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT && entry.getPath().equals(focusPath)) { if (focusQualifiedNames != null) { // builder state is usable, hence use it to try to reduce project which can // see the focus... State projectState = (State) JavaModelManager.getJavaModelManager() .getLastBuiltState(javaProject.getProject(), null); if (projectState != null) { Object[] values = projectState.getReferences().valueTable; int vLength = values.length; for (int j = 0; j < vLength; j++) { if (values[j] == null) continue; ReferenceCollection references = (ReferenceCollection) values[j]; if (references.includes(focusQualifiedNames, null, null)) { return true; } } return false; } } return true; } } return false; } catch (JavaModelException e) { return false; } }
/** * @bug 346010 - [model] strange initialization dependency in OptionTests * @test Verify that unfortunate order of map entries doesn't spoil intended semantics. * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=346010" * @deprecated As using deprecated constants */ public void testBug346010() throws CoreException { class ForcedOrderMap extends Hashtable { private static final long serialVersionUID = 8012963985718522218L; Map original; Map.Entry additionalEntry; /* Force (additionalKey,additionalValue) to be served after all entries of original. */ public ForcedOrderMap(Map original, String additionalKey, String additionalValue) { this.original = original; // convert additionalKey->additionalValue to a Map.Entry without inserting into original: Hashtable tmp = new Hashtable(); tmp.put(additionalKey, additionalValue); this.additionalEntry = (Map.Entry) tmp.entrySet().iterator().next(); } public Set entrySet() { return new HashSet() { private static final long serialVersionUID = 1L; public Iterator iterator() { List orderedEntries; orderedEntries = new ArrayList(ForcedOrderMap.this.original.entrySet()); orderedEntries.add(ForcedOrderMap.this.additionalEntry); return orderedEntries.iterator(); } }; } public synchronized boolean containsKey(Object key) { return this.original.containsKey(key) || key.equals(this.additionalEntry.getKey()); } } try { // Set the obsolete option using the IJavaProject API JavaProject project = (JavaProject) createJavaProject("P"); final String obsoleteOption = DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_MEMBER; Map testOptions = project.getOptions(true); Map orderedOptions = new ForcedOrderMap(testOptions, obsoleteOption, JavaCore.DO_NOT_INSERT); project.setOptions(orderedOptions); // Verify that obsolete preference is not stored assertNull( "Unexpected value for formatter deprecated option 'org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member'", project.getEclipsePreferences().get(obsoleteOption, null)); // Verify that project obsolete option is well retrieved assertEquals( "Unexpected value for formatter deprecated option 'org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member'", JavaCore.INSERT, project.getOption(obsoleteOption, true)); } finally { deleteProject("P"); } }
/** * @bug 125360: IJavaProject#setOption() doesn't work if same option as default * @see "http://bugs.eclipse.org/bugs/show_bug.cgi?id=125360" */ public void testBug125360() throws CoreException, BackingStoreException { try { JavaProject project = (JavaProject) createJavaProject( "P", new String[] {}, // source folders new String[] {}, // lib folders new String[] {}, // projects ""); project.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_4); project.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_3); String option = project.getOption(JavaCore.COMPILER_SOURCE, true); assertEquals(JavaCore.VERSION_1_3, option); } finally { deleteProject("P"); } }
/** * @param project * @param destinationPath * @throws JavaModelException */ private void migrateClassPathDependentContent(IProject project, IPath destinationPath) throws JavaModelException { JavaProject javaProjectToMigrate = new JavaProject(project, null); JavaProject newJavaProject = new JavaProject(newProject, null); assert (javaProjectToMigrate != null && newJavaProject != null) : JAVA_PROJECTS_COULD_NOT_BE_CREATED; IClasspathEntry[] classpathToMigrate = javaProjectToMigrate.getRawClasspath(); List<IClasspathEntry> newClassPath = new ArrayList<IClasspathEntry>(); newClassPath.addAll(Arrays.asList(newJavaProject.getRawClasspath())); assert classpathToMigrate != null : CLASSPATH_OF_PROJECT_TO_MIGRATE_IS_NULL; migrateLibraryAndContainerEntries(newJavaProject, classpathToMigrate, newClassPath); migrateSourceFiles(project, destinationPath, classpathToMigrate); migrateProjectNatures(project); }
/** * @bug 152562: [prefs] IJavaProject.setOption(..., null) does not work * @test Verify that setting an option to null removes it from project preferences * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=152562" */ public void testBug152562() throws CoreException { String wkspCompilerSource = JavaCore.getOption(JavaCore.COMPILER_SOURCE); String compilerSource = wkspCompilerSource.equals(JavaCore.VERSION_1_5) ? JavaCore.VERSION_1_6 : JavaCore.VERSION_1_5; try { JavaProject project = (JavaProject) createJavaProject("P"); project.setOption(JavaCore.COMPILER_SOURCE, compilerSource); String option = project.getOption(JavaCore.COMPILER_SOURCE, true); if (!option.equals(compilerSource)) { System.err.println("Unexpected option value: " + option + " instead of: " + compilerSource); } project.setOption(JavaCore.COMPILER_SOURCE, null); option = project.getOption(JavaCore.COMPILER_SOURCE, true); assertEquals(wkspCompilerSource, option); } finally { deleteProject("P"); } }
/** * @bug 324987: [formatter] API compatibility problem with Annotation Newline options * @test Verify that a deprecated option is well preserved when a client use it through the * IJavaProject.setOption(String, String) API * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=324987" * @deprecated As using deprecated constants */ public void testBug324987_Project01() throws CoreException { try { // Set the obsolete option using the IJavaProject API JavaProject project = (JavaProject) createJavaProject("P"); final String obsoleteOption = DefaultCodeFormatterConstants.FORMATTER_INSERT_NEW_LINE_AFTER_ANNOTATION_ON_MEMBER; project.setOption(obsoleteOption, JavaCore.DO_NOT_INSERT); // Verify that obsolete preference is not stored assertNull( "Unexpected value for formatter deprecated option 'org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member'", project.getEclipsePreferences().get(obsoleteOption, null)); // Verify that project obsolete option is well retrieved assertEquals( "Unexpected value for formatter deprecated option 'org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member'", JavaCore.DO_NOT_INSERT, project.getOption(obsoleteOption, true)); } finally { deleteProject("P"); } }
/** * Custom options must replace existing ones completely without loosing property listeners * http://bugs.eclipse.org/bugs/show_bug.cgi?id=59258 * http://bugs.eclipse.org/bugs/show_bug.cgi?id=60896 */ public void test09() throws CoreException { try { this.eventCount = 0; JavaProject projectA = (JavaProject) this.createJavaProject("A", new String[] {}, ""); // Preferences preferences = projectA.getPreferences(); // preferences.addPropertyChangeListener(new TestPropertyListener()); IEclipsePreferences eclipsePreferences = projectA.getEclipsePreferences(); eclipsePreferences.addPreferenceChangeListener(new TestPropertyListener()); Hashtable options = new Hashtable(); options.put(JavaCore.COMPILER_PB_DEPRECATION_IN_DEPRECATED_CODE, JavaCore.ENABLED); options.put(JavaCore.COMPILER_COMPLIANCE, "10.0"); projectA.setOptions(options); // check project A custom options assertEquals( "projA:unexpected custom value for deprecation option", JavaCore.ENABLED, projectA.getOptions(true).get(JavaCore.COMPILER_PB_DEPRECATION_IN_DEPRECATED_CODE)); assertEquals( "projA:unexpected custom value for compliance option", "10.0", projectA.getOptions(true).get(JavaCore.COMPILER_COMPLIANCE)); assertTrue( "projA:preferences should not be reset", eclipsePreferences == projectA.getEclipsePreferences()); assertEquals("projA:preferences property listener has been lost", 2, this.eventCount); // delete/create project A and verify that options are well reset this.deleteProject("A"); projectA = (JavaProject) this.createJavaProject("A", new String[] {}, ""); assertEquals( "projA:unexpected custom value for deprecation option", JavaCore.getOption(JavaCore.COMPILER_PB_DEPRECATION_IN_DEPRECATED_CODE), projectA.getOptions(true).get(JavaCore.COMPILER_PB_DEPRECATION_IN_DEPRECATED_CODE)); assertEquals( "projA:unexpected custom value for compliance option", JavaCore.getOption(JavaCore.COMPILER_COMPLIANCE), projectA.getOptions(true).get(JavaCore.COMPILER_COMPLIANCE)); assertTrue( "projA:preferences should not be reset", eclipsePreferences != projectA.getEclipsePreferences()); } finally { this.deleteProject("A"); } }
/** * @param newJavaProject * @param classpathToMigrate * @param newClassPath * @throws JavaModelException */ private void migrateLibraryAndContainerEntries( JavaProject newJavaProject, IClasspathEntry[] classpathToMigrate, List<IClasspathEntry> newClassPath) throws JavaModelException { for (IClasspathEntry entry : classpathToMigrate) { if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER || entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) if (!newClassPath.contains(entry)) newClassPath.add(entry); } newJavaProject.setRawClasspath( newClassPath.toArray(new IClasspathEntry[newClassPath.size()]), null); }
/* Return the list of projects for which it requires a resource delta. This builder's project * is implicitly included and need not be specified. Builders must re-specify the list * of interesting projects every time they are run as this is not carried forward * beyond the next build. Missing projects should be specified but will be ignored until * they are added to the workspace. */ private IProject[] getRequiredProjects(boolean includeBinaryPrerequisites) { if (this.javaProject == null || this.workspaceRoot == null) return new IProject[0]; ArrayList projects = new ArrayList(); ExternalFoldersManager externalFoldersManager = JavaModelManager.getExternalManager(); try { IClasspathEntry[] entries = this.javaProject.getExpandedClasspath(); for (int i = 0, l = entries.length; i < l; i++) { IClasspathEntry entry = entries[i]; IPath path = entry.getPath(); IProject p = null; switch (entry.getEntryKind()) { case IClasspathEntry.CPE_PROJECT: p = this.workspaceRoot.getProject( path.lastSegment()); // missing projects are considered too if (((ClasspathEntry) entry).isOptional() && !JavaProject.hasJavaNature(p)) // except if entry is optional p = null; break; case IClasspathEntry.CPE_LIBRARY: if (includeBinaryPrerequisites && path.segmentCount() > 0) { // some binary resources on the class path can come from projects that are not // included in the project references IResource resource = this.workspaceRoot.findMember(path.segment(0)); if (resource instanceof IProject) { p = (IProject) resource; } else { resource = externalFoldersManager.getFolder(path); if (resource != null) p = resource.getProject(); } } } if (p != null && !projects.contains(p)) projects.add(p); } } catch (JavaModelException e) { return new IProject[0]; } IProject[] result = new IProject[projects.size()]; projects.toArray(result); return result; }
private boolean isClasspathBroken(JavaProject jProj, boolean tryRepair) throws CoreException { IMarker[] markers = jProj .getProject() .findMarkers(IJavaModelMarker.BUILDPATH_PROBLEM_MARKER, false, IResource.DEPTH_ZERO); for (int i = 0, l = markers.length; i < l; i++) { if (markers[i].getAttribute(IMarker.SEVERITY, -1) == IMarker.SEVERITY_ERROR) { if (tryRepair) { Object code = markers[i].getAttribute(IJavaModelMarker.ID); if (code instanceof Integer && ((Integer) code) == IJavaModelStatusConstants.CP_INVALID_EXTERNAL_ANNOTATION_PATH) { new ClasspathValidation(jProj).validate(); return isClasspathBroken(jProj, false); } } return true; } } return false; }
private void buildForProject( JavaProject project, ArrayList potentialSubtypes, org.eclipse.jdt.core.ICompilationUnit[] workingCopies, HashSet localTypes, IProgressMonitor monitor) throws JavaModelException { // resolve int openablesLength = potentialSubtypes.size(); if (openablesLength > 0) { // copy vectors into arrays Openable[] openables = new Openable[openablesLength]; potentialSubtypes.toArray(openables); // sort in the order of roots and in reverse alphabetical order for .class file // since requesting top level types in the process of caching an enclosing type is // not supported by the lookup environment IPackageFragmentRoot[] roots = project.getPackageFragmentRoots(); int rootsLength = roots.length; final HashtableOfObjectToInt indexes = new HashtableOfObjectToInt(openablesLength); for (int i = 0; i < openablesLength; i++) { IJavaElement root = openables[i].getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT); int index; for (index = 0; index < rootsLength; index++) { if (roots[index].equals(root)) break; } indexes.put(openables[i], index); } Arrays.sort( openables, new Comparator() { public int compare(Object a, Object b) { int aIndex = indexes.get(a); int bIndex = indexes.get(b); if (aIndex != bIndex) return aIndex - bIndex; return ((Openable) b).getElementName().compareTo(((Openable) a).getElementName()); } }); IType focusType = getType(); boolean inProjectOfFocusType = focusType != null && focusType.getJavaProject().equals(project); org.eclipse.jdt.core.ICompilationUnit[] unitsToLookInside = null; if (inProjectOfFocusType) { org.eclipse.jdt.core.ICompilationUnit unitToLookInside = focusType.getCompilationUnit(); if (unitToLookInside != null) { int wcLength = workingCopies == null ? 0 : workingCopies.length; if (wcLength == 0) { unitsToLookInside = new org.eclipse.jdt.core.ICompilationUnit[] {unitToLookInside}; } else { unitsToLookInside = new org.eclipse.jdt.core.ICompilationUnit[wcLength + 1]; unitsToLookInside[0] = unitToLookInside; System.arraycopy(workingCopies, 0, unitsToLookInside, 1, wcLength); } } else { unitsToLookInside = workingCopies; } } SearchableEnvironment searchableEnvironment = project.newSearchableNameEnvironment(unitsToLookInside); this.nameLookup = searchableEnvironment.nameLookup; Map options = project.getOptions(true); // disable task tags to speed up parsing options.put(JavaCore.COMPILER_TASK_TAGS, ""); // $NON-NLS-1$ this.hierarchyResolver = new HierarchyResolver(searchableEnvironment, options, this, new DefaultProblemFactory()); if (focusType != null) { Member declaringMember = ((Member) focusType).getOuterMostLocalContext(); if (declaringMember == null) { // top level or member type if (!inProjectOfFocusType) { char[] typeQualifiedName = focusType.getTypeQualifiedName('.').toCharArray(); String[] packageName = ((PackageFragment) focusType.getPackageFragment()).names; if (searchableEnvironment.findType(typeQualifiedName, Util.toCharArrays(packageName)) == null) { // focus type is not visible in this project: no need to go further return; } } } else { // local or anonymous type Openable openable; if (declaringMember.isBinary()) { openable = (Openable) declaringMember.getClassFile(); } else { openable = (Openable) declaringMember.getCompilationUnit(); } localTypes = new HashSet(); localTypes.add(openable.getPath().toString()); this.hierarchyResolver.resolve(new Openable[] {openable}, localTypes, monitor); return; } } this.hierarchyResolver.resolve(openables, localTypes, monitor); } }
/** * Add a path to current java search scope or all project fragment roots if null. Use project * resolved classpath to retrieve and store access restriction on each classpath entry. Recurse if * dependent projects are found. * * @param javaProject Project used to get resolved classpath entries * @param pathToAdd Path to add in case of single element or null if user want to add all project * package fragment roots * @param includeMask Mask to apply on classpath entries * @param projectsToBeAdded Set to avoid infinite recursion * @param visitedProjects Set to avoid adding twice the same project * @param referringEntry Project raw entry in referring project classpath * @throws JavaModelException May happen while getting java model info */ void add( JavaProject javaProject, IPath pathToAdd, int includeMask, HashSet projectsToBeAdded, HashSet visitedProjects, IClasspathEntry referringEntry) throws JavaModelException { IProject project = javaProject.getProject(); if (!project.isAccessible() || !visitedProjects.add(project)) return; IPath projectPath = project.getFullPath(); String projectPathString = projectPath.toString(); addEnclosingProjectOrJar(projectPath); IClasspathEntry[] entries = javaProject.getResolvedClasspath(); IJavaModel model = javaProject.getJavaModel(); JavaModelManager.PerProjectInfo perProjectInfo = javaProject.getPerProjectInfo(); for (int i = 0, length = entries.length; i < length; i++) { IClasspathEntry entry = entries[i]; AccessRuleSet access = null; ClasspathEntry cpEntry = (ClasspathEntry) entry; if (referringEntry != null) { // Add only exported entries. // Source folder are implicitly exported. if (!entry.isExported() && entry.getEntryKind() != IClasspathEntry.CPE_SOURCE) { continue; } cpEntry = cpEntry.combineWith((ClasspathEntry) referringEntry); // cpEntry = ((ClasspathEntry)referringEntry).combineWith(cpEntry); } access = cpEntry.getAccessRuleSet(); switch (entry.getEntryKind()) { case IClasspathEntry.CPE_LIBRARY: IClasspathEntry rawEntry = null; Map rootPathToRawEntries = perProjectInfo.rootPathToRawEntries; if (rootPathToRawEntries != null) { rawEntry = (IClasspathEntry) rootPathToRawEntries.get(entry.getPath()); } if (rawEntry == null) break; rawKind: switch (rawEntry.getEntryKind()) { case IClasspathEntry.CPE_LIBRARY: case IClasspathEntry.CPE_VARIABLE: if ((includeMask & APPLICATION_LIBRARIES) != 0) { IPath path = entry.getPath(); if (pathToAdd == null || pathToAdd.equals(path)) { Object target = JavaModel.getTarget(path, false /*don't check existence*/); if (target instanceof IFolder) // case of an external folder path = ((IFolder) target).getFullPath(); String pathToString = path.getDevice() == null ? path.toString() : path.toOSString(); add( projectPath.toString(), "", pathToString, false /*not a package*/, access); //$NON-NLS-1$ addEnclosingProjectOrJar(entry.getPath()); } } break; case IClasspathEntry.CPE_CONTAINER: IClasspathContainer container = JavaCore.getClasspathContainer(rawEntry.getPath(), javaProject); if (container == null) break; switch (container.getKind()) { case IClasspathContainer.K_APPLICATION: if ((includeMask & APPLICATION_LIBRARIES) == 0) break rawKind; break; case IClasspathContainer.K_SYSTEM: case IClasspathContainer.K_DEFAULT_SYSTEM: if ((includeMask & SYSTEM_LIBRARIES) == 0) break rawKind; break; default: break rawKind; } IPath path = entry.getPath(); if (pathToAdd == null || pathToAdd.equals(path)) { Object target = JavaModel.getTarget(path, false /*don't check existence*/); if (target instanceof IFolder) // case of an external folder path = ((IFolder) target).getFullPath(); String pathToString = path.getDevice() == null ? path.toString() : path.toOSString(); add( projectPath.toString(), "", pathToString, false /*not a package*/, access); //$NON-NLS-1$ addEnclosingProjectOrJar(entry.getPath()); } break; } break; case IClasspathEntry.CPE_PROJECT: if ((includeMask & REFERENCED_PROJECTS) != 0) { IPath path = entry.getPath(); if (pathToAdd == null || pathToAdd.equals(path)) { JavaProject referencedProject = (JavaProject) model.getJavaProject(path.toOSString()); if (!projectsToBeAdded.contains( referencedProject)) { // do not recurse if depending project was used to create // the scope add( referencedProject, null, includeMask, projectsToBeAdded, visitedProjects, cpEntry); } } } break; case IClasspathEntry.CPE_SOURCE: if ((includeMask & SOURCES) != 0) { IPath path = entry.getPath(); if (pathToAdd == null || pathToAdd.equals(path)) { add( projectPath.toString(), Util.relativePath(path, projectPath.segmentCount() /*remove project segment*/), projectPathString, false /*not a package*/, access); } } break; } } }
private boolean isWorthBuilding() throws CoreException { boolean abortBuilds = JavaCore.ABORT.equals( this.javaProject.getOption(JavaCore.CORE_JAVA_BUILD_INVALID_CLASSPATH, true)); if (!abortBuilds) { if (DEBUG) System.out.println("JavaBuilder: Ignoring invalid classpath"); // $NON-NLS-1$ return true; } // Abort build only if there are classpath errors if (isClasspathBroken(this.javaProject, true)) { if (DEBUG) System.out.println( "JavaBuilder: Aborted build because project has classpath errors (incomplete or involved in cycle)"); //$NON-NLS-1$ removeProblemsAndTasksFor(this.currentProject); // remove all compilation problems IMarker marker = this.currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER); marker.setAttributes( new String[] { IMarker.MESSAGE, IMarker.SEVERITY, IJavaModelMarker.CATEGORY_ID, IMarker.SOURCE_ID }, new Object[] { Messages.build_abortDueToClasspathProblems, new Integer(IMarker.SEVERITY_ERROR), new Integer(CategorizedProblem.CAT_BUILDPATH), JavaBuilder.SOURCE_ID }); return false; } if (JavaCore.WARNING.equals( this.javaProject.getOption(JavaCore.CORE_INCOMPLETE_CLASSPATH, true))) return true; // make sure all prereq projects have valid build states... only when aborting builds since // projects in cycles do not have build states // except for projects involved in a 'warning' cycle (see below) IProject[] requiredProjects = getRequiredProjects(false); for (int i = 0, l = requiredProjects.length; i < l; i++) { IProject p = requiredProjects[i]; if (getLastState(p) == null) { // The prereq project has no build state: if this prereq project has a 'warning' cycle // marker then allow build (see bug id 23357) JavaProject prereq = (JavaProject) JavaCore.create(p); if (prereq.hasCycleMarker() && JavaCore.WARNING.equals( this.javaProject.getOption(JavaCore.CORE_CIRCULAR_CLASSPATH, true))) { if (DEBUG) System.out.println( "JavaBuilder: Continued to build even though prereq project " + p.getName() // $NON-NLS-1$ + " was not built since its part of a cycle"); //$NON-NLS-1$ continue; } if (!hasJavaBuilder(p)) { if (DEBUG) System.out.println( "JavaBuilder: Continued to build even though prereq project " + p.getName() // $NON-NLS-1$ + " is not built by JavaBuilder"); //$NON-NLS-1$ continue; } if (DEBUG) System.out.println( "JavaBuilder: Aborted build because prereq project " + p.getName() // $NON-NLS-1$ + " was not built"); //$NON-NLS-1$ removeProblemsAndTasksFor( this.currentProject); // make this the only problem for this project IMarker marker = this.currentProject.createMarker(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER); marker.setAttributes( new String[] { IMarker.MESSAGE, IMarker.SEVERITY, IJavaModelMarker.CATEGORY_ID, IMarker.SOURCE_ID }, new Object[] { isClasspathBroken(prereq, true) ? Messages.bind(Messages.build_prereqProjectHasClasspathProblems, p.getName()) : Messages.bind(Messages.build_prereqProjectMustBeRebuilt, p.getName()), new Integer(IMarker.SEVERITY_ERROR), new Integer(CategorizedProblem.CAT_BUILDPATH), JavaBuilder.SOURCE_ID }); return false; } } return true; }
@SuppressWarnings({"unchecked", "rawtypes", "nls", "restriction"}) @Override protected boolean buildStructure( OpenableElementInfo info, IProgressMonitor pm, Map newElements, IResource underlyingResource) throws JavaModelException { try { depth.set(depth.get() + 1); // if (!isOnBuildPath()) { // return false; // } if (GroovyLogManager.manager.hasLoggers()) { GroovyLogManager.manager.log( TraceCategory.COMPILER, "Build Structure starting for " + this.name); GroovyLogManager.manager.logStart( "Build structure: " + name + " : " + Thread.currentThread().getName()); } CompilationUnitElementInfo unitInfo = (CompilationUnitElementInfo) info; // ensure buffer is opened IBuffer buffer = getBufferManager().getBuffer(this); if (buffer == null) { openBuffer(pm, unitInfo); // open buffer independently from the // info, since we are building the info } // generate structure and compute syntax problems if needed GroovyCompilationUnitStructureRequestor requestor = new GroovyCompilationUnitStructureRequestor(this, unitInfo, newElements); JavaModelManager.PerWorkingCopyInfo perWorkingCopyInfo = getPerWorkingCopyInfo(); JavaProject project = (JavaProject) getJavaProject(); // determine what kind of buildStructure we are doing boolean createAST; int reconcileFlags; boolean resolveBindings; HashMap problems; if (info instanceof ASTHolderCUInfo) { ASTHolderCUInfo astHolder = (ASTHolderCUInfo) info; createAST = ((Integer) ReflectionUtils.getPrivateField( ASTHolderCUInfo.class, "astLevel", astHolder)) .intValue() != NO_AST; //$NON-NLS-1$ resolveBindings = ((Boolean) ReflectionUtils.getPrivateField( ASTHolderCUInfo.class, "resolveBindings", astHolder)) .booleanValue(); reconcileFlags = ((Integer) ReflectionUtils.getPrivateField( ASTHolderCUInfo.class, "reconcileFlags", astHolder)) // $NON-NLS-1$ .intValue(); problems = (HashMap) ReflectionUtils.getPrivateField(ASTHolderCUInfo.class, "problems", astHolder); } else { createAST = false; resolveBindings = false; reconcileFlags = 0; problems = null; } boolean computeProblems = perWorkingCopyInfo != null && perWorkingCopyInfo.isActive() && project != null && JavaProject.hasJavaNature(project.getProject()); IProblemFactory problemFactory = new DefaultProblemFactory(); // compiler options Map<String, String> options = (project == null ? JavaCore.getOptions() : project.getOptions(true)); if (!computeProblems) { // disable task tags checking to speed up parsing options.put(JavaCore.COMPILER_TASK_TAGS, ""); // $NON-NLS-1$ } // FIXASC deal with the case of project==null to reduce duplication in this next line and call // to setGroovyClasspath // Required for Groovy, but not for Java options.put(CompilerOptions.OPTIONG_BuildGroovyFiles, CompilerOptions.ENABLED); CompilerOptions compilerOptions = new CompilerOptions(options); if (project != null) { CompilerUtils.setGroovyClasspath(compilerOptions, project); } // Required for Groovy, but not for Java ProblemReporter reporter = new ProblemReporter( new GroovyErrorHandlingPolicy(!computeProblems), compilerOptions, new DefaultProblemFactory()); SourceElementParser parser = new MultiplexingSourceElementRequestorParser( reporter, requestor, /* * not needed if * computing groovy only */ problemFactory, compilerOptions, true /* report local declarations */, !createAST /* * optimize string literals only if not * creating a DOM AST */); parser.reportOnlyOneSyntaxError = !computeProblems; // maybe not needed for groovy, but I don't want to find out. parser.setMethodsFullRecovery(true); parser.setStatementsRecovery( (reconcileFlags & ICompilationUnit.ENABLE_STATEMENTS_RECOVERY) != 0); if (!computeProblems && !resolveBindings && !createAST) // disable javadoc parsing if not computing problems, not // resolving // and not creating ast parser.javadocParser.checkDocComment = false; requestor.setParser(parser); // update timestamp (might be IResource.NULL_STAMP if original does not // exist) if (underlyingResource == null) { underlyingResource = getResource(); } // underlying resource is null in the case of a working copy on a class // file in a jar if (underlyingResource != null) { ReflectionUtils.setPrivateField( CompilationUnitElementInfo.class, "timestamp", unitInfo, underlyingResource //$NON-NLS-1$ .getModificationStamp()); } GroovyCompilationUnitDeclaration compilationUnitDeclaration = null; CompilationUnit source = cloneCachingContents(); try { // GROOVY // note that this is a slightly different approach than taken by super.buildStructure // in super.buildStructure, there is a test here to see if computeProblems is true. // if false, then parser.parserCompilationUnit is called. // this will not work for Groovy because we need to ensure bindings are resolved // for many operations (content assist and code select) to work. // So, for groovy, always use CompilationUnitProblemFinder.process and then process problems // separately only if necessary // addendum (GRECLIPSE-942). The testcase for that bug includes a package with 200 // types in that refer to each other in a chain, through field references. If a reconcile // references the top of the chain we can go through a massive number of recursive calls // into // this buildStructure for each one. The 'full' parse (with bindings) is only required for // the top most (regardless of the computeProblems setting) and so we track how many // recursive // calls we have made - if we are at depth 2 we do what JDT was going to do (the quick // thing). if (computeProblems || depth.get() < 2) { if (problems == null) { // report problems to the problem requestor problems = new HashMap(); compilationUnitDeclaration = (GroovyCompilationUnitDeclaration) CompilationUnitProblemFinder.process( source, parser, this.owner, problems, createAST, reconcileFlags, pm); if (computeProblems) { try { perWorkingCopyInfo.beginReporting(); for (Iterator iteraror = problems.values().iterator(); iteraror.hasNext(); ) { CategorizedProblem[] categorizedProblems = (CategorizedProblem[]) iteraror.next(); if (categorizedProblems == null) continue; for (int i = 0, length = categorizedProblems.length; i < length; i++) { perWorkingCopyInfo.acceptProblem(categorizedProblems[i]); } } } finally { perWorkingCopyInfo.endReporting(); } } } else { // collect problems compilationUnitDeclaration = (GroovyCompilationUnitDeclaration) CompilationUnitProblemFinder.process( source, parser, this.owner, problems, createAST, reconcileFlags, pm); } } else { compilationUnitDeclaration = (GroovyCompilationUnitDeclaration) parser.parseCompilationUnit( source, true /* full parse to find local elements */, pm); } // GROOVY // if this is a working copy, then we have more work to do maybeCacheModuleNode(perWorkingCopyInfo, compilationUnitDeclaration); // create the DOM AST from the compiler AST if (createAST) { org.eclipse.jdt.core.dom.CompilationUnit ast; try { ast = AST.convertCompilationUnit( AST.JLS3, compilationUnitDeclaration, options, computeProblems, source, reconcileFlags, pm); ReflectionUtils.setPrivateField(ASTHolderCUInfo.class, "ast", info, ast); // $NON-NLS-1$ } catch (OperationCanceledException e) { // catch this exception so as to not enter the catch(RuntimeException e) below // might need to do the same for AbortCompilation throw e; } catch (IllegalArgumentException e) { // if necessary, we can do some better reporting here. Util.log( e, "Problem with build structure: Offset for AST node is incorrect in " //$NON-NLS-1$ + this.getParent().getElementName() + "." + getElementName()); //$NON-NLS-1$ } catch (Exception e) { Util.log(e, "Problem with build structure for " + this.getElementName()); // $NON-NLS-1$ } } } catch (OperationCanceledException e) { // catch this exception so as to not enter the catch(RuntimeException e) below // might need to do the same for AbortCompilation throw e; } catch (JavaModelException e) { // GRECLIPSE-1480 don't log element does not exist exceptions. since this could occur when // element is in a non-java // project if (e.getStatus().getCode() != IJavaModelStatusConstants.ELEMENT_DOES_NOT_EXIST || this.getJavaProject().exists()) { Util.log(e, "Problem with build structure for " + this.getElementName()); // $NON-NLS-1$ } } catch (Exception e) { // GROOVY: The groovy compiler does not handle broken code well in many situations // use this general catch clause so that exceptions thrown by broken code // do not bubble up the stack. Util.log(e, "Problem with build structure for " + this.getElementName()); // $NON-NLS-1$ } finally { if (compilationUnitDeclaration != null) { compilationUnitDeclaration.cleanUp(); } } return unitInfo.isStructureKnown(); } finally { depth.set(depth.get() - 1); if (GroovyLogManager.manager.hasLoggers()) { GroovyLogManager.manager.logEnd( "Build structure: " + name + " : " + Thread.currentThread().getName(), TraceCategory.COMPILER); } } }
/* * Compute the list of paths which are keying index files. */ private void initializeIndexLocations() { IPath[] projectsAndJars = this.searchScope.enclosingProjectsAndJars(); IndexManager manager = JavaModelManager.getIndexManager(); SimpleSet locations = new SimpleSet(); IJavaElement focus = MatchLocator.projectOrJarFocus(this.pattern); if (focus == null) { for (int i = 0; i < projectsAndJars.length; i++) { IPath path = projectsAndJars[i]; Object target = JavaModel.getTarget(path, false /*don't check existence*/); if (target instanceof IFolder) // case of an external folder path = ((IFolder) target).getFullPath(); locations.add(manager.computeIndexLocation(path)); } } else { try { // See whether the state builder might be used to reduce the number of index locations // find the projects from projectsAndJars that see the focus then walk those projects // looking for the jars from projectsAndJars int length = projectsAndJars.length; JavaProject[] projectsCanSeeFocus = new JavaProject[length]; SimpleSet visitedProjects = new SimpleSet(length); int projectIndex = 0; SimpleSet externalLibsToCheck = new SimpleSet(length); ObjectVector superTypes = new ObjectVector(); IJavaElement[] focuses = getFocusedElementsAndTypes(this.pattern, focus, superTypes); char[][][] focusQualifiedNames = null; boolean isAutoBuilding = ResourcesPlugin.getWorkspace().getDescription().isAutoBuilding(); if (isAutoBuilding && focus instanceof IJavaProject) { focusQualifiedNames = getQualifiedNames(superTypes); } IJavaModel model = JavaModelManager.getJavaModelManager().getJavaModel(); for (int i = 0; i < length; i++) { IPath path = projectsAndJars[i]; JavaProject project = (JavaProject) getJavaProject(path, model); if (project != null) { visitedProjects.add(project); if (canSeeFocus(focuses, project, focusQualifiedNames)) { locations.add(manager.computeIndexLocation(path)); projectsCanSeeFocus[projectIndex++] = project; } } else { externalLibsToCheck.add(path); } } for (int i = 0; i < projectIndex && externalLibsToCheck.elementSize > 0; i++) { IClasspathEntry[] entries = projectsCanSeeFocus[i].getResolvedClasspath(); for (int j = entries.length; --j >= 0; ) { IClasspathEntry entry = entries[j]; if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) { IPath path = entry.getPath(); if (externalLibsToCheck.remove(path) != null) { Object target = JavaModel.getTarget(path, false /*don't check existence*/); if (target instanceof IFolder) // case of an external folder path = ((IFolder) target).getFullPath(); locations.add(manager.computeIndexLocation(path)); } } } } // jar files can be included in the search scope without including one of the projects that // references them, so scan all projects that have not been visited if (externalLibsToCheck.elementSize > 0) { IJavaProject[] allProjects = model.getJavaProjects(); for (int i = 0, l = allProjects.length; i < l && externalLibsToCheck.elementSize > 0; i++) { JavaProject project = (JavaProject) allProjects[i]; if (!visitedProjects.includes(project)) { IClasspathEntry[] entries = project.getResolvedClasspath(); for (int j = entries.length; --j >= 0; ) { IClasspathEntry entry = entries[j]; if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) { IPath path = entry.getPath(); if (externalLibsToCheck.remove(path) != null) { Object target = JavaModel.getTarget(path, false /*don't check existence*/); if (target instanceof IFolder) // case of an external folder path = ((IFolder) target).getFullPath(); locations.add(manager.computeIndexLocation(path)); } } } } } } } catch (JavaModelException e) { // ignored } } this.indexLocations = new IPath[locations.elementSize]; Object[] values = locations.values; int count = 0; for (int i = values.length; --i >= 0; ) if (values[i] != null) this.indexLocations[count++] = (IPath) values[i]; }
/** * Custom options must replace existing ones completely without loosing property listeners * http://bugs.eclipse.org/bugs/show_bug.cgi?id=26255 * http://bugs.eclipse.org/bugs/show_bug.cgi?id=49691 */ public void test07() throws CoreException { try { this.eventCount = 0; JavaProject projectA = (JavaProject) this.createJavaProject( "A", new String[] {}, // source folders new String[] {}, // lib folders new String[] {}, // projects ""); // Preferences preferences = projectA.getPreferences(); // preferences.addPropertyChangeListener(new TestPropertyListener()); IEclipsePreferences eclipsePreferences = projectA.getEclipsePreferences(); TestPropertyListener listener = new TestPropertyListener(); eclipsePreferences.addPreferenceChangeListener(listener); Hashtable options = new Hashtable(); options.put(JavaCore.COMPILER_PB_DEPRECATION_IN_DEPRECATED_CODE, JavaCore.ENABLED); options.put(JavaCore.COMPILER_COMPLIANCE, "10.0"); projectA.setOptions(options); // check project A custom options assertEquals( "projA:unexpected custom value for deprecation option", JavaCore.ENABLED, projectA.getOptions(false).get(JavaCore.COMPILER_PB_DEPRECATION_IN_DEPRECATED_CODE)); assertEquals( "projA:unexpected custom value for compliance option", "10.0", projectA.getOptions(false).get(JavaCore.COMPILER_COMPLIANCE)); assertEquals( "projA:unexpected inherited value1 for hidden-catch option", null, projectA.getOptions(false).get(JavaCore.COMPILER_PB_HIDDEN_CATCH_BLOCK)); // assertTrue("projA:preferences should not be reset", preferences == // projectA.getPreferences()); assertTrue( "projA:preferences should not be reset", eclipsePreferences == projectA.getEclipsePreferences()); assertTrue("projA:preferences property listener has been lost", this.eventCount == 2); // change custom options to have one less options.clear(); options.put(JavaCore.COMPILER_PB_DEPRECATION_IN_DEPRECATED_CODE, JavaCore.ENABLED); projectA.setOptions(options); assertEquals( "projA:unexpected custom value for deprecation option", JavaCore.ENABLED, projectA.getOptions(false).get(JavaCore.COMPILER_PB_DEPRECATION_IN_DEPRECATED_CODE)); assertEquals( "projA:unexpected custom value for compliance option", null, projectA.getOptions(false).get(JavaCore.COMPILER_COMPLIANCE)); assertEquals( "projA:unexpected inherited value1 for hidden-catch option", null, projectA.getOptions(false).get(JavaCore.COMPILER_PB_HIDDEN_CATCH_BLOCK)); // assertTrue("projA:preferences should not be reset", preferences == // projectA.getPreferences()); assertTrue( "projA:preferences should not be reset", eclipsePreferences == projectA.getEclipsePreferences()); assertTrue("projA:preferences property listener has been lost", this.eventCount == 3); } finally { this.deleteProject("A"); } }