Lines 16-21
Link Here
|
16 |
import java.io.InputStreamReader; |
16 |
import java.io.InputStreamReader; |
17 |
import java.io.Reader; |
17 |
import java.io.Reader; |
18 |
import java.io.StringReader; |
18 |
import java.io.StringReader; |
|
|
19 |
import java.net.URISyntaxException; |
19 |
import java.net.URL; |
20 |
import java.net.URL; |
20 |
|
21 |
|
21 |
import org.osgi.framework.Bundle; |
22 |
import org.osgi.framework.Bundle; |
Lines 25-30
Link Here
|
25 |
import org.eclipse.swt.widgets.Display; |
26 |
import org.eclipse.swt.widgets.Display; |
26 |
import org.eclipse.swt.widgets.Shell; |
27 |
import org.eclipse.swt.widgets.Shell; |
27 |
|
28 |
|
|
|
29 |
import org.eclipse.core.runtime.OperationCanceledException; |
28 |
import org.eclipse.core.runtime.Platform; |
30 |
import org.eclipse.core.runtime.Platform; |
29 |
|
31 |
|
30 |
import org.eclipse.jface.action.Action; |
32 |
import org.eclipse.jface.action.Action; |
Lines 51-56
Link Here
|
51 |
|
53 |
|
52 |
import org.eclipse.ui.editors.text.EditorsUI; |
54 |
import org.eclipse.ui.editors.text.EditorsUI; |
53 |
|
55 |
|
|
|
56 |
import org.eclipse.jdt.core.IAnnotatable; |
54 |
import org.eclipse.jdt.core.IField; |
57 |
import org.eclipse.jdt.core.IField; |
55 |
import org.eclipse.jdt.core.IJavaElement; |
58 |
import org.eclipse.jdt.core.IJavaElement; |
56 |
import org.eclipse.jdt.core.IJavaProject; |
59 |
import org.eclipse.jdt.core.IJavaProject; |
Lines 60-70
Link Here
|
60 |
import org.eclipse.jdt.core.ITypeRoot; |
63 |
import org.eclipse.jdt.core.ITypeRoot; |
61 |
import org.eclipse.jdt.core.JavaCore; |
64 |
import org.eclipse.jdt.core.JavaCore; |
62 |
import org.eclipse.jdt.core.JavaModelException; |
65 |
import org.eclipse.jdt.core.JavaModelException; |
|
|
66 |
import org.eclipse.jdt.core.dom.AST; |
63 |
import org.eclipse.jdt.core.dom.ASTNode; |
67 |
import org.eclipse.jdt.core.dom.ASTNode; |
|
|
68 |
import org.eclipse.jdt.core.dom.ASTParser; |
69 |
import org.eclipse.jdt.core.dom.CharacterLiteral; |
64 |
import org.eclipse.jdt.core.dom.CompilationUnit; |
70 |
import org.eclipse.jdt.core.dom.CompilationUnit; |
|
|
71 |
import org.eclipse.jdt.core.dom.IAnnotationBinding; |
65 |
import org.eclipse.jdt.core.dom.IBinding; |
72 |
import org.eclipse.jdt.core.dom.IBinding; |
|
|
73 |
import org.eclipse.jdt.core.dom.IMemberValuePairBinding; |
74 |
import org.eclipse.jdt.core.dom.ITypeBinding; |
66 |
import org.eclipse.jdt.core.dom.IVariableBinding; |
75 |
import org.eclipse.jdt.core.dom.IVariableBinding; |
67 |
import org.eclipse.jdt.core.dom.SimpleName; |
76 |
import org.eclipse.jdt.core.dom.SimpleName; |
|
|
77 |
import org.eclipse.jdt.core.dom.StringLiteral; |
68 |
import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants; |
78 |
import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants; |
69 |
|
79 |
|
70 |
import org.eclipse.jdt.internal.corext.dom.NodeFinder; |
80 |
import org.eclipse.jdt.internal.corext.dom.NodeFinder; |
Lines 439-445
Link Here
|
439 |
* @see org.eclipse.jdt.internal.ui.viewsupport.JavaElementLinks.ILinkHandler#handleInlineJavadocLink(org.eclipse.jdt.core.IJavaElement) |
449 |
* @see org.eclipse.jdt.internal.ui.viewsupport.JavaElementLinks.ILinkHandler#handleInlineJavadocLink(org.eclipse.jdt.core.IJavaElement) |
440 |
*/ |
450 |
*/ |
441 |
public void handleInlineJavadocLink(IJavaElement linkTarget) { |
451 |
public void handleInlineJavadocLink(IJavaElement linkTarget) { |
442 |
JavadocBrowserInformationControlInput hoverInfo= getHoverInfo(new IJavaElement[] { linkTarget }, null, (JavadocBrowserInformationControlInput) control.getInput()); |
452 |
JavadocBrowserInformationControlInput hoverInfo= getHoverInfo(new IJavaElement[] { linkTarget }, null, null, (JavadocBrowserInformationControlInput) control.getInput()); |
443 |
if (control.hasDelayedInputChangeListener()) |
453 |
if (control.hasDelayedInputChangeListener()) |
444 |
control.notifyDelayedInputChange(hoverInfo); |
454 |
control.notifyDelayedInputChange(hoverInfo); |
445 |
else |
455 |
else |
Lines 500-525
Link Here
|
500 |
if (elements == null || elements.length == 0) |
510 |
if (elements == null || elements.length == 0) |
501 |
return null; |
511 |
return null; |
502 |
|
512 |
|
503 |
String constantValue; |
513 |
return getHoverInfo(elements, getEditorInputJavaElement(), hoverRegion, null); |
504 |
if (elements.length == 1 && elements[0].getElementType() == IJavaElement.FIELD) { |
|
|
505 |
constantValue= getConstantValue((IField) elements[0], hoverRegion); |
506 |
} else { |
507 |
constantValue= null; |
508 |
} |
509 |
|
510 |
return getHoverInfo(elements, constantValue, null); |
511 |
} |
514 |
} |
512 |
|
515 |
|
513 |
/** |
516 |
/** |
514 |
* Computes the hover info. |
517 |
* Computes the hover info. |
515 |
* |
518 |
* |
516 |
* @param elements the resolved elements |
519 |
* @param elements the resolved elements |
517 |
* @param constantValue a constant value iff result contains exactly 1 constant field, or <code>null</code> |
520 |
* @param hoverRegion a constant value iff result contains exactly 1 constant field, or <code>null</code> |
518 |
* @param previousInput the previous input, or <code>null</code> |
521 |
* @param previousInput the previous input, or <code>null</code> |
519 |
* @return the HTML hover info for the given element(s) or <code>null</code> if no information is available |
522 |
* @return the HTML hover info for the given element(s) or <code>null</code> if no information is available |
520 |
* @since 3.4 |
523 |
* @since 3.4 |
521 |
*/ |
524 |
*/ |
522 |
private static JavadocBrowserInformationControlInput getHoverInfo(IJavaElement[] elements, String constantValue, JavadocBrowserInformationControlInput previousInput) { |
525 |
private static JavadocBrowserInformationControlInput getHoverInfo(IJavaElement[] elements, ITypeRoot editorInputElement, IRegion hoverRegion, JavadocBrowserInformationControlInput previousInput) { |
523 |
int nResults= elements.length; |
526 |
int nResults= elements.length; |
524 |
StringBuffer buffer= new StringBuffer(); |
527 |
StringBuffer buffer= new StringBuffer(); |
525 |
boolean hasContents= false; |
528 |
boolean hasContents= false; |
Lines 534-541
Link Here
|
534 |
HTMLPrinter.startBulletList(buffer); |
537 |
HTMLPrinter.startBulletList(buffer); |
535 |
IJavaElement curr= elements[i]; |
538 |
IJavaElement curr= elements[i]; |
536 |
if (curr instanceof IMember || curr.getElementType() == IJavaElement.LOCAL_VARIABLE) { |
539 |
if (curr instanceof IMember || curr.getElementType() == IJavaElement.LOCAL_VARIABLE) { |
537 |
//FIXME: provide links |
540 |
String label= JavaElementLabels.getElementLabel(curr, getHeaderFlags(curr)); |
538 |
HTMLPrinter.addBullet(buffer, getInfoText(curr, constantValue, false)); |
541 |
String link; |
|
|
542 |
try { |
543 |
String uri= JavaElementLinks.createURI(JavaElementLinks.JAVADOC_SCHEME, curr); |
544 |
link= JavaElementLinks.createLink(uri, label); |
545 |
} catch (URISyntaxException e) { |
546 |
JavaPlugin.log(e); |
547 |
link= label; |
548 |
} |
549 |
HTMLPrinter.addBullet(buffer, link); |
539 |
hasContents= true; |
550 |
hasContents= true; |
540 |
} |
551 |
} |
541 |
HTMLPrinter.endBulletList(buffer); |
552 |
HTMLPrinter.endBulletList(buffer); |
Lines 545-552
Link Here
|
545 |
|
556 |
|
546 |
element= elements[0]; |
557 |
element= elements[0]; |
547 |
if (element instanceof IMember) { |
558 |
if (element instanceof IMember) { |
|
|
559 |
// addAnnotations(buffer, element, editorInputElement, hoverRegion); |
560 |
HTMLPrinter.addSmallHeader(buffer, getInfoText(element, editorInputElement, hoverRegion, true)); |
561 |
// buffer.append("<br><b>"); |
562 |
buffer.append("<br>"); |
563 |
addAnnotations(buffer, element, editorInputElement, hoverRegion); |
564 |
// buffer.append("</b>"); |
548 |
IMember member= (IMember) element; |
565 |
IMember member= (IMember) element; |
549 |
HTMLPrinter.addSmallHeader(buffer, getInfoText(member, constantValue, true)); |
|
|
550 |
Reader reader; |
566 |
Reader reader; |
551 |
try { |
567 |
try { |
552 |
// reader= JavadocContentAccess.getHTMLContentReader(member, true, true); |
568 |
// reader= JavadocContentAccess.getHTMLContentReader(member, true, true); |
Lines 585-591
Link Here
|
585 |
hasContents= true; |
601 |
hasContents= true; |
586 |
|
602 |
|
587 |
} else if (element.getElementType() == IJavaElement.LOCAL_VARIABLE || element.getElementType() == IJavaElement.TYPE_PARAMETER) { |
603 |
} else if (element.getElementType() == IJavaElement.LOCAL_VARIABLE || element.getElementType() == IJavaElement.TYPE_PARAMETER) { |
588 |
HTMLPrinter.addSmallHeader(buffer, getInfoText(element, constantValue, true)); |
604 |
addAnnotations(buffer, element, editorInputElement, hoverRegion); |
|
|
605 |
HTMLPrinter.addSmallHeader(buffer, getInfoText(element, editorInputElement, hoverRegion, true)); |
589 |
hasContents= true; |
606 |
hasContents= true; |
590 |
} |
607 |
} |
591 |
leadingImageWidth= 20; |
608 |
leadingImageWidth= 20; |
Lines 607-627
Link Here
|
607 |
return null; |
624 |
return null; |
608 |
} |
625 |
} |
609 |
|
626 |
|
610 |
private static String getInfoText(IJavaElement element, String constantValue, boolean allowImage) { |
627 |
private static String getInfoText(IJavaElement element, ITypeRoot editorInputElement, IRegion hoverRegion, boolean allowImage) { |
611 |
long flags; |
628 |
long flags= getHeaderFlags(element); |
612 |
switch (element.getElementType()) { |
|
|
613 |
case IJavaElement.LOCAL_VARIABLE: |
614 |
flags= LOCAL_VARIABLE_FLAGS; |
615 |
break; |
616 |
case IJavaElement.TYPE_PARAMETER: |
617 |
flags= TYPE_PARAMETER_FLAGS; |
618 |
break; |
619 |
default: |
620 |
flags= LABEL_FLAGS; |
621 |
break; |
622 |
} |
623 |
StringBuffer label= new StringBuffer(JavaElementLinks.getElementLabel(element, flags)); |
629 |
StringBuffer label= new StringBuffer(JavaElementLinks.getElementLabel(element, flags)); |
|
|
630 |
|
624 |
if (element.getElementType() == IJavaElement.FIELD) { |
631 |
if (element.getElementType() == IJavaElement.FIELD) { |
|
|
632 |
String constantValue= getConstantValue((IField) element, editorInputElement, hoverRegion); |
625 |
if (constantValue != null) { |
633 |
if (constantValue != null) { |
626 |
IJavaProject javaProject= element.getJavaProject(); |
634 |
IJavaProject javaProject= element.getJavaProject(); |
627 |
if (JavaCore.INSERT.equals(javaProject.getOption(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_ASSIGNMENT_OPERATOR, true))) |
635 |
if (JavaCore.INSERT.equals(javaProject.getOption(DefaultCodeFormatterConstants.FORMATTER_INSERT_SPACE_BEFORE_ASSIGNMENT_OPERATOR, true))) |
Lines 632-637
Link Here
|
632 |
label.append(constantValue); |
640 |
label.append(constantValue); |
633 |
} |
641 |
} |
634 |
} |
642 |
} |
|
|
643 |
|
644 |
// if (element.getElementType() == IJavaElement.METHOD) { |
645 |
// IMethod method= (IMethod)element; |
646 |
// //TODO: add default value for annotation type members, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=249016 |
647 |
// } |
635 |
|
648 |
|
636 |
String imageName= null; |
649 |
String imageName= null; |
637 |
if (allowImage) { |
650 |
if (allowImage) { |
Lines 642-651
Link Here
|
642 |
} |
655 |
} |
643 |
|
656 |
|
644 |
StringBuffer buf= new StringBuffer(); |
657 |
StringBuffer buf= new StringBuffer(); |
645 |
addImageAndLabel(buf, imageName, 16, 16, 2, 2, label.toString(), 20, 2); |
658 |
addImageAndLabel(buf, imageName, 16, 16, label.toString(), 20, 2); |
646 |
return buf.toString(); |
659 |
return buf.toString(); |
647 |
} |
660 |
} |
648 |
|
661 |
|
|
|
662 |
private static long getHeaderFlags(IJavaElement element) { |
663 |
switch (element.getElementType()) { |
664 |
case IJavaElement.LOCAL_VARIABLE: |
665 |
return LOCAL_VARIABLE_FLAGS; |
666 |
case IJavaElement.TYPE_PARAMETER: |
667 |
return TYPE_PARAMETER_FLAGS; |
668 |
default: |
669 |
return LABEL_FLAGS; |
670 |
} |
671 |
} |
672 |
|
649 |
/* |
673 |
/* |
650 |
* @since 3.4 |
674 |
* @since 3.4 |
651 |
*/ |
675 |
*/ |
Lines 662-687
Link Here
|
662 |
* Returns the constant value for the given field. |
686 |
* Returns the constant value for the given field. |
663 |
* |
687 |
* |
664 |
* @param field the field |
688 |
* @param field the field |
665 |
* @param hoverRegion the hover region |
689 |
* @param editorInputElement the editor input element |
|
|
690 |
* @param hoverRegion the hover region in the editor |
666 |
* @return the constant value for the given field or <code>null</code> if none |
691 |
* @return the constant value for the given field or <code>null</code> if none |
667 |
* @since 3.4 |
692 |
* @since 3.4 |
668 |
*/ |
693 |
*/ |
669 |
private String getConstantValue(IField field, IRegion hoverRegion) { |
694 |
private static String getConstantValue(IField field, ITypeRoot editorInputElement, IRegion hoverRegion) { |
670 |
if (!isStaticFinal(field)) |
695 |
if (!isStaticFinal(field)) |
671 |
return null; |
696 |
return null; |
672 |
|
697 |
|
673 |
ITypeRoot typeRoot= getEditorInputJavaElement(); |
698 |
ASTNode node= getHoveredASTNode(editorInputElement, hoverRegion); |
674 |
if (typeRoot == null) |
699 |
if (node == null) |
675 |
return null; |
700 |
return null; |
676 |
|
701 |
|
677 |
Object constantValue= null; |
702 |
Object constantValue= null; |
678 |
|
703 |
if (node.getNodeType() == ASTNode.SIMPLE_NAME) { |
679 |
CompilationUnit unit= SharedASTProvider.getAST(typeRoot, SharedASTProvider.WAIT_ACTIVE_ONLY, null); |
|
|
680 |
if (unit == null) |
681 |
return null; |
682 |
|
683 |
ASTNode node= NodeFinder.perform(unit, hoverRegion.getOffset(), hoverRegion.getLength()); |
684 |
if (node != null && node.getNodeType() == ASTNode.SIMPLE_NAME) { |
685 |
IBinding binding= ((SimpleName)node).resolveBinding(); |
704 |
IBinding binding= ((SimpleName)node).resolveBinding(); |
686 |
if (binding != null && binding.getKind() == IBinding.VARIABLE) { |
705 |
if (binding != null && binding.getKind() == IBinding.VARIABLE) { |
687 |
IVariableBinding variableBinding= (IVariableBinding)binding; |
706 |
IVariableBinding variableBinding= (IVariableBinding)binding; |
Lines 694-713
Link Here
|
694 |
return null; |
713 |
return null; |
695 |
|
714 |
|
696 |
if (constantValue instanceof String) { |
715 |
if (constantValue instanceof String) { |
697 |
StringBuffer result= new StringBuffer(); |
716 |
return getEscapedStringLiteral((String) constantValue); |
698 |
result.append('"'); |
|
|
699 |
String stringConstant= (String)constantValue; |
700 |
if (stringConstant.length() > 80) { |
701 |
result.append(stringConstant.substring(0, 80)); |
702 |
result.append(JavaElementLabels.ELLIPSIS_STRING); |
703 |
} else { |
704 |
result.append(stringConstant); |
705 |
} |
706 |
result.append('"'); |
707 |
return result.toString(); |
708 |
|
717 |
|
709 |
} else if (constantValue instanceof Character) { |
718 |
} else if (constantValue instanceof Character) { |
710 |
String constantResult= '\'' + constantValue.toString() + '\''; |
719 |
String constantResult= getEscapedCharacterLiteral(((Character) constantValue).charValue()); |
711 |
|
720 |
|
712 |
char charValue= ((Character) constantValue).charValue(); |
721 |
char charValue= ((Character) constantValue).charValue(); |
713 |
String hexString= Integer.toHexString(charValue); |
722 |
String hexString= Integer.toHexString(charValue); |
Lines 739-744
Link Here
|
739 |
} |
748 |
} |
740 |
} |
749 |
} |
741 |
|
750 |
|
|
|
751 |
private static ASTNode getHoveredASTNode(ITypeRoot editorInputElement, IRegion hoverRegion) { |
752 |
if (editorInputElement == null) |
753 |
return null; |
754 |
|
755 |
CompilationUnit unit= SharedASTProvider.getAST(editorInputElement, SharedASTProvider.WAIT_ACTIVE_ONLY, null); |
756 |
if (unit == null) |
757 |
return null; |
758 |
|
759 |
return NodeFinder.perform(unit, hoverRegion.getOffset(), hoverRegion.getLength()); |
760 |
} |
761 |
|
762 |
private static String getEscapedStringLiteral(String stringValue) { |
763 |
StringLiteral stringLiteral= AST.newAST(AST.JLS3).newStringLiteral(); |
764 |
stringLiteral.setLiteralValue(stringValue); |
765 |
String stringConstant= stringLiteral.getEscapedValue(); |
766 |
if (stringConstant.length() > 80) { |
767 |
return stringConstant.substring(0, 80) + JavaElementLabels.ELLIPSIS_STRING; |
768 |
} else { |
769 |
return stringConstant; |
770 |
} |
771 |
} |
772 |
|
773 |
private static String getEscapedCharacterLiteral(char ch) { |
774 |
CharacterLiteral characterLiteral= AST.newAST(AST.JLS3).newCharacterLiteral(); |
775 |
characterLiteral.setCharValue(ch); |
776 |
return characterLiteral.getEscapedValue(); |
777 |
} |
778 |
|
742 |
/** |
779 |
/** |
743 |
* Creates and returns a formatted message for the given |
780 |
* Creates and returns a formatted message for the given |
744 |
* constant with its hex value. |
781 |
* constant with its hex value. |
Lines 803-837
Link Here
|
803 |
return null; |
840 |
return null; |
804 |
} |
841 |
} |
805 |
|
842 |
|
806 |
public static void addImageAndLabel(StringBuffer buf, String imageName, int imageWidth, int imageHeight, int imageLeft, int imageTop, String label, int labelLeft, int labelTop) { |
843 |
public static void addImageAndLabel(StringBuffer buf, String imageSrcPath, int imageWidth, int imageHeight, String label, int labelLeft, int labelTop) { |
|
|
844 |
buf.append("<div style='word-wrap: break-word; position: relative; "); //$NON-NLS-1$ |
845 |
|
846 |
if (imageSrcPath != null) { |
847 |
buf.append("margin-left: ").append(labelLeft).append("px; "); //$NON-NLS-1$ //$NON-NLS-2$ |
848 |
buf.append("padding-top: ").append(labelTop).append("px; "); //$NON-NLS-1$ //$NON-NLS-2$ |
849 |
} |
807 |
|
850 |
|
808 |
if (imageName != null) { |
851 |
buf.append("'>"); //$NON-NLS-1$ |
|
|
852 |
if (imageSrcPath != null) { |
809 |
StringBuffer imageStyle= new StringBuffer("position: absolute; "); //$NON-NLS-1$ |
853 |
StringBuffer imageStyle= new StringBuffer("position: absolute; "); //$NON-NLS-1$ |
810 |
imageStyle.append("width: ").append(imageWidth).append("px; "); //$NON-NLS-1$ //$NON-NLS-2$ |
854 |
imageStyle.append("width: ").append(imageWidth).append("px; "); //$NON-NLS-1$ //$NON-NLS-2$ |
811 |
imageStyle.append("height: ").append(imageHeight).append("px; "); //$NON-NLS-1$ //$NON-NLS-2$ |
855 |
imageStyle.append("height: ").append(imageHeight).append("px; "); //$NON-NLS-1$ //$NON-NLS-2$ |
812 |
imageStyle.append("top: ").append(imageTop).append("px; "); //$NON-NLS-1$ //$NON-NLS-2$ |
856 |
imageStyle.append("left: ").append(- labelLeft - 1).append("px; "); //$NON-NLS-1$ //$NON-NLS-2$ |
813 |
imageStyle.append("left: ").append(imageLeft).append("px; "); //$NON-NLS-1$ //$NON-NLS-2$ |
|
|
814 |
|
857 |
|
|
|
858 |
// hack for broken transparent PNG support in IE 6, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=223900 : |
815 |
buf.append("<!--[if lte IE 6]><![if gte IE 5.5]>\n"); //$NON-NLS-1$ |
859 |
buf.append("<!--[if lte IE 6]><![if gte IE 5.5]>\n"); //$NON-NLS-1$ |
816 |
buf.append("<span style=\"").append(imageStyle).append("filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='").append(imageName).append("')\"></span>\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
860 |
buf.append("<span style=\"").append(imageStyle).append("filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='").append(imageSrcPath).append("')\"></span>\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
817 |
buf.append("<![endif]><![endif]-->\n"); //$NON-NLS-1$ |
861 |
buf.append("<![endif]><![endif]-->\n"); //$NON-NLS-1$ |
818 |
|
862 |
|
819 |
buf.append("<!--[if !IE]>-->\n"); //$NON-NLS-1$ |
863 |
buf.append("<!--[if !IE]>-->\n"); //$NON-NLS-1$ |
820 |
buf.append("<img style='").append(imageStyle).append("' src='").append(imageName).append("'/>\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
864 |
buf.append("<img style='").append(imageStyle).append("' src='").append(imageSrcPath).append("'/>\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
821 |
buf.append("<!--<![endif]-->\n"); //$NON-NLS-1$ |
865 |
buf.append("<!--<![endif]-->\n"); //$NON-NLS-1$ |
822 |
buf.append("<!--[if gte IE 7]>\n"); //$NON-NLS-1$ |
866 |
buf.append("<!--[if gte IE 7]>\n"); //$NON-NLS-1$ |
823 |
buf.append("<img style='").append(imageStyle).append("' src='").append(imageName).append("'/>\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
867 |
buf.append("<img style='").append(imageStyle).append("' src='").append(imageSrcPath).append("'/>\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
824 |
buf.append("<![endif]-->\n"); //$NON-NLS-1$ |
868 |
buf.append("<![endif]-->\n"); //$NON-NLS-1$ |
825 |
} |
869 |
} |
826 |
|
870 |
|
827 |
buf.append("<div style='word-wrap:break-word;"); //$NON-NLS-1$ |
|
|
828 |
if (imageName != null) { |
829 |
buf.append("margin-left: ").append(labelLeft).append("px; "); //$NON-NLS-1$ //$NON-NLS-2$ |
830 |
buf.append("margin-top: ").append(labelTop).append("px; "); //$NON-NLS-1$ //$NON-NLS-2$ |
831 |
} |
832 |
buf.append("'>"); //$NON-NLS-1$ |
833 |
buf.append(label); |
871 |
buf.append(label); |
|
|
872 |
|
834 |
buf.append("</div>"); //$NON-NLS-1$ |
873 |
buf.append("</div>"); //$NON-NLS-1$ |
835 |
} |
874 |
} |
836 |
|
875 |
|
|
|
876 |
public static void addAnnotations(StringBuffer buf, IJavaElement element, ITypeRoot editorInputElement, IRegion hoverRegion) { |
877 |
if (element instanceof IAnnotatable) { |
878 |
try { |
879 |
String annotationString= getAnnotations(element, editorInputElement, hoverRegion); |
880 |
if (annotationString != null) { |
881 |
buf.append("<div style='margin-bottom: 5px;'>"); //$NON-NLS-1$ |
882 |
buf.append(annotationString); |
883 |
buf.append("</div>"); //$NON-NLS-1$ |
884 |
} |
885 |
// } catch (JavaModelException e) { |
886 |
// // no more annotations today... |
887 |
// buf.append("<br>"); //$NON-NLS-1$ |
888 |
} catch (URISyntaxException e) { |
889 |
// no more annotations today... |
890 |
buf.append("<br>"); //$NON-NLS-1$ |
891 |
} |
892 |
} |
893 |
} |
894 |
|
895 |
private static String getAnnotations(IJavaElement element, ITypeRoot editorInputElement, IRegion hoverRegion) throws URISyntaxException { |
896 |
if (!(element instanceof IAnnotatable)) |
897 |
return null; |
898 |
|
899 |
// 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 |
900 |
// return null; |
901 |
//TODO: if (annotations don't include @Documented) return null; ? |
902 |
|
903 |
IBinding binding; |
904 |
ASTNode node= getHoveredASTNode(editorInputElement, hoverRegion); |
905 |
|
906 |
if (node == null) { |
907 |
ASTParser p= ASTParser.newParser(AST.JLS3); |
908 |
p.setProject(element.getJavaProject()); |
909 |
try { |
910 |
binding= p.createBindings(new IJavaElement[] { element }, null)[0]; |
911 |
} catch (OperationCanceledException e) { |
912 |
return null; |
913 |
} |
914 |
|
915 |
} else { |
916 |
if (node.getNodeType() != ASTNode.SIMPLE_NAME) |
917 |
return null; |
918 |
|
919 |
binding= ((SimpleName)node).resolveBinding(); |
920 |
} |
921 |
|
922 |
if (binding == null) |
923 |
return null; |
924 |
|
925 |
IAnnotationBinding[] annotations= binding.getAnnotations(); |
926 |
if (annotations.length == 0) |
927 |
return null; |
928 |
|
929 |
// Arrays.sort(annotations, new Comparator() { |
930 |
// public int compare(Object o1, Object o2) { |
931 |
// IAnnotationBinding b1= (IAnnotationBinding)o1; |
932 |
// IAnnotationBinding b2= (IAnnotationBinding)o2; |
933 |
// try { |
934 |
// //XXX: getJavaElement() fails, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=249844 |
935 |
// IAnnotation e1= (IAnnotation)b1.getJavaElement(); |
936 |
// IAnnotation e2= (IAnnotation)b2.getJavaElement(); |
937 |
// |
938 |
// ISourceRange sr1= e1.getSourceRange(); |
939 |
// ISourceRange sr2= e2.getSourceRange(); |
940 |
// if (SourceRange.isAvailable(sr1) && SourceRange.isAvailable(sr2)) |
941 |
// return sr1.getOffset() - sr2.getOffset(); |
942 |
// } catch (JavaModelException e) { |
943 |
// // don't sort if not available... |
944 |
// } |
945 |
// return 0; |
946 |
// } |
947 |
// }); |
948 |
|
949 |
// try { |
950 |
// IAnnotation[] annotationElements= ((IAnnotatable)element).getAnnotations(); |
951 |
// if (annotationElements.length != 0) { //XXX: mostly 0, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=248309 |
952 |
// ArrayList orderedAnnotations= new ArrayList(); |
953 |
// LinkedHashMap nameToBinding= new LinkedHashMap(); |
954 |
// for (int i= 0; i < annotations.length; i++) { |
955 |
// nameToBinding.put(Signature.getSimpleName(annotations[i].getName()), annotations[i]); |
956 |
// } |
957 |
// for (int i= 0; i < annotationElements.length; i++) { |
958 |
// String elementName= Signature.getSimpleName(annotationElements[i].getElementName()); |
959 |
// IAnnotationBinding annotationBinding= (IAnnotationBinding)nameToBinding.remove(elementName); |
960 |
// if (annotationBinding != null) { |
961 |
// orderedAnnotations.add(annotationBinding); |
962 |
// } |
963 |
// } |
964 |
// orderedAnnotations.addAll(nameToBinding.values()); |
965 |
// annotations= (IAnnotationBinding[]) orderedAnnotations.toArray(new IAnnotationBinding[orderedAnnotations.size()]); |
966 |
// } |
967 |
// } catch (JavaModelException e) { |
968 |
// // don't sort if not available... |
969 |
// } |
970 |
|
971 |
StringBuffer buf= new StringBuffer(); |
972 |
for (int i= 0; i < annotations.length; i++) { |
973 |
addAnnotation(buf, element, annotations[i]); |
974 |
buf.append("<br>"); //$NON-NLS-1$ |
975 |
} |
976 |
|
977 |
return buf.toString(); |
978 |
} |
979 |
|
980 |
private static void addAnnotation(StringBuffer buf, IJavaElement element, IAnnotationBinding annotation) throws URISyntaxException { |
981 |
String uri= JavaElementLinks.createURI(JavaElementLinks.JAVADOC_SCHEME, annotation.getAnnotationType().getJavaElement()); |
982 |
buf.append('@'); |
983 |
addLink(buf, uri, annotation.getName()); |
984 |
|
985 |
IMemberValuePairBinding[] mvPairs= annotation.getDeclaredMemberValuePairs(); //TODO: order not specified... |
986 |
if (mvPairs.length > 0) { |
987 |
buf.append('('); |
988 |
// if (mvPairs.length == 1 && "value".equals(mvPairs[0].getName())) { //$NON-NLS-1$ |
989 |
// IMemberValuePairBinding mvPair= mvPairs[0]; |
990 |
// addValue(buf, element, mvPair.getValue()); |
991 |
// } else { |
992 |
for (int j= 0; j < mvPairs.length; j++) { |
993 |
if (j > 0) { |
994 |
buf.append(JavaElementLabels.COMMA_STRING); |
995 |
} |
996 |
IMemberValuePairBinding mvPair= mvPairs[j]; |
997 |
String memberURI= JavaElementLinks.createURI(JavaElementLinks.JAVADOC_SCHEME, mvPair.getMethodBinding().getJavaElement()); |
998 |
addLink(buf, memberURI, mvPair.getName()); |
999 |
buf.append('='); |
1000 |
addValue(buf, element, mvPair.getValue()); |
1001 |
} |
1002 |
// } |
1003 |
buf.append(')'); |
1004 |
} |
1005 |
} |
1006 |
|
1007 |
private static void addValue(StringBuffer buf, IJavaElement element, Object value) throws URISyntaxException { |
1008 |
if (value instanceof ITypeBinding) { |
1009 |
ITypeBinding typeBinding= (ITypeBinding)value; |
1010 |
IJavaElement type= typeBinding.getJavaElement(); |
1011 |
String typeLabel= JavaElementLinks.getElementLabel(type, LABEL_FLAGS, true); |
1012 |
buf.append(typeLabel).append(".class"); //$NON-NLS-1$ |
1013 |
|
1014 |
} else if (value instanceof IVariableBinding) { // only enum constants |
1015 |
IVariableBinding variableBinding= (IVariableBinding)value; |
1016 |
IJavaElement variable= variableBinding.getJavaElement(); |
1017 |
String uri= JavaElementLinks.createURI(JavaElementLinks.JAVADOC_SCHEME, variable); |
1018 |
String name= variable.getElementName(); |
1019 |
addLink(buf, uri, name); |
1020 |
|
1021 |
} else if (value instanceof IAnnotationBinding) { |
1022 |
IAnnotationBinding annotationBinding= (IAnnotationBinding)value; |
1023 |
addAnnotation(buf, element, annotationBinding); |
1024 |
|
1025 |
} else if (value instanceof String) { |
1026 |
buf.append(getEscapedStringLiteral((String)value)); |
1027 |
|
1028 |
} else if (value instanceof Character) { |
1029 |
buf.append(getEscapedCharacterLiteral(((Character)value).charValue())); |
1030 |
|
1031 |
} else if (value instanceof Object[]) { |
1032 |
Object[] values= (Object[])value; |
1033 |
buf.append('{'); |
1034 |
for (int i= 0; i < values.length; i++) { |
1035 |
if (i > 0) { |
1036 |
buf.append(JavaElementLabels.COMMA_STRING); |
1037 |
} |
1038 |
addValue(buf, element, values[i]); |
1039 |
} |
1040 |
buf.append('}'); |
1041 |
|
1042 |
} else { // primitive types (except char) or null |
1043 |
buf.append(String.valueOf(value)); |
1044 |
} |
1045 |
} |
1046 |
|
1047 |
private static StringBuffer addLink(StringBuffer buf, String uri, String label) { |
1048 |
// return buf.append(JavaElementLinks.createHeaderLink(uri, label)); |
1049 |
return buf.append(JavaElementLinks.createLink(uri, label)); |
1050 |
} |
837 |
} |
1051 |
} |