From 04cbea495612b90750144e27e9d91ca26ea9d0df Mon Sep 17 00:00:00 2001 From: Anton Bannykh Date: Tue, 17 Oct 2017 14:34:44 +0300 Subject: [PATCH] JS: fix Long constant translation (KT-19228 fixed) --- .../kotlin/js/inline/FunctionReader.kt | 2 +- .../kotlin/js/inline/util/collectUtils.kt | 40 ++- .../js/test/semantics/BoxJsTestGenerated.java | 6 + .../js/test/utils/DirectiveTestUtils.java | 45 ++- .../kotlin/js/translate/context/Namer.java | 2 + .../js/translate/context/StaticContext.java | 2 +- .../translate/context/TranslationContext.java | 28 ++ .../js/translate/general/Translation.java | 39 ++- .../kotlin/js/translate/utils/JsAstUtils.java | 20 +- .../box/number/constantPropagation.kt | 256 ++++++++++++++++++ .../testData/lineNumbers/longLiteral.kt | 2 +- 11 files changed, 401 insertions(+), 41 deletions(-) create mode 100644 js/js.translator/testData/box/number/constantPropagation.kt diff --git a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/FunctionReader.kt b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/FunctionReader.kt index 23b85483141..b7c52cf88e4 100644 --- a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/FunctionReader.kt +++ b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/FunctionReader.kt @@ -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 } } diff --git a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/util/collectUtils.kt b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/util/collectUtils.kt index 433b1a790fc..d91ce442812 100644 --- a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/util/collectUtils.kt +++ b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/util/collectUtils.kt @@ -346,17 +346,25 @@ fun JsNode.collectBreakContinueTargets(): Map { 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, 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 } \ No newline at end of file diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java index 9507d9160cc..401e27c0cb5 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java @@ -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"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/utils/DirectiveTestUtils.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/utils/DirectiveTestUtils.java index 2251a1a87f0..4d90f9d785d 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/utils/DirectiveTestUtils.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/utils/DirectiveTestUtils.java @@ -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) diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/Namer.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/Namer.java index f61ca84bdbf..fda2397b09e 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/Namer.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/Namer.java @@ -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"; diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java index 1d035fe0b38..415d2dce526 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java @@ -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; diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/TranslationContext.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/TranslationContext.java index 0f61a1c8db5..ac1db137535 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/TranslationContext.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/TranslationContext.java @@ -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()) { diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Translation.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Translation.java index e1f3cc9b7a0..f834e9e5e60 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Translation.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Translation.java @@ -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; + } } } } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/JsAstUtils.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/JsAstUtils.java index 336a7d1d0c4..790fb64898c 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/JsAstUtils.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/JsAstUtils.java @@ -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 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 args = new SmartList<>(); + args.add(new JsIntLiteral(low)); + args.add(new JsIntLiteral(high)); + result = new JsNew(Namer.kotlinLong(), args); + } } else { if (value == 0) { diff --git a/js/js.translator/testData/box/number/constantPropagation.kt b/js/js.translator/testData/box/number/constantPropagation.kt new file mode 100644 index 00000000000..2ef78f9e679 --- /dev/null +++ b/js/js.translator/testData/box/number/constantPropagation.kt @@ -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" +} diff --git a/js/js.translator/testData/lineNumbers/longLiteral.kt b/js/js.translator/testData/lineNumbers/longLiteral.kt index 4162a0e8c5a..2dfe77febfb 100644 --- a/js/js.translator/testData/lineNumbers/longLiteral.kt +++ b/js/js.translator/testData/lineNumbers/longLiteral.kt @@ -5,4 +5,4 @@ fun foo() { 0L) } -// LINES: 6 2 3 4 5 \ No newline at end of file +// LINES: 3 * 5 6 2 4 \ No newline at end of file