use of org.jetbrains.kotlin.types.KotlinType in project kotlin by JetBrains.
the class RangeCodegenUtil method isCharSequenceIndices.
public static boolean isCharSequenceIndices(@NotNull CallableDescriptor descriptor) {
if (!isTopLevelInPackage(descriptor, "indices", "kotlin.text"))
return false;
ReceiverParameterDescriptor extensionReceiver = descriptor.getExtensionReceiverParameter();
if (extensionReceiver == null)
return false;
KotlinType extensionReceiverType = extensionReceiver.getType();
if (!KotlinBuiltIns.isCharSequenceOrNullableCharSequence(extensionReceiverType))
return false;
return true;
}
use of org.jetbrains.kotlin.types.KotlinType in project kotlin by JetBrains.
the class ExpressionCodegen method genVarargs.
public void genVarargs(@NotNull VarargValueArgument valueArgument, @NotNull KotlinType outType) {
Type type = asmType(outType);
assert type.getSort() == Type.ARRAY;
Type elementType = correctElementType(type);
List<ValueArgument> arguments = valueArgument.getArguments();
int size = arguments.size();
boolean hasSpread = false;
for (int i = 0; i != size; ++i) {
if (arguments.get(i).getSpreadElement() != null) {
hasSpread = true;
break;
}
}
if (hasSpread) {
boolean arrayOfReferences = KotlinBuiltIns.isArray(outType);
if (size == 1) {
// Arrays.copyOf(receiverValue, newLength)
ValueArgument argument = arguments.get(0);
Type arrayType = arrayOfReferences ? Type.getType("[Ljava/lang/Object;") : Type.getType("[" + elementType.getDescriptor());
gen(argument.getArgumentExpression(), type);
v.dup();
v.arraylength();
v.invokestatic("java/util/Arrays", "copyOf", Type.getMethodDescriptor(arrayType, arrayType, Type.INT_TYPE), false);
if (arrayOfReferences) {
v.checkcast(type);
}
} else {
String owner;
String addDescriptor;
String toArrayDescriptor;
if (arrayOfReferences) {
owner = "kotlin/jvm/internal/SpreadBuilder";
addDescriptor = "(Ljava/lang/Object;)V";
toArrayDescriptor = "([Ljava/lang/Object;)[Ljava/lang/Object;";
} else {
String spreadBuilderClassName = AsmUtil.asmPrimitiveTypeToLangPrimitiveType(elementType).getTypeName().getIdentifier() + "SpreadBuilder";
owner = "kotlin/jvm/internal/" + spreadBuilderClassName;
addDescriptor = "(" + elementType.getDescriptor() + ")V";
toArrayDescriptor = "()" + type.getDescriptor();
}
v.anew(Type.getObjectType(owner));
v.dup();
v.iconst(size);
v.invokespecial(owner, "<init>", "(I)V", false);
for (int i = 0; i != size; ++i) {
v.dup();
ValueArgument argument = arguments.get(i);
if (argument.getSpreadElement() != null) {
gen(argument.getArgumentExpression(), OBJECT_TYPE);
v.invokevirtual(owner, "addSpread", "(Ljava/lang/Object;)V", false);
} else {
gen(argument.getArgumentExpression(), elementType);
v.invokevirtual(owner, "add", addDescriptor, false);
}
}
if (arrayOfReferences) {
v.dup();
v.invokevirtual(owner, "size", "()I", false);
newArrayInstruction(outType);
v.invokevirtual(owner, "toArray", toArrayDescriptor, false);
v.checkcast(type);
} else {
v.invokevirtual(owner, "toArray", toArrayDescriptor, false);
}
}
} else {
v.iconst(arguments.size());
newArrayInstruction(outType);
for (int i = 0; i != size; ++i) {
v.dup();
StackValue rightSide = gen(arguments.get(i).getArgumentExpression());
StackValue.arrayElement(elementType, StackValue.onStack(type), StackValue.constant(i, Type.INT_TYPE)).store(rightSide, v);
}
}
}
use of org.jetbrains.kotlin.types.KotlinType in project kotlin by JetBrains.
the class ExpressionCodegen method visitArrayAccessExpression.
@Override
public StackValue visitArrayAccessExpression(@NotNull KtArrayAccessExpression expression, StackValue receiver) {
KtExpression array = expression.getArrayExpression();
KotlinType type = array != null ? bindingContext.getType(array) : null;
Type arrayType = expressionType(array);
List<KtExpression> indices = expression.getIndexExpressions();
FunctionDescriptor operationDescriptor = (FunctionDescriptor) bindingContext.get(REFERENCE_TARGET, expression);
assert operationDescriptor != null;
if (arrayType.getSort() == Type.ARRAY && indices.size() == 1 && isInt(operationDescriptor.getValueParameters().get(0).getType())) {
assert type != null;
Type elementType;
if (KotlinBuiltIns.isArray(type)) {
KotlinType jetElementType = type.getArguments().get(0).getType();
elementType = boxType(asmType(jetElementType));
} else {
elementType = correctElementType(arrayType);
}
StackValue arrayValue = genLazy(array, arrayType);
StackValue index = genLazy(indices.get(0), Type.INT_TYPE);
return StackValue.arrayElement(elementType, arrayValue, index);
} else {
ResolvedCall<FunctionDescriptor> resolvedSetCall = bindingContext.get(INDEXED_LVALUE_SET, expression);
ResolvedCall<FunctionDescriptor> resolvedGetCall = bindingContext.get(INDEXED_LVALUE_GET, expression);
boolean isGetter = OperatorNameConventions.GET.equals(operationDescriptor.getName());
Callable callable = resolveToCallable(operationDescriptor, false, isGetter ? resolvedGetCall : resolvedSetCall);
Callable callableMethod = resolveToCallableMethod(operationDescriptor, false);
Type[] argumentTypes = callableMethod.getParameterTypes();
StackValue.CollectionElementReceiver collectionElementReceiver = createCollectionElementReceiver(expression, receiver, operationDescriptor, isGetter, resolvedGetCall, resolvedSetCall, callable);
Type elementType = isGetter ? callableMethod.getReturnType() : ArrayUtil.getLastElement(argumentTypes);
return StackValue.collectionElement(collectionElementReceiver, elementType, resolvedGetCall, resolvedSetCall, this);
}
}
use of org.jetbrains.kotlin.types.KotlinType in project kotlin by JetBrains.
the class ExpressionCodegen method pushClosureOnStack.
public void pushClosureOnStack(@NotNull ClassDescriptor classDescriptor, boolean putThis, @NotNull CallGenerator callGenerator, @Nullable StackValue functionReferenceReceiver) {
CalculatedClosure closure = bindingContext.get(CLOSURE, classDescriptor);
if (closure == null)
return;
int paramIndex = 0;
if (putThis) {
ClassDescriptor captureThis = closure.getCaptureThis();
if (captureThis != null) {
StackValue thisOrOuter = generateThisOrOuter(captureThis, false);
assert !isPrimitive(thisOrOuter.type) : "This or outer should be non primitive: " + thisOrOuter.type;
callGenerator.putCapturedValueOnStack(thisOrOuter, thisOrOuter.type, paramIndex++);
}
}
KotlinType captureReceiver = closure.getCaptureReceiverType();
if (captureReceiver != null) {
StackValue capturedReceiver = functionReferenceReceiver != null ? functionReferenceReceiver : generateExtensionReceiver(unwrapOriginalReceiverOwnerForSuspendFunction(context));
callGenerator.putCapturedValueOnStack(capturedReceiver, capturedReceiver.type, paramIndex++);
}
for (Map.Entry<DeclarationDescriptor, EnclosedValueDescriptor> entry : closure.getCaptureVariables().entrySet()) {
Type sharedVarType = typeMapper.getSharedVarType(entry.getKey());
if (sharedVarType == null) {
sharedVarType = typeMapper.mapType((VariableDescriptor) entry.getKey());
}
StackValue capturedVar = lookupOuterValue(entry.getValue());
callGenerator.putCapturedValueOnStack(capturedVar, sharedVarType, paramIndex++);
}
ClassDescriptor superClass = DescriptorUtilsKt.getSuperClassNotAny(classDescriptor);
if (superClass != null) {
pushClosureOnStack(superClass, putThis && closure.getCaptureThis() == null, callGenerator, /* functionReferenceReceiver = */
null);
}
if (closure.isSuspend()) {
// resultContinuation
if (closure.isSuspendLambda()) {
v.aconst(null);
} else {
assert context.getFunctionDescriptor().isSuspend() : "Coroutines closure must be created only inside suspend functions";
ValueParameterDescriptor continuationParameter = CollectionsKt.last(context.getFunctionDescriptor().getValueParameters());
StackValue continuationValue = findLocalOrCapturedValue(continuationParameter);
assert continuationValue != null : "Couldn't find a value for continuation parameter of " + context.getFunctionDescriptor();
callGenerator.putCapturedValueOnStack(continuationValue, continuationValue.type, paramIndex++);
}
}
}
use of org.jetbrains.kotlin.types.KotlinType in project kotlin by JetBrains.
the class ExpressionCodegen method visitDestructuringDeclaration.
@Override
public StackValue visitDestructuringDeclaration(@NotNull KtDestructuringDeclaration multiDeclaration, StackValue receiver) {
KtExpression initializer = multiDeclaration.getInitializer();
if (initializer == null)
return StackValue.none();
KotlinType initializerType = bindingContext.getType(initializer);
assert initializerType != null;
Type initializerAsmType = asmType(initializerType);
TransientReceiver initializerAsReceiver = new TransientReceiver(initializerType);
int tempVarIndex = myFrameMap.enterTemp(initializerAsmType);
gen(initializer, initializerAsmType);
v.store(tempVarIndex, initializerAsmType);
StackValue.Local local = StackValue.local(tempVarIndex, initializerAsmType);
initializeDestructuringDeclarationVariables(multiDeclaration, initializerAsReceiver, local);
if (initializerAsmType.getSort() == Type.OBJECT || initializerAsmType.getSort() == Type.ARRAY) {
v.aconst(null);
v.store(tempVarIndex, initializerAsmType);
}
myFrameMap.leaveTemp(initializerAsmType);
return StackValue.none();
}
Aggregations