001    /*
002     * Copyright 2006 Google Inc.
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005     * use this file except in compliance with the License. You may obtain a copy of
006     * the License at
007     * 
008     * http://www.apache.org/licenses/LICENSE-2.0
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013     * License for the specific language governing permissions and limitations under
014     * the License.
015     */
016    package com.google.gwt.core.ext.typeinfo;
017    
018    import java.util.ArrayList;
019    import java.util.Iterator;
020    import java.util.List;
021    
022    /**
023     * Common superclass for {@link JMethod} and
024     * {@link JConstructor}.
025     */
026    public abstract class JAbstractMethod implements HasMetaData {
027    
028      // Only the builder can construct
029      JAbstractMethod(TypeOracle oracle, String name, int declStart, int declEnd,
030          int bodyStart, int bodyEnd) {
031        this.oracle = oracle;
032        this.name = name;
033        this.declStart = declStart;
034        this.declEnd = declEnd;
035        this.bodyStart = bodyStart;
036        this.bodyEnd = bodyEnd;
037      }
038    
039      public void addMetaData(String tagName, String[] values) {
040        metaData.addMetaData(tagName, values);
041      }
042    
043      public JParameter findParameter(String name) {
044        for (Iterator iter = params.iterator(); iter.hasNext();) {
045          JParameter param = (JParameter) iter.next();
046          if (param.getName().equals(name))
047            return param;
048        }
049        return null;
050      }
051    
052      public int getBodyEnd() {
053        return bodyEnd;
054      }
055    
056      public int getBodyStart() {
057        return bodyStart;
058      }
059    
060      public int getDeclEnd() {
061        return declEnd;
062      }
063    
064      public int getDeclStart() {
065        return declStart;
066      }
067    
068      /**
069       * Gets the type in which this method or constructor was declared.
070       */
071      public abstract JClassType getEnclosingType();
072    
073      public String[][] getMetaData(String tagName) {
074        return metaData.getMetaData(tagName);
075      }
076    
077      public String[] getMetaDataTags() {
078        return metaData.getMetaDataTags();
079      }
080    
081      public String getName() {
082        return name;
083      }
084    
085      public JParameter[] getParameters() {
086        return (JParameter[]) params.toArray(TypeOracle.NO_JPARAMS);
087      }
088    
089      public abstract String getReadableDeclaration();
090    
091      public JType[] getThrows() {
092        return (JType[]) thrownTypes.toArray(TypeOracle.NO_JTYPES);
093      }
094    
095      public abstract JConstructor isConstructor();
096    
097      public boolean isDefaultAccess() {
098        return 0 == (modifierBits & (TypeOracle.MOD_PUBLIC | TypeOracle.MOD_PRIVATE | TypeOracle.MOD_PROTECTED));
099      }
100    
101      public abstract JMethod isMethod();
102    
103      public boolean isPrivate() {
104        return 0 != (modifierBits & TypeOracle.MOD_PRIVATE);
105      }
106    
107      public boolean isProtected() {
108        return 0 != (modifierBits & TypeOracle.MOD_PROTECTED);
109      }
110    
111      public boolean isPublic() {
112        return 0 != (modifierBits & TypeOracle.MOD_PUBLIC);
113      }
114    
115      protected int getModifierBits() {
116        return modifierBits;
117      }
118    
119      protected void toStringParamsAndThrows(StringBuffer sb) {
120        sb.append("(");
121        boolean needComma = false;
122        for (Iterator iter = params.iterator(); iter.hasNext();) {
123          JParameter param = (JParameter) iter.next();
124          if (needComma) {
125            sb.append(", ");
126          } else {
127            needComma = true;
128          }
129          sb.append(param.getType().getParameterizedQualifiedSourceName());
130          sb.append(" ");
131          sb.append(param.getName());
132        }
133        sb.append(")");
134    
135        if (!thrownTypes.isEmpty()) {
136          sb.append(" throws ");
137          needComma = false;
138          for (Iterator iter = thrownTypes.iterator(); iter.hasNext();) {
139            JClassType thrownType = (JClassType) iter.next();
140            if (needComma) {
141              sb.append(", ");
142            } else {
143              needComma = true;
144            }
145            sb.append(thrownType.getParameterizedQualifiedSourceName());
146          }
147        }
148      }
149    
150      public void addModifierBits(int bits) {
151        modifierBits |= bits;
152      }
153    
154      void addParameter(JParameter param) {
155        params.add(param);
156      }
157    
158      public void addThrows(JType type) {
159        thrownTypes.add(type);
160      }
161    
162      boolean hasParamTypes(JType[] paramTypes) {
163        if (params.size() != paramTypes.length)
164          return false;
165    
166        for (int i = 0; i < paramTypes.length; i++) {
167          JParameter candidate = (JParameter) params.get(i);
168          // Identity tests are ok since identity is durable within an oracle.
169          //
170          if (candidate.getType() != paramTypes[i]) {
171            return false;
172          }
173        }
174        return true;
175      }
176    
177      private int bodyEnd;
178      private int bodyStart;
179      private final int declEnd;
180      private final int declStart;
181      private final HasMetaData metaData = new MetaData();
182      private int modifierBits;
183      private final String name;
184      private final TypeOracle oracle;
185      private final List params = new ArrayList();
186      private final List thrownTypes = new ArrayList();
187    }