/******************************************************************************* * Copyright (c) 2010 xored software, Inc. * * 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: * xored software, Inc. - initial API and Implementation (Alex Panchenko) *******************************************************************************/ package org.eclipse.dltk.javascript.internal.ui.text.completion; import java.io.IOException; import java.io.Reader; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.dltk.ast.ASTNode; import org.eclipse.dltk.core.IMember; import org.eclipse.dltk.core.IModelElement; import org.eclipse.dltk.core.IModelElementVisitor; import org.eclipse.dltk.core.ISourceModule; import org.eclipse.dltk.core.ISourceRange; import org.eclipse.dltk.core.ModelException; import org.eclipse.dltk.internal.javascript.ti.JSDocSupport; import org.eclipse.dltk.javascript.ast.Comment; import org.eclipse.dltk.javascript.ast.JSNode; import org.eclipse.dltk.javascript.ast.Script; import org.eclipse.dltk.javascript.core.JavaScriptNature; import org.eclipse.dltk.javascript.core.NodeFinder; import org.eclipse.dltk.javascript.internal.ui.JavaScriptUI; import org.eclipse.dltk.javascript.parser.JavaScriptParserUtil; import org.eclipse.dltk.javascript.scriptdoc.JavaDoc2HTMLTextReader; import org.eclipse.dltk.javascript.scriptdoc.ScriptDocumentationProvider; import org.eclipse.dltk.javascript.scriptdoc.StringJavaDocCommentReader; import org.eclipse.dltk.javascript.typeinference.IValueReference; import org.eclipse.dltk.javascript.typeinference.ReferenceLocation; import org.eclipse.dltk.javascript.typeinfo.IModelBuilder.IMethod; import org.eclipse.dltk.javascript.typeinfo.IModelBuilder.IVariable; import org.eclipse.dltk.javascript.typeinfo.model.Element; import org.eclipse.dltk.ui.documentation.DocumentationUtils; import org.eclipse.dltk.ui.documentation.IDocumentationResponse; import org.eclipse.dltk.ui.documentation.ScriptDocumentationAccess; import org.eclipse.dltk.ui.text.completion.ProposalInfo; public class JavaScriptProposalInfo extends ProposalInfo { private final Object ref; public JavaScriptProposalInfo(Object ref) { super(null); this.ref = ref; } @Override public String getInfo(IProgressMonitor monitor) { if (ref instanceof IMember) { Reader contentReader = new ScriptDocumentationProvider().getInfo( (IMember) ref, true, true); if (contentReader != null) { String string = getString(contentReader); return string; } } else if (ref instanceof String) { return (String) ref; } else if (ref instanceof Element) { final IDocumentationResponse response = ScriptDocumentationAccess .getDocumentation(JavaScriptNature.NATURE_ID, ref, null); if (response != null) { try { return getString(response.getReader()); } catch (IOException e) { JavaScriptUI.log(e); } } } else if (ref instanceof IValueReference) { return getInfo( ((IValueReference) ref).getLocation()); } else if (ref instanceof IMethod) { ISourceRange docRange = ((IMethod) ref).getDocRange(); if (docRange != null && docRange.getOffset() > 0 && docRange.getLength() > 0) { ISourceModule sourceModule = ((IMethod) ref).getLocation() .getSourceModule(); try { String comment = sourceModule.getSource().substring( docRange.getOffset(), docRange.getOffset() + docRange.getLength()); return getString(new JavaDoc2HTMLTextReader( new StringJavaDocCommentReader(comment))); } catch (ModelException e) { e.printStackTrace(); } } } else if (ref instanceof IVariable) { return getInfo(((IVariable) ref).getLocation()); } return null; } private String getInfo(final ReferenceLocation location) { if (location == ReferenceLocation.UNKNOWN) return null; final ISourceModule m = location.getSourceModule(); if (m == null) return null; try { m.accept(new IModelElementVisitor() { public boolean visit(IModelElement element) { if (element instanceof IMember) { try { ISourceRange nameRange = ((IMember) element) .getNameRange(); if (location.getNameStart() >= nameRange .getOffset() && location.getNameEnd() <= (nameRange .getOffset() + nameRange .getLength())) { throw new ModelElementFound(element); } } catch (ModelException e) { e.printStackTrace(); } } return true; } }); } catch (ModelException e) { e.printStackTrace(); } catch (ModelElementFound found) { Reader contentReader = new ScriptDocumentationProvider().getInfo( (IMember) found.element, true, true); if (contentReader != null) { return getString(contentReader); } } final Script script = JavaScriptParserUtil.parse(m, null); final NodeFinder nodeFinder = new NodeFinder(location.getNameStart(), location.getNameEnd()); nodeFinder.locate(script); ASTNode node = nodeFinder.getNode(); if (node instanceof JSNode) { Comment comment = JSDocSupport.getComment((JSNode) node); if (comment != null && comment.getText().length() > 0) { return getString(new JavaDoc2HTMLTextReader( new StringJavaDocCommentReader( comment.getText()))); } } return null; } /** * Gets the reader content as a String */ private String getString(Reader reader) { return DocumentationUtils.readAll(reader); } @SuppressWarnings("serial") private static class ModelElementFound extends RuntimeException { final IModelElement element; public ModelElementFound(IModelElement element) { this.element = element; } } }