Added intrinsic properties of ranges and sequences.

This commit is contained in:
Evgeny Gerashchenko
2013-01-24 01:08:32 +04:00
parent b2e74b1473
commit 000fc55035
4 changed files with 95 additions and 2 deletions
@@ -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<StackValue, StackValue> 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);
}
@@ -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));
@@ -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<JetExpression> 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
}
}
@@ -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;
}
}