1 /**********************************************************************
2 Copyright (c) 2000, 2002 IBM Corp. and others.
3 All rights reserved. This program and the accompanying materials
4 are made available under the terms of the Common Public License v1.0
5 which accompanies this distribution, and is available at
6 http://www.eclipse.org/legal/cpl-v10.html
9 IBM Corporation - Initial implementation
10 Klaus Hartlage - www.eclipseproject.de
11 **********************************************************************/
12 package net.sourceforge.phpeclipse.phpeditor.php;
14 import java.text.MessageFormat;
15 import java.util.ArrayList;
16 import java.util.Arrays;
17 import java.util.List;
19 import net.sourceforge.phpdt.internal.corext.template.ContextType;
20 import net.sourceforge.phpdt.internal.corext.template.ContextTypeRegistry;
21 import net.sourceforge.phpdt.internal.ui.text.java.IJavaCompletionProposal;
22 import net.sourceforge.phpdt.internal.ui.text.java.JavaCompletionProposalComparator;
23 import net.sourceforge.phpdt.internal.ui.text.template.TemplateEngine;
24 import org.eclipse.jface.text.BadLocationException;
25 import org.eclipse.jface.text.IDocument;
26 import org.eclipse.jface.text.ITextViewer;
27 import org.eclipse.jface.text.TextPresentation;
28 import org.eclipse.jface.text.contentassist.CompletionProposal;
29 import org.eclipse.jface.text.contentassist.ContextInformation;
30 import org.eclipse.jface.text.contentassist.ICompletionProposal;
31 import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
32 import org.eclipse.jface.text.contentassist.IContextInformation;
33 import org.eclipse.jface.text.contentassist.IContextInformationExtension;
34 import org.eclipse.jface.text.contentassist.IContextInformationPresenter;
35 import org.eclipse.jface.text.contentassist.IContextInformationValidator;
36 import org.eclipse.swt.graphics.Image;
39 * Example PHP completion processor.
41 public class PHPCompletionProcessor implements IContentAssistProcessor {
44 * Simple content assist tip closer. The tip is valid in a range
45 * of 5 characters around its popup location.
47 protected static class Validator implements IContextInformationValidator, IContextInformationPresenter {
49 protected int fInstallOffset;
52 * @see IContextInformationValidator#isContextInformationValid(int)
54 public boolean isContextInformationValid(int offset) {
55 return Math.abs(fInstallOffset - offset) < 5;
59 * @see IContextInformationValidator#install(IContextInformation, ITextViewer, int)
61 public void install(IContextInformation info, ITextViewer viewer, int offset) {
62 fInstallOffset = offset;
66 * @see org.eclipse.jface.text.contentassist.IContextInformationPresenter#updatePresentation(int, TextPresentation)
68 public boolean updatePresentation(int documentPosition, TextPresentation presentation) {
73 private static class ContextInformationWrapper implements IContextInformation, IContextInformationExtension {
75 private final IContextInformation fContextInformation;
76 private int fPosition;
78 public ContextInformationWrapper(IContextInformation contextInformation) {
79 fContextInformation = contextInformation;
83 * @see IContextInformation#getContextDisplayString()
85 public String getContextDisplayString() {
86 return fContextInformation.getContextDisplayString();
90 * @see IContextInformation#getImage()
92 public Image getImage() {
93 return fContextInformation.getImage();
97 * @see IContextInformation#getInformationDisplayString()
99 public String getInformationDisplayString() {
100 return fContextInformation.getInformationDisplayString();
104 * @see IContextInformationExtension#getContextInformationPosition()
106 public int getContextInformationPosition() {
110 public void setContextInformationPosition(int position) {
111 fPosition = position;
115 protected final static String[] fgProposals = PHPFunctionNames.FUNCTION_NAMES;
153 protected IContextInformationValidator fValidator = new Validator();
154 private TemplateEngine fTemplateEngine;
155 private JavaCompletionProposalComparator fComparator;
156 private int fNumberOfComputedResults = 0;
158 public PHPCompletionProcessor() {
160 ContextType contextType = ContextTypeRegistry.getInstance().getContextType("php"); //$NON-NLS-1$
161 if (contextType != null)
162 fTemplateEngine = new TemplateEngine(contextType);
164 fComparator = new JavaCompletionProposalComparator();
167 * Method declared on IContentAssistProcessor
169 public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int documentOffset) {
170 // IDocument document = viewer.getDocument();
171 // if (documentOffset > 0) {
173 // ICompletionProposal[] result;
174 // char character = document.getChar(documentOffset - 1);
175 // if (character == '$') {
176 ////viewer. .getActivePage().getActiveEditor();
177 // result = new ICompletionProposal[fgProposals.length];
178 // for (int i = 0; i < fgProposals.length; i++) {
179 // IContextInformation info = new ContextInformation(fgProposals[i], MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.Proposal.ContextInfo.pattern"), new Object[] { fgProposals[i] })); //$NON-NLS-1$
180 // result[i] = new CompletionProposal(fgProposals[i], documentOffset, 0, fgProposals[i].length(), null, fgProposals[i], info, MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.Proposal.hoverinfo.pattern"), new Object[] { fgProposals[i] })); //$NON-NLS-1$
184 // } catch (BadLocationException e) {
185 // return new ICompletionProposal[0];
189 // ICompletionProposal[] result = new ICompletionProposal[fgProposals.length];
190 // for (int i = 0; i < fgProposals.length; i++) {
191 // IContextInformation info = new ContextInformation(fgProposals[i], MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.Proposal.ContextInfo.pattern"), new Object[] { fgProposals[i] })); //$NON-NLS-1$
192 // result[i] = new CompletionProposal(fgProposals[i], documentOffset, 0, fgProposals[i].length(), null, fgProposals[i], info, MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.Proposal.hoverinfo.pattern"), new Object[] { fgProposals[i] })); //$NON-NLS-1$
195 int contextInformationPosition = guessContextInformationPosition(viewer, documentOffset);
196 return internalComputeCompletionProposals(viewer, documentOffset, contextInformationPosition);
200 private ICompletionProposal[] internalComputeCompletionProposals(ITextViewer viewer, int offset, int contextOffset) {
201 IDocument document = viewer.getDocument();
204 ICompletionProposal[] result;
205 char character = document.getChar(offset - 1);
206 if (character == '$') {
207 //viewer. .getActivePage().getActiveEditor();
208 result = new ICompletionProposal[fgProposals.length];
209 for (int i = 0; i < fgProposals.length; i++) {
210 IContextInformation info = new ContextInformation(fgProposals[i], MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.Proposal.ContextInfo.pattern"), new Object[] { fgProposals[i] })); //$NON-NLS-1$
211 result[i] = new CompletionProposal(fgProposals[i], offset, 0, fgProposals[i].length(), null, fgProposals[i], info, MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.Proposal.hoverinfo.pattern"), new Object[] { fgProposals[i] })); //$NON-NLS-1$
215 } catch (BadLocationException e) {
216 return new ICompletionProposal[0];
220 if (fTemplateEngine != null) {
221 IJavaCompletionProposal[] results;
223 fTemplateEngine.reset();
224 fTemplateEngine.complete(viewer, offset); //, unit);
225 // } catch (JavaModelException x) {
226 // Shell shell= viewer.getTextWidget().getShell();
227 // ErrorDialog.openError(shell, JavaTextMessages.getString("CompletionProcessor.error.accessing.title"), JavaTextMessages.getString("CompletionProcessor.error.accessing.message"), x.getStatus()); //$NON-NLS-2$ //$NON-NLS-1$
230 IJavaCompletionProposal[] templateResults = fTemplateEngine.getResults();
232 // concatenate arrays
233 IJavaCompletionProposal[] total = new IJavaCompletionProposal[templateResults.length]; // +results.length ];
234 System.arraycopy(templateResults, 0, total, 0, templateResults.length);
235 // System.arraycopy(results, 0, total, templateResults.length, results.length);
239 fNumberOfComputedResults = (results == null ? 0 : results.length);
242 * Order here and not in result collector to make sure that the order
243 * applies to all proposals and not just those of the compilation unit.
245 return order(results);
247 return new IJavaCompletionProposal[0];
250 private int guessContextInformationPosition(ITextViewer viewer, int offset) {
251 int contextPosition = offset;
253 IDocument document = viewer.getDocument();
257 // JavaCodeReader reader= new JavaCodeReader();
258 // reader.configureBackwardReader(document, offset, true, true);
260 // int nestingLevel= 0;
262 // int curr= reader.read();
263 // while (curr != JavaCodeReader.EOF) {
265 // if (')' == (char) curr)
268 // else if ('(' == (char) curr) {
271 // if (nestingLevel < 0) {
272 // int start= reader.getOffset();
273 // if (looksLikeMethod(reader))
278 // curr= reader.read();
280 // } catch (IOException e) {
283 return contextPosition;
287 * Method declared on IContentAssistProcessor
289 // public IContextInformation[] computeContextInformation(ITextViewer viewer, int documentOffset) {
290 // IContextInformation[] result = new IContextInformation[5];
291 // for (int i = 0; i < result.length; i++)
292 // result[i] = new ContextInformation(MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.ContextInfo.display.pattern"), new Object[] { new Integer(i), new Integer(documentOffset)}), //$NON-NLS-1$
293 // MessageFormat.format(PHPEditorMessages.getString("CompletionProcessor.ContextInfo.value.pattern"), new Object[] { new Integer(i), new Integer(documentOffset - 5), new Integer(documentOffset + 5)})); //$NON-NLS-1$
297 * @see IContentAssistProcessor#computeContextInformation(ITextViewer, int)
299 public IContextInformation[] computeContextInformation(ITextViewer viewer, int offset) {
300 int contextInformationPosition = guessContextInformationPosition(viewer, offset);
301 List result = addContextInformations(viewer, contextInformationPosition);
302 return (IContextInformation[]) result.toArray(new IContextInformation[result.size()]);
305 private List addContextInformations(ITextViewer viewer, int offset) {
306 ICompletionProposal[] proposals = internalComputeCompletionProposals(viewer, offset, -1);
308 List result = new ArrayList();
309 for (int i = 0; i < proposals.length; i++) {
310 IContextInformation contextInformation = proposals[i].getContextInformation();
311 if (contextInformation != null) {
312 ContextInformationWrapper wrapper = new ContextInformationWrapper(contextInformation);
313 wrapper.setContextInformationPosition(offset);
321 * Order the given proposals.
323 private ICompletionProposal[] order(ICompletionProposal[] proposals) {
324 Arrays.sort(proposals, fComparator);
329 * Method declared on IContentAssistProcessor
331 public char[] getCompletionProposalAutoActivationCharacters() {
332 return new char[] { '$' };
336 * Method declared on IContentAssistProcessor
338 public char[] getContextInformationAutoActivationCharacters() {
344 * Method declared on IContentAssistProcessor
346 public IContextInformationValidator getContextInformationValidator() {
351 * Method declared on IContentAssistProcessor
353 public String getErrorMessage() {