1 11 package org.eclipse.jdt.internal.ui.text.template.contentassist; 12 13 import java.util.ArrayList ; 14 import java.util.List ; 15 import java.util.Map ; 16 17 import org.eclipse.text.edits.MalformedTreeException; 18 19 import org.eclipse.core.runtime.CoreException; 20 21 import org.eclipse.swt.graphics.Image; 22 import org.eclipse.swt.graphics.Point; 23 import org.eclipse.swt.widgets.Shell; 24 25 import org.eclipse.jface.dialogs.MessageDialog; 26 27 import org.eclipse.jface.text.BadLocationException; 28 import org.eclipse.jface.text.Document; 29 import org.eclipse.jface.text.DocumentEvent; 30 import org.eclipse.jface.text.IDocument; 31 import org.eclipse.jface.text.IRegion; 32 import org.eclipse.jface.text.IRewriteTarget; 33 import org.eclipse.jface.text.ITextViewer; 34 import org.eclipse.jface.text.ITextViewerExtension; 35 import org.eclipse.jface.text.Region; 36 import org.eclipse.jface.text.templates.GlobalTemplateVariables; 37 import org.eclipse.jface.text.templates.Template; 38 import org.eclipse.jface.text.templates.TemplateBuffer; 39 import org.eclipse.jface.text.templates.TemplateException; 40 41 import org.eclipse.jdt.core.ICompilationUnit; 42 import org.eclipse.jdt.core.IJavaProject; 43 import org.eclipse.jdt.core.dom.AST; 44 import org.eclipse.jdt.core.dom.ASTNode; 45 import org.eclipse.jdt.core.dom.ASTParser; 46 import org.eclipse.jdt.core.dom.Block; 47 import org.eclipse.jdt.core.dom.MethodDeclaration; 48 import org.eclipse.jdt.core.dom.Statement; 49 50 import org.eclipse.jdt.internal.corext.dom.ASTNodes; 51 import org.eclipse.jdt.internal.corext.dom.GenericVisitor; 52 import org.eclipse.jdt.internal.corext.template.java.CompilationUnitContext; 53 import org.eclipse.jdt.internal.corext.template.java.CompilationUnitContextType; 54 import org.eclipse.jdt.internal.corext.template.java.JavaContextType; 55 56 import org.eclipse.jdt.ui.text.java.IInvocationContext; 57 58 import org.eclipse.jdt.internal.ui.JavaPlugin; 59 import org.eclipse.jdt.internal.ui.text.correction.AssistContext; 60 import org.eclipse.jdt.internal.ui.text.correction.SurroundWith; 61 62 public class SurroundWithTemplateProposal extends TemplateProposal { 63 64 private static class SurroundWithTemplate extends SurroundWith { 65 66 private static final String $_LINE_SELECTION= "${" + GlobalTemplateVariables.LineSelection.NAME + "}"; 68 private final Template fTemplate; 69 private final IJavaProject fCurrentProject; 70 private ASTNode fTemplateNode; 71 72 public SurroundWithTemplate(IInvocationContext context, Statement[] selectedNodes, Template template) { 73 super(context.getASTRoot(), selectedNodes); 74 fTemplate= template; 75 fCurrentProject= context.getCompilationUnit().getJavaProject(); 76 } 77 78 protected List getVariableDeclarationReadsInside(Statement[] selectedNodes, int maxVariableId) { 79 if (isNewContext()) 80 return super.getVariableDeclarationReadsInside(selectedNodes, maxVariableId); 81 return new ArrayList (); 82 } 83 84 protected boolean isNewContext() { 85 86 final String templateVariableRegEx= "\\$\\{[^\\}]*\\}"; 88 String template= fTemplate.getPattern(); 89 int currentPosition= template.indexOf($_LINE_SELECTION); 90 int insertionPosition= -1; 91 while (currentPosition != -1) { 92 insertionPosition= currentPosition; 93 template= template.replaceFirst(templateVariableRegEx, ""); currentPosition= template.indexOf($_LINE_SELECTION); 95 } 96 template= template.replaceAll(templateVariableRegEx, ""); 98 AST ast= getAst(); 99 ASTParser parser= ASTParser.newParser(ast.apiLevel()); 100 parser.setSource(template.toCharArray()); 101 parser.setProject(fCurrentProject); 102 parser.setKind(ASTParser.K_STATEMENTS); 103 ASTNode root= parser.createAST(null); 104 if (((Block)root).statements().isEmpty()) { 105 parser= ASTParser.newParser(ast.apiLevel()); 106 parser.setSource(template.toCharArray()); 107 parser.setProject(fCurrentProject); 108 parser.setKind(ASTParser.K_EXPRESSION); 109 root= parser.createAST(null); 110 } 111 112 final int lineSelectionPosition= insertionPosition; 113 root.accept(new GenericVisitor() { 114 public void endVisit(Block node) { 115 super.endVisit(node); 116 if (fTemplateNode == null && node.getStartPosition() <= lineSelectionPosition && node.getLength() + node.getStartPosition() >= lineSelectionPosition) { 117 fTemplateNode= node; 118 } 119 } 120 }); 121 122 if (fTemplateNode != null && ASTNodes.getParent(fTemplateNode, MethodDeclaration.class) != null) { 123 return true; 124 } 125 126 return false; 127 } 128 129 } 130 131 132 private final IRegion fRegion; 133 private final ICompilationUnit fCompilationUnit; 134 private final CompilationUnitContext fContext; 135 private final Template fTemplate; 136 private final Statement[] fSelectedStatements; 137 private TemplateProposal fProposal; 138 private IRegion fSelectedRegion; 139 140 public SurroundWithTemplateProposal(ICompilationUnit compilationUnit, Template template, CompilationUnitContext context, IRegion region, Image image, Statement[] selectedStatements) { 141 super(template, context, region, image); 142 fCompilationUnit= compilationUnit; 143 fTemplate= template; 144 fContext= context; 145 fRegion= region; 146 fSelectedStatements= selectedStatements; 147 } 148 149 152 public String getPreviewContent() { 153 try { 154 IDocument document= new Document(fCompilationUnit.getBuffer().getContents()); 155 CompilationUnitContext context= createNewContext(document); 156 157 int offset= context.getCompletionOffset(); 158 int start= context.getStart(); 159 int end= context.getEnd(); 160 IRegion region= new Region(start, end - start); 161 162 context.setReadOnly(false); 163 TemplateBuffer templateBuffer; 164 try { 165 templateBuffer= context.evaluate(fTemplate); 166 } catch (TemplateException e1) { 167 JavaPlugin.log(e1); 168 return null; 169 } 170 171 start= region.getOffset(); 172 end= region.getOffset() + region.getLength(); 173 end= Math.max(end, offset); 174 175 String templateString= templateBuffer.getString(); 176 document.replace(start, end - start, templateString); 177 178 return document.get(); 179 180 } catch (MalformedTreeException e) { 181 JavaPlugin.log(e); 182 } catch (IllegalArgumentException e) { 183 JavaPlugin.log(e); 184 } catch (BadLocationException e) { 185 JavaPlugin.log(e); 186 } catch (CoreException e) { 187 JavaPlugin.log(e); 188 } 189 return null; 190 } 191 192 195 public void apply(ITextViewer viewer, char trigger, int stateMask, int offset) { 196 try { 197 setRedraw(viewer, false); 198 IDocument document= viewer.getDocument(); 199 CompilationUnitContext context= createNewContext(document); 200 201 int start= context.getStart(); 202 int end= context.getEnd(); 203 IRegion region= new Region(start, end - start); 204 205 fProposal= new TemplateProposal(fTemplate, context, region, null); 207 fProposal.apply(viewer, trigger, stateMask, context.getCompletionOffset()); 208 } catch (MalformedTreeException e) { 209 handleException(viewer, e, fRegion); 210 } catch (IllegalArgumentException e) { 211 handleException(viewer, e, fRegion); 212 } catch (BadLocationException e) { 213 handleException(viewer, e, fRegion); 214 } catch (CoreException e) { 215 handleException(viewer, e, fRegion); 216 } finally { 217 setRedraw(viewer, true); 218 } 219 } 220 221 private void setRedraw(ITextViewer viewer, boolean redraw) { 222 if (viewer instanceof ITextViewerExtension) { 223 ITextViewerExtension extension= (ITextViewerExtension) viewer; 224 IRewriteTarget target= extension.getRewriteTarget(); 225 target.setRedraw(redraw); 226 } 227 } 228 229 public Point getSelection(IDocument document) { 230 if (fSelectedRegion != null) { 231 return new Point(fSelectedRegion.getOffset(), fSelectedRegion.getLength()); 232 } else if (fProposal != null) { 233 return fProposal.getSelection(document); 234 } else { 235 return null; 236 } 237 } 238 239 private CompilationUnitContext createNewContext(IDocument document) throws CoreException, BadLocationException { 240 AssistContext invocationContext= new AssistContext(fCompilationUnit, fContext.getStart(), fContext.getEnd() - fContext.getStart()); 241 242 SurroundWithTemplate surroundWith= new SurroundWithTemplate(invocationContext, fSelectedStatements, fTemplate); 243 Map options= fCompilationUnit.getJavaProject().getOptions(true); 244 245 surroundWith.getRewrite().rewriteAST(document, options).apply(document); 246 247 int offset= surroundWith.getBodyStart(); 248 int length= surroundWith.getBodyLength(); 249 String newSelection= document.get(offset, length); 250 251 CompilationUnitContextType contextType= (CompilationUnitContextType) JavaPlugin.getDefault().getTemplateContextRegistry().getContextType(JavaContextType.NAME); 253 CompilationUnitContext context= contextType.createContext(document, offset, newSelection.length(), fCompilationUnit); 254 context.setVariable("selection", newSelection); context.setForceEvaluation(true); 256 return context; 257 } 258 259 private void handleException(ITextViewer viewer, Exception e, IRegion region) { 260 JavaPlugin.log(e); 261 openErrorDialog(viewer.getTextWidget().getShell(), e); 262 fSelectedRegion= region; 263 } 264 265 private void openErrorDialog(Shell shell, Exception e) { 266 MessageDialog.openError(shell, TemplateContentAssistMessages.TemplateEvaluator_error_title, e.getMessage()); 267 } 268 269 272 public boolean validate(IDocument document, int offset, DocumentEvent event) { 273 return false; 274 } 275 } 276 | Popular Tags |