blob: 6396d4ceef3fbace4a249917d29a20817d139e56 [file] [log] [blame]
package org.eclipse.osbp.xtext.oxtype.scoping.jvmtype;
import java.util.List;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xtext.common.types.JvmType;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.resource.EObjectDescription;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.util.Strings;
public class KnownTypesScope extends AbstractKnownTypesScope {
private final List<? extends JvmType> types;
public KnownTypesScope(List<? extends JvmType> types,
AbstractOXTypeTypeScope parent) {
super(parent);
this.types = types;
}
@Override
protected void doGetElements(JvmType type, List<IEObjectDescription> result) {
for (int i = 0; i < types.size(); i++) {
JvmType knownType = types.get(i);
if (EcoreUtil.isAncestor(knownType, type)) {
doGetDescriptions(type, knownType, i, result);
}
}
super.doGetElements(type, result);
}
@Override
protected IEObjectDescription doGetSingleElement(QualifiedName name,
String firstSegment, int dollarIndex) {
int index = -1;
JvmType result = null;
for (int i = 0; i < types.size(); i++) {
JvmType type = types.get(i);
JvmType exactMatch = getExactMatch(type, index, name);
if (exactMatch != null)
return EObjectDescription.create(name, exactMatch);
if (isMatch(i, type, firstSegment, name)) {
JvmType resolved = getUnambiguousResult(result, index, type, i,
name);
if (resolved == null) {
return null;
}
if (resolved != result) {
result = resolved;
index = i;
}
}
}
return toDescription(name, result, dollarIndex, index);
}
@Override
protected IEObjectDescription toDescription(QualifiedName name,
JvmType result, int dollarIndex, int index) {
if (result != null) {
JvmType actualResult = dollarIndex > 0
|| name.getSegmentCount() > 0 ? findNestedType(result,
index, name) : result;
if (actualResult != null) {
return EObjectDescription.create(name, actualResult);
}
}
return null;
}
/*
* If we know java.util.Map$Entry exists and we query for the FQN, we assume
* things are valid.
*/
protected JvmType getExactMatch(JvmType type, int index, QualifiedName name) {
QualifiedName typeName = QualifiedName.create(Strings.split(
type.getQualifiedName(), '.'));
if (name.equals(typeName)) {
return type;
}
if (name.startsWith(typeName)) {
JvmType result = findNestedType(type, index,
name.skipFirst(typeName.getSegmentCount() - 1));
return result;
}
if (name.getSegmentCount() > typeName.getSegmentCount()) {
if (typeName.skipLast(1).equals(name.skipLast(1))) {
if (typeName.getLastSegment().equals(
name.skipFirst(typeName.getSegmentCount() - 1)
.toString("$"))) {
return type;
}
}
}
return null;
}
protected boolean isMatch(int index, JvmType type, String simpleName,
QualifiedName relativeName) {
return simpleName.equals(type.getSimpleName());
}
@Override
protected void doGetDescriptions(JvmType type, JvmType knownType,
int index, List<IEObjectDescription> result) {
if (type == knownType) {
result.add(EObjectDescription.create(
QualifiedName.create(type.getSimpleName()), type));
} else if (type.eContainer() == knownType) {
result.add(EObjectDescription.create(
QualifiedName.create(knownType.getSimpleName(),
type.getSimpleName()), type));
result.add(EObjectDescription.create(
QualifiedName.create(knownType.getSimpleName() + '$'
+ type.getSimpleName()), type));
} else {
String knownTypeName = knownType.getQualifiedName();
String withDollar = type.getQualifiedName('$');
String withDot = type.getQualifiedName('.');
result.add(EObjectDescription.create(
QualifiedName.create(Strings.split(
withDot.substring(knownTypeName.length()), '.')),
type));
result.add(EObjectDescription.create(QualifiedName
.create(withDollar.substring(knownTypeName.length())), type));
}
}
}