No classloading in TypeUtil.isMap method
See: https://www.pivotaltracker.com/story/show/167917595
This commit is contained in:
@@ -145,7 +145,7 @@ public class PropertyInfo {
|
||||
|
||||
public HintProvider getHints(TypeUtil typeUtil) {
|
||||
Type type = TypeParser.parse(this.type);
|
||||
if (TypeUtil.isMap(type)) {
|
||||
if (typeUtil.isMap(type)) {
|
||||
return HintProviders.forMap(keyHints(typeUtil), valueHints(typeUtil), TypeUtil.getDomainType(type));
|
||||
} else if (TypeUtil.isSequencable(type)) {
|
||||
return HintProviders.forAllValueContexts(valueHints(typeUtil));
|
||||
|
||||
@@ -485,7 +485,7 @@ public class TypeUtil {
|
||||
return type!=null && type.getErasure().endsWith("[]");
|
||||
}
|
||||
|
||||
public static boolean isMap(Type type) {
|
||||
public boolean isMap(Type type) {
|
||||
//Note: to be really correct we should use JDT infrastructure to resolve
|
||||
//type in project classpath instead of using Java reflection.
|
||||
//However, use reflection here is okay assuming types we care about
|
||||
@@ -493,9 +493,14 @@ public class TypeUtil {
|
||||
//also potentialy be very slow.
|
||||
if (type!=null) {
|
||||
String erasure = type.getErasure();
|
||||
if ("java.util.Map".equals(erasure)) {
|
||||
//quick / easy case. No looking for types and hierarchies required.
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
Class<?> erasureClass = Class.forName(erasure);
|
||||
return Map.class.isAssignableFrom(erasureClass);
|
||||
IType mapType = findType("java.util.Map");
|
||||
IType erasureType = findType(erasure);
|
||||
return isAssignableFrom(mapType, erasureType);
|
||||
} catch (Exception e) {
|
||||
//type not resolveable
|
||||
}
|
||||
@@ -503,6 +508,36 @@ public class TypeUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isAssignableFrom(IType mapType, IType erasureType) {
|
||||
Set<String> seen = new HashSet<>();
|
||||
return searchSuperTypes(seen, erasureType, mapType.getFullyQualifiedName());
|
||||
}
|
||||
|
||||
|
||||
private boolean searchSuperTypes(Set<String> seen, IType searchIn, String fqTargetType) {
|
||||
if (searchIn!=null) {
|
||||
String fqName = searchIn.getFullyQualifiedName();
|
||||
if (fqName.equals(fqTargetType)) {
|
||||
return true;
|
||||
}
|
||||
if (seen.add(fqName)) {
|
||||
for (String itfName : searchIn.getSuperInterfaceNames()) {
|
||||
IType itf = findType(itfName);
|
||||
if (searchSuperTypes(seen, itf, fqTargetType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
String klassName = searchIn.getSuperclassName();
|
||||
IType klass = findType(klassName);
|
||||
if (searchSuperTypes(seen, klass, fqTargetType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get domain type for a map or list generic type.
|
||||
*/
|
||||
@@ -966,9 +1001,9 @@ public class TypeUtil {
|
||||
* List<List<List<String>>> -> 2
|
||||
* Map<*,List<String>> -> 2
|
||||
*/
|
||||
public static int getDimensionality(Type type) {
|
||||
public int getDimensionality(Type type) {
|
||||
int dim = 0;
|
||||
while (isSequencable(type) || isMap(type)) {
|
||||
while (isSequencable(type) || this.isMap(type)) {
|
||||
dim++;
|
||||
type = getDomainType(type);
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ public class PropertyNavigator {
|
||||
* checked to be 'dotable'.
|
||||
*/
|
||||
private Type dotNavigate(int offset, Type type) {
|
||||
if (TypeUtil.isMap(type)) {
|
||||
if (typeUtil.isMap(type)) {
|
||||
int keyStart = offset+1;
|
||||
Type domainType = TypeUtil.getDomainType(type);
|
||||
int keyEnd = -1;
|
||||
|
||||
@@ -116,7 +116,7 @@ public abstract class ApplicationYamlAssistContext extends AbstractYamlAssistCon
|
||||
protected String appendTextFor(Type type) {
|
||||
//Note that proper indentation after each \n" is added automatically
|
||||
//so the strings created here do not need to contain indentation spaces
|
||||
if (TypeUtil.isMap(type)) {
|
||||
if (typeUtil.isMap(type)) {
|
||||
//ready to enter nested map key on next line
|
||||
return "\n"+YamlIndentUtil.INDENT_STR;
|
||||
} if (TypeUtil.isSequencable(type)) {
|
||||
@@ -328,7 +328,7 @@ public abstract class ApplicationYamlAssistContext extends AbstractYamlAssistCon
|
||||
@Override
|
||||
public YamlAssistContext traverse(YamlPathSegment s) {
|
||||
if (s.getType()==YamlPathSegmentType.VAL_AT_KEY) {
|
||||
if (TypeUtil.isSequencable(type) || TypeUtil.isMap(type)) {
|
||||
if (TypeUtil.isSequencable(type) || typeUtil.isMap(type)) {
|
||||
return contextWith(s, TypeUtil.getDomainType(type));
|
||||
}
|
||||
String key = s.toPropString();
|
||||
@@ -632,7 +632,7 @@ public abstract class ApplicationYamlAssistContext extends AbstractYamlAssistCon
|
||||
private static List<IJavaElement> getAllJavaElements(TypeUtil typeUtil, Type parentType, String propName) {
|
||||
if (propName!=null) {
|
||||
Type beanType = parentType;
|
||||
if (TypeUtil.isMap(beanType)) {
|
||||
if (typeUtil.isMap(beanType)) {
|
||||
Type keyType = typeUtil.getKeyType(beanType);
|
||||
if (keyType!=null && typeUtil.isEnum(keyType)) {
|
||||
IField field = typeUtil.getEnumConstant(keyType, propName);
|
||||
|
||||
@@ -224,7 +224,7 @@ public class ApplicationYamlASTReconciler implements YamlASTReconciler {
|
||||
checkForDuplicateKeys(mapping);
|
||||
if (typeUtil.isAtomic(type)) {
|
||||
expectTypeFoundMapping(type, mapping);
|
||||
} else if (TypeUtil.isMap(type) || TypeUtil.isSequencable(type)) {
|
||||
} else if (typeUtil.isMap(type) || TypeUtil.isSequencable(type)) {
|
||||
Type keyType = typeUtil.getKeyType(type);
|
||||
Type valueType = TypeUtil.getDomainType(type);
|
||||
if (keyType!=null) {
|
||||
|
||||
Reference in New Issue
Block a user