blob: f2840b43d7b42c90e7496a0ea772254ee90c90cb [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005 BEA Systems, Inc.
* 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:
* tyeung@bea.com - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.apt.core.internal.declaration;
import com.sun.mirror.declaration.AnnotationMirror;
import com.sun.mirror.declaration.MemberDeclaration;
import com.sun.mirror.util.DeclarationVisitor;
import com.sun.mirror.util.SourcePosition;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.eclipse.jdt.apt.core.internal.EclipseMirrorImpl;
import org.eclipse.jdt.apt.core.internal.env.ProcessorEnvImpl;
import org.eclipse.jdt.apt.core.internal.util.SourcePositionImpl;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.ISourceReference;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.AST;
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.AnnotationTypeMemberDeclaration;
import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.IExtendedModifier;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.Javadoc;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
public abstract class MemberDeclarationImpl extends DeclarationImpl implements MemberDeclaration, EclipseMirrorImpl
{
MemberDeclarationImpl(final IBinding binding, ProcessorEnvImpl env)
{
super(binding, env);
}
public void accept(DeclarationVisitor visitor)
{
super.accept(visitor);
visitor.visitMemberDeclaration(this);
}
public <A extends Annotation> A getAnnotation(Class<A> annotationClass)
{
final BodyDeclaration astNode = (BodyDeclaration)getAstNode();
if(astNode != null){
final List<org.eclipse.jdt.core.dom.Annotation> annoInstances = getAnnotations();
return _getAnnotation(annotationClass, annoInstances);
}
else{
// TODO: (theodora) handle the binary case.
return null;
}
}
public Collection<AnnotationMirror> getAnnotationMirrors()
{
if( isFromSource() )
{
final List<org.eclipse.jdt.core.dom.Annotation> annoInstances = getAnnotations();
return _getAnnotationMirrors(annoInstances);
}
else{
// TODO: (theodora) handle the binary case.
return null;
}
}
public String getDocComment()
{
if( isFromSource()){
final Javadoc javaDoc = ((BodyDeclaration)getAstNode()).getJavadoc();
if( javaDoc == null ) return "";
return javaDoc.toString();
}
return null;
}
/**
* @return the ast node that holds the range of this member declaration in source.
* The default is to find the name of the node and if that fails, return the
* node with the smallest range that contains the declaration.
*/
private ASTNode getRangeNode()
{
final ASTNode node = getAstNode();
if( node == null ) return null;
SimpleName name = null;
switch( node.getNodeType() )
{
case ASTNode.TYPE_DECLARATION:
case ASTNode.ANNOTATION_TYPE_DECLARATION:
case ASTNode.ENUM_DECLARATION:
name = ((AbstractTypeDeclaration)node).getName();
break;
case ASTNode.ANNOTATION_TYPE_MEMBER_DECLARATION:
name = ((AnnotationTypeMemberDeclaration)node).getName();
break;
case ASTNode.METHOD_DECLARATION:
name = ((MethodDeclaration)node).getName();
break;
case ASTNode.SINGLE_VARIABLE_DECLARATION:
name = ((SingleVariableDeclaration)node).getName();
break;
case ASTNode.FIELD_DECLARATION:
final String declName = getSimpleName();
if( declName == null ) return node;
for(Object obj : ((FieldDeclaration)node).fragments() ){
VariableDeclarationFragment frag = (VariableDeclarationFragment)obj;
if( declName.equals(frag.getName()) ){
name = frag.getName();
break;
}
}
break;
case ASTNode.ENUM_CONSTANT_DECLARATION:
name = ((EnumConstantDeclaration)node).getName();
break;
default:
return node;
}
if( name == null ) return node;
return name;
}
/**
* @return the source position of this declaration.
* Return null if this declaration did not come from source or
* if the declaration is (or is part of) a secondary type that is defined
* outside of the file associated with the environment.
*/
public SourcePosition getPosition()
{
if( isFromSource() ){
final ASTNode node = getRangeNode();
if( node == null ) return null;
final CompilationUnit unit = getCompilationUnit();
final int start = node.getStartPosition();
return new SourcePositionImpl(start,
node.getLength(),
unit.lineNumber(start),
this);
}
return null;
}
/**
* @return the list of annotation ast node on the given body declaration.
* This declaration must came from source.
* Return the empty list if the declaration is part of a secondary type outside
* of the file associated with the environment.
*/
List<org.eclipse.jdt.core.dom.Annotation> getAnnotations()
{
assert isFromSource() : "Declaration did not come from source.";
final BodyDeclaration decl = (BodyDeclaration)getAstNode();
if( decl == null ) return Collections.emptyList();
final List<IExtendedModifier> extMods = decl.modifiers();
if( extMods == null || extMods.isEmpty() ) return Collections.emptyList();
List<org.eclipse.jdt.core.dom.Annotation> annos = new ArrayList<org.eclipse.jdt.core.dom.Annotation>(4);
for( IExtendedModifier extMod : extMods ){
if( extMod.isAnnotation() )
annos.add((org.eclipse.jdt.core.dom.Annotation)extMod);
}
return annos;
}
}