001 /*
002 * Copyright 2010-2015 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.kotlin.name;
018
019 import org.jetbrains.annotations.NotNull;
020 import org.jetbrains.kotlin.utils.StringsKt;
021
022 import java.util.List;
023
024 public final class FqName {
025
026 @NotNull
027 public static FqName fromSegments(@NotNull List<String> names) {
028 return new FqName(StringsKt.join(names, "."));
029 }
030
031 public static final FqName ROOT = new FqName("");
032
033 @NotNull
034 private final FqNameUnsafe fqName;
035
036 // cache
037 private transient FqName parent;
038
039 public FqName(@NotNull String fqName) {
040 this.fqName = new FqNameUnsafe(fqName, this);
041 }
042
043 public FqName(@NotNull FqNameUnsafe fqName) {
044 this.fqName = fqName;
045 }
046
047 private FqName(@NotNull FqNameUnsafe fqName, FqName parent) {
048 this.fqName = fqName;
049 this.parent = parent;
050 }
051
052 @NotNull
053 public String asString() {
054 return fqName.asString();
055 }
056
057 @NotNull
058 public FqNameUnsafe toUnsafe() {
059 return fqName;
060 }
061
062 public boolean isRoot() {
063 return fqName.isRoot();
064 }
065
066 @NotNull
067 public FqName parent() {
068 if (parent != null) {
069 return parent;
070 }
071
072 if (isRoot()) {
073 throw new IllegalStateException("root");
074 }
075
076 parent = new FqName(fqName.parent());
077
078 return parent;
079 }
080
081 @NotNull
082 public FqName child(@NotNull Name name) {
083 return new FqName(fqName.child(name), this);
084 }
085
086 @NotNull
087 public Name shortName() {
088 return fqName.shortName();
089 }
090
091 @NotNull
092 public Name shortNameOrSpecial() {
093 return fqName.shortNameOrSpecial();
094 }
095
096 @NotNull
097 public List<Name> pathSegments() {
098 return fqName.pathSegments();
099 }
100
101 @NotNull
102 public static FqName topLevel(@NotNull Name shortName) {
103 return new FqName(FqNameUnsafe.topLevel(shortName));
104 }
105
106 @Override
107 public String toString() {
108 return fqName.toString();
109 }
110
111 @Override
112 public boolean equals(Object o) {
113 if (this == o) return true;
114 if (!(o instanceof FqName)) return false;
115
116 FqName otherFqName = (FqName) o;
117
118 if (!fqName.equals(otherFqName.fqName)) return false;
119
120 return true;
121 }
122
123 @Override
124 public int hashCode() {
125 return fqName.hashCode();
126 }
127 }