| /******************************************************************************* |
| * 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 java.lang.annotation.Annotation; |
| import java.lang.reflect.Proxy; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.List; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.jdt.apt.core.internal.EclipseMirrorImpl; |
| import org.eclipse.jdt.apt.core.internal.env.AnnotationInvocationHandler; |
| import org.eclipse.jdt.apt.core.internal.env.BaseProcessorEnv; |
| import org.eclipse.jdt.apt.core.internal.util.Factory; |
| import org.eclipse.jdt.core.dom.ASTNode; |
| 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.IResolvedAnnotation; |
| 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; |
| |
| import com.sun.mirror.declaration.AnnotationMirror; |
| import com.sun.mirror.declaration.Declaration; |
| import com.sun.mirror.util.DeclarationVisitor; |
| |
| public abstract class EclipseDeclarationImpl implements Declaration, EclipseMirrorImpl |
| { |
| final BaseProcessorEnv _env; |
| |
| EclipseDeclarationImpl(final BaseProcessorEnv env) |
| { |
| assert env != null : "missing environment"; //$NON-NLS-1$ |
| _env = env; |
| } |
| |
| public void accept(DeclarationVisitor visitor) |
| { |
| visitor.visitDeclaration(this); |
| } |
| |
| <A extends Annotation> A _getAnnotation(Class<A> annotationClass, |
| IResolvedAnnotation[] annoInstances) |
| { |
| if( annoInstances == null || annoInstances.length == 0 || annotationClass == null ) |
| return null; |
| |
| String annoTypeName = annotationClass.getName(); |
| if( annoTypeName == null ) return null; |
| annoTypeName = annoTypeName.replace('$', '.'); |
| final int len = annoInstances == null ? 0 : annoInstances.length; |
| if( len == 0 ) return null; |
| for( IResolvedAnnotation annoInstance : annoInstances){ |
| final ITypeBinding binding = annoInstance.getAnnotationType(); |
| if( binding != null && binding.isAnnotation() ){ |
| final String curTypeName = binding.getQualifiedName(); |
| if( annoTypeName.equals(curTypeName) ){ |
| final AnnotationMirrorImpl annoMirror = |
| (AnnotationMirrorImpl)Factory.createAnnotationMirror(annoInstance, this, _env); |
| final AnnotationInvocationHandler handler = new AnnotationInvocationHandler(annoMirror, annotationClass); |
| return (A)Proxy.newProxyInstance(annotationClass.getClassLoader(), |
| new Class[]{ annotationClass }, handler ); |
| } |
| } |
| } |
| return null; |
| } |
| |
| Collection<AnnotationMirror> _getAnnotationMirrors(IResolvedAnnotation[] annoInstances) |
| { |
| final int len = annoInstances == null ? 0 : annoInstances.length; |
| if( len == 0 ) return Collections.emptyList(); |
| final List<AnnotationMirror> result = new ArrayList<AnnotationMirror>(len); |
| for(IResolvedAnnotation annoInstance : annoInstances){ |
| final AnnotationMirrorImpl annoMirror = |
| (AnnotationMirrorImpl)Factory.createAnnotationMirror(annoInstance, this, _env); |
| result.add(annoMirror); |
| } |
| return result; |
| } |
| |
| Collection<AnnotationMirror> _getAnnotationMirrors(List<org.eclipse.jdt.core.dom.Annotation> annoInstances) |
| { |
| if( annoInstances == null || annoInstances.size() == 0 ) return Collections.emptyList(); |
| final List<AnnotationMirror> result = new ArrayList<AnnotationMirror>(annoInstances.size()); |
| for( org.eclipse.jdt.core.dom.Annotation annoInstance : annoInstances){ |
| final AnnotationMirrorImpl annoMirror = |
| (AnnotationMirrorImpl)Factory.createAnnotationMirror(annoInstance.resolveAnnotation(), this, _env); |
| result.add(annoMirror); |
| } |
| return result; |
| } |
| |
| /** |
| * @return the ast node that corresponding to this declaration. |
| * Return null if this declaration came from binary. |
| * @see #isFromSource(); |
| */ |
| abstract ASTNode getAstNode(); |
| |
| /** |
| * @return the compilation unit that the ast node of this declaration came from |
| * Return null if this declaration came from binary. |
| * @see #isFromSource() |
| */ |
| abstract CompilationUnit getCompilationUnit(); |
| |
| /** |
| * @return the resource of this declaration if the declaration is from source. |
| */ |
| abstract public IFile getResource(); |
| |
| /** |
| * @return true iff this declaration came from a source file. |
| * Return false otherwise. |
| */ |
| public abstract boolean isFromSource(); |
| |
| public abstract boolean isBindingBased(); |
| |
| public BaseProcessorEnv getEnvironment(){ return _env; } |
| |
| /** |
| * @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. |
| */ |
| protected 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; |
| } |
| |
| protected String getDocComment(final BodyDeclaration decl) |
| { |
| final Javadoc javaDoc = decl.getJavadoc(); |
| if( javaDoc == null ) return ""; //$NON-NLS-1$ |
| return javaDoc.toString(); |
| } |
| } |