JS: fix Long constant translation (KT-19228 fixed)

This commit is contained in:
Anton Bannykh
2017-10-17 14:34:44 +03:00
parent b7d79cc146
commit 04cbea4956
11 changed files with 401 additions and 41 deletions
@@ -277,7 +277,7 @@ class FunctionReader(
})
wrapperStatements?.forEach {
if (it is JsVars && it.vars.size == 1 && it.vars[0].initExpression?.let { extractImportTag(it) } != null) {
if (it is JsVars && it.vars.size == 1 && extractImportTag(it.vars[0]) != null) {
it.vars[0].name.imported = true
}
}
@@ -346,17 +346,25 @@ fun JsNode.collectBreakContinueTargets(): Map<JsContinue, JsStatement> {
fun getImportTag(jsVars: JsVars): String? {
if (jsVars.vars.size == 1) {
val jsVar = jsVars.vars[0]
if (jsVar.initExpression != null && jsVar.name.imported) {
return extractImportTag(jsVar.initExpression)
if (jsVar.name.imported) {
return extractImportTag(jsVar)
}
}
return null
}
fun extractImportTag(expression: JsExpression): String? {
fun extractImportTag(jsVar: JsVars.JsVar): String? {
val initExpression = jsVar.initExpression ?: return null
val sb = StringBuilder()
return if (extractImportTagImpl(expression, sb)) sb.toString() else null
// Handle Long const val import
if (initExpression is JsInvocation || initExpression is JsNew) {
sb.append(jsVar.name.toString()).append(":")
}
return if (extractImportTagImpl(initExpression, sb)) sb.toString() else null
}
private fun extractImportTagImpl(expression: JsExpression, sb: StringBuilder): Boolean {
@@ -378,6 +386,30 @@ private fun extractImportTagImpl(expression: JsExpression, sb: StringBuilder): B
sb.append(JsToStringGenerationVisitor.javaScriptString(stringLiteral.value))
return true
}
is JsInvocation -> {
val invocation = expression
if (!extractImportTagImpl(invocation.qualifier, sb)) return false
if (!appendArguments(invocation.arguments, sb)) return false
return true
}
is JsNew -> {
val newExpr = expression
if (!extractImportTagImpl(newExpr.constructorExpression, sb)) return false
if (!appendArguments(newExpr.arguments, sb)) return false
return true
}
else -> return false
}
}
private fun appendArguments(arguments: List<JsExpression>, sb: StringBuilder): Boolean {
arguments.forEachIndexed { index, arg ->
if (arg !is JsIntLiteral) {
return false
}
sb.append(if (index == 0) "(" else ",")
sb.append(arg.value)
}
sb.append(")")
return true
}
@@ -6831,6 +6831,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
doTest(fileName);
}
@TestMetadata("constantPropagation.kt")
public void testConstantPropagation() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/number/constantPropagation.kt");
doTest(fileName);
}
@TestMetadata("conversionsWithTruncation.kt")
public void testConversionsWithTruncation() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/number/conversionsWithTruncation.kt");
@@ -58,35 +58,37 @@ public class DirectiveTestUtils {
private static final DirectiveHandler PROPERTY_NOT_USED = new DirectiveHandler("PROPERTY_NOT_USED") {
@Override
void processEntry(@NotNull JsNode ast, @NotNull ArgumentsHelper arguments) throws Exception {
checkPropertyNotUsed(ast, arguments.getFirst(), false, false);
checkPropertyNotUsed(ast, arguments.getFirst(), arguments.findNamedArgument("scope"), false, false);
}
};
private static final DirectiveHandler PROPERTY_NOT_READ_FROM = new DirectiveHandler("PROPERTY_NOT_READ_FROM") {
@Override
void processEntry(@NotNull JsNode ast, @NotNull ArgumentsHelper arguments) throws Exception {
checkPropertyNotUsed(ast, arguments.getFirst(), false, true);
checkPropertyNotUsed(ast, arguments.getFirst(), arguments.findNamedArgument("scope"), false, true);
}
};
private static final DirectiveHandler PROPERTY_NOT_WRITTEN_TO = new DirectiveHandler("PROPERTY_NOT_WRITTEN_TO") {
@Override
void processEntry(@NotNull JsNode ast, @NotNull ArgumentsHelper arguments) throws Exception {
checkPropertyNotUsed(ast, arguments.getFirst(), true, false);
checkPropertyNotUsed(ast, arguments.getFirst(), arguments.findNamedArgument("scope"), true, false);
}
};
private static final DirectiveHandler PROPERTY_WRITE_COUNT = new DirectiveHandler("PROPERTY_WRITE_COUNT") {
@Override
void processEntry(@NotNull JsNode ast, @NotNull ArgumentsHelper arguments) throws Exception {
checkPropertyWriteCount(ast, arguments.getNamedArgument("name"), Integer.parseInt(arguments.getNamedArgument("count")));
checkPropertyWriteCount(ast, arguments.getNamedArgument("name"), arguments.findNamedArgument("scope"),
Integer.parseInt(arguments.getNamedArgument("count")));
}
};
private static final DirectiveHandler PROPERTY_READ_COUNT = new DirectiveHandler("PROPERTY_READ_COUNT") {
@Override
void processEntry(@NotNull JsNode ast, @NotNull ArgumentsHelper arguments) throws Exception {
checkPropertyReadCount(ast, arguments.getNamedArgument("name"), Integer.parseInt(arguments.getNamedArgument("count")));
checkPropertyReadCount(ast, arguments.getNamedArgument("name"), arguments.findNamedArgument("scope"),
Integer.parseInt(arguments.getNamedArgument("count")));
}
};
@@ -372,24 +374,37 @@ public class DirectiveTestUtils {
assertEquals(errorMessage, 0, callsCount);
}
public static void checkPropertyNotUsed(JsNode node, String propertyName, boolean isGetAllowed, boolean isSetAllowed) throws Exception {
PropertyReferenceCollector counter = PropertyReferenceCollector.Companion.collect(node);
@NotNull
public static JsNode findScope(@NotNull JsNode node, @Nullable String scopeFunctionName) {
if (scopeFunctionName != null) {
return AstSearchUtil.getFunction(node, scopeFunctionName);
}
return node;
}
public static void checkPropertyNotUsed(JsNode node, String propertyName, String scope, boolean isGetAllowed, boolean isSetAllowed)
throws Exception {
PropertyReferenceCollector counter = PropertyReferenceCollector.Companion.collect(findScope(node, scope));
if (!isGetAllowed) {
assertFalse("inline property getter for `" + propertyName + "` is called", counter.hasUnqualifiedReads(propertyName));
assertFalse("property getter for `" + propertyName + "`" + " in scope: " + scope + " is called",
counter.hasUnqualifiedReads(propertyName));
}
if (!isSetAllowed) {
assertFalse("inline property setter for `" + propertyName + "` is called", counter.hasUnqualifiedWrites(propertyName));
assertFalse("property setter for `" + propertyName + "`" + " in scope: " + scope + " is called",
counter.hasUnqualifiedWrites(propertyName));
}
}
private static void checkPropertyReadCount(JsNode node, String propertyName, int expectedCount) throws Exception {
PropertyReferenceCollector counter = PropertyReferenceCollector.Companion.collect(node);
assertEquals("Property read count: " + propertyName, expectedCount, counter.unqualifiedReadCount(propertyName));
private static void checkPropertyReadCount(JsNode node, String propertyName, String scope, int expectedCount) throws Exception {
PropertyReferenceCollector counter = PropertyReferenceCollector.Companion.collect(findScope(node, scope));
assertEquals("Property read count: " + propertyName + " in scope: " + scope,
expectedCount, counter.unqualifiedReadCount(propertyName));
}
private static void checkPropertyWriteCount(JsNode node, String propertyName, int expectedCount) throws Exception {
PropertyReferenceCollector counter = PropertyReferenceCollector.Companion.collect(node);
assertEquals("Property write count: " + propertyName, expectedCount, counter.unqualifiedWriteCount(propertyName));
private static void checkPropertyWriteCount(JsNode node, String propertyName, String scope, int expectedCount) throws Exception {
PropertyReferenceCollector counter = PropertyReferenceCollector.Companion.collect(findScope(node, scope));
assertEquals("Property write count: " + propertyName + " in scope: " + scope,
expectedCount, counter.unqualifiedWriteCount(propertyName));
}
public static void checkFunctionNotCalled(@NotNull JsNode node, @NotNull String functionName, @Nullable String exceptFunction)
@@ -65,6 +65,8 @@ public final class Namer {
public static final String LONG_ZERO = "ZERO";
public static final String LONG_ONE = "ONE";
public static final String LONG_NEG_ONE = "NEG_ONE";
public static final String LONG_MAX_VALUE = "MAX_VALUE";
public static final String LONG_MIN_VALUE = "MIN_VALUE";
public static final String PRIMITIVE_COMPARE_TO = "primitiveCompareTo";
public static final String IS_CHAR = "isChar";
public static final String IS_NUMBER = "isNumber";
@@ -465,7 +465,7 @@ public final class StaticContext {
}
@NotNull
private JsName importDeclaration(@NotNull String suggestedName, @NotNull String tag, @NotNull JsExpression declaration) {
JsName importDeclaration(@NotNull String suggestedName, @NotNull String tag, @NotNull JsExpression declaration) {
JsName result = importDeclarationImpl(suggestedName, tag, declaration);
fragment.getNameBindings().add(new JsNameBinding(tag, result));
return result;
@@ -879,6 +879,34 @@ public class TranslationContext {
return parent;
}
@NotNull
public JsExpression declareConstantValue(@NotNull DeclarationDescriptor descriptor, @NotNull JsExpression value) {
if (!isPublicInlineFunction() && isFromCurrentModule(descriptor)) {
return getQualifiedReference(descriptor);
}
// Tag shouldn't be null if we cannot reference this descriptor locally.
String tag = Objects.requireNonNull(staticContext.getTag(descriptor));
String suggestedName = StaticContext.getSuggestedName(descriptor);
return declareConstantValue(suggestedName, tag, value);
}
@NotNull
public JsExpression declareConstantValue(@NotNull String suggestedName, @NotNull String tag, @NotNull JsExpression value) {
if (inlineFunctionContext == null || !isPublicInlineFunction()) {
return staticContext.importDeclaration(suggestedName, tag, value).makeRef();
}
else {
return inlineFunctionContext.getImports().computeIfAbsent(tag, t -> {
JsName result = JsScope.declareTemporaryName(suggestedName);
MetadataProperties.setImported(result, true);
inlineFunctionContext.getImportBlock().getStatements().add(JsAstUtils.newVar(result, value));
return result;
}).makeRef();
}
}
@NotNull
public JsName getNameForSpecialFunction(@NotNull SpecialFunction function) {
if (inlineFunctionContext == null || !isPublicInlineFunction()) {
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.js.facade.TranslationUnit;
import org.jetbrains.kotlin.js.facade.exceptions.TranslationException;
import org.jetbrains.kotlin.js.facade.exceptions.TranslationRuntimeException;
import org.jetbrains.kotlin.js.facade.exceptions.UnsupportedFeatureException;
import org.jetbrains.kotlin.js.naming.NameSuggestion;
import org.jetbrains.kotlin.js.sourceMap.SourceFilePathResolver;
import org.jetbrains.kotlin.js.translate.callTranslator.CallTranslator;
import org.jetbrains.kotlin.js.translate.context.Namer;
@@ -41,15 +42,9 @@ import org.jetbrains.kotlin.js.translate.declaration.FileDeclarationVisitor;
import org.jetbrains.kotlin.js.translate.expression.ExpressionVisitor;
import org.jetbrains.kotlin.js.translate.expression.PatternTranslator;
import org.jetbrains.kotlin.js.translate.test.JSTestGenerator;
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils;
import org.jetbrains.kotlin.js.translate.utils.BindingUtils;
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils;
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils;
import org.jetbrains.kotlin.js.translate.utils.*;
import org.jetbrains.kotlin.js.translate.utils.mutator.AssignToExpressionMutator;
import org.jetbrains.kotlin.psi.KtDeclaration;
import org.jetbrains.kotlin.psi.KtExpression;
import org.jetbrains.kotlin.psi.KtFile;
import org.jetbrains.kotlin.psi.KtUnaryExpression;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.BindingTrace;
import org.jetbrains.kotlin.resolve.bindingContextUtil.BindingContextUtilsKt;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
@@ -99,12 +94,30 @@ public final class Translation {
}
CompileTimeConstant<?> compileTimeValue = ConstantExpressionEvaluator.getConstant(expression, context.bindingContext());
if (compileTimeValue != null) {
if (compileTimeValue != null && !compileTimeValue.getUsesNonConstValAsConstant()) {
KotlinType type = context.bindingContext().getType(expression);
if (type != null) {
if (KotlinBuiltIns.isLong(type) || (KotlinBuiltIns.isInt(type) && expression instanceof KtUnaryExpression)) {
JsExpression constantResult = translateConstant(compileTimeValue, expression, context);
if (constantResult != null) return constantResult.source(expression);
if (type != null && (KotlinBuiltIns.isLong(type) || KotlinBuiltIns.isInt(type))) {
JsExpression constantResult = translateConstant(compileTimeValue, expression, context);
if (constantResult != null) {
constantResult.setSource(expression);
if (KotlinBuiltIns.isLong(type)) {
KtReferenceExpression referenceExpression = PsiUtils.getSimpleName(expression);
if (referenceExpression != null) {
DeclarationDescriptor descriptor =
BindingUtils.getDescriptorForReferenceExpression(context.bindingContext(), referenceExpression);
if (descriptor != null) {
return context.declareConstantValue(descriptor, constantResult);
}
}
String name = NameSuggestion.sanitizeName("L" + compileTimeValue.getValue(type).toString());
return context.declareConstantValue(name, "constant:" + name, constantResult);
}
if (KotlinBuiltIns.isInt(type)) {
return constantResult;
}
}
}
}
@@ -169,12 +169,20 @@ public final class JsAstUtils {
public static JsExpression newLong(long value) {
JsExpression result;
if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) {
int low = (int) value;
int high = (int) (value >> 32);
List<JsExpression> args = new SmartList<>();
args.add(new JsIntLiteral(low));
args.add(new JsIntLiteral(high));
result = new JsNew(Namer.kotlinLong(), args);
if (value == Long.MAX_VALUE) {
return new JsNameRef(Namer.LONG_MAX_VALUE, Namer.kotlinLong());
}
else if (value == Long.MIN_VALUE) {
return new JsNameRef(Namer.LONG_MIN_VALUE, Namer.kotlinLong());
}
else {
int low = (int) value;
int high = (int) (value >> 32);
List<JsExpression> args = new SmartList<>();
args.add(new JsIntLiteral(low));
args.add(new JsIntLiteral(high));
result = new JsNew(Namer.kotlinLong(), args);
}
}
else {
if (value == 0) {
@@ -0,0 +1,256 @@
// EXPECTED_REACHABLE_NODES: 1126
// MODULE: lib1
// FILE: lib1.kt
package foo
// PROPERTY_READ_COUNT: name=longValue count=4 scope=testLongVal
// PROPERTY_READ_COUNT: name=L23 count=2 scope=testLongVal
// PROPERTY_READ_COUNT: name=L_23 count=2 scope=testLongVal
// PROPERTY_READ_COUNT: name=L46 count=1 scope=testLongVal
fun testLongVal() {
val longValue = 23L
val longValueCopy = longValue
assertEquals(23L, longValueCopy)
val minusLongValue = -longValue
assertEquals(-23L, minusLongValue)
val minusLongValueParenthesized = -(longValue)
assertEquals(-23L, minusLongValueParenthesized)
val twiceLongValue = 2 * longValue
assertEquals(46L, twiceLongValue)
}
const val longConst = 42L
// PROPERTY_READ_COUNT: name=longConst count=1 scope=testLongConst
// PROPERTY_READ_COUNT: name=L42 count=1 scope=testLongConst
// PROPERTY_READ_COUNT: name=L_42 count=4 scope=testLongConst
// PROPERTY_READ_COUNT: name=L84 count=2 scope=testLongConst
fun testLongConst() {
val longConstCopy = longConst
assertEquals(42L, longConstCopy)
val minusLongConst = -longConst
assertEquals(-42L, minusLongConst)
val minusLongConstParenthesized = -(longConst)
assertEquals(-42L, minusLongConstParenthesized)
val twiceLongConst = 2 * longConst
assertEquals(84L, twiceLongConst)
}
// PROPERTY_READ_COUNT: name=Long$Companion$MAX_VALUE count=2 scope=testLongMaxMinValue
// PROPERTY_READ_COUNT: name=L_9223372036854775807 count=2 scope=testLongMaxMinValue
// PROPERTY_READ_COUNT: name=Long$Companion$MIN_VALUE count=4 scope=testLongMaxMinValue
fun testLongMaxMinValue() {
val longMaxValue = Long.MAX_VALUE
assertEquals(9223372036854775807L, longMaxValue)
val minusLongMaxValue = -Long.MAX_VALUE
assertEquals(-9223372036854775807L, minusLongMaxValue)
val longMinValue = Long.MIN_VALUE
assertEquals(-9223372036854775807L - 1L, longMinValue)
val minusLongMinValue = -Long.MIN_VALUE
assertEquals(-9223372036854775807L - 1L, minusLongMinValue)
}
// PROPERTY_READ_COUNT: name=intValue count=4 scope=testIntVal
fun testIntVal() {
val intValue = 23
val intValueCopy = intValue
assertEquals(23, intValueCopy)
val minusIntValue = -intValue
assertEquals(-23, minusIntValue)
val minusIntValueParenthesized = -(intValue)
assertEquals(-23, minusIntValueParenthesized)
val twiceIntValue = 2 * intValue
assertEquals(46, twiceIntValue)
}
const val intConst = 42
// PROPERTY_NOT_READ_FROM: intConst scope=testIntConst
fun testIntConst() {
val intConstCopy = intConst
assertEquals(42, intConstCopy)
val minusIntConst = -intConst
assertEquals(-42, minusIntConst)
val minusIntConstParenthesized = -(intConst)
assertEquals(-42, minusIntConstParenthesized)
val twiceIntConst = 2 * intConst
assertEquals(84, twiceIntConst)
}
// PROPERTY_NOT_READ_FROM: MAX_VALUE scope=testIntMaxMinValue
// PROPERTY_NOT_READ_FROM: MIN_VALUE scope=testIntMaxMinValue
fun testIntMaxMinValue() {
val intMaxValue = Int.MAX_VALUE
assertEquals(2147483647, intMaxValue)
val minusIntMaxValue = -Int.MAX_VALUE
assertEquals(-2147483647, minusIntMaxValue)
val intMinValue = Int.MIN_VALUE
assertEquals(-2147483648, intMinValue)
val minusIntMinValue = -Int.MIN_VALUE
assertEquals(-2147483648, minusIntMinValue)
}
const val bigLongConst = 123456789012345L
// PROPERTY_READ_COUNT: name=longConst count=1 scope=testImportedLongConstInlineFunLib1
// PROPERTY_READ_COUNT: name=bigLongConst count=1 scope=testImportedLongConstInlineFunLib1
inline fun testImportedLongConstInlineFunLib1() {
val longConstCopy = longConst
assertEquals(42L, longConstCopy)
val minusLongConst = -longConst
assertEquals(-42L, minusLongConst)
val minusLongConstParenthesized = -(longConst)
assertEquals(-42L, minusLongConstParenthesized)
val twiceLongConst = 2 * longConst
assertEquals(84L, twiceLongConst)
val bigLongConstCopy = bigLongConst
assertEquals(123456789012345L, bigLongConstCopy)
}
// PROPERTY_READ_COUNT: name=longConst_0 count=1 scope=testImportedLongConstInlinedLocally
// PROPERTY_READ_COUNT: name=L42 count=1 scope=testImportedLongConstInlinedLocally
// PROPERTY_READ_COUNT: name=L_42 count=4 scope=testImportedLongConstInlinedLocally
// PROPERTY_READ_COUNT: name=L84 count=2 scope=testImportedLongConstInlinedLocally
// PROPERTY_READ_COUNT: name=bigLongConst_0 count=1 scope=testImportedLongConstInlinedLocally
// PROPERTY_READ_COUNT: name=L123456789012345 count=1 scope=testImportedLongConstInlinedLocally
private fun testImportedLongConstInlinedLocally() {
testImportedLongConstInlineFunLib1()
}
fun testLib1() {
testLongVal()
testLongConst()
testLongMaxMinValue()
testIntVal()
testIntConst()
testIntMaxMinValue()
testImportedLongConstInlinedLocally()
}
// MODULE: lib2(lib1)
// FILE: lib2.kt
package foo
// PROPERTY_NOT_READ_FROM: $module$lib1.foo.longConst
// PROPERTY_READ_COUNT: name=longConst count=1 scope=testImportedLongConst
// PROPERTY_READ_COUNT: name=L42 count=1 scope=testImportedLongConst
// PROPERTY_READ_COUNT: name=L_42 count=4 scope=testImportedLongConst
// PROPERTY_READ_COUNT: name=L84 count=2 scope=testImportedLongConst
// PROPERTY_READ_COUNT: name=bigLongConst count=1 scope=testImportedLongConst
// PROPERTY_READ_COUNT: name=L123456789012345 count=1 scope=testImportedLongConst
fun testImportedLongConst() {
val longConstCopy = longConst
assertEquals(42L, longConstCopy)
val minusLongConst = -longConst
assertEquals(-42L, minusLongConst)
val minusLongConstParenthesized = -(longConst)
assertEquals(-42L, minusLongConstParenthesized)
val twiceLongConst = 2 * longConst
assertEquals(84L, twiceLongConst)
val bigLongConstCopy = bigLongConst
assertEquals(123456789012345L, bigLongConstCopy)
}
// PROPERTY_READ_COUNT: name=longConst count=1 scope=testImportedLongConstInlineFun
// PROPERTY_READ_COUNT: name=bigLongConst count=1 scope=testImportedLongConstInlineFun
inline fun testImportedLongConstInlineFun() {
val longConstCopy = longConst
assertEquals(42L, longConstCopy)
val minusLongConst = -longConst
assertEquals(-42L, minusLongConst)
val minusLongConstParenthesized = -(longConst)
assertEquals(-42L, minusLongConstParenthesized)
val twiceLongConst = 2 * longConst
assertEquals(84L, twiceLongConst)
val bigLongConstCopy = bigLongConst
assertEquals(123456789012345L, bigLongConstCopy)
}
// PROPERTY_READ_COUNT: name=longConst count=1 scope=testImportedLongConstInlinedLocally
// PROPERTY_READ_COUNT: name=L42 count=1 scope=testImportedLongConstInlinedLocally
// PROPERTY_READ_COUNT: name=L_42 count=4 scope=testImportedLongConstInlinedLocally
// PROPERTY_READ_COUNT: name=L84 count=2 scope=testImportedLongConstInlinedLocally
// PROPERTY_READ_COUNT: name=bigLongConst count=1 scope=testImportedLongConstInlinedLocally
// PROPERTY_READ_COUNT: name=L123456789012345 count=1 scope=testImportedLongConstInlinedLocally
fun testImportedLongConstInlinedLocally() {
testImportedLongConstInlineFun()
}
// PROPERTY_READ_COUNT: name=longConst count=1 scope=testImportedLongConstInlinedLocallyFromOtherModule
// PROPERTY_READ_COUNT: name=L42 count=1 scope=testImportedLongConstInlinedLocallyFromOtherModule
// PROPERTY_READ_COUNT: name=L_42 count=4 scope=testImportedLongConstInlinedLocallyFromOtherModule
// PROPERTY_READ_COUNT: name=L84 count=2 scope=testImportedLongConstInlinedLocallyFromOtherModule
// PROPERTY_READ_COUNT: name=bigLongConst count=1 scope=testImportedLongConstInlinedLocallyFromOtherModule
// PROPERTY_READ_COUNT: name=L123456789012345 count=1 scope=testImportedLongConstInlinedLocallyFromOtherModule
private fun testImportedLongConstInlinedLocallyFromOtherModule() {
testImportedLongConstInlineFunLib1()
}
fun testLib2() {
testLib1()
testImportedLongConst()
testImportedLongConstInlinedLocallyFromOtherModule()
}
// MODULE: main(lib2)
// FILE: main.kt
package foo
// PROPERTY_READ_COUNT: name=longConst count=1 scope=testImportedLongConstInlinedFromOtherModule
// PROPERTY_READ_COUNT: name=L42 count=1 scope=testImportedLongConstInlinedFromOtherModule
// PROPERTY_READ_COUNT: name=L_42 count=4 scope=testImportedLongConstInlinedFromOtherModule
// PROPERTY_READ_COUNT: name=L84 count=2 scope=testImportedLongConstInlinedFromOtherModule
// PROPERTY_READ_COUNT: name=bigLongConst count=1 scope=testImportedLongConstInlinedFromOtherModule
// PROPERTY_READ_COUNT: name=L123456789012345 count=1 scope=testImportedLongConstInlinedFromOtherModule
fun testImportedLongConstInlinedFromOtherModule() {
testImportedLongConstInlineFun()
}
fun box(): String {
testLib2()
testImportedLongConstInlinedLocally()
testImportedLongConstInlinedFromOtherModule()
return "OK"
}
+1 -1
View File
@@ -5,4 +5,4 @@ fun foo() {
0L)
}
// LINES: 6 2 3 4 5
// LINES: 3 * 5 6 2 4