Inject builtins in constants

This commit is contained in:
Pavel V. Talanov
2015-07-07 13:34:32 +03:00
parent ea1a85e78c
commit 5dc5d77e60
33 changed files with 111 additions and 96 deletions
@@ -274,7 +274,7 @@ public abstract class AnnotationCodegen {
@Override
public Void visitEnumValue(EnumValue value, Void data) {
String propertyName = value.getValue().getName().asString();
annotationVisitor.visitEnum(name, typeMapper.mapType(value.getType(KotlinBuiltIns.getInstance())).getDescriptor(), propertyName);
annotationVisitor.visitEnum(name, typeMapper.mapType(value.getType()).getDescriptor(), propertyName);
return null;
}
@@ -282,7 +282,7 @@ public abstract class AnnotationCodegen {
public Void visitArrayValue(ArrayValue value, Void data) {
AnnotationVisitor visitor = annotationVisitor.visitArray(name);
for (CompileTimeConstant<?> argument : value.getValue()) {
genCompileTimeValue(null, argument, value.getType(KotlinBuiltIns.getInstance()), visitor);
genCompileTimeValue(null, argument, value.getType(), visitor);
}
visitor.visitEnd();
return null;
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.codegen;
import com.intellij.openapi.util.Pair;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
@@ -45,6 +46,7 @@ import static org.jetbrains.kotlin.codegen.JvmSerializationBindings.*;
public class JvmSerializerExtension extends SerializerExtension {
private final JvmSerializationBindings bindings;
private final JetTypeMapper typeMapper;
private final AnnotationSerializer annotationSerializer = new AnnotationSerializer(KotlinBuiltIns.getInstance());
public JvmSerializerExtension(@NotNull JvmSerializationBindings bindings, @NotNull JetTypeMapper typeMapper) {
this.bindings = bindings;
@@ -77,7 +79,7 @@ public class JvmSerializerExtension extends SerializerExtension {
public void serializeType(@NotNull JetType type, @NotNull ProtoBuf.Type.Builder proto, @NotNull StringTable stringTable) {
// TODO: don't store type annotations in our binary metadata on Java 8, use *TypeAnnotations attributes instead
for (AnnotationDescriptor annotation : type.getAnnotations()) {
proto.addExtension(JvmProtoBuf.typeAnnotation, AnnotationSerializer.INSTANCE$.serializeAnnotation(annotation, stringTable));
proto.addExtension(JvmProtoBuf.typeAnnotation, annotationSerializer.serializeAnnotation(annotation, stringTable));
}
}
@@ -113,7 +113,7 @@ public class BuiltInsSerializer(private val dependOnOldBuiltIns: Boolean) {
// TODO: perform some kind of validation? At the moment not possible because DescriptorValidator is in compiler-tests
// DescriptorValidator.validate(packageView)
val serializer = DescriptorSerializer.createTopLevel(BuiltInsSerializerExtension)
val serializer = DescriptorSerializer.createTopLevel(BuiltInsSerializerExtension(module))
val classifierDescriptors = DescriptorSerializer.sort(packageView.memberScope.getDescriptors(DescriptorKindFilter.CLASSIFIERS))
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.load.java.structure.JavaPropertyInitializerEvaluator
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstantFactory;
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage;
public class JavaPropertyInitializerEvaluatorImpl implements JavaPropertyInitializerEvaluator {
@Nullable
@@ -40,7 +41,7 @@ public class JavaPropertyInitializerEvaluatorImpl implements JavaPropertyInitial
ConstantExpressionEvaluator.isPropertyCompileTimeConstant(descriptor),
false,
true
));
), DescriptorUtilPackage.getBuiltIns(descriptor));
return factory.createCompileTimeConstant(evaluatedExpression, descriptor.getType());
}
return null;
@@ -61,11 +61,9 @@ import static org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE;
public class CallExpressionResolver {
private final CallResolver callResolver;
private final KotlinBuiltIns builtIns;
public CallExpressionResolver(@NotNull CallResolver callResolver, @NotNull KotlinBuiltIns builtIns) {
public CallExpressionResolver(@NotNull CallResolver callResolver) {
this.callResolver = callResolver;
this.builtIns = builtIns;
}
private ExpressionTypingServices expressionTypingServices;
@@ -372,7 +370,7 @@ public class CallExpressionResolver {
CompileTimeConstant<?> value = ConstantExpressionEvaluator.evaluate(expression, context.trace, context.expectedType);
if (value instanceof IntegerValueConstant && ((IntegerValueConstant) value).isPure()) {
return ExpressionTypingUtils.createCompileTimeConstantTypeInfo(value, expression, context, builtIns);
return ExpressionTypingUtils.createCompileTimeConstantTypeInfo(value, expression, context);
}
JetTypeInfo typeInfo;
@@ -89,7 +89,7 @@ public class CompileTimeConstantChecker {
}
if (!noExpectedTypeOrError(expectedType)) {
JetType valueType = value.getType(builtIns);
JetType valueType = value.getType();
if (!JetTypeChecker.DEFAULT.isSubtypeOf(valueType, expectedType)) {
return reportError(CONSTANT_EXPECTED_TYPE_MISMATCH.on(expression, "integer", expectedType));
}
@@ -106,7 +106,7 @@ public class CompileTimeConstantChecker {
return reportError(FLOAT_LITERAL_OUT_OF_RANGE.on(expression));
}
if (!noExpectedTypeOrError(expectedType)) {
JetType valueType = value.getType(builtIns);
JetType valueType = value.getType();
if (!JetTypeChecker.DEFAULT.isSubtypeOf(valueType, expectedType)) {
return reportError(CONSTANT_EXPECTED_TYPE_MISMATCH.on(expression, "floating-point", expectedType));
}
@@ -42,6 +42,8 @@ import kotlin.platform.platformStatic
public class ConstantExpressionEvaluator private constructor(val trace: BindingTrace) : JetVisitor<CompileTimeConstant<*>, JetType>() {
private val builtIns = KotlinBuiltIns.getInstance()
companion object {
platformStatic public fun evaluate(expression: JetExpression, trace: BindingTrace, expectedType: JetType? = TypeUtils.NO_EXPECTED_TYPE): CompileTimeConstant<*>? {
val evaluator = ConstantExpressionEvaluator(trace)
@@ -86,7 +88,7 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
}
private val stringExpressionEvaluator = object : JetVisitor<StringValue, Nothing>() {
private val factory = CompileTimeConstantFactory(CompileTimeConstant.Parameters.Impl(true, false, false))
private val factory = CompileTimeConstantFactory(CompileTimeConstant.Parameters.Impl(true, false, false), builtIns)
fun evaluate(entry: JetStringTemplateEntry): StringValue? {
return entry.accept(this, null)
@@ -108,7 +110,7 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
val text = expression.getText() ?: return null
val nodeElementType = expression.getNode().getElementType()
if (nodeElementType == JetNodeTypes.NULL) return NullValue
if (nodeElementType == JetNodeTypes.NULL) return NullValue(builtIns)
val result: Any? = when (nodeElementType) {
JetNodeTypes.INTEGER_CONSTANT -> parseLong(text)
@@ -249,7 +251,7 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
val canBeUsedInAnnotation = canBeUsedInAnnotation(argumentForReceiver.expression) && canBeUsedInAnnotation(argumentForParameter.expression)
val usesVariableAsConstant = usesVariableAsConstant(argumentForReceiver.expression) || usesVariableAsConstant(argumentForParameter.expression)
val parameters = CompileTimeConstant.Parameters.Impl(canBeUsedInAnnotation, areArgumentsPure, usesVariableAsConstant)
val factory = CompileTimeConstantFactory(parameters)
val factory = CompileTimeConstantFactory(parameters, builtIns)
return when (resultingDescriptorName) {
OperatorConventions.COMPARE_TO -> createCompileTimeConstantForCompareTo(result, callExpression, factory)
OperatorConventions.EQUALS -> createCompileTimeConstantForEquals(result, callExpression, factory)
@@ -493,12 +495,12 @@ public class ConstantExpressionEvaluator private constructor(val trace: BindingT
expectedType: JetType?,
parameters: CompileTimeConstant.Parameters
): CompileTimeConstant<*>? {
return CompileTimeConstantFactory(parameters).createCompileTimeConstant(value, if (parameters.isPure) expectedType ?: TypeUtils.NO_EXPECTED_TYPE else null)
return CompileTimeConstantFactory(parameters, builtIns).createCompileTimeConstant(value, if (parameters.isPure) expectedType ?: TypeUtils.NO_EXPECTED_TYPE else null)
}
}
public fun IntegerValueTypeConstant.createCompileTimeConstantWithType(expectedType: JetType): CompileTimeConstant<*>?
= CompileTimeConstantFactory(CompileTimeConstant.Parameters.Impl(this.canBeUsedInAnnotations(), true, false)).createCompileTimeConstant(this.getValue(expectedType))
= CompileTimeConstantFactory(CompileTimeConstant.Parameters.Impl(this.canBeUsedInAnnotations(), true, false), KotlinBuiltIns.getInstance()).createCompileTimeConstant(this.getValue(expectedType))
private fun hasLongSuffix(text: String) = text.endsWith('l') || text.endsWith('L')
@@ -594,13 +596,13 @@ private fun createCompileTimeConstantForCompareTo(result: Any?, operationReferen
private fun createStringConstant(value: CompileTimeConstant<*>?): StringValue? {
return when (value) {
is IntegerValueTypeConstant -> CompileTimeConstantFactory(value.parameters).createStringValue(value.getValue(TypeUtils.NO_EXPECTED_TYPE).toString())
is IntegerValueTypeConstant -> CompileTimeConstantFactory(value.parameters, KotlinBuiltIns.getInstance()).createStringValue(value.getValue(TypeUtils.NO_EXPECTED_TYPE).toString())
is StringValue -> value
is IntValue, is ByteValue, is ShortValue, is LongValue,
is CharValue,
is DoubleValue, is FloatValue,
is BooleanValue,
is NullValue -> CompileTimeConstantFactory(value.parameters).createStringValue("${value.value}")
is NullValue -> CompileTimeConstantFactory(value.parameters, KotlinBuiltIns.getInstance()).createStringValue("${value.value}")
else -> null
}
}
@@ -133,7 +133,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
}
assert value != null : "CompileTimeConstant should be evaluated for constant expression or an error should be recorded " + expression.getText();
return createCompileTimeConstantTypeInfo(value, expression, context, components.builtIns);
return createCompileTimeConstantTypeInfo(value, expression, context);
}
@NotNull
@@ -942,7 +942,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
CompileTimeConstant<?> value = ConstantExpressionEvaluator.evaluate(expression, contextWithExpectedType.trace,
contextWithExpectedType.expectedType);
if (value != null) {
return createCompileTimeConstantTypeInfo(value, expression, contextWithExpectedType, components.builtIns);
return createCompileTimeConstantTypeInfo(value, expression, contextWithExpectedType);
}
return DataFlowUtils.checkType(typeInfo.replaceType(result),
@@ -1138,7 +1138,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
expression, contextWithExpectedType.trace, contextWithExpectedType.expectedType
);
if (value != null) {
return createCompileTimeConstantTypeInfo(value, expression, contextWithExpectedType, components.builtIns);
return createCompileTimeConstantTypeInfo(value, expression, contextWithExpectedType);
}
return DataFlowUtils.checkType(result, expression, contextWithExpectedType);
}
@@ -246,10 +246,9 @@ public class ExpressionTypingUtils {
public static JetTypeInfo createCompileTimeConstantTypeInfo(
@NotNull CompileTimeConstant<?> value,
@NotNull JetExpression expression,
@NotNull ExpressionTypingContext context,
@NotNull KotlinBuiltIns kotlinBuiltIns
@NotNull ExpressionTypingContext context
) {
JetType expressionType = value.getType(kotlinBuiltIns);
JetType expressionType = value.getType();
if (value instanceof IntegerValueTypeConstant && context.contextDependency == INDEPENDENT) {
expressionType = ((IntegerValueTypeConstant) value).getType(context.expectedType);
ArgumentTypeResolver.updateNumberType(expressionType, expression, context);
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.serialization
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationArgumentVisitor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.resolve.constants.*
@@ -26,9 +27,9 @@ import org.jetbrains.kotlin.serialization.ProtoBuf.Annotation.Argument.Value.Typ
import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.types.JetType
public object AnnotationSerializer {
public class AnnotationSerializer(builtIns: KotlinBuiltIns) {
private val factory = CompileTimeConstantFactory(CompileTimeConstant.Parameters.ThrowException)
private val factory = CompileTimeConstantFactory(CompileTimeConstant.Parameters.ThrowException, builtIns)
public fun serializeAnnotation(annotation: AnnotationDescriptor, stringTable: StringTable): ProtoBuf.Annotation {
return with(ProtoBuf.Annotation.newBuilder()) {
@@ -17,11 +17,7 @@
package org.jetbrains.kotlin.serialization.builtins
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.resolve.constants.NullValue
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
@@ -31,10 +27,13 @@ import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.SerializerExtension
import org.jetbrains.kotlin.serialization.StringTable
public object BuiltInsSerializerExtension : SerializerExtension() {
public class BuiltInsSerializerExtension(module: ModuleDescriptor) : SerializerExtension() {
private val annotationSerializer = AnnotationSerializer(module.builtIns)
override fun serializeClass(descriptor: ClassDescriptor, proto: ProtoBuf.Class.Builder, stringTable: StringTable) {
for (annotation in descriptor.getAnnotations()) {
proto.addExtension(BuiltInsProtoBuf.classAnnotation, AnnotationSerializer.serializeAnnotation(annotation, stringTable))
proto.addExtension(BuiltInsProtoBuf.classAnnotation, annotationSerializer.serializeAnnotation(annotation, stringTable))
}
}
@@ -58,13 +57,13 @@ public object BuiltInsSerializerExtension : SerializerExtension() {
stringTable: StringTable
) {
for (annotation in callable.getAnnotations()) {
proto.addExtension(BuiltInsProtoBuf.callableAnnotation, AnnotationSerializer.serializeAnnotation(annotation, stringTable))
proto.addExtension(BuiltInsProtoBuf.callableAnnotation, annotationSerializer.serializeAnnotation(annotation, stringTable))
}
val propertyDescriptor = callable as? PropertyDescriptor ?: return
val compileTimeConstant = propertyDescriptor.getCompileTimeInitializer()
if (compileTimeConstant != null && compileTimeConstant !is NullValue) {
val type = compileTimeConstant.getType(propertyDescriptor.builtIns)
proto.setExtension(BuiltInsProtoBuf.compileTimeValue, AnnotationSerializer.valueProto(compileTimeConstant, type, stringTable).build())
val valueProto = annotationSerializer.valueProto(compileTimeConstant, compileTimeConstant.type, stringTable)
proto.setExtension(BuiltInsProtoBuf.compileTimeValue, valueProto.build())
}
}
@@ -74,7 +73,7 @@ public object BuiltInsSerializerExtension : SerializerExtension() {
stringTable: StringTable
) {
for (annotation in descriptor.getAnnotations()) {
proto.addExtension(BuiltInsProtoBuf.parameterAnnotation, AnnotationSerializer.serializeAnnotation(annotation, stringTable))
proto.addExtension(BuiltInsProtoBuf.parameterAnnotation, annotationSerializer.serializeAnnotation(annotation, stringTable))
}
}
}