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.types;
018
019 import org.jetbrains.annotations.NotNull;
020 import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
021 import org.jetbrains.jet.lang.descriptors.annotations.AnnotatedImpl;
022 import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
023 import org.jetbrains.jet.lang.resolve.scopes.JetScope;
024 import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
025
026 import java.util.Collections;
027 import java.util.Iterator;
028 import java.util.List;
029
030 public final class JetTypeImpl extends AnnotatedImpl implements JetType {
031
032 private final TypeConstructor constructor;
033 private final List<TypeProjection> arguments;
034 private final boolean nullable;
035 private final JetScope memberScope;
036
037 public JetTypeImpl(List<AnnotationDescriptor> annotations, TypeConstructor constructor, boolean nullable, @NotNull List<TypeProjection> arguments, JetScope memberScope) {
038 super(annotations);
039
040 if (memberScope instanceof ErrorUtils.ErrorScope) {
041 throw new IllegalStateException();
042 }
043
044 this.constructor = constructor;
045 this.nullable = nullable;
046 this.arguments = arguments;
047 this.memberScope = memberScope;
048 }
049
050 public JetTypeImpl(TypeConstructor constructor, JetScope memberScope) {
051 this(Collections.<AnnotationDescriptor>emptyList(), constructor, false, Collections.<TypeProjection>emptyList(), memberScope);
052 }
053
054 public JetTypeImpl(@NotNull ClassDescriptor classDescriptor) {
055 this(Collections.<AnnotationDescriptor>emptyList(),
056 classDescriptor.getTypeConstructor(),
057 false,
058 Collections.<TypeProjection>emptyList(),
059 classDescriptor.getMemberScope(Collections.<TypeProjection>emptyList()));
060 }
061
062 @NotNull
063 @Override
064 public TypeConstructor getConstructor() {
065 return constructor;
066 }
067
068 @NotNull
069 @Override
070 public List<TypeProjection> getArguments() {
071 return arguments;
072 }
073
074 @Override
075 public boolean isNullable() {
076 return nullable;
077 }
078
079 @NotNull
080 @Override
081 public JetScope getMemberScope() {
082 return memberScope;
083 }
084
085 @Override
086 public String toString() {
087 return constructor + (arguments.isEmpty() ? "" : "<" + argumentsToString() + ">") + (isNullable() ? "?" : "");
088 }
089
090 private StringBuilder argumentsToString() {
091 StringBuilder stringBuilder = new StringBuilder();
092 for (Iterator<TypeProjection> iterator = arguments.iterator(); iterator.hasNext();) {
093 TypeProjection argument = iterator.next();
094 stringBuilder.append(argument);
095 if (iterator.hasNext()) {
096 stringBuilder.append(", ");
097 }
098 }
099 return stringBuilder;
100 }
101
102 @Override
103 public boolean equals(Object o) {
104 if (this == o) return true;
105 if (!(o instanceof JetType)) return false;
106
107 JetType type = (JetType) o;
108
109 return nullable == type.isNullable() && JetTypeChecker.INSTANCE.equalTypes(this, type);
110 }
111
112 @Override
113 public int hashCode() {
114 int result = constructor != null ? constructor.hashCode() : 0;
115 result = 31 * result + arguments.hashCode();
116 result = 31 * result + (nullable ? 1 : 0);
117 return result;
118 }
119 }