Store refactoring
#KT-1213 Fixed
This commit is contained in:
@@ -20,6 +20,8 @@ import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import kotlin.Function1;
|
||||
import kotlin.Unit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.codegen.binding.CalculatedClosure;
|
||||
@@ -431,11 +433,16 @@ public class AsmUtil {
|
||||
v.invokevirtual("java/lang/StringBuilder", "append", "(" + type.getDescriptor() + ")Ljava/lang/StringBuilder;", false);
|
||||
}
|
||||
|
||||
public static StackValue genToString(InstructionAdapter v, StackValue receiver, Type receiverType) {
|
||||
Type type = stringValueOfType(receiverType);
|
||||
receiver.put(type, v);
|
||||
v.invokestatic("java/lang/String", "valueOf", "(" + type.getDescriptor() + ")Ljava/lang/String;", false);
|
||||
return StackValue.onStack(JAVA_STRING_TYPE);
|
||||
public static StackValue genToString(final InstructionAdapter v, final StackValue receiver, final Type receiverType) {
|
||||
return StackValue.operation(JAVA_STRING_TYPE, new Function1<InstructionAdapter, Unit>() {
|
||||
@Override
|
||||
public Unit invoke(InstructionAdapter adapter) {
|
||||
Type type = stringValueOfType(receiverType);
|
||||
receiver.put(type, v);
|
||||
v.invokestatic("java/lang/String", "valueOf", "(" + type.getDescriptor() + ")Ljava/lang/String;", false);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static void genHashCode(MethodVisitor mv, InstructionAdapter iv, Type type) {
|
||||
@@ -489,26 +496,33 @@ public class AsmUtil {
|
||||
|
||||
@NotNull
|
||||
public static StackValue genEqualsForExpressionsOnStack(
|
||||
@NotNull InstructionAdapter v,
|
||||
@NotNull IElementType opToken,
|
||||
@NotNull Type leftType,
|
||||
@NotNull Type rightType
|
||||
final @NotNull IElementType opToken,
|
||||
final @NotNull StackValue left,
|
||||
final @NotNull StackValue right
|
||||
) {
|
||||
final Type leftType = left.type;
|
||||
final Type rightType = right.type;
|
||||
if (isPrimitive(leftType) && leftType == rightType) {
|
||||
return StackValue.cmp(opToken, leftType);
|
||||
return StackValue.cmp(opToken, leftType, left, right);
|
||||
}
|
||||
|
||||
if (opToken == JetTokens.EQEQEQ || opToken == JetTokens.EXCLEQEQEQ) {
|
||||
return StackValue.cmp(opToken, leftType);
|
||||
return StackValue.cmp(opToken, leftType, left, right);
|
||||
}
|
||||
|
||||
v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "areEqual", "(Ljava/lang/Object;Ljava/lang/Object;)Z", false);
|
||||
return StackValue.operation(Type.BOOLEAN_TYPE, new Function1<InstructionAdapter, Unit>() {
|
||||
@Override
|
||||
public Unit invoke(InstructionAdapter v) {
|
||||
left.put(leftType, v);
|
||||
right.put(rightType, v);
|
||||
v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "areEqual", "(Ljava/lang/Object;Ljava/lang/Object;)Z", false);
|
||||
|
||||
if (opToken == JetTokens.EXCLEQ || opToken == JetTokens.EXCLEQEQEQ) {
|
||||
genInvertBoolean(v);
|
||||
}
|
||||
|
||||
return StackValue.onStack(Type.BOOLEAN_TYPE);
|
||||
if (opToken == JetTokens.EXCLEQ || opToken == JetTokens.EXCLEQEQEQ) {
|
||||
genInvertBoolean(v);
|
||||
}
|
||||
return Unit.INSTANCE$;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void genIncrement(Type expectedType, int myDelta, InstructionAdapter v) {
|
||||
@@ -639,7 +653,7 @@ public class AsmUtil {
|
||||
if (!state.isCallAssertionsEnabled()) return stackValue;
|
||||
if (approximationInfo == null || !TypesPackage.assertNotNull(approximationInfo)) return stackValue;
|
||||
|
||||
return new StackValue(stackValue.type) {
|
||||
return new StackValue.StackValueWithoutReceiver(stackValue.type) {
|
||||
|
||||
@Override
|
||||
public void put(Type type, InstructionAdapter v) {
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
||||
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodParameterKind;
|
||||
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodParameterSignature;
|
||||
import org.jetbrains.jet.lang.resolve.java.jvmSignature.JvmMethodSignature;
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method;
|
||||
@@ -170,4 +171,8 @@ public class CallableMethod implements Callable {
|
||||
public String toString() {
|
||||
return Printer.OPCODES[invokeOpcode] + " " + owner.getInternalName() + "." + signature;
|
||||
}
|
||||
|
||||
public boolean isStaticCall() {
|
||||
return getInvokeOpcode() == Opcodes.INVOKESTATIC;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ package org.jetbrains.jet.codegen;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import kotlin.Function1;
|
||||
import kotlin.Unit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.codegen.binding.CalculatedClosure;
|
||||
@@ -202,18 +204,23 @@ public class ClosureCodegen extends ParentCodegenAware {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public StackValue putInstanceOnStack(@NotNull InstructionAdapter v, @NotNull ExpressionCodegen codegen) {
|
||||
if (isConst(closure)) {
|
||||
v.getstatic(asmType.getInternalName(), JvmAbi.INSTANCE_FIELD, asmType.getDescriptor());
|
||||
}
|
||||
else {
|
||||
v.anew(asmType);
|
||||
v.dup();
|
||||
public StackValue putInstanceOnStack(@NotNull InstructionAdapter v, @NotNull final ExpressionCodegen codegen) {
|
||||
return StackValue.operation(asmType, new Function1<InstructionAdapter, Unit>() {
|
||||
@Override
|
||||
public Unit invoke(InstructionAdapter v) {
|
||||
if (isConst(closure)) {
|
||||
v.getstatic(asmType.getInternalName(), JvmAbi.INSTANCE_FIELD, asmType.getDescriptor());
|
||||
}
|
||||
else {
|
||||
v.anew(asmType);
|
||||
v.dup();
|
||||
|
||||
codegen.pushClosureOnStack(classDescriptor, true, codegen.defaultCallGenerator);
|
||||
v.invokespecial(asmType.getInternalName(), "<init>", constructor.getDescriptor(), false);
|
||||
}
|
||||
return StackValue.onStack(asmType);
|
||||
codegen.pushClosureOnStack(classDescriptor, true, codegen.defaultCallGenerator);
|
||||
v.invokespecial(asmType.getInternalName(), "<init>", constructor.getDescriptor(), false);
|
||||
}
|
||||
return Unit.INSTANCE$;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -579,7 +579,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
iv.ifne(ne);
|
||||
}
|
||||
else {
|
||||
StackValue value = genEqualsForExpressionsOnStack(iv, JetTokens.EQEQ, asmType, asmType);
|
||||
StackValue value = genEqualsForExpressionsOnStack(JetTokens.EQEQ, StackValue.onStack(asmType), StackValue.onStack(asmType));
|
||||
value.put(Type.BOOLEAN_TYPE, iv);
|
||||
iv.ifeq(ne);
|
||||
}
|
||||
@@ -802,7 +802,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
assert property != null : "Copy function doesn't correspond to any property: " + function;
|
||||
codegen.v.load(0, thisDescriptorType);
|
||||
Type propertyType = typeMapper.mapType(property);
|
||||
codegen.intermediateValueForProperty(property, false, null).put(propertyType, codegen.v);
|
||||
codegen.intermediateValueForProperty(property, false, null, StackValue.none())
|
||||
.putNoReceiver(propertyType, codegen.v);
|
||||
}
|
||||
},
|
||||
null
|
||||
@@ -898,7 +899,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
|
||||
boolean forceField = AsmUtil.isPropertyWithBackingFieldInOuterClass(original) &&
|
||||
!isClassObject(bridge.getContainingDeclaration());
|
||||
StackValue property = codegen.intermediateValueForProperty(original, forceField, null, MethodKind.SYNTHETIC_ACCESSOR);
|
||||
StackValue property = codegen.intermediateValueForProperty(original, forceField, null, MethodKind.SYNTHETIC_ACCESSOR, StackValue.none());
|
||||
|
||||
InstructionAdapter iv = codegen.v;
|
||||
|
||||
@@ -1055,18 +1056,16 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
if (classObjectIndex == -1) {
|
||||
classObjectIndex = frameMap.enter(classObjectDescriptor, OBJECT_TYPE);
|
||||
StackValue classObject = StackValue.singleton(classObjectDescriptor, typeMapper);
|
||||
classObject.put(classObject.type, codegen.v);
|
||||
StackValue.local(classObjectIndex, classObject.type).store(classObject.type, codegen.v);
|
||||
StackValue.local(classObjectIndex, classObject.type).store(classObject, codegen.v);
|
||||
}
|
||||
return classObjectIndex;
|
||||
}
|
||||
|
||||
private void copyFieldFromClassObject(PropertyDescriptor propertyDescriptor) {
|
||||
ExpressionCodegen codegen = createOrGetClInitCodegen();
|
||||
StackValue property = codegen.intermediateValueForProperty(propertyDescriptor, false, null);
|
||||
property.put(property.type, codegen.v);
|
||||
StackValue.Field field = StackValue.field(property.type, classAsmType, propertyDescriptor.getName().asString(), true);
|
||||
field.store(field.type, codegen.v);
|
||||
StackValue property = codegen.intermediateValueForProperty(propertyDescriptor, false, null, StackValue.none());
|
||||
StackValue.Field field = StackValue.field(property.type, classAsmType, propertyDescriptor.getName().asString(), true, StackValue.none());
|
||||
field.store(property, codegen.v);
|
||||
}
|
||||
|
||||
private void generateClassObjectInitializer(@NotNull ClassDescriptor classObject) {
|
||||
@@ -1136,8 +1135,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
if (isObject(descriptor)) {
|
||||
iv.load(0, classAsmType);
|
||||
StackValue.singleton(descriptor, typeMapper).store(classAsmType, iv);
|
||||
StackValue.singleton(descriptor, typeMapper).store(StackValue.local(0, classAsmType), iv);
|
||||
}
|
||||
|
||||
for (JetDelegationSpecifier specifier : myClass.getDelegationSpecifiers()) {
|
||||
@@ -1210,7 +1208,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
@NotNull
|
||||
public StackValue getStackValue() {
|
||||
return StackValue.field(type, classAsmType, name, false);
|
||||
return StackValue.field(type, classAsmType, name, false, StackValue.none());
|
||||
}
|
||||
}
|
||||
private final Map<JetDelegatorByExpressionSpecifier, Field> fields = new HashMap<JetDelegatorByExpressionSpecifier, Field>();
|
||||
@@ -1271,9 +1269,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
DelegationFieldsInfo.Field fieldInfo = fieldsInfo.getInfo(specifier);
|
||||
if (fieldInfo.generateField) {
|
||||
iv.load(0, classAsmType);
|
||||
codegen.genToJVMStack(expression);
|
||||
|
||||
fieldInfo.getStackValue().store(fieldInfo.type, iv);
|
||||
StackValue rightSide = codegen.genLazy(expression, codegen.expressionType(expression));
|
||||
fieldInfo.getStackValue().store(rightSide, iv);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1304,7 +1301,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
else return;
|
||||
|
||||
constructorContext.lookupInContext(toLookup, null, state, true);
|
||||
constructorContext.lookupInContext(toLookup, StackValue.local(0, OBJECT_TYPE), state, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -238,18 +238,14 @@ public abstract class MemberCodegen<T extends JetElement/* TODO: & JetDeclaratio
|
||||
|
||||
JetType jetType = getPropertyOrDelegateType(property, propertyDescriptor);
|
||||
|
||||
StackValue.Property propValue = codegen.intermediateValueForProperty(propertyDescriptor, true, null, MethodKind.INITIALIZER);
|
||||
|
||||
if (!propValue.isStatic) {
|
||||
codegen.v.load(0, OBJECT_TYPE);
|
||||
}
|
||||
StackValue.Property propValue = codegen.intermediateValueForProperty(propertyDescriptor, true, null, MethodKind.INITIALIZER, StackValue.local(0, OBJECT_TYPE));
|
||||
|
||||
Type type = codegen.expressionType(initializer);
|
||||
if (jetType.isNullable()) {
|
||||
type = boxType(type);
|
||||
}
|
||||
codegen.gen(initializer, type);
|
||||
propValue.store(type, codegen.v);
|
||||
|
||||
propValue.store(codegen.genLazy(initializer, type), codegen.v);
|
||||
|
||||
ResolvedCall<FunctionDescriptor> pdResolvedCall =
|
||||
bindingContext.get(BindingContext.DELEGATED_PROPERTY_PD_RESOLVED_CALL, propertyDescriptor);
|
||||
|
||||
@@ -380,14 +380,7 @@ public class PropertyCodegen {
|
||||
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
|
||||
InstructionAdapter v = codegen.v;
|
||||
PropertyDescriptor propertyDescriptor = callableDescriptor.getCorrespondingProperty();
|
||||
|
||||
int paramCode = 0;
|
||||
if (codegen.getContext().getContextKind() != OwnerKind.PACKAGE) {
|
||||
v.load(0, OBJECT_TYPE);
|
||||
paramCode = 1;
|
||||
}
|
||||
|
||||
StackValue property = codegen.intermediateValueForProperty(propertyDescriptor, true, null);
|
||||
StackValue property = codegen.intermediateValueForProperty(propertyDescriptor, true, null, StackValue.local(0, OBJECT_TYPE));
|
||||
|
||||
if (callableDescriptor instanceof PropertyGetterDescriptor) {
|
||||
Type type = signature.getReturnType();
|
||||
@@ -396,12 +389,13 @@ public class PropertyCodegen {
|
||||
}
|
||||
else if (callableDescriptor instanceof PropertySetterDescriptor) {
|
||||
ReceiverParameterDescriptor receiverParameter = propertyDescriptor.getExtensionReceiverParameter();
|
||||
int paramCode = codegen.getContext().getContextKind() != OwnerKind.PACKAGE ? 1 : 0;
|
||||
if (receiverParameter != null) {
|
||||
paramCode += codegen.typeMapper.mapType(receiverParameter.getType()).getSize();
|
||||
}
|
||||
Type type = codegen.typeMapper.mapType(propertyDescriptor);
|
||||
v.load(paramCode, type);
|
||||
property.store(type, v);
|
||||
StackValue.Local value = StackValue.local(paramCode, type);
|
||||
property.store(value, codegen.v);
|
||||
v.visitInsn(RETURN);
|
||||
} else {
|
||||
throw new IllegalStateException("Unknown property accessor: " + callableDescriptor);
|
||||
@@ -417,10 +411,6 @@ public class PropertyCodegen {
|
||||
final int indexInPropertyMetadataArray,
|
||||
int propertyMetadataArgumentIndex
|
||||
) {
|
||||
if (codegen.getContext().getContextKind() != OwnerKind.PACKAGE) {
|
||||
codegen.v.load(0, OBJECT_TYPE);
|
||||
}
|
||||
|
||||
CodegenContext<? extends ClassOrPackageFragmentDescriptor> ownerContext = codegen.getContext().getClassOrPackageParentContext();
|
||||
final Type owner;
|
||||
if (ownerContext instanceof ClassContext) {
|
||||
@@ -435,17 +425,18 @@ public class PropertyCodegen {
|
||||
|
||||
codegen.tempVariables.put(
|
||||
resolvedCall.getCall().getValueArguments().get(propertyMetadataArgumentIndex).asElement(),
|
||||
new StackValue(PROPERTY_METADATA_TYPE) {
|
||||
new StackValue.StackValueWithoutReceiver(PROPERTY_METADATA_TYPE) {
|
||||
@Override
|
||||
public void put(Type type, InstructionAdapter v) {
|
||||
v.getstatic(owner.getInternalName(), JvmAbi.PROPERTY_METADATA_ARRAY_NAME, "[" + PROPERTY_METADATA_TYPE);
|
||||
v.iconst(indexInPropertyMetadataArray);
|
||||
StackValue.arrayElement(PROPERTY_METADATA_TYPE).put(type, v);
|
||||
public void put(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
Field array = StackValue
|
||||
.field(Type.getType("[" + PROPERTY_METADATA_TYPE), owner, JvmAbi.PROPERTY_METADATA_ARRAY_NAME, true,
|
||||
StackValue.none());
|
||||
StackValue.arrayElement(PROPERTY_METADATA_TYPE, array, StackValue.constant(indexInPropertyMetadataArray, Type.INT_TYPE)).put(type, v);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
StackValue delegatedProperty = codegen.intermediateValueForProperty(propertyDescriptor, true, null);
|
||||
StackValue delegatedProperty = codegen.intermediateValueForProperty(propertyDescriptor, true, null, StackValue.local(0, OBJECT_TYPE));
|
||||
return codegen.invokeFunction(resolvedCall, delegatedProperty);
|
||||
}
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ public class SamWrapperCodegen {
|
||||
|
||||
FunctionDescriptor invokeFunction = functionJetType.getMemberScope()
|
||||
.getFunctions(Name.identifier("invoke")).iterator().next().getOriginal();
|
||||
StackValue functionField = StackValue.field(functionType, ownerType, FUNCTION_FIELD_NAME, false);
|
||||
StackValue functionField = StackValue.field(functionType, ownerType, FUNCTION_FIELD_NAME, false, StackValue.none());
|
||||
codegen.genDelegate(erasedInterfaceFunction, invokeFunction, functionField);
|
||||
|
||||
// generate sam bridges
|
||||
|
||||
@@ -194,8 +194,11 @@ public class ScriptCodegen extends MemberCodegen<JetScript> {
|
||||
StackValue stackValue =
|
||||
new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, methodContext, state, this).gen(scriptDeclaration.getBlockExpression());
|
||||
if (stackValue.type != Type.VOID_TYPE) {
|
||||
StackValue.Field resultValue = StackValue
|
||||
.field(blockType, classType, ScriptDescriptor.LAST_EXPRESSION_VALUE_FIELD_NAME, false, StackValue.local(0, classType));
|
||||
resultValue.store(stackValue, iv);
|
||||
} else {
|
||||
stackValue.put(blockType, iv);
|
||||
iv.putfield(classType.getInternalName(), ScriptDescriptor.LAST_EXPRESSION_VALUE_FIELD_NAME, blockType.getDescriptor());
|
||||
}
|
||||
|
||||
iv.areturn(Type.VOID_TYPE);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright 2010-2014 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
|
||||
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.jet.codegen.StackValue.StackValueWithReceiver
|
||||
import org.jetbrains.jet.codegen.StackValue.StackValueWithoutReceiver
|
||||
import org.jetbrains.jet.codegen.StackValue.StackValueWithSimpleReceiver
|
||||
|
||||
public fun castValue(value: StackValue, castType: Type): StackValue {
|
||||
return if (value is StackValueWithReceiver) CastValueWithReceiver(value, castType) else CastValue(value, castType)
|
||||
}
|
||||
|
||||
class CastValueWithReceiver(val value: StackValueWithReceiver, val castType: Type) : StackValueWithSimpleReceiver(castType, !value.hasReceiver(true), !value.hasReceiver(false), value.receiver), StackValueI by value {
|
||||
|
||||
override fun putReceiver(v: InstructionAdapter, isRead: Boolean) {
|
||||
value.putReceiver(v, isRead )
|
||||
}
|
||||
|
||||
override fun putNoReceiver(type: Type, v: InstructionAdapter) {
|
||||
value.putNoReceiver(type, v)
|
||||
}
|
||||
|
||||
override fun hasReceiver(isRead: Boolean): Boolean {
|
||||
return value.hasReceiver(isRead)
|
||||
}
|
||||
}
|
||||
|
||||
class CastValue(val value: StackValue, val castType: Type) : StackValueWithoutReceiver(castType), StackValueI by value {
|
||||
|
||||
}
|
||||
|
||||
class FunctionCallStackValue(val resultType: Type, val lambda: (v: InstructionAdapter)-> Unit) : StackValueWithoutReceiver(resultType) {
|
||||
|
||||
override fun put(type: Type, v: InstructionAdapter) {
|
||||
lambda(v)
|
||||
coerceTo(type, v)
|
||||
}
|
||||
|
||||
override fun store(topOfStackType: Type, v: InstructionAdapter) {
|
||||
throw UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
public class StackValueWithLeaveTask(val stackValue: StackValue, val leaveTasks: StackValueWithLeaveTask.()-> Unit) : StackValueWithReceiver(stackValue.type, if (stackValue is StackValueWithReceiver) stackValue.receiver else StackValue.none()), StackValueI by stackValue {
|
||||
|
||||
override fun put(type: Type, v: InstructionAdapter) {
|
||||
stackValue.put(type, v)
|
||||
leaveTasks()
|
||||
}
|
||||
|
||||
override fun condJump(label: Label, jumpIfFalse: Boolean, v: InstructionAdapter ) {
|
||||
stackValue.condJump(label, jumpIfFalse, v)
|
||||
leaveTasks()
|
||||
}
|
||||
|
||||
override fun putReceiver(v: InstructionAdapter, isRead: Boolean) {
|
||||
if (stackValue is StackValueWithReceiver) {
|
||||
stackValue.putReceiver(v, isRead)
|
||||
}
|
||||
}
|
||||
|
||||
override fun putNoReceiver(type: Type, v: InstructionAdapter) {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
override fun hasReceiver(isRead: Boolean): Boolean {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
override fun store(topOfStackType: Type, v: InstructionAdapter) {
|
||||
throw UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
class OperationStackValue(val resultType: Type, val lambda: (v: InstructionAdapter)-> Unit) : StackValueWithoutReceiver(resultType) {
|
||||
|
||||
override fun put(type: Type, v: InstructionAdapter) {
|
||||
lambda(v)
|
||||
coerceTo(type, v)
|
||||
}
|
||||
|
||||
override fun store(topOfStackType: Type, v: InstructionAdapter) {
|
||||
throw UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2010-2014 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;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.org.objectweb.asm.Label;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
|
||||
public interface StackValueI {
|
||||
|
||||
void moveToTopOfStack(@NotNull Type type, @NotNull InstructionAdapter v, int depth);
|
||||
|
||||
void put(@NotNull Type type, @NotNull InstructionAdapter v);
|
||||
|
||||
void store(@NotNull Type topOfStackType, @NotNull InstructionAdapter v);
|
||||
|
||||
void store(@NotNull StackValue value, @NotNull InstructionAdapter v);
|
||||
|
||||
void store(@NotNull StackValue value, @NotNull InstructionAdapter v, boolean skipReceiver);
|
||||
|
||||
void condJump(@NotNull Label label, boolean jumpIfFalse, @NotNull InstructionAdapter v);
|
||||
|
||||
void coerceTo(@NotNull Type toType, @NotNull InstructionAdapter v);
|
||||
|
||||
void coerceFrom(@NotNull Type topOfStackType, @NotNull InstructionAdapter v);
|
||||
|
||||
void putAsBoolean(InstructionAdapter v);
|
||||
|
||||
void dup(@NotNull InstructionAdapter v, boolean withReceiver);
|
||||
}
|
||||
@@ -26,6 +26,7 @@ import org.jetbrains.jet.codegen.state.JetTypeMapper;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.storage.LockBasedStorageManager;
|
||||
import org.jetbrains.jet.storage.NullableLazyValue;
|
||||
@@ -52,7 +53,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
|
||||
private Map<DeclarationDescriptor, DeclarationDescriptor> accessors;
|
||||
private Map<DeclarationDescriptor, CodegenContext> childContexts;
|
||||
private NullableLazyValue<StackValue> lazyOuterExpression;
|
||||
private NullableLazyValue<StackValue.Field> lazyOuterExpression;
|
||||
|
||||
public CodegenContext(
|
||||
@NotNull T contextDescriptor,
|
||||
@@ -128,7 +129,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
}
|
||||
closure.setCaptureThis();
|
||||
}
|
||||
return prefix != null ? StackValue.composed(prefix, lazyOuterExpression.invoke()) : lazyOuterExpression.invoke();
|
||||
return StackValue.changeReceiverForFieldAndSharedVar(lazyOuterExpression.invoke(), prefix);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -260,15 +261,15 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
public abstract boolean isStatic();
|
||||
|
||||
protected void initOuterExpression(@NotNull final JetTypeMapper typeMapper, @NotNull final ClassDescriptor classDescriptor) {
|
||||
lazyOuterExpression = LockBasedStorageManager.NO_LOCKS.createNullableLazyValue(new Function0<StackValue>() {
|
||||
lazyOuterExpression = LockBasedStorageManager.NO_LOCKS.createNullableLazyValue(new Function0<StackValue.Field>() {
|
||||
@Override
|
||||
public StackValue invoke() {
|
||||
public StackValue.Field invoke() {
|
||||
ClassDescriptor enclosingClass = getEnclosingClass();
|
||||
if (enclosingClass == null) return null;
|
||||
|
||||
return canHaveOuter(typeMapper.getBindingContext(), classDescriptor)
|
||||
? StackValue.field(typeMapper.mapType(enclosingClass), typeMapper.mapType(classDescriptor),
|
||||
CAPTURED_THIS_FIELD, false)
|
||||
CAPTURED_THIS_FIELD, false, StackValue.local(0, AsmTypeConstants.OBJECT_TYPE))
|
||||
: null;
|
||||
}
|
||||
});
|
||||
@@ -279,25 +280,25 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
if (closure != null) {
|
||||
EnclosedValueDescriptor answer = closure.getCaptureVariables().get(d);
|
||||
if (answer != null) {
|
||||
StackValue innerValue = answer.getInnerValue();
|
||||
return result == null ? innerValue : StackValue.composed(result, innerValue);
|
||||
return StackValue.changeReceiverForFieldAndSharedVar(answer.getInnerValue(), result);
|
||||
}
|
||||
|
||||
for (LocalLookup.LocalLookupCase aCase : LocalLookup.LocalLookupCase.values()) {
|
||||
if (aCase.isCase(d)) {
|
||||
Type classType = state.getTypeMapper().mapType(getThisDescriptor());
|
||||
StackValue innerValue = aCase.innerValue(d, enclosingLocalLookup, state, closure, classType);
|
||||
StackValue.StackValueWithSimpleReceiver innerValue = aCase.innerValue(d, enclosingLocalLookup, state, closure, classType);
|
||||
if (innerValue == null) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
return result == null ? innerValue : composedOrStatic(result, innerValue);
|
||||
//return result == null ? innerValue : composedOrStatic(result, innerValue);
|
||||
return StackValue.changeReceiverForFieldAndSharedVar(innerValue, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
myOuter = getOuterExpression(null, ignoreNoOuter, false);
|
||||
result = result == null || myOuter == null ? myOuter : StackValue.composed(result, myOuter);
|
||||
myOuter = getOuterExpression(result, ignoreNoOuter, false);
|
||||
result = myOuter;
|
||||
}
|
||||
|
||||
StackValue resultValue;
|
||||
@@ -441,15 +442,15 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
return childContexts == null ? null : childContexts.get(child);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static StackValue composedOrStatic(@NotNull StackValue prefix, @NotNull StackValue suffix) {
|
||||
if (isStaticField(suffix)) {
|
||||
return suffix;
|
||||
}
|
||||
return StackValue.composed(prefix, suffix);
|
||||
}
|
||||
//@NotNull
|
||||
//private static StackValue composedOrStatic(@NotNull StackValue prefix, @NotNull StackValue suffix) {
|
||||
// if (isStaticField(suffix)) {
|
||||
// return suffix;
|
||||
// }
|
||||
// return StackValue.composed(prefix, suffix);
|
||||
//}
|
||||
|
||||
private static boolean isStaticField(@NotNull StackValue value) {
|
||||
return value instanceof StackValue.Field && ((StackValue.Field) value).isStatic;
|
||||
return value instanceof StackValue.Field && ((StackValue.Field) value).isStaticPut;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,13 +26,13 @@ import org.jetbrains.org.objectweb.asm.Type;
|
||||
public final class EnclosedValueDescriptor {
|
||||
private final String fieldName;
|
||||
private final DeclarationDescriptor descriptor;
|
||||
private final StackValue innerValue;
|
||||
private final StackValue.StackValueWithSimpleReceiver innerValue;
|
||||
private final Type type;
|
||||
|
||||
public EnclosedValueDescriptor(
|
||||
@NotNull String fieldName,
|
||||
@Nullable DeclarationDescriptor descriptor,
|
||||
@Nullable StackValue innerValue,
|
||||
@NotNull StackValue.StackValueWithSimpleReceiver innerValue,
|
||||
@NotNull Type type
|
||||
) {
|
||||
this.fieldName = fieldName;
|
||||
@@ -51,8 +51,8 @@ public final class EnclosedValueDescriptor {
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public StackValue getInnerValue() {
|
||||
@NotNull
|
||||
public StackValue.StackValueWithSimpleReceiver getInnerValue() {
|
||||
return innerValue;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.jetbrains.jet.codegen.binding.MutableClosure;
|
||||
import org.jetbrains.jet.codegen.state.GenerationState;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
@@ -42,7 +43,7 @@ public interface LocalLookup {
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackValue innerValue(
|
||||
public StackValue.StackValueWithSimpleReceiver innerValue(
|
||||
DeclarationDescriptor d,
|
||||
LocalLookup localLookup,
|
||||
GenerationState state,
|
||||
@@ -59,9 +60,10 @@ public interface LocalLookup {
|
||||
Type type = sharedVarType != null ? sharedVarType : localType;
|
||||
|
||||
String fieldName = "$" + vd.getName();
|
||||
StackValue innerValue = sharedVarType != null
|
||||
? StackValue.fieldForSharedVar(localType, classType, fieldName)
|
||||
: StackValue.field(type, classType, fieldName, false);
|
||||
StackValue.Local thiz = StackValue.local(0, AsmTypeConstants.OBJECT_TYPE);
|
||||
StackValue.StackValueWithSimpleReceiver innerValue = sharedVarType != null
|
||||
? StackValue.fieldForSharedVar(localType, classType, fieldName, thiz)
|
||||
: StackValue.field(type, classType, fieldName, false, thiz);
|
||||
|
||||
closure.recordField(fieldName, type);
|
||||
closure.captureVariable(new EnclosedValueDescriptor(fieldName, d, innerValue, type));
|
||||
@@ -77,7 +79,7 @@ public interface LocalLookup {
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackValue innerValue(
|
||||
public StackValue.StackValueWithSimpleReceiver innerValue(
|
||||
DeclarationDescriptor d,
|
||||
LocalLookup localLookup,
|
||||
GenerationState state,
|
||||
@@ -96,11 +98,11 @@ public interface LocalLookup {
|
||||
if (localFunClosure != null && JvmCodegenUtil.isConst(localFunClosure)) {
|
||||
// This is an optimization: we can obtain an instance of a const closure simply by GETSTATIC ...$instance
|
||||
// (instead of passing this instance to the constructor and storing as a field)
|
||||
return StackValue.field(localType, localType, JvmAbi.INSTANCE_FIELD, true);
|
||||
return StackValue.field(localType, localType, JvmAbi.INSTANCE_FIELD, true, StackValue.local(0, AsmTypeConstants.OBJECT_TYPE));
|
||||
}
|
||||
|
||||
String fieldName = "$" + vd.getName();
|
||||
StackValue innerValue = StackValue.field(localType, classType, fieldName, false);
|
||||
StackValue.StackValueWithSimpleReceiver innerValue = StackValue.field(localType, classType, fieldName, false, StackValue.local(0, AsmTypeConstants.OBJECT_TYPE));
|
||||
|
||||
closure.recordField(fieldName, localType);
|
||||
closure.captureVariable(new EnclosedValueDescriptor(fieldName, d, innerValue, localType));
|
||||
@@ -116,7 +118,7 @@ public interface LocalLookup {
|
||||
}
|
||||
|
||||
@Override
|
||||
public StackValue innerValue(
|
||||
public StackValue.StackValueWithSimpleReceiver innerValue(
|
||||
DeclarationDescriptor d,
|
||||
LocalLookup enclosingLocalLookup,
|
||||
GenerationState state,
|
||||
@@ -129,7 +131,7 @@ public interface LocalLookup {
|
||||
|
||||
JetType receiverType = closure.getEnclosingReceiverDescriptor().getType();
|
||||
Type type = state.getTypeMapper().mapType(receiverType);
|
||||
StackValue innerValue = StackValue.field(type, classType, CAPTURED_RECEIVER_FIELD, false);
|
||||
StackValue.StackValueWithSimpleReceiver innerValue = StackValue.field(type, classType, CAPTURED_RECEIVER_FIELD, false, StackValue.local(0, AsmTypeConstants.OBJECT_TYPE));
|
||||
closure.setCaptureReceiver();
|
||||
|
||||
return innerValue;
|
||||
@@ -145,7 +147,7 @@ public interface LocalLookup {
|
||||
|
||||
public abstract boolean isCase(DeclarationDescriptor d);
|
||||
|
||||
public abstract StackValue innerValue(
|
||||
public abstract StackValue.StackValueWithSimpleReceiver innerValue(
|
||||
DeclarationDescriptor d,
|
||||
LocalLookup localLookup,
|
||||
GenerationState state,
|
||||
|
||||
@@ -116,14 +116,4 @@ public class MethodContext extends CodegenContext<CallableMemberDescriptor> {
|
||||
return isInliningLambda;
|
||||
}
|
||||
|
||||
public boolean isSpecialStackValue(StackValue stackValue) {
|
||||
if (isInliningLambda && stackValue instanceof StackValue.Composed) {
|
||||
StackValue prefix = ((StackValue.Composed) stackValue).prefix;
|
||||
StackValue suffix = ((StackValue.Composed) stackValue).suffix;
|
||||
if (prefix instanceof StackValue.Local && ((StackValue.Local) prefix).index == 0) {
|
||||
return suffix instanceof StackValue.Field;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+10
-10
@@ -250,11 +250,11 @@ public class AnonymousObjectTransformer {
|
||||
|
||||
if (fake.getLambda() != null) {
|
||||
//set remap value to skip this fake (captured with lambda already skipped)
|
||||
StackValue composed = StackValue.composed(StackValue.local(0, oldObjectType),
|
||||
StackValue.field(fake.getType(),
|
||||
oldObjectType,
|
||||
fake.getNewFieldName(), false)
|
||||
);
|
||||
StackValue composed = StackValue.field(fake.getType(),
|
||||
oldObjectType,
|
||||
fake.getNewFieldName(),
|
||||
false,
|
||||
StackValue.local(0, oldObjectType));
|
||||
fake.setRemapValue(composed);
|
||||
}
|
||||
}
|
||||
@@ -393,11 +393,11 @@ public class AnonymousObjectTransformer {
|
||||
for (LambdaInfo info : capturedLambdas) {
|
||||
for (CapturedParamDesc desc : info.getCapturedVars()) {
|
||||
CapturedParamInfo recapturedParamInfo = capturedParamBuilder.addCapturedParam(desc, getNewFieldName(desc.getFieldName()));
|
||||
StackValue composed = StackValue.composed(StackValue.local(0, oldObjectType),
|
||||
StackValue.field(desc.getType(),
|
||||
oldObjectType, /*TODO owner type*/
|
||||
recapturedParamInfo.getNewFieldName(), false)
|
||||
);
|
||||
StackValue composed = StackValue.field(desc.getType(),
|
||||
oldObjectType, /*TODO owner type*/
|
||||
recapturedParamInfo.getNewFieldName(),
|
||||
false,
|
||||
StackValue.local(0, oldObjectType));
|
||||
recapturedParamInfo.setRemapValue(composed);
|
||||
allRecapturedParameters.add(desc);
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.jetbrains.jet.codegen.inline;
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.containers.Stack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.codegen.*;
|
||||
@@ -336,16 +335,20 @@ public class InlineCodegen implements CallGenerator {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stackValue instanceof StackValue.Composed) {
|
||||
//see: Method.isSpecialStackValue: go through aload 0
|
||||
if (codegen.getContext().isInliningLambda() && codegen.getContext().getContextDescriptor() instanceof AnonymousFunctionDescriptor) {
|
||||
if (descriptor != null && !InlineUtil.hasNoinlineAnnotation(descriptor)) {
|
||||
//TODO: check type of context
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//skip direct capturing fields
|
||||
StackValue receiver = null;
|
||||
if (stackValue instanceof StackValue.Field) {
|
||||
receiver = ((StackValue.Field) stackValue).receiver;
|
||||
} else if(stackValue instanceof StackValue.FieldForSharedVar) {
|
||||
receiver = ((StackValue.Field) ((StackValue.FieldForSharedVar) stackValue).receiver).receiver;
|
||||
}
|
||||
return true;
|
||||
|
||||
if (!(receiver instanceof StackValue.Local)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//TODO: check type of context
|
||||
return !(codegen.getContext().isInliningLambda() && descriptor != null && !InlineUtil.hasNoinlineAnnotation(descriptor));
|
||||
}
|
||||
|
||||
private void putParameterOnStack(ParameterInfo... infos) {
|
||||
@@ -364,7 +367,7 @@ public class InlineCodegen implements CallGenerator {
|
||||
ParameterInfo info = infos[i];
|
||||
if (!info.isSkippedOrRemapped()) {
|
||||
Type type = info.type;
|
||||
StackValue.local(index[i], type).store(type, codegen.v);
|
||||
StackValue.local(index[i], type).store(StackValue.onStack(type), codegen.v, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.jet.codegen.inline;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.codegen.AsmUtil;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.codegen.binding.CalculatedClosure;
|
||||
import org.jetbrains.jet.codegen.context.EnclosedValueDescriptor;
|
||||
import org.jetbrains.jet.codegen.state.JetTypeMapper;
|
||||
@@ -106,12 +107,25 @@ public class LambdaInfo implements CapturedParamOwner, LabelOwner {
|
||||
capturedVars = new ArrayList<CapturedParamDesc>();
|
||||
|
||||
if (closure.getCaptureThis() != null) {
|
||||
EnclosedValueDescriptor descriptor = new EnclosedValueDescriptor(AsmUtil.CAPTURED_THIS_FIELD, null, null, typeMapper.mapType(closure.getCaptureThis()));
|
||||
Type type = typeMapper.mapType(closure.getCaptureThis());
|
||||
EnclosedValueDescriptor descriptor =
|
||||
new EnclosedValueDescriptor(AsmUtil.CAPTURED_THIS_FIELD,
|
||||
null,
|
||||
StackValue.field(type, closureClassType, AsmUtil.CAPTURED_THIS_FIELD, false,
|
||||
StackValue.local(0, AsmTypeConstants.OBJECT_TYPE)),
|
||||
type);
|
||||
capturedVars.add(getCapturedParamInfo(descriptor));
|
||||
}
|
||||
|
||||
if (closure.getCaptureReceiverType() != null) {
|
||||
EnclosedValueDescriptor descriptor = new EnclosedValueDescriptor(AsmUtil.CAPTURED_RECEIVER_FIELD, null, null, typeMapper.mapType(closure.getCaptureReceiverType()));
|
||||
Type type = typeMapper.mapType(closure.getCaptureReceiverType());
|
||||
EnclosedValueDescriptor descriptor =
|
||||
new EnclosedValueDescriptor(
|
||||
AsmUtil.CAPTURED_RECEIVER_FIELD,
|
||||
null,
|
||||
StackValue.field(type, closureClassType, AsmUtil.CAPTURED_RECEIVER_FIELD, false,
|
||||
StackValue.local(0, AsmTypeConstants.OBJECT_TYPE)),
|
||||
type);
|
||||
capturedVars.add(getCapturedParamInfo(descriptor));
|
||||
}
|
||||
|
||||
|
||||
+4
-6
@@ -91,12 +91,10 @@ public class RegeneratedLambdaFieldRemapper extends FieldRemapper {
|
||||
}
|
||||
}
|
||||
|
||||
StackValue result =
|
||||
StackValue.composed(prefix == null ? StackValue.local(0, Type.getObjectType(getLambdaInternalName())) : prefix,
|
||||
StackValue.field(field.getType(),
|
||||
Type.getObjectType(newOwnerType), /*TODO owner type*/
|
||||
field.getNewFieldName(), false)
|
||||
);
|
||||
StackValue result = StackValue.field(field.getType(),
|
||||
Type.getObjectType(newOwnerType), /*TODO owner type*/
|
||||
field.getNewFieldName(), false,
|
||||
prefix == null ? StackValue.local(0, Type.getObjectType(getLambdaInternalName())) : prefix);
|
||||
|
||||
return searchInParent ? parent.getFieldForInline(node, result) : result;
|
||||
}
|
||||
|
||||
@@ -45,18 +45,15 @@ public class Equals extends IntrinsicMethod {
|
||||
StackValue leftExpr;
|
||||
JetExpression rightExpr;
|
||||
if (element instanceof JetCallExpression) {
|
||||
leftExpr = receiver;
|
||||
leftExpr = StackValue.lazyCast(receiver, OBJECT_TYPE);
|
||||
rightExpr = arguments.get(0);
|
||||
}
|
||||
else {
|
||||
leftExpr = codegen.gen(arguments.get(0));
|
||||
leftExpr = codegen.genLazy(arguments.get(0), OBJECT_TYPE);
|
||||
rightExpr = arguments.get(1);
|
||||
}
|
||||
|
||||
leftExpr.put(OBJECT_TYPE, v);
|
||||
codegen.gen(rightExpr).put(OBJECT_TYPE, v);
|
||||
|
||||
genEqualsForExpressionsOnStack(v, JetTokens.EQEQ, OBJECT_TYPE, OBJECT_TYPE).put(returnType, v);
|
||||
genEqualsForExpressionsOnStack(JetTokens.EQEQ, leftExpr, codegen.genLazy(rightExpr, OBJECT_TYPE)).put(returnType, v);
|
||||
return returnType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,17 +42,19 @@ public class IdentityEquals extends IntrinsicMethod {
|
||||
List<JetExpression> arguments,
|
||||
StackValue receiver
|
||||
) {
|
||||
StackValue left;
|
||||
StackValue right;
|
||||
if (element instanceof JetCallExpression) {
|
||||
receiver.put(OBJECT_TYPE, v);
|
||||
codegen.gen(arguments.get(0)).put(OBJECT_TYPE, v);
|
||||
left = StackValue.lazyCast(receiver, OBJECT_TYPE);
|
||||
right = codegen.genLazy(arguments.get(0), OBJECT_TYPE);
|
||||
}
|
||||
else {
|
||||
assert element instanceof JetBinaryExpression;
|
||||
JetBinaryExpression e = (JetBinaryExpression) element;
|
||||
codegen.gen(e.getLeft()).put(OBJECT_TYPE, v);
|
||||
codegen.gen(e.getRight()).put(OBJECT_TYPE, v);
|
||||
left = codegen.genLazy(e.getLeft(), OBJECT_TYPE);
|
||||
right = codegen.genLazy(e.getRight(), OBJECT_TYPE);
|
||||
}
|
||||
StackValue.cmp(JetTokens.EQEQEQ, OBJECT_TYPE).put(returnType, v);
|
||||
StackValue.cmp(JetTokens.EQEQEQ, OBJECT_TYPE, left, right).put(returnType, v);
|
||||
return returnType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,13 +66,13 @@ public class Increment extends IntrinsicMethod {
|
||||
}
|
||||
}
|
||||
StackValue value = codegen.genQualified(receiver, operand);
|
||||
value.dupReceiver(v);
|
||||
value.dupReceiver(v);
|
||||
value = StackValue.complexReceiver(value, StackValue.RECEIVER_READ, StackValue.RECEIVER_WRITE, StackValue.RECEIVER_READ);
|
||||
//value.putReadWriteReadReceiver(v);
|
||||
|
||||
value.put(returnType, v);
|
||||
genIncrement(returnType, myDelta, v);
|
||||
value.store(returnType, v);
|
||||
value.put(returnType, v);
|
||||
StackValue.putNoReceiver(value, returnType, v);
|
||||
}
|
||||
else {
|
||||
receiver.put(returnType, v);
|
||||
|
||||
@@ -17,28 +17,37 @@
|
||||
package org.jetbrains.jet.codegen.intrinsics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import kotlin.Function1;
|
||||
import kotlin.Unit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
import org.jetbrains.jet.codegen.Callable;
|
||||
import org.jetbrains.jet.codegen.ExpressionCodegen;
|
||||
import org.jetbrains.jet.codegen.StackValue;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class IntrinsicMethod implements Callable {
|
||||
public final void generate(
|
||||
@NotNull ExpressionCodegen codegen,
|
||||
@NotNull InstructionAdapter v,
|
||||
@NotNull Type returnType,
|
||||
@Nullable PsiElement element,
|
||||
@Nullable List<JetExpression> arguments,
|
||||
@Nullable StackValue receiver
|
||||
public final StackValue generate(
|
||||
@NotNull final ExpressionCodegen codegen,
|
||||
@NotNull final InstructionAdapter v,
|
||||
@NotNull final Type returnType,
|
||||
@Nullable final PsiElement element,
|
||||
@Nullable final List<JetExpression> arguments,
|
||||
@Nullable final StackValue receiver
|
||||
) {
|
||||
Type actualType = generateImpl(codegen, v, returnType, element, arguments, receiver);
|
||||
StackValue.coerce(actualType, returnType, v);
|
||||
return StackValue.operation(returnType, new Function1<InstructionAdapter, Unit>() {
|
||||
|
||||
@Override
|
||||
public Unit invoke(InstructionAdapter adapter) {
|
||||
Type actualType = generateImpl(codegen, v, returnType, element, arguments, receiver);
|
||||
StackValue.coerce(actualType, returnType, v);
|
||||
return Unit.INSTANCE$;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -38,7 +38,7 @@ public class NewArray extends IntrinsicMethod {
|
||||
List<JetExpression> arguments,
|
||||
StackValue receiver
|
||||
) {
|
||||
codegen.generateNewArray((JetCallExpression) element);
|
||||
codegen.generateNewArray((JetCallExpression) element).put(returnType, v);
|
||||
return returnType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,8 +44,7 @@ public class Not extends IntrinsicMethod {
|
||||
else {
|
||||
stackValue = receiver;
|
||||
}
|
||||
stackValue.put(Type.BOOLEAN_TYPE, v);
|
||||
StackValue.not(StackValue.onStack(Type.BOOLEAN_TYPE)).put(returnType, v);
|
||||
StackValue.not(StackValue.lazyCast(stackValue, Type.BOOLEAN_TYPE)).put(returnType, v);
|
||||
return returnType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
|
||||
class A {
|
||||
class object {
|
||||
private var r: Int = 1;
|
||||
|
||||
fun a(): Int {
|
||||
r++
|
||||
++r
|
||||
return r
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun box() : String {
|
||||
val p = A.a()
|
||||
return if (p == 3) return "OK" else "fail"
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
object A {
|
||||
private var r: Int = 1;
|
||||
|
||||
fun a() : Int {
|
||||
r++
|
||||
++r
|
||||
return r
|
||||
}
|
||||
}
|
||||
|
||||
fun box() : String {
|
||||
val p = A.a()
|
||||
return if (p == 3) return "OK" else "fail"
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
class A(val p: String) {
|
||||
val prop: String = throw RuntimeException()
|
||||
}
|
||||
|
||||
class B(val p: String) {
|
||||
val prop: String = if (p == "test") "OK" else throw RuntimeException()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var result = "fail"
|
||||
try {
|
||||
if (A("test").prop != "OK") return "fail 1"
|
||||
}
|
||||
catch (e: RuntimeException) {
|
||||
result = "OK"
|
||||
}
|
||||
if (result != "OK") return "fail 1: $result"
|
||||
|
||||
|
||||
if (B("test").prop != "OK") return "fail 2"
|
||||
|
||||
|
||||
result = "fail"
|
||||
try {
|
||||
if (B("fail").prop != "OK") return "fail 3"
|
||||
}
|
||||
catch (e: RuntimeException) {
|
||||
return "OK"
|
||||
}
|
||||
|
||||
return "fail"
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
class A (val p: String, p1: String, p2: String) {
|
||||
|
||||
var cond1 :String = ""
|
||||
|
||||
var cond2 :String = ""
|
||||
|
||||
val prop: String = if (p == "test") p1 else p2
|
||||
|
||||
val prop1 = if (cond1(p)) p1
|
||||
|
||||
val prop2 = if (cond2(p)) else;
|
||||
|
||||
fun cond1(p: String): Boolean {
|
||||
cond1 = "cond1"
|
||||
return p == "test"
|
||||
}
|
||||
|
||||
fun cond2(p: String): Boolean {
|
||||
cond2 = "cond2"
|
||||
return p == "test"
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val a = A("test", "OK", "fail")
|
||||
|
||||
if (a.prop != "OK") return "fail 1"
|
||||
|
||||
if (a.cond1 != "cond1") return "fail 2"
|
||||
|
||||
if (a.cond2 != "cond2") return "fail 3"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
class Shape(var result: String) {
|
||||
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var a : Shape? = Shape("fail");
|
||||
a?.result = "OK";
|
||||
|
||||
return a!!.result
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
var holder = ""
|
||||
|
||||
var mainShape: Shape? = null
|
||||
|
||||
fun getShape(): Shape? {
|
||||
holder += "getShape1()"
|
||||
mainShape = Shape("fail")
|
||||
return mainShape
|
||||
}
|
||||
|
||||
fun getOK(): String {
|
||||
holder += "->OK"
|
||||
return "OK"
|
||||
}
|
||||
|
||||
|
||||
class Shape(var result: String) {
|
||||
|
||||
var innerShape: Shape? = null
|
||||
|
||||
fun getShape2(): Shape? {
|
||||
holder += "->getShape2()"
|
||||
innerShape = Shape(result)
|
||||
return innerShape
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
getShape()?.getShape2()?.result = getOK();
|
||||
|
||||
if (holder != "getShape1()->getShape2()->OK") return "fail $holder"
|
||||
|
||||
return mainShape!!.innerShape!!.result
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
class C {
|
||||
fun calc() : String {
|
||||
return "OK"
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String? {
|
||||
val c: C? = C()
|
||||
val arrayList = array(c?.calc(), "")
|
||||
return arrayList[0]
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
class A (val p: String) {
|
||||
|
||||
val _kind: String = "$p"
|
||||
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
|
||||
if (A("OK")._kind != "OK") return "fail"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
class A {
|
||||
val p : Int = try{
|
||||
1
|
||||
} catch(e: Exception) {
|
||||
throw RuntimeException()
|
||||
}
|
||||
}
|
||||
|
||||
fun box() : String {
|
||||
if (A().p != 1) return "fail 1"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
class A (val p: String) {
|
||||
|
||||
val _kind: String = when {
|
||||
p == "test" -> "OK"
|
||||
else -> "fail"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
|
||||
if (A("test")._kind != "OK") return "fail"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
class A {
|
||||
class object {
|
||||
val r: Int = 1;
|
||||
}
|
||||
}
|
||||
// A and class object constructor call
|
||||
// 2 ALOAD 0
|
||||
@@ -0,0 +1,8 @@
|
||||
class A {
|
||||
class object {
|
||||
private var r: Int = 1;
|
||||
}
|
||||
}
|
||||
// A and class object constructor call
|
||||
// 2 ALOAD 0
|
||||
// 1 synthetic getR
|
||||
@@ -30,7 +30,7 @@ import java.util.regex.Pattern;
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@InnerTestClasses({BytecodeTextTestGenerated.BoxingOptimization.class, BytecodeTextTestGenerated.Constants.class, BytecodeTextTestGenerated.DirectInvoke.class, BytecodeTextTestGenerated.Inline.class, BytecodeTextTestGenerated.LineNumbers.class, BytecodeTextTestGenerated.Statements.class, BytecodeTextTestGenerated.StoreStackBeforeInline.class, BytecodeTextTestGenerated.When.class, BytecodeTextTestGenerated.WhenEnumOptimization.class, BytecodeTextTestGenerated.WhenStringOptimization.class})
|
||||
@InnerTestClasses({BytecodeTextTestGenerated.BoxingOptimization.class, BytecodeTextTestGenerated.Constants.class, BytecodeTextTestGenerated.DirectInvoke.class, BytecodeTextTestGenerated.Inline.class, BytecodeTextTestGenerated.LineNumbers.class, BytecodeTextTestGenerated.Statements.class, BytecodeTextTestGenerated.StaticFields.class, BytecodeTextTestGenerated.StoreStackBeforeInline.class, BytecodeTextTestGenerated.When.class, BytecodeTextTestGenerated.WhenEnumOptimization.class, BytecodeTextTestGenerated.WhenStringOptimization.class})
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
||||
@TestMetadata("accessorForProtected.kt")
|
||||
@@ -433,6 +433,27 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/staticFields")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class StaticFields extends AbstractBytecodeTextTest {
|
||||
public void testAllFilesPresentInStaticFields() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/bytecodeText/staticFields"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("classObject.kt")
|
||||
public void testClassObject() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/staticFields/classObject.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classObjectSyntheticAccessor.kt")
|
||||
public void testClassObjectSyntheticAccessor() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/staticFields/classObjectSyntheticAccessor.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/storeStackBeforeInline")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+22
-1
@@ -30,7 +30,7 @@ import java.util.regex.Pattern;
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("compiler/testData/codegen/box")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@InnerTestClasses({BlackBoxCodegenTestGenerated.Arrays.class, BlackBoxCodegenTestGenerated.BinaryOp.class, BlackBoxCodegenTestGenerated.Bridges.class, BlackBoxCodegenTestGenerated.BuiltinStubMethods.class, BlackBoxCodegenTestGenerated.Casts.class, BlackBoxCodegenTestGenerated.Classes.class, BlackBoxCodegenTestGenerated.Closures.class, BlackBoxCodegenTestGenerated.Constants.class, BlackBoxCodegenTestGenerated.ControlStructures.class, BlackBoxCodegenTestGenerated.DefaultArguments.class, BlackBoxCodegenTestGenerated.DelegatedProperty.class, BlackBoxCodegenTestGenerated.Elvis.class, BlackBoxCodegenTestGenerated.Enum.class, BlackBoxCodegenTestGenerated.ExclExcl.class, BlackBoxCodegenTestGenerated.ExtensionFunctions.class, BlackBoxCodegenTestGenerated.ExtensionProperties.class, BlackBoxCodegenTestGenerated.FakeOverride.class, BlackBoxCodegenTestGenerated.FieldRename.class, BlackBoxCodegenTestGenerated.Finally.class, BlackBoxCodegenTestGenerated.Functions.class, BlackBoxCodegenTestGenerated.InnerNested.class, BlackBoxCodegenTestGenerated.Instructions.class, BlackBoxCodegenTestGenerated.Intrinsics.class, BlackBoxCodegenTestGenerated.JavaInterop.class, BlackBoxCodegenTestGenerated.Labels.class, BlackBoxCodegenTestGenerated.LocalClasses.class, BlackBoxCodegenTestGenerated.MultiDecl.class, BlackBoxCodegenTestGenerated.Objects.class, BlackBoxCodegenTestGenerated.OperatorConventions.class, BlackBoxCodegenTestGenerated.Package.class, BlackBoxCodegenTestGenerated.PlatformTypes.class, BlackBoxCodegenTestGenerated.PrimitiveTypes.class, BlackBoxCodegenTestGenerated.Properties.class, BlackBoxCodegenTestGenerated.Reflection.class, BlackBoxCodegenTestGenerated.Regressions.class, BlackBoxCodegenTestGenerated.SafeCall.class, BlackBoxCodegenTestGenerated.SamConstructors.class, BlackBoxCodegenTestGenerated.Strings.class, BlackBoxCodegenTestGenerated.Super.class, BlackBoxCodegenTestGenerated.SuperConstructorCall.class, BlackBoxCodegenTestGenerated.ToArray.class, BlackBoxCodegenTestGenerated.Traits.class, BlackBoxCodegenTestGenerated.TypeInfo.class, BlackBoxCodegenTestGenerated.TypeMapping.class, BlackBoxCodegenTestGenerated.UnaryOp.class, BlackBoxCodegenTestGenerated.Unit.class, BlackBoxCodegenTestGenerated.Vararg.class, BlackBoxCodegenTestGenerated.When.class})
|
||||
@InnerTestClasses({BlackBoxCodegenTestGenerated.Arrays.class, BlackBoxCodegenTestGenerated.BinaryOp.class, BlackBoxCodegenTestGenerated.Bridges.class, BlackBoxCodegenTestGenerated.BuiltinStubMethods.class, BlackBoxCodegenTestGenerated.Casts.class, BlackBoxCodegenTestGenerated.Classes.class, BlackBoxCodegenTestGenerated.Closures.class, BlackBoxCodegenTestGenerated.Constants.class, BlackBoxCodegenTestGenerated.ControlStructures.class, BlackBoxCodegenTestGenerated.DefaultArguments.class, BlackBoxCodegenTestGenerated.DelegatedProperty.class, BlackBoxCodegenTestGenerated.Elvis.class, BlackBoxCodegenTestGenerated.Enum.class, BlackBoxCodegenTestGenerated.ExclExcl.class, BlackBoxCodegenTestGenerated.ExtensionFunctions.class, BlackBoxCodegenTestGenerated.ExtensionProperties.class, BlackBoxCodegenTestGenerated.FakeOverride.class, BlackBoxCodegenTestGenerated.FieldRename.class, BlackBoxCodegenTestGenerated.Finally.class, BlackBoxCodegenTestGenerated.Functions.class, BlackBoxCodegenTestGenerated.InnerNested.class, BlackBoxCodegenTestGenerated.Instructions.class, BlackBoxCodegenTestGenerated.Intrinsics.class, BlackBoxCodegenTestGenerated.JavaInterop.class, BlackBoxCodegenTestGenerated.Labels.class, BlackBoxCodegenTestGenerated.LocalClasses.class, BlackBoxCodegenTestGenerated.MultiDecl.class, BlackBoxCodegenTestGenerated.Objects.class, BlackBoxCodegenTestGenerated.OperatorConventions.class, BlackBoxCodegenTestGenerated.Package.class, BlackBoxCodegenTestGenerated.PlatformTypes.class, BlackBoxCodegenTestGenerated.PrimitiveTypes.class, BlackBoxCodegenTestGenerated.Properties.class, BlackBoxCodegenTestGenerated.Reflection.class, BlackBoxCodegenTestGenerated.Regressions.class, BlackBoxCodegenTestGenerated.SafeCall.class, BlackBoxCodegenTestGenerated.SamConstructors.class, BlackBoxCodegenTestGenerated.StaticFields.class, BlackBoxCodegenTestGenerated.Strings.class, BlackBoxCodegenTestGenerated.Super.class, BlackBoxCodegenTestGenerated.SuperConstructorCall.class, BlackBoxCodegenTestGenerated.ToArray.class, BlackBoxCodegenTestGenerated.Traits.class, BlackBoxCodegenTestGenerated.TypeInfo.class, BlackBoxCodegenTestGenerated.TypeMapping.class, BlackBoxCodegenTestGenerated.UnaryOp.class, BlackBoxCodegenTestGenerated.Unit.class, BlackBoxCodegenTestGenerated.Vararg.class, BlackBoxCodegenTestGenerated.When.class})
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
public void testAllFilesPresentInBox() throws Exception {
|
||||
@@ -6165,6 +6165,27 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/staticFields")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class StaticFields extends AbstractBlackBoxCodegenTest {
|
||||
public void testAllFilesPresentInStaticFields() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/staticFields"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("classObjectInc.kt")
|
||||
public void testClassObjectInc() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/staticFields/classObjectInc.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("objectInc.kt")
|
||||
public void testObjectInc() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/staticFields/objectInc.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/strings")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+58
-1
@@ -30,7 +30,7 @@ import java.util.regex.Pattern;
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("compiler/testData/codegen/boxWithStdlib")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@InnerTestClasses({BlackBoxWithStdlibCodegenTestGenerated.Annotations.class, BlackBoxWithStdlibCodegenTestGenerated.Arrays.class, BlackBoxWithStdlibCodegenTestGenerated.BoxingOptimization.class, BlackBoxWithStdlibCodegenTestGenerated.CallableReference.class, BlackBoxWithStdlibCodegenTestGenerated.Casts.class, BlackBoxWithStdlibCodegenTestGenerated.DataClasses.class, BlackBoxWithStdlibCodegenTestGenerated.DefaultArguments.class, BlackBoxWithStdlibCodegenTestGenerated.Enum.class, BlackBoxWithStdlibCodegenTestGenerated.Evaluate.class, BlackBoxWithStdlibCodegenTestGenerated.FullJdk.class, BlackBoxWithStdlibCodegenTestGenerated.HashPMap.class, BlackBoxWithStdlibCodegenTestGenerated.Intrinsics.class, BlackBoxWithStdlibCodegenTestGenerated.JdkAnnotations.class, BlackBoxWithStdlibCodegenTestGenerated.LocalFunInLambda.class, BlackBoxWithStdlibCodegenTestGenerated.NonLocalReturns.class, BlackBoxWithStdlibCodegenTestGenerated.PlatformNames.class, BlackBoxWithStdlibCodegenTestGenerated.PlatformStatic.class, BlackBoxWithStdlibCodegenTestGenerated.PlatformTypes.class, BlackBoxWithStdlibCodegenTestGenerated.Ranges.class, BlackBoxWithStdlibCodegenTestGenerated.Reflection.class, BlackBoxWithStdlibCodegenTestGenerated.Regressions.class, BlackBoxWithStdlibCodegenTestGenerated.Reified.class, BlackBoxWithStdlibCodegenTestGenerated.StoreStackBeforeInline.class, BlackBoxWithStdlibCodegenTestGenerated.Strings.class, BlackBoxWithStdlibCodegenTestGenerated.ToArray.class, BlackBoxWithStdlibCodegenTestGenerated.Vararg.class, BlackBoxWithStdlibCodegenTestGenerated.When.class, BlackBoxWithStdlibCodegenTestGenerated.WhenEnumOptimization.class, BlackBoxWithStdlibCodegenTestGenerated.WhenStringOptimization.class})
|
||||
@InnerTestClasses({BlackBoxWithStdlibCodegenTestGenerated.Annotations.class, BlackBoxWithStdlibCodegenTestGenerated.Arrays.class, BlackBoxWithStdlibCodegenTestGenerated.BoxingOptimization.class, BlackBoxWithStdlibCodegenTestGenerated.CallableReference.class, BlackBoxWithStdlibCodegenTestGenerated.Casts.class, BlackBoxWithStdlibCodegenTestGenerated.DataClasses.class, BlackBoxWithStdlibCodegenTestGenerated.DefaultArguments.class, BlackBoxWithStdlibCodegenTestGenerated.Enum.class, BlackBoxWithStdlibCodegenTestGenerated.Evaluate.class, BlackBoxWithStdlibCodegenTestGenerated.FullJdk.class, BlackBoxWithStdlibCodegenTestGenerated.HashPMap.class, BlackBoxWithStdlibCodegenTestGenerated.Intrinsics.class, BlackBoxWithStdlibCodegenTestGenerated.JdkAnnotations.class, BlackBoxWithStdlibCodegenTestGenerated.LazyCodegen.class, BlackBoxWithStdlibCodegenTestGenerated.LocalFunInLambda.class, BlackBoxWithStdlibCodegenTestGenerated.NonLocalReturns.class, BlackBoxWithStdlibCodegenTestGenerated.PlatformNames.class, BlackBoxWithStdlibCodegenTestGenerated.PlatformStatic.class, BlackBoxWithStdlibCodegenTestGenerated.PlatformTypes.class, BlackBoxWithStdlibCodegenTestGenerated.Ranges.class, BlackBoxWithStdlibCodegenTestGenerated.Reflection.class, BlackBoxWithStdlibCodegenTestGenerated.Regressions.class, BlackBoxWithStdlibCodegenTestGenerated.Reified.class, BlackBoxWithStdlibCodegenTestGenerated.StoreStackBeforeInline.class, BlackBoxWithStdlibCodegenTestGenerated.Strings.class, BlackBoxWithStdlibCodegenTestGenerated.ToArray.class, BlackBoxWithStdlibCodegenTestGenerated.Vararg.class, BlackBoxWithStdlibCodegenTestGenerated.When.class, BlackBoxWithStdlibCodegenTestGenerated.WhenEnumOptimization.class, BlackBoxWithStdlibCodegenTestGenerated.WhenStringOptimization.class})
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
public void testAllFilesPresentInBoxWithStdlib() throws Exception {
|
||||
@@ -1464,6 +1464,63 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxWithStdlib/lazyCodegen")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class LazyCodegen extends AbstractBlackBoxCodegenTest {
|
||||
public void testAllFilesPresentInLazyCodegen() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxWithStdlib/lazyCodegen"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("exceptionInFieldInitializer.kt")
|
||||
public void testExceptionInFieldInitializer() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/lazyCodegen/exceptionInFieldInitializer.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ifElse.kt")
|
||||
public void testIfElse() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/lazyCodegen/ifElse.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("safeAssign.kt")
|
||||
public void testSafeAssign() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/lazyCodegen/safeAssign.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("safeAssignComplex.kt")
|
||||
public void testSafeAssignComplex() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/lazyCodegen/safeAssignComplex.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("safeCallAndArray.kt")
|
||||
public void testSafeCallAndArray() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/lazyCodegen/safeCallAndArray.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("toString.kt")
|
||||
public void testToString() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/lazyCodegen/toString.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("tryCatchExpression.kt")
|
||||
public void testTryCatchExpression() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/lazyCodegen/tryCatchExpression.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("when.kt")
|
||||
public void testWhen() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/lazyCodegen/when.kt");
|
||||
doTestWithStdlib(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxWithStdlib/localFunInLambda")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Reference in New Issue
Block a user