JS: refactor range and progression related intrinsics
This commit is contained in:
@@ -56,8 +56,6 @@ public final class Namer {
|
|||||||
|
|
||||||
public static final String EQUALS_METHOD_NAME = getStableMangledNameForDescriptor(JsPlatform.INSTANCE.getBuiltIns().getAny(), "equals");
|
public static final String EQUALS_METHOD_NAME = getStableMangledNameForDescriptor(JsPlatform.INSTANCE.getBuiltIns().getAny(), "equals");
|
||||||
public static final String COMPARE_TO_METHOD_NAME = getStableMangledNameForDescriptor(JsPlatform.INSTANCE.getBuiltIns().getComparable(), "compareTo");
|
public static final String COMPARE_TO_METHOD_NAME = getStableMangledNameForDescriptor(JsPlatform.INSTANCE.getBuiltIns().getComparable(), "compareTo");
|
||||||
public static final String INT_RANGE = "kotlin.ranges.IntRange";
|
|
||||||
public static final String CHAR_RANGE = "kotlin.ranges.CharRange";
|
|
||||||
public static final String LONG_FROM_NUMBER = "fromNumber";
|
public static final String LONG_FROM_NUMBER = "fromNumber";
|
||||||
public static final String LONG_TO_NUMBER = "toNumber";
|
public static final String LONG_TO_NUMBER = "toNumber";
|
||||||
public static final String LONG_FROM_INT = "fromInt";
|
public static final String LONG_FROM_INT = "fromInt";
|
||||||
|
|||||||
-50
@@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
class FqnCallIntrinsic(
|
|
||||||
simpleName: String,
|
|
||||||
fqn: String,
|
|
||||||
isConstructor: Boolean = false,
|
|
||||||
receiverAsArgument: Boolean = true
|
|
||||||
) : LazyImportedCallIntrinsic(simpleName, isConstructor = isConstructor, receiverAsArgument = receiverAsArgument) {
|
|
||||||
val fqn = FqName(fqn)
|
|
||||||
|
|
||||||
override fun getExpression(context: TranslationContext): JsExpression {
|
|
||||||
val packageDescriptor = context.currentModule.getPackage(fqn.parent())
|
|
||||||
|
|
||||||
// Hack to compile stdlib
|
|
||||||
val descriptors = packageDescriptor.memberScope.getContributedDescriptors(DescriptorKindFilter.ALL) {
|
|
||||||
it.asString() == fqn.shortName().asString()
|
|
||||||
}
|
|
||||||
|
|
||||||
return if (descriptors.size == 1) {
|
|
||||||
JsAstUtils.replaceRootReference(context.getQualifiedReference(fqn), Namer.kotlinObject())
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ReferenceTranslator.translateAsValueReference(descriptors.first(), context)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-49
@@ -1,49 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.js.translate.intrinsic.functions.basic
|
|
||||||
|
|
||||||
import com.google.dart.compiler.backend.js.ast.*
|
|
||||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
|
||||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.pureFqn
|
|
||||||
import org.jetbrains.kotlin.utils.singletonOrEmptyList
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
abstract class LazyImportedCallIntrinsic(
|
|
||||||
val simpleName: String,
|
|
||||||
val isConstructor: Boolean = false,
|
|
||||||
val receiverAsArgument: Boolean = true
|
|
||||||
) : FunctionIntrinsic() {
|
|
||||||
private val internalNameMap = WeakHashMap<TranslationContext, JsName>()
|
|
||||||
|
|
||||||
override fun apply(receiver: JsExpression?, arguments: MutableList<JsExpression>, context: TranslationContext): JsExpression {
|
|
||||||
val rootContext = generateSequence(context) { it.parent }.last()
|
|
||||||
val functionName = internalNameMap.getOrPut(rootContext) {
|
|
||||||
val declaration = getExpression(rootContext)
|
|
||||||
if (declaration is JsNameRef && declaration.name != null && declaration.qualifier == null) {
|
|
||||||
declaration.name!!
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
rootContext.importDeclaration(simpleName, declaration)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val allArguments = (if (receiverAsArgument) receiver else null).singletonOrEmptyList() + arguments
|
|
||||||
val function = pureFqn(functionName, null)
|
|
||||||
return if (isConstructor) JsNew(function, allArguments) else JsInvocation(function, allArguments)
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract fun getExpression(context: TranslationContext): JsExpression
|
|
||||||
}
|
|
||||||
+42
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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.JsNew
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||||
|
import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
||||||
|
import org.jetbrains.kotlin.js.translate.reference.ReferenceTranslator
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||||
|
import org.jetbrains.kotlin.utils.singletonOrEmptyList
|
||||||
|
|
||||||
|
class RangeToIntrinsic(function: FunctionDescriptor) : FunctionIntrinsic() {
|
||||||
|
val rangeTypeDescriptor = function.returnType!!.constructor.declarationDescriptor as ClassDescriptor
|
||||||
|
|
||||||
|
override fun apply(receiver: JsExpression?, arguments: MutableList<JsExpression>, context: TranslationContext): JsExpression {
|
||||||
|
val packageName = (rangeTypeDescriptor.containingDeclaration as PackageFragmentDescriptor).fqName
|
||||||
|
val packageDescriptor = context.currentModule.getPackage(packageName)
|
||||||
|
val existingClasses = packageDescriptor.memberScope.getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS) {
|
||||||
|
it == rangeTypeDescriptor.name
|
||||||
|
}
|
||||||
|
val finalClass = (existingClasses.firstOrNull() as? ClassDescriptor) ?: rangeTypeDescriptor
|
||||||
|
val constructor = ReferenceTranslator.translateAsTypeReference(finalClass, context)
|
||||||
|
return JsNew(constructor, receiver.singletonOrEmptyList() + arguments)
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-10
@@ -28,10 +28,9 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
|||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
|
||||||
import org.jetbrains.kotlin.js.patterns.DescriptorPredicate;
|
import org.jetbrains.kotlin.js.patterns.DescriptorPredicate;
|
||||||
import org.jetbrains.kotlin.js.patterns.NamePredicate;
|
import org.jetbrains.kotlin.js.patterns.NamePredicate;
|
||||||
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.intrinsic.functions.basic.FqnCallIntrinsic;
|
|
||||||
import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsic;
|
import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsic;
|
||||||
|
import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.RangeToIntrinsic;
|
||||||
import org.jetbrains.kotlin.js.translate.operation.OperatorTable;
|
import org.jetbrains.kotlin.js.translate.operation.OperatorTable;
|
||||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils;
|
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils;
|
||||||
import org.jetbrains.kotlin.lexer.KtToken;
|
import org.jetbrains.kotlin.lexer.KtToken;
|
||||||
@@ -62,12 +61,6 @@ public enum PrimitiveBinaryOperationFIF implements FunctionIntrinsicFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private static final FunctionIntrinsic RANGE_TO_INTRINSIC = new FqnCallIntrinsic("IntRange", Namer.INT_RANGE, true, true);
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private static final FunctionIntrinsic CHAR_RANGE_TO_INTRINSIC = new FqnCallIntrinsic("CharRange", Namer.CHAR_RANGE, true, true);
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static final BinaryOperationIntrinsicBase INTEGER_DIVISION_INTRINSIC = new BinaryOperationIntrinsicBase() {
|
private static final BinaryOperationIntrinsicBase INTEGER_DIVISION_INTRINSIC = new BinaryOperationIntrinsicBase() {
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -127,7 +120,7 @@ public enum PrimitiveBinaryOperationFIF implements FunctionIntrinsicFactory {
|
|||||||
@Override
|
@Override
|
||||||
public FunctionIntrinsic getIntrinsic(@NotNull FunctionDescriptor descriptor) {
|
public FunctionIntrinsic getIntrinsic(@NotNull FunctionDescriptor descriptor) {
|
||||||
if (pattern("Char.rangeTo(Char)").apply(descriptor)) {
|
if (pattern("Char.rangeTo(Char)").apply(descriptor)) {
|
||||||
return CHAR_RANGE_TO_INTRINSIC;
|
return new RangeToIntrinsic(descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PRIMITIVE_NUMBERS_COMPARE_TO_OPERATIONS.apply(descriptor)) {
|
if (PRIMITIVE_NUMBERS_COMPARE_TO_OPERATIONS.apply(descriptor)) {
|
||||||
@@ -148,7 +141,7 @@ public enum PrimitiveBinaryOperationFIF implements FunctionIntrinsicFactory {
|
|||||||
return INTEGER_DIVISION_INTRINSIC;
|
return INTEGER_DIVISION_INTRINSIC;
|
||||||
}
|
}
|
||||||
if (descriptor.getName().equals(Name.identifier("rangeTo"))) {
|
if (descriptor.getName().equals(Name.identifier("rangeTo"))) {
|
||||||
return RANGE_TO_INTRINSIC;
|
return new RangeToIntrinsic(descriptor);
|
||||||
}
|
}
|
||||||
if (INT_WITH_BIT_OPERATIONS.apply(descriptor)) {
|
if (INT_WITH_BIT_OPERATIONS.apply(descriptor)) {
|
||||||
JsBinaryOperator op = BINARY_BITWISE_OPERATIONS.get(descriptor.getName().asString());
|
JsBinaryOperator op = BINARY_BITWISE_OPERATIONS.get(descriptor.getName().asString());
|
||||||
|
|||||||
+22
-15
@@ -18,26 +18,33 @@ package org.jetbrains.kotlin.js.translate.intrinsic.functions.factories
|
|||||||
|
|
||||||
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.JsNew
|
import com.google.dart.compiler.backend.js.ast.JsNew
|
||||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.js.patterns.PatternBuilder.pattern
|
import org.jetbrains.kotlin.js.patterns.PatternBuilder.pattern
|
||||||
import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
import org.jetbrains.kotlin.js.translate.context.TranslationContext
|
||||||
import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FqnCallIntrinsic
|
|
||||||
import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsic
|
import org.jetbrains.kotlin.js.translate.intrinsic.functions.basic.FunctionIntrinsic
|
||||||
|
import org.jetbrains.kotlin.js.translate.reference.ReferenceTranslator
|
||||||
|
|
||||||
|
object ProgressionCompanionFIF : FunctionIntrinsicFactory {
|
||||||
object ProgressionCompanionFIF : CompositeFIF() {
|
val patterns = listOf(methodPattern("IntProgression"), methodPattern("LongProgression"), methodPattern("CharProgression"))
|
||||||
init {
|
|
||||||
val numberProgressionConstructor = FqnCallIntrinsic("IntProgression", "kotlin.ranges.IntProgression", isConstructor = true,
|
|
||||||
receiverAsArgument = false)
|
|
||||||
for (type in arrayOf(PrimitiveType.INT)) {
|
|
||||||
add(methodPattern("${type.typeName}Progression"), numberProgressionConstructor)
|
|
||||||
}
|
|
||||||
add(methodPattern("LongProgression"), FqnCallIntrinsic("LongProgression", "kotlin.ranges.LongProgression", isConstructor = true,
|
|
||||||
receiverAsArgument = false))
|
|
||||||
add(methodPattern("CharProgression"), FqnCallIntrinsic("CharProgression", "kotlin.ranges.CharProgression", isConstructor = true,
|
|
||||||
receiverAsArgument = false))
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun methodPattern(builtinProgressionName: String) =
|
private fun methodPattern(builtinProgressionName: String) =
|
||||||
pattern("kotlin.ranges", builtinProgressionName, "Companion", "fromClosedRange")
|
pattern("kotlin.ranges", builtinProgressionName, "Companion", "fromClosedRange")
|
||||||
|
|
||||||
|
override fun getIntrinsic(descriptor: FunctionDescriptor): FunctionIntrinsic? =
|
||||||
|
if (patterns.any { it.apply(descriptor) }) {
|
||||||
|
FromClosedRangeIntrinsic(descriptor)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
private class FromClosedRangeIntrinsic(descriptor: FunctionDescriptor) : FunctionIntrinsic() {
|
||||||
|
val progressionType = descriptor.containingDeclaration.containingDeclaration as ClassDescriptor
|
||||||
|
|
||||||
|
override fun apply(receiver: JsExpression?, arguments: MutableList<JsExpression>, context: TranslationContext): JsExpression {
|
||||||
|
val constructor = ReferenceTranslator.translateAsTypeReference(progressionType, context)
|
||||||
|
return JsNew(constructor, arguments)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user