When by enum:
Generate TABLESWITCH/LOOKUPSWITCH bytecode command in case of "when" by enum entries
This commit is contained in:
committed by
Evgeny Gerashchenko
parent
b2aa249817
commit
5a1c995b5c
@@ -788,4 +788,9 @@ public class AsmUtil {
|
||||
v.aconst(type);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Type getArrayOf(@NotNull String internalClassName) {
|
||||
return Type.getType("[L" + internalClassName + ";");
|
||||
}
|
||||
}
|
||||
|
||||
+78
-4
@@ -20,13 +20,14 @@ import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.util.containers.Stack;
|
||||
import kotlin.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.codegen.AsmUtil;
|
||||
import org.jetbrains.jet.codegen.JvmRuntimeTypes;
|
||||
import org.jetbrains.jet.codegen.SamCodegenUtil;
|
||||
import org.jetbrains.jet.codegen.SamType;
|
||||
import org.jetbrains.jet.codegen.*;
|
||||
import org.jetbrains.jet.codegen.state.GenerationState;
|
||||
import org.jetbrains.jet.codegen.when.SwitchCodegenUtil;
|
||||
import org.jetbrains.jet.codegen.when.WhenByEnumsMapping;
|
||||
import org.jetbrains.jet.lang.cfg.WhenChecker;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.ClassDescriptorImpl;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
@@ -37,8 +38,11 @@ import org.jetbrains.jet.lang.resolve.bindingContextUtil.BindingContextUtilPacka
|
||||
import org.jetbrains.jet.lang.resolve.calls.model.ExpressionValueArgument;
|
||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument;
|
||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.jet.lang.resolve.constants.EnumValue;
|
||||
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
||||
import org.jetbrains.jet.lang.resolve.java.PackageClassUtils;
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.PackagePartClassUtils;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
@@ -489,4 +493,74 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitWhenExpression(@NotNull JetWhenExpression expression) {
|
||||
super.visitWhenExpression(expression);
|
||||
if (isWhenWithEnums(expression)) {
|
||||
String currentClassName = getCurrentTopLevelClassOrPackagePartInternalName(expression.getContainingJetFile());
|
||||
|
||||
if (bindingContext.get(MAPPINGS_FOR_WHENS_BY_ENUM_IN_CLASS_FILE, currentClassName) == null) {
|
||||
bindingTrace.record(
|
||||
MAPPINGS_FOR_WHENS_BY_ENUM_IN_CLASS_FILE,
|
||||
currentClassName,
|
||||
new ArrayList<WhenByEnumsMapping>()
|
||||
);
|
||||
}
|
||||
|
||||
List<WhenByEnumsMapping> mappings = bindingContext.get(MAPPINGS_FOR_WHENS_BY_ENUM_IN_CLASS_FILE, currentClassName);
|
||||
assert mappings != null : "guaranteed by contract";
|
||||
|
||||
int fieldNumber = mappings.size();
|
||||
|
||||
JetType type = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression.getSubjectExpression());
|
||||
assert type != null : "should not be null in a valid when by enums";
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) type.getConstructor().getDeclarationDescriptor();
|
||||
assert classDescriptor != null : "because it's enum";
|
||||
|
||||
WhenByEnumsMapping mapping = new WhenByEnumsMapping(
|
||||
CodegenBinding.getAsmType(bindingContext, classDescriptor).getInternalName(),
|
||||
currentClassName,
|
||||
fieldNumber
|
||||
);
|
||||
|
||||
for (CompileTimeConstant constant : SwitchCodegenUtil.getAllConstants(expression, bindingContext)) {
|
||||
assert constant instanceof EnumValue : "expression in when should be EnumValue";
|
||||
mapping.putFirstTime((EnumValue) constant, mapping.size() + 1);
|
||||
}
|
||||
|
||||
mappings.add(mapping);
|
||||
|
||||
bindingTrace.record(MAPPING_FOR_WHEN_BY_ENUM, expression, mapping);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isWhenWithEnums(@NotNull JetWhenExpression expression) {
|
||||
return WhenChecker.isWhenByEnum(expression, bindingContext) &&
|
||||
SwitchCodegenUtil.checkAllItemsAreConstantsSatisfying(
|
||||
expression,
|
||||
bindingContext,
|
||||
new Function1<CompileTimeConstant, Boolean>() {
|
||||
@Override
|
||||
public Boolean invoke(
|
||||
@NotNull CompileTimeConstant constant
|
||||
) {
|
||||
return constant instanceof EnumValue;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String getCurrentTopLevelClassOrPackagePartInternalName(@NotNull JetFile file) {
|
||||
ListIterator<ClassDescriptorWithState> iterator = classStack.listIterator(classStack.size());
|
||||
while(iterator.hasPrevious()) {
|
||||
ClassDescriptor previous = iterator.previous().getDescriptor();
|
||||
if (DescriptorUtils.isTopLevelOrInnerClass(previous)) {
|
||||
return CodegenBinding.getAsmType(bindingContext, previous).getInternalName();
|
||||
}
|
||||
}
|
||||
|
||||
return PackagePartClassUtils.getPackagePartInternalName(file);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.codegen.SamType;
|
||||
import org.jetbrains.jet.codegen.state.GenerationState;
|
||||
import org.jetbrains.jet.codegen.when.WhenByEnumsMapping;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.impl.ClassDescriptorImpl;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
@@ -60,6 +61,12 @@ public class CodegenBinding {
|
||||
|
||||
public static final WritableSlice<JetExpression, SamType> SAM_VALUE = Slices.createSimpleSlice();
|
||||
|
||||
public static final WritableSlice<JetWhenExpression, WhenByEnumsMapping> MAPPING_FOR_WHEN_BY_ENUM = Slices.
|
||||
<JetWhenExpression, WhenByEnumsMapping>sliceBuilder().build();
|
||||
|
||||
public static final WritableSlice<String, List<WhenByEnumsMapping>> MAPPINGS_FOR_WHENS_BY_ENUM_IN_CLASS_FILE =
|
||||
Slices.<String, List<WhenByEnumsMapping>>sliceBuilder().build();
|
||||
|
||||
static {
|
||||
BasicWritableSlice.initSliceDebugNames(CodegenBinding.class);
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.jetbrains.jet.codegen.inline.InlineCodegenUtil;
|
||||
import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethods;
|
||||
import org.jetbrains.jet.codegen.optimization.OptimizationClassBuilderFactory;
|
||||
import org.jetbrains.jet.codegen.optimization.OptimizationUtils;
|
||||
import org.jetbrains.jet.codegen.when.MappingsClassesForWhenByEnum;
|
||||
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ScriptDescriptor;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticHolder;
|
||||
@@ -79,6 +80,9 @@ public class GenerationState {
|
||||
@NotNull
|
||||
private final SamWrapperClasses samWrapperClasses = new SamWrapperClasses(this);
|
||||
|
||||
@NotNull
|
||||
private final MappingsClassesForWhenByEnum mappingsClassesForWhenByEnum = new MappingsClassesForWhenByEnum(this);
|
||||
|
||||
@NotNull
|
||||
private final BindingTrace bindingTrace;
|
||||
|
||||
@@ -222,6 +226,11 @@ public class GenerationState {
|
||||
return samWrapperClasses;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public MappingsClassesForWhenByEnum getMappingsClassesForWhenByEnum() {
|
||||
return mappingsClassesForWhenByEnum;
|
||||
}
|
||||
|
||||
public boolean isGenerateNotNullAssertions() {
|
||||
return generateNotNullAssertions;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package org.jetbrains.jet.codegen.when;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.codegen.ExpressionCodegen;
|
||||
import org.jetbrains.jet.lang.psi.JetWhenExpression;
|
||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.jet.lang.resolve.constants.EnumValue;
|
||||
import org.jetbrains.org.objectweb.asm.Label;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
public class EnumSwitchCodegen extends SwitchCodegen {
|
||||
private final WhenByEnumsMapping mapping;
|
||||
|
||||
public EnumSwitchCodegen(
|
||||
@NotNull JetWhenExpression expression,
|
||||
boolean isStatement,
|
||||
@NotNull ExpressionCodegen codegen,
|
||||
@NotNull WhenByEnumsMapping mapping
|
||||
) {
|
||||
super(expression, isStatement, codegen);
|
||||
this.mapping = mapping;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateSubject() {
|
||||
codegen.getState().getMappingsClassesForWhenByEnum().generateMappingsClassForExpression(expression);
|
||||
|
||||
v.getstatic(
|
||||
mapping.getMappingsClassInternalName(),
|
||||
mapping.getFieldName(),
|
||||
MappingClassesForWhenByEnumCodegen.MAPPINGS_FIELD_DESCRIPTOR
|
||||
);
|
||||
|
||||
super.generateSubject();
|
||||
|
||||
v.invokevirtual(
|
||||
mapping.getEnumClassInternalName(),
|
||||
"ordinal",
|
||||
Type.getMethodDescriptor(Type.INT_TYPE),
|
||||
false
|
||||
);
|
||||
v.aload(Type.INT_TYPE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processConstant(
|
||||
@NotNull CompileTimeConstant constant,
|
||||
@NotNull Label entryLabel
|
||||
) {
|
||||
assert constant instanceof EnumValue : "guaranteed by usage contract";
|
||||
putTransitionOnce(mapping.getIndexByEntry((EnumValue) constant), entryLabel);
|
||||
}
|
||||
}
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* 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.when;
|
||||
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.codegen.AsmUtil;
|
||||
import org.jetbrains.jet.codegen.ClassBuilder;
|
||||
import org.jetbrains.jet.codegen.state.GenerationState;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.constants.EnumValue;
|
||||
import org.jetbrains.jet.lang.resolve.java.diagnostics.JvmDeclarationOrigin;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
|
||||
public class MappingClassesForWhenByEnumCodegen {
|
||||
public static final String MAPPINGS_FIELD_DESCRIPTOR = Type.getDescriptor(int[].class);
|
||||
private final GenerationState state;
|
||||
|
||||
public MappingClassesForWhenByEnumCodegen(@NotNull GenerationState state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public void generate(
|
||||
@NotNull List<WhenByEnumsMapping> mappings,
|
||||
@NotNull Type mappingsClass,
|
||||
@NotNull JetFile srcFile
|
||||
) {
|
||||
ClassBuilder cb = state.getFactory().newVisitor(
|
||||
JvmDeclarationOrigin.NO_ORIGIN,
|
||||
mappingsClass,
|
||||
srcFile
|
||||
);
|
||||
cb.defineClass(
|
||||
srcFile,
|
||||
V1_6,
|
||||
ACC_FINAL | ACC_SYNTHETIC,
|
||||
mappingsClass.getInternalName(),
|
||||
null,
|
||||
OBJECT_TYPE.getInternalName(),
|
||||
ArrayUtil.EMPTY_STRING_ARRAY
|
||||
);
|
||||
|
||||
generateFields(cb, mappings);
|
||||
generateInitialization(cb, mappings);
|
||||
|
||||
cb.done();
|
||||
}
|
||||
|
||||
private static void generateFields(
|
||||
@NotNull ClassBuilder cb,
|
||||
@NotNull List<WhenByEnumsMapping> mappings
|
||||
) {
|
||||
for (WhenByEnumsMapping mapping : mappings) {
|
||||
cb.newField(
|
||||
JvmDeclarationOrigin.NO_ORIGIN,
|
||||
ACC_STATIC | ACC_PUBLIC | ACC_FINAL | ACC_SYNTHETIC,
|
||||
mapping.getFieldName(),
|
||||
MAPPINGS_FIELD_DESCRIPTOR,
|
||||
null, null
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static void generateInitialization(
|
||||
@NotNull ClassBuilder cb,
|
||||
@NotNull List<WhenByEnumsMapping> mappings
|
||||
) {
|
||||
MethodVisitor mv = cb.newMethod(
|
||||
JvmDeclarationOrigin.NO_ORIGIN,
|
||||
ACC_STATIC | ACC_SYNTHETIC, "<clinit>", "()V", null, ArrayUtil.EMPTY_STRING_ARRAY
|
||||
);
|
||||
|
||||
mv.visitCode();
|
||||
|
||||
InstructionAdapter v = new InstructionAdapter(mv);
|
||||
|
||||
for (WhenByEnumsMapping mapping : mappings) {
|
||||
generateInitializationForMapping(cb, v, mapping);
|
||||
}
|
||||
|
||||
v.areturn(Type.VOID_TYPE);
|
||||
|
||||
mv.visitMaxs(-1, -1);
|
||||
mv.visitEnd();
|
||||
}
|
||||
|
||||
private static void generateInitializationForMapping(
|
||||
@NotNull ClassBuilder cb,
|
||||
@NotNull InstructionAdapter v,
|
||||
@NotNull WhenByEnumsMapping mapping
|
||||
) {
|
||||
v.invokestatic(
|
||||
mapping.getEnumClassInternalName(), "values",
|
||||
Type.getMethodDescriptor(
|
||||
AsmUtil.getArrayOf(mapping.getEnumClassInternalName())
|
||||
),
|
||||
false
|
||||
);
|
||||
v.arraylength();
|
||||
|
||||
v.newarray(Type.INT_TYPE);
|
||||
v.putstatic(cb.getThisName(), mapping.getFieldName(), MAPPINGS_FIELD_DESCRIPTOR);
|
||||
|
||||
String enumClassDesc = Type.getObjectType(mapping.getEnumClassInternalName()).getDescriptor();
|
||||
|
||||
for (Map.Entry<EnumValue, Integer> item : mapping.enumValuesToIntMapping()) {
|
||||
EnumValue enumEntry = item.getKey();
|
||||
int mappedValue = item.getValue();
|
||||
|
||||
v.getstatic(cb.getThisName(), mapping.getFieldName(), MAPPINGS_FIELD_DESCRIPTOR);
|
||||
v.getstatic(
|
||||
mapping.getEnumClassInternalName(),
|
||||
enumEntry.getValue().getName().asString(),
|
||||
enumClassDesc
|
||||
);
|
||||
v.invokevirtual(
|
||||
mapping.getEnumClassInternalName(), "ordinal",
|
||||
Type.getMethodDescriptor(Type.INT_TYPE),
|
||||
false
|
||||
);
|
||||
v.iconst(mappedValue);
|
||||
v.astore(Type.INT_TYPE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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.when;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.codegen.binding.CodegenBinding;
|
||||
import org.jetbrains.jet.codegen.state.GenerationState;
|
||||
import org.jetbrains.jet.lang.psi.JetWhenExpression;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class MappingsClassesForWhenByEnum {
|
||||
private final GenerationState state;
|
||||
private final Set<String> generatedMappingClasses = new HashSet<String>();
|
||||
private final MappingClassesForWhenByEnumCodegen mappingsCodegen;
|
||||
|
||||
public MappingsClassesForWhenByEnum(@NotNull GenerationState state) {
|
||||
this.state = state;
|
||||
this.mappingsCodegen = new MappingClassesForWhenByEnumCodegen(state);
|
||||
}
|
||||
|
||||
public void generateMappingsClassForExpression(@NotNull JetWhenExpression expression) {
|
||||
WhenByEnumsMapping mapping = state.getBindingContext().get(CodegenBinding.MAPPING_FOR_WHEN_BY_ENUM, expression);
|
||||
|
||||
assert mapping != null : "mapping class should not be requested for non enum when";
|
||||
|
||||
if (!generatedMappingClasses.contains(mapping.getMappingsClassInternalName())) {
|
||||
List<WhenByEnumsMapping> mappings = state.getBindingContext().get(
|
||||
CodegenBinding.MAPPINGS_FOR_WHENS_BY_ENUM_IN_CLASS_FILE,
|
||||
mapping.getOuterClassInternalNameForExpression()
|
||||
);
|
||||
|
||||
assert mappings != null : "guaranteed by usage contract of EnumSwitchCodegen";
|
||||
|
||||
Type mappingsClassType = Type.getObjectType(mapping.getMappingsClassInternalName());
|
||||
|
||||
mappingsCodegen.generate(mappings, mappingsClassType, expression.getContainingJetFile());
|
||||
generatedMappingClasses.add(mapping.getMappingsClassInternalName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import kotlin.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.codegen.ExpressionCodegen;
|
||||
import org.jetbrains.jet.codegen.binding.CodegenBinding;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||
@@ -35,6 +36,12 @@ public class SwitchCodegenUtil {
|
||||
@NotNull Type subjectType,
|
||||
@NotNull BindingContext bindingContext
|
||||
) {
|
||||
// *switch opcode can be used if each item is enum entry or integral constant
|
||||
// in case of enum CodegenAnnotationVisitor should put mappings into bindingContext
|
||||
if (bindingContext.get(CodegenBinding.MAPPING_FOR_WHEN_BY_ENUM, expression) != null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int typeSort = subjectType.getSort();
|
||||
|
||||
if (typeSort != Type.INT && typeSort != Type.CHAR && typeSort != Type.SHORT && typeSort != Type.BYTE) {
|
||||
@@ -120,6 +127,12 @@ public class SwitchCodegenUtil {
|
||||
boolean isStatement,
|
||||
@NotNull ExpressionCodegen codegen
|
||||
) {
|
||||
WhenByEnumsMapping mapping = codegen.getBindingContext().get(CodegenBinding.MAPPING_FOR_WHEN_BY_ENUM, expression);
|
||||
|
||||
if (mapping != null) {
|
||||
return new EnumSwitchCodegen(expression, isStatement, codegen, mapping);
|
||||
}
|
||||
|
||||
return new IntegralConstantsSwitchCodegen(expression, isStatement, codegen);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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.when;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.resolve.constants.EnumValue;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class WhenByEnumsMapping {
|
||||
private static final String MAPPING_ARRAY_FIELD_PREFIX = "$EnumSwitchMapping$";
|
||||
private static final String MAPPINGS_CLASS_NAME_POSTFIX = "$WhenMappings";
|
||||
|
||||
private final Map<EnumValue, Integer> map = new HashMap<EnumValue, Integer>();
|
||||
private final String enumClassInternalName;
|
||||
private final String outerClassInternalNameForExpression;
|
||||
private final String mappingsClassInternalName;
|
||||
private final int fieldNumber;
|
||||
|
||||
public WhenByEnumsMapping(String enumClassInternalName, String outerClassInternalNameForExpression, int fieldNumber) {
|
||||
this.enumClassInternalName = enumClassInternalName;
|
||||
this.outerClassInternalNameForExpression = outerClassInternalNameForExpression;
|
||||
this.mappingsClassInternalName = outerClassInternalNameForExpression + MAPPINGS_CLASS_NAME_POSTFIX;
|
||||
this.fieldNumber = fieldNumber;
|
||||
}
|
||||
|
||||
public int getIndexByEntry(@NotNull EnumValue value) {
|
||||
Integer result = map.get(value);
|
||||
assert result != null : "entry " + value + " has no mapping";
|
||||
return result;
|
||||
}
|
||||
|
||||
public void putFirstTime(EnumValue value, int index) {
|
||||
if (!map.containsKey(value)) {
|
||||
map.put(value, index);
|
||||
}
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return map.size();
|
||||
}
|
||||
|
||||
public String getFieldName() {
|
||||
return MAPPING_ARRAY_FIELD_PREFIX + fieldNumber;
|
||||
}
|
||||
|
||||
public String getEnumClassInternalName() {
|
||||
return enumClassInternalName;
|
||||
}
|
||||
|
||||
public String getOuterClassInternalNameForExpression() {
|
||||
return outerClassInternalNameForExpression;
|
||||
}
|
||||
|
||||
public String getMappingsClassInternalName() {
|
||||
return mappingsClassInternalName;
|
||||
}
|
||||
|
||||
public Iterable<Map.Entry<EnumValue, Integer>> enumValuesToIntMapping() {
|
||||
return map.entrySet();
|
||||
}
|
||||
}
|
||||
@@ -42,15 +42,28 @@ public final class WhenChecker {
|
||||
return !isUnit && !isStatement && !isWhenExhaustive(expression, trace);
|
||||
}
|
||||
|
||||
private static boolean isWhenExhaustive(@NotNull JetWhenExpression expression, @NotNull BindingTrace trace) {
|
||||
public static boolean isWhenByEnum(@NotNull JetWhenExpression expression, @NotNull BindingContext context) {
|
||||
return getSubjectClassDescriptorIfEnum(expression, context) != null;
|
||||
}
|
||||
|
||||
private static ClassDescriptor getSubjectClassDescriptorIfEnum(@NotNull JetWhenExpression expression, @NotNull BindingContext context) {
|
||||
JetExpression subjectExpression = expression.getSubjectExpression();
|
||||
if (subjectExpression == null) return false;
|
||||
JetType type = trace.get(BindingContext.EXPRESSION_TYPE, subjectExpression);
|
||||
if (type == null) return false;
|
||||
if (subjectExpression == null) return null;
|
||||
JetType type = context.get(BindingContext.EXPRESSION_TYPE, subjectExpression);
|
||||
if (type == null) return null;
|
||||
DeclarationDescriptor declarationDescriptor = type.getConstructor().getDeclarationDescriptor();
|
||||
if (!(declarationDescriptor instanceof ClassDescriptor)) return false;
|
||||
if (!(declarationDescriptor instanceof ClassDescriptor)) return null;
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor;
|
||||
if (classDescriptor.getKind() != ClassKind.ENUM_CLASS || classDescriptor.getModality().isOverridable()) return false;
|
||||
if (classDescriptor.getKind() != ClassKind.ENUM_CLASS || classDescriptor.getModality().isOverridable()) return null;
|
||||
|
||||
return classDescriptor;
|
||||
}
|
||||
|
||||
private static boolean isWhenExhaustive(@NotNull JetWhenExpression expression, @NotNull BindingTrace trace) {
|
||||
ClassDescriptor classDescriptor = getSubjectClassDescriptorIfEnum(expression, trace.getBindingContext());
|
||||
|
||||
if (classDescriptor == null) return false;
|
||||
|
||||
boolean isExhaust = true;
|
||||
boolean notEmpty = false;
|
||||
for (DeclarationDescriptor descriptor : classDescriptor.getUnsubstitutedInnerClassesScope().getAllDescriptors()) {
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
enum class BigEnum {
|
||||
ITEM1 ITEM2 ITEM3 ITEM4 ITEM5 ITEM6 ITEM7 ITEM8 ITEM9 ITEM10 ITEM11 ITEM12 ITEM13 ITEM14 ITEM15 ITEM16 ITEM17 ITEM18 ITEM19 ITEM20
|
||||
}
|
||||
|
||||
fun bar1(x : BigEnum) : String {
|
||||
when (x) {
|
||||
BigEnum.ITEM1, BigEnum.ITEM2, BigEnum.ITEM3 -> return "123"
|
||||
BigEnum.ITEM4, BigEnum.ITEM5, BigEnum.ITEM6 -> return "456"
|
||||
}
|
||||
|
||||
return "-1";
|
||||
|
||||
}
|
||||
|
||||
fun bar2(x : BigEnum) : String {
|
||||
when (x) {
|
||||
BigEnum.ITEM7, BigEnum.ITEM8, BigEnum.ITEM9 -> return "789"
|
||||
BigEnum.ITEM10 -> return "10"
|
||||
BigEnum.ITEM11, BigEnum.ITEM12 -> return "1112"
|
||||
else -> return "-1"
|
||||
}
|
||||
}
|
||||
|
||||
fun box() : String {
|
||||
//bar1
|
||||
assertEquals("123", bar1(BigEnum.ITEM1))
|
||||
assertEquals("123", bar1(BigEnum.ITEM2))
|
||||
assertEquals("123", bar1(BigEnum.ITEM3))
|
||||
|
||||
assertEquals("456", bar1(BigEnum.ITEM4))
|
||||
assertEquals("456", bar1(BigEnum.ITEM5))
|
||||
assertEquals("456", bar1(BigEnum.ITEM6))
|
||||
|
||||
assertEquals("-1", bar1(BigEnum.ITEM7))
|
||||
|
||||
//bar2
|
||||
assertEquals("789", bar2(BigEnum.ITEM7))
|
||||
assertEquals("789", bar2(BigEnum.ITEM8))
|
||||
assertEquals("789", bar2(BigEnum.ITEM9))
|
||||
|
||||
assertEquals("10", bar2(BigEnum.ITEM10))
|
||||
|
||||
assertEquals("1112", bar2(BigEnum.ITEM11))
|
||||
assertEquals("1112", bar2(BigEnum.ITEM12))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
enum class Season {
|
||||
WINTER
|
||||
SPRING
|
||||
SUMMER
|
||||
AUTUMN
|
||||
}
|
||||
|
||||
fun bar(x : Season) : String {
|
||||
when (x) {
|
||||
Season.WINTER, Season.SPRING -> return "winter_spring"
|
||||
Season.SUMMER, Season.SPRING -> return "summer"
|
||||
else -> return "autumn"
|
||||
}
|
||||
}
|
||||
|
||||
fun box() : String {
|
||||
assertEquals("winter_spring", bar(Season.WINTER))
|
||||
assertEquals("winter_spring", bar(Season.SPRING))
|
||||
assertEquals("summer", bar(Season.SUMMER))
|
||||
assertEquals("autumn", bar(Season.AUTUMN))
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class A {
|
||||
class object {
|
||||
enum class Season {
|
||||
WINTER
|
||||
SPRING
|
||||
SUMMER
|
||||
AUTUMN
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun foo(x : A.Season) : String {
|
||||
return when (x) {
|
||||
A.Season.WINTER -> "winter"
|
||||
A.Season.SPRING -> "spring"
|
||||
A.Season.SUMMER -> "summer"
|
||||
else -> "other"
|
||||
}
|
||||
}
|
||||
|
||||
fun box() : String {
|
||||
assertEquals("winter", foo(A.Season.WINTER))
|
||||
assertEquals("spring", foo(A.Season.SPRING))
|
||||
assertEquals("summer", foo(A.Season.SUMMER))
|
||||
assertEquals("other", foo(A.Season.AUTUMN))
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
enum class Season {
|
||||
WINTER
|
||||
SPRING
|
||||
SUMMER
|
||||
AUTUMN
|
||||
}
|
||||
|
||||
fun bar1(x : Season) : String {
|
||||
return when (x) {
|
||||
Season.WINTER, Season.SPRING -> "winter_spring"
|
||||
Season.SUMMER -> "summer"
|
||||
else -> "autumn"
|
||||
}
|
||||
}
|
||||
|
||||
fun bar2(x : Season) : String {
|
||||
return when (x) {
|
||||
Season.WINTER, Season.SPRING -> "winter_spring"
|
||||
Season.SUMMER -> "summer"
|
||||
Season.AUTUMN -> "autumn"
|
||||
}
|
||||
}
|
||||
|
||||
fun box() : String {
|
||||
assertEquals("winter_spring", bar1(Season.WINTER))
|
||||
assertEquals("winter_spring", bar1(Season.SPRING))
|
||||
assertEquals("summer", bar1(Season.SUMMER))
|
||||
assertEquals("autumn", bar1(Season.AUTUMN))
|
||||
|
||||
assertEquals("winter_spring", bar2(Season.WINTER))
|
||||
assertEquals("winter_spring", bar2(Season.SPRING))
|
||||
assertEquals("summer", bar2(Season.SUMMER))
|
||||
assertEquals("autumn", bar2(Season.AUTUMN))
|
||||
return "OK"
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
enum class Season {
|
||||
WINTER
|
||||
SPRING
|
||||
SUMMER
|
||||
AUTUMN
|
||||
}
|
||||
|
||||
fun foo(x : Season, block : (Season) -> String) = block(x)
|
||||
|
||||
fun box() : String {
|
||||
return foo(Season.SPRING) {
|
||||
x -> when (x) {
|
||||
Season.SPRING -> "OK"
|
||||
else -> "fail"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
enum class Season {
|
||||
WINTER
|
||||
SPRING
|
||||
SUMMER
|
||||
AUTUMN
|
||||
}
|
||||
|
||||
class A {
|
||||
public fun bar1(x : Season) : String {
|
||||
when (x) {
|
||||
Season.WINTER, Season.SPRING -> return "winter_spring"
|
||||
Season.SPRING -> return "spring"
|
||||
Season.SUMMER -> return "summer"
|
||||
}
|
||||
|
||||
return "autumn";
|
||||
}
|
||||
|
||||
public fun bar2(y : Season) : String {
|
||||
return bar3(y) { x ->
|
||||
when (x) {
|
||||
Season.WINTER, Season.SPRING -> "winter_spring"
|
||||
Season.SPRING -> "spring"
|
||||
Season.SUMMER -> "summer"
|
||||
else -> "autumn"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun bar3(x : Season, block : (Season) -> String) = block(x)
|
||||
}
|
||||
|
||||
fun box() : String {
|
||||
val a = A()
|
||||
|
||||
assertEquals("winter_spring", a.bar1(Season.WINTER))
|
||||
assertEquals("winter_spring", a.bar1(Season.SPRING))
|
||||
assertEquals("summer", a.bar1(Season.SUMMER))
|
||||
assertEquals("autumn", a.bar1(Season.AUTUMN))
|
||||
|
||||
assertEquals("winter_spring", a.bar2(Season.WINTER))
|
||||
assertEquals("winter_spring", a.bar2(Season.SPRING))
|
||||
assertEquals("summer", a.bar2(Season.SUMMER))
|
||||
assertEquals("autumn", a.bar2(Season.AUTUMN))
|
||||
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
enum class Season {
|
||||
WINTER
|
||||
SPRING
|
||||
SUMMER
|
||||
AUTUMN
|
||||
}
|
||||
|
||||
fun foo(): Season = Season.SPRING
|
||||
fun bar(): Season = Season.SPRING
|
||||
|
||||
fun box() : String {
|
||||
when (foo()) {
|
||||
bar() -> return "OK"
|
||||
else -> return "fail"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
enum class Season {
|
||||
WINTER
|
||||
SPRING
|
||||
SUMMER
|
||||
AUTUMN
|
||||
}
|
||||
|
||||
fun foo(x : Any) : String {
|
||||
return when (x) {
|
||||
Season.WINTER -> "winter"
|
||||
Season.SPRING -> "spring"
|
||||
Season.SUMMER -> "summer"
|
||||
else -> "other"
|
||||
}
|
||||
}
|
||||
|
||||
fun box() : String {
|
||||
assertEquals("winter", foo(Season.WINTER))
|
||||
assertEquals("spring", foo(Season.SPRING))
|
||||
assertEquals("summer", foo(Season.SUMMER))
|
||||
assertEquals("other", foo(Season.AUTUMN))
|
||||
assertEquals("other", foo(123))
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
enum class Season {
|
||||
WINTER
|
||||
SPRING
|
||||
SUMMER
|
||||
AUTUMN
|
||||
}
|
||||
|
||||
fun bar1(x : Season) : String {
|
||||
when (x) {
|
||||
Season.WINTER, Season.SPRING -> return "winter_spring"
|
||||
Season.SPRING -> return "spring"
|
||||
Season.SUMMER -> return "summer"
|
||||
}
|
||||
return "autumn"
|
||||
}
|
||||
|
||||
fun bar2(x : Season) : String {
|
||||
when (x) {
|
||||
Season.WINTER, Season.SPRING -> return "winter_spring"
|
||||
Season.SPRING -> return "spring"
|
||||
Season.SUMMER -> return "summer"
|
||||
Season.AUTUMN -> return "autumn"
|
||||
}
|
||||
|
||||
return "fail unknown"
|
||||
}
|
||||
|
||||
fun box() : String {
|
||||
assertEquals("winter_spring", bar1(Season.WINTER))
|
||||
assertEquals("winter_spring", bar1(Season.SPRING))
|
||||
assertEquals("summer", bar1(Season.SUMMER))
|
||||
assertEquals("autumn", bar1(Season.AUTUMN))
|
||||
|
||||
assertEquals("winter_spring", bar2(Season.WINTER))
|
||||
assertEquals("winter_spring", bar2(Season.SPRING))
|
||||
assertEquals("summer", bar2(Season.SUMMER))
|
||||
assertEquals("autumn", bar2(Season.AUTUMN))
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
enum class BigEnum {
|
||||
ITEM1 ITEM2 ITEM3 ITEM4 ITEM5 ITEM6 ITEM7 ITEM8 ITEM9 ITEM10 ITEM11 ITEM12 ITEM13 ITEM14 ITEM15 ITEM16 ITEM17 ITEM18 ITEM19 ITEM20
|
||||
}
|
||||
|
||||
fun bar1(x : BigEnum) : String {
|
||||
when (x) {
|
||||
BigEnum.ITEM1, BigEnum.ITEM2, BigEnum.ITEM3 -> return "123"
|
||||
BigEnum.ITEM4, BigEnum.ITEM5, BigEnum.ITEM6 -> return "456"
|
||||
}
|
||||
|
||||
return "-1";
|
||||
|
||||
}
|
||||
|
||||
fun bar2(x : BigEnum) : String {
|
||||
when (x) {
|
||||
BigEnum.ITEM7, BigEnum.ITEM8, BigEnum.ITEM9 -> return "789"
|
||||
BigEnum.ITEM10 -> return "10"
|
||||
BigEnum.ITEM11, BigEnum.ITEM12 -> return "1112"
|
||||
else -> return "-1"
|
||||
}
|
||||
}
|
||||
|
||||
// 2 TABLESWITCH
|
||||
@@ -0,0 +1,18 @@
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
enum class Season {
|
||||
WINTER
|
||||
SPRING
|
||||
SUMMER
|
||||
AUTUMN
|
||||
}
|
||||
|
||||
fun bar(x : Season) : String {
|
||||
when (x) {
|
||||
Season.WINTER, Season.SPRING -> return "winter_spring"
|
||||
Season.SUMMER, Season.SPRING -> return "summer"
|
||||
else -> return "autumn"
|
||||
}
|
||||
}
|
||||
|
||||
// 1 TABLESWITCH
|
||||
@@ -0,0 +1,27 @@
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
enum class Season {
|
||||
WINTER
|
||||
SPRING
|
||||
SUMMER
|
||||
AUTUMN
|
||||
}
|
||||
|
||||
fun bar1(x : Season) : String {
|
||||
return when (x) {
|
||||
Season.WINTER, Season.SPRING -> "winter_spring"
|
||||
Season.SUMMER -> "summer"
|
||||
else -> "autumn"
|
||||
}
|
||||
}
|
||||
|
||||
fun bar2(x : Season) : String {
|
||||
return when (x) {
|
||||
Season.WINTER, Season.SPRING -> "winter_spring"
|
||||
Season.SUMMER -> "summer"
|
||||
Season.AUTUMN -> "autumn"
|
||||
}
|
||||
}
|
||||
|
||||
// 2 TABLESWITCH
|
||||
// 1 @_DefaultPackage-expression-.*\$WhenMappings\.class
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
enum class Season {
|
||||
WINTER
|
||||
SPRING
|
||||
SUMMER
|
||||
AUTUMN
|
||||
}
|
||||
|
||||
fun foo(x : Season, block : (Season) -> String) = block(x)
|
||||
|
||||
fun box() : String {
|
||||
return foo(Season.SPRING) {
|
||||
x -> when (x) {
|
||||
Season.SPRING -> "OK"
|
||||
else -> "fail"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 1 LOOKUPSWITCH
|
||||
// 1 @_DefaultPackage-functionLiteralInTopLevel-[a-z0-9]+\$WhenMappings.class
|
||||
@@ -0,0 +1,36 @@
|
||||
package abc.foo
|
||||
|
||||
enum class Season {
|
||||
WINTER
|
||||
SPRING
|
||||
SUMMER
|
||||
AUTUMN
|
||||
}
|
||||
|
||||
class A {
|
||||
public fun bar1(x : Season) : String {
|
||||
when (x) {
|
||||
Season.WINTER, Season.SPRING -> return "winter_spring"
|
||||
Season.SPRING -> return "spring"
|
||||
Season.SUMMER -> return "summer"
|
||||
}
|
||||
|
||||
return "autumn";
|
||||
}
|
||||
|
||||
public fun bar2(y : Season) : String {
|
||||
return bar3(y) { x ->
|
||||
when (x) {
|
||||
Season.WINTER, Season.SPRING -> "winter_spring"
|
||||
Season.SPRING -> "spring"
|
||||
Season.SUMMER -> "summer"
|
||||
else -> "autumn"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun bar3(x : Season, block : (Season) -> String) = block(x)
|
||||
}
|
||||
|
||||
// 2 TABLESWITCH
|
||||
// 1 @abc/foo/A\$WhenMappings\.class
|
||||
@@ -0,0 +1,18 @@
|
||||
enum class Season {
|
||||
WINTER
|
||||
SPRING
|
||||
SUMMER
|
||||
AUTUMN
|
||||
}
|
||||
|
||||
fun foo(): Season = Season.SPRING
|
||||
fun bar(): Season = Season.SPRING
|
||||
|
||||
fun box() : String {
|
||||
when (foo()) {
|
||||
bar() -> return "OK"
|
||||
else -> return "fail"
|
||||
}
|
||||
}
|
||||
|
||||
// 0 TABLESWITCH
|
||||
@@ -0,0 +1,18 @@
|
||||
enum class Season {
|
||||
WINTER
|
||||
SPRING
|
||||
SUMMER
|
||||
AUTUMN
|
||||
}
|
||||
|
||||
fun foo(x : Any) : String {
|
||||
return when (x) {
|
||||
Season.WINTER -> "winter"
|
||||
Season.SPRING -> "spring"
|
||||
Season.SUMMER -> "summer"
|
||||
else -> "other"
|
||||
}
|
||||
}
|
||||
|
||||
// 0 TABLESWITCH
|
||||
// 0 LOOKUPSWITCH
|
||||
@@ -0,0 +1,31 @@
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
enum class Season {
|
||||
WINTER
|
||||
SPRING
|
||||
SUMMER
|
||||
AUTUMN
|
||||
}
|
||||
|
||||
fun bar1(x : Season) : String {
|
||||
when (x) {
|
||||
Season.WINTER, Season.SPRING -> return "winter_spring"
|
||||
Season.SPRING -> return "spring"
|
||||
Season.SUMMER -> return "summer"
|
||||
}
|
||||
return "autumn"
|
||||
}
|
||||
|
||||
fun bar2(x : Season) : String {
|
||||
when (x) {
|
||||
Season.WINTER, Season.SPRING -> return "winter_spring"
|
||||
Season.SPRING -> return "spring"
|
||||
Season.SUMMER -> return "summer"
|
||||
Season.AUTUMN -> return "autumn"
|
||||
}
|
||||
|
||||
return "fail unknown"
|
||||
}
|
||||
|
||||
// 2 TABLESWITCH
|
||||
// 1 @_DefaultPackage-withoutElse-.*\$WhenMappings\.class
|
||||
@@ -31,7 +31,7 @@ import org.jetbrains.jet.codegen.AbstractBytecodeTextTest;
|
||||
/** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText")
|
||||
@InnerTestClasses({BytecodeTextTestGenerated.BoxingOptimization.class, BytecodeTextTestGenerated.Constants.class, BytecodeTextTestGenerated.DirectInvoke.class, BytecodeTextTestGenerated.Statements.class})
|
||||
@InnerTestClasses({BytecodeTextTestGenerated.BoxingOptimization.class, BytecodeTextTestGenerated.Constants.class, BytecodeTextTestGenerated.DirectInvoke.class, BytecodeTextTestGenerated.Statements.class, BytecodeTextTestGenerated.WhenEnumOptimization.class})
|
||||
public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
||||
@TestMetadata("accessorForProtected.kt")
|
||||
public void testAccessorForProtected() throws Exception {
|
||||
@@ -304,6 +304,54 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/whenEnumOptimization")
|
||||
public static class WhenEnumOptimization extends AbstractBytecodeTextTest {
|
||||
public void testAllFilesPresentInWhenEnumOptimization() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/bytecodeText/whenEnumOptimization"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("bigEnum.kt")
|
||||
public void testBigEnum() throws Exception {
|
||||
doTest("compiler/testData/codegen/bytecodeText/whenEnumOptimization/bigEnum.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("duplicatingItems.kt")
|
||||
public void testDuplicatingItems() throws Exception {
|
||||
doTest("compiler/testData/codegen/bytecodeText/whenEnumOptimization/duplicatingItems.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("expression.kt")
|
||||
public void testExpression() throws Exception {
|
||||
doTest("compiler/testData/codegen/bytecodeText/whenEnumOptimization/expression.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("functionLiteralInTopLevel.kt")
|
||||
public void testFunctionLiteralInTopLevel() throws Exception {
|
||||
doTest("compiler/testData/codegen/bytecodeText/whenEnumOptimization/functionLiteralInTopLevel.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("manyWhensWithinClass.kt")
|
||||
public void testManyWhensWithinClass() throws Exception {
|
||||
doTest("compiler/testData/codegen/bytecodeText/whenEnumOptimization/manyWhensWithinClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nonConstantEnum.kt")
|
||||
public void testNonConstantEnum() throws Exception {
|
||||
doTest("compiler/testData/codegen/bytecodeText/whenEnumOptimization/nonConstantEnum.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("subjectAny.kt")
|
||||
public void testSubjectAny() throws Exception {
|
||||
doTest("compiler/testData/codegen/bytecodeText/whenEnumOptimization/subjectAny.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("withoutElse.kt")
|
||||
public void testWithoutElse() throws Exception {
|
||||
doTest("compiler/testData/codegen/bytecodeText/whenEnumOptimization/withoutElse.kt");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
TestSuite suite = new TestSuite("BytecodeTextTestGenerated");
|
||||
suite.addTestSuite(BytecodeTextTestGenerated.class);
|
||||
@@ -311,6 +359,7 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
||||
suite.addTestSuite(Constants.class);
|
||||
suite.addTestSuite(DirectInvoke.class);
|
||||
suite.addTestSuite(Statements.class);
|
||||
suite.addTestSuite(WhenEnumOptimization.class);
|
||||
return suite;
|
||||
}
|
||||
}
|
||||
|
||||
+55
-1
@@ -31,7 +31,7 @@ import org.jetbrains.jet.codegen.generated.AbstractBlackBoxCodegenTest;
|
||||
/** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("compiler/testData/codegen/boxWithStdlib")
|
||||
@InnerTestClasses({BlackBoxWithStdlibCodegenTestGenerated.Annotations.class, BlackBoxWithStdlibCodegenTestGenerated.Arrays.class, BlackBoxWithStdlibCodegenTestGenerated.BoxingOptimization.class, BlackBoxWithStdlibCodegenTestGenerated.CallableReference.class, BlackBoxWithStdlibCodegenTestGenerated.Casts.class, BlackBoxWithStdlibCodegenTestGenerated.DataClasses.class, BlackBoxWithStdlibCodegenTestGenerated.Evaluate.class, BlackBoxWithStdlibCodegenTestGenerated.FullJdk.class, BlackBoxWithStdlibCodegenTestGenerated.HashPMap.class, BlackBoxWithStdlibCodegenTestGenerated.JdkAnnotations.class, BlackBoxWithStdlibCodegenTestGenerated.PlatformNames.class, BlackBoxWithStdlibCodegenTestGenerated.Ranges.class, BlackBoxWithStdlibCodegenTestGenerated.Reflection.class, BlackBoxWithStdlibCodegenTestGenerated.Regressions.class, BlackBoxWithStdlibCodegenTestGenerated.Strings.class, BlackBoxWithStdlibCodegenTestGenerated.ToArray.class, BlackBoxWithStdlibCodegenTestGenerated.Vararg.class, BlackBoxWithStdlibCodegenTestGenerated.When.class})
|
||||
@InnerTestClasses({BlackBoxWithStdlibCodegenTestGenerated.Annotations.class, BlackBoxWithStdlibCodegenTestGenerated.Arrays.class, BlackBoxWithStdlibCodegenTestGenerated.BoxingOptimization.class, BlackBoxWithStdlibCodegenTestGenerated.CallableReference.class, BlackBoxWithStdlibCodegenTestGenerated.Casts.class, BlackBoxWithStdlibCodegenTestGenerated.DataClasses.class, BlackBoxWithStdlibCodegenTestGenerated.Evaluate.class, BlackBoxWithStdlibCodegenTestGenerated.FullJdk.class, BlackBoxWithStdlibCodegenTestGenerated.HashPMap.class, BlackBoxWithStdlibCodegenTestGenerated.JdkAnnotations.class, BlackBoxWithStdlibCodegenTestGenerated.PlatformNames.class, BlackBoxWithStdlibCodegenTestGenerated.Ranges.class, BlackBoxWithStdlibCodegenTestGenerated.Reflection.class, BlackBoxWithStdlibCodegenTestGenerated.Regressions.class, BlackBoxWithStdlibCodegenTestGenerated.Strings.class, BlackBoxWithStdlibCodegenTestGenerated.ToArray.class, BlackBoxWithStdlibCodegenTestGenerated.Vararg.class, BlackBoxWithStdlibCodegenTestGenerated.When.class, BlackBoxWithStdlibCodegenTestGenerated.WhenEnumOptimization.class})
|
||||
public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
public void testAllFilesPresentInBoxWithStdlib() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/boxWithStdlib"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
@@ -1952,6 +1952,59 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxWithStdlib/whenEnumOptimization")
|
||||
public static class WhenEnumOptimization extends AbstractBlackBoxCodegenTest {
|
||||
public void testAllFilesPresentInWhenEnumOptimization() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/boxWithStdlib/whenEnumOptimization"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("bigEnum.kt")
|
||||
public void testBigEnum() throws Exception {
|
||||
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/whenEnumOptimization/bigEnum.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("duplicatingItems.kt")
|
||||
public void testDuplicatingItems() throws Exception {
|
||||
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/whenEnumOptimization/duplicatingItems.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("enumInsideClassObject.kt")
|
||||
public void testEnumInsideClassObject() throws Exception {
|
||||
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/whenEnumOptimization/enumInsideClassObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("expression.kt")
|
||||
public void testExpression() throws Exception {
|
||||
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/whenEnumOptimization/expression.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("functionLiteralInTopLevel.kt")
|
||||
public void testFunctionLiteralInTopLevel() throws Exception {
|
||||
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/whenEnumOptimization/functionLiteralInTopLevel.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("manyWhensWithinClass.kt")
|
||||
public void testManyWhensWithinClass() throws Exception {
|
||||
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/whenEnumOptimization/manyWhensWithinClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nonConstantEnum.kt")
|
||||
public void testNonConstantEnum() throws Exception {
|
||||
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/whenEnumOptimization/nonConstantEnum.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("subjectAny.kt")
|
||||
public void testSubjectAny() throws Exception {
|
||||
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/whenEnumOptimization/subjectAny.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("withoutElse.kt")
|
||||
public void testWithoutElse() throws Exception {
|
||||
doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/whenEnumOptimization/withoutElse.kt");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
TestSuite suite = new TestSuite("BlackBoxWithStdlibCodegenTestGenerated");
|
||||
suite.addTestSuite(BlackBoxWithStdlibCodegenTestGenerated.class);
|
||||
@@ -1973,6 +2026,7 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
||||
suite.addTestSuite(ToArray.class);
|
||||
suite.addTestSuite(Vararg.class);
|
||||
suite.addTestSuite(When.class);
|
||||
suite.addTestSuite(WhenEnumOptimization.class);
|
||||
return suite;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user