JetStandardClasses and JetStandardLibrary deleted

This commit is contained in:
Andrey Breslav
2012-10-17 13:21:29 +04:00
parent e81f38b6a8
commit 69f44dec62
2 changed files with 0 additions and 1230 deletions
@@ -1,618 +0,0 @@
/*
* Copyright 2010-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.types.lang;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.DescriptorResolver;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.*;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.*;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;
/**
* @author abreslav
*/
public class JetStandardClasses {
private JetStandardClasses() {
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public static final ModuleDescriptor FAKE_STANDARD_CLASSES_MODULE = new ModuleDescriptor(Name.special("<builtin>"));
private static final NamespaceDescriptorImpl STANDARD_CLASSES_FAKE_ROOT_NS = new NamespaceDescriptorImpl(
FAKE_STANDARD_CLASSES_MODULE, Collections.<AnnotationDescriptor>emptyList(), FqNameUnsafe.ROOT_NAME);
static {
FAKE_STANDARD_CLASSES_MODULE.setRootNamespace(STANDARD_CLASSES_FAKE_ROOT_NS);
}
public static NamespaceDescriptorImpl STANDARD_CLASSES_NAMESPACE = new NamespaceDescriptorImpl(
STANDARD_CLASSES_FAKE_ROOT_NS, Collections.<AnnotationDescriptor>emptyList(), Name.identifier("jet"));
public static final FqName STANDARD_CLASSES_FQNAME = DescriptorUtils.getFQName(STANDARD_CLASSES_NAMESPACE).toSafe();
private static final ClassDescriptor NOTHING_CLASS;
private static final JetType NOTHING_TYPE;
static {
ClassDescriptorImpl nothing = new ClassDescriptorImpl(
STANDARD_CLASSES_NAMESPACE,
Collections.<AnnotationDescriptor>emptyList(),
Modality.FINAL,
Name.identifier("Nothing")
);
ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(nothing, Collections.<AnnotationDescriptor>emptyList(), true);
constructorDescriptor.initialize(Collections.<TypeParameterDescriptor>emptyList(), Collections.<ValueParameterDescriptor>emptyList(), Visibilities.PRIVATE);
NOTHING_CLASS = nothing.initialize(
true,
Collections.<TypeParameterDescriptor>emptyList(),
new AbstractCollection<JetType>() {
@Override
public boolean contains(Object o) {
return o instanceof JetType;
}
@Override
public Iterator<JetType> iterator() {
throw new UnsupportedOperationException("Don't enumerate supertypes of Nothing");
}
@Override
public int size() {
throw new UnsupportedOperationException("Supertypes of Nothing do not constitute a valid collection");
}
},
JetScope.EMPTY,
Collections.<ConstructorDescriptor>singleton(constructorDescriptor),
null
);
NOTHING_TYPE = new JetTypeImpl(getNothing());
constructorDescriptor.setReturnType(NOTHING_TYPE);
}
private static final JetType NULLABLE_NOTHING_TYPE = new JetTypeImpl(
Collections.<AnnotationDescriptor>emptyList(),
getNothing().getTypeConstructor(),
true,
Collections.<TypeProjection>emptyList(),
JetScope.EMPTY);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private static final ClassDescriptor ANY;
private static final JetType ANY_TYPE;
static {
ClassDescriptorImpl any = new ClassDescriptorImpl(
STANDARD_CLASSES_NAMESPACE,
Collections.<AnnotationDescriptor>emptyList(),
Modality.OPEN,
Name.identifier("Any")
);
ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(any, Collections.<AnnotationDescriptor>emptyList(), true);
constructorDescriptor.initialize(Collections.<TypeParameterDescriptor>emptyList(), Collections.<ValueParameterDescriptor>emptyList(), Visibilities.PUBLIC);
ANY = any.initialize(
false,
Collections.<TypeParameterDescriptor>emptyList(),
Collections.<JetType>emptySet(),
JetScope.EMPTY,
Collections.<ConstructorDescriptor>singleton(constructorDescriptor),
null
);
ANY_TYPE = new JetTypeImpl(ANY.getTypeConstructor(), new JetScopeImpl() {
@NotNull
@Override
public DeclarationDescriptor getContainingDeclaration() {
return STANDARD_CLASSES_NAMESPACE;
}
@Override
public String toString() {
return "Scope for Any";
}
});
constructorDescriptor.setReturnType(ANY_TYPE);
}
private static final JetType NULLABLE_ANY_TYPE = new JetTypeImpl(ANY_TYPE.getAnnotations(), ANY_TYPE.getConstructor(), true, ANY_TYPE.getArguments(), ANY_TYPE.getMemberScope());
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private static final JetType DEFAULT_BOUND = getNullableAnyType();
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public static final JetScope STUB = JetScope.EMPTY;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public static final int MAX_TUPLE_ORDER = 22;
private static final Set<TypeConstructor> TUPLE_CONSTRUCTORS = Sets.newHashSet();
private static final ClassDescriptor[] TUPLE = new ClassDescriptor[MAX_TUPLE_ORDER + 1];
static {
for (int i = 0; i <= MAX_TUPLE_ORDER; i++) {
List<TypeParameterDescriptor> typeParameters = Lists.newArrayList();
List<ValueParameterDescriptor> constructorValueParameters = Lists.newArrayList();
ClassDescriptorImpl classDescriptor = new ClassDescriptorImpl(
STANDARD_CLASSES_NAMESPACE,
Collections.<AnnotationDescriptor>emptyList(),
Modality.FINAL,
Name.identifier("Tuple" + i));
WritableScopeImpl writableScope = new WritableScopeImpl(JetScope.EMPTY, classDescriptor, RedeclarationHandler.THROW_EXCEPTION, "tuples");
for (int j = 0; j < i; j++) {
TypeParameterDescriptor typeParameterDescriptor = TypeParameterDescriptorImpl.createWithDefaultBound(
classDescriptor,
Collections.<AnnotationDescriptor>emptyList(),
false, Variance.OUT_VARIANCE, Name.identifier("T" + (j + 1)), j);
typeParameters.add(typeParameterDescriptor);
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(classDescriptor, Collections.<AnnotationDescriptor>emptyList(), Modality.FINAL, Visibilities.PUBLIC, false, Name.identifier("_" + (j + 1)), CallableMemberDescriptor.Kind.DECLARATION);
propertyDescriptor.setType(typeParameterDescriptor.getDefaultType(), Collections.<TypeParameterDescriptorImpl>emptyList(), classDescriptor.getImplicitReceiver(), ReceiverDescriptor.NO_RECEIVER);
PropertyGetterDescriptor getterDescriptor = new PropertyGetterDescriptor(propertyDescriptor, Collections.<AnnotationDescriptor>emptyList(), Modality.FINAL, Visibilities.PUBLIC, false, true, CallableMemberDescriptor.Kind.DECLARATION);
getterDescriptor.initialize(typeParameterDescriptor.getDefaultType());
propertyDescriptor.initialize(getterDescriptor, null);
writableScope.addPropertyDescriptor(propertyDescriptor);
ValueParameterDescriptorImpl valueParameterDescriptor =
new ValueParameterDescriptorImpl(classDescriptor, j, Collections.<AnnotationDescriptor>emptyList(),
Name.identifier("_" + (j + 1)), false, typeParameterDescriptor.getDefaultType(),
false,
null);
constructorValueParameters.add(valueParameterDescriptor);
}
writableScope.changeLockLevel(WritableScope.LockLevel.READING);
ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(classDescriptor, Collections.<AnnotationDescriptor>emptyList(), true);
TUPLE[i] = classDescriptor.initialize(
true,
typeParameters,
Collections.singleton(getAnyType()),
writableScope,
Collections.<ConstructorDescriptor>singleton(constructorDescriptor),
null);
if (i == 0) {
// Unit.VALUE
classDescriptor.setClassObjectDescriptor(createClassObjectForUnit(classDescriptor));
}
TUPLE_CONSTRUCTORS.add(TUPLE[i].getTypeConstructor());
constructorDescriptor.initialize(classDescriptor.getTypeConstructor().getParameters(), constructorValueParameters, i == 0 ? Visibilities.PRIVATE : Visibilities.PUBLIC);
constructorDescriptor.setReturnType(classDescriptor.getDefaultType());
}
}
@NotNull
private static ClassDescriptor createClassObjectForUnit(@NotNull ClassDescriptorImpl unitClass) {
ClassDescriptorImpl classObjectDescriptor = new ClassDescriptorImpl(
unitClass,
ClassKind.CLASS_OBJECT,
Collections.<AnnotationDescriptor>emptyList(),
Modality.FINAL,
DescriptorUtils.getClassObjectName(unitClass.getName())
);
WritableScopeImpl classObjectMemberScope = new WritableScopeImpl(
JetScope.EMPTY,
classObjectDescriptor,
RedeclarationHandler.DO_NOTHING,
"Unit class object members"
);
PropertyDescriptor valueProperty = createUnitValueProperty(unitClass, classObjectDescriptor);
classObjectMemberScope.addPropertyDescriptor(valueProperty);
classObjectMemberScope.changeLockLevel(WritableScope.LockLevel.READING);
ConstructorDescriptorImpl classObjectConstructorDescriptor = new ConstructorDescriptorImpl(classObjectDescriptor, Collections.<AnnotationDescriptor>emptyList(), true);
classObjectConstructorDescriptor.initialize(
Collections.<TypeParameterDescriptor>emptyList(),
Collections.<ValueParameterDescriptor>emptyList(),
Visibilities.PRIVATE
);
classObjectDescriptor.initialize(
/*sealed = */ true,
Collections.<TypeParameterDescriptor>emptyList(),
Collections.singleton(getAnyType()),
classObjectMemberScope,
Collections.<ConstructorDescriptor>singleton(classObjectConstructorDescriptor),
classObjectConstructorDescriptor
);
classObjectConstructorDescriptor.setReturnType(classObjectDescriptor.getDefaultType());
return classObjectDescriptor;
}
@NotNull
private static PropertyDescriptor createUnitValueProperty(
@NotNull ClassDescriptorImpl unitClass,
@NotNull ClassDescriptorImpl unitClassObject
) {
PropertyDescriptor valueProperty = new PropertyDescriptor(
unitClassObject,
Collections.<AnnotationDescriptor>emptyList(),
Modality.FINAL,
Visibilities.PUBLIC,
/*isVar = */ false,
Name.identifier("VALUE"),
CallableMemberDescriptor.Kind.DECLARATION);
valueProperty.setType(
unitClass.getDefaultType(),
Collections.<TypeParameterDescriptor>emptyList(),
unitClassObject.getImplicitReceiver(),
ReceiverDescriptor.NO_RECEIVER);
PropertyGetterDescriptor getter = DescriptorResolver.createDefaultGetter(valueProperty);
getter.initialize(unitClass.getDefaultType());
valueProperty.initialize(getter, null);
return valueProperty;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public static final int MAX_FUNCTION_ORDER = 22;
private static final ClassDescriptor[] FUNCTION = new ClassDescriptor[MAX_FUNCTION_ORDER + 1];
private static final ClassDescriptor[] RECEIVER_FUNCTION = new ClassDescriptor[MAX_FUNCTION_ORDER + 1];
private static final Set<TypeConstructor> FUNCTION_TYPE_CONSTRUCTORS = Sets.newHashSet();
private static final Set<TypeConstructor> RECEIVER_FUNCTION_TYPE_CONSTRUCTORS = Sets.newHashSet();
static {
for (int i = 0; i <= MAX_FUNCTION_ORDER; i++) {
ClassDescriptorImpl function = new ClassDescriptorImpl(
STANDARD_CLASSES_NAMESPACE,
Collections.<AnnotationDescriptor>emptyList(),
Modality.ABSTRACT,
Name.identifier("Function" + i));
SimpleFunctionDescriptorImpl invoke = new SimpleFunctionDescriptorImpl(function, Collections.<AnnotationDescriptor>emptyList(), Name.identifier("invoke"), CallableMemberDescriptor.Kind.DECLARATION);
WritableScope scopeForInvoke = createScopeForInvokeFunction(function, invoke);
List<TypeParameterDescriptor> typeParameters = createTypeParameters(0, i, function);
ConstructorDescriptorImpl constructorDescriptorForFunction = new ConstructorDescriptorImpl(function, Collections.<AnnotationDescriptor>emptyList(), true);
FUNCTION[i] = function.initialize(
false,
typeParameters,
Collections.singleton(getAnyType()), scopeForInvoke, Collections.<ConstructorDescriptor>singleton(constructorDescriptorForFunction), null);
FUNCTION_TYPE_CONSTRUCTORS.add(FUNCTION[i].getTypeConstructor());
FunctionDescriptorUtil.initializeFromFunctionType(invoke, function.getDefaultType(), new ClassReceiver(FUNCTION[i]), Modality.ABSTRACT, Visibilities.PUBLIC);
constructorDescriptorForFunction.initialize(function.getTypeConstructor().getParameters(),
Collections.<ValueParameterDescriptor>emptyList(), Visibilities.PUBLIC);
constructorDescriptorForFunction.setReturnType(function.getDefaultType());
ClassDescriptorImpl receiverFunction = new ClassDescriptorImpl(
STANDARD_CLASSES_NAMESPACE,
Collections.<AnnotationDescriptor>emptyList(),
Modality.ABSTRACT,
Name.identifier("ExtensionFunction" + i));
SimpleFunctionDescriptorImpl invokeWithReceiver = new SimpleFunctionDescriptorImpl(receiverFunction, Collections.<AnnotationDescriptor>emptyList(), Name.identifier("invoke"), CallableMemberDescriptor.Kind.DECLARATION);
WritableScope scopeForInvokeWithReceiver = createScopeForInvokeFunction(receiverFunction, invokeWithReceiver);
List<TypeParameterDescriptor> parameters = createTypeParameters(1, i, receiverFunction);
parameters.add(0, TypeParameterDescriptorImpl.createWithDefaultBound(
receiverFunction,
Collections.<AnnotationDescriptor>emptyList(),
false, Variance.IN_VARIANCE, Name.identifier("T"), 0));
ConstructorDescriptorImpl constructorDescriptorForReceiverFunction = new ConstructorDescriptorImpl(function, Collections.<AnnotationDescriptor>emptyList(), true);
RECEIVER_FUNCTION[i] = receiverFunction.initialize(
false,
parameters,
Collections.singleton(getAnyType()), scopeForInvokeWithReceiver, Collections.<ConstructorDescriptor>singleton(
constructorDescriptorForReceiverFunction), null);
RECEIVER_FUNCTION_TYPE_CONSTRUCTORS.add(RECEIVER_FUNCTION[i].getTypeConstructor());
FunctionDescriptorUtil.initializeFromFunctionType(invokeWithReceiver, receiverFunction.getDefaultType(), new ClassReceiver(RECEIVER_FUNCTION[i]), Modality.ABSTRACT, Visibilities.PUBLIC);
constructorDescriptorForReceiverFunction.initialize(receiverFunction.getTypeConstructor().getParameters(),
Collections.<ValueParameterDescriptor>emptyList(), Visibilities.PUBLIC);
constructorDescriptorForReceiverFunction.setReturnType(receiverFunction.getDefaultType());
}
}
private static WritableScope createScopeForInvokeFunction(ClassDescriptorImpl function, SimpleFunctionDescriptorImpl invoke) {
WritableScope scopeForInvoke = new WritableScopeImpl(STUB, function, RedeclarationHandler.THROW_EXCEPTION, "Scope for function type");
scopeForInvoke.addFunctionDescriptor(invoke);
scopeForInvoke.changeLockLevel(WritableScope.LockLevel.READING);
return scopeForInvoke;
}
private static List<TypeParameterDescriptor> createTypeParameters(int baseIndex, int parameterCount, ClassDescriptorImpl function) {
List<TypeParameterDescriptor> parameters = new ArrayList<TypeParameterDescriptor>();
for (int j = 0; j < parameterCount; j++) {
parameters.add(TypeParameterDescriptorImpl.createWithDefaultBound(
function,
Collections.<AnnotationDescriptor>emptyList(),
false, Variance.IN_VARIANCE, Name.identifier("P" + (j + 1)), baseIndex + j));
}
parameters.add(TypeParameterDescriptorImpl.createWithDefaultBound(
function,
Collections.<AnnotationDescriptor>emptyList(),
false, Variance.OUT_VARIANCE, Name.identifier("R"), baseIndex + parameterCount));
return parameters;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private static final JetType UNIT_TYPE = new JetTypeImpl(getTuple(0));
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@NotNull
public static final JetScope STANDARD_CLASSES;
public static final Name UNIT_ALIAS = Name.identifier("Unit");
static {
WritableScope writableScope = new WritableScopeImpl(JetScope.EMPTY, STANDARD_CLASSES_NAMESPACE, RedeclarationHandler.DO_NOTHING, "JetStandardClasses.STANDARD_CLASSES");
writableScope.changeLockLevel(WritableScope.LockLevel.BOTH);
STANDARD_CLASSES = writableScope;
writableScope.addClassifierAlias(UNIT_ALIAS, getTuple(0));
Field[] declaredFields = JetStandardClasses.class.getDeclaredFields();
for (Field field : declaredFields) {
if ((field.getModifiers() & Modifier.STATIC) == 0) {
continue;
}
Class<?> type = field.getType();
if (type == ClassDescriptor.class) {
try {
ClassDescriptor descriptor = (ClassDescriptor) field.get(null);
writableScope.addClassifierDescriptor(descriptor);
} catch (IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
else if (type.isArray() && type.getComponentType() == ClassDescriptor.class) {
try {
ClassDescriptor[] array = (ClassDescriptor[]) field.get(null);
for (ClassDescriptor descriptor : array) {
writableScope.addClassifierDescriptor(descriptor);
}
} catch (IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
}
STANDARD_CLASSES_NAMESPACE.initialize(writableScope);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@NotNull
public static JetType getDefaultBound() {
return DEFAULT_BOUND;
}
@NotNull
public static ClassDescriptor getAny() {
return ANY;
}
@NotNull
public static JetType getAnyType() {
return ANY_TYPE;
}
public static boolean isAny(JetType type) {
return !(type instanceof NamespaceType) &&
type.getConstructor() == ANY_TYPE.getConstructor();
}
public static JetType getNullableAnyType() {
return NULLABLE_ANY_TYPE;
}
@NotNull
public static ClassDescriptor getNothing() {
return NOTHING_CLASS;
}
@NotNull
public static ClassDescriptor getTuple(int size) {
return TUPLE[size];
}
@NotNull
public static ClassDescriptor getFunction(int parameterCount) {
return FUNCTION[parameterCount];
}
@NotNull
public static ClassDescriptor getReceiverFunction(int parameterCount) {
return RECEIVER_FUNCTION[parameterCount];
}
public static JetType getUnitType() {
return UNIT_TYPE;
}
public static JetType getNothingType() {
return NOTHING_TYPE;
}
public static JetType getNullableNothingType() {
return NULLABLE_NOTHING_TYPE;
}
public static boolean isNothing(@NotNull JetType type) {
return isNothingOrNullableNothing(type)
&& !type.isNullable();
}
public static boolean isNothingOrNullableNothing(@NotNull JetType type) {
return !(type instanceof NamespaceType)
&& type.getConstructor() == NOTHING_CLASS.getTypeConstructor();
}
public static boolean isUnit(@NotNull JetType type) {
return !(type instanceof NamespaceType) &&
type.getConstructor() == UNIT_TYPE.getConstructor();
}
public static JetType getTupleType(List<AnnotationDescriptor> annotations, List<JetType> arguments) {
if (annotations.isEmpty() && arguments.isEmpty()) {
return getUnitType();
}
ClassDescriptor tuple = getTuple(arguments.size());
List<TypeProjection> typeArguments = toProjections(arguments);
return new JetTypeImpl(annotations, tuple.getTypeConstructor(), false, typeArguments, tuple.getMemberScope(typeArguments));
}
public static JetType getTupleType(List<JetType> arguments) {
return getTupleType(Collections.<AnnotationDescriptor>emptyList(), arguments);
}
public static JetType getTupleType(JetType... arguments) {
return getTupleType(Collections.<AnnotationDescriptor>emptyList(), Arrays.asList(arguments));
}
public static boolean isTupleType(@NotNull JetType type) {
return TUPLE_CONSTRUCTORS.contains(type.getConstructor());
}
public static List<JetType> getTupleElementTypes(@NotNull JetType type) {
assert isTupleType(type);
List<JetType> result = Lists.newArrayList();
for (TypeProjection typeProjection : type.getArguments()) {
result.add(typeProjection.getType());
}
return result;
}
public static JetType getLabeledTupleType(List<AnnotationDescriptor> annotations, List<ValueParameterDescriptor> arguments) {
// TODO
return getTupleType(annotations, toTypes(arguments));
}
public static JetType getLabeledTupleType(List<ValueParameterDescriptor> arguments) {
// TODO
return getLabeledTupleType(Collections.<AnnotationDescriptor>emptyList(), arguments);
}
private static List<TypeProjection> toProjections(List<JetType> arguments) {
List<TypeProjection> result = new ArrayList<TypeProjection>();
for (JetType argument : arguments) {
result.add(new TypeProjection(Variance.OUT_VARIANCE, argument));
}
return result;
}
private static List<JetType> toTypes(List<ValueParameterDescriptor> labeledEntries) {
List<JetType> result = new ArrayList<JetType>();
for (ValueParameterDescriptor entry : labeledEntries) {
result.add(entry.getType());
}
return result;
}
// TODO : labeled version?
public static JetType getFunctionType(List<AnnotationDescriptor> annotations, @Nullable JetType receiverType, @NotNull List<JetType> parameterTypes, @NotNull JetType returnType) {
List<TypeProjection> arguments = new ArrayList<TypeProjection>();
if (receiverType != null) {
arguments.add(defaultProjection(receiverType));
}
for (JetType parameterType : parameterTypes) {
arguments.add(defaultProjection(parameterType));
}
arguments.add(defaultProjection(returnType));
int size = parameterTypes.size();
ClassDescriptor classDescriptor = receiverType == null ? FUNCTION[size] : RECEIVER_FUNCTION[size];
TypeConstructor constructor = classDescriptor.getTypeConstructor();
return new JetTypeImpl(annotations, constructor, false, arguments, classDescriptor.getMemberScope(arguments));
}
private static TypeProjection defaultProjection(JetType returnType) {
return new TypeProjection(Variance.INVARIANT, returnType);
}
public static boolean isFunctionType(@NotNull JetType type) {
return FUNCTION_TYPE_CONSTRUCTORS.contains(type.getConstructor()) || isReceiverFunctionType(type);
}
public static boolean isReceiverFunctionType(@NotNull JetType type) {
return RECEIVER_FUNCTION_TYPE_CONSTRUCTORS.contains(type.getConstructor());
}
@Nullable
public static JetType getReceiverType(@NotNull JetType type) {
assert isFunctionType(type) : type;
if (RECEIVER_FUNCTION_TYPE_CONSTRUCTORS.contains(type.getConstructor())) {
return type.getArguments().get(0).getType();
}
return null;
}
@NotNull
public static List<ValueParameterDescriptor> getValueParameters(@NotNull FunctionDescriptor functionDescriptor, @NotNull JetType type) {
assert isFunctionType(type);
List<ValueParameterDescriptor> valueParameters = Lists.newArrayList();
List<TypeProjection> parameterTypes = getParameterTypeProjectionsFromFunctionType(type);
for (int i = 0; i < parameterTypes.size(); i++) {
TypeProjection parameterType = parameterTypes.get(i);
ValueParameterDescriptorImpl valueParameterDescriptor = new ValueParameterDescriptorImpl(
functionDescriptor, i, Collections.<AnnotationDescriptor>emptyList(),
Name.identifier("p" + (i + 1)), false, parameterType.getType(), false, null);
valueParameters.add(valueParameterDescriptor);
}
return valueParameters;
}
@NotNull
public static List<TypeProjection> getParameterTypeProjectionsFromFunctionType(@NotNull JetType type) {
assert isFunctionType(type);
List<TypeProjection> arguments = type.getArguments();
int first = RECEIVER_FUNCTION_TYPE_CONSTRUCTORS.contains(type.getConstructor()) ? 1 : 0;
int last = arguments.size() - 2;
List<TypeProjection> parameterTypes = Lists.newArrayList();
for (int i = first; i <= last; i++) {
parameterTypes.add(arguments.get(i));
}
return parameterTypes;
}
@NotNull
public static JetType getReturnTypeFromFunctionType(@NotNull JetType type) {
assert isFunctionType(type);
List<TypeProjection> arguments = type.getArguments();
return arguments.get(arguments.size() - 1).getType();
}
@NotNull
public static Collection<DeclarationDescriptor> getAllStandardClasses() {
return STANDARD_CLASSES.getAllDescriptors();
}
public static boolean isStandardClass(@NotNull FqName fqName) {
return JetStandardClasses.STANDARD_CLASSES_FQNAME.equals(fqName.parent());
}
}
@@ -1,612 +0,0 @@
/*
* Copyright 2010-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.types.lang;
import com.google.common.collect.ImmutableSet;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.psi.PsiFileFactory;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
import org.jetbrains.jet.lang.resolve.BindingTraceContext;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.TopDownAnalyzer;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.RedeclarationHandler;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.plugin.JetFileType;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.*;
/**
* @author abreslav
*/
public class JetStandardLibrary {
private static JetStandardLibrary instance = null;
private static boolean initializing;
private static Throwable initializationFailed;
// This method must be called at least once per application run, on any project
// before any type checking is run
public static synchronized void initialize(@NotNull Project project) {
if (instance == null) {
if (initializationFailed != null) {
throw new RuntimeException(
"builtin library initialization failed previously: " + initializationFailed, initializationFailed);
}
if (initializing) {
throw new IllegalStateException("builtin library initialization loop");
}
initializing = true;
try {
instance = new JetStandardLibrary(project);
}
catch (Throwable e) {
initializationFailed = e;
throw new RuntimeException("builtin library initialization failed: " + e, e);
}
initializing = false;
}
}
@NotNull // This asserts that initialize() is called before any resolution happens
public static JetStandardLibrary getInstance() {
return instance;
}
private JetScope libraryScope;
private ClassDescriptor numberClass;
private ClassDescriptor charSequenceClass;
private ClassDescriptor stringClass;
private ClassDescriptor arrayClass;
private ClassDescriptor iterableClass;
private ClassDescriptor iteratorClass;
private ClassDescriptor mutableIterableClass;
private ClassDescriptor mutableIteratorClass;
private ClassDescriptor comparableClass;
private ClassDescriptor throwableClass;
private ClassDescriptor enumClass;
private ClassDescriptor annotationClass;
private ClassDescriptor volatileClass;
private ClassDescriptor dataClass;
private JetType stringType;
private JetType annotationType;
private JetType tuple0Type;
private EnumMap<PrimitiveType, ClassDescriptor> primitiveTypeToClass;
private EnumMap<PrimitiveType, ClassDescriptor> primitiveTypeToArrayClass;
private EnumMap<PrimitiveType, JetType> primitiveTypeToJetType;
private EnumMap<PrimitiveType, JetType> primitiveTypeToNullableJetType;
private EnumMap<PrimitiveType, JetType> primitiveTypeToArrayJetType;
private Map<JetType, JetType> primitiveJetTypeToJetArrayType;
private Map<JetType, JetType> jetArrayTypeToPrimitiveJetType;
private JetStandardLibrary(@NotNull Project project) {
// TODO : review
List<String> libraryFiles = Arrays.asList(
"Library.jet",
"Numbers.jet",
"Ranges.jet",
"Iterables.jet",
"Iterators.jet",
"Arrays.jet",
"Enum.jet",
"Collections.jet"
);
try {
List<JetFile> files = new LinkedList<JetFile>();
for(String fileName : libraryFiles) {
String path = "jet/" + fileName;
InputStream stream = JetStandardClasses.class.getClassLoader().getResourceAsStream(path);
if (stream == null) {
throw new IllegalStateException("resource not found in classpath: " + path);
}
//noinspection IOResourceOpenedButNotSafelyClosed
JetFile file = (JetFile) PsiFileFactory.getInstance(project).createFileFromText(fileName,
JetFileType.INSTANCE, FileUtil.loadTextAndClose(new InputStreamReader(stream)));
files.add(file);
}
BindingTraceContext bindingTraceContext = new BindingTraceContext();
WritableScopeImpl writableScope = new WritableScopeImpl(
JetStandardClasses.STANDARD_CLASSES, JetStandardClasses.STANDARD_CLASSES_NAMESPACE,
RedeclarationHandler.THROW_EXCEPTION, "Root bootstrap scope");
writableScope.changeLockLevel(WritableScope.LockLevel.BOTH);
TopDownAnalyzer.processStandardLibraryNamespace(project, bindingTraceContext, writableScope, JetStandardClasses.STANDARD_CLASSES_NAMESPACE, files);
AnalyzingUtils.throwExceptionOnErrors(bindingTraceContext.getBindingContext());
initStdClasses();
} catch (IOException e) {
throw new IllegalStateException(e);
} catch (ProcessCanceledException e) {
throw e;
}
}
public JetScope getLibraryScope() {
initStdClasses();
return libraryScope;
}
private void initStdClasses() {
if (libraryScope == null) {
this.libraryScope = JetStandardClasses.STANDARD_CLASSES_NAMESPACE.getMemberScope();
this.numberClass = getStdClassByName("Number");
this.stringClass = getStdClassByName("String");
this.charSequenceClass = getStdClassByName("CharSequence");
this.arrayClass = getStdClassByName("Array");
this.throwableClass = getStdClassByName("Throwable");
this.enumClass = getStdClassByName("Enum");
this.volatileClass = getStdClassByName("volatile");
this.dataClass = getStdClassByName("data");
this.iterableClass = getStdClassByName("Iterable");
this.iteratorClass = getStdClassByName("Iterator");
this.mutableIterableClass = getStdClassByName("MutableIterable");
this.mutableIteratorClass = getStdClassByName("MutableIterator");
this.comparableClass = getStdClassByName("Comparable");
this.stringType = new JetTypeImpl(getString());
this.tuple0Type = new JetTypeImpl(JetStandardClasses.getTuple(0));
this.annotationClass = getStdClassByName("Annotation");
this.annotationType = new JetTypeImpl(annotationClass);
primitiveTypeToClass = new EnumMap<PrimitiveType, ClassDescriptor>(PrimitiveType.class);
primitiveTypeToJetType = new EnumMap<PrimitiveType, JetType>(PrimitiveType.class);
primitiveTypeToNullableJetType = new EnumMap<PrimitiveType, JetType>(PrimitiveType.class);
primitiveTypeToArrayClass = new EnumMap<PrimitiveType, ClassDescriptor>(PrimitiveType.class);
primitiveTypeToArrayJetType = new EnumMap<PrimitiveType, JetType>(PrimitiveType.class);
primitiveJetTypeToJetArrayType = new HashMap<JetType, JetType>();
jetArrayTypeToPrimitiveJetType = new HashMap<JetType, JetType>();
for (PrimitiveType primitive : PrimitiveType.values()) {
makePrimitive(primitive);
}
}
}
@NotNull
private ClassDescriptor getStdClassByName(String className) {
ClassDescriptor classDescriptor = (ClassDescriptor) libraryScope.getClassifier(Name.identifier(className));
assert classDescriptor != null : "Standard class not found: " + className;
return classDescriptor;
}
private void makePrimitive(PrimitiveType primitiveType) {
ClassDescriptor clazz = (ClassDescriptor) libraryScope.getClassifier(primitiveType.getTypeName());
ClassDescriptor arrayClazz = (ClassDescriptor) libraryScope.getClassifier(primitiveType.getArrayTypeName());
JetTypeImpl type = new JetTypeImpl(clazz);
JetTypeImpl arrayType = new JetTypeImpl(arrayClazz);
primitiveTypeToClass.put(primitiveType, clazz);
primitiveTypeToJetType.put(primitiveType, type);
primitiveTypeToNullableJetType.put(primitiveType, TypeUtils.makeNullable(type));
primitiveTypeToArrayClass.put(primitiveType, arrayClazz);
primitiveTypeToArrayJetType.put(primitiveType, arrayType);
primitiveJetTypeToJetArrayType.put(type, arrayType);
jetArrayTypeToPrimitiveJetType.put(arrayType, type);
}
public Set<DeclarationDescriptor> getIntegralRanges() {
initStdClasses();
return ImmutableSet.<DeclarationDescriptor>of(
getStdClassByName("ByteRange"),
getStdClassByName("ShortRange"),
getStdClassByName("CharRange"),
getStdClassByName("IntRange"),
getStdClassByName("LongRange")
);
}
public Collection<ClassDescriptor> getStandardTypes() {
initStdClasses();
Collection<ClassDescriptor> classDescriptors = new ArrayList<ClassDescriptor>(primitiveTypeToClass.values());
classDescriptors.add(numberClass);
classDescriptors.add(stringClass);
classDescriptors.add(charSequenceClass);
classDescriptors.add(arrayClass);
classDescriptors.add(throwableClass);
classDescriptors.add(iterableClass);
classDescriptors.add(iteratorClass);
classDescriptors.add(mutableIterableClass);
classDescriptors.add(mutableIteratorClass);
classDescriptors.add(comparableClass);
classDescriptors.add(enumClass);
return classDescriptors;
}
@NotNull
public ClassDescriptor getNumber() {
initStdClasses();
return numberClass;
}
@NotNull
public ClassDescriptor getPrimitiveClassDescriptor(PrimitiveType primitiveType) {
initStdClasses();
return primitiveTypeToClass.get(primitiveType);
}
@NotNull
public ClassDescriptor getPrimitiveArrayClassDescriptor(PrimitiveType primitiveType) {
initStdClasses();
return primitiveTypeToArrayClass.get(primitiveType);
}
@NotNull
public ClassDescriptor getByte() {
return getPrimitiveClassDescriptor(PrimitiveType.BYTE);
}
@NotNull
public ClassDescriptor getChar() {
return getPrimitiveClassDescriptor(PrimitiveType.CHAR);
}
@NotNull
public ClassDescriptor getShort() {
return getPrimitiveClassDescriptor(PrimitiveType.SHORT);
}
@NotNull
public ClassDescriptor getInt() {
return getPrimitiveClassDescriptor(PrimitiveType.INT);
}
@NotNull
public ClassDescriptor getLong() {
return getPrimitiveClassDescriptor(PrimitiveType.LONG);
}
@NotNull
public ClassDescriptor getFloat() {
return getPrimitiveClassDescriptor(PrimitiveType.FLOAT);
}
@NotNull
public ClassDescriptor getDouble() {
return getPrimitiveClassDescriptor(PrimitiveType.DOUBLE);
}
@NotNull
public ClassDescriptor getBoolean() {
return getPrimitiveClassDescriptor(PrimitiveType.BOOLEAN);
}
@NotNull
public ClassDescriptor getString() {
initStdClasses();
return stringClass;
}
@NotNull
public ClassDescriptor getCharSequence() {
initStdClasses();
return charSequenceClass;
}
@NotNull
public ClassDescriptor getArray() {
initStdClasses();
return arrayClass;
}
@NotNull
public ClassDescriptor getIterable() {
initStdClasses();
return iterableClass;
}
@NotNull
public ClassDescriptor getIterator() {
initStdClasses();
return iteratorClass;
}
@NotNull
public ClassDescriptor getMutableIterable() {
initStdClasses();
return mutableIterableClass;
}
@NotNull
public ClassDescriptor getMutableIterator() {
initStdClasses();
return mutableIteratorClass;
}
@NotNull
public ClassDescriptor getComparable() {
initStdClasses();
return comparableClass;
}
@NotNull
public ClassDescriptor getThrowable() {
initStdClasses();
return throwableClass;
}
@NotNull
public ClassDescriptor getEnum() {
initStdClasses();
return enumClass;
}
@NotNull
public ClassDescriptor getAnnotation() {
initStdClasses();
return annotationClass;
}
@NotNull
public JetType getAnnotationType() {
initStdClasses();
return annotationType;
}
@NotNull
public ClassDescriptor getCollection() {
return getStdClassByName("Collection");
}
@NotNull
public ClassDescriptor getMutableCollection() {
return getStdClassByName("MutableCollection");
}
@NotNull
public ClassDescriptor getList() {
return getStdClassByName("List");
}
@NotNull
public ClassDescriptor getMutableList() {
return getStdClassByName("MutableList");
}
@NotNull
public ClassDescriptor getListIterator() {
return getStdClassByName("ListIterator");
}
@NotNull
public ClassDescriptor getMutableListIterator() {
return getStdClassByName("MutableListIterator");
}
@NotNull
public ClassDescriptor getSet() {
return getStdClassByName("Set");
}
@NotNull
public ClassDescriptor getMutableSet() {
return getStdClassByName("MutableSet");
}
@NotNull
public ClassDescriptor getMap() {
return getStdClassByName("Map");
}
@NotNull
public ClassDescriptor getMutableMap() {
return getStdClassByName("MutableMap");
}
@NotNull
public ClassDescriptor getMapEntry() {
ClassifierDescriptor entry = DescriptorUtils.getInnerClassByName(getMap(), "Entry");
assert entry instanceof ClassDescriptor;
return (ClassDescriptor) entry;
}
@NotNull
public ClassDescriptor getMutableMapEntry() {
ClassifierDescriptor entry = DescriptorUtils.getInnerClassByName(getMutableMap(), "MutableEntry");
assert entry instanceof ClassDescriptor;
return (ClassDescriptor) entry;
}
@NotNull
public JetType getPrimitiveJetType(PrimitiveType primitiveType) {
return primitiveTypeToJetType.get(primitiveType);
}
@NotNull
public JetType getIntType() {
return getPrimitiveJetType(PrimitiveType.INT);
}
@NotNull
public JetType getLongType() {
return getPrimitiveJetType(PrimitiveType.LONG);
}
@NotNull
public JetType getDoubleType() {
return getPrimitiveJetType(PrimitiveType.DOUBLE);
}
@NotNull
public JetType getFloatType() {
return getPrimitiveJetType(PrimitiveType.FLOAT);
}
@NotNull
public JetType getCharType() {
return getPrimitiveJetType(PrimitiveType.CHAR);
}
@NotNull
public JetType getBooleanType() {
return getPrimitiveJetType(PrimitiveType.BOOLEAN);
}
@NotNull
public JetType getStringType() {
initStdClasses();
return stringType;
}
@NotNull
public JetType getByteType() {
return getPrimitiveJetType(PrimitiveType.BYTE);
}
@NotNull
public JetType getShortType() {
return getPrimitiveJetType(PrimitiveType.SHORT);
}
@NotNull
public JetType getArrayType(@NotNull JetType argument) {
return getArrayType(Variance.INVARIANT, argument);
}
@NotNull
public JetType getEnumType(@NotNull JetType argument) {
return getEnumType(Variance.INVARIANT, argument);
}
@NotNull
public ClassDescriptor getDataClassAnnotation() {
return dataClass;
}
@NotNull
public JetType getArrayType(@NotNull Variance projectionType, @NotNull JetType argument) {
List<TypeProjection> types = Collections.singletonList(new TypeProjection(projectionType, argument));
return new JetTypeImpl(
Collections.<AnnotationDescriptor>emptyList(),
getArray().getTypeConstructor(),
false,
types,
getArray().getMemberScope(types)
);
}
@NotNull
public JetType getEnumType(@NotNull Variance projectionType, @NotNull JetType argument) {
List<TypeProjection> types = Collections.singletonList(new TypeProjection(projectionType, argument));
return new JetTypeImpl(
Collections.<AnnotationDescriptor>emptyList(),
getEnum().getTypeConstructor(),
false,
types,
getEnum().getMemberScope(types)
);
}
@NotNull
public JetType getArrayElementType(@NotNull JetType arrayType) {
// make non-null?
if (arrayType.getConstructor().getDeclarationDescriptor() == getArray()) {
if (arrayType.getArguments().size() != 1) {
throw new IllegalStateException();
}
return arrayType.getArguments().get(0).getType();
}
JetType primitiveType = jetArrayTypeToPrimitiveJetType.get(arrayType);
if (primitiveType == null) {
throw new IllegalStateException("not array: " + arrayType);
}
return primitiveType;
}
@NotNull
public JetType getNullablePrimitiveJetType(PrimitiveType primitiveType) {
initStdClasses();
return primitiveTypeToNullableJetType.get(primitiveType);
}
@NotNull
public JetType getPrimitiveArrayJetType(PrimitiveType primitiveType) {
initStdClasses();
return primitiveTypeToArrayJetType.get(primitiveType);
}
/**
* @return <code>null</code> if not primitive
*/
@Nullable
public JetType getPrimitiveArrayJetTypeByPrimitiveJetType(JetType jetType) {
return primitiveJetTypeToJetArrayType.get(jetType);
}
public boolean isVolatile(@NotNull PropertyDescriptor descriptor) {
return containsAnnotation(descriptor, volatileClass);
}
public static boolean isData(@NotNull ClassDescriptor descriptor) {
if (initializing) {
// This is a hack to make this method callable while resolving standard library
// (otherwise getInstance() would throw an Exception)
// This also means that "data" annotation has no effect in standard library
return false;
}
return containsAnnotation(descriptor, getInstance().dataClass);
}
private static boolean containsAnnotation(DeclarationDescriptor descriptor, ClassDescriptor annotationClass) {
List<AnnotationDescriptor> annotations = descriptor.getOriginal().getAnnotations();
if (annotations != null) {
for (AnnotationDescriptor annotation : annotations) {
if (annotationClass.equals(annotation.getType().getConstructor().getDeclarationDescriptor())) {
return true;
}
}
}
return false;
}
public boolean isArray(@NotNull JetType type) {
return getArray().equals(type.getConstructor().getDeclarationDescriptor());
}
public JetType getTuple0Type() {
return tuple0Type;
}
}