blob: 6a212bc620c8bba6a8e0db7797c00eec9293a146 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2006 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.correction;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.swt.graphics.Image;
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.ChildListPropertyDescriptor;
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.ListRewrite;
import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory;
import org.eclipse.jdt.internal.corext.dom.ASTNodes;
/**
*
*/
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;
}
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) {
ASTRewrite rewrite= ASTRewrite.create(astRoot.getAST());
AnnotationTypeMemberDeclaration newStub= getStub(rewrite, (AnnotationTypeDeclaration) newTypeDecl);
ChildListPropertyDescriptor property= ASTNodes.getBodyDeclarationsProperty(newTypeDecl);
List members= (List) newTypeDecl.getStructuralProperty(property);
int insertIndex= members.size();
ListRewrite listRewriter= rewrite.getListRewrite(newTypeDecl, property);
listRewriter.insertAt(newStub, insertIndex, null);
return rewrite;
}
return null;
}
private AnnotationTypeMemberDeclaration getStub(ASTRewrite rewrite, AnnotationTypeDeclaration targetTypeDecl) throws CoreException {
AST ast= targetTypeDecl.getAST();
AnnotationTypeMemberDeclaration decl= ast.newAnnotationTypeMemberDeclaration();
SimpleName newNameNode= getNewName(rewrite);
decl.modifiers().addAll(ASTNodeFactory.newModifiers(ast, evaluateModifiers(targetTypeDecl)));
ModifierCorrectionSubProcessor.installLinkedVisibilityProposals(this, 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) {
newTypeNode= getImportRewrite().addImport(binding, ast);
}
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 methodDecls= targetTypeDecl.bodyDeclarations();
for (int i= 0; i < methodDecls.size(); i++) {
Object curr= methodDecls.get(i);
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;
}
}