/* Copyright (C) 2009 Versant Inc. http://www.db4o.com */ package sharpen.core; import org.eclipse.jdt.core.dom.*; import static sharpen.core.framework.Environments.*; public class CRefBuilder { private ASTNode _crefTarget; public CRefBuilder(ASTNode ref) { _crefTarget = ref; } public String build() { switch (_crefTarget.getNodeType()) { case ASTNode.SIMPLE_NAME: case ASTNode.QUALIFIED_NAME: return mapCRefTarget(_crefTarget, ((Name) _crefTarget).resolveBinding()); case ASTNode.MEMBER_REF: return mapCRefTarget(_crefTarget, ((MemberRef) _crefTarget).resolveBinding()); case ASTNode.METHOD_REF: return mapCRefTarget(_crefTarget, ((MethodRef) _crefTarget).resolveBinding()); } return null; } private String mapCRefTarget(ASTNode node, IBinding binding) { if (null == binding) { my(Configuration.class).getWarningHandler().warning(node, "Unresolved cref target"); return node.toString(); } return documentationNameFor(binding); } private String documentationNameFor(IBinding binding) { switch (binding.getKind()) { case IBinding.METHOD: return methodSignatureForDocumentation((IMethodBinding) binding); case IBinding.TYPE: return mappedTypeName((ITypeBinding) binding); case IBinding.VARIABLE: return mappedQualifiedFieldName((IVariableBinding) binding); case IBinding.PACKAGE: return mappedNamespace(((IPackageBinding) binding).getName()); } throw new IllegalArgumentException("Binding type not supported: " + binding); } private String methodSignatureForDocumentation(final IMethodBinding method) { StringBuilder methodFQN = new StringBuilder(); if (belongsToCurrentType(method)) { methodFQN.append(mappedMethodName(method)); } else { methodFQN.append(mappedQualifiedMethodName(method)); } final String parameterList = parameterListSeparatedBy(method, ", "); methodFQN.append(genericTypeParametersFor(method)); methodFQN.append("("); methodFQN.append(parameterList); methodFQN.append(")"); return methodFQN.toString(); } private boolean belongsToCurrentType(IMethodBinding method) { return _currentType == method.getDeclaringClass(); } private String mappedQualifiedMethodName(IMethodBinding binding) { String methodName = mappedMethodName(binding); if (methodName.indexOf('.') > -1) { return methodName; } return mappedTypeName(binding.getDeclaringClass()) + "." + methodName; } private String genericTypeParametersFor(IMethodBinding method) { final IMethodBinding bind = method.getMethodDeclaration(); return genericQualifierFor(bind.getTypeParameters()); } private String genericQualifierFor(final ITypeBinding[] typeParameters) { if (typeParameters.length == 0) return ""; return "{" + typesSeparatedBy(typeParameters, ", ") + "}"; } private String parameterListSeparatedBy(final IMethodBinding binding, final String separator) { return typesSeparatedBy(binding.getParameterTypes(), separator); } private String typesSeparatedBy(final ITypeBinding[] types, final String separator) { StringBuilder result = new StringBuilder(); for (ITypeBinding parameter : types) { if (result.length() > 0) { result.append(separator); } result.append(mappedTypeName(parameter)); } return result.toString(); } private String mappedMethodName(IMethodBinding binding) { return my(Mappings.class).mappedMethodName(binding); } private String mappedQualifiedFieldName(IVariableBinding binding) { String name = my(Mappings.class).mappedFieldName(binding); if (null != name) return name; final String fieldName = identifier(binding.getName()); if (_currentType == binding.getDeclaringClass()) return fieldName; return mappedTypeName(binding.getDeclaringClass()) + "." + fieldName; } private String mappedTypeName(ITypeBinding type) { if (type.isArray()){ int dimensions = type.getDimensions(); StringBuilder sb = new StringBuilder(); for(int i =0; i < dimensions; i++){ sb.append("[]"); } return mappedTypeName(type.getElementType()) + sb; } final String mappedTypeName = my(Mappings.class).mappedTypeName(type); final String effectiveTypeName = _currentType.getPackage() == type.getPackage() ? simpleName(mappedTypeName) : mappedTypeName; return effectiveTypeName + genericQualifierFor(type.getTypeDeclaration().getTypeParameters()); } private String simpleName(String typeName) { final int lastDot = typeName.lastIndexOf('.'); return lastDot > 0 ? typeName.substring(lastDot + 1) : typeName; } private String identifier(String name) { return my(Configuration.class).getNamingStrategy().identifier(name); } private String mappedNamespace(String namespace) { return my(Configuration.class).mappedNamespace(namespace); } private final ITypeBinding _currentType = my(NameScope.class).currentType().resolveBinding(); }