1 12 package org.eclipse.jdt.internal.ui.text.java; 13 14 import org.eclipse.core.runtime.Platform; 15 16 import org.eclipse.swt.graphics.Point; 17 import org.eclipse.swt.widgets.Shell; 18 19 import org.eclipse.jface.dialogs.MessageDialog; 20 21 import org.eclipse.jface.text.BadLocationException; 22 import org.eclipse.jface.text.BadPositionCategoryException; 23 import org.eclipse.jface.text.IDocument; 24 import org.eclipse.jface.text.IPositionUpdater; 25 import org.eclipse.jface.text.IRegion; 26 import org.eclipse.jface.text.Position; 27 import org.eclipse.jface.text.Region; 28 import org.eclipse.jface.text.contentassist.ICompletionProposal; 29 import org.eclipse.jface.text.link.ILinkedModeListener; 30 import org.eclipse.jface.text.link.InclusivePositionUpdater; 31 import org.eclipse.jface.text.link.LinkedModeModel; 32 import org.eclipse.jface.text.link.LinkedModeUI; 33 import org.eclipse.jface.text.link.LinkedPosition; 34 import org.eclipse.jface.text.link.LinkedPositionGroup; 35 import org.eclipse.jface.text.link.ProposalPosition; 36 37 import org.eclipse.ui.IEditorPart; 38 import org.eclipse.ui.texteditor.link.EditorLinkedModeUI; 39 40 import org.eclipse.jdt.core.CompletionProposal; 41 import org.eclipse.jdt.core.ICompilationUnit; 42 import org.eclipse.jdt.core.JavaModelException; 43 import org.eclipse.jdt.core.Signature; 44 45 import org.eclipse.jdt.internal.corext.template.java.SignatureUtil; 46 import org.eclipse.jdt.internal.corext.util.JavaModelUtil; 47 48 import org.eclipse.jdt.ui.text.java.JavaContentAssistInvocationContext; 49 50 import org.eclipse.jdt.internal.ui.JavaPlugin; 51 import org.eclipse.jdt.internal.ui.javaeditor.EditorHighlightingSynchronizer; 52 import org.eclipse.jdt.internal.ui.javaeditor.JavaEditor; 53 54 58 public final class ParameterGuessingProposal extends JavaMethodCompletionProposal { 59 60 61 private static final boolean DEBUG= "true".equalsIgnoreCase(Platform.getDebugOption("org.eclipse.jdt.ui/debug/ResultCollector")); 63 private ICompletionProposal[][] fChoices; private Position[] fPositions; 66 private IRegion fSelectedRegion; private IPositionUpdater fUpdater; 68 69 public ParameterGuessingProposal(CompletionProposal proposal, JavaContentAssistInvocationContext context) { 70 super(proposal, context); 71 } 72 73 76 public void apply(IDocument document, char trigger, int offset) { 77 try { 78 super.apply(document, trigger, offset); 79 80 int baseOffset= getReplacementOffset(); 81 String replacement= getReplacementString(); 82 83 if (fPositions != null && getTextViewer() != null) { 84 85 LinkedModeModel model= new LinkedModeModel(); 86 87 for (int i= 0; i < fPositions.length; i++) { 88 LinkedPositionGroup group= new LinkedPositionGroup(); 89 int positionOffset= fPositions[i].getOffset(); 90 int positionLength= fPositions[i].getLength(); 91 92 if (fChoices[i].length < 2) { 93 group.addPosition(new LinkedPosition(document, positionOffset, positionLength, LinkedPositionGroup.NO_STOP)); 94 } else { 95 ensurePositionCategoryInstalled(document, model); 96 document.addPosition(getCategory(), fPositions[i]); 97 group.addPosition(new ProposalPosition(document, positionOffset, positionLength, LinkedPositionGroup.NO_STOP, fChoices[i])); 98 } 99 model.addGroup(group); 100 } 101 102 model.forceInstall(); 103 JavaEditor editor= getJavaEditor(); 104 if (editor != null) { 105 model.addLinkingListener(new EditorHighlightingSynchronizer(editor)); 106 } 107 108 LinkedModeUI ui= new EditorLinkedModeUI(model, getTextViewer()); 109 ui.setExitPosition(getTextViewer(), baseOffset + replacement.length(), 0, Integer.MAX_VALUE); 110 ui.setExitPolicy(new ExitPolicy(')', document)); 111 ui.setCyclingMode(LinkedModeUI.CYCLE_WHEN_NO_PARENT); 112 ui.setDoContextInfo(true); 113 ui.enter(); 114 fSelectedRegion= ui.getSelectedRegion(); 115 116 } else { 117 fSelectedRegion= new Region(baseOffset + replacement.length(), 0); 118 } 119 120 } catch (BadLocationException e) { 121 ensurePositionCategoryRemoved(document); 122 JavaPlugin.log(e); 123 openErrorDialog(e); 124 } catch (BadPositionCategoryException e) { 125 ensurePositionCategoryRemoved(document); 126 JavaPlugin.log(e); 127 openErrorDialog(e); 128 } 129 } 130 131 134 protected boolean needsLinkedMode() { 135 return false; } 137 138 141 protected String computeReplacementString() { 142 143 if (!hasParameters() || !hasArgumentList()) 144 return super.computeReplacementString(); 145 146 long millis= DEBUG ? System.currentTimeMillis() : 0; 147 String replacement; 148 try { 149 replacement= computeGuessingCompletion(); 150 } catch (JavaModelException x) { 151 fPositions= null; 152 fChoices= null; 153 JavaPlugin.log(x); 154 openErrorDialog(x); 155 return super.computeReplacementString(); 156 } 157 if (DEBUG) System.err.println("Parameter Guessing: " + (System.currentTimeMillis() - millis)); 159 return replacement; 160 } 161 162 166 private String computeGuessingCompletion() throws JavaModelException { 167 168 StringBuffer buffer= new StringBuffer (String.valueOf(fProposal.getName())); 169 170 FormatterPrefs prefs= getFormatterPrefs(); 171 if (prefs.beforeOpeningParen) 172 buffer.append(SPACE); 173 buffer.append(LPAREN); 174 175 setCursorPosition(buffer.length()); 176 177 if (prefs.afterOpeningParen) 178 buffer.append(SPACE); 179 180 fChoices= guessParameters(); 181 int count= fChoices.length; 182 int replacementOffset= getReplacementOffset(); 183 184 for (int i= 0; i < count; i++) { 185 if (i != 0) { 186 if (prefs.beforeComma) 187 buffer.append(SPACE); 188 buffer.append(COMMA); 189 if (prefs.afterComma) 190 buffer.append(SPACE); 191 } 192 193 ICompletionProposal proposal= fChoices[i][0]; 194 String argument= proposal.getDisplayString(); 195 Position position= fPositions[i]; 196 position.setOffset(replacementOffset + buffer.length()); 197 position.setLength(argument.length()); 198 if (proposal instanceof JavaCompletionProposal) ((JavaCompletionProposal) proposal).setReplacementOffset(replacementOffset + buffer.length()); 200 buffer.append(argument); 201 } 202 203 if (prefs.beforeClosingParen) 204 buffer.append(SPACE); 205 206 buffer.append(RPAREN); 207 208 return buffer.toString(); 209 } 210 211 217 private JavaEditor getJavaEditor() { 218 IEditorPart part= JavaPlugin.getActivePage().getActiveEditor(); 219 if (part instanceof JavaEditor) 220 return (JavaEditor) part; 221 else 222 return null; 223 } 224 225 private ICompletionProposal[][] guessParameters() throws JavaModelException { 226 237 char[][] parameterNames= fProposal.findParameterNames(null); 238 int count= parameterNames.length; 239 fPositions= new Position[count]; 240 fChoices= new ICompletionProposal[count][]; 241 242 IDocument document= fInvocationContext.getDocument(); 243 ICompilationUnit cu= fInvocationContext.getCompilationUnit(); 244 JavaModelUtil.reconcile(cu); 245 String [][] parameterTypes= getParameterSignatures(); 246 ParameterGuesser guesser= new ParameterGuesser(fProposal.getCompletionLocation() + 1, cu); 247 248 for (int i= count - 1; i >= 0; i--) { 249 String paramName= new String (parameterNames[i]); 250 Position position= new Position(0,0); 251 252 ICompletionProposal[] argumentProposals= guesser.parameterProposals(parameterTypes[i][0], parameterTypes[i][1], paramName, position, document); 253 if (argumentProposals.length == 0) 254 argumentProposals= new ICompletionProposal[] {new JavaCompletionProposal(paramName, 0, paramName.length(), null, paramName, 0)}; 255 256 fPositions[i]= position; 257 fChoices[i]= argumentProposals; 258 } 259 260 return fChoices; 261 } 262 263 private String [][] getParameterSignatures() { 264 char[] signature= SignatureUtil.fix83600(fProposal.getSignature()); 265 char[][] types= Signature.getParameterTypes(signature); 266 String [][] ret= new String [types.length][2]; 267 268 for (int i= 0; i < types.length; i++) { 269 char[] type= SignatureUtil.getLowerBound(types[i]); 270 ret[i][0]= String.valueOf(Signature.getSignatureQualifier(type)); 271 ret[i][1]= String.valueOf(Signature.getSignatureSimpleName(type)); 272 } 273 return ret; 274 } 275 276 279 public Point getSelection(IDocument document) { 280 if (fSelectedRegion == null) 281 return new Point(getReplacementOffset(), 0); 282 283 return new Point(fSelectedRegion.getOffset(), fSelectedRegion.getLength()); 284 } 285 286 private void openErrorDialog(Exception e) { 287 Shell shell= getTextViewer().getTextWidget().getShell(); 288 MessageDialog.openError(shell, JavaTextMessages.ParameterGuessingProposal_error_msg, e.getMessage()); 289 } 290 291 private void ensurePositionCategoryInstalled(final IDocument document, LinkedModeModel model) { 292 if (!document.containsPositionCategory(getCategory())) { 293 document.addPositionCategory(getCategory()); 294 fUpdater= new InclusivePositionUpdater(getCategory()); 295 document.addPositionUpdater(fUpdater); 296 297 model.addLinkingListener(new ILinkedModeListener() { 298 299 302 public void left(LinkedModeModel environment, int flags) { 303 ensurePositionCategoryRemoved(document); 304 } 305 306 public void suspend(LinkedModeModel environment) {} 307 public void resume(LinkedModeModel environment, int flags) {} 308 }); 309 } 310 } 311 312 private void ensurePositionCategoryRemoved(IDocument document) { 313 if (document.containsPositionCategory(getCategory())) { 314 try { 315 document.removePositionCategory(getCategory()); 316 } catch (BadPositionCategoryException e) { 317 } 319 document.removePositionUpdater(fUpdater); 320 } 321 } 322 323 private String getCategory() { 324 return "ParameterGuessingProposal_" + toString(); } 326 327 } 328 | Popular Tags |