blob: 2e6feb107b093db07bb6c7c431df87cdf6397614 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2019 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.ui.text.correction.proposals;
import java.util.List;
import org.eclipse.swt.graphics.Image;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
import org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration;
import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.MemberValuePair;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext;
import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.TypeLocation;
import org.eclipse.jdt.core.dom.rewrite.ListRewrite;
import org.eclipse.jdt.internal.core.manipulation.dom.ASTResolving;
import org.eclipse.jdt.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext;
import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory;
import org.eclipse.jdt.internal.ui.text.correction.ModifierCorrectionSubProcessorCore;
public class NewAnnotationMemberProposal extends LinkedCorrectionProposal {
private static final String KEY_NAME= "name"; //$NON-NLS-1$
private static final String KEY_TYPE= "type"; //$NON-NLS-1$
private final ASTNode fInvocationNode;
private final ITypeBinding fSenderBinding;
public NewAnnotationMemberProposal(String label, ICompilationUnit targetCU, ASTNode invocationNode, ITypeBinding binding, int relevance, Image image) {
super(label, targetCU, null, relevance, image);
fInvocationNode= invocationNode;
fSenderBinding= binding;
}
@Override
protected ASTRewrite getRewrite() throws CoreException {
CompilationUnit astRoot= ASTResolving.findParentCompilationUnit(fInvocationNode);
ASTNode typeDecl= astRoot.findDeclaringNode(fSenderBinding);
ASTNode newTypeDecl= null;
if (typeDecl != null) {
newTypeDecl= typeDecl;
} else {
astRoot= ASTResolving.createQuickFixAST(getCompilationUnit(), null);
newTypeDecl= astRoot.findDeclaringNode(fSenderBinding.getKey());
}
createImportRewrite(astRoot);
if (newTypeDecl instanceof AnnotationTypeDeclaration) {
AnnotationTypeDeclaration newAnnotationTypeDecl= (AnnotationTypeDeclaration) newTypeDecl;
ASTRewrite rewrite= ASTRewrite.create(astRoot.getAST());
AnnotationTypeMemberDeclaration newStub= getStub(rewrite, newAnnotationTypeDecl);
List<BodyDeclaration> members= newAnnotationTypeDecl.bodyDeclarations();
int insertIndex= members.size();
ListRewrite listRewriter= rewrite.getListRewrite(newAnnotationTypeDecl, AnnotationTypeDeclaration.BODY_DECLARATIONS_PROPERTY);
listRewriter.insertAt(newStub, insertIndex, null);
return rewrite;
}
return null;
}
private AnnotationTypeMemberDeclaration getStub(ASTRewrite rewrite, AnnotationTypeDeclaration targetTypeDecl) {
AST ast= targetTypeDecl.getAST();
AnnotationTypeMemberDeclaration decl= ast.newAnnotationTypeMemberDeclaration();
SimpleName newNameNode= getNewName(rewrite);
decl.modifiers().addAll(ASTNodeFactory.newModifiers(ast, evaluateModifiers(targetTypeDecl)));
ModifierCorrectionSubProcessorCore.installLinkedVisibilityProposals(getLinkedProposalModel(), rewrite, decl.modifiers(), true);
decl.setName(newNameNode);
Type returnType= getNewType(rewrite);
decl.setType(returnType);
return decl;
}
private Type getNewType(ASTRewrite rewrite) {
AST ast= rewrite.getAST();
Type newTypeNode= null;
ITypeBinding binding= null;
if (fInvocationNode.getLocationInParent() == MemberValuePair.NAME_PROPERTY) {
Expression value= ((MemberValuePair) fInvocationNode.getParent()).getValue();
binding= value.resolveTypeBinding();
} else if (fInvocationNode instanceof Expression) {
binding= ((Expression) fInvocationNode).resolveTypeBinding();
}
if (binding != null) {
ImportRewriteContext importRewriteContext= new ContextSensitiveImportRewriteContext(fInvocationNode, getImportRewrite());
newTypeNode= getImportRewrite().addImport(binding, ast, importRewriteContext, TypeLocation.RETURN_TYPE);
}
if (newTypeNode == null) {
newTypeNode= ast.newSimpleType(ast.newSimpleName("String")); //$NON-NLS-1$
}
addLinkedPosition(rewrite.track(newTypeNode), false, KEY_TYPE);
return newTypeNode;
}
private int evaluateModifiers(AnnotationTypeDeclaration targetTypeDecl) {
List<BodyDeclaration> methodDecls= targetTypeDecl.bodyDeclarations();
for (BodyDeclaration curr : methodDecls) {
if (curr instanceof AnnotationTypeMemberDeclaration) {
return ((AnnotationTypeMemberDeclaration) curr).getModifiers();
}
}
return 0;
}
private SimpleName getNewName(ASTRewrite rewrite) {
AST ast= rewrite.getAST();
String name;
if (fInvocationNode.getLocationInParent() == MemberValuePair.NAME_PROPERTY) {
name= ((SimpleName) fInvocationNode).getIdentifier();
if (ast == fInvocationNode.getAST()) {
addLinkedPosition(rewrite.track(fInvocationNode), true, KEY_NAME);
}
} else {
name= "value"; //$NON-NLS-1$
}
SimpleName newNameNode= ast.newSimpleName(name);
addLinkedPosition(rewrite.track(newNameNode), false, KEY_NAME);
return newNameNode;
}
}