### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.ui Index: ui/org/eclipse/jdt/internal/ui/infoviews/JavadocView.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/infoviews/JavadocView.java,v retrieving revision 1.87 diff -u -r1.87 JavadocView.java --- ui/org/eclipse/jdt/internal/ui/infoviews/JavadocView.java 11 Sep 2008 11:59:57 -0000 1.87 +++ ui/org/eclipse/jdt/internal/ui/infoviews/JavadocView.java 8 Oct 2008 12:32:37 -0000 @@ -75,6 +75,7 @@ import org.eclipse.jface.text.IDocumentExtension3; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.text.ITypedRegion; +import org.eclipse.jface.text.Region; import org.eclipse.jface.text.TextPresentation; import org.eclipse.jface.text.TextSelection; import org.eclipse.jface.text.TextUtilities; @@ -103,6 +104,7 @@ import org.eclipse.jdt.core.IMember; import org.eclipse.jdt.core.IOpenable; import org.eclipse.jdt.core.IPackageFragmentRoot; +import org.eclipse.jdt.core.ISourceRange; import org.eclipse.jdt.core.ITypeRoot; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; @@ -822,6 +824,7 @@ * @see AbstractInfoView#computeInput(Object) */ protected Object computeInput(Object input) { + //TODO: never used? if (getControl() == null || ! (input instanceof IJavaElement)) return null; @@ -985,6 +988,16 @@ if (member instanceof IField) constantValue= computeFieldConstant(activePart, selection, (IField) member, monitor); + ISourceRange nameRange; + try { + nameRange= ((IMember)curr).getNameRange(); + if (nameRange != null) { + //TODO + JavadocHover.addAnnotations(buffer, curr, ((IMember)curr).getTypeRoot(), new Region(nameRange.getOffset(), nameRange.getLength())); + } + } catch (JavaModelException e) { + // TODO Auto-generated catch block + } HTMLPrinter.addSmallHeader(buffer, getInfoText(member, constantValue, true)); Reader reader; try { @@ -1020,6 +1033,7 @@ HTMLPrinter.addParagraph(buffer, reader); } } else if (curr.getElementType() == IJavaElement.LOCAL_VARIABLE || curr.getElementType() == IJavaElement.TYPE_PARAMETER) { +//TODO JavadocHover.addAnnotations(buffer, curr); HTMLPrinter.addSmallHeader(buffer, getInfoText(curr, null, true)); } } @@ -1061,7 +1075,7 @@ } StringBuffer buf= new StringBuffer(); - JavadocHover.addImageAndLabel(buf, imageName, 16, 16, 8, 5, label.toString(), 22, 0); + JavadocHover.addImageAndLabel(buf, imageName, 16, 16, label.toString(), 20, 2); return buf.toString(); } @@ -1212,6 +1226,8 @@ return null; VariableDeclarationFragment fieldDecl= ASTNodeSearchUtil.getFieldDeclarationFragmentNode(constantField, ast); + if (fieldDecl == null) + return null; Expression initializer= fieldDecl.getInitializer(); if (initializer == null) return null; Index: ui/org/eclipse/jdt/internal/ui/viewsupport/JavaElementLinks.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/viewsupport/JavaElementLinks.java,v retrieving revision 1.9 diff -u -r1.9 JavaElementLinks.java --- ui/org/eclipse/jdt/internal/ui/viewsupport/JavaElementLinks.java 11 Sep 2008 11:59:40 -0000 1.9 +++ ui/org/eclipse/jdt/internal/ui/viewsupport/JavaElementLinks.java 8 Oct 2008 12:32:37 -0000 @@ -24,6 +24,7 @@ import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jdt.core.IAnnotation; import org.eclipse.jdt.core.IField; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.ILocalVariable; @@ -103,7 +104,7 @@ public String getElementName(IJavaElement element) { String elementName= element.getElementName(); - if (fElement.equals(element)) { // linking to the member itself would be a no-op + if (element.equals(fElement)) { // linking to the member itself would be a no-op return elementName; } if (elementName.length() == 0) { // anonymous @@ -111,17 +112,13 @@ } try { String uri= createURI(JAVADOC_SCHEME, element); - return createLink(uri, elementName); + return createHeaderLink(uri, elementName); } catch (URISyntaxException e) { JavaPlugin.log(e); return elementName; } } - private String createLink(String uri, String elementName) { - return "" + elementName + ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - protected String getGT() { return ">"; //$NON-NLS-1$ } @@ -134,7 +131,7 @@ String typeName= super.getSimpleTypeName(enclosingElement, typeSig); try { String uri= createURI(JAVADOC_SCHEME, enclosingElement, typeName, null, null); - return createLink(uri, typeName); + return createHeaderLink(uri, typeName); } catch (URISyntaxException e) { JavaPlugin.log(e); return typeName; @@ -319,7 +316,10 @@ JavaPlugin.log(e); } } - + if (element instanceof IAnnotation) { + element= element.getParent(); + } + if (element instanceof ILocalVariable) { element= element.getAncestor(IJavaElement.TYPE); } else if (element instanceof ITypeParameter) { @@ -459,8 +459,33 @@ } /** + * Creates a link with the given URI and label text. + * + * @param uri the URI + * @param label the label + * @return the HTML link + * @since 3.5 + */ + public static String createLink(String uri, String label) { + return "" + label + ""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + /** + * Creates a header link with the given URI and label text. + * + * @param uri the URI + * @param label the label + * @return the HTML link + * @since 3.5 + */ + public static String createHeaderLink(String uri, String label) { + return "" + label + ""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + /** * Returns the label for a Java element with the flags as defined by {@link JavaElementLabels}. - * Referenced element names in the label (except the given element's name) are rendered as Javadoc links. + * Referenced element names in the label (except the given element's name) are rendered as + * header links. * * @param element the element to render * @param flags the rendering flags @@ -468,9 +493,24 @@ * @since 3.5 */ public static String getElementLabel(IJavaElement element, long flags) { + return getElementLabel(element, flags, false); + } + + /** + * Returns the label for a Java element with the flags as defined by {@link JavaElementLabels}. + * Referenced element names in the label are rendered as header links. + * If linkAllNames is false, don't link the name of the given element + * + * @param element the element to render + * @param flags the rendering flags + * @param linkAllNames if true, link all names; if false, link all names except original element's name + * @return the label of the Java element + * @since 3.5 + */ + public static String getElementLabel(IJavaElement element, long flags, boolean linkAllNames) { StringBuffer buf= new StringBuffer(); - new JavaElementLinkedLabelComposer(element, buf).appendElementLabel(element, flags); + new JavaElementLinkedLabelComposer(linkAllNames ? null : element, buf).appendElementLabel(element, flags); return Strings.markLTR(buf.toString(), JavaElementLabelComposer.ADDITIONAL_DELIMITERS); // new JavaElementLabelComposer(buf).appendElementLabel(element, flags); @@ -478,3 +518,4 @@ // return Strings.markLTR(string, JavaElementLabelComposer.ADDITIONAL_DELIMITERS); } } + Index: ui/org/eclipse/jdt/internal/ui/text/java/hover/JavadocHover.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/java/hover/JavadocHover.java,v retrieving revision 1.75 diff -u -r1.75 JavadocHover.java --- ui/org/eclipse/jdt/internal/ui/text/java/hover/JavadocHover.java 11 Sep 2008 11:59:40 -0000 1.75 +++ ui/org/eclipse/jdt/internal/ui/text/java/hover/JavadocHover.java 8 Oct 2008 12:32:37 -0000 @@ -16,6 +16,7 @@ import java.io.InputStreamReader; import java.io.Reader; import java.io.StringReader; +import java.net.URISyntaxException; import java.net.URL; import org.osgi.framework.Bundle; @@ -25,6 +26,7 @@ import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; +import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.action.Action; @@ -51,6 +53,7 @@ import org.eclipse.ui.editors.text.EditorsUI; +import org.eclipse.jdt.core.IAnnotatable; import org.eclipse.jdt.core.IField; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; @@ -60,11 +63,18 @@ import org.eclipse.jdt.core.ITypeRoot; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.dom.AST; import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.ASTParser; +import org.eclipse.jdt.core.dom.CharacterLiteral; import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.IAnnotationBinding; import org.eclipse.jdt.core.dom.IBinding; +import org.eclipse.jdt.core.dom.IMemberValuePairBinding; +import org.eclipse.jdt.core.dom.ITypeBinding; import org.eclipse.jdt.core.dom.IVariableBinding; import org.eclipse.jdt.core.dom.SimpleName; +import org.eclipse.jdt.core.dom.StringLiteral; import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants; import org.eclipse.jdt.internal.corext.dom.NodeFinder; @@ -439,7 +449,7 @@ * @see org.eclipse.jdt.internal.ui.viewsupport.JavaElementLinks.ILinkHandler#handleInlineJavadocLink(org.eclipse.jdt.core.IJavaElement) */ public void handleInlineJavadocLink(IJavaElement linkTarget) { - JavadocBrowserInformationControlInput hoverInfo= getHoverInfo(new IJavaElement[] { linkTarget }, null, (JavadocBrowserInformationControlInput) control.getInput()); + JavadocBrowserInformationControlInput hoverInfo= getHoverInfo(new IJavaElement[] { linkTarget }, null, null, (JavadocBrowserInformationControlInput) control.getInput()); if (control.hasDelayedInputChangeListener()) control.notifyDelayedInputChange(hoverInfo); else @@ -500,26 +510,19 @@ if (elements == null || elements.length == 0) return null; - String constantValue; - if (elements.length == 1 && elements[0].getElementType() == IJavaElement.FIELD) { - constantValue= getConstantValue((IField) elements[0], hoverRegion); - } else { - constantValue= null; - } - - return getHoverInfo(elements, constantValue, null); + return getHoverInfo(elements, getEditorInputJavaElement(), hoverRegion, null); } /** * Computes the hover info. * * @param elements the resolved elements - * @param constantValue a constant value iff result contains exactly 1 constant field, or null + * @param hoverRegion a constant value iff result contains exactly 1 constant field, or null * @param previousInput the previous input, or null * @return the HTML hover info for the given element(s) or null if no information is available * @since 3.4 */ - private static JavadocBrowserInformationControlInput getHoverInfo(IJavaElement[] elements, String constantValue, JavadocBrowserInformationControlInput previousInput) { + private static JavadocBrowserInformationControlInput getHoverInfo(IJavaElement[] elements, ITypeRoot editorInputElement, IRegion hoverRegion, JavadocBrowserInformationControlInput previousInput) { int nResults= elements.length; StringBuffer buffer= new StringBuffer(); boolean hasContents= false; @@ -534,8 +537,16 @@ HTMLPrinter.startBulletList(buffer); IJavaElement curr= elements[i]; if (curr instanceof IMember || curr.getElementType() == IJavaElement.LOCAL_VARIABLE) { - //FIXME: provide links - HTMLPrinter.addBullet(buffer, getInfoText(curr, constantValue, false)); + String label= JavaElementLabels.getElementLabel(curr, getHeaderFlags(curr)); + String link; + try { + String uri= JavaElementLinks.createURI(JavaElementLinks.JAVADOC_SCHEME, curr); + link= JavaElementLinks.createLink(uri, label); + } catch (URISyntaxException e) { + JavaPlugin.log(e); + link= label; + } + HTMLPrinter.addBullet(buffer, link); hasContents= true; } HTMLPrinter.endBulletList(buffer); @@ -545,8 +556,13 @@ element= elements[0]; if (element instanceof IMember) { +// addAnnotations(buffer, element, editorInputElement, hoverRegion); + HTMLPrinter.addSmallHeader(buffer, getInfoText(element, editorInputElement, hoverRegion, true)); +// buffer.append("
"); + buffer.append("
"); + addAnnotations(buffer, element, editorInputElement, hoverRegion); +// buffer.append("
"); IMember member= (IMember) element; - HTMLPrinter.addSmallHeader(buffer, getInfoText(member, constantValue, true)); Reader reader; try { // reader= JavadocContentAccess.getHTMLContentReader(member, true, true); @@ -585,7 +601,8 @@ hasContents= true; } else if (element.getElementType() == IJavaElement.LOCAL_VARIABLE || element.getElementType() == IJavaElement.TYPE_PARAMETER) { - HTMLPrinter.addSmallHeader(buffer, getInfoText(element, constantValue, true)); + addAnnotations(buffer, element, editorInputElement, hoverRegion); + HTMLPrinter.addSmallHeader(buffer, getInfoText(element, editorInputElement, hoverRegion, true)); hasContents= true; } leadingImageWidth= 20; @@ -607,21 +624,12 @@ return null; } - private static String getInfoText(IJavaElement element, String constantValue, boolean allowImage) { - long flags; - switch (element.getElementType()) { - case IJavaElement.LOCAL_VARIABLE: - flags= LOCAL_VARIABLE_FLAGS; - break; - case IJavaElement.TYPE_PARAMETER: - flags= TYPE_PARAMETER_FLAGS; - break; - default: - flags= LABEL_FLAGS; - break; - } + private static String getInfoText(IJavaElement element, ITypeRoot editorInputElement, IRegion hoverRegion, boolean allowImage) { + long flags= getHeaderFlags(element); StringBuffer label= new StringBuffer(JavaElementLinks.getElementLabel(element, flags)); + if (element.getElementType() == IJavaElement.FIELD) { + String constantValue= getConstantValue((IField) element, editorInputElement, hoverRegion); if (constantValue != null) { IJavaProject javaProject= element.getJavaProject(); if (JavaCore.INSERT.equals(javaProject.getOption(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_ASSIGNMENT_OPERATOR, true))) @@ -632,6 +640,11 @@ label.append(constantValue); } } + +// if (element.getElementType() == IJavaElement.METHOD) { +// IMethod method= (IMethod)element; +// //TODO: add default value for annotation type members, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=249016 +// } String imageName= null; if (allowImage) { @@ -642,10 +655,21 @@ } StringBuffer buf= new StringBuffer(); - addImageAndLabel(buf, imageName, 16, 16, 2, 2, label.toString(), 20, 2); + addImageAndLabel(buf, imageName, 16, 16, label.toString(), 20, 2); return buf.toString(); } + private static long getHeaderFlags(IJavaElement element) { + switch (element.getElementType()) { + case IJavaElement.LOCAL_VARIABLE: + return LOCAL_VARIABLE_FLAGS; + case IJavaElement.TYPE_PARAMETER: + return TYPE_PARAMETER_FLAGS; + default: + return LABEL_FLAGS; + } + } + /* * @since 3.4 */ @@ -662,26 +686,21 @@ * Returns the constant value for the given field. * * @param field the field - * @param hoverRegion the hover region + * @param editorInputElement the editor input element + * @param hoverRegion the hover region in the editor * @return the constant value for the given field or null if none * @since 3.4 */ - private String getConstantValue(IField field, IRegion hoverRegion) { + private static String getConstantValue(IField field, ITypeRoot editorInputElement, IRegion hoverRegion) { if (!isStaticFinal(field)) return null; - ITypeRoot typeRoot= getEditorInputJavaElement(); - if (typeRoot == null) + ASTNode node= getHoveredASTNode(editorInputElement, hoverRegion); + if (node == null) return null; - + Object constantValue= null; - - CompilationUnit unit= SharedASTProvider.getAST(typeRoot, SharedASTProvider.WAIT_ACTIVE_ONLY, null); - if (unit == null) - return null; - - ASTNode node= NodeFinder.perform(unit, hoverRegion.getOffset(), hoverRegion.getLength()); - if (node != null && node.getNodeType() == ASTNode.SIMPLE_NAME) { + if (node.getNodeType() == ASTNode.SIMPLE_NAME) { IBinding binding= ((SimpleName)node).resolveBinding(); if (binding != null && binding.getKind() == IBinding.VARIABLE) { IVariableBinding variableBinding= (IVariableBinding)binding; @@ -694,20 +713,10 @@ return null; if (constantValue instanceof String) { - StringBuffer result= new StringBuffer(); - result.append('"'); - String stringConstant= (String)constantValue; - if (stringConstant.length() > 80) { - result.append(stringConstant.substring(0, 80)); - result.append(JavaElementLabels.ELLIPSIS_STRING); - } else { - result.append(stringConstant); - } - result.append('"'); - return result.toString(); + return getEscapedStringLiteral((String) constantValue); } else if (constantValue instanceof Character) { - String constantResult= '\'' + constantValue.toString() + '\''; + String constantResult= getEscapedCharacterLiteral(((Character) constantValue).charValue()); char charValue= ((Character) constantValue).charValue(); String hexString= Integer.toHexString(charValue); @@ -739,6 +748,34 @@ } } + private static ASTNode getHoveredASTNode(ITypeRoot editorInputElement, IRegion hoverRegion) { + if (editorInputElement == null) + return null; + + CompilationUnit unit= SharedASTProvider.getAST(editorInputElement, SharedASTProvider.WAIT_ACTIVE_ONLY, null); + if (unit == null) + return null; + + return NodeFinder.perform(unit, hoverRegion.getOffset(), hoverRegion.getLength()); + } + + private static String getEscapedStringLiteral(String stringValue) { + StringLiteral stringLiteral= AST.newAST(AST.JLS3).newStringLiteral(); + stringLiteral.setLiteralValue(stringValue); + String stringConstant= stringLiteral.getEscapedValue(); + if (stringConstant.length() > 80) { + return stringConstant.substring(0, 80) + JavaElementLabels.ELLIPSIS_STRING; + } else { + return stringConstant; + } + } + + private static String getEscapedCharacterLiteral(char ch) { + CharacterLiteral characterLiteral= AST.newAST(AST.JLS3).newCharacterLiteral(); + characterLiteral.setCharValue(ch); + return characterLiteral.getEscapedValue(); + } + /** * Creates and returns a formatted message for the given * constant with its hex value. @@ -803,35 +840,212 @@ return null; } - public static void addImageAndLabel(StringBuffer buf, String imageName, int imageWidth, int imageHeight, int imageLeft, int imageTop, String label, int labelLeft, int labelTop) { + public static void addImageAndLabel(StringBuffer buf, String imageSrcPath, int imageWidth, int imageHeight, String label, int labelLeft, int labelTop) { + buf.append("
"); //$NON-NLS-1$ + if (imageSrcPath != null) { StringBuffer imageStyle= new StringBuffer("position: absolute; "); //$NON-NLS-1$ imageStyle.append("width: ").append(imageWidth).append("px; "); //$NON-NLS-1$ //$NON-NLS-2$ imageStyle.append("height: ").append(imageHeight).append("px; "); //$NON-NLS-1$ //$NON-NLS-2$ - imageStyle.append("top: ").append(imageTop).append("px; "); //$NON-NLS-1$ //$NON-NLS-2$ - imageStyle.append("left: ").append(imageLeft).append("px; "); //$NON-NLS-1$ //$NON-NLS-2$ + imageStyle.append("left: ").append(- labelLeft - 1).append("px; "); //$NON-NLS-1$ //$NON-NLS-2$ + // hack for broken transparent PNG support in IE 6, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=223900 : buf.append("\n"); //$NON-NLS-1$ buf.append("\n"); //$NON-NLS-1$ - buf.append("\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + buf.append("\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ buf.append("\n"); //$NON-NLS-1$ buf.append("\n"); //$NON-NLS-1$ } - - buf.append("
"); //$NON-NLS-1$ + buf.append(label); + buf.append("
"); //$NON-NLS-1$ } + public static void addAnnotations(StringBuffer buf, IJavaElement element, ITypeRoot editorInputElement, IRegion hoverRegion) { + if (element instanceof IAnnotatable) { + try { + String annotationString= getAnnotations(element, editorInputElement, hoverRegion); + if (annotationString != null) { + buf.append("
"); //$NON-NLS-1$ + buf.append(annotationString); + buf.append("
"); //$NON-NLS-1$ + } +// } catch (JavaModelException e) { +// // no more annotations today... +// buf.append("
"); //$NON-NLS-1$ + } catch (URISyntaxException e) { + // no more annotations today... + buf.append("
"); //$NON-NLS-1$ + } + } + } + + private static String getAnnotations(IJavaElement element, ITypeRoot editorInputElement, IRegion hoverRegion) throws URISyntaxException { + if (!(element instanceof IAnnotatable)) + return null; + +// if (((IAnnotatable)element).getAnnotations().length == 0) //XXX core bug: always 0 for binary types, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=248309 +// return null; + //TODO: if (annotations don't include @Documented) return null; ? + + IBinding binding; + ASTNode node= getHoveredASTNode(editorInputElement, hoverRegion); + + if (node == null) { + ASTParser p= ASTParser.newParser(AST.JLS3); + p.setProject(element.getJavaProject()); + try { + binding= p.createBindings(new IJavaElement[] { element }, null)[0]; + } catch (OperationCanceledException e) { + return null; + } + + } else { + if (node.getNodeType() != ASTNode.SIMPLE_NAME) + return null; + + binding= ((SimpleName)node).resolveBinding(); + } + + if (binding == null) + return null; + + IAnnotationBinding[] annotations= binding.getAnnotations(); + if (annotations.length == 0) + return null; + +// Arrays.sort(annotations, new Comparator() { +// public int compare(Object o1, Object o2) { +// IAnnotationBinding b1= (IAnnotationBinding)o1; +// IAnnotationBinding b2= (IAnnotationBinding)o2; +// try { +// //XXX: getJavaElement() fails, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=249844 +// IAnnotation e1= (IAnnotation)b1.getJavaElement(); +// IAnnotation e2= (IAnnotation)b2.getJavaElement(); +// +// ISourceRange sr1= e1.getSourceRange(); +// ISourceRange sr2= e2.getSourceRange(); +// if (SourceRange.isAvailable(sr1) && SourceRange.isAvailable(sr2)) +// return sr1.getOffset() - sr2.getOffset(); +// } catch (JavaModelException e) { +// // don't sort if not available... +// } +// return 0; +// } +// }); + +// try { +// IAnnotation[] annotationElements= ((IAnnotatable)element).getAnnotations(); +// if (annotationElements.length != 0) { //XXX: mostly 0, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=248309 +// ArrayList orderedAnnotations= new ArrayList(); +// LinkedHashMap nameToBinding= new LinkedHashMap(); +// for (int i= 0; i < annotations.length; i++) { +// nameToBinding.put(Signature.getSimpleName(annotations[i].getName()), annotations[i]); +// } +// for (int i= 0; i < annotationElements.length; i++) { +// String elementName= Signature.getSimpleName(annotationElements[i].getElementName()); +// IAnnotationBinding annotationBinding= (IAnnotationBinding)nameToBinding.remove(elementName); +// if (annotationBinding != null) { +// orderedAnnotations.add(annotationBinding); +// } +// } +// orderedAnnotations.addAll(nameToBinding.values()); +// annotations= (IAnnotationBinding[]) orderedAnnotations.toArray(new IAnnotationBinding[orderedAnnotations.size()]); +// } +// } catch (JavaModelException e) { +// // don't sort if not available... +// } + + StringBuffer buf= new StringBuffer(); + for (int i= 0; i < annotations.length; i++) { + addAnnotation(buf, element, annotations[i]); + buf.append("
"); //$NON-NLS-1$ + } + + return buf.toString(); + } + + private static void addAnnotation(StringBuffer buf, IJavaElement element, IAnnotationBinding annotation) throws URISyntaxException { + String uri= JavaElementLinks.createURI(JavaElementLinks.JAVADOC_SCHEME, annotation.getAnnotationType().getJavaElement()); + buf.append('@'); + addLink(buf, uri, annotation.getName()); + + IMemberValuePairBinding[] mvPairs= annotation.getDeclaredMemberValuePairs(); //TODO: order not specified... + if (mvPairs.length > 0) { + buf.append('('); +// if (mvPairs.length == 1 && "value".equals(mvPairs[0].getName())) { //$NON-NLS-1$ +// IMemberValuePairBinding mvPair= mvPairs[0]; +// addValue(buf, element, mvPair.getValue()); +// } else { + for (int j= 0; j < mvPairs.length; j++) { + if (j > 0) { + buf.append(JavaElementLabels.COMMA_STRING); + } + IMemberValuePairBinding mvPair= mvPairs[j]; + String memberURI= JavaElementLinks.createURI(JavaElementLinks.JAVADOC_SCHEME, mvPair.getMethodBinding().getJavaElement()); + addLink(buf, memberURI, mvPair.getName()); + buf.append('='); + addValue(buf, element, mvPair.getValue()); + } +// } + buf.append(')'); + } + } + + private static void addValue(StringBuffer buf, IJavaElement element, Object value) throws URISyntaxException { + if (value instanceof ITypeBinding) { + ITypeBinding typeBinding= (ITypeBinding)value; + IJavaElement type= typeBinding.getJavaElement(); + String typeLabel= JavaElementLinks.getElementLabel(type, LABEL_FLAGS, true); + buf.append(typeLabel).append(".class"); //$NON-NLS-1$ + + } else if (value instanceof IVariableBinding) { // only enum constants + IVariableBinding variableBinding= (IVariableBinding)value; + IJavaElement variable= variableBinding.getJavaElement(); + String uri= JavaElementLinks.createURI(JavaElementLinks.JAVADOC_SCHEME, variable); + String name= variable.getElementName(); + addLink(buf, uri, name); + + } else if (value instanceof IAnnotationBinding) { + IAnnotationBinding annotationBinding= (IAnnotationBinding)value; + addAnnotation(buf, element, annotationBinding); + + } else if (value instanceof String) { + buf.append(getEscapedStringLiteral((String)value)); + + } else if (value instanceof Character) { + buf.append(getEscapedCharacterLiteral(((Character)value).charValue())); + + } else if (value instanceof Object[]) { + Object[] values= (Object[])value; + buf.append('{'); + for (int i= 0; i < values.length; i++) { + if (i > 0) { + buf.append(JavaElementLabels.COMMA_STRING); + } + addValue(buf, element, values[i]); + } + buf.append('}'); + + } else { // primitive types (except char) or null + buf.append(String.valueOf(value)); + } + } + + private static StringBuffer addLink(StringBuffer buf, String uri, String label) { +// return buf.append(JavaElementLinks.createHeaderLink(uri, label)); + return buf.append(JavaElementLinks.createLink(uri, label)); + } }