Split CompileTimeConstant into two entities

1. ConstantValue
	* just holds some value and its type
	* implementations for concrete constants
2. CompileTimeConstant
	* is only produced by ConstantExpressionEvaluator
	* has additional flags (canBeUsedInAnnotation etc)
	* has two implementations TypedCompileTimeConstant containing a constant value
		and IntegerValueConstant which does not have exact type
	* can be converted to ConstantValue

Adjustt usages to use ConstantValue if flags are not needed
Add tests for some uncovered cases
This commit is contained in:
Pavel V. Talanov
2015-07-07 14:56:19 +03:00
parent 155f00578d
commit c313887641
134 changed files with 791 additions and 907 deletions
@@ -20,37 +20,28 @@ import com.google.dart.compiler.backend.js.ast.JsFunctionScope
import com.google.dart.compiler.backend.js.ast.JsProgram
import com.google.dart.compiler.backend.js.ast.JsRootScope
import com.google.gwt.dev.js.parserExceptions.AbortParsingException
import com.google.gwt.dev.js.rhino.*
import com.google.gwt.dev.js.rhino.Utils.*
import org.jetbrains.annotations.TestOnly
import com.google.gwt.dev.js.rhino.CodePosition
import com.google.gwt.dev.js.rhino.ErrorReporter
import com.google.gwt.dev.js.rhino.Utils.isEndOfLine
import com.intellij.openapi.util.TextRange
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.diagnostics.ParametrizedDiagnostic
import org.jetbrains.kotlin.js.parser.parse
import org.jetbrains.kotlin.js.patterns.DescriptorPredicate
import org.jetbrains.kotlin.js.patterns.PatternBuilder
import org.jetbrains.kotlin.js.resolve.diagnostics.ErrorsJs
import org.jetbrains.kotlin.psi.JetCallExpression
import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.kotlin.psi.JetLiteralStringTemplateEntry
import org.jetbrains.kotlin.psi.JetStringTemplateExpression
import org.jetbrains.kotlin.renderer.Renderer
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.TemporaryBindingTrace
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
import org.jetbrains.kotlin.types.JetType
import com.intellij.openapi.util.TextRange
import org.jetbrains.kotlin.js.parser.parse
import java.io.StringReader
import kotlin.platform.platformStatic
import org.jetbrains.kotlin.resolve.TemporaryBindingTrace
public class JsCallChecker : CallChecker {
@@ -84,7 +75,7 @@ public class JsCallChecker : CallChecker {
return
}
val code = evaluationResult.value as String
val code = evaluationResult.getValue(stringType) as String
val errorReporter = JsCodeErrorReporter(argument, code, context.trace)
try {
@@ -27,7 +27,7 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.kotlin.js.PredefinedAnnotation;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import java.util.List;
import java.util.Set;
@@ -53,7 +53,7 @@ public final class AnnotationsUtils {
if (annotationDescriptor.getAllValueArguments().isEmpty()) {
return null;
}
CompileTimeConstant<?> constant = annotationDescriptor.getAllValueArguments().values().iterator().next();
ConstantValue<?> constant = annotationDescriptor.getAllValueArguments().values().iterator().next();
//TODO: this is a quick fix for unsupported default args problem
if (constant == null) {
return null;
@@ -18,14 +18,14 @@ package org.jetbrains.kotlin.serialization.js
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant
import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.*
import org.jetbrains.kotlin.types.JetType
class KotlinJavascriptAnnotationAndConstantLoader(
module: ModuleDescriptor
) : AnnotationAndConstantLoader<AnnotationDescriptor, CompileTimeConstant<*>> {
) : AnnotationAndConstantLoader<AnnotationDescriptor, ConstantValue<*>> {
private val deserializer = AnnotationDeserializer(module)
override fun loadClassAnnotations(
@@ -67,7 +67,7 @@ class KotlinJavascriptAnnotationAndConstantLoader(
proto: ProtoBuf.Callable,
nameResolver: NameResolver,
expectedType: JetType
): CompileTimeConstant<*>? {
): ConstantValue<*>? {
val value = proto.getExtension(JsProtoBuf.compileTimeValue)
return deserializer.resolveValue(expectedType, value, nameResolver)
}
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.resolve.constants.NullValue
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.serialization.AnnotationSerializer
import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.SerializerExtension
@@ -48,10 +47,10 @@ public object KotlinJavascriptSerializerExtension : SerializerExtension() {
proto.addExtension(JsProtoBuf.callableAnnotation, annotationSerializer.serializeAnnotation(annotation, stringTable))
}
val propertyDescriptor = callable as? PropertyDescriptor ?: return
val compileTimeConstant = propertyDescriptor.getCompileTimeInitializer()
if (compileTimeConstant != null && compileTimeConstant !is NullValue) {
val type = compileTimeConstant.type
proto.setExtension(JsProtoBuf.compileTimeValue, annotationSerializer.valueProto(compileTimeConstant, type, stringTable).build())
val constantInitializer = propertyDescriptor.getCompileTimeInitializer()
if (constantInitializer != null && constantInitializer !is NullValue) {
val type = constantInitializer.type
proto.setExtension(JsProtoBuf.compileTimeValue, annotationSerializer.valueProto(constantInitializer, type, stringTable).build())
}
}
@@ -41,6 +41,7 @@ import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.BindingContextUtils;
import org.jetbrains.kotlin.resolve.bindingContextUtil.BindingContextUtilPackage;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.resolve.constants.NullValue;
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
import org.jetbrains.kotlin.resolve.inline.InlineUtil;
@@ -75,14 +76,13 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
@NotNull
private static JsNode translateConstantExpression(@NotNull JetConstantExpression expression, @NotNull TranslationContext context) {
CompileTimeConstant<?> compileTimeValue = ConstantExpressionEvaluator.getConstant(expression, context.bindingContext());
assert compileTimeValue != null : message(expression, "Expression is not compile time value: " + expression.getText() + " ");
if (compileTimeValue instanceof NullValue) {
JetType expectedType = context.bindingContext().getType(expression);
ConstantValue<?> constant = compileTimeValue.toConstantValue(expectedType != null ? expectedType : TypeUtils.NO_EXPECTED_TYPE);
if (constant instanceof NullValue) {
return JsLiteral.NULL;
}
Object value = getCompileTimeValue(context.bindingContext(), expression, compileTimeValue);
Object value = constant.getValue();
if (value instanceof Integer || value instanceof Short || value instanceof Byte) {
return context.program().getNumberLiteral(((Number) value).intValue());
}
@@ -29,7 +29,6 @@ import org.jetbrains.kotlin.lexer.JetTokens;
import org.jetbrains.kotlin.psi.JetConstantExpression;
import org.jetbrains.kotlin.psi.JetExpression;
import org.jetbrains.kotlin.psi.JetUnaryExpression;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.BindingContextUtils;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
@@ -130,7 +130,7 @@ public final class CallExpressionTranslator extends AbstractCallExpressionTransl
CompileTimeConstant<?> constant = ConstantExpressionEvaluator.evaluate(jsCodeExpression, bindingTrace, stringType);
assert constant != null: "jsCode must be compile time string " + jsCodeExpression;
String jsCode = (String) constant.getValue();
String jsCode = (String) constant.getValue(stringType);
assert jsCode != null: jsCodeExpression.toString();
// Parser can change local or global scope.
@@ -27,7 +27,6 @@ import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant;
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
import org.jetbrains.kotlin.types.JetType;
import org.jetbrains.kotlin.types.TypeUtils;
@@ -159,14 +158,8 @@ public final class BindingUtils {
@Nullable
public static Object getCompileTimeValue(@NotNull BindingContext context, @NotNull JetExpression expression, @NotNull CompileTimeConstant<?> constant) {
if (constant != null) {
if (constant instanceof IntegerValueTypeConstant) {
JetType expectedType = context.getType(expression);
return ((IntegerValueTypeConstant) constant).getValue(expectedType == null ? TypeUtils.NO_EXPECTED_TYPE : expectedType);
}
return constant.getValue();
}
return null;
JetType expectedType = context.getType(expression);
return constant.getValue(expectedType == null ? TypeUtils.NO_EXPECTED_TYPE : expectedType);
}
@NotNull