KT-2589 fix: putting some order on bytecode flags

This commit is contained in:
Alex Tkachman
2012-08-09 13:35:44 +03:00
parent f5e9786ffc
commit 6af235fe2b
10 changed files with 105 additions and 63 deletions
+30
View File
@@ -0,0 +1,30 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="All Jvm Backend Tests" type="JUnit" factoryName="JUnit">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea">
<pattern>
<option name="PATTERN" value="org.jetbrains.jet.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<module name="compiler-tests" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" value="" />
<option name="PACKAGE_NAME" value="org.jetbrains.jet.codegen" />
<option name="MAIN_CLASS_NAME" value="" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="package" />
<option name="VM_PARAMETERS" value="-ea -XX:+HeapDumpOnOutOfMemoryError -Xmx512m -XX:MaxPermSize=320m" />
<option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="wholeProject" />
</option>
<envs />
<patterns />
<RunnerSettings RunnerId="Run" />
<ConfigurationWrapper RunnerId="Run" />
<method />
</configuration>
</component>
@@ -16,7 +16,6 @@
package org.jetbrains.jet.codegen;
import org.jetbrains.asm4.FieldVisitor;
import org.jetbrains.asm4.MethodVisitor;
import org.jetbrains.asm4.Opcodes;
import org.jetbrains.asm4.Type;
@@ -25,14 +24,12 @@ import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static org.jetbrains.asm4.Opcodes.ACC_ABSTRACT;
import static org.jetbrains.asm4.Opcodes.ACC_PRIVATE;
import static org.jetbrains.asm4.Opcodes.ACC_PUBLIC;
/**
@@ -100,26 +97,10 @@ public abstract class ClassBodyCodegen {
PropertyDescriptor propertyDescriptor = state.getBindingContext().get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, p);
if (propertyDescriptor != null) {
if (!isAnnotation) {
int accessModifiers = JetTypeMapper.getAccessModifiers(propertyDescriptor, 0);
if((accessModifiers & ACC_PRIVATE) == 0) {
propertyCodegen.generateDefaultGetter(propertyDescriptor, accessModifiers, p);
if (propertyDescriptor.isVar()) {
propertyCodegen.generateDefaultSetter(propertyDescriptor, accessModifiers, origin);
}
}
//noinspection ConstantConditions
if (!(kind instanceof OwnerKind.DelegateKind) && state.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) {
int modifiers = accessModifiers;
if (!propertyDescriptor.isVar()) {
modifiers |= Opcodes.ACC_FINAL;
}
if (JetStandardLibrary.isVolatile(propertyDescriptor)) {
modifiers |= Opcodes.ACC_VOLATILE;
}
Type type = state.getInjector().getJetTypeMapper().mapType(propertyDescriptor.getType(), MapTypeMode.VALUE);
FieldVisitor fieldVisitor = v.newField(p, modifiers, p.getName(), type.getDescriptor(), null, null);
AnnotationCodegen.forField(fieldVisitor, state.getInjector().getJetTypeMapper()).genAnnotations(propertyDescriptor);
propertyCodegen.generateBackingField(p, propertyDescriptor);
propertyCodegen.generateDefaultGetter(propertyDescriptor, JetTypeMapper.getAccessModifiers(propertyDescriptor,0), p);
if (propertyDescriptor.isVar()) {
propertyCodegen.generateDefaultSetter(propertyDescriptor, JetTypeMapper.getAccessModifiers(propertyDescriptor,0), p);
}
}
else {
@@ -1027,18 +1027,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
}
}
for (JetParameter p : toClass.getPrimaryConstructorParameters()) {
if (p.getValOrVarNode() != null) {
PropertyDescriptor propertyDescriptor = bindingContext.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, p);
if (propertyDescriptor != null) {
propertyCodegen.generateDefaultGetter(propertyDescriptor, ACC_PUBLIC, p);
if (propertyDescriptor.isVar()) {
propertyCodegen.generateDefaultSetter(propertyDescriptor, ACC_PUBLIC, p);
}
}
}
}
}
@Nullable
@@ -1002,7 +1002,7 @@ public class JetTypeMapper {
return defaultFlags;
}
if (p.getContainingDeclaration() instanceof NamespaceDescriptor) {
return ACC_PROTECTED;
return 0;
}
return ACC_PRIVATE;
}
@@ -41,6 +41,7 @@ import java.util.BitSet;
/**
* @author max
* @author alex.tkachman
*/
public class PropertyCodegen {
private final GenerationState state;
@@ -75,14 +76,14 @@ public class PropertyCodegen {
}
}
private void generateBackingField(JetProperty p, PropertyDescriptor propertyDescriptor) {
public void generateBackingField(PsiElement p, PropertyDescriptor propertyDescriptor) {
if (state.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) {
DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration();
if (CodegenUtil.isInterface(containingDeclaration))
return;
Object value = null;
final JetExpression initializer = p.getInitializer();
final JetExpression initializer = p instanceof JetProperty ? ((JetProperty)p).getInitializer() : null;
if (initializer != null) {
if (initializer instanceof JetConstantExpression) {
CompileTimeConstant<?> compileTimeValue = state.getBindingContext().get(BindingContext.COMPILE_TIME_VALUE, initializer);
@@ -91,11 +92,10 @@ public class PropertyCodegen {
}
int modifiers;
if (kind == OwnerKind.NAMESPACE) {
int access = JetTypeMapper.getAccessModifiers(propertyDescriptor, 0);
modifiers = access | Opcodes.ACC_STATIC;
modifiers = Opcodes.ACC_STATIC;
}
else {
modifiers = JetTypeMapper.getAccessModifiers(propertyDescriptor, 0);
modifiers = Opcodes.ACC_PRIVATE;
}
if (!propertyDescriptor.isVar()) {
modifiers |= Opcodes.ACC_FINAL;
@@ -104,7 +104,7 @@ public class PropertyCodegen {
modifiers |= Opcodes.ACC_VOLATILE;
}
Type type = state.getInjector().getJetTypeMapper().mapType(propertyDescriptor.getType(), MapTypeMode.VALUE);
FieldVisitor fieldVisitor = v.newField(p, modifiers, p.getName(), type.getDescriptor(), null, value);
FieldVisitor fieldVisitor = v.newField(p, modifiers, propertyDescriptor.getName().getName(), type.getDescriptor(), null, value);
AnnotationCodegen.forField(fieldVisitor, state.getInjector().getJetTypeMapper()).genAnnotations(propertyDescriptor);
}
}
@@ -150,7 +150,8 @@ public class PropertyCodegen {
private void generateDefaultGetter(JetProperty p) {
final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, p);
int flags = JetTypeMapper.getAccessModifiers(propertyDescriptor, 0) | (propertyDescriptor.getModality() == Modality.ABSTRACT ? Opcodes.ACC_ABSTRACT : 0);
assert propertyDescriptor != null;
int flags = JetTypeMapper.getAccessModifiers(propertyDescriptor, 0) | (propertyDescriptor.getModality() == Modality.ABSTRACT ? Opcodes.ACC_ABSTRACT : (propertyDescriptor.getModality() == Modality.FINAL ? Opcodes.ACC_FINAL : 0));
generateDefaultGetter(propertyDescriptor, flags, p);
}
@@ -21,7 +21,6 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.DescriptorResolver;
import org.jetbrains.jet.lang.resolve.ScriptNameUtil;
import org.jetbrains.jet.lang.resolve.name.FqName;
@@ -34,11 +33,9 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ScriptReceiver;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeProjection;
import org.jetbrains.jet.lang.types.TypeSubstitutor;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
@@ -106,17 +103,8 @@ public class ScriptDescriptor extends DeclarationDescriptorNonRootImpl {
if(jetDeclaration instanceof JetProperty) {
VariableDescriptor descriptor = bindingContext.get(BindingContext.VARIABLE, jetDeclaration);
assert descriptor != null;
propertyDescriptor = new PropertyDescriptor(classDescriptor,
Collections.<AnnotationDescriptor>emptyList(),
Modality.FINAL,
propertyDescriptor.getVisibility(),
false,
false,
descriptor.getName(),
CallableMemberDescriptor.Kind.DECLARATION);
propertyDescriptor.setType(returnType, Collections.<TypeParameterDescriptor>emptyList(), classReceiver, ReceiverDescriptor.NO_RECEIVER);
propertyDescriptor.initialize(null, null);
classScope.addPropertyDescriptor(propertyDescriptor);
initializeWithDefaultGetterSetter((PropertyDescriptor) descriptor);
classScope.addPropertyDescriptor(descriptor);
}
else if(jetDeclaration instanceof JetNamedFunction) {
SimpleFunctionDescriptor descriptor = bindingContext.get(BindingContext.FUNCTION, jetDeclaration);
@@ -128,6 +116,21 @@ public class ScriptDescriptor extends DeclarationDescriptorNonRootImpl {
}
}
public static void initializeWithDefaultGetterSetter(PropertyDescriptor propertyDescriptor) {
PropertyGetterDescriptor getter = propertyDescriptor.getGetter();
if(getter == null) {
getter = propertyDescriptor.getVisibility() != Visibilities.PRIVATE ? DescriptorResolver.createDefaultGetter(propertyDescriptor) : null;
if(getter != null)
getter.initialize(propertyDescriptor.getType());
}
PropertySetterDescriptor setter = propertyDescriptor.getSetter();
if(setter == null) {
setter = propertyDescriptor.isVar() ? DescriptorResolver.createDefaultSetter(propertyDescriptor) : null;
}
propertyDescriptor.initialize(getter, setter);
}
public int getPriority() {
return priority;
}
@@ -372,7 +372,7 @@ public class DescriptorResolver {
return constructorDescriptor;
}
final class UpperBoundCheckerTask {
static final class UpperBoundCheckerTask {
JetTypeReference upperBound;
JetType upperBoundType;
boolean isClassObjectConstraint;
@@ -834,7 +834,7 @@ public class DescriptorResolver {
return setterDescriptor;
}
private PropertySetterDescriptor createDefaultSetter(PropertyDescriptor propertyDescriptor) {
public static PropertySetterDescriptor createDefaultSetter(PropertyDescriptor propertyDescriptor) {
PropertySetterDescriptor setterDescriptor;
setterDescriptor = new PropertySetterDescriptor(
propertyDescriptor, Collections.<AnnotationDescriptor>emptyList(), propertyDescriptor.getModality(),
@@ -0,0 +1 @@
open class Foo(var foo: String?, open protected val bar: String?)
@@ -16,6 +16,7 @@
package org.jetbrains.jet.codegen;
import org.jetbrains.asm4.Opcodes;
import org.jetbrains.jet.ConfigurationKind;
import java.lang.reflect.Constructor;
@@ -81,7 +82,7 @@ public class PropertyGenTest extends CodegenTestCase {
final Field field = fields[0];
field.setAccessible(true);
assertEquals("x", field.getName());
assertEquals(Modifier.PROTECTED | Modifier.STATIC | Modifier.FINAL, field.getModifiers());
assertEquals(Modifier.STATIC | Modifier.FINAL, field.getModifiers());
assertEquals(239, field.get(null));
}
@@ -279,4 +280,32 @@ public class PropertyGenTest extends CodegenTestCase {
blackBoxFile("regressions/kt2509.kt");
}
public void testKt2589() throws Exception {
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
loadFile("regressions/kt2589.kt");
final Class aClass = loadImplementationClass(generateClassesInFile(), "Foo");
assertTrue((aClass.getModifiers() & Opcodes.ACC_FINAL) == 0);
try {
Field foo = aClass.getDeclaredField("foo");
assertTrue((foo.getModifiers() & Opcodes.ACC_PRIVATE) != 0);
assertTrue((foo.getModifiers() & Opcodes.ACC_FINAL) == 0);
Field bar = aClass.getDeclaredField("bar");
assertTrue((bar.getModifiers() & Opcodes.ACC_PRIVATE) != 0);
assertTrue((bar.getModifiers() & Opcodes.ACC_FINAL) != 0);
Method getFoo = aClass.getDeclaredMethod("getFoo");
assertTrue((getFoo.getModifiers() & Opcodes.ACC_PUBLIC) != 0);
assertTrue((getFoo.getModifiers() & Opcodes.ACC_FINAL) != 0);
Method getBar = aClass.getDeclaredMethod("getBar");
assertTrue((getBar.getModifiers() & Opcodes.ACC_PROTECTED) != 0);
assertTrue((getBar.getModifiers() & Opcodes.ACC_FINAL) == 0);
}
catch (Throwable e) {
System.out.println(generateToText());
throw new RuntimeException(e);
}
}
}
@@ -17,6 +17,7 @@
package org.jetbrains.jet.codegen;
import com.intellij.openapi.components.ServiceManager;
import org.jetbrains.asm4.Opcodes;
import org.jetbrains.jet.ConfigurationKind;
import org.jetbrains.jet.lang.parsing.JetParserDefinition;
import org.jetbrains.jet.lang.parsing.JetScriptDefinition;
@@ -106,7 +107,8 @@ public class ScriptGenTest extends CodegenTestCase {
final Class aClass = loadClass("Fib", generateClassesInFile());
try {
Constructor constructor = aClass.getConstructor(int.class);
Field result = aClass.getField("result");
Field result = aClass.getDeclaredField("result");
result.setAccessible(true);
Object script = constructor.newInstance(5);
assertEquals(8,result.get(script));
}
@@ -121,7 +123,8 @@ public class ScriptGenTest extends CodegenTestCase {
final Class aClass = loadClass("test.Fibwp", generateClassesInFile());
try {
Constructor constructor = aClass.getConstructor(int.class);
Field result = aClass.getField("result");
Field result = aClass.getDeclaredField("result");
result.setAccessible(true);
Object script = constructor.newInstance(5);
assertEquals(8,result.get(script));
}
@@ -136,11 +139,17 @@ public class ScriptGenTest extends CodegenTestCase {
final Class aClass = loadClass("Fibwprunner", generateClassesInFile());
try {
Constructor constructor = aClass.getConstructor();
Field result = aClass.getField("result");
Field result = aClass.getDeclaredField("result");
result.setAccessible(true);
Method resultMethod = aClass.getDeclaredMethod("getResult");
assertTrue((resultMethod.getModifiers() & Opcodes.ACC_FINAL) != 0);
assertTrue((resultMethod.getModifiers() & Opcodes.ACC_PUBLIC) != 0);
Field rv = aClass.getField("rv");
assertTrue((result.getModifiers() & Opcodes.ACC_PRIVATE) != 0);
Object script = constructor.newInstance();
assertEquals(12,rv.get(script));
assertEquals(8,result.get(script));
assertEquals(8,resultMethod.invoke(script));
}
catch (Exception e) {
throw new RuntimeException(e);