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