blob: 02e9c0ea70ef25cf2453685f2b723440998f3e35 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2007 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.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.eclipse.core.resources.IFile;
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.BodyDeclaration;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import com.sun.mirror.declaration.ClassDeclaration;
import com.sun.mirror.declaration.ConstructorDeclaration;
import com.sun.mirror.declaration.Declaration;
import com.sun.mirror.declaration.MethodDeclaration;
import com.sun.mirror.type.ClassType;
import com.sun.mirror.util.DeclarationVisitor;
import com.sun.mirror.util.TypeVisitor;
public class ClassDeclarationImpl extends TypeDeclarationImpl implements ClassDeclaration, ClassType
{
public ClassDeclarationImpl(final ITypeBinding binding, final BaseProcessorEnv env)
{
super(binding, env);
// Enum types return false for isClass().
assert !binding.isInterface();
}
public void accept(DeclarationVisitor visitor)
{
visitor.visitClassDeclaration(this);
}
@SuppressWarnings("unchecked")
private void getASTConstructor(
final AbstractTypeDeclaration typeDecl,
final List<ConstructorDeclaration> results){
final List bodyDecls = typeDecl.bodyDeclarations();
IFile file = null;
for( int i=0, len=bodyDecls.size(); i<len; i++ ){
final BodyDeclaration bodyDecl = (BodyDeclaration)bodyDecls.get(i);
if( bodyDecl.getNodeType() == ASTNode.METHOD_DECLARATION ){
final org.eclipse.jdt.core.dom.MethodDeclaration methodDecl =
(org.eclipse.jdt.core.dom.MethodDeclaration)bodyDecl;
if( methodDecl.isConstructor() ){
final IMethodBinding methodBinding = methodDecl.resolveBinding();
// built an ast based representation.
if( methodBinding == null ){
if( file == null )
file = getResource();
ConstructorDeclaration mirrorDecl =
(ConstructorDeclaration)Factory.createDeclaration(methodDecl, file, _env);
if( mirrorDecl != null )
results.add(mirrorDecl);
}
}
}
}
}
public Collection<ConstructorDeclaration> getConstructors()
{
final List<ConstructorDeclaration> results = new ArrayList<ConstructorDeclaration>();
if( isFromSource() ){
// need to consult the ast since methods with broken signature
// do not appear in bindings.
final ITypeBinding typeBinding = getDeclarationBinding();
final ASTNode node =
_env.getASTNodeForBinding(typeBinding);
if( node != null ){
switch( node.getNodeType() )
{
case ASTNode.TYPE_DECLARATION:
case ASTNode.ANNOTATION_TYPE_DECLARATION:
case ASTNode.ENUM_DECLARATION:
AbstractTypeDeclaration typeDecl =
(AbstractTypeDeclaration)node;
// built the ast based methods first.
getASTConstructor(typeDecl, results);
break;
default:
// the ast node for a type binding should be a AbstractTypeDeclaration.
throw new IllegalStateException("expecting a AbstractTypeDeclaration but got " //$NON-NLS-1$
+ node.getClass().getName() );
}
}
}
// build methods for binding type or
// build the binding based method for source type.
final IMethodBinding[] methods = getDeclarationBinding().getDeclaredMethods();
for( IMethodBinding method : methods ){
if( method.isSynthetic() ) continue;
if( method.isConstructor() ){
Declaration mirrorDecl = Factory.createDeclaration(method, _env);
if( mirrorDecl != null)
results.add((ConstructorDeclaration)mirrorDecl);
}
}
return results;
}
@SuppressWarnings("unchecked")
public Collection<MethodDeclaration> getMethods()
{
return (Collection<MethodDeclaration>)_getMethods();
}
// Start of implementation of ClassType API
public void accept(TypeVisitor visitor)
{
visitor.visitClassType(this);
}
public ClassType getSuperclass()
{
final ITypeBinding superClass = getDeclarationBinding().getSuperclass();
if ( superClass == null )
return null;
else if( superClass.isClass() )
return (ClassType)Factory.createReferenceType(superClass, _env);
else // catch error case where user extends some interface instead of a class.
return Factory.createErrorClassType(superClass);
}
public ClassDeclaration getDeclaration()
{
return (ClassDeclaration)super.getDeclaration();
}
// End of implementation of ClassType API
public MirrorKind kind(){ return MirrorKind.TYPE_CLASS; }
}