001    /*
002     * Copyright 2010-2013 JetBrains s.r.o.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of 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,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package org.jetbrains.jet.lang.resolve.java.structure;
018    
019    import org.jetbrains.annotations.NotNull;
020    
021    import java.util.List;
022    
023    public class JavaSignatureFormatter {
024        private static JavaSignatureFormatter instance;
025    
026        private JavaSignatureFormatter() {
027        }
028    
029        @NotNull
030        public static JavaSignatureFormatter getInstance() {
031            if (instance == null) {
032                instance = new JavaSignatureFormatter();
033            }
034            return instance;
035        }
036    
037        /**
038         * @return a formatted signature of a method, showing method name and fully qualified names of its parameter types, e.g.:
039         * {@code "foo(double, java.lang.String)"}
040         */
041        @NotNull
042        public String formatMethod(@NotNull JavaMethod method) {
043            StringBuilder buffer = new StringBuilder();
044    
045            buffer.append(method.getName());
046    
047            buffer.append('(');
048            boolean firstParameter = true;
049            for (JavaValueParameter parameter : method.getValueParameters()) {
050                if (!firstParameter) buffer.append(", ");
051                firstParameter = false;
052    
053                buffer.append(formatType(parameter.getType()));
054            }
055    
056            buffer.append(')');
057    
058            return buffer.toString();
059        }
060    
061        @NotNull
062        private String formatType(@NotNull JavaType type) {
063            if (type instanceof JavaPrimitiveType) {
064                return ((JavaPrimitiveType) type).getCanonicalText();
065            }
066            else if (type instanceof JavaArrayType) {
067                return formatType(((JavaArrayType) type).getComponentType()) + "[]";
068            }
069            else if (type instanceof JavaClassifierType) {
070                return formatClassifierType((JavaClassifierType) type);
071            }
072            else if (type instanceof JavaWildcardType) {
073                JavaWildcardType wildcardType = (JavaWildcardType) type;
074                if (wildcardType.isExtends()) {
075                    //noinspection ConstantConditions
076                    return "? extends " + formatType(wildcardType.getBound());
077                } else {
078                    return "?";
079                }
080            } else {
081                throw new IllegalArgumentException("Wrong type: " + type);
082            }
083        }
084    
085        @NotNull
086        private String formatClassifierType(@NotNull JavaClassifierType type) {
087            JavaClassifier classifier = type.getClassifier();
088    
089            if (classifier == null) return "[UNRESOLVED: " + type + "]";
090    
091            if (classifier instanceof JavaTypeParameter) {
092                return classifier.getName().asString();
093            }
094    
095            //noinspection ConstantConditions
096            StringBuilder buffer = new StringBuilder(((JavaClass) classifier).getFqName().asString());
097    
098            List<JavaType> typeArguments = type.getTypeArguments();
099            if (!typeArguments.isEmpty()) {
100                buffer.append("<");
101                boolean firstArgument = true;
102                for (JavaType typeArgument : typeArguments) {
103                    if (!firstArgument) buffer.append(",");
104                    firstArgument = false;
105    
106                    buffer.append(formatType(typeArgument));
107                }
108                buffer.append(">");
109            }
110    
111            return buffer.toString();
112        }
113    }