/** * Parse type variables for generics * * @param variables * @return */ protected static TypeVar[] ParseTypeVariables(TypeVariable[] variables, ParamTag[] tags) { TypeVar[] vars = null; if (variables != null && variables.length > 0) { ArrayList<TypeVar> varsList = new ArrayList<TypeVar>(); for (TypeVariable variable : variables) { TypeVar var = new TypeVar(); var.name = variable.typeName(); Type[] bounds = variable.bounds(); if (bounds != null && bounds.length > 0) { ArrayList<String> list = new ArrayList<String>(); for (Type bound : bounds) { list.add(bound.qualifiedTypeName()); } var.bounds = list.toArray(new String[] {}); } for (ParamTag tag : tags) if (tag.parameterName().equals(var.name)) var.comment = tag.parameterComment(); varsList.add(var); } vars = varsList.toArray(new TypeVar[] {}); } return vars; }
/** * Prints dependencies recovered from the methods of a class. A dependency is inferred only if * another relation between the two classes is not already in the graph. * * @param classes */ public void printInferredDependencies(ClassDoc c) { Options opt = optionProvider.getOptionsFor(c); String sourceName = c.toString(); if (hidden(c)) return; Set<Type> types = new HashSet<Type>(); // harvest method return and parameter types for (MethodDoc method : filterByVisibility(c.methods(false), opt.inferDependencyVisibility)) { types.add(method.returnType()); for (Parameter parameter : method.parameters()) { types.add(parameter.type()); } } // and the field types if (!opt.inferRelationships) { for (FieldDoc field : filterByVisibility(c.fields(false), opt.inferDependencyVisibility)) { types.add(field.type()); } } // see if there are some type parameters if (c.asParameterizedType() != null) { ParameterizedType pt = c.asParameterizedType(); types.addAll(Arrays.asList(pt.typeArguments())); } // see if type parameters extend something for (TypeVariable tv : c.typeParameters()) { if (tv.bounds().length > 0) types.addAll(Arrays.asList(tv.bounds())); } // and finally check for explicitly imported classes (this // assumes there are no unused imports...) if (opt.useImports) types.addAll(Arrays.asList(c.importedClasses())); // compute dependencies for (Type type : types) { // skip primitives and type variables, as well as dependencies // on the source class if (type.isPrimitive() || type instanceof WildcardType || type instanceof TypeVariable || c.toString().equals(type.asClassDoc().toString())) continue; // check if the destination is excluded from inference ClassDoc fc = type.asClassDoc(); if (hidden(fc)) continue; // check if source and destination are in the same package and if we are allowed // to infer dependencies between classes in the same package if (!opt.inferDepInPackage && c.containingPackage().equals(fc.containingPackage())) continue; // if source and dest are not already linked, add a dependency RelationPattern rp = getClassInfo(sourceName).getRelation(fc.toString()); if (rp == null || rp.matchesOne(new RelationPattern(RelationDirection.OUT))) { relation(opt, RelationType.DEPEND, c, fc, "", "", ""); } } }