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 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_TO_NUMBER = "toNumber";
|
||||
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.js.patterns.DescriptorPredicate;
|
||||
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.intrinsic.functions.basic.FqnCallIntrinsic;
|
||||
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.utils.JsAstUtils;
|
||||
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
|
||||
private static final BinaryOperationIntrinsicBase INTEGER_DIVISION_INTRINSIC = new BinaryOperationIntrinsicBase() {
|
||||
@NotNull
|
||||
@@ -127,7 +120,7 @@ public enum PrimitiveBinaryOperationFIF implements FunctionIntrinsicFactory {
|
||||
@Override
|
||||
public FunctionIntrinsic getIntrinsic(@NotNull FunctionDescriptor 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)) {
|
||||
@@ -148,7 +141,7 @@ public enum PrimitiveBinaryOperationFIF implements FunctionIntrinsicFactory {
|
||||
return INTEGER_DIVISION_INTRINSIC;
|
||||
}
|
||||
if (descriptor.getName().equals(Name.identifier("rangeTo"))) {
|
||||
return RANGE_TO_INTRINSIC;
|
||||
return new RangeToIntrinsic(descriptor);
|
||||
}
|
||||
if (INT_WITH_BIT_OPERATIONS.apply(descriptor)) {
|
||||
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.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.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.reference.ReferenceTranslator
|
||||
|
||||
|
||||
object ProgressionCompanionFIF : CompositeFIF() {
|
||||
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))
|
||||
}
|
||||
object ProgressionCompanionFIF : FunctionIntrinsicFactory {
|
||||
val patterns = listOf(methodPattern("IntProgression"), methodPattern("LongProgression"), methodPattern("CharProgression"))
|
||||
|
||||
private fun methodPattern(builtinProgressionName: String) =
|
||||
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