001: /*******************************************************************************
002: * Copyright (c) 2005, 2007 BEA Systems, Inc.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * tyeung@bea.com - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.apt.core.internal.declaration;
011:
012: import java.util.ArrayList;
013: import java.util.Collection;
014: import java.util.List;
015:
016: import org.eclipse.core.resources.IFile;
017: import org.eclipse.jdt.apt.core.internal.env.BaseProcessorEnv;
018: import org.eclipse.jdt.apt.core.internal.util.Factory;
019: import org.eclipse.jdt.core.dom.ASTNode;
020: import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
021: import org.eclipse.jdt.core.dom.BodyDeclaration;
022: import org.eclipse.jdt.core.dom.IMethodBinding;
023: import org.eclipse.jdt.core.dom.ITypeBinding;
024:
025: import com.sun.mirror.declaration.ClassDeclaration;
026: import com.sun.mirror.declaration.ConstructorDeclaration;
027: import com.sun.mirror.declaration.Declaration;
028: import com.sun.mirror.declaration.MethodDeclaration;
029: import com.sun.mirror.type.ClassType;
030: import com.sun.mirror.util.DeclarationVisitor;
031: import com.sun.mirror.util.TypeVisitor;
032:
033: public class ClassDeclarationImpl extends TypeDeclarationImpl implements
034: ClassDeclaration, ClassType {
035: public ClassDeclarationImpl(final ITypeBinding binding,
036: final BaseProcessorEnv env) {
037: super (binding, env);
038: // Enum types return false for isClass().
039: assert !binding.isInterface();
040: }
041:
042: public void accept(DeclarationVisitor visitor) {
043: visitor.visitClassDeclaration(this );
044: }
045:
046: @SuppressWarnings("unchecked")
047: private void getASTConstructor(
048: final AbstractTypeDeclaration typeDecl,
049: final List<ConstructorDeclaration> results) {
050:
051: final List bodyDecls = typeDecl.bodyDeclarations();
052: IFile file = null;
053: for (int i = 0, len = bodyDecls.size(); i < len; i++) {
054: final BodyDeclaration bodyDecl = (BodyDeclaration) bodyDecls
055: .get(i);
056: if (bodyDecl.getNodeType() == ASTNode.METHOD_DECLARATION) {
057: final org.eclipse.jdt.core.dom.MethodDeclaration methodDecl = (org.eclipse.jdt.core.dom.MethodDeclaration) bodyDecl;
058:
059: if (methodDecl.isConstructor()) {
060: final IMethodBinding methodBinding = methodDecl
061: .resolveBinding();
062: // built an ast based representation.
063: if (methodBinding == null) {
064: if (file == null)
065: file = getResource();
066: ConstructorDeclaration mirrorDecl = (ConstructorDeclaration) Factory
067: .createDeclaration(methodDecl, file,
068: _env);
069: if (mirrorDecl != null)
070: results.add(mirrorDecl);
071: }
072: }
073: }
074: }
075: }
076:
077: public Collection<ConstructorDeclaration> getConstructors() {
078: final List<ConstructorDeclaration> results = new ArrayList<ConstructorDeclaration>();
079: if (isFromSource()) {
080: // need to consult the ast since methods with broken signature
081: // do not appear in bindings.
082: final ITypeBinding typeBinding = getDeclarationBinding();
083: final ASTNode node = _env.getASTNodeForBinding(typeBinding);
084: if (node != null) {
085: switch (node.getNodeType()) {
086: case ASTNode.TYPE_DECLARATION:
087: case ASTNode.ANNOTATION_TYPE_DECLARATION:
088: case ASTNode.ENUM_DECLARATION:
089: AbstractTypeDeclaration typeDecl = (AbstractTypeDeclaration) node;
090: // built the ast based methods first.
091: getASTConstructor(typeDecl, results);
092: break;
093: default:
094: // the ast node for a type binding should be a AbstractTypeDeclaration.
095: throw new IllegalStateException(
096: "expecting a AbstractTypeDeclaration but got " //$NON-NLS-1$
097: + node.getClass().getName());
098: }
099: }
100: }
101: // build methods for binding type or
102: // build the binding based method for source type.
103:
104: final IMethodBinding[] methods = getDeclarationBinding()
105: .getDeclaredMethods();
106: for (IMethodBinding method : methods) {
107: if (method.isSynthetic())
108: continue;
109: if (method.isConstructor()) {
110: Declaration mirrorDecl = Factory.createDeclaration(
111: method, _env);
112: if (mirrorDecl != null)
113: results.add((ConstructorDeclaration) mirrorDecl);
114: }
115: }
116: return results;
117:
118: }
119:
120: @SuppressWarnings("unchecked")
121: public Collection<MethodDeclaration> getMethods() {
122: return (Collection<MethodDeclaration>) _getMethods();
123: }
124:
125: // Start of implementation of ClassType API
126: public void accept(TypeVisitor visitor) {
127: visitor.visitClassType(this );
128: }
129:
130: public ClassType getSuperclass() {
131: final ITypeBinding super Class = getDeclarationBinding()
132: .getSuperclass();
133: if (super Class == null)
134: return null;
135: else if (super Class.isClass())
136: return (ClassType) Factory.createReferenceType(super Class,
137: _env);
138: else
139: // catch error case where user extends some interface instead of a class.
140: return Factory.createErrorClassType(super Class);
141: }
142:
143: public ClassDeclaration getDeclaration() {
144: return (ClassDeclaration) super .getDeclaration();
145: }
146:
147: // End of implementation of ClassType API
148:
149: public MirrorKind kind() {
150: return MirrorKind.TYPE_CLASS;
151: }
152: }
|