Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 167145 Details for
Bug 311734
PHP Text hover enhancement
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read
this important communication.
[patch]
patch
clipboard.txt (text/plain), 104.78 KB, created by
xu jiaxi
on 2010-05-05 10:30:20 EDT
(
hide
)
Description:
patch
Filename:
MIME Type:
Creator:
xu jiaxi
Created:
2010-05-05 10:30:20 EDT
Size:
104.78 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.php.ui >Index: PHPDocumentationHoverStyleSheet.css >=================================================================== >RCS file: PHPDocumentationHoverStyleSheet.css >diff -N PHPDocumentationHoverStyleSheet.css >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ PHPDocumentationHoverStyleSheet.css 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,34 @@ >+/* Font definitions */ >+html { font-family: sans-serif; font-size: 9pt; font-style: normal; font-weight: normal; } >+body, h1, h2, h3, h4, h5, h6, p, table, td, caption, th, ul, ol, dl, li, dd, dt { font-size: 1em; } >+pre { font-family: monospace; } >+ >+/* Margins */ >+body { overflow: auto; margin-top: 0px; margin-bottom: 0.5em; margin-left: 0.3em; margin-right: 0px; } >+h1 { margin-top: 0.3em; margin-bottom: 0.04em; } >+h2 { margin-top: 2em; margin-bottom: 0.25em; } >+h3 { margin-top: 1.7em; margin-bottom: 0.25em; } >+h4 { margin-top: 2em; margin-bottom: 0.3em; } >+h5 { margin-top: 0px; margin-bottom: 0px; } >+p { margin-top: 1em; margin-bottom: 1em; } >+pre { margin-left: 0.6em; } >+ul { margin-top: 0px; margin-bottom: 1em; } >+li { margin-top: 0px; margin-bottom: 0px; } >+li p { margin-top: 0px; margin-bottom: 0px; } >+ol { margin-top: 0px; margin-bottom: 1em; } >+dl { margin-top: 0px; margin-bottom: 1em; } >+dt { margin-top: 0px; margin-bottom: 0px; font-weight: bold; } >+dd { margin-top: 0px; margin-bottom: 0px; } >+ >+/* Styles and colors */ >+a:link { color: #0000FF; } >+a:hover { color: #000080; } >+a:visited { text-decoration: underline; } >+a.header:link { text-decoration: none; color: InfoText } >+a.header:visited { text-decoration: none; color: InfoText } >+a.header:hover { text-decoration: underline; color: #000080; } >+h4 { font-style: italic; } >+strong { font-weight: bold; } >+em { font-style: italic; } >+var { font-style: italic; } >+th { font-weight: bold; } >Index: build.properties >=================================================================== >RCS file: /cvsroot/tools/org.eclipse.pdt/plugins/org.eclipse.php.ui/build.properties,v >retrieving revision 1.6 >diff -u -r1.6 build.properties >--- build.properties 28 May 2009 19:50:43 -0000 1.6 >+++ build.properties 5 May 2010 14:28:39 -0000 >@@ -15,6 +15,7 @@ > .,\ > icons/,\ > plugin.properties,\ >+ PHPDocumentationHoverStyleSheet.css,\ > templates/,\ > META-INF/,\ > about.html,\ >Index: src/org/eclipse/php/internal/ui/PHPUiPlugin.java >=================================================================== >RCS file: /cvsroot/tools/org.eclipse.pdt/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/PHPUiPlugin.java,v >retrieving revision 1.27 >diff -u -r1.27 PHPUiPlugin.java >--- src/org/eclipse/php/internal/ui/PHPUiPlugin.java 18 Oct 2009 09:28:25 -0000 1.27 >+++ src/org/eclipse/php/internal/ui/PHPUiPlugin.java 5 May 2010 14:28:41 -0000 >@@ -45,6 +45,7 @@ > import org.eclipse.php.internal.ui.util.ImageDescriptorRegistry; > import org.eclipse.php.internal.ui.util.PHPManualSiteDescriptor; > import org.eclipse.php.internal.ui.util.ProblemMarkerManager; >+import org.eclipse.php.internal.ui.viewsupport.ImagesOnFileSystemRegistry; > import org.eclipse.swt.widgets.Shell; > import org.eclipse.ui.*; > import org.eclipse.ui.editors.text.templates.ContributionContextTypeRegistry; >@@ -95,6 +96,7 @@ > private PHPFoldingStructureProviderRegistry fFoldingStructureProviderRegistry; > private PHPEditorTextHoverDescriptor[] fPHPEditorTextHoverDescriptors; > private PHPManualSiteDescriptor[] fPHPManualSiteDescriptors; >+ private ImagesOnFileSystemRegistry fImagesOnFSRegistry; > > /** > * The AST provider. >@@ -143,9 +145,9 @@ > > if (PlatformUI.isWorkbenchRunning()) { > new InitializeAfterLoadJob().schedule(); // must be last >- // call in >- // start() >- // method >+ // call in >+ // start() >+ // method > } > return Status.OK_STATUS; > } >@@ -538,4 +540,18 @@ > } > return fActiveFormatter; > } >+ >+ /** >+ * Returns the image registry that keeps its images on the local file >+ * system. >+ * >+ * @return the image registry >+ */ >+ public ImagesOnFileSystemRegistry getImagesOnFSRegistry() { >+ if (fImagesOnFSRegistry == null) { >+ fImagesOnFSRegistry = new ImagesOnFileSystemRegistry(); >+ } >+ return fImagesOnFSRegistry; >+ } >+ > } >Index: src/org/eclipse/php/internal/ui/documentation/PHPDocumentationContentAccess.java >=================================================================== >RCS file: src/org/eclipse/php/internal/ui/documentation/PHPDocumentationContentAccess.java >diff -N src/org/eclipse/php/internal/ui/documentation/PHPDocumentationContentAccess.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/php/internal/ui/documentation/PHPDocumentationContentAccess.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,1297 @@ >+package org.eclipse.php.internal.ui.documentation; >+ >+import java.text.MessageFormat; >+import java.util.*; >+ >+import org.eclipse.dltk.ast.references.SimpleReference; >+import org.eclipse.dltk.ast.references.TypeReference; >+import org.eclipse.dltk.ast.references.VariableReference; >+import org.eclipse.dltk.core.*; >+import org.eclipse.dltk.internal.core.util.MethodOverrideTester; >+import org.eclipse.dltk.ui.ScriptElementLabels; >+import org.eclipse.php.core.compiler.PHPFlags; >+import org.eclipse.php.internal.core.ast.nodes.Identifier; >+import org.eclipse.php.internal.core.compiler.ast.nodes.PHPDocBlock; >+import org.eclipse.php.internal.core.compiler.ast.nodes.PHPDocTag; >+import org.eclipse.php.internal.core.typeinference.PHPModelUtils; >+import org.eclipse.php.internal.ui.PHPUiPlugin; >+import org.eclipse.php.internal.ui.corext.util.SuperTypeHierarchyCache; >+ >+/** >+ * Helper to get the content of a Javadoc comment as HTML. >+ * >+ * <p> >+ * <strong>This is work in progress. Parts of this will later become API through >+ * {@link JavadocContentAccess}</strong> >+ * </p> >+ * >+ * @since 3.4 >+ */ >+@SuppressWarnings({ "restriction", "unchecked", "rawtypes" }) >+public class PHPDocumentationContentAccess { >+ >+ private static final String BLOCK_TAG_START = "<dl>"; //$NON-NLS-1$ >+ private static final String BLOCK_TAG_END = "</dl>"; //$NON-NLS-1$ >+ >+ private static final String BlOCK_TAG_ENTRY_START = "<dd>"; //$NON-NLS-1$ >+ private static final String BlOCK_TAG_ENTRY_END = "</dd>"; //$NON-NLS-1$ >+ >+ private static final String PARAM_NAME_START = "<b>"; //$NON-NLS-1$ >+ private static final String PARAM_NAME_END = "</b> "; //$NON-NLS-1$ >+ private static final int PARAMETER_TYPE_TYPE = 1; >+ private static final int PARAMETER_NAME_TYPE = 2; >+ private static final int PARAMETER_DESCRIPTION_TYPE = 3; >+ >+ /** >+ * Implements the "Algorithm for Inheriting Method Comments" as specified >+ * for <a href= >+ * "http://java.sun.com/j2se/1.4.2/docs/tooldocs/solaris/javadoc.html#inheritingcomments" >+ * >1.4.2</a>, <a href= >+ * "http://java.sun.com/j2se/1.5.0/docs/tooldocs/windows/javadoc.html#inheritingcomments" >+ * >1.5</a>, and <a href= >+ * "http://java.sun.com/javase/6/docs/technotes/tools/windows/javadoc.html#inheritingcomments" >+ * >1.6</a>. >+ * >+ * <p> >+ * Unfortunately, the implementation is broken in Javadoc implementations >+ * since 1.5, see <a >+ * href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6376959">Sun's >+ * bug</a>. >+ * </p> >+ * >+ * <p> >+ * We adhere to the spec. >+ * </p> >+ */ >+ private static abstract class InheritDocVisitor { >+ public static final Object STOP_BRANCH = new Object() { >+ public String toString() { >+ return "STOP_BRANCH";} //$NON-NLS-1$ >+ }; >+ public static final Object CONTINUE = new Object() { >+ public String toString() { >+ return "CONTINUE";} //$NON-NLS-1$ >+ }; >+ >+ /** >+ * Visits a type and decides how the visitor should proceed. >+ * >+ * @param currType >+ * the current type >+ * @return <ul> >+ * <li>{@link #STOP_BRANCH} to indicate that no Javadoc has been >+ * found and visiting super types should stop here</li> >+ * <li>{@link #CONTINUE} to indicate that no Javadoc has been >+ * found and visiting super types should continue</li> >+ * <li>an {@link Object} or <code>null</code>, to indicate that >+ * visiting should be cancelled immediately. The returned value >+ * is the result of >+ * {@link #visitInheritDoc(IType, ITypeHierarchy)}</li> >+ * </ul> >+ * @throws ModelException >+ * unexpected problem >+ * @see #visitInheritDoc(IType, ITypeHierarchy) >+ */ >+ public abstract Object visit(IType currType) throws ModelException; >+ >+ /** >+ * Visits the super types of the given <code>currentType</code>. >+ * >+ * @param currentType >+ * the starting type >+ * @param typeHierarchy >+ * a super type hierarchy that contains >+ * <code>currentType</code> >+ * @return the result from a call to {@link #visit(IType)}, or >+ * <code>null</code> if none of the calls returned a result >+ * @throws ModelException >+ * unexpected problem >+ */ >+ public Object visitInheritDoc(IType currentType, >+ ITypeHierarchy typeHierarchy) throws ModelException { >+ ArrayList visited = new ArrayList(); >+ visited.add(currentType); >+ // Object result = visitInheritDocInterfaces(visited, currentType, >+ // typeHierarchy); >+ // if (result != InheritDocVisitor.CONTINUE) >+ // return result; >+ Object result; >+ IType[] superClasses = typeHierarchy.getSuperclass(currentType); >+ for (IType superClass : superClasses) { >+ while (superClass != null && !visited.contains(superClass)) { >+ result = visit(superClass); >+ if (result == InheritDocVisitor.STOP_BRANCH) { >+ return null; >+ } else if (result == InheritDocVisitor.CONTINUE) { >+ visited.add(superClass); >+ result = visitInheritDocInterfaces(visited, superClass, >+ typeHierarchy); >+ if (result != InheritDocVisitor.CONTINUE) >+ return result; >+ else >+ superClasses = typeHierarchy >+ .getSuperclass(superClass); >+ } else { >+ return result; >+ } >+ } >+ } >+ return null; >+ } >+ >+ /** >+ * Visits the super interfaces of the given type in the given hierarchy, >+ * thereby skipping already visited types. >+ * >+ * @param visited >+ * set of visited types >+ * @param currentType >+ * type whose super interfaces should be visited >+ * @param typeHierarchy >+ * type hierarchy (must include <code>currentType</code>) >+ * @return the result, or {@link #CONTINUE} if no result has been found >+ * @throws ModelException >+ * unexpected problem >+ */ >+ private Object visitInheritDocInterfaces(ArrayList visited, >+ IType currentType, ITypeHierarchy typeHierarchy) >+ throws ModelException { >+ ArrayList toVisitChildren = new ArrayList(); >+ IType[] superInterfaces = typeHierarchy.getSuperclass(currentType); >+ for (int i = 0; i < superInterfaces.length; i++) { >+ IType superInterface = superInterfaces[i]; >+ if (visited.contains(superInterface)) >+ continue; >+ visited.add(superInterface); >+ Object result = visit(superInterface); >+ if (result == InheritDocVisitor.STOP_BRANCH) { >+ // skip >+ } else if (result == InheritDocVisitor.CONTINUE) { >+ toVisitChildren.add(superInterface); >+ } else { >+ return result; >+ } >+ } >+ for (Iterator iter = toVisitChildren.iterator(); iter.hasNext();) { >+ IType child = (IType) iter.next(); >+ Object result = visitInheritDocInterfaces(visited, child, >+ typeHierarchy); >+ if (result != InheritDocVisitor.CONTINUE) >+ return result; >+ } >+ return InheritDocVisitor.CONTINUE; >+ } >+ } >+ >+ private static class JavadocLookup { >+ private static final JavadocLookup NONE = new JavadocLookup(null) { >+ public CharSequence getInheritedMainDescription(IMethod method) { >+ return null; >+ } >+ >+ public CharSequence getInheritedParamDescription(IMethod method, >+ int i) { >+ return null; >+ } >+ >+ public CharSequence getInheritedReturnDescription(IMethod method) { >+ return null; >+ } >+ >+ public CharSequence getInheritedExceptionDescription( >+ IMethod method, String name) { >+ return null; >+ } >+ }; >+ >+ private static interface DescriptionGetter { >+ /** >+ * Returns a Javadoc tag description or <code>null</code>. >+ * >+ * @param contentAccess >+ * the content access >+ * @return the description, or <code>null</code> if none >+ * @throws ModelException >+ * unexpected problem >+ */ >+ CharSequence getDescription( >+ PHPDocumentationContentAccess contentAccess) >+ throws ModelException; >+ } >+ >+ private final IType fStartingType; >+ private final HashMap fContentAccesses; >+ >+ private ITypeHierarchy fTypeHierarchy; >+ private MethodOverrideTester fOverrideTester; >+ >+ private JavadocLookup(IType startingType) { >+ fStartingType = startingType; >+ fContentAccesses = new HashMap(); >+ } >+ >+ /** >+ * For the given method, returns the main description from an overridden >+ * method. >+ * >+ * @param method >+ * a method >+ * @return the description that replaces the >+ * <code>{@inheritDoc}</code> tag, or <code>null</code> if >+ * none could be found >+ */ >+ public CharSequence getInheritedMainDescription(IMethod method) { >+ return getInheritedDescription(method, new DescriptionGetter() { >+ public CharSequence getDescription( >+ PHPDocumentationContentAccess contentAccess) { >+ return contentAccess.getMainDescription(); >+ } >+ }); >+ } >+ >+ /** >+ * For the given method, returns the @param tag description for the >+ * given parameter from an overridden method. >+ * >+ * @param method >+ * a method >+ * @param paramIndex >+ * the index of the parameter >+ * @return the description that replaces the >+ * <code>{@inheritDoc}</code> tag, or <code>null</code> if >+ * none could be found >+ */ >+ public CharSequence getInheritedParamDescription(IMethod method, >+ final int paramIndex) { >+ return getInheritedDescription(method, new DescriptionGetter() { >+ public CharSequence getDescription( >+ PHPDocumentationContentAccess contentAccess) >+ throws ModelException { >+ return contentAccess >+ .getInheritedParamDescription(paramIndex); >+ } >+ }); >+ } >+ >+ /** >+ * For the given method, returns the @param tag description for the >+ * given parameter from an overridden method. >+ * >+ * @param method >+ * a method >+ * @param paramIndex >+ * the index of the parameter >+ * @return the description that replaces the >+ * <code>{@inheritDoc}</code> tag, or <code>null</code> if >+ * none could be found >+ */ >+ public CharSequence getInheritedParamType(IMethod method, >+ final int paramIndex) { >+ return getInheritedDescription(method, new DescriptionGetter() { >+ public CharSequence getDescription( >+ PHPDocumentationContentAccess contentAccess) >+ throws ModelException { >+ return contentAccess.getInheritedParamType(paramIndex); >+ } >+ }); >+ } >+ >+ /** >+ * For the given method, returns the @return tag description from an >+ * overridden method. >+ * >+ * @param method >+ * a method >+ * @return the description that replaces the >+ * <code>{@inheritDoc}</code> tag, or <code>null</code> if >+ * none could be found >+ */ >+ public CharSequence getInheritedReturnDescription(IMethod method) { >+ return getInheritedDescription(method, new DescriptionGetter() { >+ public CharSequence getDescription( >+ PHPDocumentationContentAccess contentAccess) { >+ return contentAccess.getReturnDescription(); >+ } >+ }); >+ } >+ >+ /** >+ * For the given method, returns the @throws/@exception tag description >+ * for the given exception from an overridden method. >+ * >+ * @param method >+ * a method >+ * @param simpleName >+ * the simple name of an exception >+ * @return the description that replaces the >+ * <code>{@inheritDoc}</code> tag, or <code>null</code> if >+ * none could be found >+ */ >+ public CharSequence getInheritedExceptionDescription(IMethod method, >+ final String simpleName) { >+ return getInheritedDescription(method, new DescriptionGetter() { >+ public CharSequence getDescription( >+ PHPDocumentationContentAccess contentAccess) { >+ return contentAccess.getExceptionDescription(simpleName); >+ } >+ }); >+ } >+ >+ private CharSequence getInheritedDescription(final IMethod method, >+ final DescriptionGetter descriptionGetter) { >+ try { >+ return (CharSequence) new InheritDocVisitor() { >+ public Object visit(IType currType) throws ModelException { >+ IMethod overridden = getOverrideTester() >+ .findOverriddenMethodInType(currType, method); >+ if (overridden == null) >+ return InheritDocVisitor.CONTINUE; >+ >+ PHPDocumentationContentAccess contentAccess = getJavadocContentAccess(overridden); >+ if (contentAccess == null) { >+ // if (overridden.getOpenable().getBuffer() == null) >+ // { >+ // return InheritDocVisitor.CONTINUE; >+ // } else { >+ // return InheritDocVisitor.CONTINUE; >+ // } >+ return InheritDocVisitor.CONTINUE; >+ } >+ >+ CharSequence overriddenDescription = descriptionGetter >+ .getDescription(contentAccess); >+ if (overriddenDescription != null) >+ return overriddenDescription; >+ else >+ return InheritDocVisitor.CONTINUE; >+ } >+ }.visitInheritDoc(method.getDeclaringType(), getTypeHierarchy()); >+ } catch (ModelException e) { >+ PHPUiPlugin.log(e); >+ } >+ return null; >+ } >+ >+ /** >+ * @param method >+ * the method >+ * @return the Javadoc content access for the given method, or >+ * <code>null</code> if no Javadoc could be found in source >+ * @throws ModelException >+ * unexpected problem >+ */ >+ private PHPDocumentationContentAccess getJavadocContentAccess( >+ IMethod method) throws ModelException { >+ Object cached = fContentAccesses.get(method); >+ if (cached != null) >+ return (PHPDocumentationContentAccess) cached; >+ if (fContentAccesses.containsKey(method)) >+ return null; >+ >+ // IBuffer buf = method.getOpenable().getBuffer(); >+ // if (buf == null) { // no source attachment found >+ // fContentAccesses.put(method, null); >+ // return null; >+ // } >+ >+ PHPDocBlock javadoc = PHPModelUtils.getDocBlock(method); >+ if (javadoc == null) { >+ fContentAccesses.put(method, null); >+ return null; >+ } >+ >+ PHPDocumentationContentAccess contentAccess = new PHPDocumentationContentAccess( >+ method, javadoc, this); >+ fContentAccesses.put(method, contentAccess); >+ return contentAccess; >+ } >+ >+ private ITypeHierarchy getTypeHierarchy() throws ModelException { >+ if (fTypeHierarchy == null) >+ fTypeHierarchy = SuperTypeHierarchyCache >+ .getTypeHierarchy(fStartingType); >+ return fTypeHierarchy; >+ } >+ >+ private MethodOverrideTester getOverrideTester() throws ModelException { >+ if (fOverrideTester == null) >+ fOverrideTester = SuperTypeHierarchyCache >+ .getMethodOverrideTester(fStartingType); >+ return fOverrideTester; >+ } >+ } >+ >+ private final IMember fMember; >+ /** >+ * The method, or <code>null</code> if {@link #fMember} is not a method >+ * where {@inheritDoc} could work. >+ */ >+ private final IMethod fMethod; >+ private final PHPDocBlock fJavadoc; >+ private final JavadocLookup fJavadocLookup; >+ >+ private StringBuffer fBuf; >+ private StringBuffer fMainDescription; >+ private StringBuffer fReturnDescription; >+ private StringBuffer[] fParamDescriptions; >+ private StringBuffer[] fParamTypes; >+ private HashMap<String, StringBuffer> fExceptionDescriptions; >+ >+ private PHPDocumentationContentAccess(IMethod method, PHPDocBlock javadoc, >+ JavadocLookup lookup) { >+ fMember = method; >+ fMethod = method; >+ fJavadoc = javadoc; >+ fJavadocLookup = lookup; >+ } >+ >+ private PHPDocumentationContentAccess(IMember member, PHPDocBlock javadoc) { >+ fMember = member; >+ fMethod = null; >+ fJavadoc = javadoc; >+ fJavadocLookup = JavadocLookup.NONE; >+ } >+ >+ /** >+ * Gets an IMember's Javadoc comment content from the source or Javadoc >+ * attachment and renders the tags and links in HTML. Returns >+ * <code>null</code> if the member does not contain a Javadoc comment or if >+ * no source is available. >+ * >+ * @param member >+ * the member to get the Javadoc of >+ * @param useAttachedJavadoc >+ * if <code>true</code> Javadoc will be extracted from attached >+ * Javadoc if there's no source >+ * @return the Javadoc comment content in HTML or <code>null</code> if the >+ * member does not have a Javadoc comment or if no source is >+ * available >+ * @throws ModelException >+ * is thrown when the element's Javadoc can not be accessed >+ */ >+ public static String getHTMLContent(IMember member) throws ModelException { >+ return getHTMLContentFromSource(member); >+ } >+ >+ private static StringBuffer createSuperMethodReferences(final IMethod method) >+ throws ModelException { >+ IType type = method.getDeclaringType(); >+ ITypeHierarchy hierarchy = SuperTypeHierarchyCache >+ .getTypeHierarchy(type); >+ final MethodOverrideTester tester = SuperTypeHierarchyCache >+ .getMethodOverrideTester(type); >+ >+ final ArrayList<IMethod> superInterfaceMethods = new ArrayList<IMethod>(); >+ final IMethod[] superClassMethod = { null }; >+ new InheritDocVisitor() { >+ public Object visit(IType currType) throws ModelException { >+ IMethod overridden = tester.findOverriddenMethodInType( >+ currType, method); >+ if (overridden == null) >+ return InheritDocVisitor.CONTINUE; >+ >+ if (PHPFlags.isInterface(currType.getFlags())) >+ superInterfaceMethods.add(overridden); >+ else >+ superClassMethod[0] = overridden; >+ >+ return STOP_BRANCH; >+ } >+ }.visitInheritDoc(type, hierarchy); >+ >+ boolean hasSuperInterfaceMethods = superInterfaceMethods.size() != 0; >+ if (!hasSuperInterfaceMethods && superClassMethod[0] == null) >+ return null; >+ >+ StringBuffer buf = new StringBuffer(); >+ buf.append("<div>"); //$NON-NLS-1$ >+ if (hasSuperInterfaceMethods) { >+ buf.append("<b>"); //$NON-NLS-1$ >+ buf.append(PHPDocumentationMessages.JavaDoc2HTMLTextReader_specified_by_section); >+ buf.append("</b> "); //$NON-NLS-1$ >+ for (Iterator<IMethod> iter = superInterfaceMethods.iterator(); iter >+ .hasNext();) { >+ IMethod overridden = (IMethod) iter.next(); >+ buf.append(createMethodInTypeLinks(overridden)); >+ if (iter.hasNext()) >+ buf.append(ScriptElementLabels.COMMA_STRING); >+ } >+ } >+ if (superClassMethod[0] != null) { >+ if (hasSuperInterfaceMethods) >+ buf.append(ScriptElementLabels.COMMA_STRING); >+ buf.append("<b>"); //$NON-NLS-1$ >+ buf.append(PHPDocumentationMessages.JavaDoc2HTMLTextReader_overrides_section); >+ buf.append("</b> "); //$NON-NLS-1$ >+ buf.append(createMethodInTypeLinks(superClassMethod[0])); >+ } >+ buf.append("</div>"); //$NON-NLS-1$ >+ return buf; >+ } >+ >+ private static String createMethodInTypeLinks(IMethod overridden) { >+ CharSequence methodLink = createSimpleMemberLink(overridden); >+ CharSequence typeLink = createSimpleMemberLink(overridden >+ .getDeclaringType()); >+ String methodInType = MessageFormat.format( >+ PHPDocumentationMessages.JavaDoc2HTMLTextReader_method_in_type, >+ new Object[] { methodLink, typeLink }); >+ return methodInType; >+ } >+ >+ private static CharSequence createSimpleMemberLink(IMember member) { >+ StringBuffer buf = new StringBuffer(); >+ buf.append("<a href='"); //$NON-NLS-1$ >+ // try { >+ // String uri= >+ // JavaElementLinks.createURI(JavaElementLinks.JAVADOC_SCHEME, member); >+ // buf.append(uri); >+ // } catch (URISyntaxException e) { >+ // JavaPlugin.log(e); >+ // } >+ buf.append("'>"); //$NON-NLS-1$ >+ ScriptElementLabels.getDefault().getElementLabel(member, 0, buf); >+ buf.append("</a>"); //$NON-NLS-1$ >+ return buf; >+ } >+ >+ private static String getHTMLContentFromSource(IMember member) >+ throws ModelException { >+ return javadoc2HTML(member); >+ } >+ >+ private static PHPDocBlock getJavadocNode(IMember member) { >+ if (member instanceof IType) { >+ return PHPModelUtils.getDocBlock((IType) member); >+ } >+ if (member instanceof IMethod) { >+ return PHPModelUtils.getDocBlock((IMethod) member); >+ } >+ if (member instanceof IField) { >+ return PHPModelUtils.getDocBlock((IField) member); >+ } >+ return null; >+ } >+ >+ private static String javadoc2HTML(IMember member) { >+ PHPDocBlock javadoc = getJavadocNode(member); >+ >+ if (javadoc == null) { >+ javadoc = new PHPDocBlock(0, 0, null, new PHPDocTag[0]); >+ } >+ if (canInheritJavadoc(member)) { >+ IMethod method = (IMethod) member; >+ IType declaringType = method.getDeclaringType(); >+ JavadocLookup lookup; >+ if (declaringType == null) { >+ lookup = JavadocLookup.NONE; >+ } else { >+ lookup = new JavadocLookup(method.getDeclaringType()); >+ } >+ return new PHPDocumentationContentAccess(method, javadoc, lookup) >+ .toHTML(); >+ } >+ return new PHPDocumentationContentAccess(member, javadoc).toHTML(); >+ } >+ >+ private static boolean canInheritJavadoc(IMember member) { >+ if (member instanceof IMethod && member.getScriptProject().exists()) { >+ /* >+ * Exists test catches ExternalJavaProject, in which case no >+ * hierarchy can be built. >+ */ >+ try { >+ return !((IMethod) member).isConstructor(); >+ } catch (ModelException e) { >+ PHPUiPlugin.log(e); >+ } >+ } >+ return false; >+ } >+ >+ private String toHTML() { >+ fBuf = new StringBuffer(); >+ >+ if (appendBuiltinDoc(fMember, fBuf)) { >+ return fBuf.toString(); >+ } >+ >+ // After first loop, non-null entries in the following two lists are >+ // missing and need to be inherited: >+ List<String> parameterNames = initParameterNames(); >+ List<String> exceptionNames = new ArrayList<String>(); >+ >+ PHPDocTag deprecatedTag = null; >+ PHPDocTag returnTag = null; >+ List<PHPDocTag> parameters = new ArrayList<PHPDocTag>(); >+ List<PHPDocTag> exceptions = new ArrayList<PHPDocTag>(); >+ List<PHPDocTag> versions = new ArrayList<PHPDocTag>(); >+ List<PHPDocTag> authors = new ArrayList<PHPDocTag>(); >+ List<PHPDocTag> sees = new ArrayList<PHPDocTag>(); >+ List<PHPDocTag> since = new ArrayList<PHPDocTag>(); >+ List<PHPDocTag> rest = new ArrayList<PHPDocTag>(); >+ String shortDescription = fJavadoc.getShortDescription(); >+ PHPDocTag[] tags = fJavadoc.getTags(); >+ for (PHPDocTag tag : tags) { >+ if (PHPDocTag.PARAM == tag.getTagKind()) { >+ parameters.add(tag); >+ SimpleReference[] fragments = tag.getReferences(); >+ if (fragments.length == 0) { >+ if (parameterNames.size() > parameters.indexOf(tag)) >+ parameterNames.set(parameters.indexOf(tag), null); >+ } >+ for (SimpleReference reference : fragments) { >+ String name = reference.getName(); >+ if (reference instanceof TypeReference) { >+ // parameterTypes.add(name); >+ } else if (reference instanceof VariableReference) { >+ int paramIndex = parameterNames.indexOf(name); >+ if (paramIndex != -1) { >+ parameterNames.set(paramIndex, null); >+ } >+ } >+ } >+ } else if (PHPDocTag.RETURN == tag.getTagKind()) { >+ if (returnTag == null) >+ returnTag = tag; // the Javadoc tool only shows the first >+ // return tag >+ >+ } else if (PHPDocTag.THROWS == tag.getTagKind()) { >+ exceptions.add(tag); >+ SimpleReference[] fragments = tag.getReferences(); >+ if (fragments.length > 0) { >+ Object first = fragments[0]; >+ if (first instanceof TypeReference) { >+ exceptionNames.add(((TypeReference) first).getName()); >+ } >+ } >+ >+ } else if (PHPDocTag.SINCE == tag.getTagKind()) { >+ since.add(tag); >+ } else if (PHPDocTag.VERSION == tag.getTagKind()) { >+ versions.add(tag); >+ } else if (PHPDocTag.AUTHOR == tag.getTagKind()) { >+ authors.add(tag); >+ } else if (PHPDocTag.SEE == tag.getTagKind()) { >+ sees.add(tag); >+ } else if (PHPDocTag.DEPRECATED == tag.getTagKind()) { >+ if (deprecatedTag == null) >+ deprecatedTag = tag; // the Javadoc tool only shows the >+ // first deprecated tag >+ } else { >+ rest.add(tag); >+ } >+ } >+ >+ if (deprecatedTag != null) >+ handleDeprecatedTag(deprecatedTag); >+ if (shortDescription != null && shortDescription.length() > 0) >+ fBuf.append(shortDescription); >+ else if (fMethod != null) { >+ CharSequence inherited = fJavadocLookup >+ .getInheritedMainDescription(fMethod); >+ handleInherited(inherited); >+ } >+ >+ CharSequence[] parameterDescriptions = new CharSequence[parameterNames >+ .size()]; >+ CharSequence[] parameterTypes = new CharSequence[parameterNames.size()]; >+ boolean hasInheritedParameters = inheritParameterDescriptions( >+ parameterNames, parameterDescriptions, parameterTypes); >+ boolean hasParameters = parameters.size() > 0 || hasInheritedParameters; >+ >+ CharSequence returnDescription = null; >+ if (returnTag == null) >+ returnDescription = fJavadocLookup >+ .getInheritedReturnDescription(fMethod); >+ boolean hasReturnTag = returnTag != null || returnDescription != null; >+ >+ CharSequence[] exceptionDescriptions = new CharSequence[exceptionNames >+ .size()]; >+ boolean hasInheritedExceptions = inheritExceptionDescriptions( >+ exceptionNames, exceptionDescriptions); >+ boolean hasExceptions = exceptions.size() > 0 || hasInheritedExceptions; >+ >+ if (hasParameters >+ || hasReturnTag >+ || hasExceptions >+ || versions.size() > 0 >+ || authors.size() > 0 >+ || since.size() > 0 >+ || sees.size() > 0 >+ || rest.size() > 0 >+ || (fBuf.length() > 0 && (parameterDescriptions.length > 0 || exceptionDescriptions.length > 0))) { >+ handleSuperMethodReferences(); >+ fBuf.append(BLOCK_TAG_START); >+ handleParameterTags(parameters, parameterNames, parameterTypes, >+ parameterDescriptions); >+ handleReturnTag(returnTag, returnDescription); >+ handleExceptionTags(exceptions, exceptionNames, >+ exceptionDescriptions); >+ handleBlockTags( >+ PHPDocumentationMessages.JavaDoc2HTMLTextReader_since_section, >+ since); >+ handleBlockTags( >+ PHPDocumentationMessages.JavaDoc2HTMLTextReader_version_section, >+ versions); >+ handleBlockTags( >+ PHPDocumentationMessages.JavaDoc2HTMLTextReader_author_section, >+ authors); >+ handleBlockTags( >+ PHPDocumentationMessages.JavaDoc2HTMLTextReader_see_section, >+ sees); >+ handleBlockTags(rest); >+ fBuf.append(BLOCK_TAG_END); >+ >+ } else if (fBuf.length() > 0) { >+ handleSuperMethodReferences(); >+ } >+ >+ String result = fBuf.toString(); >+ fBuf = null; >+ return result; >+ } >+ >+ private void handleDeprecatedTag(PHPDocTag tag) { >+ fBuf.append("<p><b>"); //$NON-NLS-1$ >+ fBuf.append(PHPDocumentationMessages.JavaDoc2HTMLTextReader_deprecated_section); >+ fBuf.append("</b> <i>"); //$NON-NLS-1$ >+ handleContentElements(tag); >+ fBuf.append("</i><p>"); //$NON-NLS-1$ >+ } >+ >+ private void handleSuperMethodReferences() { >+ if (fMethod != null && fMethod.getDeclaringType() != null) { >+ try { >+ StringBuffer superMethodReferences = createSuperMethodReferences(fMethod); >+ if (superMethodReferences != null) >+ fBuf.append(superMethodReferences); >+ } catch (ModelException e) { >+ PHPUiPlugin.log(e); >+ } >+ } >+ } >+ >+ private List<String> initParameterNames() { >+ if (fMethod != null) { >+ try { >+ return new ArrayList<String>(Arrays.asList(fMethod >+ .getParameterNames())); >+ } catch (ModelException e) { >+ PHPUiPlugin.log(e); >+ } >+ } >+ return Collections.EMPTY_LIST; >+ } >+ >+ private boolean inheritParameterDescriptions(List<String> parameterNames, >+ CharSequence[] parameterDescriptions, CharSequence[] parameterTypes) { >+ boolean hasInheritedParameters = false; >+ if (fMethod != null && fMethod.getDeclaringType() == null) { >+ return hasInheritedParameters; >+ } >+ for (int i = 0; i < parameterNames.size(); i++) { >+ String name = (String) parameterNames.get(i); >+ if (name != null) { >+ parameterDescriptions[i] = fJavadocLookup >+ .getInheritedParamDescription(fMethod, i); >+ parameterTypes[i] = fJavadocLookup.getInheritedParamType( >+ fMethod, i); >+ if (parameterDescriptions[i] != null) >+ hasInheritedParameters = true; >+ } >+ } >+ return hasInheritedParameters; >+ } >+ >+ private boolean inheritExceptionDescriptions(List<String> exceptionNames, >+ CharSequence[] exceptionDescriptions) { >+ boolean hasInheritedExceptions = false; >+ if (fMethod != null && fMethod.getDeclaringType() == null) { >+ return hasInheritedExceptions; >+ } >+ for (int i = 0; i < exceptionNames.size(); i++) { >+ String name = (String) exceptionNames.get(i); >+ if (name != null) { >+ exceptionDescriptions[i] = fJavadocLookup >+ .getInheritedExceptionDescription(fMethod, name); >+ if (exceptionDescriptions[i] != null) >+ hasInheritedExceptions = true; >+ } >+ } >+ return hasInheritedExceptions; >+ } >+ >+ CharSequence getMainDescription() { >+ if (fMainDescription == null) { >+ fMainDescription = new StringBuffer(); >+ fBuf = fMainDescription; >+ >+ String shortDescription = fJavadoc.getShortDescription(); >+ if (shortDescription != null && shortDescription.length() > 0) { >+ fMainDescription.append(shortDescription); >+ } >+ fBuf = null; >+ } >+ return fMainDescription.length() > 0 ? fMainDescription : null; >+ } >+ >+ CharSequence getReturnDescription() { >+ if (fReturnDescription == null) { >+ fReturnDescription = new StringBuffer(); >+ fBuf = fReturnDescription; >+ >+ PHPDocTag[] tags = fJavadoc.getTags(); >+ for (PHPDocTag tag : tags) { >+ if (PHPDocTag.RETURN == tag.getTagKind()) { >+ handleContentElements(tag); >+ break; >+ } >+ } >+ >+ fBuf = null; >+ } >+ return fReturnDescription.length() > 0 ? fReturnDescription : null; >+ } >+ >+ CharSequence getInheritedParamDescription(int paramIndex) >+ throws ModelException { >+ if (fMethod != null) { >+ String[] parameterNames = fMethod.getParameterNames(); >+ if (paramIndex >= parameterNames.length) { >+ return null; >+ } >+ if (fParamDescriptions == null) { >+ fParamDescriptions = new StringBuffer[parameterNames.length]; >+ } else { >+ StringBuffer description = fParamDescriptions[paramIndex]; >+ if (description != null) { >+ return description.length() > 0 ? description : null; >+ } >+ } >+ >+ StringBuffer description = new StringBuffer(); >+ fParamDescriptions[paramIndex] = description; >+ fBuf = description; >+ >+ String paramName = parameterNames[paramIndex]; >+ String info = getParameterInfo(fJavadoc, paramName, >+ PARAMETER_DESCRIPTION_TYPE); >+ if (info != null) >+ description.append(info); >+ fBuf = null; >+ return description.length() > 0 ? description : null; >+ } >+ return null; >+ } >+ >+ CharSequence getInheritedParamType(int paramIndex) throws ModelException { >+ if (fMethod != null) { >+ String[] parameterNames = fMethod.getParameterNames(); >+ if (paramIndex >= parameterNames.length) { >+ return null; >+ } >+ if (fParamTypes == null) { >+ fParamTypes = new StringBuffer[parameterNames.length]; >+ } else { >+ StringBuffer typeName = fParamTypes[paramIndex]; >+ if (typeName != null) { >+ return typeName.length() > 0 ? typeName : null; >+ } >+ } >+ >+ StringBuffer typeName = new StringBuffer(); >+ fParamTypes[paramIndex] = typeName; >+ fBuf = typeName; >+ >+ String paramName = parameterNames[paramIndex]; >+ String info = getParameterInfo(fJavadoc, paramName, >+ PARAMETER_TYPE_TYPE); >+ if (info != null) >+ typeName.append(info); >+ >+ fBuf = null; >+ return typeName.length() > 0 ? typeName : null; >+ } >+ return null; >+ } >+ >+ CharSequence getExceptionDescription(String simpleName) { >+ if (fMethod != null) { >+ if (fExceptionDescriptions == null) { >+ fExceptionDescriptions = new HashMap(); >+ } else { >+ StringBuffer description = (StringBuffer) fExceptionDescriptions >+ .get(simpleName); >+ if (description != null) { >+ return description.length() > 0 ? description : null; >+ } >+ } >+ >+ StringBuffer description = new StringBuffer(); >+ fExceptionDescriptions.put(simpleName, description); >+ fBuf = description; >+ >+ List tags = Arrays.asList(fJavadoc.getTags()); >+ for (Iterator iter = tags.iterator(); iter.hasNext();) { >+ PHPDocTag tag = (PHPDocTag) iter.next(); >+ if (PHPDocTag.THROWS == tag.getTagKind()) { >+ List fragments = Arrays.asList(tag.getReferences()); >+ if (fragments.size() > 0) { >+ Object first = fragments.get(0); >+ if (first instanceof Identifier) { >+ String name = ((Identifier) first).getName(); >+ if (name.equals(simpleName)) { >+ if (fragments.size() > 1) >+ handleContentElements(tag); >+ break; >+ } >+ } >+ } >+ } >+ } >+ >+ fBuf = null; >+ return description.length() > 0 ? description : null; >+ } >+ return null; >+ } >+ >+ private void handleContentElements(PHPDocTag tag) { >+ fBuf.append(tag.getValue()); >+ } >+ >+ private boolean handleInherited(CharSequence inherited) { >+ if (inherited == null) >+ return false; >+ >+ fBuf.append(inherited); >+ return true; >+ } >+ >+ private void handleBlockTags(String title, List tags) { >+ if (tags.isEmpty()) >+ return; >+ >+ handleBlockTagTitle(title); >+ >+ for (Iterator iter = tags.iterator(); iter.hasNext();) { >+ PHPDocTag tag = (PHPDocTag) iter.next(); >+ fBuf.append(BlOCK_TAG_ENTRY_START); >+ if (PHPDocTag.SEE == tag.getTagKind()) { >+ handleSeeTag(tag); >+ } else { >+ handleContentElements(tag); >+ } >+ fBuf.append(BlOCK_TAG_ENTRY_END); >+ } >+ } >+ >+ private void handleReturnTag(PHPDocTag tag, CharSequence returnDescription) { >+ if (tag == null && returnDescription == null) >+ return; >+ >+ handleBlockTagTitle(PHPDocumentationMessages.JavaDoc2HTMLTextReader_returns_section); >+ fBuf.append(BlOCK_TAG_ENTRY_START); >+ if (tag != null) >+ handleContentElements(tag); >+ else >+ fBuf.append(returnDescription); >+ fBuf.append(BlOCK_TAG_ENTRY_END); >+ } >+ >+ private void handleBlockTags(List tags) { >+ for (Iterator iter = tags.iterator(); iter.hasNext();) { >+ PHPDocTag tag = (PHPDocTag) iter.next(); >+ if (tag.getTagKind() == PHPDocTag.VAR) { >+ handleBlockTagTitle("Type"); >+ } else { >+ handleBlockTagTitle(PHPDocTag.getTagKind(tag.getTagKind())); >+ } >+ fBuf.append(BlOCK_TAG_ENTRY_START); >+ if (tag.getTagKind() == PHPDocTag.LINK) { >+ handleLinkTag(tag); >+ } else { >+ handleContentElements(tag); >+ } >+ fBuf.append(BlOCK_TAG_ENTRY_END); >+ } >+ } >+ >+ private void handleBlockTagTitle(String title) { >+ fBuf.append("<dt>"); //$NON-NLS-1$ >+ fBuf.append(title); >+ fBuf.append("</dt>"); //$NON-NLS-1$ >+ } >+ >+ private void handleSeeTag(PHPDocTag tag) { >+ handleLink(Arrays.asList(tag.getReferences())); >+ } >+ >+ private void handleExceptionTags(List tags, List exceptionNames, >+ CharSequence[] exceptionDescriptions) { >+ if (tags.size() == 0 && containsOnlyNull(exceptionNames)) >+ return; >+ >+ handleBlockTagTitle(PHPDocumentationMessages.JavaDoc2HTMLTextReader_throws_section); >+ >+ for (Iterator iter = tags.iterator(); iter.hasNext();) { >+ PHPDocTag tag = (PHPDocTag) iter.next(); >+ fBuf.append(BlOCK_TAG_ENTRY_START); >+ handleThrowsTag(tag); >+ fBuf.append(BlOCK_TAG_ENTRY_END); >+ } >+ for (int i = 0; i < exceptionDescriptions.length; i++) { >+ CharSequence description = exceptionDescriptions[i]; >+ String name = (String) exceptionNames.get(i); >+ if (name != null) { >+ fBuf.append(BlOCK_TAG_ENTRY_START); >+ // handleLink(Collections.singletonList( >+ // .newSimpleName(name))); >+ if (description != null) { >+ fBuf.append(ScriptElementLabels.CONCAT_STRING); >+ fBuf.append(description); >+ } >+ fBuf.append(BlOCK_TAG_ENTRY_END); >+ } >+ } >+ } >+ >+ private void handleThrowsTag(PHPDocTag tag) { >+ List<SimpleReference> fragments = Arrays.asList(tag.getReferences()); >+ int size = fragments.size(); >+ if (size > 0) { >+ String exceptionName = ""; >+ if (fragments.get(0) instanceof TypeReference) { >+ exceptionName = fragments.get(0).getName().trim(); >+ fBuf.append(exceptionName); >+ } >+ String value = tag.getValue().trim(); >+ String description = value.substring(exceptionName.length()); >+ if (description.length() > 0) { >+ fBuf.append(ScriptElementLabels.CONCAT_STRING); >+ fBuf.append(description.trim()); >+ } >+ } >+ } >+ >+ private void handleParameterTags(List tags, List parameterNames, >+ CharSequence[] parameterTypes, CharSequence[] parameterDescriptions) { >+ if (tags.size() == 0 && containsOnlyNull(parameterNames)) >+ return; >+ >+ handleBlockTagTitle(PHPDocumentationMessages.JavaDoc2HTMLTextReader_parameters_section); >+ >+ for (Iterator iter = tags.iterator(); iter.hasNext();) { >+ PHPDocTag tag = (PHPDocTag) iter.next(); >+ fBuf.append(BlOCK_TAG_ENTRY_START); >+ handleParamTag(tag); >+ fBuf.append(BlOCK_TAG_ENTRY_END); >+ } >+ for (int i = 0; i < parameterDescriptions.length; i++) { >+ CharSequence description = parameterDescriptions[i]; >+ String name = (String) parameterNames.get(i); >+ if (name != null) { >+ fBuf.append(BlOCK_TAG_ENTRY_START); >+ if (parameterTypes[i] != null) { >+ fBuf.append(PARAM_NAME_START); >+ fBuf.append(parameterTypes[i]); >+ fBuf.append(PARAM_NAME_END); >+ } >+ fBuf.append(PARAM_NAME_END); >+ fBuf.append(PARAM_NAME_START); >+ fBuf.append(name); >+ fBuf.append(PARAM_NAME_END); >+ if (description != null) >+ fBuf.append(description); >+ fBuf.append(BlOCK_TAG_ENTRY_END); >+ } >+ } >+ } >+ >+ private void handleParamTag(PHPDocTag tag) { >+ if (tag.getReferences().length == 0) { >+ fBuf.append(tag.getValue()); >+ return; >+ } >+ String parameterName = getParameterInfo(tag, PARAMETER_NAME_TYPE); >+ String parameterType = getParameterInfo(tag, PARAMETER_TYPE_TYPE); >+ String description = getParameterInfo(tag, PARAMETER_DESCRIPTION_TYPE); >+ fBuf.append(BlOCK_TAG_ENTRY_START); >+ if (parameterType != null) { >+ fBuf.append(PARAM_NAME_START); >+ fBuf.append(parameterType); >+ fBuf.append(PARAM_NAME_END); >+ } >+ fBuf.append(PARAM_NAME_START); >+ fBuf.append(parameterName); >+ fBuf.append(PARAM_NAME_END); >+ if (description != null) >+ fBuf.append(description); >+ fBuf.append(BlOCK_TAG_ENTRY_END); >+ } >+ >+ private void handleLinkTag(PHPDocTag tag) { >+ fBuf.append("<a href="); >+ fBuf.append(tag.getValue()); >+ fBuf.append(">").append(tag.getValue()).append("</a>"); >+ } >+ >+ private void handleLink(List fragments) { >+ // int fs = fragments.size(); >+ // if (fs > 0) { >+ // Object first = fragments.get(0); >+ // String refTypeName = null; >+ // String refMemberName = null; >+ // String[] refMethodParamTypes = null; >+ // String[] refMethodParamNames = null; >+ // if (first instanceof Name) { >+ // Name name = (Name) first; >+ // refTypeName = name.getFullyQualifiedName(); >+ // } else if (first instanceof MemberRef) { >+ // MemberRef memberRef = (MemberRef) first; >+ // Name qualifier = memberRef.getQualifier(); >+ // refTypeName = qualifier == null ? "" : qualifier.getFullyQualifiedName(); //$NON-NLS-1$ >+ // refMemberName = memberRef.getName().getIdentifier(); >+ // } else if (first instanceof MethodRef) { >+ // MethodRef methodRef = (MethodRef) first; >+ // Name qualifier = methodRef.getQualifier(); >+ // refTypeName = qualifier == null ? "" : qualifier.getFullyQualifiedName(); //$NON-NLS-1$ >+ // refMemberName = methodRef.getName().getIdentifier(); >+ // List params = methodRef.parameters(); >+ // int ps = params.size(); >+ // refMethodParamTypes = new String[ps]; >+ // refMethodParamNames = new String[ps]; >+ // for (int i = 0; i < ps; i++) { >+ // MethodRefParameter param = (MethodRefParameter) params >+ // .get(i); >+ // refMethodParamTypes[i] = ASTNodes.asString(param.getType()); >+ // SimpleName paramName = param.getName(); >+ // if (paramName != null) >+ // refMethodParamNames[i] = paramName.getIdentifier(); >+ // } >+ // } >+ // >+ // if (refTypeName != null) { >+ // fBuf.append("<a href='"); //$NON-NLS-1$ >+ // try { >+ // String scheme = JavaElementLinks.JAVADOC_SCHEME; >+ // String uri = JavaElementLinks.createURI(scheme, fMember, >+ // refTypeName, refMemberName, refMethodParamTypes); >+ // fBuf.append(uri); >+ // } catch (URISyntaxException e) { >+ // PHPUiPlugin.log(e); >+ // } >+ // fBuf.append("'>"); //$NON-NLS-1$ >+ // if (fs > 1) { >+ // // if (fs == 2 && fragments.get(1) instanceof TextElement) { >+ // // String text= removeLeadingWhitespace(((TextElement) >+ // // fragments.get(1)).getText()); >+ // // if (text.length() != 0) >+ // // handleText(text); >+ // // else >+ // // //throws >+ // // } >+ // handleContentElements(fragments.subList(1, fs)); >+ // } else { >+ // fBuf.append(refTypeName); >+ // if (refMemberName != null) { >+ // if (refTypeName.length() > 0) { >+ // fBuf.append('.'); >+ // } >+ // fBuf.append(refMemberName); >+ // if (refMethodParamTypes != null) { >+ // fBuf.append('('); >+ // for (int i = 0; i < refMethodParamTypes.length; i++) { >+ // String pType = refMethodParamTypes[i]; >+ // fBuf.append(pType); >+ // String pName = refMethodParamNames[i]; >+ // if (pName != null) { >+ // fBuf.append(' ').append(pName); >+ // } >+ // if (i < refMethodParamTypes.length - 1) { >+ // fBuf.append(", "); //$NON-NLS-1$ >+ // } >+ // } >+ // fBuf.append(')'); >+ // } >+ // } >+ // } >+ // fBuf.append("</a>"); //$NON-NLS-1$ >+ // } else { >+ // handleContentElements(fragments); >+ // } >+ // } >+ } >+ >+ private boolean containsOnlyNull(List parameterNames) { >+ for (Iterator iter = parameterNames.iterator(); iter.hasNext();) { >+ if (iter.next() != null) >+ return false; >+ } >+ return true; >+ } >+ >+ private String getParameterInfo(PHPDocBlock phpDoc, String paramName, >+ int infoType) { >+ for (PHPDocTag tag : phpDoc.getTags(PHPDocTag.PARAM)) { >+ String name = getParameterInfo(tag, PARAMETER_NAME_TYPE); >+ if (name.equals(paramName)) { >+ return getParameterInfo(tag, infoType); >+ } >+ continue; >+ } >+ return null; >+ } >+ >+ private String getParameterInfo(PHPDocTag tag, int infoType) { >+ if (tag.getTagKind() != PHPDocTag.PARAM) { >+ return null; >+ } >+ SimpleReference typeRef = null; >+ SimpleReference variableRef = null; >+ String value = tag.getValue(); >+ if (tag.getReferences().length != 2) { >+ return null; >+ } >+ for (SimpleReference reference : tag.getReferences()) { >+ if (reference instanceof TypeReference) { >+ typeRef = reference; >+ } else if (reference instanceof VariableReference) { >+ variableRef = reference; >+ } >+ } >+ if (infoType == PARAMETER_DESCRIPTION_TYPE) { >+ int typeRefIndex = value.indexOf(typeRef.getName()); >+ int variableRefIndex = value.indexOf(variableRef.getName()); >+ int lastRefIndex = typeRefIndex > variableRefIndex ? typeRefIndex >+ + typeRef.getName().length() : variableRefIndex >+ + variableRef.getName().length(); >+ return value.substring(lastRefIndex).trim(); >+ } else if (infoType == PARAMETER_TYPE_TYPE) { >+ return typeRef.getName(); >+ } else if (infoType == PARAMETER_NAME_TYPE) { >+ return variableRef.getName(); >+ } >+ return null; >+ } >+ >+ private boolean appendBuiltinDoc(IMember element, StringBuffer buf) { >+ String builtinDoc = BuiltinDoc.getString(element.getElementName()); >+ if (builtinDoc.length() > 0) { >+ // String fileName = getFileName(element); >+ // >+ // // append the file name >+ // appendDefinitionRow(FIELD_LOCATION, fileName, buf); >+ // >+ // // append the class name if it exists >+ // IType declaringType = element.getDeclaringType(); >+ // appendTypeInfoRow(declaringType, buf); >+ >+ buf.append(builtinDoc); >+ return true; >+ } >+ return false; >+ } >+ >+} >Index: src/org/eclipse/php/internal/ui/documentation/PHPDocumentationMessages.java >=================================================================== >RCS file: src/org/eclipse/php/internal/ui/documentation/PHPDocumentationMessages.java >diff -N src/org/eclipse/php/internal/ui/documentation/PHPDocumentationMessages.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/php/internal/ui/documentation/PHPDocumentationMessages.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,33 @@ >+package org.eclipse.php.internal.ui.documentation; >+ >+import org.eclipse.osgi.util.NLS; >+ >+/** >+ * Helper class to get NLSed messages. >+ */ >+final class PHPDocumentationMessages extends NLS { >+ >+ private static final String BUNDLE_NAME = PHPDocumentationMessages.class >+ .getName(); >+ >+ private PHPDocumentationMessages() { >+ // Do not instantiate >+ } >+ >+ public static String CompletionEvaluator_default_package; >+ public static String JavaDoc2HTMLTextReader_parameters_section; >+ public static String JavaDoc2HTMLTextReader_returns_section; >+ public static String JavaDoc2HTMLTextReader_throws_section; >+ public static String JavaDoc2HTMLTextReader_author_section; >+ public static String JavaDoc2HTMLTextReader_deprecated_section; >+ public static String JavaDoc2HTMLTextReader_method_in_type; >+ public static String JavaDoc2HTMLTextReader_overrides_section; >+ public static String JavaDoc2HTMLTextReader_see_section; >+ public static String JavaDoc2HTMLTextReader_since_section; >+ public static String JavaDoc2HTMLTextReader_specified_by_section; >+ public static String JavaDoc2HTMLTextReader_version_section; >+ >+ static { >+ NLS.initializeMessages(BUNDLE_NAME, PHPDocumentationMessages.class); >+ } >+} >\ No newline at end of file >Index: src/org/eclipse/php/internal/ui/documentation/PHPDocumentationMessages.properties >=================================================================== >RCS file: src/org/eclipse/php/internal/ui/documentation/PHPDocumentationMessages.properties >diff -N src/org/eclipse/php/internal/ui/documentation/PHPDocumentationMessages.properties >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/php/internal/ui/documentation/PHPDocumentationMessages.properties 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,24 @@ >+############################################################################### >+# Copyright (c) 2000, 2008 IBM Corporation and others. >+# All rights reserved. This program and the accompanying materials >+# are made available under the terms of the Eclipse Public License v1.0 >+# which accompanies this distribution, and is available at >+# http://www.eclipse.org/legal/epl-v10.html >+# >+# Contributors: >+# IBM Corporation - initial API and implementation >+############################################################################### >+ >+CompletionEvaluator_default_package=(default package) >+ >+JavaDoc2HTMLTextReader_parameters_section=Parameters: >+JavaDoc2HTMLTextReader_returns_section=Returns: >+JavaDoc2HTMLTextReader_throws_section=Throws: >+JavaDoc2HTMLTextReader_author_section=Author: >+JavaDoc2HTMLTextReader_deprecated_section=Deprecated. >+JavaDoc2HTMLTextReader_method_in_type={0} in {1} >+JavaDoc2HTMLTextReader_overrides_section=Overrides: >+JavaDoc2HTMLTextReader_see_section=See Also: >+JavaDoc2HTMLTextReader_since_section=Since: >+JavaDoc2HTMLTextReader_specified_by_section=Specified by: >+JavaDoc2HTMLTextReader_version_section=Version: >Index: src/org/eclipse/php/internal/ui/editor/hover/AbstractPHPEditorTextHover.java >=================================================================== >RCS file: src/org/eclipse/php/internal/ui/editor/hover/AbstractPHPEditorTextHover.java >diff -N src/org/eclipse/php/internal/ui/editor/hover/AbstractPHPEditorTextHover.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/php/internal/ui/editor/hover/AbstractPHPEditorTextHover.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,108 @@ >+package org.eclipse.php.internal.ui.editor.hover; >+ >+import org.eclipse.core.resources.IStorage; >+import org.eclipse.dltk.core.ICodeAssist; >+import org.eclipse.dltk.core.IModelElement; >+import org.eclipse.dltk.core.ModelException; >+import org.eclipse.dltk.internal.core.ExternalSourceModule; >+import org.eclipse.dltk.internal.ui.editor.ExternalStorageEditorInput; >+import org.eclipse.dltk.internal.ui.text.hover.AbstractScriptEditorTextHover; >+import org.eclipse.dltk.ui.DLTKUIPlugin; >+import org.eclipse.dltk.ui.IWorkingCopyManager; >+import org.eclipse.jface.text.*; >+import org.eclipse.swt.widgets.Shell; >+import org.eclipse.ui.IEditorInput; >+import org.eclipse.ui.IEditorPart; >+import org.eclipse.ui.editors.text.EditorsUI; >+ >+public class AbstractPHPEditorTextHover extends AbstractScriptEditorTextHover >+ implements ITextHoverExtension2 { >+ >+ public Object getHoverInfo2(ITextViewer textViewer, IRegion hoverRegion) { >+ return getHoverInfo(textViewer, hoverRegion); >+ } >+ >+ /* >+ * @see ITextHoverExtension#getHoverControlCreator() >+ * >+ * @since 3.0 >+ */ >+ public IInformationControlCreator getHoverControlCreator() { >+ return new IInformationControlCreator() { >+ public IInformationControl createInformationControl(Shell parent) { >+ return new DefaultInformationControl(parent, EditorsUI >+ .getTooltipAffordanceString()); >+ } >+ }; >+ } >+ >+ /* >+ * @seeorg.eclipse.jface.text.ITextHoverExtension2# >+ * getInformationPresenterControlCreator() >+ * >+ * @since 3.4 >+ */ >+ public IInformationControlCreator getInformationPresenterControlCreator() { >+ return new IInformationControlCreator() { >+ public IInformationControl createInformationControl(Shell shell) { >+ return new DefaultInformationControl(shell, true); >+ } >+ }; >+ } >+ >+ protected ICodeAssist getCodeAssist() { >+ IEditorPart editor = getEditor(); >+ if (editor != null) { >+ IEditorInput input = editor.getEditorInput(); >+ >+ if (input instanceof ExternalStorageEditorInput) { >+ ExternalStorageEditorInput external = (ExternalStorageEditorInput) input; >+ IStorage storage = external.getStorage(); >+ if (storage != null) { >+ if (storage instanceof ExternalSourceModule) { >+ ExternalSourceModule externalSourceModule = (ExternalSourceModule) storage; >+ return externalSourceModule; >+ } >+ } >+ } >+ >+ IWorkingCopyManager manager = DLTKUIPlugin.getDefault() >+ .getWorkingCopyManager(); >+ return manager.getWorkingCopy(input, false); >+ } >+ >+ return null; >+ } >+ >+ /** >+ * Returns the Java elements at the given hover region. >+ * >+ * @param textViewer >+ * the text viewer >+ * @param hoverRegion >+ * the hover region >+ * @return the array with the Java elements or <code>null</code> >+ * @since 3.4 >+ */ >+ protected IModelElement[] getElementsAt(ITextViewer textViewer, >+ IRegion hoverRegion) { >+ /* >+ * The region should be a word region an not of length 0. This check is >+ * needed because codeSelect(...) also finds the Java element if the >+ * offset is behind the word. >+ */ >+ if (hoverRegion.getLength() == 0) >+ return null; >+ >+ ICodeAssist resolve = getCodeAssist(); >+ if (resolve != null) { >+ try { >+ return resolve.codeSelect(hoverRegion.getOffset(), hoverRegion >+ .getLength()); >+ } catch (ModelException x) { >+ return null; >+ } >+ } >+ return null; >+ } >+} >Index: src/org/eclipse/php/internal/ui/editor/hover/BestMatchHover.java >=================================================================== >RCS file: /cvsroot/tools/org.eclipse.pdt/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/editor/hover/BestMatchHover.java,v >retrieving revision 1.7 >diff -u -r1.7 BestMatchHover.java >--- src/org/eclipse/php/internal/ui/editor/hover/BestMatchHover.java 18 Oct 2009 09:28:35 -0000 1.7 >+++ src/org/eclipse/php/internal/ui/editor/hover/BestMatchHover.java 5 May 2010 14:28:44 -0000 >@@ -15,7 +15,6 @@ > import java.util.Iterator; > import java.util.List; > >-import org.eclipse.dltk.internal.ui.text.hover.AbstractScriptEditorTextHover; > import org.eclipse.jface.preference.IPreferenceStore; > import org.eclipse.jface.text.*; > import org.eclipse.jface.text.information.IInformationProviderExtension2; >@@ -26,7 +25,7 @@ > import org.eclipse.php.ui.editor.hover.IPHPTextHover; > import org.eclipse.ui.IEditorPart; > >-public class BestMatchHover extends AbstractScriptEditorTextHover implements >+public class BestMatchHover extends AbstractPHPEditorTextHover implements > IPHPTextHover, ITextHoverExtension, IInformationProviderExtension2 { > > private List<PHPEditorTextHoverDescriptor> fTextHoverSpecifications; >@@ -113,6 +112,42 @@ > } > > /* >+ * @see >+ * org.eclipse.jface.text.ITextHoverExtension2#getHoverInfo2(org.eclipse >+ * .jface.text.ITextViewer, org.eclipse.jface.text.IRegion) >+ */ >+ public Object getHoverInfo2(ITextViewer textViewer, IRegion hoverRegion) { >+ >+ checkTextHovers(); >+ fBestHover = null; >+ >+ if (fInstantiatedTextHovers == null) >+ return null; >+ >+ for (Iterator iterator = fInstantiatedTextHovers.iterator(); iterator >+ .hasNext();) { >+ ITextHover hover = (ITextHover) iterator.next(); >+ >+ if (hover instanceof ITextHoverExtension2) { >+ Object info = ((ITextHoverExtension2) hover).getHoverInfo2( >+ textViewer, hoverRegion); >+ if (info != null) { >+ fBestHover = hover; >+ return info; >+ } >+ } else { >+ String s = hover.getHoverInfo(textViewer, hoverRegion); >+ if (s != null && s.trim().length() > 0) { >+ fBestHover = hover; >+ return s; >+ } >+ } >+ } >+ >+ return null; >+ } >+ >+ /* > * @see org.eclipse.jface.text.ITextHoverExtension#getHoverControlCreator() > * > * @since 3.0 >Index: src/org/eclipse/php/internal/ui/editor/hover/PHPDocumentationBrowserInformationControlInput.java >=================================================================== >RCS file: src/org/eclipse/php/internal/ui/editor/hover/PHPDocumentationBrowserInformationControlInput.java >diff -N src/org/eclipse/php/internal/ui/editor/hover/PHPDocumentationBrowserInformationControlInput.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/php/internal/ui/editor/hover/PHPDocumentationBrowserInformationControlInput.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,81 @@ >+package org.eclipse.php.internal.ui.editor.hover; >+ >+import org.eclipse.core.runtime.Assert; >+import org.eclipse.dltk.core.IModelElement; >+import org.eclipse.jface.internal.text.html.BrowserInformationControlInput; >+ >+/** >+ * Browser input for Javadoc hover. >+ * >+ * @since 3.4 >+ */ >+public class PHPDocumentationBrowserInformationControlInput extends >+ BrowserInformationControlInput { >+ >+ private final IModelElement fElement; >+ private final String fHtml; >+ private final int fLeadingImageWidth; >+ >+ /** >+ * Creates a new browser information control input. >+ * >+ * @param previous >+ * previous input, or <code>null</code> if none available >+ * @param element >+ * the element, or <code>null</code> if none available >+ * @param html >+ * HTML contents, must not be null >+ * @param leadingImageWidth >+ * the indent required for the element image >+ */ >+ public PHPDocumentationBrowserInformationControlInput( >+ PHPDocumentationBrowserInformationControlInput previous, >+ IModelElement element, String html, int leadingImageWidth) { >+ super(previous); >+ Assert.isNotNull(html); >+ fElement = element; >+ fHtml = html; >+ fLeadingImageWidth = leadingImageWidth; >+ } >+ >+ /* >+ * @seeorg.eclipse.jface.internal.text.html.BrowserInformationControlInput# >+ * getLeadingImageWidth() >+ * >+ * @since 3.4 >+ */ >+ public int getLeadingImageWidth() { >+ return fLeadingImageWidth; >+ } >+ >+ /** >+ * Returns the Java element. >+ * >+ * @return the element or <code>null</code> if none available >+ */ >+ public IModelElement getElement() { >+ return fElement; >+ } >+ >+ /* >+ * @see org.eclipse.jface.internal.text.html.BrowserInput#getHtml() >+ */ >+ public String getHtml() { >+ return fHtml; >+ } >+ >+ /* >+ * @see org.eclipse.jdt.internal.ui.infoviews.BrowserInput#getInputElement() >+ */ >+ public Object getInputElement() { >+ return fElement == null ? (Object) fHtml : fElement; >+ } >+ >+ /* >+ * @see org.eclipse.jdt.internal.ui.infoviews.BrowserInput#getInputName() >+ */ >+ public String getInputName() { >+ return fElement == null ? "" : fElement.getElementName(); //$NON-NLS-1$ >+ } >+ >+} >Index: src/org/eclipse/php/internal/ui/editor/hover/PHPDocumentationHover.java >=================================================================== >RCS file: /cvsroot/tools/org.eclipse.pdt/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/editor/hover/PHPDocumentationHover.java,v >retrieving revision 1.6 >diff -u -r1.6 PHPDocumentationHover.java >--- src/org/eclipse/php/internal/ui/editor/hover/PHPDocumentationHover.java 6 Apr 2010 11:35:32 -0000 1.6 >+++ src/org/eclipse/php/internal/ui/editor/hover/PHPDocumentationHover.java 5 May 2010 14:28:46 -0000 >@@ -11,150 +11,593 @@ > *******************************************************************************/ > package org.eclipse.php.internal.ui.editor.hover; > >-import java.io.Reader; >-import java.io.StringReader; >+import java.io.*; >+import java.net.URL; > >-import org.eclipse.core.resources.IStorage; >-import org.eclipse.dltk.core.ICodeAssist; >-import org.eclipse.dltk.core.IMember; >-import org.eclipse.dltk.core.IModelElement; >-import org.eclipse.dltk.core.ModelException; >-import org.eclipse.dltk.internal.core.ExternalSourceModule; >-import org.eclipse.dltk.internal.ui.editor.ExternalStorageEditorInput; >-import org.eclipse.dltk.internal.ui.text.HTMLPrinter; >-import org.eclipse.dltk.internal.ui.text.hover.DocumentationHover; >-import org.eclipse.dltk.internal.ui.text.hover.ScriptHoverMessages; >-import org.eclipse.dltk.ui.DLTKUIPlugin; >-import org.eclipse.dltk.ui.IWorkingCopyManager; >+import org.eclipse.core.runtime.Platform; >+import org.eclipse.dltk.core.*; >+import org.eclipse.dltk.internal.ui.editor.EditorUtility; >+import org.eclipse.dltk.ui.DLTKPluginImages; >+import org.eclipse.dltk.ui.PreferenceConstants; > import org.eclipse.dltk.ui.ScriptElementLabels; >-import org.eclipse.dltk.ui.documentation.ScriptDocumentationAccess; >-import org.eclipse.dltk.utils.TextUtils; >+import org.eclipse.dltk.ui.viewsupport.BasicElementLabels; >+import org.eclipse.jface.action.Action; >+import org.eclipse.jface.action.ToolBarManager; >+import org.eclipse.jface.internal.text.html.BrowserInformationControl; >+import org.eclipse.jface.internal.text.html.BrowserInformationControlInput; >+import org.eclipse.jface.internal.text.html.BrowserInput; >+import org.eclipse.jface.internal.text.html.HTMLPrinter; >+import org.eclipse.jface.resource.JFaceResources; >+import org.eclipse.jface.text.*; >+import org.eclipse.jface.text.IRegion; >+import org.eclipse.php.core.compiler.PHPFlags; >+import org.eclipse.php.internal.core.ast.nodes.*; >+import org.eclipse.php.internal.core.corext.dom.NodeFinder; >+import org.eclipse.php.internal.ui.PHPUiPlugin; >+import org.eclipse.php.internal.ui.documentation.PHPDocumentationContentAccess; >+import org.eclipse.php.internal.ui.util.Messages; >+import org.eclipse.php.ui.editor.SharedASTProvider; > import org.eclipse.php.ui.editor.hover.IHoverMessageDecorator; > import org.eclipse.php.ui.editor.hover.IPHPTextHover; >-import org.eclipse.ui.IEditorInput; >+import org.eclipse.swt.SWT; >+import org.eclipse.swt.graphics.FontData; >+import org.eclipse.swt.widgets.Shell; > import org.eclipse.ui.IEditorPart; >+import org.eclipse.ui.ISharedImages; >+import org.eclipse.ui.PartInitException; >+import org.eclipse.ui.PlatformUI; >+import org.eclipse.ui.editors.text.EditorsUI; >+import org.osgi.framework.Bundle; > >-public class PHPDocumentationHover extends DocumentationHover implements >+@SuppressWarnings("restriction") >+public class PHPDocumentationHover extends AbstractPHPEditorTextHover implements > IPHPTextHover { > >- private final long LABEL_FLAGS = // ScriptElementLabels.ALL_FULLY_QUALIFIED >- ScriptElementLabels.M_APP_TYPE_PARAMETERS >+ public IHoverMessageDecorator getMessageDecorator() { >+ return null; >+ } >+ >+ /** >+ * Action to go back to the previous input in the hover control. >+ * >+ * @since 3.4 >+ */ >+ private static final class BackAction extends Action { >+ private final BrowserInformationControl fInfoControl; >+ >+ public BackAction(BrowserInformationControl infoControl) { >+ fInfoControl = infoControl; >+ setText(PHPHoverMessages.JavadocHover_back); >+ ISharedImages images = PlatformUI.getWorkbench().getSharedImages(); >+ setImageDescriptor(images >+ .getImageDescriptor(ISharedImages.IMG_TOOL_BACK)); >+ setDisabledImageDescriptor(images >+ .getImageDescriptor(ISharedImages.IMG_TOOL_BACK_DISABLED)); >+ >+ update(); >+ } >+ >+ public void run() { >+ BrowserInformationControlInput previous = (BrowserInformationControlInput) fInfoControl >+ .getInput().getPrevious(); >+ if (previous != null) { >+ fInfoControl.setInput(previous); >+ } >+ } >+ >+ public void update() { >+ BrowserInformationControlInput current = fInfoControl.getInput(); >+ >+ if (current != null && current.getPrevious() != null) { >+ BrowserInput previous = current.getPrevious(); >+ setToolTipText(Messages.format( >+ PHPHoverMessages.JavadocHover_back_toElement_toolTip, >+ BasicElementLabels.getJavaElementName(previous >+ .getInputName()))); >+ setEnabled(true); >+ } else { >+ setToolTipText(PHPHoverMessages.JavadocHover_back); >+ setEnabled(false); >+ } >+ } >+ } >+ >+ /** >+ * Action to go forward to the next input in the hover control. >+ * >+ * @since 3.4 >+ */ >+ private static final class ForwardAction extends Action { >+ private final BrowserInformationControl fInfoControl; >+ >+ public ForwardAction(BrowserInformationControl infoControl) { >+ fInfoControl = infoControl; >+ setText(PHPHoverMessages.JavadocHover_forward); >+ ISharedImages images = PlatformUI.getWorkbench().getSharedImages(); >+ setImageDescriptor(images >+ .getImageDescriptor(ISharedImages.IMG_TOOL_FORWARD)); >+ setDisabledImageDescriptor(images >+ .getImageDescriptor(ISharedImages.IMG_TOOL_FORWARD_DISABLED)); >+ >+ update(); >+ } >+ >+ public void run() { >+ BrowserInformationControlInput next = (BrowserInformationControlInput) fInfoControl >+ .getInput().getNext(); >+ if (next != null) { >+ fInfoControl.setInput(next); >+ } >+ } >+ >+ public void update() { >+ BrowserInformationControlInput current = fInfoControl.getInput(); >+ >+ if (current != null && current.getNext() != null) { >+ setToolTipText(Messages >+ .format( >+ PHPHoverMessages.JavadocHover_forward_toElement_toolTip, >+ BasicElementLabels.getJavaElementName(current >+ .getNext().getInputName()))); >+ setEnabled(true); >+ } else { >+ setToolTipText(PHPHoverMessages.JavadocHover_forward_toolTip); >+ setEnabled(false); >+ } >+ } >+ } >+ >+ /** >+ * Action that opens the current hover input element. >+ * >+ * @since 3.4 >+ */ >+ private static final class OpenDeclarationAction extends Action { >+ private final BrowserInformationControl fInfoControl; >+ >+ public OpenDeclarationAction(BrowserInformationControl infoControl) { >+ fInfoControl = infoControl; >+ setText(PHPHoverMessages.JavadocHover_openDeclaration); >+ DLTKPluginImages.setLocalImageDescriptors(this, "goto_input.gif"); //$NON-NLS-1$ //TODO: better images >+ } >+ >+ /* >+ * @see org.eclipse.jface.action.Action#run() >+ */ >+ public void run() { >+ PHPDocumentationBrowserInformationControlInput infoInput = (PHPDocumentationBrowserInformationControlInput) fInfoControl >+ .getInput(); // TODO: check cast >+ fInfoControl.notifyDelayedInputChange(null); >+ fInfoControl.dispose(); // FIXME: should have protocol to hide, >+ // rather than dispose >+ >+ try { >+ // FIXME: add hover location to editor navigation history? >+ IEditorPart editor = EditorUtility.openInEditor(infoInput >+ .getElement(), true); >+ EditorUtility.revealInEditor(editor, infoInput.getElement()); >+ } catch (PartInitException e) { >+ PHPUiPlugin.log(e); >+ } catch (ModelException e) { >+ PHPUiPlugin.log(e); >+ } >+ } >+ } >+ >+ /** >+ * Presenter control creator. >+ * >+ * @since 3.3 >+ */ >+ public static final class PresenterControlCreator extends >+ AbstractReusableInformationControlCreator { >+ >+ /* >+ * @seeorg.eclipse.jdt.internal.ui.text.java.hover. >+ * AbstractReusableInformationControlCreator >+ * #doCreateInformationControl(org.eclipse.swt.widgets.Shell) >+ */ >+ public IInformationControl doCreateInformationControl(Shell parent) { >+ if (BrowserInformationControl.isAvailable(parent)) { >+ ToolBarManager tbm = new ToolBarManager(SWT.FLAT); >+ String font = PreferenceConstants.APPEARANCE_DOCUMENTATION_FONT; >+ BrowserInformationControl iControl = new BrowserInformationControl( >+ parent, font, tbm); >+ >+ final BackAction backAction = new BackAction(iControl); >+ backAction.setEnabled(false); >+ tbm.add(backAction); >+ final ForwardAction forwardAction = new ForwardAction(iControl); >+ tbm.add(forwardAction); >+ forwardAction.setEnabled(false); >+ >+ final OpenDeclarationAction openDeclarationAction = new OpenDeclarationAction( >+ iControl); >+ tbm.add(openDeclarationAction); >+ >+ // final SimpleSelectionProvider selectionProvider = new >+ // SimpleSelectionProvider(); >+ // OpenExternalBrowserAction openExternalJavadocAction = new >+ // OpenExternalBrowserAction( >+ // parent.getDisplay(), selectionProvider); >+ // selectionProvider >+ // .addSelectionChangedListener(openExternalJavadocAction); >+ // selectionProvider.setSelection(new StructuredSelection()); >+ // tbm.add(openExternalJavadocAction); >+ >+ IInputChangedListener inputChangeListener = new IInputChangedListener() { >+ public void inputChanged(Object newInput) { >+ backAction.update(); >+ forwardAction.update(); >+ if (newInput == null) { >+ } else if (newInput instanceof BrowserInformationControlInput) { >+ BrowserInformationControlInput input = (BrowserInformationControlInput) newInput; >+ Object inputElement = input.getInputElement(); >+ boolean isJavaElementInput = inputElement instanceof IModelElement; >+ openDeclarationAction >+ .setEnabled(isJavaElementInput); >+ } >+ } >+ }; >+ iControl.addInputChangeListener(inputChangeListener); >+ >+ tbm.update(true); >+ >+ return iControl; >+ >+ } else { >+ return new DefaultInformationControl(parent, true); >+ } >+ } >+ } >+ >+ /** >+ * Hover control creator. >+ * >+ * @since 3.3 >+ */ >+ public static final class HoverControlCreator extends >+ AbstractReusableInformationControlCreator { >+ /** >+ * The information presenter control creator. >+ * >+ * @since 3.4 >+ */ >+ private final IInformationControlCreator fInformationPresenterControlCreator; >+ /** >+ * <code>true</code> to use the additional info affordance, >+ * <code>false</code> to use the hover affordance. >+ */ >+ private final boolean fAdditionalInfoAffordance; >+ >+ /** >+ * @param informationPresenterControlCreator >+ * control creator for enriched hover >+ * @since 3.4 >+ */ >+ public HoverControlCreator( >+ IInformationControlCreator informationPresenterControlCreator) { >+ this(informationPresenterControlCreator, false); >+ } >+ >+ /** >+ * @param informationPresenterControlCreator >+ * control creator for enriched hover >+ * @param additionalInfoAffordance >+ * <code>true</code> to use the additional info affordance, >+ * <code>false</code> to use the hover affordance >+ * @since 3.4 >+ */ >+ public HoverControlCreator( >+ IInformationControlCreator informationPresenterControlCreator, >+ boolean additionalInfoAffordance) { >+ fInformationPresenterControlCreator = informationPresenterControlCreator; >+ fAdditionalInfoAffordance = additionalInfoAffordance; >+ } >+ >+ /* >+ * @seeorg.eclipse.jdt.internal.ui.text.java.hover. >+ * AbstractReusableInformationControlCreator >+ * #doCreateInformationControl(org.eclipse.swt.widgets.Shell) >+ */ >+ public IInformationControl doCreateInformationControl(Shell parent) { >+ String tooltipAffordanceString = EditorsUI >+ .getTooltipAffordanceString(); >+ if (BrowserInformationControl.isAvailable(parent)) { >+ String font = PreferenceConstants.APPEARANCE_DOCUMENTATION_FONT; >+ BrowserInformationControl iControl = new BrowserInformationControl( >+ parent, font, tooltipAffordanceString) { >+ /* >+ * @see >+ * org.eclipse.jface.text.IInformationControlExtension5# >+ * getInformationPresenterControlCreator() >+ */ >+ public IInformationControlCreator getInformationPresenterControlCreator() { >+ return fInformationPresenterControlCreator; >+ } >+ }; >+ return iControl; >+ } else { >+ return new DefaultInformationControl(parent, >+ tooltipAffordanceString); >+ } >+ } >+ >+ /* >+ * @seeorg.eclipse.jdt.internal.ui.text.java.hover. >+ * AbstractReusableInformationControlCreator >+ * #canReuse(org.eclipse.jface.text.IInformationControl) >+ */ >+ public boolean canReuse(IInformationControl control) { >+ if (!super.canReuse(control)) >+ return false; >+ >+ if (control instanceof IInformationControlExtension4) { >+ String tooltipAffordanceString = EditorsUI >+ .getTooltipAffordanceString(); >+ ((IInformationControlExtension4) control) >+ .setStatusText(tooltipAffordanceString); >+ } >+ >+ return true; >+ } >+ } >+ >+ private static final long LABEL_FLAGS = ScriptElementLabels.ALL_FULLY_QUALIFIED >+ | ScriptElementLabels.M_PRE_RETURNTYPE >+ | ScriptElementLabels.M_PARAMETER_TYPES > | ScriptElementLabels.M_PARAMETER_NAMES > | ScriptElementLabels.M_EXCEPTIONS > | ScriptElementLabels.F_PRE_TYPE_SIGNATURE > | ScriptElementLabels.M_PRE_TYPE_PARAMETERS > | ScriptElementLabels.T_TYPE_PARAMETERS > | ScriptElementLabels.USE_RESOLVED; >- private final long LOCAL_VARIABLE_FLAGS = LABEL_FLAGS >+ private static final long LOCAL_VARIABLE_FLAGS = LABEL_FLAGS > & ~ScriptElementLabels.F_FULLY_QUALIFIED > | ScriptElementLabels.F_POST_QUALIFIED; > >- public IHoverMessageDecorator getMessageDecorator() { >- return null; >+ /** >+ * The style sheet (css). >+ * >+ * @since 3.4 >+ */ >+ private static String fgStyleSheet; >+ >+ /** >+ * The hover control creator. >+ * >+ * @since 3.2 >+ */ >+ private IInformationControlCreator fHoverControlCreator; >+ /** >+ * The presentation control creator. >+ * >+ * @since 3.2 >+ */ >+ private IInformationControlCreator fPresenterControlCreator; >+ >+ /* >+ * @seeorg.eclipse.jface.text.ITextHoverExtension2# >+ * getInformationPresenterControlCreator() >+ * >+ * @since 3.1 >+ */ >+ public IInformationControlCreator getInformationPresenterControlCreator() { >+ if (fPresenterControlCreator == null) >+ fPresenterControlCreator = new PresenterControlCreator(); >+ return fPresenterControlCreator; > } > >- protected ICodeAssist getCodeAssist() { >- IEditorPart editor = getEditor(); >- if (editor != null) { >- IEditorInput input = editor.getEditorInput(); >- >- if (input instanceof ExternalStorageEditorInput) { >- ExternalStorageEditorInput external = (ExternalStorageEditorInput) input; >- IStorage storage = external.getStorage(); >- if (storage != null) { >- if (storage instanceof ExternalSourceModule) { >- ExternalSourceModule externalSourceModule = (ExternalSourceModule) storage; >- return externalSourceModule; >- } >- } >- } >+ /* >+ * @see ITextHoverExtension#getHoverControlCreator() >+ * >+ * @since 3.2 >+ */ >+ public IInformationControlCreator getHoverControlCreator() { >+ if (fHoverControlCreator == null) >+ fHoverControlCreator = new HoverControlCreator( >+ getInformationPresenterControlCreator()); >+ return fHoverControlCreator; >+ } > >- IWorkingCopyManager manager = DLTKUIPlugin.getDefault() >- .getWorkingCopyManager(); >- return manager.getWorkingCopy(input, false); >- } >+ // private static void addLinkListener(final BrowserInformationControl >+ // control) { >+ // control.addLocationListener(JavaElementLinks >+ // .createLocationListener(new JavaElementLinks.ILinkHandler() { >+ // /* >+ // * (non-Javadoc) >+ // * >+ // * @see >+ // * org.eclipse.jdt.internal.ui.viewsupport.JavaElementLinks >+ // * .ILinkHandler >+ // * #handleJavadocViewLink(org.eclipse.jdt.core. >+ // * IModelElement) >+ // */ >+ // public void handleJavadocViewLink(IModelElement linkTarget) { >+ // control.notifyDelayedInputChange(null); >+ // control.setVisible(false); >+ // control.dispose(); // FIXME: should have protocol to >+ // // hide, rather than dispose >+ // try { >+ // JavadocView view = (JavadocView) PHPUiPlugin >+ // .getActivePage().showView( >+ // JavaUI.ID_JAVADOC_VIEW); >+ // view.setInput(linkTarget); >+ // } catch (PartInitException e) { >+ // PHPUiPlugin.log(e); >+ // } >+ // } >+ // >+ // /* >+ // * (non-Javadoc) >+ // * >+ // * @see >+ // * org.eclipse.jdt.internal.ui.viewsupport.JavaElementLinks >+ // * .ILinkHandler >+ // * #handleInlineJavadocLink(org.eclipse.jdt.core >+ // * .IModelElement) >+ // */ >+ // public void handleInlineJavadocLink(IModelElement linkTarget) { >+ // PHPDocumentationBrowserInformationControlInput hoverInfo = getHoverInfo( >+ // new IModelElement[] { linkTarget }, null, >+ // (PHPDocumentationBrowserInformationControlInput) control >+ // .getInput()); >+ // if (control.hasDelayedInputChangeListener()) >+ // control.notifyDelayedInputChange(hoverInfo); >+ // else >+ // control.setInput(hoverInfo); >+ // } >+ // >+ // /* >+ // * (non-Javadoc) >+ // * >+ // * @see >+ // * org.eclipse.jdt.internal.ui.viewsupport.JavaElementLinks >+ // * .ILinkHandler >+ // * #handleDeclarationLink(org.eclipse.jdt.core. >+ // * IModelElement) >+ // */ >+ // public void handleDeclarationLink(IModelElement linkTarget) { >+ // control.notifyDelayedInputChange(null); >+ // control.dispose(); // FIXME: should have protocol to >+ // // hide, rather than dispose >+ // try { >+ // // FIXME: add hover location to editor navigation >+ // // history? >+ // JavaUI.openInEditor(linkTarget); >+ // } catch (PartInitException e) { >+ // PHPUiPlugin.log(e); >+ // } catch (ModelException e) { >+ // PHPUiPlugin.log(e); >+ // } >+ // } >+ // >+ // /* >+ // * (non-Javadoc) >+ // * >+ // * @see >+ // * org.eclipse.jdt.internal.ui.viewsupport.JavaElementLinks >+ // * .ILinkHandler#handleExternalLink(java.net.URL, >+ // * org.eclipse.swt.widgets.Display) >+ // */ >+ // public boolean handleExternalLink(URL url, Display display) { >+ // control.notifyDelayedInputChange(null); >+ // control.dispose(); // FIXME: should have protocol to >+ // // hide, rather than dispose >+ // >+ // // open external links in real browser: >+ // OpenBrowserUtil.open(url, display, ""); //$NON-NLS-1$ >+ // >+ // return true; >+ // } >+ // >+ // public void handleTextSet() { >+ // } >+ // })); >+ // } >+ >+ /** >+ * @deprecated see >+ * {@link org.eclipse.jface.text.ITextHover#getHoverInfo(ITextViewer, IRegion)} >+ */ >+ public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) { >+ PHPDocumentationBrowserInformationControlInput info = (PHPDocumentationBrowserInformationControlInput) getHoverInfo2( >+ textViewer, hoverRegion); >+ return info != null ? info.getHtml() : null; >+ } > >- return null; >+ /* >+ * @see >+ * org.eclipse.jface.text.ITextHoverExtension2#getHoverInfo2(org.eclipse >+ * .jface.text.ITextViewer, org.eclipse.jface.text.IRegion) >+ */ >+ public Object getHoverInfo2(ITextViewer textViewer, IRegion hoverRegion) { >+ return internalGetHoverInfo(textViewer, hoverRegion); > } > >- @Override >- protected String getHoverInfo(String nature, IModelElement[] result) { >- StringBuffer buffer = new StringBuffer(); >- int nResults = result.length; >- if (nResults == 0) >+ private PHPDocumentationBrowserInformationControlInput internalGetHoverInfo( >+ ITextViewer textViewer, IRegion hoverRegion) { >+ IModelElement[] elements = getElementsAt(textViewer, hoverRegion); >+ if (elements == null || elements.length == 0) > return null; > >+ String constantValue; >+ if (elements.length == 1 >+ && elements[0].getElementType() == IModelElement.FIELD) { >+ constantValue = getConstantValue((IField) elements[0], hoverRegion); >+ if (constantValue != null) >+ constantValue = HTMLPrinter.convertToHTMLContent(constantValue); >+ } else { >+ constantValue = null; >+ } >+ >+ return getHoverInfo(elements, constantValue, null); >+ } >+ >+ /** >+ * Computes the hover info. >+ * >+ * @param elements >+ * the resolved elements >+ * @param constantValue >+ * a constant value iff result contains exactly 1 constant field, >+ * or <code>null</code> >+ * @param previousInput >+ * the previous input, or <code>null</code> >+ * @return the HTML hover info for the given element(s) or <code>null</code> >+ * if no information is available >+ * @since 3.4 >+ */ >+ private static PHPDocumentationBrowserInformationControlInput getHoverInfo( >+ IModelElement[] elements, String constantValue, >+ PHPDocumentationBrowserInformationControlInput previousInput) { >+ int nResults = elements.length; >+ StringBuffer buffer = new StringBuffer(); > boolean hasContents = false; >- if (nResults > 1) { >- HTMLPrinter.addSmallHeader(buffer, getInfoText(result[0])); >- HTMLPrinter.addParagraph(buffer, "<hr>"); //$NON-NLS-1$ >- for (int i = 0; i < result.length; i++) { >- // HTMLPrinter.startBulletList(buffer); >- IModelElement curr = result[i]; >- if (curr instanceof IMember) { >- IMember member = (IMember) curr; >- >- Reader reader; >- try { >- reader = ScriptDocumentationAccess >- .getHTMLContentReader(nature, member, true, >- true); >- >- // Provide hint why there's no doc >- if (reader == null) { >- // reader= new >- // StringReader(DLTKHoverMessages.ScriptdocHover_noAttachedInformation); >- continue; >- } >+ String base = null; >+ IModelElement element = null; > >- } catch (ModelException ex) { >- return null; >- } >+ int leadingImageWidth = 0; > >- if (reader != null) { >- // HTMLPrinter.addBullet(buffer, getInfoText(curr)); >- // HTMLPrinter.addParagraph(buffer, "<br>"); >- if (hasContents) { >- HTMLPrinter.addParagraph(buffer, "<hr>"); //$NON-NLS-1$ >- } >- HTMLPrinter.addParagraph(buffer, reader); >- } >+ if (nResults > 1) { >+ >+ for (int i = 0; i < elements.length; i++) { >+ HTMLPrinter.startBulletList(buffer); >+ IModelElement curr = elements[i]; >+ if (curr instanceof IMember >+ || curr.getElementType() == IModelElement.FIELD) { >+ // FIXME: provide links >+ HTMLPrinter.addBullet(buffer, getInfoText(curr, >+ constantValue, false)); > hasContents = true; > } >- // HTMLPrinter.endBulletList(buffer); >+ HTMLPrinter.endBulletList(buffer); > } > > } else { > >- IModelElement curr = result[0]; >- if (curr instanceof IMember) { >- IMember member = (IMember) curr; >- HTMLPrinter.addSmallHeader(buffer, getInfoText(member)); >- Reader reader; >+ element = elements[0]; >+ if (element instanceof IMember) { >+ IMember member = (IMember) element; >+ HTMLPrinter.addSmallHeader(buffer, getInfoText(member, >+ constantValue, true)); >+ Reader reader = null; > try { >- reader = ScriptDocumentationAccess.getHTMLContentReader( >- nature, member, true, true); >- >- // Provide hint why there's no doc >- if (reader == null) { >- reader = new StringReader( >- ScriptHoverMessages.ScriptdocHover_noAttachedInformation); >- } >- >- } catch (ModelException ex) { >- return null; >+ reader = getHTMLContent(member); >+ } catch (ModelException e) { > } > > if (reader != null) { > HTMLPrinter.addParagraph(buffer, reader); > } > hasContents = true; >- }/* >- * else if (curr.getElementType() == IModelElement.LOCAL_VARIABLE || >- * curr.getElementType() == IModelElement.TYPE_PARAMETER) { >- * HTMLPrinter.addSmallHeader(buffer, getInfoText(curr)); >- * hasContents= true; } >- */ >+ >+ } else if (element.getElementType() == IModelElement.FIELD) { >+ HTMLPrinter.addSmallHeader(buffer, getInfoText(element, >+ constantValue, true)); >+ hasContents = true; >+ } >+ leadingImageWidth = 20; > } > > if (!hasContents) >@@ -163,18 +606,240 @@ > if (buffer.length() > 0) { > HTMLPrinter.insertPageProlog(buffer, 0, getStyleSheet()); > HTMLPrinter.addPageEpilog(buffer); >- return buffer.toString(); >+ return new PHPDocumentationBrowserInformationControlInput( >+ previousInput, element, buffer.toString(), >+ leadingImageWidth); > } > > return null; > } > >- private String getInfoText(IModelElement member) { >+ private static String getInfoText(IModelElement element, >+ String constantValue, boolean allowImage) { >+ StringBuffer label = getInfoText(element); >+ if (element.getElementType() == IModelElement.FIELD) { >+ if (constantValue != null) { >+ label.append(' '); >+ label.append('='); >+ label.append(' '); >+ label.append(constantValue); >+ } >+ } >+ >+ String imageName = null; >+ if (allowImage) { >+ URL imageUrl = PHPUiPlugin.getDefault().getImagesOnFSRegistry() >+ .getImageURL(element); >+ if (imageUrl != null) { >+ imageName = imageUrl.toExternalForm(); >+ } >+ } >+ >+ StringBuffer buf = new StringBuffer(); >+ addImageAndLabel(buf, imageName, 16, 16, 2, 2, label.toString(), 20, 2); >+ return buf.toString(); >+ } >+ >+ /* >+ * @since 3.4 >+ */ >+ private static boolean isFinal(IField field) { >+ try { >+ return PHPFlags.isFinal(field.getFlags()); >+ } catch (ModelException e) { >+ PHPUiPlugin.log(e); >+ return false; >+ } >+ } >+ >+ /** >+ * Returns the constant value for the given field. >+ * >+ * @param field >+ * the field >+ * @param hoverRegion >+ * the hover region >+ * @return the constant value for the given field or <code>null</code> if >+ * none >+ * @since 3.4 >+ */ >+ private String getConstantValue(IField field, IRegion hoverRegion) { >+ if (!isFinal(field)) >+ return null; >+ >+ ISourceModule typeRoot = getEditorInputModelElement(); >+ if (typeRoot == null) >+ return null; >+ >+ Object constantValue = null; >+ if (field != null && field.exists()) { >+ try { >+ Program unit = SharedASTProvider.getAST( >+ field.getSourceModule(), SharedASTProvider.WAIT_YES, >+ null); >+ ASTNode node = NodeFinder.perform(unit, field.getNameRange() >+ .getOffset(), field.getNameRange().getLength()); >+ if (node != null && node instanceof Identifier >+ && node.getParent() instanceof ConstantDeclaration) { >+ ConstantDeclaration decl = (ConstantDeclaration) node >+ .getParent(); >+ if (decl.initializers().size() == 1 >+ && decl.initializers().get(0) instanceof Scalar) { >+ Scalar scalar = (Scalar) decl.initializers().get(0); >+ constantValue = scalar.getStringValue(); >+ } >+ } >+ } catch (ModelException e) { >+ } catch (IOException e) { >+ } >+ } >+ >+ if (constantValue == null) >+ return null; >+ >+ if (constantValue instanceof String) { >+ StringBuffer result = new StringBuffer(); >+ String stringConstant = (String) constantValue; >+ if (stringConstant.length() > 80) { >+ result.append(stringConstant.substring(0, 80)); >+ result.append(ScriptElementLabels.ELLIPSIS_STRING); >+ } else { >+ result.append(stringConstant); >+ } >+ return result.toString(); >+ >+ } else if (constantValue instanceof Integer) { >+ int intValue = ((Integer) constantValue).intValue(); >+ return formatWithHexValue(constantValue, >+ "0x" + Integer.toHexString(intValue)); //$NON-NLS-1$ >+ } else { >+ return constantValue.toString(); >+ } >+ } >+ >+ /** >+ * Creates and returns a formatted message for the given constant with its >+ * hex value. >+ * >+ * @param constantValue >+ * the constant value >+ * @param hexValue >+ * the hex value >+ * @return a formatted string with constant and hex values >+ * @since 3.4 >+ */ >+ private static String formatWithHexValue(Object constantValue, >+ String hexValue) { >+ return Messages.format( >+ PHPHoverMessages.JavadocHover_constantValue_hexValue, >+ new String[] { constantValue.toString(), hexValue }); >+ } >+ >+ /** >+ * Returns the Javadoc hover style sheet with the current Javadoc font from >+ * the preferences. >+ * >+ * @return the updated style sheet >+ * @since 3.4 >+ */ >+ protected static String getStyleSheet() { >+ if (fgStyleSheet == null) >+ fgStyleSheet = loadStyleSheet(); >+ String css = fgStyleSheet; >+ if (css != null) { >+ FontData fontData = JFaceResources.getFontRegistry().getFontData( >+ PreferenceConstants.APPEARANCE_DOCUMENTATION_FONT)[0]; >+ css = HTMLPrinter.convertTopLevelFont(css, fontData); >+ } >+ >+ return css; >+ } >+ >+ /** >+ * Loads and returns the Javadoc hover style sheet. >+ * >+ * @return the style sheet, or <code>null</code> if unable to load >+ * @since 3.4 >+ */ >+ private static String loadStyleSheet() { >+ Bundle bundle = Platform.getBundle(PHPUiPlugin.getPluginId()); >+ URL styleSheetURL = bundle >+ .getEntry("/PHPDocumentationHoverStyleSheet.css"); //$NON-NLS-1$ >+ if (styleSheetURL != null) { >+ BufferedReader reader = null; >+ try { >+ reader = new BufferedReader(new InputStreamReader(styleSheetURL >+ .openStream())); >+ StringBuffer buffer = new StringBuffer(1500); >+ String line = reader.readLine(); >+ while (line != null) { >+ buffer.append(line); >+ buffer.append('\n'); >+ line = reader.readLine(); >+ } >+ return buffer.toString(); >+ } catch (IOException ex) { >+ PHPUiPlugin.log(ex); >+ return ""; //$NON-NLS-1$ >+ } finally { >+ try { >+ if (reader != null) >+ reader.close(); >+ } catch (IOException e) { >+ } >+ } >+ } >+ return null; >+ } >+ >+ public static void addImageAndLabel(StringBuffer buf, String imageName, >+ int imageWidth, int imageHeight, int imageLeft, int imageTop, >+ String label, int labelLeft, int labelTop) { >+ >+ if (imageName != 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$ >+ >+ buf.append("<!--[if lte IE 6]><![if gte IE 5.5]>\n"); //$NON-NLS-1$ >+ 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$ >+ buf.append("<![endif]><![endif]-->\n"); //$NON-NLS-1$ >+ >+ buf.append("<!--[if !IE]>-->\n"); //$NON-NLS-1$ >+ buf.append("<img style='").append(imageStyle).append("' src='").append(imageName).append("'/>\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ >+ buf.append("<!--<![endif]-->\n"); //$NON-NLS-1$ >+ buf.append("<!--[if gte IE 7]>\n"); //$NON-NLS-1$ >+ buf.append("<img style='").append(imageStyle).append("' src='").append(imageName).append("'/>\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ >+ buf.append("<![endif]-->\n"); //$NON-NLS-1$ >+ } >+ >+ buf.append("<div style='word-wrap:break-word;"); //$NON-NLS-1$ >+ if (imageName != null) { >+ buf.append("margin-left: ").append(labelLeft).append("px; "); //$NON-NLS-1$ //$NON-NLS-2$ >+ buf.append("margin-top: ").append(labelTop).append("px; "); //$NON-NLS-1$ //$NON-NLS-2$ >+ } >+ buf.append("'>"); //$NON-NLS-1$ >+ buf.append(label); >+ buf.append("</div>"); //$NON-NLS-1$ >+ } >+ >+ protected static Reader getHTMLContent(IMember curr) throws ModelException { >+ String html = PHPDocumentationContentAccess.getHTMLContent(curr); >+ if (html != null) { >+ return new StringReader(html); >+ } >+ return null; >+ // return ScriptDocumentationAccess.getHTMLContentReader(PHPNature.ID, >+ // curr, true, true); >+ } >+ >+ private static StringBuffer getInfoText(IModelElement member) { > long flags = member.getElementType() == IModelElement.FIELD ? LOCAL_VARIABLE_FLAGS > : LABEL_FLAGS; > String label = ScriptElementLabels.getDefault().getElementLabel(member, > flags); >- return TextUtils.escapeHTML(label); >+ return new StringBuffer(label); > } >- > } >Index: src/org/eclipse/php/internal/ui/editor/hover/PHPHoverMessages.java >=================================================================== >RCS file: src/org/eclipse/php/internal/ui/editor/hover/PHPHoverMessages.java >diff -N src/org/eclipse/php/internal/ui/editor/hover/PHPHoverMessages.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/php/internal/ui/editor/hover/PHPHoverMessages.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,54 @@ >+package org.eclipse.php.internal.ui.editor.hover; >+ >+import org.eclipse.osgi.util.NLS; >+ >+/** >+ * Helper class to get NLSed messages. >+ */ >+final class PHPHoverMessages extends NLS { >+ >+ private static final String BUNDLE_NAME = PHPHoverMessages.class.getName(); >+ >+ private PHPHoverMessages() { >+ // Do not instantiate >+ } >+ >+ public static String AbstractAnnotationHover_action_configureAnnotationPreferences; >+ public static String AbstractAnnotationHover_message_singleQuickFix; >+ public static String AbstractAnnotationHover_message_multipleQuickFix; >+ >+ public static String JavadocHover_back; >+ public static String JavadocHover_back_toElement_toolTip; >+ public static String JavadocHover_back_toolTip; >+ public static String JavadocHover_noAttachments; >+ public static String JavadocHover_noAttachedJavadoc; >+ public static String JavadocHover_noAttachedSource; >+ public static String JavadocHover_noInformation; >+ public static String JavadocHover_constantValue_hexValue; >+ public static String JavadocHover_error_gettingJavadoc; >+ public static String JavadocHover_forward; >+ public static String JavadocHover_forward_toElement_toolTip; >+ public static String JavadocHover_forward_toolTip; >+ public static String JavadocHover_openDeclaration; >+ public static String JavadocHover_showInJavadoc; >+ >+ public static String JavaTextHover_createTextHover; >+ >+ public static String NoBreakpointAnnotation_addBreakpoint; >+ >+ public static String NLSStringHover_NLSStringHover_missingKeyWarning; >+ public static String NLSStringHover_NLSStringHover_PropertiesFileNotDetectedWarning; >+ public static String NLSStringHover_open_in_properties_file; >+ public static String ProblemHover_action_configureProblemSeverity; >+ >+ public static String ProblemHover_chooseSettingsTypeDialog_button_cancel; >+ public static String ProblemHover_chooseSettingsTypeDialog_button_project; >+ public static String ProblemHover_chooseSettingsTypeDialog_button_workspace; >+ public static String ProblemHover_chooseSettingsTypeDialog_checkBox_dontShowAgain; >+ public static String ProblemHover_chooseSettingsTypeDialog_message; >+ public static String ProblemHover_chooseSettingsTypeDialog_title; >+ >+ static { >+ NLS.initializeMessages(BUNDLE_NAME, PHPHoverMessages.class); >+ } >+} >Index: src/org/eclipse/php/internal/ui/editor/hover/PHPHoverMessages.properties >=================================================================== >RCS file: src/org/eclipse/php/internal/ui/editor/hover/PHPHoverMessages.properties >diff -N src/org/eclipse/php/internal/ui/editor/hover/PHPHoverMessages.properties >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/php/internal/ui/editor/hover/PHPHoverMessages.properties 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,44 @@ >+############################################################################### >+# Copyright (c) 2000, 2009 IBM Corporation and others. >+# All rights reserved. This program and the accompanying materials >+# are made available under the terms of the Eclipse Public License v1.0 >+# which accompanies this distribution, and is available at >+# http://www.eclipse.org/legal/epl-v10.html >+# >+# Contributors: >+# IBM Corporation - initial API and implementation >+############################################################################### >+ >+AbstractAnnotationHover_action_configureAnnotationPreferences= Configure Annotation Preferences >+AbstractAnnotationHover_message_singleQuickFix= 1 quick fix available: >+AbstractAnnotationHover_message_multipleQuickFix= {0} quick fixes available: >+ >+JavaTextHover_createTextHover= Could not create Java text hover >+ >+NoBreakpointAnnotation_addBreakpoint= Add a breakpoint >+ >+NLSStringHover_NLSStringHover_PropertiesFileNotDetectedWarning= The properties file could not be detected >+NLSStringHover_NLSStringHover_missingKeyWarning= <b>Warning:</b> The key is missing! >+NLSStringHover_open_in_properties_file=Open in Properties File >+JavadocHover_back= Back >+JavadocHover_back_toElement_toolTip=Back to {0} >+JavadocHover_back_toolTip=Back >+JavadocHover_noAttachments= <em>Note: This element neither has attached source nor attached Javadoc and hence no Javadoc could be found.</em> >+JavadocHover_noAttachedSource= <em>Note: This element has no attached source and the Javadoc could not be found in the attached Javadoc.</em> >+JavadocHover_noAttachedJavadoc= <em>Note: This element has no attached Javadoc and the Javadoc could not be found in the attached source.</em> >+JavadocHover_noInformation= <em>Note: The Javadoc for this element could neither be found in the attached source nor the attached Javadoc.</em> >+# The first parameter is the constant value string and the second is its hex representation >+JavadocHover_constantValue_hexValue={0} [{1}] >+JavadocHover_error_gettingJavadoc= <em>Note: An exception occurred while getting the Javadoc. See log for details.</em> >+JavadocHover_forward= Forward >+JavadocHover_forward_toElement_toolTip=Forward to {0} >+JavadocHover_forward_toolTip=Forward >+JavadocHover_openDeclaration= Open Declaration >+JavadocHover_showInJavadoc= Show in Javadoc View >+ProblemHover_action_configureProblemSeverity=Configure Problem Severity >+ProblemHover_chooseSettingsTypeDialog_button_cancel=Cancel >+ProblemHover_chooseSettingsTypeDialog_button_project=Configure &Project >+ProblemHover_chooseSettingsTypeDialog_button_workspace=Configure &Workspace >+ProblemHover_chooseSettingsTypeDialog_checkBox_dontShowAgain=&Always configure the workspace settings >+ProblemHover_chooseSettingsTypeDialog_message=The project ''{0}'' does not have any project specific problem severity settings yet.\n\nDo you want to create and configure the project settings or do you want to configure the workspace settings? >+ProblemHover_chooseSettingsTypeDialog_title=Configure Problem Severity >Index: src/org/eclipse/php/internal/ui/editor/hover/PHPTextHoverProxy.java >=================================================================== >RCS file: /cvsroot/tools/org.eclipse.pdt/plugins/org.eclipse.php.ui/src/org/eclipse/php/internal/ui/editor/hover/PHPTextHoverProxy.java,v >retrieving revision 1.8 >diff -u -r1.8 PHPTextHoverProxy.java >--- src/org/eclipse/php/internal/ui/editor/hover/PHPTextHoverProxy.java 18 Oct 2009 09:28:34 -0000 1.8 >+++ src/org/eclipse/php/internal/ui/editor/hover/PHPTextHoverProxy.java 5 May 2010 14:28:49 -0000 >@@ -11,19 +11,15 @@ > *******************************************************************************/ > package org.eclipse.php.internal.ui.editor.hover; > >-import org.eclipse.dltk.internal.ui.text.hover.AbstractScriptEditorTextHover; > import org.eclipse.jface.preference.IPreferenceStore; >-import org.eclipse.jface.text.IInformationControlCreator; >-import org.eclipse.jface.text.IRegion; >-import org.eclipse.jface.text.ITextHoverExtension; >-import org.eclipse.jface.text.ITextViewer; >+import org.eclipse.jface.text.*; > import org.eclipse.jface.text.information.IInformationProviderExtension2; > import org.eclipse.php.internal.ui.text.hover.PHPEditorTextHoverDescriptor; > import org.eclipse.php.ui.editor.hover.IHoverMessageDecorator; > import org.eclipse.php.ui.editor.hover.IPHPTextHover; > import org.eclipse.ui.IEditorPart; > >-public class PHPTextHoverProxy extends AbstractScriptEditorTextHover implements >+public class PHPTextHoverProxy extends AbstractPHPEditorTextHover implements > IPHPTextHover, ITextHoverExtension, IInformationProviderExtension2 { > > private PHPEditorTextHoverDescriptor fHoverDescriptor; >@@ -75,6 +71,18 @@ > return null; > } > >+ public Object getHoverInfo2(ITextViewer textViewer, IRegion hoverRegion) { >+ if (ensureHoverCreated()) { >+ if (fHover instanceof ITextHoverExtension2) >+ return ((ITextHoverExtension2) fHover).getHoverInfo2( >+ textViewer, hoverRegion); >+ else >+ return fHover.getHoverInfo(textViewer, hoverRegion); >+ } >+ >+ return null; >+ } >+ > private boolean ensureHoverCreated() { > if (!isEnabled() || fHoverDescriptor == null) > return false; >Index: src/org/eclipse/php/internal/ui/viewsupport/ImagesOnFileSystemRegistry.java >=================================================================== >RCS file: src/org/eclipse/php/internal/ui/viewsupport/ImagesOnFileSystemRegistry.java >diff -N src/org/eclipse/php/internal/ui/viewsupport/ImagesOnFileSystemRegistry.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/php/internal/ui/viewsupport/ImagesOnFileSystemRegistry.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,125 @@ >+package org.eclipse.php.internal.ui.viewsupport; >+ >+import java.io.File; >+import java.net.MalformedURLException; >+import java.net.URL; >+import java.util.HashMap; >+ >+import org.eclipse.dltk.core.IModelElement; >+import org.eclipse.dltk.ui.ScriptElementImageProvider; >+import org.eclipse.jface.resource.ImageDescriptor; >+import org.eclipse.php.internal.ui.PHPUiPlugin; >+import org.eclipse.swt.SWT; >+import org.eclipse.swt.graphics.ImageData; >+import org.eclipse.swt.graphics.ImageLoader; >+ >+/** >+ * Image registry that keeps its images on the local file system. >+ * >+ * @since 3.4 >+ */ >+public class ImagesOnFileSystemRegistry { >+ >+ private static final String IMAGE_DIR = "pdt-images"; //$NON-NLS-1$ >+ >+ private HashMap fURLMap; >+ private final File fTempDir; >+ private final ScriptElementImageProvider fImageProvider; >+ private int fImageCount; >+ >+ public ImagesOnFileSystemRegistry() { >+ fURLMap = new HashMap(); >+ fTempDir = getTempDir(); >+ fImageProvider = new ScriptElementImageProvider(); >+ fImageCount = 0; >+ } >+ >+ private File getTempDir() { >+ try { >+ File imageDir = PHPUiPlugin.getDefault().getStateLocation().append( >+ IMAGE_DIR).toFile(); >+ if (imageDir.exists()) { >+ // has not been deleted on previous shutdown >+ delete(imageDir); >+ } >+ if (!imageDir.exists()) { >+ imageDir.mkdir(); >+ } >+ if (!imageDir.isDirectory()) { >+ PHPUiPlugin >+ .logErrorMessage("Failed to create image directory " + imageDir.toString()); //$NON-NLS-1$ >+ return null; >+ } >+ return imageDir; >+ } catch (IllegalStateException e) { >+ // no state location >+ return null; >+ } >+ } >+ >+ private void delete(File file) { >+ if (file.isDirectory()) { >+ File[] listFiles = file.listFiles(); >+ for (int i = 0; i < listFiles.length; i++) { >+ delete(listFiles[i]); >+ } >+ } >+ file.delete(); >+ } >+ >+ public URL getImageURL(IModelElement element) { >+ ImageDescriptor descriptor = fImageProvider.getScriptImageDescriptor( >+ element, ScriptElementImageProvider.OVERLAY_ICONS >+ | ScriptElementImageProvider.SMALL_ICONS); >+ if (descriptor == null) >+ return null; >+ return getImageURL(descriptor); >+ } >+ >+ public URL getImageURL(ImageDescriptor descriptor) { >+ if (fTempDir == null) >+ return null; >+ >+ URL url = (URL) fURLMap.get(descriptor); >+ if (url != null) >+ return url; >+ >+ File imageFile = getNewFile(); >+ ImageData imageData = descriptor.getImageData(); >+ if (imageData == null) { >+ return null; >+ } >+ >+ ImageLoader loader = new ImageLoader(); >+ loader.data = new ImageData[] { imageData }; >+ loader.save(imageFile.getAbsolutePath(), SWT.IMAGE_PNG); >+ >+ try { >+ url = imageFile.toURI().toURL(); >+ fURLMap.put(descriptor, url); >+ return url; >+ } catch (MalformedURLException e) { >+ PHPUiPlugin.log(e); >+ } >+ return null; >+ } >+ >+ private File getNewFile() { >+ File file; >+ do { >+ file = new File(fTempDir, String.valueOf(getImageCount()) + ".png"); //$NON-NLS-1$ >+ } while (file.exists()); >+ return file; >+ } >+ >+ private synchronized int getImageCount() { >+ return fImageCount++; >+ } >+ >+ public void dispose() { >+ if (fTempDir != null) { >+ delete(fTempDir); >+ } >+ fURLMap = null; >+ } >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 311734
:
167144
| 167145