--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
+ * 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.ui.text.java;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.NullProgressMonitor;
+
+import org.eclipse.text.edits.MalformedTreeException;
+
+import org.eclipse.jface.viewers.StyledString;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.TextUtilities;
+import org.eclipse.jface.text.contentassist.ICompletionProposalExtension4;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.dom.ASTNode;
+import org.eclipse.jdt.core.dom.ASTParser;
+import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
+import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
+import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.IMethodBinding;
+import org.eclipse.jdt.core.dom.ITypeBinding;
+import org.eclipse.jdt.core.dom.MethodDeclaration;
+import org.eclipse.jdt.core.dom.NodeFinder;
+import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
+import org.eclipse.jdt.core.dom.rewrite.ITrackedNodePosition;
+import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
+import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext;
+import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
+import org.eclipse.jdt.core.formatter.IndentManipulation;
+
+import org.eclipse.jdt.internal.corext.codemanipulation.CodeGenerationSettings;
+import org.eclipse.jdt.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext;
+import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
+import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility2;
+import org.eclipse.jdt.internal.corext.dom.Bindings;
+
+import org.eclipse.jdt.ui.SharedASTProvider;
+
+import org.eclipse.jdt.internal.ui.JavaPlugin;
+import org.eclipse.jdt.internal.ui.javaeditor.ASTProvider;
+import org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings;
+
+public class OverrideCompletionProposal extends JavaTypeCompletionProposal implements ICompletionProposalExtension4 {
+
+ private IJavaProject fJavaProject;
+ private String fMethodName;
+ private String[] fParamTypes;
+
+ public OverrideCompletionProposal(IJavaProject jproject, ICompilationUnit cu, String methodName, String[] paramTypes, int start, int length, StyledString displayName, String completionProposal) {
+ super(completionProposal, cu, start, length, null, displayName, 0);
+ Assert.isNotNull(jproject);
+ Assert.isNotNull(methodName);
+ Assert.isNotNull(paramTypes);
+ Assert.isNotNull(cu);
+
+ fParamTypes= paramTypes;
+ fMethodName= methodName;
+
+ fJavaProject= jproject;
+
+ StringBuffer buffer= new StringBuffer();
+ buffer.append(completionProposal);
+ buffer.append(" {};"); //$NON-NLS-1$
+
+ setReplacementString(buffer.toString());
+ }
+
+ /*
+ * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension3#getPrefixCompletionText(org.eclipse.jface.text.IDocument,int)
+ */
+ @Override
+ public CharSequence getPrefixCompletionText(IDocument document, int completionOffset) {
+ return fMethodName;
+ }
+
+ private CompilationUnit getRecoveredAST(IDocument document, int offset, Document recoveredDocument) {
+ CompilationUnit ast= SharedASTProvider.getAST(fCompilationUnit, SharedASTProvider.WAIT_ACTIVE_ONLY, null);
+ if (ast != null) {
+ recoveredDocument.set(document.get());
+ return ast;
+ }
+
+ char[] content= document.get().toCharArray();
+
+ // clear prefix to avoid compile errors
+ int index= offset - 1;
+ while (index >= 0 && Character.isJavaIdentifierPart(content[index])) {
+ content[index]= ' ';
+ index--;
+ }
+
+ recoveredDocument.set(new String(content));
+
+ final ASTParser parser= ASTParser.newParser(ASTProvider.SHARED_AST_LEVEL);
+ parser.setResolveBindings(true);
+ parser.setStatementsRecovery(true);
+ parser.setSource(content);
+ parser.setUnitName(fCompilationUnit.getElementName());
+ parser.setProject(fCompilationUnit.getJavaProject());
+ return (CompilationUnit) parser.createAST(new NullProgressMonitor());
+ }
+
+ /*
+ * @see JavaTypeCompletionProposal#updateReplacementString(IDocument,char,int,ImportRewrite)
+ */
+ @Override
+ protected boolean updateReplacementString(IDocument document, char trigger, int offset, ImportRewrite importRewrite) throws CoreException, BadLocationException {
+ Document recoveredDocument= new Document();
+ CompilationUnit unit= getRecoveredAST(document, offset, recoveredDocument);
+ ImportRewriteContext context;
+ if (importRewrite != null) {
+ context= new ContextSensitiveImportRewriteContext(unit, offset, importRewrite);
+ } else {
+ importRewrite= StubUtility.createImportRewrite(unit, true); // create a dummy import rewriter to have one
+ context= new ImportRewriteContext() { // forces that all imports are fully qualified
+ @Override
+ public int findInContext(String qualifier, String name, int kind) {
+ return RES_NAME_CONFLICT;
+ }
+ };
+ }
+
+ ITypeBinding declaringType= null;
+ ChildListPropertyDescriptor descriptor= null;
+ ASTNode node= NodeFinder.perform(unit, offset, 1);
+ if (node instanceof AnonymousClassDeclaration) {
+ declaringType= ((AnonymousClassDeclaration) node).resolveBinding();
+ descriptor= AnonymousClassDeclaration.BODY_DECLARATIONS_PROPERTY;
+ } else if (node instanceof AbstractTypeDeclaration) {
+ AbstractTypeDeclaration declaration= (AbstractTypeDeclaration) node;
+ descriptor= declaration.getBodyDeclarationsProperty();
+ declaringType= declaration.resolveBinding();
+ }
+ if (declaringType != null) {
+ ASTRewrite rewrite= ASTRewrite.create(unit.getAST());
+ IMethodBinding methodToOverride= Bindings.findMethodInHierarchy(declaringType, fMethodName, fParamTypes);
+ if (methodToOverride == null && declaringType.isInterface()) {
+ methodToOverride= Bindings.findMethodInType(node.getAST().resolveWellKnownType("java.lang.Object"), fMethodName, fParamTypes); //$NON-NLS-1$
+ }
+ if (methodToOverride != null) {
+ CodeGenerationSettings settings= JavaPreferencesSettings.getCodeGenerationSettings(fJavaProject);
+ MethodDeclaration stub= StubUtility2.createImplementationStub(fCompilationUnit, rewrite, importRewrite, context, methodToOverride, declaringType.getName(), settings, declaringType.isInterface());
+ ListRewrite rewriter= rewrite.getListRewrite(node, descriptor);
+ rewriter.insertFirst(stub, null);
+
+ ITrackedNodePosition position= rewrite.track(stub);
+ try {
+ rewrite.rewriteAST(recoveredDocument, fJavaProject.getOptions(true)).apply(recoveredDocument);
+
+ String generatedCode= recoveredDocument.get(position.getStartPosition(), position.getLength());
+ int generatedIndent= IndentManipulation.measureIndentUnits(getIndentAt(recoveredDocument, position.getStartPosition(), settings), settings.tabWidth, settings.indentWidth);
+
+ String indent= getIndentAt(document, getReplacementOffset(), settings);
+ setReplacementString(IndentManipulation.changeIndent(generatedCode, generatedIndent, settings.tabWidth, settings.indentWidth, indent, TextUtilities.getDefaultLineDelimiter(document)));
+
+ } catch (MalformedTreeException exception) {
+ JavaPlugin.log(exception);
+ } catch (BadLocationException exception) {
+ JavaPlugin.log(exception);
+ }
+ }
+ }
+ return true;
+ }
+
+ private static String getIndentAt(IDocument document, int offset, CodeGenerationSettings settings) {
+ try {
+ IRegion region= document.getLineInformationOfOffset(offset);
+ return IndentManipulation.extractIndentString(document.get(region.getOffset(), region.getLength()), settings.tabWidth, settings.indentWidth);
+ } catch (BadLocationException e) {
+ return ""; //$NON-NLS-1$
+ }
+ }
+
+ /*
+ * @see org.eclipse.jface.text.contentassist.ICompletionProposalExtension4#isAutoInsertable()
+ */
+ public boolean isAutoInsertable() {
+ return false;
+ }
+}