/******************************************************************************* * Copyright (c) 2005, 2012 eBay 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 * *******************************************************************************/ package org.eclipse.vjet.eclipse.ui.text.completion; import java.util.Collection; import java.util.List; import java.util.Set; import org.eclipse.vjet.dsf.jst.IJstMethod; import org.eclipse.vjet.dsf.jst.IJstType; import org.eclipse.vjet.eclipse.codeassist.keywords.FieldOrMethodCompletionHandler; import org.eclipse.vjet.eclipse.core.IJSType; import org.eclipse.vjet.eclipse.core.IVjoSourceModule; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.dltk.mod.core.IMethod; import org.eclipse.dltk.mod.core.IType; import org.eclipse.dltk.mod.core.ModelException; import org.eclipse.dltk.mod.ui.DLTKPluginImages; import org.eclipse.dltk.mod.ui.text.completion.ProposalInfo; import org.eclipse.dltk.mod.ui.text.completion.ScriptTypeCompletionProposal; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.TextUtilities; import org.eclipse.jface.text.contentassist.ICompletionProposalExtension4; import org.eclipse.jface.text.contentassist.IContextInformation; public class MethodDeclarationCompletionProposal extends ScriptTypeCompletionProposal implements ICompletionProposalExtension4 { // modifiers private static final String PRIVATE_MODIFIER = "private"; private static final String PROTECTED_MODIFIER = "protected"; private static final String PUBLIC_MODIFIER = "public"; public static void evaluateProposals(IType type, String prefix, int offset, int length, int relevance, Set suggestedMethods, Collection result, boolean isStatic) throws CoreException { IMethod[] methods = type.getMethods(); if (type instanceof IJSType && !((IJSType) type).isInterface()) { final String constructorName = "constructs"; if (constructorName.startsWith(prefix) && !hasMethod(methods, constructorName) && suggestedMethods.add(constructorName)) { result.add(new MethodDeclarationCompletionProposal(type, constructorName, PUBLIC_MODIFIER, null, offset, length, relevance + 500, isStatic)); } } if (prefix.length() > 0 && !"base".equals(prefix) && !hasMethod(methods, prefix) && suggestedMethods.add(prefix)) { //$NON-NLS-1$ // TODO add name validation // if // (!JavaConventions.validateMethodName(prefix).matches(IStatus.ERROR)) // { result.add(new MethodDeclarationCompletionProposal(type, prefix, PUBLIC_MODIFIER, "void", offset, length, relevance, isStatic)); if (!(FieldOrMethodCompletionHandler.MAIN_METHOD.equals(prefix) && isStatic)) { result.add(new MethodDeclarationCompletionProposal(type, prefix, PROTECTED_MODIFIER, "void", offset, length, relevance, isStatic)); result.add(new MethodDeclarationCompletionProposal(type, prefix, PRIVATE_MODIFIER, "void", offset, length, relevance, isStatic)); } // } } } private static boolean hasMethod(IMethod[] methods, String name) { for (int i = 0; i < methods.length; i++) { IMethod curr = methods[i]; try { if (curr.getElementName().equals(name) && curr.getParameters().length == 0) { return true; } } catch (ModelException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return false; } private final IType fType; private final String fModifier; private final String fReturnTypeSig; private final String fMethodName; private final boolean fIsStatic; public MethodDeclarationCompletionProposal(IType type, String methodName, String modifiers, String returnTypeSig, int start, int length, int relevance, boolean isStatic) { super( "", type.getSourceModule(), start, length, null, getDisplayName(methodName, returnTypeSig, modifiers), relevance); //$NON-NLS-1$ Assert.isNotNull(type); Assert.isNotNull(methodName); fType = type; fMethodName = methodName; fReturnTypeSig = returnTypeSig; fModifier = modifiers; fIsStatic = isStatic; if (fModifier.equals(PRIVATE_MODIFIER)) { setImage(DLTKPluginImages.get(DLTKPluginImages.IMG_METHOD_PRIVATE)); } else if (fModifier.equals(PROTECTED_MODIFIER)) { setImage(DLTKPluginImages .get(DLTKPluginImages.IMG_METHOD_PROTECTED)); } else if (fModifier.equals(PUBLIC_MODIFIER)) { setImage(DLTKPluginImages.get(DLTKPluginImages.IMG_METHOD_PUBLIC)); } else { setImage(DLTKPluginImages.get(DLTKPluginImages.IMG_METHOD_PRIVATE)); } if (returnTypeSig == null) setProposalInfo(new ProposalInfo(type)); } private static String getDisplayName(String methodName, String returnTypeSig, String modifier) { StringBuffer buf = new StringBuffer(); buf.append(methodName); buf.append('('); buf.append(')'); if (returnTypeSig != null) { buf.append(" "); //$NON-NLS-1$ buf.append(returnTypeSig); buf.append(" - "); //$NON-NLS-1$ // if (modifier != null) // buf.append(modifier + " "); buf.append("method stub"); } else { buf.append(" - "); //$NON-NLS-1$ buf.append("Default constructor"); } return buf.toString(); } /* * (non-Javadoc) * * @see org.eclipse.dltk.mod.ui.text.completion.ScriptTypeCompletionProposal#updateReplacementString(org.eclipse.jface.text.IDocument, * char, int) */ protected boolean updateReplacementString(IDocument document, char trigger, int offset) throws CoreException, BadLocationException { String lineDelim = TextUtilities.getDefaultLineDelimiter(document); String declTypeName = fType.getTypeQualifiedName("."); boolean isInterface = false; if (fType instanceof IJSType) { isInterface = ((IJSType) fType).isInterface(); } StringBuffer comment = new StringBuffer("//>"); if (fModifier != null) comment.append(fModifier); else if ((fReturnTypeSig != null) && (!isInterface)) { comment.append(PRIVATE_MODIFIER); //$NON-NLS-1$ } else { comment.append(PUBLIC_MODIFIER); //$NON-NLS-1$ } // generate comment comment.append(" "); if (fReturnTypeSig != null) { comment.append(fReturnTypeSig); comment.append(" "); } else if (fMethodName.indexOf("constructs") != -1) { comment.append(""); } else { comment.append(fType.getElementName()); comment.append(" "); } comment.append(fMethodName); if (isMainMethod()) { comment.append("(String ... arguments)"); } else { comment.append("()"); } comment.append(CompletionUtils.NEWLINE_1); comment.append(CompletionUtils.NEWLINE_2); // generate method stub String ident = CompletionUtils.calculateIndent(document, offset); StringBuffer completionText = new StringBuffer(comment); completionText.append(ident); completionText.append(fMethodName); completionText.append(" : function("); if (isMainMethod()) { completionText.append(""); } completionText.append(") {"); completionText.append(CompletionUtils.NEWLINE_1); completionText.append(CompletionUtils.NEWLINE_2); completionText.append(ident); completionText.append(CompletionUtils.TAB); final int cursorPosition = completionText.length(); completionText.append(CompletionUtils.NEWLINE_1); completionText.append(CompletionUtils.NEWLINE_2); completionText.append(ident); completionText.append("}"); if (!isInEndOfBlock(offset)) completionText.append(","); setReplacementString(completionText.toString()); // TODO move this to another place setCursorPosition(cursorPosition); return false; } private boolean isMainMethod() { return FieldOrMethodCompletionHandler.MAIN_METHOD.equals(fMethodName) && fIsStatic; } public CharSequence getPrefixCompletionText(IDocument document, int completionOffset) { return new String(); // don't let method stub proposals complete // incrementally } /* * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension4#isAutoInsertable() */ public boolean isAutoInsertable() { return false; } @Override protected boolean isValidPrefix(String prefix) { return super.isValidPrefix(prefix) || true; } @Override public IContextInformation getContextInformation() { return null; } private boolean isInEndOfBlock(int offset) { IJstType type = ((IVjoSourceModule) fSourceModule).getJstType(); List<? extends IJstMethod> methods = type.getMethods(fIsStatic); for (IJstMethod method : methods) { if (method.getSource().getEndOffSet() > offset) return false; } return true; } }