From 000fc55035a711f3a77c8bc09f548365d62adc7d Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Thu, 24 Jan 2013 01:08:32 +0400 Subject: [PATCH] Added intrinsic properties of ranges and sequences. --- .../jet/codegen/ExpressionCodegen.java | 7 +- .../codegen/intrinsics/IntrinsicMethods.java | 13 ++++ .../intrinsics/PropertyOfSequenceOrRange.java | 69 +++++++++++++++++++ .../jet/lang/types/lang/PrimitiveType.java | 8 +++ 4 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/PropertyOfSequenceOrRange.java diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index f80918ca390..dbf51228975 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -55,6 +55,7 @@ import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants; import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.java.JvmClassName; +import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType; import org.jetbrains.jet.lang.resolve.scopes.receivers.*; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.checker.JetTypeChecker; @@ -845,11 +846,13 @@ public class ExpressionCodegen extends JetVisitor implem v.dup(); indexVar = myFrameMap.enterTemp(Type.INT_TYPE); - v.invokevirtual(JET_INT_RANGE_TYPE.getInternalName(), "getStart", "()I"); + v.invokevirtual(JET_INT_RANGE_TYPE.getInternalName(), "getStart", "()Ljava/lang/Integer;"); + StackValue.coerce(Type.getType("Ljava/lang/Integer;"), Type.INT_TYPE, v); v.store(indexVar, Type.INT_TYPE); endVar = myFrameMap.enterTemp(Type.INT_TYPE); - v.invokevirtual(JET_INT_RANGE_TYPE.getInternalName(), "getEnd", "()I"); + v.invokevirtual(JET_INT_RANGE_TYPE.getInternalName(), "getEnd", "()Ljava/lang/Integer;"); + StackValue.coerce(Type.getType("Ljava/lang/Integer;"), Type.INT_TYPE, v); v.store(endVar, Type.INT_TYPE); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java index af041216b79..a6f7eb3f615 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java @@ -156,9 +156,22 @@ public class IntrinsicMethods { Name.identifier("EMPTY"), -1, new EmptyRange(type)); } + for (PrimitiveType type : PrimitiveType.NUMBER_TYPES) { + registerRangeOrSequenceProperty(type.getRangeClassName(), Name.identifier("start")); + registerRangeOrSequenceProperty(type.getRangeClassName(), Name.identifier("end")); + + registerRangeOrSequenceProperty(type.getSequenceClassName(), Name.identifier("start")); + registerRangeOrSequenceProperty(type.getSequenceClassName(), Name.identifier("end")); + registerRangeOrSequenceProperty(type.getSequenceClassName(), Name.identifier("increment")); + } + declareArrayMethods(); } + private void registerRangeOrSequenceProperty(@NotNull FqName ownerClass, @NotNull Name propertyName) { + intrinsicsMap.registerIntrinsic(ownerClass, propertyName, -1, new PropertyOfSequenceOrRange(ownerClass, propertyName)); + } + @NotNull private static FqNameUnsafe getClassObjectFqName(@NotNull Name builtinClassName) { return KotlinBuiltIns.getInstance().getBuiltInsPackageFqName().child(builtinClassName).toUnsafe().child(getClassObjectName(builtinClassName)); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/PropertyOfSequenceOrRange.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/PropertyOfSequenceOrRange.java new file mode 100644 index 00000000000..a964c7c0fb4 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/PropertyOfSequenceOrRange.java @@ -0,0 +1,69 @@ +/* + * Copyright 2010-2013 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.jet.codegen.intrinsics; + +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; +import org.jetbrains.jet.codegen.ExpressionCodegen; +import org.jetbrains.jet.codegen.PropertyCodegen; +import org.jetbrains.jet.codegen.StackValue; +import org.jetbrains.jet.codegen.state.GenerationState; +import org.jetbrains.jet.lang.psi.JetExpression; +import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants; +import org.jetbrains.jet.lang.resolve.java.JvmClassName; +import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType; +import org.jetbrains.jet.lang.resolve.name.FqName; +import org.jetbrains.jet.lang.resolve.name.Name; + +import java.util.List; + +public class PropertyOfSequenceOrRange implements IntrinsicMethod { + private final FqName ownerClass; + private final Name propertyName; + + public PropertyOfSequenceOrRange(@NotNull FqName ownerClass, @NotNull Name propertyName) { + this.ownerClass = ownerClass; + this.propertyName = propertyName; + } + + @Override + public StackValue generate( + ExpressionCodegen codegen, + InstructionAdapter v, + @NotNull Type expectedType, + PsiElement element, + List arguments, + StackValue receiver, + @NotNull GenerationState state + ) { + String ownerInternalName = JvmClassName.byFqNameWithoutInnerClasses(this.ownerClass).getInternalName(); + JvmClassName wrapperClass = JvmPrimitiveType.getByAsmType(expectedType).getWrapper(); + String getterName = PropertyCodegen.getterName(propertyName); + + receiver.put(AsmTypeConstants.OBJECT_TYPE, v); + v.invokevirtual(ownerInternalName, getterName, "()" + wrapperClass.getDescriptor()); + StackValue.coerce(wrapperClass.getAsmType(), expectedType, v); + return StackValue.onStack(expectedType); + } + + public enum OwnerKind { + SEQUENCE, + RANGE + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/lang/PrimitiveType.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/lang/PrimitiveType.java index 31a3b99c5dc..7af5fde467b 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/lang/PrimitiveType.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/lang/PrimitiveType.java @@ -41,6 +41,7 @@ public enum PrimitiveType { private final FqName className; private final FqName arrayClassName; private final FqName rangeClassName; + private final FqName sequenceClassName; private PrimitiveType(String typeName) { this.typeName = Name.identifier(typeName); @@ -50,6 +51,8 @@ public enum PrimitiveType { this.className = builtInsPackageFqName.child(this.typeName); this.arrayClassName = builtInsPackageFqName.child(this.arrayTypeName); this.rangeClassName = builtInsPackageFqName.child(this.rangeTypeName); + this.sequenceClassName = builtInsPackageFqName.child( + Name.identifier((typeName == "Char") ? "CharacterSequence" : typeName + "Sequence")); } @NotNull @@ -81,4 +84,9 @@ public enum PrimitiveType { public FqName getRangeClassName() { return rangeClassName; } + + @NotNull + public FqName getSequenceClassName() { + return sequenceClassName; + } }