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 017package org.jetbrains.jet.lang.types; 018 019import org.jetbrains.annotations.NotNull; 020import org.jetbrains.jet.lang.descriptors.ClassDescriptor; 021import org.jetbrains.jet.lang.descriptors.annotations.AnnotatedImpl; 022import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; 023import org.jetbrains.jet.lang.resolve.scopes.JetScope; 024import org.jetbrains.jet.lang.types.checker.JetTypeChecker; 025 026import java.util.Collections; 027import java.util.Iterator; 028import java.util.List; 029 030public 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}