No classloading in TypeUtil.isMap method

See: https://www.pivotaltracker.com/story/show/167917595
This commit is contained in:
Kris De Volder
2019-08-27 16:25:53 -07:00
parent a89e5a04db
commit 48e460d78f
5 changed files with 46 additions and 11 deletions

View File

@@ -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));

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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) {