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;
018    
019    import org.jetbrains.annotations.NotNull;
020    import org.jetbrains.jet.lang.resolve.name.FqName;
021    
022    public class JvmClassName {
023        @NotNull
024        public static JvmClassName byInternalName(@NotNull String internalName) {
025            return new JvmClassName(internalName);
026        }
027    
028        /**
029         * WARNING: fq name cannot be uniquely mapped to JVM class name.
030         */
031        @NotNull
032        public static JvmClassName byFqNameWithoutInnerClasses(@NotNull FqName fqName) {
033            JvmClassName r = new JvmClassName(fqName.asString().replace('.', '/'));
034            r.fqName = fqName;
035            return r;
036        }
037    
038        @NotNull
039        public static JvmClassName byFqNameWithoutInnerClasses(@NotNull String fqName) {
040            return byFqNameWithoutInnerClasses(new FqName(fqName));
041        }
042    
043        private final static String CLASS_OBJECT_REPLACE_GUARD = "<class_object>";
044        private final static String TRAIT_IMPL_REPLACE_GUARD = "<trait_impl>";
045    
046        // Internal name:  kotlin/Map$Entry
047        // FqName:         kotlin.Map.Entry
048    
049        private final String internalName;
050        private FqName fqName;
051    
052        private JvmClassName(@NotNull String internalName) {
053            this.internalName = internalName;
054        }
055    
056        /**
057         * WARNING: internal name cannot be converted to FQ name for a class which contains dollars in the name
058         */
059        @NotNull
060        public FqName getFqNameForClassNameWithoutDollars() {
061            if (fqName == null) {
062                String fqName = internalName
063                        .replace(JvmAbi.CLASS_OBJECT_CLASS_NAME, CLASS_OBJECT_REPLACE_GUARD)
064                        .replace(JvmAbi.TRAIT_IMPL_CLASS_NAME, TRAIT_IMPL_REPLACE_GUARD)
065                        .replace('$', '.')
066                        .replace('/', '.')
067                        .replace(TRAIT_IMPL_REPLACE_GUARD, JvmAbi.TRAIT_IMPL_CLASS_NAME)
068                        .replace(CLASS_OBJECT_REPLACE_GUARD, JvmAbi.CLASS_OBJECT_CLASS_NAME);
069                this.fqName = new FqName(fqName);
070            }
071            return fqName;
072        }
073    
074        @NotNull
075        public String getInternalName() {
076            return internalName;
077        }
078    
079        @Override
080        public String toString() {
081            return internalName;
082        }
083    
084        @Override
085        public boolean equals(Object o) {
086            if (this == o) return true;
087            if (o == null || getClass() != o.getClass()) return false;
088            return internalName.equals(((JvmClassName) o).internalName);
089        }
090    
091        @Override
092        public int hashCode() {
093            return internalName.hashCode();
094        }
095    }