package org.eclipse.jdt.internal.corext.codemanipulation;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
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.Modifier;
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
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.internal.core.manipulation.StubUtility;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
import org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings;
public final class AddUnimplementedConstructorsOperation implements IWorkspaceRunnable {
private final boolean fApply;
private String[] fCreatedImports;
private final List<String> fCreatedMethods= new ArrayList<>();
private final boolean fImports;
private final int fInsertPos;
private final IMethodBinding[] fConstructorsToImplement;
private boolean fOmitSuper;
private final boolean fSave;
private boolean ;
private final ITypeBinding fType;
private final CompilationUnit fASTRoot;
private int fVisibility;
private Map<String, String> fFormatSettings;
private TextEdit fResultingEdit= null;
public AddUnimplementedConstructorsOperation(CompilationUnit astRoot, ITypeBinding type, IMethodBinding[] constructorsToImplement, int insertPos, final boolean imports, final boolean apply, final boolean save, Map<String, String> formatSettings) {
if (astRoot == null || !(astRoot.getJavaElement() instanceof ICompilationUnit)) {
throw new IllegalArgumentException("AST must not be null and has to be created from a ICompilationUnit");
}
if (type == null) {
throw new IllegalArgumentException("The type must not be null");
}
ASTNode node= astRoot.findDeclaringNode(type);
if (!(node instanceof AnonymousClassDeclaration || node instanceof AbstractTypeDeclaration)) {
throw new IllegalArgumentException("type has to map to a type declaration in the AST");
}
fType= type;
fInsertPos= insertPos;
fASTRoot= astRoot;
fConstructorsToImplement= constructorsToImplement;
fSave= save;
fApply= apply;
fImports= imports;
fCreateComments= StubUtility.doAddComments(astRoot.getJavaElement().getJavaProject());
fVisibility= Modifier.PUBLIC;
fOmitSuper= false;
fFormatSettings= formatSettings;
}
public String[] getCreatedConstructors() {
final String[] keys= new String[fCreatedMethods.size()];
fCreatedMethods.toArray(keys);
return keys;
}
public String[] getCreatedImports() {
return fCreatedImports;
}
public ISchedulingRule getSchedulingRule() {
return ResourcesPlugin.getWorkspace().getRoot();
}
public final TextEdit getResultingEdit() {
return fResultingEdit;
}
public int getVisibility() {
return fVisibility;
}
public boolean isOmitSuper() {
return fOmitSuper;
}
public void (final boolean comments) {
fCreateComments= comments;
}
@Override
public void run(IProgressMonitor monitor) throws CoreException {
if (monitor == null)
monitor= new NullProgressMonitor();
try {
monitor.beginTask("", 2);
monitor.setTaskName(CodeGenerationMessages.AddUnimplementedMethodsOperation_description);
fCreatedMethods.clear();
ICompilationUnit cu= (ICompilationUnit) fASTRoot.getJavaElement();
AST ast= fASTRoot.getAST();
ASTRewrite astRewrite= ASTRewrite.create(ast);
ImportRewrite importRewrite= StubUtility.createImportRewrite(fASTRoot, true);
ITypeBinding currTypeBinding= fType;
ListRewrite memberRewriter= null;
ASTNode node= fASTRoot.findDeclaringNode(currTypeBinding);
if (node instanceof AnonymousClassDeclaration) {
memberRewriter= astRewrite.getListRewrite(node, AnonymousClassDeclaration.BODY_DECLARATIONS_PROPERTY);
} else if (node instanceof AbstractTypeDeclaration) {
ChildListPropertyDescriptor property= ((AbstractTypeDeclaration) node).getBodyDeclarationsProperty();
memberRewriter= astRewrite.getListRewrite(node, property);
} else {
throw new IllegalArgumentException();
}
final CodeGenerationSettings settings= JavaPreferencesSettings.getCodeGenerationSettings(cu.getJavaProject());
settings.createComments= fCreateComments;
ASTNode insertion= getNodeToInsertBefore(memberRewriter);
IMethodBinding[] toImplement= fConstructorsToImplement;
if (toImplement == null) {
toImplement= StubUtility2Core.getVisibleConstructors(currTypeBinding, true, true);
}
int deprecationCount= 0;
for (int i= 0; i < toImplement.length; i++) {
if (toImplement[i].isDeprecated())
deprecationCount++;
}
boolean createDeprecated= deprecationCount == toImplement.length;
for (int i= 0; i < toImplement.length; i++) {
IMethodBinding curr= toImplement[i];
if (!curr.isDeprecated() || createDeprecated) {
ImportRewriteContext context= new ContextSensitiveImportRewriteContext(node, importRewrite);
MethodDeclaration stub= StubUtility2Core.createConstructorStub(cu, astRewrite, importRewrite, context, curr, currTypeBinding.getName(), fVisibility, fOmitSuper, true, settings, fFormatSettings);
if (stub != null) {
fCreatedMethods.add(curr.getKey());
if (insertion != null)
memberRewriter.insertBefore(stub, insertion, null);
else
memberRewriter.insertLast(stub, null);
}
}
}
fResultingEdit= new MultiTextEdit();
TextEdit importEdits= importRewrite.rewriteImports(new SubProgressMonitor(monitor, 1));
fCreatedImports= importRewrite.getCreatedImports();
if (fImports) {
fResultingEdit.addChild(importEdits);
}
fResultingEdit.addChild(astRewrite.rewriteAST());
if (fApply) {
JavaModelUtil.applyEdit(cu, fResultingEdit, fSave, new SubProgressMonitor(monitor, 1));
}
} finally {
monitor.done();
}
}
public void setOmitSuper(final boolean omit) {
fOmitSuper= omit;
}
public void setVisibility(final int visibility) {
fVisibility= visibility;
}
private ASTNode getNodeToInsertBefore(ListRewrite rewriter) {
if (fInsertPos != -1) {
List<?> members= rewriter.getOriginalList();
for (int i= 0; i < members.size(); i++) {
ASTNode curr= (ASTNode) members.get(i);
if (curr.getStartPosition() >= fInsertPos) {
return curr;
}
}
}
return null;
}
}