blob: 30198266ab6c72064811e55837a548ac77a14eed [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008, 2016 xored software, Inc.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* xored software, Inc. - initial API and Implementation (Alex Panchenko)
*******************************************************************************/
package org.eclipse.dltk.ruby.internal.debug.ui.console;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.core.DLTKLanguageManager;
import org.eclipse.dltk.core.IDLTKLanguageToolkit;
import org.eclipse.dltk.core.IProjectFragment;
import org.eclipse.dltk.core.IScriptFolder;
import org.eclipse.dltk.core.IScriptProject;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.core.environment.EnvironmentPathUtils;
import org.eclipse.dltk.core.search.IDLTKSearchScope;
import org.eclipse.dltk.core.search.SearchEngine;
import org.eclipse.dltk.internal.core.util.Util;
public class RubyConsoleSourceModuleLookup {
private final IDLTKSearchScope scope;
public RubyConsoleSourceModuleLookup(IDLTKLanguageToolkit toolkit) {
scope = SearchEngine.createWorkspaceScope(toolkit);
}
private IProject[] getAllProjects() {
return ResourcesPlugin.getWorkspace().getRoot().getProjects();
}
private boolean checkScope(IProject project, IPath[] scopeProjectsAndZips) {
final IPath location = project.getFullPath();
for (int j = 0; j < scopeProjectsAndZips.length; j++) {
if (scopeProjectsAndZips[j].equals(location)) {
return true;
}
}
return false;
}
public ISourceModule findSourceModuleByLocalPath(final IPath path) {
final boolean isFullPath = EnvironmentPathUtils.isFull(path);
final IProject[] projects = getAllProjects();
final IPath[] enclosingProjectsAndZips = scope
.enclosingProjectsAndZips();
for (int i = 0, max = projects.length; i < max; i++) {
try {
final IProject project = projects[i];
if (!checkScope(project, enclosingProjectsAndZips)) {
continue;
}
if (!project.isAccessible()
|| !DLTKLanguageManager.hasScriptNature(project))
continue;
IScriptProject scriptProject = DLTKCore.create(project);
final ISourceModule module = findInProject(scriptProject, path,
isFullPath);
if (module != null) {
return module.exists() ? module : null;
}
} catch (CoreException e) {
// CoreException from hasNature - should not happen since we
// check that the project is accessible
// ModelException from getProjectFragments - a problem occurred
// while accessing project: nothing we can do, ignore
}
}
return null;
}
public static boolean isIncluded(IProjectFragment fragment, IPath path) {
final IProjectFragment root = fragment;
return !Util.isExcluded(path, root, false);
}
private ISourceModule findInProject(IScriptProject scriptProject,
IPath path, boolean isFullPath) throws ModelException {
IProjectFragment[] roots = scriptProject.getProjectFragments();
for (int j = 0, rootCount = roots.length; j < rootCount; j++) {
final IProjectFragment root = roots[j];
IPath rootPath = root.getPath();
if (!isFullPath) {
rootPath = EnvironmentPathUtils.getLocalPath(rootPath);
}
if (rootPath.isPrefixOf(path) && isIncluded(root, path)) {
IPath localPath = path.setDevice(null).removeFirstSegments(
rootPath.segmentCount());
if (localPath.segmentCount() >= 1) {
final IScriptFolder folder;
if (localPath.segmentCount() > 1) {
folder = root.getScriptFolder(localPath
.removeLastSegments(1));
} else {
folder = root.getScriptFolder(Path.EMPTY);
}
return folder.getSourceModule(localPath.lastSegment());
}
}
}
return null;
}
}