/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * This file is part of the debugger and core tools for the AspectJ(tm) * programming language; see http://aspectj.org * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/. * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is AspectJ. * * The Initial Developer of the Original Code is Xerox Corporation. Portions * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation. * All Rights Reserved. */ package org.aspectj.tools.ajdoc; import org.aspectj.ajdoc.AdviceDoc; import org.aspectj.compiler.base.ast.Formals; import org.aspectj.compiler.base.ast.NameType; import org.aspectj.compiler.base.ast.TypeDs; import com.sun.javadoc.ClassDoc; import com.sun.javadoc.ExecutableMemberDoc; import com.sun.javadoc.ParamTag; import com.sun.javadoc.Parameter; import com.sun.javadoc.ThrowsTag; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; public abstract class ExecutableMemberDocImpl extends MemberDocImpl implements ExecutableMemberDoc { /* * These three fields should be final, but can't because * they contain calls to abstract methods that aren't * valid until after the subclasses constructor is run. * To compensate the accessor methods lazily evaluate * them, and these methods are final. */ /** The collection of advice placed on each ExecutableMemberDoc. */ private Collection advice; /** The List of parameters. */ private Collection parameters; /** The List of thrown exceptions. */ private Collection thrownExceptions; /** The full signature. */ private String signature; /** The flat signature. */ private String flatSignature; /** * Constructs a new Doc with the enclosing ClassDoc. * * @param containingClass enclosing ClassDoc. */ public ExecutableMemberDocImpl(ClassDoc containingClass) { super(containingClass); } /** * Returns a non-null Collection of AdviceDoc * representing the advice placed on the underlying Dec. * * @return a non-null Collection of AdviceDoc * representing the advice placed on the * underlying Dec. */ protected abstract Collection createAdvice(); /** * Returns the Formals of the underlying Dec. * * @return the Formals of the underlying Dec. */ protected abstract Formals getFormals(); /** * Returns the TypeDs representing the exceptions * thrown by the underlying Dec. * * @return the TypeDs representing the exceptions * thrown by the underlying Dec. */ protected abstract TypeDs getThrows(); /** * Converts the passed in Formals to a Collection of * Parameter and sets our parameters to this value. * * @param formals the Formals to use. */ public void makeParameters(Formals formals) { parameters = createParameters(formals); } /** * Converts the passed in TypeDs to a Collection of * ClassDoc and sets our thrownExceptions to this value. * * @param thrown the TypeDs to use. */ public void makeThrownExceptions(TypeDs thrown) { thrownExceptions = createThrownExceptions(thrown); } /** * Returns the advice affecting this member. * * @return an array of AdviceDoc representing the advice * affecting this member. */ public final AdviceDoc[] advice() { if (advice == null) advice = createAdvice(); return (AdviceDoc[])advice.toArray(new AdviceDoc[advice.size()]); } /** * Returns the exceptions this code declares to throw. * * @return an array of ClassDoc representing the exceptions * this code declares to throw. */ public final ClassDoc[] thrownExceptions() { if (thrownExceptions == null) makeThrownExceptions(getThrows()); return (ClassDoc[])thrownExceptions.toArray (new ClassDoc[thrownExceptions.size()]); } /** * Returns the parameters taken by this code. * * @return an array of Parameter representing the * parameters this code takes. */ public final Parameter[] parameters() { if (parameters == null) makeParameters(getFormals()); return (Parameter[])parameters.toArray (new Parameter[parameters.size()]); } /** * Returns the flat signature. * * @return the flat signature with all types unqualified. */ public String flatSignature() { if (flatSignature == null) { flatSignature = Util.flatSignature(parameters()); } return flatSignature; } /** * Returns the full signature. * * @return the full signature with all types qualified. */ public String signature() { if (signature == null) { signature = Util.signature(parameters()); } return signature; } /** * Returns true if this code is synchronized. * * @return true if this code is synchronized. */ public boolean isSynchronized() { //return getModifiers().isSynchronized(); return Modifier.isSynchronized(modifierSpecifier()); } /** * Returns trueif this code is native. * * @return trueif this code is native. */ public boolean isNative() { //return (modifierSpecifier() & Modifiers.NATIVE) != 0; return Modifier.isNative(modifierSpecifier()); } /** * Returns the throw tags describing exceptions thrown * declared by this code. * * @return an array of ThrowsTag representing the exception * this code declares to throw. */ public ThrowsTag[] throwsTags() { return getComment().throwsTags(); } /** * Returns the param tags describing parameters taken * by this code. * * @return an array of ParamTag representing the * parameters taken by this code. */ public ParamTag[] paramTags() { return getComment().paramTags(); } /** * Returns the simple name followed the parameters * enclosed in parens. * * @return the simple name followed the parameters * enclosed in parens. */ public String toString() { StringBuffer sb = new StringBuffer(name()); sb.append('('); Parameter[] params = parameters(); for (int i = 0, N = params.length; i < N; i++) { if (i > 0) sb.append(","); sb.append(params[i].type().qualifiedTypeName()); sb.append(params[i].type().dimension()); } sb.append(')'); return sb.toString(); } /** * Returns a Collection of Parameter corresponding to * the Formals passed in. * * @param formals the Formals to use. * @return a Collection of Parameter corresponding to * the Formals passed in. */ private Collection createParameters(Formals formals) { if (formals == null) return Collections.EMPTY_LIST; List list = new ArrayList(formals.size()); for (int i = 0, N = formals.size(); i < N; i++) { list.add(new ParameterImpl(formals.get(i))); } return list; } /** * Returns a Collection of ClassDoc corresponding to * the TypeDs passed in. * * @param thrown the TypeDs to use * @return a Collection of ClassDoc corresponding to * the TypeDs passed in. */ private Collection createThrownExceptions(TypeDs typeds) { if (typeds == null) return Collections.EMPTY_LIST; List list = new ArrayList(typeds.size()); for (int i = 0, N = typeds.size(); i < N; i++) { list.add(ClassDocImpl.getInstance (((NameType)typeds.get(i).getType()).getTypeDec())); } return list; } /** * Returns true if the passed in Object is * an ExecutableMemberDocImpl, its name equals ours, and * its parameters equals ours. * * @return equality based on name and parameters. */ public boolean weakEquals(Object md) { if (!(md instanceof ExecutableMemberDocImpl)) { return false; } ExecutableMemberDocImpl emdi = (ExecutableMemberDocImpl)md; if (!name().equals(emdi.name())) { return false; } Parameter[] ourPds = this.parameters(); Parameter[] edsPds = emdi.parameters(); if (ourPds.length != edsPds.length) { return false; } for (int i = 0, N = ourPds.length; i < N; i++) { if (!ourPds[i].equals(edsPds[i])) { return false; } } return true; } }