JS: fix inlining in a new flat JS generator

This commit is contained in:
Alexey Andreev
2016-10-17 16:24:02 +03:00
parent e13d34e08d
commit 20396b0e5f
257 changed files with 384 additions and 4228 deletions
@@ -1173,7 +1173,7 @@ fun main(args: Array<String>) {
} }
} }
generateTestDataForReservedWords() //generateTestDataForReservedWords()
testGroup("js/js.tests/test", "js/js.translator/testData") { testGroup("js/js.tests/test", "js/js.translator/testData") {
testClass<AbstractBoxJsTest>() { testClass<AbstractBoxJsTest>() {
@@ -64,7 +64,7 @@ public class JsInliner extends JsVisitorWithContextImpl {
public static JsProgram process(@NotNull TranslationContext context) { public static JsProgram process(@NotNull TranslationContext context) {
JsProgram program = context.program(); JsProgram program = context.program();
IdentityHashMap<JsName, JsFunction> functions = CollectUtilsKt.collectNamedFunctions(program); Map<JsName, JsFunction> functions = CollectUtilsKt.collectNamedFunctions(program);
JsInliner inliner = new JsInliner(functions, new FunctionReader(context), context.bindingTrace()); JsInliner inliner = new JsInliner(functions, new FunctionReader(context), context.bindingTrace());
inliner.accept(program); inliner.accept(program);
RemoveUnusedFunctionDefinitionsKt.removeUnusedFunctionDefinitions(program, functions); RemoveUnusedFunctionDefinitionsKt.removeUnusedFunctionDefinitions(program, functions);
@@ -22,6 +22,7 @@ import com.google.dart.compiler.backend.js.ast.metadata.staticRef
import org.jetbrains.kotlin.js.inline.util.collectors.InstanceCollector import org.jetbrains.kotlin.js.inline.util.collectors.InstanceCollector
import org.jetbrains.kotlin.js.inline.util.collectors.PropertyCollector import org.jetbrains.kotlin.js.inline.util.collectors.PropertyCollector
import org.jetbrains.kotlin.js.translate.expression.* import org.jetbrains.kotlin.js.translate.expression.*
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
import java.util.* import java.util.*
fun collectFunctionReferencesInside(scope: JsNode): List<JsName> = fun collectFunctionReferencesInside(scope: JsNode): List<JsName> =
@@ -133,19 +134,54 @@ fun collectJsProperties(scope: JsNode): IdentityHashMap<JsName, JsExpression> {
return collector.properties return collector.properties
} }
fun collectNamedFunctions(scope: JsNode): IdentityHashMap<JsName, JsFunction> { fun collectNamedFunctions(scope: JsNode) = collectNamedFunctionsAndMetadata(scope).mapValues { it.value.first }
val namedFunctions = IdentityHashMap<JsName, JsFunction>()
for ((name, value) in collectJsProperties(scope)) { fun collectNamedFunctionsOrMetadata(scope: JsNode) = collectNamedFunctionsAndMetadata(scope).mapValues { it.value.second }
val function: JsFunction? = when (value) {
is JsFunction -> value fun collectNamedFunctionsAndMetadata(scope: JsNode): Map<JsName, Pair<JsFunction, JsExpression>> {
else -> InlineMetadata.decompose(value)?.function val namedFunctions = mutableMapOf<JsName, Pair<JsFunction, JsExpression>>()
scope.accept(object : RecursiveJsVisitor() {
override fun visitBinaryExpression(x: JsBinaryOperation) {
val assignment = JsAstUtils.decomposeAssignment(x)
if (assignment != null) {
val (left, right) = assignment
if (left is JsNameRef) {
val name = left.name
val function = extractFunction(right)
if (function != null && name != null) {
namedFunctions[name] = Pair(function, right)
}
}
}
super.visitBinaryExpression(x)
} }
if (function != null) { override fun visit(x: JsVars.JsVar) {
namedFunctions[name] = function val initializer = x.initExpression
val name = x.name
if (initializer != null && name != null) {
val function = extractFunction(initializer)
if (function != null) {
namedFunctions[name] = Pair(function, initializer)
}
}
super.visit(x)
} }
}
override fun visitFunction(x: JsFunction) {
val name = x.name
if (name != null) {
namedFunctions[name] = Pair(x, x)
}
super.visitFunction(x)
}
private fun extractFunction(expression: JsExpression) = when (expression) {
is JsFunction -> expression
else -> InlineMetadata.decompose(expression)?.function
}
})
return namedFunctions return namedFunctions
} }
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.js.inline.util.collectors
import com.google.dart.compiler.backend.js.ast.* import com.google.dart.compiler.backend.js.ast.*
import org.jetbrains.kotlin.js.translate.expression.InlineMetadata import org.jetbrains.kotlin.js.translate.expression.InlineMetadata
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
import java.util.IdentityHashMap import java.util.IdentityHashMap
+12 -2
View File
@@ -16,9 +16,19 @@
package kotlin package kotlin
open class Error(message: String? = null) : Throwable(message, null) {} open class Error(message: String? = null) : Throwable(message, null) {
init {
val self: dynamic = this
self.message = message
}
}
open class Exception(message: String? = null) : Throwable(message, null) {} open class Exception(message: String? = null) : Throwable(message, null) {
init {
val self: dynamic = this
self.message = message
}
}
open class RuntimeException(message: String? = null) : Exception(message) {} open class RuntimeException(message: String? = null) : Exception(message) {}
File diff suppressed because it is too large Load Diff
@@ -22,6 +22,7 @@ import com.google.dart.compiler.backend.js.ast.JsName;
import com.google.dart.compiler.backend.js.ast.JsNode; import com.google.dart.compiler.backend.js.ast.JsNode;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.js.inline.util.CollectUtilsKt;
import java.util.Map; import java.util.Map;
@@ -43,6 +44,13 @@ public class AstSearchUtil {
return property; return property;
} }
@NotNull
public static JsExpression getMetadataOrFunction(@NotNull JsNode searchRoot, @NotNull String name) {
JsExpression property = findByIdent(CollectUtilsKt.collectNamedFunctionsOrMetadata(searchRoot), name);
assert property != null: "Property `" + name + "` was not found";
return property;
}
@Nullable @Nullable
private static <T extends JsExpression> T findByIdent(@NotNull Map<JsName, T> properties, @NotNull String name) { private static <T extends JsExpression> T findByIdent(@NotNull Map<JsName, T> properties, @NotNull String name) {
for (Map.Entry<JsName, T> entry : properties.entrySet()) { for (Map.Entry<JsName, T> entry : properties.entrySet()) {
@@ -94,7 +94,7 @@ public class DirectiveTestUtils {
@NotNull @NotNull
String getFunctionCode(@NotNull JsNode ast, @NotNull String functionName) { String getFunctionCode(@NotNull JsNode ast, @NotNull String functionName) {
JsFunction function = AstSearchUtil.getFunction(ast, functionName); JsFunction function = AstSearchUtil.getFunction(ast, functionName);
return function.toString(); return function.getBody().toString();
} }
@NotNull @NotNull
@@ -213,7 +213,7 @@ public class DirectiveTestUtils {
@Override @Override
void processEntry(@NotNull JsNode ast, @NotNull ArgumentsHelper arguments) throws Exception { void processEntry(@NotNull JsNode ast, @NotNull ArgumentsHelper arguments) throws Exception {
String functionName = arguments.getPositionalArgument(0); String functionName = arguments.getPositionalArgument(0);
JsExpression property = AstSearchUtil.getProperty(ast, functionName); JsExpression property = AstSearchUtil.getMetadataOrFunction(ast, functionName);
String message = "Inline metadata has not been generated for function " + functionName; String message = "Inline metadata has not been generated for function " + functionName;
assertNotNull(message, InlineMetadata.decompose(property)); assertNotNull(message, InlineMetadata.decompose(property));
} }
@@ -223,7 +223,7 @@ public class DirectiveTestUtils {
@Override @Override
void processEntry(@NotNull JsNode ast, @NotNull ArgumentsHelper arguments) throws Exception { void processEntry(@NotNull JsNode ast, @NotNull ArgumentsHelper arguments) throws Exception {
String functionName = arguments.getPositionalArgument(0); String functionName = arguments.getPositionalArgument(0);
JsExpression property = AstSearchUtil.getProperty(ast, functionName); JsExpression property = AstSearchUtil.getMetadataOrFunction(ast, functionName);
String message = "Inline metadata has been generated for not effectively public function " + functionName; String message = "Inline metadata has been generated for not effectively public function " + functionName;
assertTrue(message, property instanceof JsFunction); assertTrue(message, property instanceof JsFunction);
} }
@@ -49,7 +49,7 @@ fun CallInfo.isSuperInvocation(): Boolean {
val CallInfo.calleeOwner: JsExpression val CallInfo.calleeOwner: JsExpression
get() { get() {
val calleeOwner = resolvedCall.resultingDescriptor.containingDeclaration val calleeOwner = resolvedCall.resultingDescriptor.containingDeclaration
return ReferenceTranslator.translateAsFQReference(calleeOwner, context) return ReferenceTranslator.translateAsValueReference(calleeOwner, context)
} }
val VariableAccessInfo.variableDescriptor: VariableDescriptor val VariableAccessInfo.variableDescriptor: VariableDescriptor
@@ -81,7 +81,7 @@ object DefaultFunctionCallCase : FunctionCallCase() {
return JsInvocation(JsNameRef(context.getNameForDescriptor(callableDescriptor)), argumentsInfo.translateArguments) return JsInvocation(JsNameRef(context.getNameForDescriptor(callableDescriptor)), argumentsInfo.translateArguments)
} }
val functionRef = ReferenceTranslator.translateAsFQReference(callableDescriptor, context) val functionRef = ReferenceTranslator.translateAsValueReference(callableDescriptor, context)
return JsInvocation(functionRef, argumentsInfo.translateArguments) return JsInvocation(functionRef, argumentsInfo.translateArguments)
} }
@@ -101,7 +101,7 @@ object DefaultFunctionCallCase : FunctionCallCase() {
return JsInvocation(JsNameRef(functionName, extensionReceiver), argumentsInfo.translateArguments) return JsInvocation(JsNameRef(functionName, extensionReceiver), argumentsInfo.translateArguments)
} }
val functionRef = ReferenceTranslator.translateAsFQReference(callableDescriptor, context) val functionRef = ReferenceTranslator.translateAsValueReference(callableDescriptor, context)
val referenceToCall = val referenceToCall =
if (callableDescriptor.visibility == Visibilities.LOCAL) { if (callableDescriptor.visibility == Visibilities.LOCAL) {
@@ -212,7 +212,7 @@ object ConstructorCallCase : FunctionCallCase() {
private inline fun FunctionCallInfo.doTranslate( private inline fun FunctionCallInfo.doTranslate(
getArguments: CallArgumentTranslator.ArgumentsInfo.() -> List<JsExpression> getArguments: CallArgumentTranslator.ArgumentsInfo.() -> List<JsExpression>
): JsExpression { ): JsExpression {
val functionRef = ReferenceTranslator.translateAsFQReference(callableDescriptor, context) val functionRef = ReferenceTranslator.translateAsValueReference(callableDescriptor, context)
val invocationArguments = mutableListOf<JsExpression>() val invocationArguments = mutableListOf<JsExpression>()
val constructorDescriptor = callableDescriptor as ClassConstructorDescriptor val constructorDescriptor = callableDescriptor as ClassConstructorDescriptor
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
import org.jetbrains.kotlin.js.translate.context.Namer import org.jetbrains.kotlin.js.translate.context.Namer
import org.jetbrains.kotlin.js.translate.context.Namer.getCapturedVarAccessor import org.jetbrains.kotlin.js.translate.context.Namer.getCapturedVarAccessor
import org.jetbrains.kotlin.js.translate.reference.ReferenceTranslator
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.pureFqn import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.pureFqn
import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils
@@ -84,17 +85,7 @@ object DefaultVariableAccessCase : VariableAccessCase() {
return JsInvocation(pureFqn(context.getNameForObjectInstance (descriptor.getReferencedObject()), null)) return JsInvocation(pureFqn(context.getNameForObjectInstance (descriptor.getReferencedObject()), null))
} }
val functionRef = context.aliasOrValue(callableDescriptor) { val functionRef = ReferenceTranslator.translateAsValueReference(callableDescriptor, context)
if (context.isFromCurrentModule(variableDescriptor)) {
context.getInnerReference(variableDescriptor)
}
else {
val qualifier = context.getInnerReference(variableDescriptor.containingDeclaration)
val name = context.getNameForDescriptor(variableDescriptor)
JsNameRef(name, qualifier)
}
}
val ref = if (isVarCapturedInClosure(context.bindingContext(), callableDescriptor)) { val ref = if (isVarCapturedInClosure(context.bindingContext(), callableDescriptor)) {
getCapturedVarAccessor(functionRef) getCapturedVarAccessor(functionRef)
} }
@@ -170,7 +161,8 @@ object SuperPropertyAccessCase : VariableAccessCase() {
return if (descriptor is PropertyDescriptor && TranslationUtils.shouldAccessViaFunctions(descriptor)) { return if (descriptor is PropertyDescriptor && TranslationUtils.shouldAccessViaFunctions(descriptor)) {
val accessor = getAccessDescriptorIfNeeded() val accessor = getAccessDescriptorIfNeeded()
val prototype = pureFqn(Namer.getPrototypeName(), context.getInnerReference(descriptor.containingDeclaration)) val containingRef = ReferenceTranslator.translateAsValueReference(descriptor.containingDeclaration, context)
val prototype = pureFqn(Namer.getPrototypeName(), containingRef)
val funRef = Namer.getFunctionCallRef(pureFqn(context.getNameForDescriptor(accessor), prototype)) val funRef = Namer.getFunctionCallRef(pureFqn(context.getNameForDescriptor(accessor), prototype))
val arguments = listOf(dispatchReceiver!!) + additionalArguments val arguments = listOf(dispatchReceiver!!) + additionalArguments
JsInvocation(funRef, *arguments.toTypedArray()) JsInvocation(funRef, *arguments.toTypedArray())
@@ -153,6 +153,9 @@ public final class StaticContext {
@NotNull @NotNull
private final JsObjectLiteral exportObject = rootPackage.objectLiteral; private final JsObjectLiteral exportObject = rootPackage.objectLiteral;
@NotNull
private final Set<MemberDescriptor> exportedDeclarations = new HashSet<MemberDescriptor>();
//TODO: too many parameters in constructor //TODO: too many parameters in constructor
private StaticContext( private StaticContext(
@NotNull JsProgram program, @NotNull JsProgram program,
@@ -527,7 +530,9 @@ public final class StaticContext {
return null; return null;
} }
if (getSuperclass((ClassDescriptor) descriptor) == null) { if (getSuperclass((ClassDescriptor) descriptor) == null) {
return rootFunction.getScope(); JsFunction function = new JsFunction(rootFunction.getScope(), new JsBlock(), descriptor.toString());
scopeToFunction.put(function.getScope(), function);
return function.getScope();
} }
return null; return null;
} }
@@ -555,8 +560,7 @@ public final class StaticContext {
Rule<JsScope> generateInnerScopesForMembers = new Rule<JsScope>() { Rule<JsScope> generateInnerScopesForMembers = new Rule<JsScope>() {
@Override @Override
public JsScope apply(@NotNull DeclarationDescriptor descriptor) { public JsScope apply(@NotNull DeclarationDescriptor descriptor) {
JsScope enclosingScope = getEnclosingScope(descriptor); return rootFunction.getScope().innerObjectScope("Scope for member " + descriptor.getName());
return enclosingScope.innerObjectScope("Scope for member " + descriptor.getName());
} }
}; };
Rule<JsScope> createFunctionObjectsForCallableDescriptors = new Rule<JsScope>() { Rule<JsScope> createFunctionObjectsForCallableDescriptors = new Rule<JsScope>() {
@@ -659,27 +663,40 @@ public final class StaticContext {
classes.add(classDescriptor); classes.add(classDescriptor);
} }
public void export(@NotNull DeclarationDescriptor descriptor) { public void export(@NotNull MemberDescriptor descriptor, boolean force) {
DeclarationDescriptor container = descriptor.getContainingDeclaration(); if (exportedDeclarations.contains(descriptor)) return;
if (descriptor instanceof ConstructorDescriptor) {
ConstructorDescriptor constructor = (ConstructorDescriptor) descriptor;
container = constructor.getConstructedClass().getContainingDeclaration();
}
if (!(container instanceof PackageFragmentDescriptor)) {
throw new IllegalArgumentException("Declaration " + descriptor + " is not a top-level declaration");
}
PackageFragmentDescriptor packageDescriptor = (PackageFragmentDescriptor) container; if (descriptor instanceof ConstructorDescriptor && ((ConstructorDescriptor) descriptor).isPrimary()) return;
ExportedPackage exportedPackage = rootPackage;
for (Name packageName : packageDescriptor.getFqName().pathSegments()) {
exportedPackage = exportedPackage.getSubpackage(packageName.asString());
}
JsExpression initializerExpr = DeclarationExporter.exportDeclaration(this, descriptor, exportStatements); SuggestedName suggestedName = nameSuggestion.suggest(descriptor);
if (initializerExpr != null) { if (suggestedName == null) return;
JsPropertyInitializer initializer = new JsPropertyInitializer(
getNameForDescriptor(descriptor).makeRef(), initializerExpr); DeclarationDescriptor container = suggestedName.getScope();
exportedPackage.objectLiteral.getPropertyInitializers().add(initializer); if (!DeclarationExporter.shouldBeExported(descriptor, force)) return;
exportedDeclarations.add(descriptor);
if (container instanceof PackageFragmentDescriptor) {
PackageFragmentDescriptor packageDescriptor = (PackageFragmentDescriptor) container;
ExportedPackage exportedPackage = rootPackage;
for (Name packageName : packageDescriptor.getFqName().pathSegments()) {
exportedPackage = exportedPackage.getSubpackage(packageName.asString());
}
JsExpression initializerExpr = DeclarationExporter.exportDeclaration(this, descriptor, exportStatements);
if (initializerExpr != null) {
JsName propertyName = getNameForDescriptor(descriptor);
if (MetadataProperties.getStaticRef(propertyName) == null) {
if (!(initializerExpr instanceof JsNameRef) || ((JsNameRef) initializerExpr).getName() != propertyName) {
MetadataProperties.setStaticRef(propertyName, initializerExpr);
}
}
JsPropertyInitializer initializer = new JsPropertyInitializer(propertyName.makeRef(), initializerExpr);
exportedPackage.objectLiteral.getPropertyInitializers().add(initializer);
}
}
else {
JsExpression initializerExpr = DeclarationExporter.exportDeclaration(this, descriptor, exportStatements);
assert initializerExpr == null : "Should not produce initializer for non-package declaration";
} }
} }
@@ -698,11 +715,12 @@ public final class StaticContext {
rootFunction.getBody().getStatements().addAll(importStatements); rootFunction.getBody().getStatements().addAll(importStatements);
addClassPrototypes(); addClassPrototypes();
rootFunction.getBody().getStatements().addAll(declarationStatements); rootFunction.getBody().getStatements().addAll(declarationStatements);
rootFunction.getBody().getStatements().addAll(topLevelStatements);
JsName rootPackageName = rootFunction.getScope().declareName(Namer.getRootPackageName()); JsName rootPackageName = rootFunction.getScope().declareName(Namer.getRootPackageName());
rootFunction.getBody().getStatements().add(JsAstUtils.newVar(rootPackageName, exportObject)); rootFunction.getBody().getStatements().add(JsAstUtils.newVar(rootPackageName, exportObject));
rootFunction.getBody().getStatements().addAll(exportStatements); rootFunction.getBody().getStatements().addAll(exportStatements);
rootFunction.getBody().getStatements().addAll(topLevelStatements);
} }
private void addClassPrototypes() { private void addClassPrototypes() {
@@ -236,6 +236,9 @@ public class TranslationContext {
@NotNull @NotNull
public JsNameRef getQualifiedReference(@NotNull DeclarationDescriptor descriptor) { public JsNameRef getQualifiedReference(@NotNull DeclarationDescriptor descriptor) {
if (descriptor instanceof MemberDescriptor && isFromCurrentModule(descriptor) && isPublicInlineFunction()) {
staticContext.export((MemberDescriptor) descriptor, true);
}
return staticContext.getQualifiedReference(descriptor); return staticContext.getQualifiedReference(descriptor);
} }
@@ -608,14 +611,20 @@ public class TranslationContext {
staticContext.addClass(classDescriptor); staticContext.addClass(classDescriptor);
} }
public void export(@NotNull DeclarationDescriptor descriptor) { public void export(@NotNull MemberDescriptor descriptor) {
staticContext.export(descriptor); staticContext.export(descriptor, false);
} }
public boolean isFromCurrentModule(@NotNull DeclarationDescriptor descriptor) { public boolean isFromCurrentModule(@NotNull DeclarationDescriptor descriptor) {
return staticContext.getCurrentModule() == DescriptorUtilsKt.getModule(descriptor); return staticContext.getCurrentModule() == DescriptorUtilsKt.getModule(descriptor);
} }
public boolean isPublicInlineFunction() {
if (!(declarationDescriptor instanceof FunctionDescriptor)) return false;
FunctionDescriptor function = (FunctionDescriptor) declarationDescriptor;
return function.isInline() && DescriptorUtilsKt.isEffectivelyPublicApi(function);
}
@NotNull @NotNull
public ModuleDescriptor getCurrentModule() { public ModuleDescriptor getCurrentModule() {
return staticContext.getCurrentModule(); return staticContext.getCurrentModule();
@@ -19,39 +19,81 @@ package org.jetbrains.kotlin.js.translate.context
import com.google.dart.compiler.backend.js.ast.* import com.google.dart.compiler.backend.js.ast.*
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyPublicApi
fun StaticContext.exportDeclaration(declaration: DeclarationDescriptor, additionalStatements: MutableList<in JsStatement>): JsExpression? { // TODO: refactor
fun StaticContext.exportDeclaration(declaration: MemberDescriptor, additionalStatements: MutableList<in JsStatement>): JsExpression? {
val scope = nameSuggestion.suggest(declaration)!!.scope
return when { return when {
declaration is ClassDescriptor && declaration.kind == ClassKind.OBJECT -> { declaration is ClassDescriptor -> when {
exportObject(declaration, additionalStatements) declaration.kind == ClassKind.OBJECT || declaration.kind == ClassKind.ENUM_ENTRY -> {
null exportObject(declaration, scope, additionalStatements)
null
}
scope is ClassDescriptor -> {
exportNested(declaration, scope, additionalStatements)
null
}
else -> {
getInnerNameForDescriptor(declaration).makeRef()
}
} }
declaration is PropertyDescriptor -> { declaration is PropertyDescriptor -> {
exportProperty(declaration, additionalStatements) if (scope is PackageFragmentDescriptor) {
exportProperty(declaration, scope, additionalStatements)
}
null null
} }
else -> { scope is PackageFragmentDescriptor -> {
getInnerNameForDescriptor(declaration).makeRef() getInnerNameForDescriptor(declaration).makeRef()
} }
else -> null
} }
} }
private fun StaticContext.exportObject(declaration: ClassDescriptor, additionalStatements: MutableList<in JsStatement>) { fun MemberDescriptor.shouldBeExported(force: Boolean) =
val suggestedName = nameSuggestion.suggest(declaration)!! force || isEffectivelyPublicApi || AnnotationsUtils.getJsNameAnnotation(this) != null
val qualifier = getQualifiedReference(suggestedName.scope)
private fun StaticContext.exportNested(
descriptor: ClassDescriptor,
scope: ClassDescriptor,
additionalStatements: MutableList<in JsStatement>
) {
val qualifier = getBaseReference(scope)
val reference = JsAstUtils.pureFqn(getNameForDescriptor(descriptor), qualifier)
val instanceRef = JsAstUtils.pureFqn(getInnerNameForDescriptor(descriptor), null)
additionalStatements += JsAstUtils.assignment(reference, instanceRef).makeStmt()
}
private fun StaticContext.exportObject(
declaration: ClassDescriptor,
scope: DeclarationDescriptor,
additionalStatements: MutableList<in JsStatement>
) {
val qualifier = getBaseReference(scope)
val name = getNameForDescriptor(declaration) val name = getNameForDescriptor(declaration)
additionalStatements += JsAstUtils.defineGetter(program, qualifier, name.ident, getNameForObjectInstance(declaration).makeRef()) additionalStatements += JsAstUtils.defineGetter(program, qualifier, name.ident, getNameForObjectInstance(declaration).makeRef())
} }
private fun StaticContext.exportProperty(declaration: PropertyDescriptor, additionalStatements: MutableList<in JsStatement>) { private fun StaticContext.getBaseReference(declaration: DeclarationDescriptor) = when (declaration) {
is PackageFragmentDescriptor -> getQualifiedReference(declaration)
else -> JsAstUtils.pureFqn(getInnerNameForDescriptor(declaration), null)
}
private fun StaticContext.exportProperty(
declaration: PropertyDescriptor,
scope: DeclarationDescriptor,
additionalStatements: MutableList<in JsStatement>
) {
val propertyLiteral = JsObjectLiteral(true) val propertyLiteral = JsObjectLiteral(true)
val suggestedName = nameSuggestion.suggest(declaration)!! val qualifier = getBaseReference(scope)
val qualifier = getQualifiedReference(suggestedName.scope)
val name = getNameForDescriptor(declaration).ident val name = getNameForDescriptor(declaration).ident
val getterBody: JsExpression = if (JsDescriptorUtils.isSimpleFinalProperty(declaration)) { val getterBody: JsExpression = if (JsDescriptorUtils.isSimpleFinalProperty(declaration)) {
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.js.translate.context.*
import org.jetbrains.kotlin.js.translate.expression.FunctionTranslator import org.jetbrains.kotlin.js.translate.expression.FunctionTranslator
import org.jetbrains.kotlin.js.translate.general.AbstractTranslator import org.jetbrains.kotlin.js.translate.general.AbstractTranslator
import org.jetbrains.kotlin.js.translate.initializer.ClassInitializerTranslator import org.jetbrains.kotlin.js.translate.initializer.ClassInitializerTranslator
import org.jetbrains.kotlin.js.translate.reference.ReferenceTranslator
import org.jetbrains.kotlin.js.translate.utils.* import org.jetbrains.kotlin.js.translate.utils.*
import org.jetbrains.kotlin.js.translate.utils.BindingUtils.getClassDescriptor import org.jetbrains.kotlin.js.translate.utils.BindingUtils.getClassDescriptor
import org.jetbrains.kotlin.js.translate.utils.BindingUtils.getPropertyDescriptorForConstructorParameter import org.jetbrains.kotlin.js.translate.utils.BindingUtils.getPropertyDescriptorForConstructorParameter
@@ -301,7 +302,7 @@ class ClassTranslator private constructor(
val name = nonConstructorUsageTracker.getNameForCapturedDescriptor(it)!! val name = nonConstructorUsageTracker.getNameForCapturedDescriptor(it)!!
JsAstUtils.pureFqn(name, closureQualifier) JsAstUtils.pureFqn(name, closureQualifier)
} }
callSite.invocationArgs.addAll(0, closureArgs.toList()) callSite.invocationArgs.addAll(0, closureArgs)
} }
} }
} }
@@ -340,7 +341,7 @@ class ClassTranslator private constructor(
if (supertypes.size == 1) { if (supertypes.size == 1) {
val type = supertypes[0] val type = supertypes[0]
val supertypeDescriptor = getClassDescriptorForType(type) val supertypeDescriptor = getClassDescriptorForType(type)
return listOf(context().getInnerReference(supertypeDescriptor)) return listOf(ReferenceTranslator.translateAsTypeReference(supertypeDescriptor, context()))
} }
val supertypeConstructors = mutableSetOf<TypeConstructor>() val supertypeConstructors = mutableSetOf<TypeConstructor>()
@@ -356,7 +357,7 @@ class ClassTranslator private constructor(
for (typeConstructor in sortedAllSuperTypes) { for (typeConstructor in sortedAllSuperTypes) {
if (supertypeConstructors.contains(typeConstructor)) { if (supertypeConstructors.contains(typeConstructor)) {
val supertypeDescriptor = getClassDescriptorForTypeConstructor(typeConstructor) val supertypeDescriptor = getClassDescriptorForTypeConstructor(typeConstructor)
supertypesRefs += context().getInnerReference(supertypeDescriptor) supertypesRefs += ReferenceTranslator.translateAsTypeReference(supertypeDescriptor, context())
} }
} }
return supertypesRefs return supertypesRefs
@@ -62,6 +62,7 @@ class DeclarationBodyVisitor(
assert(supertypes.size == 1) { "Simple Enum entry must have one supertype" } assert(supertypes.size == 1) { "Simple Enum entry must have one supertype" }
val jsEnumEntryCreation = ClassInitializerTranslator val jsEnumEntryCreation = ClassInitializerTranslator
.generateEnumEntryInstanceCreation(context, supertypes[0], enumEntry, enumEntryOrdinal) .generateEnumEntryInstanceCreation(context, supertypes[0], enumEntry, enumEntryOrdinal)
context.addDeclarationStatement(JsAstUtils.newVar(enumInstanceName, jsEnumEntryCreation))
val jsEnumEntryFunction = context.createTopLevelAnonymousFunction(descriptor) val jsEnumEntryFunction = context.createTopLevelAnonymousFunction(descriptor)
jsEnumEntryFunction.body.statements.add(JsReturn(jsEnumEntryCreation)) jsEnumEntryFunction.body.statements.add(JsReturn(jsEnumEntryCreation))
@@ -69,12 +70,6 @@ class DeclarationBodyVisitor(
enumInstanceFunction.name = context.getNameForObjectInstance(descriptor) enumInstanceFunction.name = context.getNameForObjectInstance(descriptor)
context.addDeclarationStatement(enumInstanceFunction.makeStmt()) context.addDeclarationStatement(enumInstanceFunction.makeStmt())
val classRef = context.getInnerReference(descriptor.containingDeclaration)
val enumExtName = context.getNameForDescriptor(descriptor)
val enumExtFq = JsNameRef(enumExtName, classRef)
context.addDeclarationStatement(JsAstUtils.assignment(enumExtFq, enumInstanceFunction.name.makeRef()).makeStmt())
context.addDeclarationStatement(JsAstUtils.newVar(enumInstanceName, jsEnumEntryCreation))
enumInstanceFunction.body.statements.add(JsReturn(enumInstanceName.makeRef())) enumInstanceFunction.body.statements.add(JsReturn(enumInstanceName.makeRef()))
} }
@@ -92,7 +87,7 @@ class DeclarationBodyVisitor(
} }
override fun addClass(descriptor: ClassDescriptor) { override fun addClass(descriptor: ClassDescriptor) {
//context.export(descriptor) context.export(descriptor)
} }
override fun addFunction(descriptor: FunctionDescriptor, expression: JsExpression) { override fun addFunction(descriptor: FunctionDescriptor, expression: JsExpression) {
@@ -518,9 +518,9 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
@NotNull @NotNull
public JsNode visitObjectLiteralExpression(@NotNull KtObjectLiteralExpression expression, @NotNull TranslationContext context) { public JsNode visitObjectLiteralExpression(@NotNull KtObjectLiteralExpression expression, @NotNull TranslationContext context) {
ClassDescriptor descriptor = BindingUtils.getClassDescriptor(context.bindingContext(), expression.getObjectDeclaration()); ClassDescriptor descriptor = BindingUtils.getClassDescriptor(context.bindingContext(), expression.getObjectDeclaration());
translateClassOrObject(expression.getObjectDeclaration(), descriptor, context); translateClassOrObject(expression.getObjectDeclaration(), descriptor, context);
JsExpression constructor = context.getInnerReference(descriptor); JsExpression constructor = ReferenceTranslator.translateAsTypeReference(descriptor, context);
List<DeclarationDescriptor> closure = context.getClassOrConstructorClosure(descriptor); List<DeclarationDescriptor> closure = context.getClassOrConstructorClosure(descriptor);
List<JsExpression> closureArgs = new ArrayList<JsExpression>(); List<JsExpression> closureArgs = new ArrayList<JsExpression>();
if (closure != null) { if (closure != null) {
@@ -21,7 +21,6 @@ import com.google.dart.compiler.backend.js.ast.metadata.*
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.js.inline.util.getInnerFunction import org.jetbrains.kotlin.js.inline.util.getInnerFunction
import org.jetbrains.kotlin.js.inline.util.refreshLabelNames
import org.jetbrains.kotlin.js.translate.context.TranslationContext import org.jetbrains.kotlin.js.translate.context.TranslationContext
import org.jetbrains.kotlin.js.translate.context.getNameForCapturedDescriptor import org.jetbrains.kotlin.js.translate.context.getNameForCapturedDescriptor
import org.jetbrains.kotlin.js.translate.context.hasCapturedExceptContaining import org.jetbrains.kotlin.js.translate.context.hasCapturedExceptContaining
@@ -73,12 +72,14 @@ class LiteralFunctionTranslator(context: TranslationContext) : AbstractTranslato
if (!isRecursive) { if (!isRecursive) {
lambda.name = null lambda.name = null
} }
lambdaCreator.name.staticRef = lambdaCreator
return lambdaCreator.withCapturedParameters(functionContext, invokingContext) return lambdaCreator.withCapturedParameters(functionContext, invokingContext)
} }
lambda.isLocal = true lambda.isLocal = true
context().addDeclarationStatement(lambda.makeStmt()) context().addDeclarationStatement(lambda.makeStmt())
lambda.name.staticRef = lambda
return lambda.name.makeRef().apply { sideEffects = SideEffectKind.PURE } return lambda.name.makeRef().apply { sideEffects = SideEffectKind.PURE }
} }
@@ -92,10 +93,7 @@ class LiteralFunctionTranslator(context: TranslationContext) : AbstractTranslato
} }
} }
fun JsFunction.withCapturedParameters( fun JsFunction.withCapturedParameters(context: TranslationContext, invokingContext: TranslationContext): JsExpression {
context: TranslationContext,
invokingContext: TranslationContext
): JsExpression {
context.addDeclarationStatement(makeStmt()) context.addDeclarationStatement(makeStmt())
val ref = name.makeRef().apply { sideEffects = SideEffectKind.PURE } val ref = name.makeRef().apply { sideEffects = SideEffectKind.PURE }
val invocation = JsInvocation(ref).apply { sideEffects = SideEffectKind.PURE } val invocation = JsInvocation(ref).apply { sideEffects = SideEffectKind.PURE }
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.js.translate.context.TranslationContext;
import org.jetbrains.kotlin.js.translate.general.AbstractTranslator; import org.jetbrains.kotlin.js.translate.general.AbstractTranslator;
import org.jetbrains.kotlin.js.translate.general.Translation; import org.jetbrains.kotlin.js.translate.general.Translation;
import org.jetbrains.kotlin.js.translate.intrinsic.functions.factories.TopLevelFIF; import org.jetbrains.kotlin.js.translate.intrinsic.functions.factories.TopLevelFIF;
import org.jetbrains.kotlin.js.translate.reference.ReferenceTranslator;
import org.jetbrains.kotlin.js.translate.utils.BindingUtils; import org.jetbrains.kotlin.js.translate.utils.BindingUtils;
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils; import org.jetbrains.kotlin.js.translate.utils.TranslationUtils;
import org.jetbrains.kotlin.lexer.KtTokens; import org.jetbrains.kotlin.lexer.KtTokens;
@@ -169,7 +170,7 @@ public final class PatternTranslator extends AbstractTranslator {
ClassDescriptor referencedClass = DescriptorUtils.getClassDescriptorForType(type); ClassDescriptor referencedClass = DescriptorUtils.getClassDescriptorForType(type);
JsNameRef typeName = context().getInnerReference(referencedClass); JsExpression typeName = ReferenceTranslator.translateAsTypeReference(referencedClass, context());
return referencedClass.getKind() != ClassKind.OBJECT ? namer().isInstanceOf(typeName) : namer().isInstanceOfObject(typeName); return referencedClass.getKind() != ClassKind.OBJECT ? namer().isInstanceOf(typeName) : namer().isInstanceOfObject(typeName);
} }
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.js.translate.intrinsic.functions.basic
import com.google.dart.compiler.backend.js.ast.JsExpression import com.google.dart.compiler.backend.js.ast.JsExpression
import org.jetbrains.kotlin.js.translate.context.Namer import org.jetbrains.kotlin.js.translate.context.Namer
import org.jetbrains.kotlin.js.translate.context.TranslationContext import org.jetbrains.kotlin.js.translate.context.TranslationContext
import org.jetbrains.kotlin.js.translate.reference.ReferenceTranslator
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
@@ -43,7 +44,7 @@ class FqnCallIntrinsic(
JsAstUtils.replaceRootReference(context.getQualifiedReference(fqn), Namer.kotlinObject()) JsAstUtils.replaceRootReference(context.getQualifiedReference(fqn), Namer.kotlinObject())
} }
else { else {
context.getInnerReference(descriptors.first()) ReferenceTranslator.translateAsValueReference(descriptors.first(), context)
} }
} }
} }
@@ -63,7 +63,7 @@ object CallableReferenceTranslator {
isMember(descriptor) -> isMember(descriptor) ->
translateForMemberFunction(descriptor, context) translateForMemberFunction(descriptor, context)
else -> else ->
ReferenceTranslator.translateAsFQReference(descriptor, context) ReferenceTranslator.translateAsValueReference(descriptor, context)
} }
} }
@@ -108,14 +108,14 @@ object CallableReferenceTranslator {
} }
private fun translateForExtensionProperty(descriptor: PropertyDescriptor, context: TranslationContext): JsExpression { private fun translateForExtensionProperty(descriptor: PropertyDescriptor, context: TranslationContext): JsExpression {
val jsGetterNameRef = context.getInnerReference(descriptor.getter!!) val jsGetterNameRef = ReferenceTranslator.translateAsValueReference(descriptor.getter!!, context)
val propertyName = descriptor.name val propertyName = descriptor.name
val jsPropertyNameAsString = context.program().getStringLiteral(propertyName.asString()) val jsPropertyNameAsString = context.program().getStringLiteral(propertyName.asString())
val argumentList = ArrayList<JsExpression>(3) val argumentList = ArrayList<JsExpression>(3)
argumentList.add(jsPropertyNameAsString) argumentList.add(jsPropertyNameAsString)
argumentList.add(jsGetterNameRef) argumentList.add(jsGetterNameRef)
if (descriptor.isVar) { if (descriptor.isVar) {
val jsSetterNameRef = context.getInnerReference(descriptor.setter!!) val jsSetterNameRef = ReferenceTranslator.translateAsValueReference(descriptor.setter!!, context)
argumentList.add(jsSetterNameRef) argumentList.add(jsSetterNameRef)
} }
return if (AnnotationsUtils.isNativeObject(descriptor)) return if (AnnotationsUtils.isNativeObject(descriptor))
@@ -125,7 +125,7 @@ object CallableReferenceTranslator {
} }
private fun translateForConstructor(descriptor: FunctionDescriptor, context: TranslationContext): JsExpression { private fun translateForConstructor(descriptor: FunctionDescriptor, context: TranslationContext): JsExpression {
val jsFunctionRef = ReferenceTranslator.translateAsFQReference(descriptor, context) val jsFunctionRef = ReferenceTranslator.translateAsValueReference(descriptor, context)
return JsInvocation(context.namer().callableRefForConstructorReference(), jsFunctionRef) return JsInvocation(context.namer().callableRefForConstructorReference(), jsFunctionRef)
} }
@@ -133,7 +133,7 @@ object CallableReferenceTranslator {
val receiverParameterDescriptor = descriptor.extensionReceiverParameter ?: val receiverParameterDescriptor = descriptor.extensionReceiverParameter ?:
error("receiverParameter for extension should not be null") error("receiverParameter for extension should not be null")
val jsFunctionRef = ReferenceTranslator.translateAsFQReference(descriptor, context) val jsFunctionRef = ReferenceTranslator.translateAsValueReference(descriptor, context)
if (descriptor.visibility == Visibilities.LOCAL) { if (descriptor.visibility == Visibilities.LOCAL) {
return JsInvocation(context.namer().callableRefForLocalExtensionFunctionReference(), jsFunctionRef) return JsInvocation(context.namer().callableRefForLocalExtensionFunctionReference(), jsFunctionRef)
} }
@@ -159,12 +159,7 @@ object CallableReferenceTranslator {
classDescriptor: ClassDescriptor, classDescriptor: ClassDescriptor,
context: TranslationContext context: TranslationContext
): JsExpression { ): JsExpression {
val jsClassNameRef = if (AnnotationsUtils.isNativeObject(classDescriptor)) { val jsClassNameRef = ReferenceTranslator.translateAsTypeReference(classDescriptor, context)
context.getQualifiedReference(classDescriptor)
}
else {
context.getInnerReference(classDescriptor)
}
val funName = context.getNameForDescriptor(descriptor) val funName = context.getNameForDescriptor(descriptor)
val funNameAsString = context.program().getStringLiteral(funName.toString()) val funNameAsString = context.program().getStringLiteral(funName.toString())
return JsInvocation(context.namer().callableRefForMemberFunctionReference(), jsClassNameRef, funNameAsString) return JsInvocation(context.namer().callableRefForMemberFunctionReference(), jsClassNameRef, funNameAsString)
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.js.translate.general.AbstractTranslator;
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils; import org.jetbrains.kotlin.js.translate.utils.JsAstUtils;
import org.jetbrains.kotlin.psi.KtSimpleNameExpression; import org.jetbrains.kotlin.psi.KtSimpleNameExpression;
import static org.jetbrains.kotlin.js.translate.reference.ReferenceTranslator.translateAsLocalNameReference; import static org.jetbrains.kotlin.js.translate.reference.ReferenceTranslator.translateAsValueReference;
import static org.jetbrains.kotlin.js.translate.utils.BindingUtils.getDescriptorForReferenceExpression; import static org.jetbrains.kotlin.js.translate.utils.BindingUtils.getDescriptorForReferenceExpression;
public final class ReferenceAccessTranslator extends AbstractTranslator implements AccessTranslator { public final class ReferenceAccessTranslator extends AbstractTranslator implements AccessTranslator {
@@ -42,7 +42,7 @@ public final class ReferenceAccessTranslator extends AbstractTranslator implemen
private ReferenceAccessTranslator(@NotNull DeclarationDescriptor descriptor, @NotNull TranslationContext context) { private ReferenceAccessTranslator(@NotNull DeclarationDescriptor descriptor, @NotNull TranslationContext context) {
super(context); super(context);
this.reference = translateAsLocalNameReference(descriptor, context()); this.reference = translateAsValueReference(descriptor, context());
} }
@Override @Override
@@ -18,6 +18,11 @@ package org.jetbrains.kotlin.js.translate.reference;
import com.google.dart.compiler.backend.js.ast.JsExpression; import com.google.dart.compiler.backend.js.ast.JsExpression;
import com.google.dart.compiler.backend.js.ast.JsInvocation; import com.google.dart.compiler.backend.js.ast.JsInvocation;
import com.google.dart.compiler.backend.js.ast.JsName;
import com.google.dart.compiler.backend.js.ast.JsNameRef;
import com.google.dart.compiler.backend.js.ast.metadata.HasMetadata;
import com.google.dart.compiler.backend.js.ast.metadata.MetadataProperties;
import com.google.dart.compiler.backend.js.ast.metadata.SideEffectKind;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.js.translate.context.TranslationContext; import org.jetbrains.kotlin.js.translate.context.TranslationContext;
@@ -43,52 +48,85 @@ public final class ReferenceTranslator {
} }
@NotNull @NotNull
public static JsExpression translateAsFQReference(@NotNull DeclarationDescriptor referencedDescriptor, public static JsExpression translateAsValueReference(@NotNull DeclarationDescriptor descriptor, @NotNull TranslationContext context) {
@NotNull TranslationContext context) { JsExpression alias = context.getAliasForDescriptor(descriptor);
JsExpression alias = context.getAliasForDescriptor(referencedDescriptor);
if (alias != null) return alias; if (alias != null) return alias;
if (isLocalVarOrFunction(referencedDescriptor) || if (shouldTranslateAsFQN(descriptor, context)) {
AnnotationsUtils.isNativeObject(referencedDescriptor) || return context.getQualifiedReference(descriptor);
AnnotationsUtils.isLibraryObject(referencedDescriptor)
) {
return context.getQualifiedReference(referencedDescriptor);
} }
return context.getInnerReference(referencedDescriptor); if (descriptor instanceof PropertyDescriptor) {
} PropertyDescriptor property = (PropertyDescriptor) descriptor;
if (context.isFromCurrentModule(property)) {
private static boolean isLocalVarOrFunction(DeclarationDescriptor descriptor) { return context.getInnerReference(property);
return descriptor.getContainingDeclaration() instanceof FunctionDescriptor && !(descriptor instanceof ClassDescriptor); }
} else {
JsExpression qualifier = context.getInnerReference(property.getContainingDeclaration());
@NotNull JsName name = context.getNameForDescriptor(property);
public static JsExpression translateAsLocalNameReference(@NotNull DeclarationDescriptor descriptor, return new JsNameRef(name, qualifier);
@NotNull TranslationContext context) {
if (descriptor instanceof FunctionDescriptor || descriptor instanceof VariableDescriptor) {
JsExpression alias = context.getAliasForDescriptor(descriptor);
if (alias != null) {
return alias;
} }
} }
if (DescriptorUtils.isObject(descriptor) || DescriptorUtils.isEnumEntry(descriptor)) { if (DescriptorUtils.isObject(descriptor) || DescriptorUtils.isEnumEntry(descriptor)) {
if (AnnotationsUtils.isNativeObject(descriptor)) { if (AnnotationsUtils.isNativeObject(descriptor)) {
return context.getQualifiedReference(descriptor); return context.getQualifiedReference(descriptor);
} }
else if (!context.isFromCurrentModule(descriptor)) { else if (!context.isFromCurrentModule(descriptor)) {
DeclarationDescriptor container = descriptor.getContainingDeclaration(); return getLazyReferenceToObject((ClassDescriptor) descriptor, context);
assert container != null : "Object must have containing declaration: " + descriptor;
JsExpression qualifier = context.getInnerReference(container);
return JsAstUtils.pureFqn(context.getNameForDescriptor(descriptor), qualifier);
} }
else { else {
JsExpression functionRef = JsAstUtils.pureFqn(context.getNameForObjectInstance((ClassDescriptor) descriptor), null); JsExpression functionRef = JsAstUtils.pureFqn(context.getNameForObjectInstance((ClassDescriptor) descriptor), null);
return new JsInvocation(functionRef); return new JsInvocation(functionRef);
} }
} }
return context.getInnerReference(descriptor); return context.getInnerReference(descriptor);
} }
@NotNull
public static JsExpression translateAsTypeReference(@NotNull ClassDescriptor descriptor, @NotNull TranslationContext context) {
if (AnnotationsUtils.isNativeObject(descriptor)) {
return context.getQualifiedReference(descriptor);
}
if (!shouldTranslateAsFQN(descriptor, context)) {
if (DescriptorUtils.isObject(descriptor) || DescriptorUtils.isEnumEntry(descriptor)) {
if (!context.isFromCurrentModule(descriptor)) {
return getLazyReferenceToObject(descriptor, context);
}
}
return context.getInnerReference(descriptor);
}
JsExpression reference = context.getQualifiedReference(descriptor);
if (DescriptorUtils.isObject(descriptor) || DescriptorUtils.isEnumEntry(descriptor)) {
JsNameRef getPrototypeRef = JsAstUtils.pureFqn("getPrototypeOf", JsAstUtils.pureFqn("Object", null));
JsInvocation getPrototypeInvocation = new JsInvocation(getPrototypeRef, reference);
MetadataProperties.setSideEffects(getPrototypeInvocation, SideEffectKind.PURE);
reference = JsAstUtils.pureFqn("constructor", getPrototypeInvocation);
}
return reference;
}
@NotNull
private static JsExpression getLazyReferenceToObject(@NotNull ClassDescriptor descriptor, @NotNull TranslationContext context) {
DeclarationDescriptor container = descriptor.getContainingDeclaration();
JsExpression qualifier = context.getInnerReference(container);
return JsAstUtils.pureFqn(context.getNameForDescriptor(descriptor), qualifier);
}
private static boolean shouldTranslateAsFQN(@NotNull DeclarationDescriptor descriptor, @NotNull TranslationContext context) {
return isLocalVarOrFunction(descriptor) ||
AnnotationsUtils.isNativeObject(descriptor) ||
AnnotationsUtils.isLibraryObject(descriptor) ||
context.isPublicInlineFunction();
}
private static boolean isLocalVarOrFunction(DeclarationDescriptor descriptor) {
return descriptor.getContainingDeclaration() instanceof FunctionDescriptor && !(descriptor instanceof ClassDescriptor);
}
@NotNull @NotNull
public static AccessTranslator getAccessTranslator(@NotNull KtSimpleNameExpression referenceExpression, public static AccessTranslator getAccessTranslator(@NotNull KtSimpleNameExpression referenceExpression,
@NotNull TranslationContext context) { @NotNull TranslationContext context) {
@@ -58,7 +58,7 @@ public final class JSTestGenerator {
private static void generateCodeForTestMethod(@NotNull TranslationContext context, private static void generateCodeForTestMethod(@NotNull TranslationContext context,
@NotNull FunctionDescriptor functionDescriptor, @NotNull FunctionDescriptor functionDescriptor,
@NotNull ClassDescriptor classDescriptor, @NotNull JSTester tester) { @NotNull ClassDescriptor classDescriptor, @NotNull JSTester tester) {
JsExpression expression = ReferenceTranslator.translateAsFQReference(classDescriptor, context); JsExpression expression = ReferenceTranslator.translateAsValueReference(classDescriptor, context);
JsNew testClass = new JsNew(expression); JsNew testClass = new JsNew(expression);
JsExpression functionToTestCall = CallTranslator.INSTANCE.buildCall(context, functionDescriptor, JsExpression functionToTestCall = CallTranslator.INSTANCE.buildCall(context, functionDescriptor,
Collections.<JsExpression>emptyList(), testClass); Collections.<JsExpression>emptyList(), testClass);
@@ -52,13 +52,13 @@ fun setInlineCallMetadata(
"Expected descriptor of callable, that should be inlined, but got: $descriptor" "Expected descriptor of callable, that should be inlined, but got: $descriptor"
} }
val name = context.aliasedName(descriptor) val candidateNames = setOf(context.aliasedName(descriptor), context.getInnerNameForDescriptor(descriptor))
val visitor = object : RecursiveJsVisitor() { val visitor = object : RecursiveJsVisitor() {
override fun visitInvocation(invocation: JsInvocation) { override fun visitInvocation(invocation: JsInvocation) {
super.visitInvocation(invocation) super.visitInvocation(invocation)
if (name == invocation.name) { if (invocation.name in candidateNames) {
invocation.descriptor = descriptor invocation.descriptor = descriptor
invocation.inlineStrategy = InlineStrategy.IN_PLACE invocation.inlineStrategy = InlineStrategy.IN_PLACE
invocation.psiElement = psiElement invocation.psiElement = psiElement
@@ -21,6 +21,7 @@ import com.intellij.util.SmartList
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.js.translate.context.Namer import org.jetbrains.kotlin.js.translate.context.Namer
import org.jetbrains.kotlin.js.translate.context.TranslationContext import org.jetbrains.kotlin.js.translate.context.TranslationContext
import org.jetbrains.kotlin.js.translate.reference.ReferenceTranslator
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils.simpleReturnFunction import org.jetbrains.kotlin.js.translate.utils.TranslationUtils.simpleReturnFunction
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
@@ -78,27 +79,21 @@ fun <T, S> List<T>.splitToRanges(classifier: (T) -> S): List<Pair<List<T>, S>> {
return result return result
} }
fun getReferenceToJsClass(type: KotlinType, context: TranslationContext): JsNameRef { fun getReferenceToJsClass(type: KotlinType, context: TranslationContext): JsExpression {
val referenceToJsClass: JsNameRef
val classifierDescriptor = type.constructor.declarationDescriptor val classifierDescriptor = type.constructor.declarationDescriptor
if (classifierDescriptor is ClassDescriptor) { val referenceToJsClass: JsExpression = when (classifierDescriptor) {
val reference = context.getInnerReference(classifierDescriptor) is ClassDescriptor -> {
if (classifierDescriptor.kind == ClassKind.OBJECT) { ReferenceTranslator.translateAsTypeReference(classifierDescriptor, context)
referenceToJsClass = JsAstUtils.pureFqn("constructor", JsInvocation(JsNameRef("getPrototypeOf", JsNameRef("Object")), reference))
} }
else { is TypeParameterDescriptor -> {
referenceToJsClass = reference assert(classifierDescriptor.isReified)
}
}
else if (classifierDescriptor is TypeParameterDescriptor) {
assert(classifierDescriptor.isReified)
referenceToJsClass = context.getNameForDescriptor(classifierDescriptor).makeRef() context.getNameForDescriptor(classifierDescriptor).makeRef()
} }
else { else -> {
throw IllegalStateException("Can't get reference for $type") throw IllegalStateException("Can't get reference for $type")
}
} }
return referenceToJsClass return referenceToJsClass
@@ -5,13 +5,13 @@ package foo
@native @native
const val ROOT = "Kotlin.modules.JS_TESTS" const val ROOT = "Kotlin.modules.JS_TESTS"
@native @native
const val PATH_TO_F_CREATOR = "foo.B.far\$f" const val PATH_TO_F_CREATOR = "B\$far\$lambda"
@native @native
const val PATH_TO_G_CREATOR = "foo.B.gar\$f" const val PATH_TO_G_CREATOR = "B\$gar\$lambda"
@native("$ROOT.$PATH_TO_F_CREATOR") @native("$PATH_TO_F_CREATOR")
val F_CREATOR: Any = noImpl val F_CREATOR: Any = noImpl
@native("$ROOT.$PATH_TO_G_CREATOR") @native("$PATH_TO_G_CREATOR")
val G_CREATOR: Any = noImpl val G_CREATOR: Any = noImpl
@@ -38,7 +38,7 @@ fun box(): String {
assertEquals("B::boo", g()) assertEquals("B::boo", g())
val fs = F_CREATOR.toString() val fs = F_CREATOR.toString()
val gs = G_CREATOR.toString().replaceAll("boo", "foo") val gs = G_CREATOR.toString().replaceAll("boo", "foo").replaceAll("gar", "far")
assertEquals(gs, fs) assertEquals(gs, fs)
+2 -2
View File
@@ -1,7 +1,7 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: multiplyInline_0 // CHECK_CONTAINS_NO_CALLS: multiplyInline
// CHECK_NOT_CALLED: runNoinline_0 // CHECK_NOT_CALLED: runNoinline
internal inline fun multiply(a: Int, b: Int) = a * b internal inline fun multiply(a: Int, b: Int) = a * b
@@ -1,6 +1,6 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: test_0 // CHECK_CONTAINS_NO_CALLS: test
// A copy of stdlib run function. // A copy of stdlib run function.
// Copied to not to depend on run implementation. // Copied to not to depend on run implementation.
@@ -1,6 +1,6 @@
package foo package foo
// CHECK_NOT_CALLED_IN_SCOPE: scope=multiply_0 function=multiply_0$f // CHECK_NOT_CALLED_IN_SCOPE: scope=multiply function=multiply$lambda
internal class A(val a: Int) internal class A(val a: Int)
+1 -1
View File
@@ -1,6 +1,6 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: squareMultipliedByTwo_0 // CHECK_CONTAINS_NO_CALLS: squareMultipliedByTwo
internal inline fun inline1(a: Int): Int { internal inline fun inline1(a: Int): Int {
return a return a
@@ -1,6 +1,6 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: squareMultipliedByTwo_0 // CHECK_CONTAINS_NO_CALLS: squareMultipliedByTwo
internal inline fun inline1(a: Int): Int { internal inline fun inline1(a: Int): Int {
return a return a
@@ -1,7 +1,7 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: identity_0 // CHECK_CONTAINS_NO_CALLS: identity
// CHECK_CONTAINS_NO_CALLS: sumNoInline_0 // CHECK_CONTAINS_NO_CALLS: sumNoInline
internal inline fun sum(a: Int, b: Int = 0): Int { internal inline fun sum(a: Int, b: Int = 0): Int {
return a + b return a + b
@@ -1,6 +1,6 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: doNothingNoInline_0 // CHECK_CONTAINS_NO_CALLS: doNothingNoInline
internal inline fun <T> doNothing1(a: T): T { internal inline fun <T> doNothing1(a: T): T {
return a return a
@@ -1,7 +1,7 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: doNothingInt_0 // CHECK_CONTAINS_NO_CALLS: doNothingInt
// CHECK_CONTAINS_NO_CALLS: doNothingStr_0 // CHECK_CONTAINS_NO_CALLS: doNothingStr
internal inline fun <T> doNothing(a: T): T { internal inline fun <T> doNothing(a: T): T {
return a return a
+1 -1
View File
@@ -1,6 +1,6 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: multiplyNoInline_0 // CHECK_CONTAINS_NO_CALLS: multiplyNoInline
internal inline fun multiply(a: Int, b: Int): Int { internal inline fun multiply(a: Int, b: Int): Int {
return a * b return a * b
+3 -3
View File
@@ -1,8 +1,8 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: doNothing1_0 // CHECK_CONTAINS_NO_CALLS: doNothing1
// CHECK_CONTAINS_NO_CALLS: doNothing2_0 // CHECK_CONTAINS_NO_CALLS: doNothing2
// CHECK_CONTAINS_NO_CALLS: doNothing3_0 // CHECK_CONTAINS_NO_CALLS: doNothing3
internal class Inline { internal class Inline {
public inline fun <T> identity1 (x: T): T { public inline fun <T> identity1 (x: T): T {
@@ -1,6 +1,6 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: sumEven_0 // CHECK_CONTAINS_NO_CALLS: sumEven
internal inline fun filteredReduce(a: Array<Int>, predicate: (Int) -> Boolean, reduceFun: (Int, Int) -> Int): Int { internal inline fun filteredReduce(a: Array<Int>, predicate: (Int) -> Boolean, reduceFun: (Int, Int) -> Int): Int {
var result = 0 var result = 0
@@ -1,6 +1,6 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: maxBySquare_0 // CHECK_CONTAINS_NO_CALLS: maxBySquare
internal data class Result(var value: Int = 0, var invocationCount: Int = 0) internal data class Result(var value: Int = 0, var invocationCount: Int = 0)
+1 -1
View File
@@ -1,6 +1,6 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: add_0 // CHECK_CONTAINS_NO_CALLS: add
internal data class IntPair(public var fst: Int, public var snd: Int) { internal data class IntPair(public var fst: Int, public var snd: Int) {
inline public fun getFst(): Int { return fst } inline public fun getFst(): Int { return fst }
+1 -1
View File
@@ -1,6 +1,6 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: factAbsNoInline1_0 // CHECK_CONTAINS_NO_CALLS: factAbsNoInline1
internal class State(value: Int) { internal class State(value: Int) {
public var value: Int = value public var value: Int = value
+1 -1
View File
@@ -1,6 +1,6 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: test_0 // CHECK_CONTAINS_NO_CALLS: test
internal inline fun sum(x: Int, y: Int): Int = js("x + y") internal inline fun sum(x: Int, y: Int): Int = js("x + y")
+1 -1
View File
@@ -1,6 +1,6 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: test_0 // CHECK_CONTAINS_NO_CALLS: test
internal inline fun sum(x: Int, y: Int): Int = js("var a = x; a + y") internal inline fun sum(x: Int, y: Int): Int = js("var a = x; a + y")
+3 -3
View File
@@ -1,8 +1,8 @@
package foo package foo
// CHECK_CALLED_IN_SCOPE: scope=multiplyBy2_0 function=multiplyBy2_0$f // CHECK_CALLED_IN_SCOPE: scope=multiplyBy2 function=multiplyBy2$lambda
// CHECK_NOT_CALLED_IN_SCOPE: scope=multiplyBy2_0 function=multiplyBy2_0$f_0 // CHECK_NOT_CALLED_IN_SCOPE: scope=multiplyBy2 function=multiplyBy2$lambda_0
// CHECK_NOT_CALLED_IN_SCOPE: scope=multiplyBy2_0 function=run // CHECK_NOT_CALLED_IN_SCOPE: scope=multiplyBy2 function=run
internal inline fun <T> runLambdaInLambda(noinline inner: (T) -> T, outer: ((T) -> T, T) -> T, arg: T): T { internal inline fun <T> runLambdaInLambda(noinline inner: (T) -> T, outer: ((T) -> T, T) -> T, arg: T): T {
return outer(inner, arg) return outer(inner, arg)
@@ -1,7 +1,7 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: capturedInLambda_0 // CHECK_CONTAINS_NO_CALLS: capturedInLambda
// CHECK_CONTAINS_NO_CALLS: declaredInLambda_0 // CHECK_CONTAINS_NO_CALLS: declaredInLambda
internal data class State(var count: Int = 0) internal data class State(var count: Int = 0)
@@ -1,7 +1,7 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: localWithCapture_0 // CHECK_CONTAINS_NO_CALLS: localWithCapture
// CHECK_CONTAINS_NO_CALLS: localWithoutCapture_0 // CHECK_CONTAINS_NO_CALLS: localWithoutCapture
internal inline fun repeatAction(times: Int, action: () -> Unit) { internal inline fun repeatAction(times: Int, action: () -> Unit) {
for (i in 1..times) { for (i in 1..times) {
@@ -1,6 +1,6 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: add_0 // CHECK_CONTAINS_NO_CALLS: add
internal data class State(var count: Int = 0) internal data class State(var count: Int = 0)
@@ -1,7 +1,7 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: localWithCapture_0 // CHECK_CONTAINS_NO_CALLS: localWithCapture
// CHECK_CONTAINS_NO_CALLS: localWithoutCapture_0 // CHECK_CONTAINS_NO_CALLS: localWithoutCapture
internal inline fun repeatAction(times: Int, action: () -> Unit) { internal inline fun repeatAction(times: Int, action: () -> Unit) {
for (i in 1..times) { for (i in 1..times) {
@@ -1,6 +1,6 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: add_0 // CHECK_CONTAINS_NO_CALLS: add
internal inline fun run(action: () -> Int): Int { internal inline fun run(action: () -> Int): Int {
return action() return action()
@@ -1,11 +1,11 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: test1_0 // CHECK_CONTAINS_NO_CALLS: test1
// CHECK_CONTAINS_NO_CALLS: test2_0 // CHECK_CONTAINS_NO_CALLS: test2
// CHECK_CONTAINS_NO_CALLS: test3_0 // CHECK_CONTAINS_NO_CALLS: test3
// CHECK_CONTAINS_NO_CALLS: test4_buocd8$ // CHECK_CONTAINS_NO_CALLS: test4_buocd8$
// CHECK_CONTAINS_NO_CALLS: test5_0 // CHECK_CONTAINS_NO_CALLS: test5
// CHECK_HAS_INLINE_METADATA: apply_hiyix$ // CHECK_HAS_INLINE_METADATA: apply
// CHECK_HAS_INLINE_METADATA: applyL_hiyix$ // CHECK_HAS_INLINE_METADATA: applyL_hiyix$
// CHECK_HAS_INLINE_METADATA: applyM_hiyix$ // CHECK_HAS_INLINE_METADATA: applyM_hiyix$
// CHECK_HAS_NO_INLINE_METADATA: applyN_hiyix$ // CHECK_HAS_NO_INLINE_METADATA: applyN_hiyix$
+2 -2
View File
@@ -1,7 +1,7 @@
package foo package foo
// CHECK_CALLED_IN_SCOPE: scope=multiplyBy2_0 function=multiplyBy2_0$f // CHECK_CALLED_IN_SCOPE: scope=multiplyBy2 function=multiplyBy2$lambda
// CHECK_NOT_CALLED_IN_SCOPE: scope=multiplyBy2_0 function=run // CHECK_NOT_CALLED_IN_SCOPE: scope=multiplyBy2 function=run
internal inline fun <T> run(noinline func: (T) -> T, arg: T): T { internal inline fun <T> run(noinline func: (T) -> T, arg: T): T {
return func(arg) return func(arg)
+1 -1
View File
@@ -1,6 +1,6 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: sum_0 // CHECK_CONTAINS_NO_CALLS: sum
inline fun <T : Any, R> T.doLet(f: (T) -> R): R = f(this) inline fun <T : Any, R> T.doLet(f: (T) -> R): R = f(this)
+3 -3
View File
@@ -1,9 +1,9 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: test1_0 // CHECK_CONTAINS_NO_CALLS: test1
// CHECK_CONTAINS_NO_CALLS: test2_0 // CHECK_CONTAINS_NO_CALLS: test2
// CHECK_CONTAINS_NO_CALLS: test3_0 except=slice // CHECK_CONTAINS_NO_CALLS: test3 except=slice
internal inline fun concat(vararg strings: String): String { internal inline fun concat(vararg strings: String): String {
var result = "" var result = ""
+1 -1
View File
@@ -8,7 +8,7 @@ package foo
import test.* import test.*
// CHECK_CONTAINS_NO_CALLS: testClassObject_0 // CHECK_CONTAINS_NO_CALLS: testClassObject
internal fun testFinalInline(): String { internal fun testFinalInline(): String {
return Z().finalInline({"final"}) return Z().finalInline({"final"})
@@ -17,7 +17,7 @@ public fun log(s: String): String {
import utils.* import utils.*
// CHECK_CONTAINS_NO_CALLS: test_0 // CHECK_CONTAINS_NO_CALLS: test
internal fun test(s: String): String = log(s + ";") internal fun test(s: String): String = log(s + ";")
@@ -12,7 +12,7 @@ public fun <T, R> apply(x: T, fn: (T)->R): R =
import utils.* import utils.*
// CHECK_CONTAINS_NO_CALLS: test_0 // CHECK_CONTAINS_NO_CALLS: test
internal fun multiplyBy2(x: Int): Int = x * 2 internal fun multiplyBy2(x: Int): Int = x * 2
@@ -9,7 +9,7 @@ public fun sum(x: Int, y: Int): Int =
// MODULE: main(lib) // MODULE: main(lib)
// FILE: main.kt // FILE: main.kt
// CHECK_CONTAINS_NO_CALLS: test_0 // CHECK_CONTAINS_NO_CALLS: test
internal fun test(x: Int, y: Int): Int = utils.sum(x, y) internal fun test(x: Int, y: Int): Int = utils.sum(x, y)
@@ -13,7 +13,7 @@ public fun <T, R> apply(x: T, fn: T.()->R): R =
import utils.* import utils.*
// CHECK_CONTAINS_NO_CALLS: test_0 // CHECK_CONTAINS_NO_CALLS: test
internal class A(val n: Int) internal class A(val n: Int)
+1 -1
View File
@@ -13,7 +13,7 @@ public fun <T, R> apply(x: T, fn: (T)->R): R =
import utils.* import utils.*
// CHECK_CONTAINS_NO_CALLS: test_0 // CHECK_CONTAINS_NO_CALLS: test
internal fun test(x: Int): Int = apply(x) { it * 2 } internal fun test(x: Int): Int = apply(x) { it * 2 }
@@ -13,7 +13,7 @@ public fun <T, R> apply(x: T, fn: (T)->R): R =
import utils.* import utils.*
// CHECK_CONTAINS_NO_CALLS: test_0 // CHECK_CONTAINS_NO_CALLS: test
internal fun test(x: Int, y: Int): Int = apply(x) { it + y } internal fun test(x: Int, y: Int): Int = apply(x) { it + y }
@@ -15,7 +15,7 @@ public fun <T, R> apply(x: T, fn: (T)->R): R {
import utils.* import utils.*
// CHECK_CONTAINS_NO_CALLS: test_0 // CHECK_CONTAINS_NO_CALLS: test
internal fun test(x: Int, y: Int): Int = apply(x) { it + 1 } * y internal fun test(x: Int, y: Int): Int = apply(x) { it + 1 } * y
+1 -1
View File
@@ -14,7 +14,7 @@ public class A(public val x: Int) {
import utils.* import utils.*
// CHECK_CONTAINS_NO_CALLS: test_0 // CHECK_CONTAINS_NO_CALLS: test
internal fun test(a: A, y: Int): Int = a.plus(y) internal fun test(a: A, y: Int): Int = a.plus(y)
+1 -1
View File
@@ -13,7 +13,7 @@ public fun sum(x: Int, y: Int): Int =
import utils.* import utils.*
// CHECK_CONTAINS_NO_CALLS: test_0 // CHECK_CONTAINS_NO_CALLS: test
internal fun test(x: Int, y: Int): Int = sum(x, y) internal fun test(x: Int, y: Int): Int = sum(x, y)
@@ -1,8 +1,8 @@
package foo package foo
// CHECK_NOT_CALLED: f1_0 // CHECK_NOT_CALLED: f1
// CHECK_NOT_CALLED: f2_0 // CHECK_NOT_CALLED: f2
// CHECK_BREAKS_COUNT: function=test_0 count=3 // CHECK_BREAKS_COUNT: function=test count=3
internal var even = arrayListOf<Int>() internal var even = arrayListOf<Int>()
internal var odd = arrayListOf<Int>() internal var odd = arrayListOf<Int>()
@@ -1,6 +1,6 @@
package foo package foo
// CHECK_VARS_COUNT: function=test_za3lpa$ count=2 // CHECK_VARS_COUNT: function=test count=2
inline fun if1(f: (Int) -> Int, a: Int, b: Int, c: Int): Int { inline fun if1(f: (Int) -> Int, a: Int, b: Int, c: Int): Int {
val result = f(a) val result = f(a)
@@ -1,9 +1,9 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: test1_0 // CHECK_CONTAINS_NO_CALLS: test1
// CHECK_CONTAINS_NO_CALLS: test2_0 // CHECK_CONTAINS_NO_CALLS: test2
// CHECK_VARS_COUNT: function=test1_0 count=0 // CHECK_VARS_COUNT: function=test1 count=0
// CHECK_VARS_COUNT: function=test2_0 count=1 // CHECK_VARS_COUNT: function=test2 count=1
var log = "" var log = ""
@@ -1,7 +1,7 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: test_0 // CHECK_CONTAINS_NO_CALLS: test except=SumHolder_getInstance
// CHECK_VARS_COUNT: function=test_0 count=0 // CHECK_VARS_COUNT: function=test count=1
object SumHolder { object SumHolder {
var sum = 0 var sum = 0
@@ -1,7 +1,7 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: test_0 // CHECK_CONTAINS_NO_CALLS: test
// CHECK_VARS_COUNT: function=test_0 count=0 // CHECK_VARS_COUNT: function=test count=0
internal inline fun sign(x: Int): Int { internal inline fun sign(x: Int): Int {
if (x < 0) return -1 if (x < 0) return -1
@@ -1,7 +1,7 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: test_0 // CHECK_CONTAINS_NO_CALLS: test
// CHECK_VARS_COUNT: function=test_0 count=0 // CHECK_VARS_COUNT: function=test count=0
// A copy of stdlib run function. // A copy of stdlib run function.
// Copied to not to depend on run implementation. // Copied to not to depend on run implementation.
@@ -1,8 +1,8 @@
package foo package foo
// CHECK_VARS_COUNT: function=test1_za3lpa$ count=0 // CHECK_VARS_COUNT: function=test1 count=0
// CHECK_VARS_COUNT: function=test2_za3lpa$ count=1 // CHECK_VARS_COUNT: function=test2 count=1
// CHECK_VARS_COUNT: function=test3_za3lpa$ count=0 // CHECK_VARS_COUNT: function=test3 count=0
inline fun a(x: Int) = b(x) inline fun a(x: Int) = b(x)
+2 -2
View File
@@ -1,7 +1,7 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: test_0 // CHECK_CONTAINS_NO_CALLS: test
// CHECK_VARS_COUNT: function=test_0 count=0 // CHECK_VARS_COUNT: function=test count=0
internal class A(val x: Int) { internal class A(val x: Int) {
inline fun f(): Int = x inline fun f(): Int = x
@@ -1,7 +1,7 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: test_0 // CHECK_CONTAINS_NO_CALLS: test
// CHECK_VARS_COUNT: function=test_0 count=1 // CHECK_VARS_COUNT: function=test count=1
internal inline fun sum(x: Int, y: Int): Int { internal inline fun sum(x: Int, y: Int): Int {
if (x == 0 || y == 0) return 0 if (x == 0 || y == 0) return 0
@@ -1,7 +1,7 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: test_0 // CHECK_CONTAINS_NO_CALLS: test
// CHECK_VARS_COUNT: function=test_0 count=1 // CHECK_VARS_COUNT: function=test count=1
internal inline fun sum(x: Int, y: Int): Int { internal inline fun sum(x: Int, y: Int): Int {
if (x == 0 || y == 0) return 0 if (x == 0 || y == 0) return 0
@@ -1,7 +1,7 @@
package foo package foo
// CHECK_NOT_CALLED_IN_SCOPE: scope=test_0 function=even_0 // CHECK_NOT_CALLED_IN_SCOPE: scope=test function=even
// CHECK_NOT_CALLED_IN_SCOPE: scope=test_0 function=filter_azvtw4$ // CHECK_NOT_CALLED_IN_SCOPE: scope=test function=filter_azvtw4$
internal fun even(x: Int) = x % 2 == 0 internal fun even(x: Int) = x % 2 == 0
+1 -1
View File
@@ -1,6 +1,6 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: test_0 // CHECK_CONTAINS_NO_CALLS: test
internal fun test(a: Int, b: Int): Int { internal fun test(a: Int, b: Int): Int {
var c = 0 var c = 0
@@ -1,6 +1,6 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: test_0 // CHECK_CONTAINS_NO_CALLS: test
internal fun test(a: Int, b: Int): Int { internal fun test(a: Int, b: Int): Int {
var res = 0 var res = 0
@@ -1,6 +1,6 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: test_0 // CHECK_CONTAINS_NO_CALLS: test
internal fun test(x: Int, y: Int): Int = internal fun test(x: Int, y: Int): Int =
with (x + x) { with (x + x) {
+1 -1
View File
@@ -1,6 +1,6 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: test_0 // CHECK_CONTAINS_NO_CALLS: test
internal var counter = 0 internal var counter = 0
@@ -1,7 +1,7 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: testImplicitThis_0 // CHECK_CONTAINS_NO_CALLS: testImplicitThis
// CHECK_CONTAINS_NO_CALLS: testExplicitThis_0 // CHECK_CONTAINS_NO_CALLS: testExplicitThis
internal class A(var value: Int) internal class A(var value: Int)
@@ -1,9 +1,9 @@
package foo package foo
// CHECK_CONTAINS_NO_CALLS: test_0 // CHECK_CONTAINS_NO_CALLS: test
// CHECK_LABELS_COUNT: function=test_0 name=loop count=1 // CHECK_LABELS_COUNT: function=test name=loop count=1
// CHECK_LABELS_COUNT: function=test_0 name=loop_0 count=1 // CHECK_LABELS_COUNT: function=test name=loop_0 count=1
// CHECK_LABELS_COUNT: function=test_0 name=loop_1 count=1 // CHECK_LABELS_COUNT: function=test name=loop_1 count=1
class State() { class State() {
public var value: Int = 0 public var value: Int = 0
@@ -1,8 +1,8 @@
package foo package foo
// CHECK_LABELS_COUNT: function=test_0 name=loop count=1 // CHECK_LABELS_COUNT: function=test name=loop count=1
// CHECK_LABELS_COUNT: function=test_0 name=loop_0 count=1 // CHECK_LABELS_COUNT: function=test name=loop_0 count=1
// CHECK_LABELS_COUNT: function=test_0 name=loop_1 count=1 // CHECK_LABELS_COUNT: function=test name=loop_1 count=1
class State() { class State() {
public var value: Int = 0 public var value: Int = 0
-45
View File
@@ -1,45 +0,0 @@
NOTE THIS FILE IS AUTO-GENERATED by the generateTestDataForReservedWords.kt. DO NOT EDIT!
dataClass / param
dataClass / val
dataClass / var
delegated / fun
delegated / funParam
delegated / label
delegated / val
delegated / var
enum / entry
enum / fun
enum / funParam
enum / label
enum / val
enum / var
insideClass / fun
insideClass / funParam
insideClass / label
insideClass / val
insideClass / var
insideClassObject / fun
insideClassObject / funParam
insideClassObject / label
insideClassObject / val
insideClassObject / var
insideObject / fun
insideObject / funParam
insideObject / label
insideObject / val
insideObject / var
local / catch
local / fun
local / funParam
local / label
local / val
local / var
toplevel / class
toplevel / enum
toplevel / fun
toplevel / funParam
toplevel / interface
toplevel / label
toplevel / object
toplevel / val
toplevel / var
@@ -1,22 +0,0 @@
NOTE THIS FILE IS AUTO-GENERATED by the generateTestDataForReservedWords.kt. DO NOT EDIT!
break
class
continue
do
else
false
for
if
in
interface
null
package
return
super
this
throw
true
try
typeof
var
while
@@ -1,32 +0,0 @@
NOTE THIS FILE IS AUTO-GENERATED by the generateTestDataForReservedWords.kt. DO NOT EDIT!
Infinity
Kotlin
NaN
arguments
await
case
catch
const
debugger
default
delete
enum
eval
export
extends
finally
function
implements
import
instanceof
let
new
private
protected
public
static
switch
undefined
void
with
yield
-24
View File
@@ -1,24 +0,0 @@
package foo
import kotlin.text.Regex
fun testRenamed(case: String, f: () -> Unit) = test(case, true, f)
fun testNotRenamed(case: String, f: () -> Unit) = test(case, false, f)
fun test(keyword: String, expectedRenamed: Boolean, f: Any) {
val fs = f.toString().replace("while (false)", "")
val matches = Regex("[\\w$]*$keyword[\\w_$]*").matchAll(fs).map { it.value }.toList()
assertNotEquals(0, matches.size, "matches is empty for fs = $fs")
val actual = matches.last()
assertTrue(actual.contains(keyword), "'$keyword' not found in '$matches' from '$fs'")
if (expectedRenamed) {
assertNotEquals(keyword, actual, "fs = $fs")
}
else {
assertEquals(keyword, actual, "fs = $fs")
}
}
@@ -1,15 +0,0 @@
package foo
// NOTE THIS FILE IS AUTO-GENERATED by the generateTestDataForReservedWords.kt. DO NOT EDIT!
data class DataClass(val `typeof`: String) {
init {
testNotRenamed("typeof", { `typeof` })
}
}
fun box(): String {
DataClass("123")
return "OK"
}
@@ -1,15 +0,0 @@
package foo
// NOTE THIS FILE IS AUTO-GENERATED by the generateTestDataForReservedWords.kt. DO NOT EDIT!
data class DataClass(val `var`: String) {
init {
testNotRenamed("var", { `var` })
}
}
fun box(): String {
DataClass("123")
return "OK"
}
@@ -1,15 +0,0 @@
package foo
// NOTE THIS FILE IS AUTO-GENERATED by the generateTestDataForReservedWords.kt. DO NOT EDIT!
data class DataClass(val with: String) {
init {
testNotRenamed("with", { with })
}
}
fun box(): String {
DataClass("123")
return "OK"
}
@@ -1,15 +0,0 @@
package foo
// NOTE THIS FILE IS AUTO-GENERATED by the generateTestDataForReservedWords.kt. DO NOT EDIT!
data class DataClass(val yield: String) {
init {
testNotRenamed("yield", { yield })
}
}
fun box(): String {
DataClass("123")
return "OK"
}
@@ -1,15 +0,0 @@
package foo
// NOTE THIS FILE IS AUTO-GENERATED by the generateTestDataForReservedWords.kt. DO NOT EDIT!
data class DataClass(var `break`: String) {
init {
testNotRenamed("break", { `break` })
}
}
fun box(): String {
DataClass("123")
return "OK"
}
@@ -1,15 +0,0 @@
package foo
// NOTE THIS FILE IS AUTO-GENERATED by the generateTestDataForReservedWords.kt. DO NOT EDIT!
data class DataClass(var Infinity: String) {
init {
testNotRenamed("Infinity", { Infinity })
}
}
fun box(): String {
DataClass("123")
return "OK"
}
@@ -1,15 +0,0 @@
package foo
// NOTE THIS FILE IS AUTO-GENERATED by the generateTestDataForReservedWords.kt. DO NOT EDIT!
data class DataClass(var Kotlin: String) {
init {
testNotRenamed("Kotlin", { Kotlin })
}
}
fun box(): String {
DataClass("123")
return "OK"
}
@@ -1,15 +0,0 @@
package foo
// NOTE THIS FILE IS AUTO-GENERATED by the generateTestDataForReservedWords.kt. DO NOT EDIT!
data class DataClass(var `while`: String) {
init {
testNotRenamed("while", { `while` })
}
}
fun box(): String {
DataClass("123")
return "OK"
}
@@ -1,23 +0,0 @@
package foo
// NOTE THIS FILE IS AUTO-GENERATED by the generateTestDataForReservedWords.kt. DO NOT EDIT!
interface Trait {
fun debugger()
}
class TraitImpl : Trait {
override fun debugger() { debugger() }
}
class TestDelegate : Trait by TraitImpl() {
fun test() {
testNotRenamed("debugger", { debugger() })
}
}
fun box(): String {
TestDelegate().test()
return "OK"
}
@@ -1,23 +0,0 @@
package foo
// NOTE THIS FILE IS AUTO-GENERATED by the generateTestDataForReservedWords.kt. DO NOT EDIT!
interface Trait {
fun default()
}
class TraitImpl : Trait {
override fun default() { default() }
}
class TestDelegate : Trait by TraitImpl() {
fun test() {
testNotRenamed("default", { default() })
}
}
fun box(): String {
TestDelegate().test()
return "OK"
}
@@ -1,23 +0,0 @@
package foo
// NOTE THIS FILE IS AUTO-GENERATED by the generateTestDataForReservedWords.kt. DO NOT EDIT!
interface Trait {
fun `if`()
}
class TraitImpl : Trait {
override fun `if`() { `if`() }
}
class TestDelegate : Trait by TraitImpl() {
fun test() {
testNotRenamed("if", { `if`() })
}
}
fun box(): String {
TestDelegate().test()
return "OK"
}
@@ -1,23 +0,0 @@
package foo
// NOTE THIS FILE IS AUTO-GENERATED by the generateTestDataForReservedWords.kt. DO NOT EDIT!
interface Trait {
fun `in`()
}
class TraitImpl : Trait {
override fun `in`() { `in`() }
}
class TestDelegate : Trait by TraitImpl() {
fun test() {
testNotRenamed("in", { `in`() })
}
}
fun box(): String {
TestDelegate().test()
return "OK"
}
@@ -1,26 +0,0 @@
package foo
// NOTE THIS FILE IS AUTO-GENERATED by the generateTestDataForReservedWords.kt. DO NOT EDIT!
interface Trait {
fun foo(delete: String)
}
class TraitImpl : Trait {
override fun foo(delete: String) {
assertEquals("123", delete)
testRenamed("delete", { delete })
}
}
class TestDelegate : Trait by TraitImpl() {
fun test() {
foo("123")
}
}
fun box(): String {
TestDelegate().test()
return "OK"
}
@@ -1,26 +0,0 @@
package foo
// NOTE THIS FILE IS AUTO-GENERATED by the generateTestDataForReservedWords.kt. DO NOT EDIT!
interface Trait {
fun foo(enum: String)
}
class TraitImpl : Trait {
override fun foo(enum: String) {
assertEquals("123", enum)
testRenamed("enum", { enum })
}
}
class TestDelegate : Trait by TraitImpl() {
fun test() {
foo("123")
}
}
fun box(): String {
TestDelegate().test()
return "OK"
}
@@ -1,26 +0,0 @@
package foo
// NOTE THIS FILE IS AUTO-GENERATED by the generateTestDataForReservedWords.kt. DO NOT EDIT!
interface Trait {
fun foo(`interface`: String)
}
class TraitImpl : Trait {
override fun foo(`interface`: String) {
assertEquals("123", `interface`)
testRenamed("interface", { `interface` })
}
}
class TestDelegate : Trait by TraitImpl() {
fun test() {
foo("123")
}
}
fun box(): String {
TestDelegate().test()
return "OK"
}

Some files were not shown because too many files have changed in this diff Show More