public void recursiveTemplateSubstitution(SymbolType st, Map<String, SymbolType> typeParamsMap) { List<SymbolType> bounds = st.getBounds(); if (bounds != null) { for (SymbolType bound : bounds) { recursiveTemplateSubstitution(bound, typeParamsMap); } } else { List<SymbolType> params = st.getParameterizedTypes(); if (params != null) { List<SymbolType> paramsFinal = new LinkedList<SymbolType>(); for (SymbolType param : params) { String tv = param.getTemplateVariable(); if (tv != null) { SymbolType genericTypeDef = typeParamsMap.get(tv); if (genericTypeDef != null) { paramsFinal.add(genericTypeDef); } else { recursiveTemplateSubstitution(param, typeParamsMap); paramsFinal.add(param); } } else { recursiveTemplateSubstitution(param, typeParamsMap); paramsFinal.add(param); } } st.setParameterizedTypes(paramsFinal); } } }
private void processSuperGenerics( SymbolTable table, Symbol<?> symbol, ClassOrInterfaceType type) { if (type != null) { Map<String, SymbolType> typeResolution = new HashMap<String, SymbolType>(); ASTSymbolTypeResolver res = new ASTSymbolTypeResolver(typeResolution, table); SymbolType superType = type.accept(res, null); List<SymbolType> params = superType.getParameterizedTypes(); Map<String, SymbolType> typeMapping = table.getTypeParams(); if (params != null) { Symbol<?> superSymbol = symbol.getInnerScope().findSymbol("super"); Scope innerScope = superSymbol.getInnerScope(); Scope aux = null; if (innerScope != null) { aux = new Scope(superSymbol); } else { aux = new Scope(); } superSymbol.setInnerScope(aux); table.pushScope(aux); Symbol<?> intermediateSuper = new Symbol("super", superSymbol.getType(), superSymbol.getLocation()); if (innerScope != null) { intermediateSuper.setInnerScope(innerScope); } table.pushSymbol(intermediateSuper); // extends a parameterizable type TypeVariable<?>[] tps = superType.getClazz().getTypeParameters(); for (int i = 0; i < tps.length; i++) { table.pushSymbol(tps[i].getName(), ReferenceType.TYPE_PARAM, params.get(i), null); } table.popScope(true); } Set<String> genericLetters = typeMapping.keySet(); if (genericLetters != null) { for (String letter : genericLetters) { if (typeResolution.containsKey(letter)) { table.pushSymbol(letter, ReferenceType.TYPE, typeMapping.get(letter), null); } } } } }
@Override public boolean filter(Method method) throws Exception { if (resultTypeFilters != null) { b2.setMethod(method); b2.setArgumentValues(argumentValues); typeMapping = b2.build(new HashMap<String, SymbolType>(typeMapping)); SymbolType result = SymbolType.valueOf(method, typeMapping); List<Class<?>> classes = result.getBoundClasses(); resultTypeFilters.setElements(classes); return resultTypeFilters.filterOne() != null; } return false; }
public void load(SymbolTable table, List<TypeParameter> typeParams, SymbolType thisType) { if (typeParams != null && !typeParams.isEmpty()) { List<SymbolType> parameterizedTypes = new LinkedList<SymbolType>(); for (TypeParameter tp : typeParams) { List<ClassOrInterfaceType> typeBounds = tp.getTypeBound(); List<SymbolType> bounds = new LinkedList<SymbolType>(); SymbolType st = null; if (typeBounds != null) { for (ClassOrInterfaceType type : typeBounds) { SymbolType paramType = ASTSymbolTypeResolver.getInstance().valueOf(type); if (paramType == null) { paramType = new SymbolType(Object.class); } bounds.add(paramType); } st = new SymbolType(bounds); } else { st = new SymbolType(Object.class); } st.setTemplateVariable(tp.getName()); table.pushSymbol(tp.getName(), ReferenceType.TYPE_PARAM, st, tp); parameterizedTypes.add(st); } Map<String, SymbolType> typeParamsMap = table.getTypeParams(); for (String key : typeParamsMap.keySet()) { SymbolType st = typeParamsMap.get(key); recursiveTemplateSubstitution(st, typeParamsMap); } if (thisType != null && !parameterizedTypes.isEmpty()) { thisType.setParameterizedTypes(parameterizedTypes); } } }
@Override public Map<String, SymbolType> build(Map<String, SymbolType> obj) { if (obj == null) { obj = new HashMap<String, SymbolType>(); } TypeVariable<?>[] typeParams = clazz.getTypeParameters(); if (typeParams != null) { for (int i = 0; i < typeParams.length; i++) { if (parameterizedTypes != null) { if (i >= parameterizedTypes.size()) { SymbolType st = new SymbolType("java.lang.Object"); st.setTemplateVariable(typeParams[i].getName()); obj.put(typeParams[i].getName(), st); } else { if (parameterizedTypes.get(i).getName() == null && parameterizedTypes.get(i).hasBounds()) { obj.put(typeParams[i].getName(), parameterizedTypes.get(i)); } else { if (!"java.lang.Object".equals(parameterizedTypes.get(i).getName())) { obj.put(typeParams[i].getName(), parameterizedTypes.get(i)); } else { SymbolType st = new SymbolType("java.lang.Object"); st.setTemplateVariable(typeParams[i].getName()); obj.put(typeParams[i].getName(), st); } } } } else { Type[] bounds = typeParams[i].getBounds(); SymbolType resultType = null; if (bounds.length == 0) { resultType = new SymbolType("java.lang.Object"); } else { try { SymbolType auxSt = null; for (int j = 0; j < bounds.length; j++) { auxSt = SymbolType.valueOf(bounds[j], obj); if (resultType == null) { resultType = auxSt; } else { resultType = (SymbolType) resultType.merge(auxSt); } } } catch (InvalidTypeException e) { throw new RuntimeException("Error processing bounds of type ", e); } } if (resultType != null) { obj.put(typeParams[i].getName(), resultType); } } } } return obj; }