001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements. See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership. The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the  "License");
007     * you may not use this file except in compliance with the License.
008     * You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    /*
019     * $Id: MethodType.java 468649 2006-10-28 07:00:55Z minchau $
020     */
021    
022    package org.apache.xalan.xsltc.compiler.util;
023    
024    import java.util.Vector;
025    
026    /**
027     * @author Jacek Ambroziak
028     * @author Santiago Pericas-Geertsen
029     */
030    public final class MethodType extends Type {
031        private final Type _resultType;     
032        private final Vector _argsType;
033            
034        public MethodType(Type resultType) {
035            _argsType = null;
036            _resultType = resultType;
037        }
038    
039        public MethodType(Type resultType, Type arg1) {
040            if (arg1 != Type.Void) {
041                _argsType = new Vector();
042                _argsType.addElement(arg1);
043            }
044            else {
045                _argsType = null;
046            }
047            _resultType = resultType;
048        }
049    
050        public MethodType(Type resultType, Type arg1, Type arg2) {
051            _argsType = new Vector(2);
052            _argsType.addElement(arg1);
053            _argsType.addElement(arg2);
054            _resultType = resultType;
055        }
056    
057        public MethodType(Type resultType, Type arg1, Type arg2, Type arg3) {
058            _argsType = new Vector(3);
059            _argsType.addElement(arg1);
060            _argsType.addElement(arg2);
061            _argsType.addElement(arg3);
062            _resultType = resultType;
063        }
064    
065        public MethodType(Type resultType, Vector argsType) {
066            _resultType = resultType;
067            _argsType = argsType.size() > 0 ? argsType : null;
068        }
069    
070        public String toString() {
071            StringBuffer result = new StringBuffer("method{");
072            if (_argsType != null) {
073                final int count = _argsType.size();
074                for (int i=0; i<count; i++) {
075                    result.append(_argsType.elementAt(i));
076                    if (i != (count-1)) result.append(',');
077                }
078            }
079            else {
080                result.append("void");
081            }
082            result.append('}');
083            return result.toString();
084        }
085    
086        public String toSignature() {
087            return toSignature("");
088        }
089    
090        /**
091         * Returns the signature of this method that results by adding
092         * <code>lastArgSig</code> to the end of the argument list.
093         */
094        public String toSignature(String lastArgSig) {
095            final StringBuffer buffer = new StringBuffer();
096            buffer.append('(');
097            if (_argsType != null) {
098                final int n = _argsType.size();
099                for (int i = 0; i < n; i++) {
100                    buffer.append(((Type)_argsType.elementAt(i)).toSignature());
101                }
102            }
103            return buffer
104                .append(lastArgSig)
105                .append(')')
106                .append(_resultType.toSignature())
107                .toString();
108        }
109    
110        public org.apache.bcel.generic.Type toJCType() {
111            return null;    // should never be called
112        }
113    
114        public boolean identicalTo(Type other) {
115            boolean result = false;
116            if (other instanceof MethodType) {
117                final MethodType temp = (MethodType) other;
118                if (_resultType.identicalTo(temp._resultType)) {
119                    final int len = argsCount();
120                    result = len == temp.argsCount();
121                    for (int i = 0; i < len && result; i++) {
122                        final Type arg1 = (Type)_argsType.elementAt(i);
123                        final Type arg2 = (Type)temp._argsType.elementAt(i);
124                        result = arg1.identicalTo(arg2);
125                    }
126                }
127            }
128            return result;  
129        }
130            
131        public int distanceTo(Type other) {
132            int result = Integer.MAX_VALUE;
133            if (other instanceof MethodType) {
134                final MethodType mtype = (MethodType) other;
135                if (_argsType != null) {
136                    final int len = _argsType.size();
137                    if (len == mtype._argsType.size()) {
138                        result = 0;
139                        for (int i = 0; i < len; i++) {
140                            Type arg1 = (Type) _argsType.elementAt(i);
141                            Type arg2 = (Type) mtype._argsType.elementAt(i);
142                            final int temp = arg1.distanceTo(arg2);
143                            if (temp == Integer.MAX_VALUE) {
144                                result = temp;  // return MAX_VALUE
145                                break;
146                            }
147                            else {
148                                result += arg1.distanceTo(arg2);
149                            }
150                        }
151                    }
152                }
153                else if (mtype._argsType == null) {
154                    result = 0;   // both methods have no args
155                }
156            }
157            return result;
158        }
159                    
160        public Type resultType() {
161            return _resultType;
162        }
163                    
164        public Vector argsType() {
165            return _argsType;
166        }
167    
168        public int argsCount() {
169            return _argsType == null ? 0 : _argsType.size();
170        }
171    }