JS: fix inlining in a new flat JS generator
This commit is contained in:
@@ -1173,7 +1173,7 @@ fun main(args: Array<String>) {
|
||||
}
|
||||
}
|
||||
|
||||
generateTestDataForReservedWords()
|
||||
//generateTestDataForReservedWords()
|
||||
|
||||
testGroup("js/js.tests/test", "js/js.translator/testData") {
|
||||
testClass<AbstractBoxJsTest>() {
|
||||
|
||||
@@ -64,7 +64,7 @@ public class JsInliner extends JsVisitorWithContextImpl {
|
||||
|
||||
public static JsProgram process(@NotNull TranslationContext context) {
|
||||
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());
|
||||
inliner.accept(program);
|
||||
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.PropertyCollector
|
||||
import org.jetbrains.kotlin.js.translate.expression.*
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
|
||||
import java.util.*
|
||||
|
||||
fun collectFunctionReferencesInside(scope: JsNode): List<JsName> =
|
||||
@@ -133,19 +134,54 @@ fun collectJsProperties(scope: JsNode): IdentityHashMap<JsName, JsExpression> {
|
||||
return collector.properties
|
||||
}
|
||||
|
||||
fun collectNamedFunctions(scope: JsNode): IdentityHashMap<JsName, JsFunction> {
|
||||
val namedFunctions = IdentityHashMap<JsName, JsFunction>()
|
||||
fun collectNamedFunctions(scope: JsNode) = collectNamedFunctionsAndMetadata(scope).mapValues { it.value.first }
|
||||
|
||||
for ((name, value) in collectJsProperties(scope)) {
|
||||
val function: JsFunction? = when (value) {
|
||||
is JsFunction -> value
|
||||
else -> InlineMetadata.decompose(value)?.function
|
||||
fun collectNamedFunctionsOrMetadata(scope: JsNode) = collectNamedFunctionsAndMetadata(scope).mapValues { it.value.second }
|
||||
|
||||
fun collectNamedFunctionsAndMetadata(scope: JsNode): Map<JsName, Pair<JsFunction, JsExpression>> {
|
||||
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) {
|
||||
namedFunctions[name] = function
|
||||
override fun visit(x: JsVars.JsVar) {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.js.inline.util.collectors
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.*
|
||||
import org.jetbrains.kotlin.js.translate.expression.InlineMetadata
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
|
||||
|
||||
import java.util.IdentityHashMap
|
||||
|
||||
|
||||
@@ -16,9 +16,19 @@
|
||||
|
||||
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) {}
|
||||
|
||||
|
||||
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 org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.js.inline.util.CollectUtilsKt;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@@ -43,6 +44,13 @@ public class AstSearchUtil {
|
||||
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
|
||||
private static <T extends JsExpression> T findByIdent(@NotNull Map<JsName, T> properties, @NotNull String name) {
|
||||
for (Map.Entry<JsName, T> entry : properties.entrySet()) {
|
||||
|
||||
@@ -94,7 +94,7 @@ public class DirectiveTestUtils {
|
||||
@NotNull
|
||||
String getFunctionCode(@NotNull JsNode ast, @NotNull String functionName) {
|
||||
JsFunction function = AstSearchUtil.getFunction(ast, functionName);
|
||||
return function.toString();
|
||||
return function.getBody().toString();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -213,7 +213,7 @@ public class DirectiveTestUtils {
|
||||
@Override
|
||||
void processEntry(@NotNull JsNode ast, @NotNull ArgumentsHelper arguments) throws Exception {
|
||||
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;
|
||||
assertNotNull(message, InlineMetadata.decompose(property));
|
||||
}
|
||||
@@ -223,7 +223,7 @@ public class DirectiveTestUtils {
|
||||
@Override
|
||||
void processEntry(@NotNull JsNode ast, @NotNull ArgumentsHelper arguments) throws Exception {
|
||||
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;
|
||||
assertTrue(message, property instanceof JsFunction);
|
||||
}
|
||||
|
||||
+1
-1
@@ -49,7 +49,7 @@ fun CallInfo.isSuperInvocation(): Boolean {
|
||||
val CallInfo.calleeOwner: JsExpression
|
||||
get() {
|
||||
val calleeOwner = resolvedCall.resultingDescriptor.containingDeclaration
|
||||
return ReferenceTranslator.translateAsFQReference(calleeOwner, context)
|
||||
return ReferenceTranslator.translateAsValueReference(calleeOwner, context)
|
||||
}
|
||||
|
||||
val VariableAccessInfo.variableDescriptor: VariableDescriptor
|
||||
|
||||
+3
-3
@@ -81,7 +81,7 @@ object DefaultFunctionCallCase : FunctionCallCase() {
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ object DefaultFunctionCallCase : FunctionCallCase() {
|
||||
return JsInvocation(JsNameRef(functionName, extensionReceiver), argumentsInfo.translateArguments)
|
||||
}
|
||||
|
||||
val functionRef = ReferenceTranslator.translateAsFQReference(callableDescriptor, context)
|
||||
val functionRef = ReferenceTranslator.translateAsValueReference(callableDescriptor, context)
|
||||
|
||||
val referenceToCall =
|
||||
if (callableDescriptor.visibility == Visibilities.LOCAL) {
|
||||
@@ -212,7 +212,7 @@ object ConstructorCallCase : FunctionCallCase() {
|
||||
private inline fun FunctionCallInfo.doTranslate(
|
||||
getArguments: CallArgumentTranslator.ArgumentsInfo.() -> List<JsExpression>
|
||||
): JsExpression {
|
||||
val functionRef = ReferenceTranslator.translateAsFQReference(callableDescriptor, context)
|
||||
val functionRef = ReferenceTranslator.translateAsValueReference(callableDescriptor, context)
|
||||
val invocationArguments = mutableListOf<JsExpression>()
|
||||
|
||||
val constructorDescriptor = callableDescriptor as ClassConstructorDescriptor
|
||||
|
||||
+4
-12
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||
import org.jetbrains.kotlin.js.translate.context.Namer
|
||||
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.pureFqn
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils
|
||||
@@ -84,17 +85,7 @@ object DefaultVariableAccessCase : VariableAccessCase() {
|
||||
return JsInvocation(pureFqn(context.getNameForObjectInstance (descriptor.getReferencedObject()), null))
|
||||
}
|
||||
|
||||
val functionRef = context.aliasOrValue(callableDescriptor) {
|
||||
if (context.isFromCurrentModule(variableDescriptor)) {
|
||||
context.getInnerReference(variableDescriptor)
|
||||
}
|
||||
else {
|
||||
val qualifier = context.getInnerReference(variableDescriptor.containingDeclaration)
|
||||
val name = context.getNameForDescriptor(variableDescriptor)
|
||||
JsNameRef(name, qualifier)
|
||||
}
|
||||
}
|
||||
|
||||
val functionRef = ReferenceTranslator.translateAsValueReference(callableDescriptor, context)
|
||||
val ref = if (isVarCapturedInClosure(context.bindingContext(), callableDescriptor)) {
|
||||
getCapturedVarAccessor(functionRef)
|
||||
}
|
||||
@@ -170,7 +161,8 @@ object SuperPropertyAccessCase : VariableAccessCase() {
|
||||
|
||||
return if (descriptor is PropertyDescriptor && TranslationUtils.shouldAccessViaFunctions(descriptor)) {
|
||||
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 arguments = listOf(dispatchReceiver!!) + additionalArguments
|
||||
JsInvocation(funRef, *arguments.toTypedArray())
|
||||
|
||||
@@ -153,6 +153,9 @@ public final class StaticContext {
|
||||
@NotNull
|
||||
private final JsObjectLiteral exportObject = rootPackage.objectLiteral;
|
||||
|
||||
@NotNull
|
||||
private final Set<MemberDescriptor> exportedDeclarations = new HashSet<MemberDescriptor>();
|
||||
|
||||
//TODO: too many parameters in constructor
|
||||
private StaticContext(
|
||||
@NotNull JsProgram program,
|
||||
@@ -527,7 +530,9 @@ public final class StaticContext {
|
||||
return 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;
|
||||
}
|
||||
@@ -555,8 +560,7 @@ public final class StaticContext {
|
||||
Rule<JsScope> generateInnerScopesForMembers = new Rule<JsScope>() {
|
||||
@Override
|
||||
public JsScope apply(@NotNull DeclarationDescriptor descriptor) {
|
||||
JsScope enclosingScope = getEnclosingScope(descriptor);
|
||||
return enclosingScope.innerObjectScope("Scope for member " + descriptor.getName());
|
||||
return rootFunction.getScope().innerObjectScope("Scope for member " + descriptor.getName());
|
||||
}
|
||||
};
|
||||
Rule<JsScope> createFunctionObjectsForCallableDescriptors = new Rule<JsScope>() {
|
||||
@@ -659,27 +663,40 @@ public final class StaticContext {
|
||||
classes.add(classDescriptor);
|
||||
}
|
||||
|
||||
public void export(@NotNull DeclarationDescriptor descriptor) {
|
||||
DeclarationDescriptor container = descriptor.getContainingDeclaration();
|
||||
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");
|
||||
}
|
||||
public void export(@NotNull MemberDescriptor descriptor, boolean force) {
|
||||
if (exportedDeclarations.contains(descriptor)) return;
|
||||
|
||||
PackageFragmentDescriptor packageDescriptor = (PackageFragmentDescriptor) container;
|
||||
ExportedPackage exportedPackage = rootPackage;
|
||||
for (Name packageName : packageDescriptor.getFqName().pathSegments()) {
|
||||
exportedPackage = exportedPackage.getSubpackage(packageName.asString());
|
||||
}
|
||||
if (descriptor instanceof ConstructorDescriptor && ((ConstructorDescriptor) descriptor).isPrimary()) return;
|
||||
|
||||
JsExpression initializerExpr = DeclarationExporter.exportDeclaration(this, descriptor, exportStatements);
|
||||
if (initializerExpr != null) {
|
||||
JsPropertyInitializer initializer = new JsPropertyInitializer(
|
||||
getNameForDescriptor(descriptor).makeRef(), initializerExpr);
|
||||
exportedPackage.objectLiteral.getPropertyInitializers().add(initializer);
|
||||
SuggestedName suggestedName = nameSuggestion.suggest(descriptor);
|
||||
if (suggestedName == null) return;
|
||||
|
||||
DeclarationDescriptor container = suggestedName.getScope();
|
||||
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);
|
||||
addClassPrototypes();
|
||||
rootFunction.getBody().getStatements().addAll(declarationStatements);
|
||||
rootFunction.getBody().getStatements().addAll(topLevelStatements);
|
||||
|
||||
JsName rootPackageName = rootFunction.getScope().declareName(Namer.getRootPackageName());
|
||||
rootFunction.getBody().getStatements().add(JsAstUtils.newVar(rootPackageName, exportObject));
|
||||
rootFunction.getBody().getStatements().addAll(exportStatements);
|
||||
|
||||
rootFunction.getBody().getStatements().addAll(topLevelStatements);
|
||||
}
|
||||
|
||||
private void addClassPrototypes() {
|
||||
|
||||
+11
-2
@@ -236,6 +236,9 @@ public class TranslationContext {
|
||||
|
||||
@NotNull
|
||||
public JsNameRef getQualifiedReference(@NotNull DeclarationDescriptor descriptor) {
|
||||
if (descriptor instanceof MemberDescriptor && isFromCurrentModule(descriptor) && isPublicInlineFunction()) {
|
||||
staticContext.export((MemberDescriptor) descriptor, true);
|
||||
}
|
||||
return staticContext.getQualifiedReference(descriptor);
|
||||
}
|
||||
|
||||
@@ -608,14 +611,20 @@ public class TranslationContext {
|
||||
staticContext.addClass(classDescriptor);
|
||||
}
|
||||
|
||||
public void export(@NotNull DeclarationDescriptor descriptor) {
|
||||
staticContext.export(descriptor);
|
||||
public void export(@NotNull MemberDescriptor descriptor) {
|
||||
staticContext.export(descriptor, false);
|
||||
}
|
||||
|
||||
public boolean isFromCurrentModule(@NotNull DeclarationDescriptor 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
|
||||
public ModuleDescriptor getCurrentModule() {
|
||||
return staticContext.getCurrentModule();
|
||||
|
||||
+54
-12
@@ -19,39 +19,81 @@ package org.jetbrains.kotlin.js.translate.context
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.*
|
||||
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.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 {
|
||||
declaration is ClassDescriptor && declaration.kind == ClassKind.OBJECT -> {
|
||||
exportObject(declaration, additionalStatements)
|
||||
null
|
||||
declaration is ClassDescriptor -> when {
|
||||
declaration.kind == ClassKind.OBJECT || declaration.kind == ClassKind.ENUM_ENTRY -> {
|
||||
exportObject(declaration, scope, additionalStatements)
|
||||
null
|
||||
}
|
||||
scope is ClassDescriptor -> {
|
||||
exportNested(declaration, scope, additionalStatements)
|
||||
null
|
||||
}
|
||||
else -> {
|
||||
getInnerNameForDescriptor(declaration).makeRef()
|
||||
}
|
||||
}
|
||||
|
||||
declaration is PropertyDescriptor -> {
|
||||
exportProperty(declaration, additionalStatements)
|
||||
if (scope is PackageFragmentDescriptor) {
|
||||
exportProperty(declaration, scope, additionalStatements)
|
||||
}
|
||||
null
|
||||
}
|
||||
|
||||
else -> {
|
||||
scope is PackageFragmentDescriptor -> {
|
||||
getInnerNameForDescriptor(declaration).makeRef()
|
||||
}
|
||||
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun StaticContext.exportObject(declaration: ClassDescriptor, additionalStatements: MutableList<in JsStatement>) {
|
||||
val suggestedName = nameSuggestion.suggest(declaration)!!
|
||||
val qualifier = getQualifiedReference(suggestedName.scope)
|
||||
fun MemberDescriptor.shouldBeExported(force: Boolean) =
|
||||
force || isEffectivelyPublicApi || AnnotationsUtils.getJsNameAnnotation(this) != null
|
||||
|
||||
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)
|
||||
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 suggestedName = nameSuggestion.suggest(declaration)!!
|
||||
val qualifier = getQualifiedReference(suggestedName.scope)
|
||||
val qualifier = getBaseReference(scope)
|
||||
val name = getNameForDescriptor(declaration).ident
|
||||
|
||||
val getterBody: JsExpression = if (JsDescriptorUtils.isSimpleFinalProperty(declaration)) {
|
||||
|
||||
+4
-3
@@ -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.general.AbstractTranslator
|
||||
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.BindingUtils.getClassDescriptor
|
||||
import org.jetbrains.kotlin.js.translate.utils.BindingUtils.getPropertyDescriptorForConstructorParameter
|
||||
@@ -301,7 +302,7 @@ class ClassTranslator private constructor(
|
||||
val name = nonConstructorUsageTracker.getNameForCapturedDescriptor(it)!!
|
||||
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) {
|
||||
val type = supertypes[0]
|
||||
val supertypeDescriptor = getClassDescriptorForType(type)
|
||||
return listOf(context().getInnerReference(supertypeDescriptor))
|
||||
return listOf(ReferenceTranslator.translateAsTypeReference(supertypeDescriptor, context()))
|
||||
}
|
||||
|
||||
val supertypeConstructors = mutableSetOf<TypeConstructor>()
|
||||
@@ -356,7 +357,7 @@ class ClassTranslator private constructor(
|
||||
for (typeConstructor in sortedAllSuperTypes) {
|
||||
if (supertypeConstructors.contains(typeConstructor)) {
|
||||
val supertypeDescriptor = getClassDescriptorForTypeConstructor(typeConstructor)
|
||||
supertypesRefs += context().getInnerReference(supertypeDescriptor)
|
||||
supertypesRefs += ReferenceTranslator.translateAsTypeReference(supertypeDescriptor, context())
|
||||
}
|
||||
}
|
||||
return supertypesRefs
|
||||
|
||||
+2
-7
@@ -62,6 +62,7 @@ class DeclarationBodyVisitor(
|
||||
assert(supertypes.size == 1) { "Simple Enum entry must have one supertype" }
|
||||
val jsEnumEntryCreation = ClassInitializerTranslator
|
||||
.generateEnumEntryInstanceCreation(context, supertypes[0], enumEntry, enumEntryOrdinal)
|
||||
context.addDeclarationStatement(JsAstUtils.newVar(enumInstanceName, jsEnumEntryCreation))
|
||||
val jsEnumEntryFunction = context.createTopLevelAnonymousFunction(descriptor)
|
||||
jsEnumEntryFunction.body.statements.add(JsReturn(jsEnumEntryCreation))
|
||||
|
||||
@@ -69,12 +70,6 @@ class DeclarationBodyVisitor(
|
||||
enumInstanceFunction.name = context.getNameForObjectInstance(descriptor)
|
||||
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()))
|
||||
}
|
||||
|
||||
@@ -92,7 +87,7 @@ class DeclarationBodyVisitor(
|
||||
}
|
||||
|
||||
override fun addClass(descriptor: ClassDescriptor) {
|
||||
//context.export(descriptor)
|
||||
context.export(descriptor)
|
||||
}
|
||||
|
||||
override fun addFunction(descriptor: FunctionDescriptor, expression: JsExpression) {
|
||||
|
||||
+2
-2
@@ -518,9 +518,9 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
|
||||
@NotNull
|
||||
public JsNode visitObjectLiteralExpression(@NotNull KtObjectLiteralExpression expression, @NotNull TranslationContext context) {
|
||||
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<JsExpression> closureArgs = new ArrayList<JsExpression>();
|
||||
if (closure != null) {
|
||||
|
||||
+3
-5
@@ -21,7 +21,6 @@ import com.google.dart.compiler.backend.js.ast.metadata.*
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||
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.getNameForCapturedDescriptor
|
||||
import org.jetbrains.kotlin.js.translate.context.hasCapturedExceptContaining
|
||||
@@ -73,12 +72,14 @@ class LiteralFunctionTranslator(context: TranslationContext) : AbstractTranslato
|
||||
if (!isRecursive) {
|
||||
lambda.name = null
|
||||
}
|
||||
lambdaCreator.name.staticRef = lambdaCreator
|
||||
return lambdaCreator.withCapturedParameters(functionContext, invokingContext)
|
||||
}
|
||||
|
||||
lambda.isLocal = true
|
||||
|
||||
context().addDeclarationStatement(lambda.makeStmt())
|
||||
lambda.name.staticRef = lambda
|
||||
return lambda.name.makeRef().apply { sideEffects = SideEffectKind.PURE }
|
||||
}
|
||||
|
||||
@@ -92,10 +93,7 @@ class LiteralFunctionTranslator(context: TranslationContext) : AbstractTranslato
|
||||
}
|
||||
}
|
||||
|
||||
fun JsFunction.withCapturedParameters(
|
||||
context: TranslationContext,
|
||||
invokingContext: TranslationContext
|
||||
): JsExpression {
|
||||
fun JsFunction.withCapturedParameters(context: TranslationContext, invokingContext: TranslationContext): JsExpression {
|
||||
context.addDeclarationStatement(makeStmt())
|
||||
val ref = name.makeRef().apply { sideEffects = SideEffectKind.PURE }
|
||||
val invocation = JsInvocation(ref).apply { sideEffects = SideEffectKind.PURE }
|
||||
|
||||
+2
-1
@@ -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.Translation;
|
||||
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.TranslationUtils;
|
||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
@@ -169,7 +170,7 @@ public final class PatternTranslator extends AbstractTranslator {
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.js.translate.intrinsic.functions.basic
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression
|
||||
import org.jetbrains.kotlin.js.translate.context.Namer
|
||||
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.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
@@ -43,7 +44,7 @@ class FqnCallIntrinsic(
|
||||
JsAstUtils.replaceRootReference(context.getQualifiedReference(fqn), Namer.kotlinObject())
|
||||
}
|
||||
else {
|
||||
context.getInnerReference(descriptors.first())
|
||||
ReferenceTranslator.translateAsValueReference(descriptors.first(), context)
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-11
@@ -63,7 +63,7 @@ object CallableReferenceTranslator {
|
||||
isMember(descriptor) ->
|
||||
translateForMemberFunction(descriptor, context)
|
||||
else ->
|
||||
ReferenceTranslator.translateAsFQReference(descriptor, context)
|
||||
ReferenceTranslator.translateAsValueReference(descriptor, context)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,14 +108,14 @@ object CallableReferenceTranslator {
|
||||
}
|
||||
|
||||
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 jsPropertyNameAsString = context.program().getStringLiteral(propertyName.asString())
|
||||
val argumentList = ArrayList<JsExpression>(3)
|
||||
argumentList.add(jsPropertyNameAsString)
|
||||
argumentList.add(jsGetterNameRef)
|
||||
if (descriptor.isVar) {
|
||||
val jsSetterNameRef = context.getInnerReference(descriptor.setter!!)
|
||||
val jsSetterNameRef = ReferenceTranslator.translateAsValueReference(descriptor.setter!!, context)
|
||||
argumentList.add(jsSetterNameRef)
|
||||
}
|
||||
return if (AnnotationsUtils.isNativeObject(descriptor))
|
||||
@@ -125,7 +125,7 @@ object CallableReferenceTranslator {
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ object CallableReferenceTranslator {
|
||||
val receiverParameterDescriptor = descriptor.extensionReceiverParameter ?:
|
||||
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) {
|
||||
return JsInvocation(context.namer().callableRefForLocalExtensionFunctionReference(), jsFunctionRef)
|
||||
}
|
||||
@@ -159,12 +159,7 @@ object CallableReferenceTranslator {
|
||||
classDescriptor: ClassDescriptor,
|
||||
context: TranslationContext
|
||||
): JsExpression {
|
||||
val jsClassNameRef = if (AnnotationsUtils.isNativeObject(classDescriptor)) {
|
||||
context.getQualifiedReference(classDescriptor)
|
||||
}
|
||||
else {
|
||||
context.getInnerReference(classDescriptor)
|
||||
}
|
||||
val jsClassNameRef = ReferenceTranslator.translateAsTypeReference(classDescriptor, context)
|
||||
val funName = context.getNameForDescriptor(descriptor)
|
||||
val funNameAsString = context.program().getStringLiteral(funName.toString())
|
||||
return JsInvocation(context.namer().callableRefForMemberFunctionReference(), jsClassNameRef, funNameAsString)
|
||||
|
||||
+2
-2
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.js.translate.general.AbstractTranslator;
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils;
|
||||
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;
|
||||
|
||||
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) {
|
||||
super(context);
|
||||
this.reference = translateAsLocalNameReference(descriptor, context());
|
||||
this.reference = translateAsValueReference(descriptor, context());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+64
-26
@@ -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.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.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext;
|
||||
@@ -43,52 +48,85 @@ public final class ReferenceTranslator {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression translateAsFQReference(@NotNull DeclarationDescriptor referencedDescriptor,
|
||||
@NotNull TranslationContext context) {
|
||||
JsExpression alias = context.getAliasForDescriptor(referencedDescriptor);
|
||||
public static JsExpression translateAsValueReference(@NotNull DeclarationDescriptor descriptor, @NotNull TranslationContext context) {
|
||||
JsExpression alias = context.getAliasForDescriptor(descriptor);
|
||||
if (alias != null) return alias;
|
||||
|
||||
if (isLocalVarOrFunction(referencedDescriptor) ||
|
||||
AnnotationsUtils.isNativeObject(referencedDescriptor) ||
|
||||
AnnotationsUtils.isLibraryObject(referencedDescriptor)
|
||||
) {
|
||||
return context.getQualifiedReference(referencedDescriptor);
|
||||
if (shouldTranslateAsFQN(descriptor, context)) {
|
||||
return context.getQualifiedReference(descriptor);
|
||||
}
|
||||
|
||||
return context.getInnerReference(referencedDescriptor);
|
||||
}
|
||||
|
||||
private static boolean isLocalVarOrFunction(DeclarationDescriptor descriptor) {
|
||||
return descriptor.getContainingDeclaration() instanceof FunctionDescriptor && !(descriptor instanceof ClassDescriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JsExpression translateAsLocalNameReference(@NotNull DeclarationDescriptor descriptor,
|
||||
@NotNull TranslationContext context) {
|
||||
if (descriptor instanceof FunctionDescriptor || descriptor instanceof VariableDescriptor) {
|
||||
JsExpression alias = context.getAliasForDescriptor(descriptor);
|
||||
if (alias != null) {
|
||||
return alias;
|
||||
if (descriptor instanceof PropertyDescriptor) {
|
||||
PropertyDescriptor property = (PropertyDescriptor) descriptor;
|
||||
if (context.isFromCurrentModule(property)) {
|
||||
return context.getInnerReference(property);
|
||||
}
|
||||
else {
|
||||
JsExpression qualifier = context.getInnerReference(property.getContainingDeclaration());
|
||||
JsName name = context.getNameForDescriptor(property);
|
||||
return new JsNameRef(name, qualifier);
|
||||
}
|
||||
}
|
||||
|
||||
if (DescriptorUtils.isObject(descriptor) || DescriptorUtils.isEnumEntry(descriptor)) {
|
||||
if (AnnotationsUtils.isNativeObject(descriptor)) {
|
||||
return context.getQualifiedReference(descriptor);
|
||||
}
|
||||
else if (!context.isFromCurrentModule(descriptor)) {
|
||||
DeclarationDescriptor container = descriptor.getContainingDeclaration();
|
||||
assert container != null : "Object must have containing declaration: " + descriptor;
|
||||
JsExpression qualifier = context.getInnerReference(container);
|
||||
return JsAstUtils.pureFqn(context.getNameForDescriptor(descriptor), qualifier);
|
||||
return getLazyReferenceToObject((ClassDescriptor) descriptor, context);
|
||||
}
|
||||
else {
|
||||
JsExpression functionRef = JsAstUtils.pureFqn(context.getNameForObjectInstance((ClassDescriptor) descriptor), null);
|
||||
return new JsInvocation(functionRef);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
public static AccessTranslator getAccessTranslator(@NotNull KtSimpleNameExpression referenceExpression,
|
||||
@NotNull TranslationContext context) {
|
||||
|
||||
@@ -58,7 +58,7 @@ public final class JSTestGenerator {
|
||||
private static void generateCodeForTestMethod(@NotNull TranslationContext context,
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
@NotNull ClassDescriptor classDescriptor, @NotNull JSTester tester) {
|
||||
JsExpression expression = ReferenceTranslator.translateAsFQReference(classDescriptor, context);
|
||||
JsExpression expression = ReferenceTranslator.translateAsValueReference(classDescriptor, context);
|
||||
JsNew testClass = new JsNew(expression);
|
||||
JsExpression functionToTestCall = CallTranslator.INSTANCE.buildCall(context, functionDescriptor,
|
||||
Collections.<JsExpression>emptyList(), testClass);
|
||||
|
||||
@@ -52,13 +52,13 @@ fun setInlineCallMetadata(
|
||||
"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() {
|
||||
override fun visitInvocation(invocation: JsInvocation) {
|
||||
super.visitInvocation(invocation)
|
||||
|
||||
if (name == invocation.name) {
|
||||
if (invocation.name in candidateNames) {
|
||||
invocation.descriptor = descriptor
|
||||
invocation.inlineStrategy = InlineStrategy.IN_PLACE
|
||||
invocation.psiElement = psiElement
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.intellij.util.SmartList
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.js.translate.context.Namer
|
||||
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.resolve.DescriptorUtils
|
||||
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
|
||||
}
|
||||
|
||||
fun getReferenceToJsClass(type: KotlinType, context: TranslationContext): JsNameRef {
|
||||
val referenceToJsClass: JsNameRef
|
||||
|
||||
fun getReferenceToJsClass(type: KotlinType, context: TranslationContext): JsExpression {
|
||||
val classifierDescriptor = type.constructor.declarationDescriptor
|
||||
|
||||
if (classifierDescriptor is ClassDescriptor) {
|
||||
val reference = context.getInnerReference(classifierDescriptor)
|
||||
if (classifierDescriptor.kind == ClassKind.OBJECT) {
|
||||
referenceToJsClass = JsAstUtils.pureFqn("constructor", JsInvocation(JsNameRef("getPrototypeOf", JsNameRef("Object")), reference))
|
||||
val referenceToJsClass: JsExpression = when (classifierDescriptor) {
|
||||
is ClassDescriptor -> {
|
||||
ReferenceTranslator.translateAsTypeReference(classifierDescriptor, context)
|
||||
}
|
||||
else {
|
||||
referenceToJsClass = reference
|
||||
}
|
||||
}
|
||||
else if (classifierDescriptor is TypeParameterDescriptor) {
|
||||
assert(classifierDescriptor.isReified)
|
||||
is TypeParameterDescriptor -> {
|
||||
assert(classifierDescriptor.isReified)
|
||||
|
||||
referenceToJsClass = context.getNameForDescriptor(classifierDescriptor).makeRef()
|
||||
}
|
||||
else {
|
||||
throw IllegalStateException("Can't get reference for $type")
|
||||
context.getNameForDescriptor(classifierDescriptor).makeRef()
|
||||
}
|
||||
else -> {
|
||||
throw IllegalStateException("Can't get reference for $type")
|
||||
}
|
||||
}
|
||||
|
||||
return referenceToJsClass
|
||||
|
||||
+5
-5
@@ -5,13 +5,13 @@ package foo
|
||||
@native
|
||||
const val ROOT = "Kotlin.modules.JS_TESTS"
|
||||
@native
|
||||
const val PATH_TO_F_CREATOR = "foo.B.far\$f"
|
||||
const val PATH_TO_F_CREATOR = "B\$far\$lambda"
|
||||
@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
|
||||
@native("$ROOT.$PATH_TO_G_CREATOR")
|
||||
@native("$PATH_TO_G_CREATOR")
|
||||
val G_CREATOR: Any = noImpl
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ fun box(): String {
|
||||
assertEquals("B::boo", g())
|
||||
|
||||
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)
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: multiplyInline_0
|
||||
// CHECK_NOT_CALLED: runNoinline_0
|
||||
// CHECK_CONTAINS_NO_CALLS: multiplyInline
|
||||
// CHECK_NOT_CALLED: runNoinline
|
||||
|
||||
internal inline fun multiply(a: Int, b: Int) = a * b
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: test_0
|
||||
// CHECK_CONTAINS_NO_CALLS: test
|
||||
|
||||
// A copy of stdlib run function.
|
||||
// Copied to not to depend on run implementation.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
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)
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: squareMultipliedByTwo_0
|
||||
// CHECK_CONTAINS_NO_CALLS: squareMultipliedByTwo
|
||||
|
||||
internal inline fun inline1(a: Int): Int {
|
||||
return a
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: squareMultipliedByTwo_0
|
||||
// CHECK_CONTAINS_NO_CALLS: squareMultipliedByTwo
|
||||
|
||||
internal inline fun inline1(a: Int): Int {
|
||||
return a
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: identity_0
|
||||
// CHECK_CONTAINS_NO_CALLS: sumNoInline_0
|
||||
// CHECK_CONTAINS_NO_CALLS: identity
|
||||
// CHECK_CONTAINS_NO_CALLS: sumNoInline
|
||||
|
||||
internal inline fun sum(a: Int, b: Int = 0): Int {
|
||||
return a + b
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: doNothingNoInline_0
|
||||
// CHECK_CONTAINS_NO_CALLS: doNothingNoInline
|
||||
|
||||
internal inline fun <T> doNothing1(a: T): T {
|
||||
return a
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: doNothingInt_0
|
||||
// CHECK_CONTAINS_NO_CALLS: doNothingStr_0
|
||||
// CHECK_CONTAINS_NO_CALLS: doNothingInt
|
||||
// CHECK_CONTAINS_NO_CALLS: doNothingStr
|
||||
|
||||
internal inline fun <T> doNothing(a: T): T {
|
||||
return a
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: multiplyNoInline_0
|
||||
// CHECK_CONTAINS_NO_CALLS: multiplyNoInline
|
||||
|
||||
internal inline fun multiply(a: Int, b: Int): Int {
|
||||
return a * b
|
||||
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: doNothing1_0
|
||||
// CHECK_CONTAINS_NO_CALLS: doNothing2_0
|
||||
// CHECK_CONTAINS_NO_CALLS: doNothing3_0
|
||||
// CHECK_CONTAINS_NO_CALLS: doNothing1
|
||||
// CHECK_CONTAINS_NO_CALLS: doNothing2
|
||||
// CHECK_CONTAINS_NO_CALLS: doNothing3
|
||||
|
||||
internal class Inline {
|
||||
public inline fun <T> identity1 (x: T): T {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
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 {
|
||||
var result = 0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
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)
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
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) {
|
||||
inline public fun getFst(): Int { return fst }
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: factAbsNoInline1_0
|
||||
// CHECK_CONTAINS_NO_CALLS: factAbsNoInline1
|
||||
|
||||
internal class State(value: Int) {
|
||||
public var value: Int = value
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
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")
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
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")
|
||||
|
||||
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CALLED_IN_SCOPE: scope=multiplyBy2_0 function=multiplyBy2_0$f
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: scope=multiplyBy2_0 function=multiplyBy2_0$f_0
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: scope=multiplyBy2_0 function=run
|
||||
// CHECK_CALLED_IN_SCOPE: scope=multiplyBy2 function=multiplyBy2$lambda
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: scope=multiplyBy2 function=multiplyBy2$lambda_0
|
||||
// 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 {
|
||||
return outer(inner, arg)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: capturedInLambda_0
|
||||
// CHECK_CONTAINS_NO_CALLS: declaredInLambda_0
|
||||
// CHECK_CONTAINS_NO_CALLS: capturedInLambda
|
||||
// CHECK_CONTAINS_NO_CALLS: declaredInLambda
|
||||
|
||||
internal data class State(var count: Int = 0)
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: localWithCapture_0
|
||||
// CHECK_CONTAINS_NO_CALLS: localWithoutCapture_0
|
||||
// CHECK_CONTAINS_NO_CALLS: localWithCapture
|
||||
// CHECK_CONTAINS_NO_CALLS: localWithoutCapture
|
||||
|
||||
internal inline fun repeatAction(times: Int, action: () -> Unit) {
|
||||
for (i in 1..times) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: add_0
|
||||
// CHECK_CONTAINS_NO_CALLS: add
|
||||
|
||||
internal data class State(var count: Int = 0)
|
||||
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: localWithCapture_0
|
||||
// CHECK_CONTAINS_NO_CALLS: localWithoutCapture_0
|
||||
// CHECK_CONTAINS_NO_CALLS: localWithCapture
|
||||
// CHECK_CONTAINS_NO_CALLS: localWithoutCapture
|
||||
|
||||
internal inline fun repeatAction(times: Int, action: () -> Unit) {
|
||||
for (i in 1..times) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: add_0
|
||||
// CHECK_CONTAINS_NO_CALLS: add
|
||||
|
||||
internal inline fun run(action: () -> Int): Int {
|
||||
return action()
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: test1_0
|
||||
// CHECK_CONTAINS_NO_CALLS: test2_0
|
||||
// CHECK_CONTAINS_NO_CALLS: test3_0
|
||||
// CHECK_CONTAINS_NO_CALLS: test1
|
||||
// CHECK_CONTAINS_NO_CALLS: test2
|
||||
// CHECK_CONTAINS_NO_CALLS: test3
|
||||
// CHECK_CONTAINS_NO_CALLS: test4_buocd8$
|
||||
// CHECK_CONTAINS_NO_CALLS: test5_0
|
||||
// CHECK_HAS_INLINE_METADATA: apply_hiyix$
|
||||
// CHECK_CONTAINS_NO_CALLS: test5
|
||||
// CHECK_HAS_INLINE_METADATA: apply
|
||||
// CHECK_HAS_INLINE_METADATA: applyL_hiyix$
|
||||
// CHECK_HAS_INLINE_METADATA: applyM_hiyix$
|
||||
// CHECK_HAS_NO_INLINE_METADATA: applyN_hiyix$
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CALLED_IN_SCOPE: scope=multiplyBy2_0 function=multiplyBy2_0$f
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: scope=multiplyBy2_0 function=run
|
||||
// CHECK_CALLED_IN_SCOPE: scope=multiplyBy2 function=multiplyBy2$lambda
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: scope=multiplyBy2 function=run
|
||||
|
||||
internal inline fun <T> run(noinline func: (T) -> T, arg: T): T {
|
||||
return func(arg)
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
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)
|
||||
|
||||
|
||||
+3
-3
@@ -1,9 +1,9 @@
|
||||
package foo
|
||||
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: test1_0
|
||||
// CHECK_CONTAINS_NO_CALLS: test2_0
|
||||
// CHECK_CONTAINS_NO_CALLS: test3_0 except=slice
|
||||
// CHECK_CONTAINS_NO_CALLS: test1
|
||||
// CHECK_CONTAINS_NO_CALLS: test2
|
||||
// CHECK_CONTAINS_NO_CALLS: test3 except=slice
|
||||
|
||||
internal inline fun concat(vararg strings: String): String {
|
||||
var result = ""
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ package foo
|
||||
|
||||
import test.*
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: testClassObject_0
|
||||
// CHECK_CONTAINS_NO_CALLS: testClassObject
|
||||
|
||||
internal fun testFinalInline(): String {
|
||||
return Z().finalInline({"final"})
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ public fun log(s: String): String {
|
||||
|
||||
import utils.*
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: test_0
|
||||
// CHECK_CONTAINS_NO_CALLS: test
|
||||
|
||||
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.*
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: test_0
|
||||
// CHECK_CONTAINS_NO_CALLS: test
|
||||
|
||||
internal fun multiplyBy2(x: Int): Int = x * 2
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ public fun sum(x: Int, y: Int): Int =
|
||||
|
||||
// MODULE: main(lib)
|
||||
// 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)
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ public fun <T, R> apply(x: T, fn: T.()->R): R =
|
||||
|
||||
import utils.*
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: test_0
|
||||
// CHECK_CONTAINS_NO_CALLS: test
|
||||
|
||||
internal class A(val n: Int)
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ public fun <T, R> apply(x: T, fn: (T)->R): R =
|
||||
|
||||
import utils.*
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: test_0
|
||||
// CHECK_CONTAINS_NO_CALLS: test
|
||||
|
||||
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.*
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: test_0
|
||||
// CHECK_CONTAINS_NO_CALLS: test
|
||||
|
||||
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.*
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: test_0
|
||||
// CHECK_CONTAINS_NO_CALLS: test
|
||||
|
||||
internal fun test(x: Int, y: Int): Int = apply(x) { it + 1 } * y
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ public class A(public val x: Int) {
|
||||
|
||||
import utils.*
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: test_0
|
||||
// CHECK_CONTAINS_NO_CALLS: test
|
||||
|
||||
internal fun test(a: A, y: Int): Int = a.plus(y)
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ public fun sum(x: Int, y: Int): Int =
|
||||
|
||||
import utils.*
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: test_0
|
||||
// CHECK_CONTAINS_NO_CALLS: test
|
||||
|
||||
internal fun test(x: Int, y: Int): Int = sum(x, y)
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package foo
|
||||
|
||||
// CHECK_NOT_CALLED: f1_0
|
||||
// CHECK_NOT_CALLED: f2_0
|
||||
// CHECK_BREAKS_COUNT: function=test_0 count=3
|
||||
// CHECK_NOT_CALLED: f1
|
||||
// CHECK_NOT_CALLED: f2
|
||||
// CHECK_BREAKS_COUNT: function=test count=3
|
||||
|
||||
internal var even = arrayListOf<Int>()
|
||||
internal var odd = arrayListOf<Int>()
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
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 {
|
||||
val result = f(a)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: test1_0
|
||||
// CHECK_CONTAINS_NO_CALLS: test2_0
|
||||
// CHECK_VARS_COUNT: function=test1_0 count=0
|
||||
// CHECK_VARS_COUNT: function=test2_0 count=1
|
||||
// CHECK_CONTAINS_NO_CALLS: test1
|
||||
// CHECK_CONTAINS_NO_CALLS: test2
|
||||
// CHECK_VARS_COUNT: function=test1 count=0
|
||||
// CHECK_VARS_COUNT: function=test2 count=1
|
||||
|
||||
var log = ""
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: test_0
|
||||
// CHECK_VARS_COUNT: function=test_0 count=0
|
||||
// CHECK_CONTAINS_NO_CALLS: test except=SumHolder_getInstance
|
||||
// CHECK_VARS_COUNT: function=test count=1
|
||||
|
||||
object SumHolder {
|
||||
var sum = 0
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: test_0
|
||||
// CHECK_VARS_COUNT: function=test_0 count=0
|
||||
// CHECK_CONTAINS_NO_CALLS: test
|
||||
// CHECK_VARS_COUNT: function=test count=0
|
||||
|
||||
internal inline fun sign(x: Int): Int {
|
||||
if (x < 0) return -1
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: test_0
|
||||
// CHECK_VARS_COUNT: function=test_0 count=0
|
||||
// CHECK_CONTAINS_NO_CALLS: test
|
||||
// CHECK_VARS_COUNT: function=test count=0
|
||||
|
||||
// A copy of stdlib run function.
|
||||
// Copied to not to depend on run implementation.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package foo
|
||||
|
||||
// CHECK_VARS_COUNT: function=test1_za3lpa$ count=0
|
||||
// CHECK_VARS_COUNT: function=test2_za3lpa$ count=1
|
||||
// CHECK_VARS_COUNT: function=test3_za3lpa$ count=0
|
||||
// CHECK_VARS_COUNT: function=test1 count=0
|
||||
// CHECK_VARS_COUNT: function=test2 count=1
|
||||
// CHECK_VARS_COUNT: function=test3 count=0
|
||||
|
||||
inline fun a(x: Int) = b(x)
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: test_0
|
||||
// CHECK_VARS_COUNT: function=test_0 count=0
|
||||
// CHECK_CONTAINS_NO_CALLS: test
|
||||
// CHECK_VARS_COUNT: function=test count=0
|
||||
|
||||
internal class A(val x: Int) {
|
||||
inline fun f(): Int = x
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: test_0
|
||||
// CHECK_VARS_COUNT: function=test_0 count=1
|
||||
// CHECK_CONTAINS_NO_CALLS: test
|
||||
// CHECK_VARS_COUNT: function=test count=1
|
||||
|
||||
internal inline fun sum(x: Int, y: Int): Int {
|
||||
if (x == 0 || y == 0) return 0
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: test_0
|
||||
// CHECK_VARS_COUNT: function=test_0 count=1
|
||||
// CHECK_CONTAINS_NO_CALLS: test
|
||||
// CHECK_VARS_COUNT: function=test count=1
|
||||
|
||||
internal inline fun sum(x: Int, y: Int): Int {
|
||||
if (x == 0 || y == 0) return 0
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
package foo
|
||||
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: scope=test_0 function=even_0
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: scope=test_0 function=filter_azvtw4$
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: scope=test function=even
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: scope=test function=filter_azvtw4$
|
||||
|
||||
internal fun even(x: Int) = x % 2 == 0
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: test_0
|
||||
// CHECK_CONTAINS_NO_CALLS: test
|
||||
|
||||
internal fun test(a: Int, b: Int): Int {
|
||||
var c = 0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: test_0
|
||||
// CHECK_CONTAINS_NO_CALLS: test
|
||||
|
||||
internal fun test(a: Int, b: Int): Int {
|
||||
var res = 0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: test_0
|
||||
// CHECK_CONTAINS_NO_CALLS: test
|
||||
|
||||
internal fun test(x: Int, y: Int): Int =
|
||||
with (x + x) {
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: test_0
|
||||
// CHECK_CONTAINS_NO_CALLS: test
|
||||
|
||||
internal var counter = 0
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: testImplicitThis_0
|
||||
// CHECK_CONTAINS_NO_CALLS: testExplicitThis_0
|
||||
// CHECK_CONTAINS_NO_CALLS: testImplicitThis
|
||||
// CHECK_CONTAINS_NO_CALLS: testExplicitThis
|
||||
|
||||
internal class A(var value: Int)
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package foo
|
||||
|
||||
// CHECK_CONTAINS_NO_CALLS: test_0
|
||||
// CHECK_LABELS_COUNT: function=test_0 name=loop count=1
|
||||
// CHECK_LABELS_COUNT: function=test_0 name=loop_0 count=1
|
||||
// CHECK_LABELS_COUNT: function=test_0 name=loop_1 count=1
|
||||
// CHECK_CONTAINS_NO_CALLS: test
|
||||
// CHECK_LABELS_COUNT: function=test name=loop count=1
|
||||
// CHECK_LABELS_COUNT: function=test name=loop_0 count=1
|
||||
// CHECK_LABELS_COUNT: function=test name=loop_1 count=1
|
||||
|
||||
class State() {
|
||||
public var value: Int = 0
|
||||
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
package foo
|
||||
|
||||
// CHECK_LABELS_COUNT: function=test_0 name=loop count=1
|
||||
// CHECK_LABELS_COUNT: function=test_0 name=loop_0 count=1
|
||||
// CHECK_LABELS_COUNT: function=test_0 name=loop_1 count=1
|
||||
// CHECK_LABELS_COUNT: function=test name=loop count=1
|
||||
// CHECK_LABELS_COUNT: function=test name=loop_0 count=1
|
||||
// CHECK_LABELS_COUNT: function=test name=loop_1 count=1
|
||||
|
||||
class State() {
|
||||
public var value: Int = 0
|
||||
|
||||
@@ -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
|
||||
@@ -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
Reference in New Issue
Block a user