blob: be3688f01b58db9d909934c1e579c21946f0e5a7 [file] [log] [blame]
package org.eclipse.dltk.core.model.binary;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import org.eclipse.core.runtime.IPath;
import org.eclipse.dltk.compiler.IElementRequestor.FieldInfo;
import org.eclipse.dltk.compiler.IElementRequestor.MethodInfo;
import org.eclipse.dltk.compiler.IElementRequestor.TypeInfo;
import org.eclipse.dltk.compiler.util.Util;
import org.eclipse.dltk.core.IField;
import org.eclipse.dltk.core.IMethod;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.ISourceRange;
import org.eclipse.dltk.core.IType;
import org.eclipse.dltk.core.SourceRange;
/**
* @since 2.0
*/
public class SourceMapper {
private static class Range {
int start;
int end;
public Range(int start, int end) {
super();
this.start = start;
this.end = end;
}
}
private Map<IModelElement, Range> sourceRanges = new HashMap<>();
private Map<IModelElement, Range> nameRanges = new HashMap<>();
private IPath sourcePath;
// private IPath sourceRoot;
private Set<IBinaryModule> sourcesNotPressent = new HashSet<>();
private Map<IBinaryModule, String> sourcesMap = new WeakHashMap<>();
public SourceMapper(IPath sourcePath, IPath sourceAttachmentRootPath) {
this.sourcePath = sourcePath;
// this.sourceRoot = sourceAttachmentRootPath;
}
private ISourceRange getRange(Range range) {
if (range == null) {
return SourceRange.UNKNOWN_RANGE;
}
return new SourceRange(range.start, range.end - range.start + 1);
}
public ISourceRange getSourceRange(IModelElement element) {
fetchRangesForElement(element);
Range range = null;
synchronized (sourceRanges) {
range = sourceRanges.get(element);
}
return getRange(range);
}
protected void fetchRangesForElement(IModelElement element) {
}
public ISourceRange getNameRange(IModelElement element) {
fetchRangesForElement(element);
Range range = null;
synchronized (sourceRanges) {
range = nameRanges.get(element);
}
return getRange(range);
}
void reportType(TypeInfo info, IType type) {
synchronized (sourceRanges) {
nameRanges.put(type,
new Range(info.nameSourceStart, info.nameSourceEnd));
sourceRanges.put(type, new Range(info.declarationStart, 0));
}
}
void reportField(FieldInfo info, IField field) {
synchronized (sourceRanges) {
nameRanges.put(field,
new Range(info.nameSourceStart, info.nameSourceEnd));
sourceRanges.put(field, new Range(info.declarationStart, 0));
}
}
void reportMethod(MethodInfo info, IMethod method) {
synchronized (sourceRanges) {
nameRanges.put(method,
new Range(info.nameSourceStart, info.nameSourceEnd));
sourceRanges.put(method, new Range(info.declarationStart, 0));
}
}
public void setRangeEnd(IModelElement element, int declarationEnd) {
Range range = null;
synchronized (sourceRanges) {
range = sourceRanges.get(element);
}
if (range != null) {
range.end = declarationEnd;
}
}
public String getSource(IBinaryModule binaryModule) {
if (sourcesNotPressent.contains(binaryModule)) {
return null;
}
String content = sourcesMap.get(binaryModule);
if (content != null) {
return content;
}
String source = findSource(binaryModule, binaryModule.getElementName());
if (source != null) {
sourcesMap.put(binaryModule, source);
} else {
sourcesNotPressent.add(binaryModule);
}
return source;
}
protected String findSource(IBinaryModule binaryModule, String filename) {
File file = sourcePath.toFile();
if (file.isDirectory()) {
// Look into directory
File result = traversePath(file, filename);
if (result != null) {
try {
return new String(Util.getFileByteContent(result));
} catch (IOException e) {
e.printStackTrace();
}
}
} else if (isArchive(file)) {
return findSourceInArchive(file, filename);
}
return null;
}
protected String findSourceInArchive(File file, String filename) {
return null;
}
public boolean isArchive(File file) {
return false;
}
private File traversePath(File file, String filename) {
File[] listFiles = file.listFiles();
for (File child : listFiles) {
if (child.isDirectory()) {
File result = traversePath(child, filename);
if (result != null) {
return result;
}
} else {
if (isFileMatch(child, filename)) {
return child;
}
}
}
return null;
}
protected boolean isFileMatch(File child, String filename) {
if (child.getName().equals(filename)) {
return true;
}
return false;
}
}