KT-2589 fix: putting some order on bytecode flags
This commit is contained in:
+30
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user