enum entries which overrides methods
This commit is contained in:
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.jet.codegen;
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.ClassKind;
|
||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
@@ -58,7 +59,12 @@ public class ClassCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (JetDeclaration declaration : aClass.getDeclarations()) {
|
for (JetDeclaration declaration : aClass.getDeclarations()) {
|
||||||
if (declaration instanceof JetClass && !(declaration instanceof JetEnumEntry)) {
|
if (declaration instanceof JetClass) {
|
||||||
|
if (declaration instanceof JetEnumEntry && !state.getInjector().getClosureAnnotator().enumEntryNeedSubclass(
|
||||||
|
(JetEnumEntry) declaration)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
generate(contextForInners, (JetClass) declaration);
|
generate(contextForInners, (JetClass) declaration);
|
||||||
}
|
}
|
||||||
if (declaration instanceof JetClassObject) {
|
if (declaration instanceof JetClassObject) {
|
||||||
@@ -73,7 +79,13 @@ public class ClassCodegen {
|
|||||||
classBuilder.done();
|
classBuilder.done();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateImplementation(CodegenContext context, JetClassOrObject aClass, OwnerKind kind, HashMap<DeclarationDescriptor, DeclarationDescriptor> accessors, ClassBuilder classBuilder) {
|
private void generateImplementation(
|
||||||
|
CodegenContext context,
|
||||||
|
JetClassOrObject aClass,
|
||||||
|
OwnerKind kind,
|
||||||
|
HashMap<DeclarationDescriptor, DeclarationDescriptor> accessors,
|
||||||
|
ClassBuilder classBuilder
|
||||||
|
) {
|
||||||
ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass);
|
ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass);
|
||||||
CodegenContext classContext = context.intoClass(descriptor, kind, jetTypeMapper);
|
CodegenContext classContext = context.intoClass(descriptor, kind, jetTypeMapper);
|
||||||
classContext.copyAccessors(accessors);
|
classContext.copyAccessors(accessors);
|
||||||
@@ -81,7 +93,8 @@ public class ClassCodegen {
|
|||||||
|
|
||||||
if (aClass instanceof JetClass && ((JetClass) aClass).isTrait()) {
|
if (aClass instanceof JetClass && ((JetClass) aClass).isTrait()) {
|
||||||
ClassBuilder traitBuilder = state.forTraitImplementation(descriptor);
|
ClassBuilder traitBuilder = state.forTraitImplementation(descriptor);
|
||||||
new TraitImplBodyCodegen(aClass, context.intoClass(descriptor, OwnerKind.TRAIT_IMPL, jetTypeMapper), traitBuilder, state).generate();
|
new TraitImplBodyCodegen(aClass, context.intoClass(descriptor, OwnerKind.TRAIT_IMPL, jetTypeMapper), traitBuilder, state)
|
||||||
|
.generate();
|
||||||
traitBuilder.done();
|
traitBuilder.done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ public class ClosureAnnotator {
|
|||||||
|
|
||||||
private BindingContext bindingContext;
|
private BindingContext bindingContext;
|
||||||
private List<JetFile> files;
|
private List<JetFile> files;
|
||||||
|
private final Map<ClassDescriptor, Boolean> enumEntryNeedSubclass = new HashMap<ClassDescriptor, Boolean>();
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public void setBindingContext(BindingContext bindingContext) {
|
public void setBindingContext(BindingContext bindingContext) {
|
||||||
@@ -229,6 +230,16 @@ public class ClosureAnnotator {
|
|||||||
return other != null;
|
return other != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean enumEntryNeedSubclass(JetEnumEntry enumEntry) {
|
||||||
|
ClassDescriptor descriptor = bindingContext.get(BindingContext.CLASS, enumEntry);
|
||||||
|
return enumEntryNeedSubclass.get(descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean enumEntryNeedSubclass(ClassDescriptor enumEntry) {
|
||||||
|
Boolean aBoolean = enumEntryNeedSubclass.get(enumEntry);
|
||||||
|
return aBoolean != null && aBoolean;
|
||||||
|
}
|
||||||
|
|
||||||
private class MyJetVisitorVoid extends JetVisitorVoid {
|
private class MyJetVisitorVoid extends JetVisitorVoid {
|
||||||
private final LinkedList<ClassDescriptor> classStack = new LinkedList<ClassDescriptor>();
|
private final LinkedList<ClassDescriptor> classStack = new LinkedList<ClassDescriptor>();
|
||||||
private final LinkedList<String> nameStack = new LinkedList<String>();
|
private final LinkedList<String> nameStack = new LinkedList<String>();
|
||||||
@@ -285,6 +296,13 @@ public class ClosureAnnotator {
|
|||||||
nameStack.pop();
|
nameStack.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitEnumEntry(JetEnumEntry enumEntry) {
|
||||||
|
ClassDescriptor descriptor = bindingContext.get(BindingContext.CLASS, enumEntry);
|
||||||
|
enumEntryNeedSubclass.put(descriptor, !enumEntry.getDeclarations().isEmpty());
|
||||||
|
super.visitEnumEntry(enumEntry);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitClassObject(JetClassObject classObject) {
|
public void visitClassObject(JetClassObject classObject) {
|
||||||
JvmClassName name = recordClassObject(classObject);
|
JvmClassName name = recordClassObject(classObject);
|
||||||
|
|||||||
@@ -43,7 +43,9 @@ public class ConstructorFrameMap extends FrameMap {
|
|||||||
|
|
||||||
List<Type> explicitArgTypes = callableMethod.getValueParameterTypes();
|
List<Type> explicitArgTypes = callableMethod.getValueParameterTypes();
|
||||||
|
|
||||||
if(descriptor != null && descriptor.getContainingDeclaration().getKind() == ClassKind.ENUM_CLASS) {
|
if (descriptor != null &&
|
||||||
|
(descriptor.getContainingDeclaration().getKind() == ClassKind.ENUM_CLASS ||
|
||||||
|
descriptor.getContainingDeclaration().getKind() == ClassKind.ENUM_ENTRY)) {
|
||||||
enterTemp(); // name
|
enterTemp(); // name
|
||||||
enterTemp(); // ordinal
|
enterTemp(); // ordinal
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,11 +101,13 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public ExpressionCodegen(MethodVisitor v,
|
public ExpressionCodegen(
|
||||||
|
MethodVisitor v,
|
||||||
FrameMap myMap,
|
FrameMap myMap,
|
||||||
Type returnType,
|
Type returnType,
|
||||||
CodegenContext context,
|
CodegenContext context,
|
||||||
GenerationState state) {
|
GenerationState state
|
||||||
|
) {
|
||||||
this.myFrameMap = myMap;
|
this.myFrameMap = myMap;
|
||||||
this.typeMapper = state.getInjector().getJetTypeMapper();
|
this.typeMapper = state.getInjector().getJetTypeMapper();
|
||||||
this.returnType = returnType;
|
this.returnType = returnType;
|
||||||
@@ -123,11 +125,13 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
StackValue castToRequiredTypeOfInterfaceIfNeeded(StackValue inner, DeclarationDescriptor provided, @Nullable ClassDescriptor required) {
|
StackValue castToRequiredTypeOfInterfaceIfNeeded(StackValue inner, DeclarationDescriptor provided, @Nullable ClassDescriptor required) {
|
||||||
if (required == null)
|
if (required == null) {
|
||||||
return inner;
|
return inner;
|
||||||
|
}
|
||||||
|
|
||||||
if (provided instanceof CallableDescriptor)
|
if (provided instanceof CallableDescriptor) {
|
||||||
provided = ((CallableDescriptor) provided).getReceiverParameter().getType().getConstructor().getDeclarationDescriptor();
|
provided = ((CallableDescriptor) provided).getReceiverParameter().getType().getConstructor().getDeclarationDescriptor();
|
||||||
|
}
|
||||||
|
|
||||||
assert provided instanceof ClassDescriptor;
|
assert provided instanceof ClassDescriptor;
|
||||||
|
|
||||||
@@ -229,8 +233,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isEmptyExpression(JetElement expr) {
|
private static boolean isEmptyExpression(JetElement expr) {
|
||||||
if (expr == null)
|
if (expr == null) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
if (expr instanceof JetBlockExpression) {
|
if (expr instanceof JetBlockExpression) {
|
||||||
JetBlockExpression blockExpression = (JetBlockExpression) expr;
|
JetBlockExpression blockExpression = (JetBlockExpression) expr;
|
||||||
List<JetElement> statements = blockExpression.getStatements();
|
List<JetElement> statements = blockExpression.getStatements();
|
||||||
@@ -361,12 +366,15 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
FunctionDescriptor nextDescriptor = bindingContext.get(BindingContext.LOOP_RANGE_NEXT, loopRange);
|
FunctionDescriptor nextDescriptor = bindingContext.get(BindingContext.LOOP_RANGE_NEXT, loopRange);
|
||||||
DeclarationDescriptor hasNextDescriptor = bindingContext.get(BindingContext.LOOP_RANGE_HAS_NEXT, loopRange);
|
DeclarationDescriptor hasNextDescriptor = bindingContext.get(BindingContext.LOOP_RANGE_HAS_NEXT, loopRange);
|
||||||
|
|
||||||
if (iteratorDescriptor == null)
|
if (iteratorDescriptor == null) {
|
||||||
throw new IllegalStateException("No iterator() method " + DiagnosticUtils.atLocation(loopRange));
|
throw new IllegalStateException("No iterator() method " + DiagnosticUtils.atLocation(loopRange));
|
||||||
if (nextDescriptor == null)
|
}
|
||||||
|
if (nextDescriptor == null) {
|
||||||
throw new IllegalStateException("No next() method " + DiagnosticUtils.atLocation(loopRange));
|
throw new IllegalStateException("No next() method " + DiagnosticUtils.atLocation(loopRange));
|
||||||
if (hasNextDescriptor == null)
|
}
|
||||||
|
if (hasNextDescriptor == null) {
|
||||||
throw new IllegalStateException("No hasNext method or property" + DiagnosticUtils.atLocation(loopRange));
|
throw new IllegalStateException("No hasNext method or property" + DiagnosticUtils.atLocation(loopRange));
|
||||||
|
}
|
||||||
|
|
||||||
final JetParameter loopParameter = expression.getLoopParameter();
|
final JetParameter loopParameter = expression.getLoopParameter();
|
||||||
final VariableDescriptor parameterDescriptor = bindingContext.get(BindingContext.VALUE_PARAMETER, loopParameter);
|
final VariableDescriptor parameterDescriptor = bindingContext.get(BindingContext.VALUE_PARAMETER, loopParameter);
|
||||||
@@ -647,7 +655,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
else if (stackElement instanceof LoopBlockStackElement) {
|
else if (stackElement instanceof LoopBlockStackElement) {
|
||||||
LoopBlockStackElement loopBlockStackElement = (LoopBlockStackElement) stackElement;
|
LoopBlockStackElement loopBlockStackElement = (LoopBlockStackElement) stackElement;
|
||||||
if (labelElement == null || loopBlockStackElement.targetLabel != null && labelElement.getReferencedName().equals(loopBlockStackElement.targetLabel.getReferencedName())) {
|
if (labelElement == null ||
|
||||||
|
loopBlockStackElement.targetLabel != null &&
|
||||||
|
labelElement.getReferencedName().equals(loopBlockStackElement.targetLabel.getReferencedName())) {
|
||||||
v.goTo(loopBlockStackElement.breakLabel);
|
v.goTo(loopBlockStackElement.breakLabel);
|
||||||
return StackValue.none();
|
return StackValue.none();
|
||||||
}
|
}
|
||||||
@@ -673,7 +683,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
else if (stackElement instanceof LoopBlockStackElement) {
|
else if (stackElement instanceof LoopBlockStackElement) {
|
||||||
LoopBlockStackElement loopBlockStackElement = (LoopBlockStackElement) stackElement;
|
LoopBlockStackElement loopBlockStackElement = (LoopBlockStackElement) stackElement;
|
||||||
if (labelElement == null || loopBlockStackElement.targetLabel != null && labelElement.getReferencedName().equals(loopBlockStackElement.targetLabel.getReferencedName())) {
|
if (labelElement == null ||
|
||||||
|
loopBlockStackElement.targetLabel != null &&
|
||||||
|
labelElement.getReferencedName().equals(loopBlockStackElement.targetLabel.getReferencedName())) {
|
||||||
v.goTo(loopBlockStackElement.continueLabel);
|
v.goTo(loopBlockStackElement.continueLabel);
|
||||||
return StackValue.none();
|
return StackValue.none();
|
||||||
}
|
}
|
||||||
@@ -809,7 +821,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
|
|
||||||
if (closure.isCaptureReceiver() != null) {
|
if (closure.isCaptureReceiver() != null) {
|
||||||
k++;
|
k++;
|
||||||
v.load(context.getContextDescriptor().getContainingDeclaration() instanceof NamespaceDescriptor ? 0: 1, closure.isCaptureReceiver());
|
v.load(context.getContextDescriptor().getContainingDeclaration() instanceof NamespaceDescriptor ? 0 : 1,
|
||||||
|
closure.isCaptureReceiver());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < closure.getArgs().size(); i++) {
|
for (int i = 0; i < closure.getArgs().size(); i++) {
|
||||||
@@ -843,16 +856,22 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
for (Map.Entry<DeclarationDescriptor, EnclosedValueDescriptor> entry : closureCodegen.closure.entrySet()) {
|
for (Map.Entry<DeclarationDescriptor, EnclosedValueDescriptor> entry : closureCodegen.closure.entrySet()) {
|
||||||
if (entry.getKey() instanceof VariableDescriptor && !(entry.getKey() instanceof PropertyDescriptor)) {
|
if (entry.getKey() instanceof VariableDescriptor && !(entry.getKey() instanceof PropertyDescriptor)) {
|
||||||
Type sharedVarType = typeMapper.getSharedVarType(entry.getKey());
|
Type sharedVarType = typeMapper.getSharedVarType(entry.getKey());
|
||||||
if (sharedVarType == null)
|
if (sharedVarType == null) {
|
||||||
sharedVarType = state.getInjector().getJetTypeMapper().mapType(((VariableDescriptor) entry.getKey()).getType(), MapTypeMode.VALUE);
|
sharedVarType = state.getInjector().getJetTypeMapper()
|
||||||
|
.mapType(((VariableDescriptor) entry.getKey()).getType(), MapTypeMode.VALUE);
|
||||||
|
}
|
||||||
consArgTypes.add(sharedVarType);
|
consArgTypes.add(sharedVarType);
|
||||||
entry.getValue().getOuterValue().put(sharedVarType, v);
|
entry.getValue().getOuterValue().put(sharedVarType, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (closureCodegen.superCall != null) {
|
if (closureCodegen.superCall != null) {
|
||||||
ConstructorDescriptor superConstructor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, closureCodegen.superCall.getCalleeExpression().getConstructorReferenceExpression());
|
ConstructorDescriptor superConstructor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET,
|
||||||
CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION, typeMapper.hasThis0(superConstructor.getContainingDeclaration()));
|
closureCodegen.superCall
|
||||||
|
.getCalleeExpression()
|
||||||
|
.getConstructorReferenceExpression());
|
||||||
|
CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION,
|
||||||
|
typeMapper.hasThis0(superConstructor.getContainingDeclaration()));
|
||||||
Type[] argumentTypes = superCallable.getSignature().getAsmMethod().getArgumentTypes();
|
Type[] argumentTypes = superCallable.getSignature().getAsmMethod().getArgumentTypes();
|
||||||
Collections.addAll(consArgTypes, argumentTypes);
|
Collections.addAll(consArgTypes, argumentTypes);
|
||||||
ResolvedCall resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, closureCodegen.superCall.getCalleeExpression());
|
ResolvedCall resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, closureCodegen.superCall.getCalleeExpression());
|
||||||
@@ -895,7 +914,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
StackValue answer = StackValue.none();
|
StackValue answer = StackValue.none();
|
||||||
for (int i = 0, statementsSize = statements.size(); i < statementsSize; i++) {
|
for (int i = 0, statementsSize = statements.size(); i < statementsSize; i++) {
|
||||||
JetElement statement = statements.get(i);
|
JetElement statement = statements.get(i);
|
||||||
if (i == statements.size() - 1 /*&& statement instanceof JetExpression && !bindingContext.get(BindingContext.STATEMENT, statement)*/) {
|
if (i ==
|
||||||
|
statements.size() -
|
||||||
|
1 /*&& statement instanceof JetExpression && !bindingContext.get(BindingContext.STATEMENT, statement)*/) {
|
||||||
answer = gen(statement);
|
answer = gen(statement);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -1058,15 +1079,16 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
|
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
|
||||||
|
|
||||||
if (propertyDescriptor.isObjectDeclaration()) {
|
if (propertyDescriptor.isObjectDeclaration()) {
|
||||||
ClassDescriptor classDescriptor = (ClassDescriptor) propertyDescriptor.getReturnType().getConstructor().getDeclarationDescriptor();
|
ClassDescriptor classDescriptor =
|
||||||
|
(ClassDescriptor) propertyDescriptor.getReturnType().getConstructor().getDeclarationDescriptor();
|
||||||
|
assert classDescriptor != null;
|
||||||
if (classDescriptor.getKind() == ClassKind.ENUM_ENTRY) {
|
if (classDescriptor.getKind() == ClassKind.ENUM_ENTRY) {
|
||||||
ClassDescriptor containing = (ClassDescriptor) classDescriptor.getContainingDeclaration().getContainingDeclaration();
|
ClassDescriptor containing = (ClassDescriptor) classDescriptor.getContainingDeclaration().getContainingDeclaration();
|
||||||
|
assert containing != null;
|
||||||
Type type = typeMapper.mapType(containing.getDefaultType(), MapTypeMode.VALUE);
|
Type type = typeMapper.mapType(containing.getDefaultType(), MapTypeMode.VALUE);
|
||||||
StackValue.field(type, JvmClassName.byType(type), classDescriptor.getName().getName(), true).put(TYPE_OBJECT, v);
|
Type entryType = typeMapper.mapType(classDescriptor.getDefaultType(), MapTypeMode.VALUE);
|
||||||
|
StackValue.field(type, JvmClassName.byType(type), classDescriptor.getName().getName(), true).put(entryType, v);
|
||||||
// todo: for now we don't generate classes for enum entries, so we need this hack
|
return StackValue.onStack(entryType);
|
||||||
type = typeMapper.mapType(classDescriptor.getDefaultType(), MapTypeMode.VALUE);
|
|
||||||
return StackValue.onStack(type);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Type type = typeMapper.mapType(classDescriptor.getDefaultType(), MapTypeMode.VALUE);
|
Type type = typeMapper.mapType(classDescriptor.getDefaultType(), MapTypeMode.VALUE);
|
||||||
@@ -1075,11 +1097,13 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean isStatic = container instanceof NamespaceDescriptor;
|
boolean isStatic = container instanceof NamespaceDescriptor;
|
||||||
final boolean directToField = expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER && contextKind() != OwnerKind.TRAIT_IMPL ;
|
final boolean directToField =
|
||||||
|
expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER && contextKind() != OwnerKind.TRAIT_IMPL;
|
||||||
JetExpression r = getReceiverForSelector(expression);
|
JetExpression r = getReceiverForSelector(expression);
|
||||||
final boolean isSuper = r instanceof JetSuperExpression;
|
final boolean isSuper = r instanceof JetSuperExpression;
|
||||||
propertyDescriptor = accessablePropertyDescriptor(propertyDescriptor);
|
propertyDescriptor = accessablePropertyDescriptor(propertyDescriptor);
|
||||||
final StackValue.Property iValue = intermediateValueForProperty(propertyDescriptor, directToField, isSuper ? (JetSuperExpression)r : null);
|
final StackValue.Property iValue =
|
||||||
|
intermediateValueForProperty(propertyDescriptor, directToField, isSuper ? (JetSuperExpression) r : null);
|
||||||
if (!directToField && resolvedCall != null && !isSuper) {
|
if (!directToField && resolvedCall != null && !isSuper) {
|
||||||
receiver.put(propertyDescriptor.getReceiverParameter().exists() || isStatic
|
receiver.put(propertyDescriptor.getReceiverParameter().exists() || isStatic
|
||||||
? receiver.type
|
? receiver.type
|
||||||
@@ -1088,20 +1112,24 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
else {
|
else {
|
||||||
if (!isStatic) {
|
if (!isStatic) {
|
||||||
if (receiver == StackValue.none()) {
|
if (receiver == StackValue.none()) {
|
||||||
if (resolvedCall == null)
|
if (resolvedCall == null) {
|
||||||
receiver = generateThisOrOuter((ClassDescriptor) propertyDescriptor.getContainingDeclaration());
|
receiver = generateThisOrOuter((ClassDescriptor) propertyDescriptor.getContainingDeclaration());
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
if (resolvedCall.getThisObject() instanceof ExtensionReceiver)
|
if (resolvedCall.getThisObject() instanceof ExtensionReceiver) {
|
||||||
receiver = generateReceiver(((ExtensionReceiver) resolvedCall.getThisObject()).getDeclarationDescriptor());
|
receiver = generateReceiver(((ExtensionReceiver) resolvedCall.getThisObject()).getDeclarationDescriptor());
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
receiver = generateThisOrOuter((ClassDescriptor) propertyDescriptor.getContainingDeclaration());
|
receiver = generateThisOrOuter((ClassDescriptor) propertyDescriptor.getContainingDeclaration());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
JetType receiverType = bindingContext.get(BindingContext.EXPRESSION_TYPE, r);
|
JetType receiverType = bindingContext.get(BindingContext.EXPRESSION_TYPE, r);
|
||||||
receiver.put(receiverType != null && !isSuper ? asmType(receiverType) : TYPE_OBJECT, v);
|
receiver.put(receiverType != null && !isSuper ? asmType(receiverType) : TYPE_OBJECT, v);
|
||||||
if (receiverType != null) {
|
if (receiverType != null) {
|
||||||
ClassDescriptor propReceiverDescriptor = (ClassDescriptor) propertyDescriptor.getContainingDeclaration();
|
ClassDescriptor propReceiverDescriptor = (ClassDescriptor) propertyDescriptor.getContainingDeclaration();
|
||||||
if (!CodegenUtil.isInterface(propReceiverDescriptor) && CodegenUtil.isInterface(receiverType.getConstructor().getDeclarationDescriptor())) {
|
if (!CodegenUtil.isInterface(propReceiverDescriptor) &&
|
||||||
|
CodegenUtil.isInterface(receiverType.getConstructor().getDeclarationDescriptor())) {
|
||||||
// I hope it happens only in case of required super class for traits
|
// I hope it happens only in case of required super class for traits
|
||||||
assert propReceiverDescriptor != null;
|
assert propReceiverDescriptor != null;
|
||||||
v.checkcast(asmType(propReceiverDescriptor.getDefaultType()));
|
v.checkcast(asmType(propReceiverDescriptor.getDefaultType()));
|
||||||
@@ -1119,7 +1147,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
assert descriptor1 != null;
|
assert descriptor1 != null;
|
||||||
final Type type = typeMapper.mapType(descriptor1.getDefaultType(), MapTypeMode.VALUE);
|
final Type type = typeMapper.mapType(descriptor1.getDefaultType(), MapTypeMode.VALUE);
|
||||||
return StackValue.field(type,
|
return StackValue.field(type,
|
||||||
JvmClassName.byType(typeMapper.mapType(((ClassDescriptor) descriptor).getDefaultType(), MapTypeMode.IMPL)),
|
JvmClassName.byType(typeMapper.mapType(((ClassDescriptor) descriptor).getDefaultType(),
|
||||||
|
MapTypeMode.IMPL)),
|
||||||
"$classobj",
|
"$classobj",
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
@@ -1149,7 +1178,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
if (value instanceof StackValue.FieldForSharedVar) {
|
if (value instanceof StackValue.FieldForSharedVar) {
|
||||||
StackValue.FieldForSharedVar fieldForSharedVar = (StackValue.FieldForSharedVar) value;
|
StackValue.FieldForSharedVar fieldForSharedVar = (StackValue.FieldForSharedVar) value;
|
||||||
Type sharedType = StackValue.sharedTypeForType(value.type);
|
Type sharedType = StackValue.sharedTypeForType(value.type);
|
||||||
v.visitFieldInsn(Opcodes.GETFIELD, fieldForSharedVar.owner.getInternalName(), fieldForSharedVar.name, sharedType.getDescriptor());
|
v.visitFieldInsn(Opcodes.GETFIELD, fieldForSharedVar.owner.getInternalName(), fieldForSharedVar.name,
|
||||||
|
sharedType.getDescriptor());
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
@@ -1219,7 +1249,11 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
StackValue.onStack(asmType(functionDescriptor.getReturnType())).coerce(type, v);
|
StackValue.onStack(asmType(functionDescriptor.getReturnType())).coerce(type, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
public StackValue.Property intermediateValueForProperty(PropertyDescriptor propertyDescriptor, final boolean forceField, @Nullable JetSuperExpression superExpression) {
|
public StackValue.Property intermediateValueForProperty(
|
||||||
|
PropertyDescriptor propertyDescriptor,
|
||||||
|
final boolean forceField,
|
||||||
|
@Nullable JetSuperExpression superExpression
|
||||||
|
) {
|
||||||
boolean isSuper = superExpression != null;
|
boolean isSuper = superExpression != null;
|
||||||
|
|
||||||
DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration();
|
DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration();
|
||||||
@@ -1232,19 +1266,23 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
PropertyDescriptor initialDescriptor = propertyDescriptor;
|
PropertyDescriptor initialDescriptor = propertyDescriptor;
|
||||||
propertyDescriptor = initialDescriptor.getOriginal();
|
propertyDescriptor = initialDescriptor.getOriginal();
|
||||||
boolean isInsideClass = !isFakeOverride && (((containingDeclaration == context.getThisDescriptor()) ||
|
boolean isInsideClass = !isFakeOverride && (((containingDeclaration == context.getThisDescriptor()) ||
|
||||||
(context.getParentContext() instanceof CodegenContexts.NamespaceContext) && context.getParentContext().getContextDescriptor() == containingDeclaration)
|
(context.getParentContext() instanceof CodegenContexts.NamespaceContext) &&
|
||||||
|
context.getParentContext().getContextDescriptor() == containingDeclaration)
|
||||||
&& contextKind() != OwnerKind.TRAIT_IMPL);
|
&& contextKind() != OwnerKind.TRAIT_IMPL);
|
||||||
Method getter = null;
|
Method getter = null;
|
||||||
Method setter = null;
|
Method setter = null;
|
||||||
if (!forceField) {
|
if (!forceField) {
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
if (isInsideClass && (propertyDescriptor.getGetter() == null || propertyDescriptor.getGetter().isDefault() && propertyDescriptor.getGetter().getModality() == Modality.FINAL)) {
|
if (isInsideClass &&
|
||||||
|
(propertyDescriptor.getGetter() == null ||
|
||||||
|
propertyDescriptor.getGetter().isDefault() && propertyDescriptor.getGetter().getModality() == Modality.FINAL)) {
|
||||||
getter = null;
|
getter = null;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (isSuper) {
|
if (isSuper) {
|
||||||
PsiElement enclosingElement = bindingContext.get(BindingContext.LABEL_TARGET, superExpression.getTargetLabel());
|
PsiElement enclosingElement = bindingContext.get(BindingContext.LABEL_TARGET, superExpression.getTargetLabel());
|
||||||
ClassDescriptor enclosed = (ClassDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, enclosingElement);
|
ClassDescriptor enclosed =
|
||||||
|
(ClassDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, enclosingElement);
|
||||||
if (!CodegenUtil.isInterface(containingDeclaration)) {
|
if (!CodegenUtil.isInterface(containingDeclaration)) {
|
||||||
if (enclosed != null && enclosed != context.getThisDescriptor()) {
|
if (enclosed != null && enclosed != context.getThisDescriptor()) {
|
||||||
CodegenContext c = context;
|
CodegenContext c = context;
|
||||||
@@ -1269,14 +1307,16 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
if (getter == null && propertyDescriptor.getReceiverParameter().exists()) {
|
if (getter == null && propertyDescriptor.getReceiverParameter().exists()) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
if (isInsideClass && (propertyDescriptor.getSetter() == null || propertyDescriptor.getSetter().isDefault() && propertyDescriptor.getSetter().getModality() == Modality.FINAL)) {
|
if (isInsideClass &&
|
||||||
|
(propertyDescriptor.getSetter() == null ||
|
||||||
|
propertyDescriptor.getSetter().isDefault() && propertyDescriptor.getSetter().getModality() == Modality.FINAL)) {
|
||||||
setter = null;
|
setter = null;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
JvmPropertyAccessorSignature jvmMethodSignature = typeMapper.mapSetterSignature(propertyDescriptor, OwnerKind.IMPLEMENTATION);
|
JvmPropertyAccessorSignature jvmMethodSignature =
|
||||||
|
typeMapper.mapSetterSignature(propertyDescriptor, OwnerKind.IMPLEMENTATION);
|
||||||
setter = jvmMethodSignature != null ? jvmMethodSignature.getJvmMethodSignature().getAsmMethod() : null;
|
setter = jvmMethodSignature != null ? jvmMethodSignature.getJvmMethodSignature().getAsmMethod() : null;
|
||||||
|
|
||||||
if (propertyDescriptor.getSetter() == null) {
|
if (propertyDescriptor.getSetter() == null) {
|
||||||
@@ -1306,15 +1346,21 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
// TODO ugly
|
// TODO ugly
|
||||||
CallableMethod callableMethod = typeMapper.mapToCallableMethod(propertyDescriptor.getGetter(), isSuper, contextKind());
|
CallableMethod callableMethod = typeMapper.mapToCallableMethod(propertyDescriptor.getGetter(), isSuper, contextKind());
|
||||||
invokeOpcode = callableMethod.getInvokeOpcode();
|
invokeOpcode = callableMethod.getInvokeOpcode();
|
||||||
owner = isFakeOverride && !overridesTrait && !CodegenUtil.isInterface(initialDescriptor.getContainingDeclaration()) ? JvmClassName.byType(typeMapper.mapType(((ClassDescriptor)initialDescriptor.getContainingDeclaration()).getDefaultType(), MapTypeMode.IMPL)): callableMethod.getOwner();
|
owner = isFakeOverride && !overridesTrait && !CodegenUtil.isInterface(initialDescriptor.getContainingDeclaration())
|
||||||
|
? JvmClassName.byType(typeMapper.mapType(
|
||||||
|
((ClassDescriptor) initialDescriptor.getContainingDeclaration()).getDefaultType(), MapTypeMode.IMPL))
|
||||||
|
: callableMethod.getOwner();
|
||||||
ownerParam = callableMethod.getDefaultImplParam();
|
ownerParam = callableMethod.getDefaultImplParam();
|
||||||
}
|
}
|
||||||
|
|
||||||
return StackValue.property(propertyDescriptor.getName().getName(), owner, ownerParam, asmType(propertyDescriptor.getType()), isStatic, isInterface, isSuper, getter, setter, invokeOpcode);
|
return StackValue
|
||||||
|
.property(propertyDescriptor.getName().getName(), owner, ownerParam, asmType(propertyDescriptor.getType()), isStatic,
|
||||||
|
isInterface, isSuper, getter, setter, invokeOpcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PropertyDescriptor accessablePropertyDescriptor(PropertyDescriptor propertyDescriptor) {
|
private PropertyDescriptor accessablePropertyDescriptor(PropertyDescriptor propertyDescriptor) {
|
||||||
if ((propertyDescriptor.getVisibility() == Visibilities.PRIVATE ||(propertyDescriptor.getSetter() != null && propertyDescriptor.getSetter().getVisibility() == Visibilities.PRIVATE))
|
if ((propertyDescriptor.getVisibility() == Visibilities.PRIVATE ||
|
||||||
|
(propertyDescriptor.getSetter() != null && propertyDescriptor.getSetter().getVisibility() == Visibilities.PRIVATE))
|
||||||
&& !DescriptorUtils.isClassObject(propertyDescriptor.getContainingDeclaration())
|
&& !DescriptorUtils.isClassObject(propertyDescriptor.getContainingDeclaration())
|
||||||
&& propertyDescriptor.getContainingDeclaration() instanceof ClassDescriptor) {
|
&& propertyDescriptor.getContainingDeclaration() instanceof ClassDescriptor) {
|
||||||
if (context.getClassOrNamespaceDescriptor() != propertyDescriptor.getContainingDeclaration()) {
|
if (context.getClassOrNamespaceDescriptor() != propertyDescriptor.getContainingDeclaration()) {
|
||||||
@@ -1324,11 +1370,12 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
while (c != null && c.getContextDescriptor() != enclosed) {
|
while (c != null && c.getContextDescriptor() != enclosed) {
|
||||||
c = c.getParentContext();
|
c = c.getParentContext();
|
||||||
}
|
}
|
||||||
if(c != null)
|
if (c != null) {
|
||||||
propertyDescriptor = (PropertyDescriptor) c.getAccessor(propertyDescriptor);
|
propertyDescriptor = (PropertyDescriptor) c.getAccessor(propertyDescriptor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return propertyDescriptor;
|
return propertyDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1376,10 +1423,12 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private StackValue invokeFunction(JetCallExpression expression,
|
private StackValue invokeFunction(
|
||||||
|
JetCallExpression expression,
|
||||||
FunctionDescriptor fd,
|
FunctionDescriptor fd,
|
||||||
StackValue receiver,
|
StackValue receiver,
|
||||||
ResolvedCall<? extends CallableDescriptor> resolvedCall) {
|
ResolvedCall<? extends CallableDescriptor> resolvedCall
|
||||||
|
) {
|
||||||
boolean superCall = false;
|
boolean superCall = false;
|
||||||
if (expression.getParent() instanceof JetQualifiedExpression) {
|
if (expression.getParent() instanceof JetQualifiedExpression) {
|
||||||
final JetExpression receiverExpression = ((JetQualifiedExpression) expression.getParent()).getReceiverExpression();
|
final JetExpression receiverExpression = ((JetQualifiedExpression) expression.getParent()).getReceiverExpression();
|
||||||
@@ -1395,7 +1444,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
if (enclosed != context.getThisDescriptor()) {
|
if (enclosed != context.getThisDescriptor()) {
|
||||||
CodegenContext c = context;
|
CodegenContext c = context;
|
||||||
while(!(c instanceof CodegenContexts.ClassContext) || !DescriptorUtils.isSubclass(c.getThisDescriptor(), enclosed)) {
|
while (!(c instanceof CodegenContexts.ClassContext) ||
|
||||||
|
!DescriptorUtils.isSubclass(c.getThisDescriptor(), enclosed)) {
|
||||||
c = c.getParentContext();
|
c = c.getParentContext();
|
||||||
}
|
}
|
||||||
fd = (FunctionDescriptor) c.getAccessor(fd);
|
fd = (FunctionDescriptor) c.getAccessor(fd);
|
||||||
@@ -1483,7 +1533,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
else if (fd instanceof ExpressionAsFunctionDescriptor) {
|
else if (fd instanceof ExpressionAsFunctionDescriptor) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (fd instanceof SimpleFunctionDescriptor && (fd.getContainingDeclaration() instanceof FunctionDescriptor || fd.getContainingDeclaration() instanceof ScriptDescriptor)) {
|
else if (fd instanceof SimpleFunctionDescriptor &&
|
||||||
|
(fd.getContainingDeclaration() instanceof FunctionDescriptor ||
|
||||||
|
fd.getContainingDeclaration() instanceof ScriptDescriptor)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -1498,7 +1550,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
gen(expression.getCalleeExpression(), calleeType);
|
gen(expression.getCalleeExpression(), calleeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getCalleeExpression());
|
ResolvedCall<? extends CallableDescriptor> resolvedCall =
|
||||||
|
bindingContext.get(BindingContext.RESOLVED_CALL, expression.getCalleeExpression());
|
||||||
assert resolvedCall != null;
|
assert resolvedCall != null;
|
||||||
|
|
||||||
if (resolvedCall instanceof VariableAsFunctionResolvedCall) {
|
if (resolvedCall instanceof VariableAsFunctionResolvedCall) {
|
||||||
@@ -1514,13 +1567,19 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int mask = pushMethodArguments(expression, callableMethod.getValueParameterTypes());
|
int mask = pushMethodArguments(expression, callableMethod.getValueParameterTypes());
|
||||||
if (mask == 0)
|
if (mask == 0) {
|
||||||
callableMethod.invoke(v);
|
callableMethod.invoke(v);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
callableMethod.invokeWithDefault(v, mask);
|
callableMethod.invokeWithDefault(v, mask);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void genThisAndReceiverFromResolvedCall(StackValue receiver, ResolvedCall<? extends CallableDescriptor> resolvedCall, CallableMethod callableMethod) {
|
private void genThisAndReceiverFromResolvedCall(
|
||||||
|
StackValue receiver,
|
||||||
|
ResolvedCall<? extends CallableDescriptor> resolvedCall,
|
||||||
|
CallableMethod callableMethod
|
||||||
|
) {
|
||||||
receiver = StackValue.receiver(resolvedCall, receiver, this, callableMethod, state);
|
receiver = StackValue.receiver(resolvedCall, receiver, this, callableMethod, state);
|
||||||
receiver.put(receiver.type, v);
|
receiver.put(receiver.type, v);
|
||||||
}
|
}
|
||||||
@@ -1533,9 +1592,12 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
if (DescriptorUtils.isClassObject(classReceiverDeclarationDescriptor)) {
|
if (DescriptorUtils.isClassObject(classReceiverDeclarationDescriptor)) {
|
||||||
ClassDescriptor containingDeclaration = (ClassDescriptor) classReceiverDeclarationDescriptor.getContainingDeclaration();
|
ClassDescriptor containingDeclaration = (ClassDescriptor) classReceiverDeclarationDescriptor.getContainingDeclaration();
|
||||||
Type classObjType = typeMapper.mapType(containingDeclaration.getDefaultType(), MapTypeMode.IMPL);
|
Type classObjType = typeMapper.mapType(containingDeclaration.getDefaultType(), MapTypeMode.IMPL);
|
||||||
if (context.getContextDescriptor() instanceof ConstructorDescriptor && classReceiverDeclarationDescriptor.getDefaultType().equals(((ConstructorDescriptor)context.getContextDescriptor()).getReturnType())) {
|
if (context.getContextDescriptor() instanceof ConstructorDescriptor &&
|
||||||
|
classReceiverDeclarationDescriptor.getDefaultType()
|
||||||
|
.equals(((ConstructorDescriptor) context.getContextDescriptor()).getReturnType())) {
|
||||||
v.load(0, classObjType);
|
v.load(0, classObjType);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
v.getstatic(classObjType.getInternalName(), "$classobj", exprType.getDescriptor());
|
v.getstatic(classObjType.getInternalName(), "$classobj", exprType.getDescriptor());
|
||||||
}
|
}
|
||||||
StackValue.onStack(exprType).put(type, v);
|
StackValue.onStack(exprType).put(type, v);
|
||||||
@@ -1596,18 +1658,21 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
cur = context;
|
cur = context;
|
||||||
StackValue result = StackValue.local(0, TYPE_OBJECT);
|
StackValue result = StackValue.local(0, TYPE_OBJECT);
|
||||||
while (cur != null) {
|
while (cur != null) {
|
||||||
if (cur instanceof CodegenContexts.MethodContext && !(cur instanceof CodegenContexts.ConstructorContext))
|
if (cur instanceof CodegenContexts.MethodContext && !(cur instanceof CodegenContexts.ConstructorContext)) {
|
||||||
cur = cur.getParentContext();
|
cur = cur.getParentContext();
|
||||||
|
}
|
||||||
|
|
||||||
if (cur instanceof CodegenContexts.ScriptContext) {
|
if (cur instanceof CodegenContexts.ScriptContext) {
|
||||||
CodegenContexts.ScriptContext scriptContext = (CodegenContexts.ScriptContext) cur;
|
CodegenContexts.ScriptContext scriptContext = (CodegenContexts.ScriptContext) cur;
|
||||||
|
|
||||||
JvmClassName currentScriptClassName = state.getInjector().getClosureAnnotator().classNameForScriptDescriptor(scriptContext.getScriptDescriptor());
|
JvmClassName currentScriptClassName =
|
||||||
|
state.getInjector().getClosureAnnotator().classNameForScriptDescriptor(scriptContext.getScriptDescriptor());
|
||||||
if (scriptContext.getScriptDescriptor() == receiver.getDeclarationDescriptor()) {
|
if (scriptContext.getScriptDescriptor() == receiver.getDeclarationDescriptor()) {
|
||||||
result.put(currentScriptClassName.getAsmType(), v);
|
result.put(currentScriptClassName.getAsmType(), v);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
JvmClassName className = state.getInjector().getClosureAnnotator().classNameForScriptDescriptor(receiver.getDeclarationDescriptor());
|
JvmClassName className =
|
||||||
|
state.getInjector().getClosureAnnotator().classNameForScriptDescriptor(receiver.getDeclarationDescriptor());
|
||||||
String fieldName = state.getInjector().getScriptCodegen().getScriptFieldName(receiver.getDeclarationDescriptor());
|
String fieldName = state.getInjector().getScriptCodegen().getScriptFieldName(receiver.getDeclarationDescriptor());
|
||||||
result.put(currentScriptClassName.getAsmType(), v);
|
result.put(currentScriptClassName.getAsmType(), v);
|
||||||
StackValue.field(className.getAsmType(), currentScriptClassName, fieldName, false).put(className.getAsmType(), v);
|
StackValue.field(className.getAsmType(), currentScriptClassName, fieldName, false).put(className.getAsmType(), v);
|
||||||
@@ -1634,8 +1699,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
Type type = asmType(calleeContainingClass.getDefaultType());
|
Type type = asmType(calleeContainingClass.getDefaultType());
|
||||||
StackValue result = StackValue.local(0, type);
|
StackValue result = StackValue.local(0, type);
|
||||||
while (cur != null) {
|
while (cur != null) {
|
||||||
if (cur instanceof CodegenContexts.MethodContext && !(cur instanceof CodegenContexts.ConstructorContext))
|
if (cur instanceof CodegenContexts.MethodContext && !(cur instanceof CodegenContexts.ConstructorContext)) {
|
||||||
cur = cur.getParentContext();
|
cur = cur.getParentContext();
|
||||||
|
}
|
||||||
|
|
||||||
if (DescriptorUtils.isSubclass(cur.getThisDescriptor(), calleeContainingClass)) {
|
if (DescriptorUtils.isSubclass(cur.getThisDescriptor(), calleeContainingClass)) {
|
||||||
if (!isObject || (cur.getThisDescriptor() == calleeContainingClass)) {
|
if (!isObject || (cur.getThisDescriptor() == calleeContainingClass)) {
|
||||||
@@ -1686,8 +1752,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
else if (resolvedValueArgument instanceof DefaultValueArgument) {
|
else if (resolvedValueArgument instanceof DefaultValueArgument) {
|
||||||
Type type = valueParameterTypes.get(index);
|
Type type = valueParameterTypes.get(index);
|
||||||
if (type.getSort() == Type.OBJECT||type.getSort() == Type.ARRAY)
|
if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
|
||||||
v.aconst(null);
|
v.aconst(null);
|
||||||
|
}
|
||||||
else if (type.getSort() == Type.FLOAT) {
|
else if (type.getSort() == Type.FLOAT) {
|
||||||
v.aconst(0f);
|
v.aconst(0f);
|
||||||
}
|
}
|
||||||
@@ -1773,7 +1840,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int pushMethodArguments(JetCallElement expression, List<Type> valueParameterTypes) {
|
public int pushMethodArguments(JetCallElement expression, List<Type> valueParameterTypes) {
|
||||||
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getCalleeExpression());
|
ResolvedCall<? extends CallableDescriptor> resolvedCall =
|
||||||
|
bindingContext.get(BindingContext.RESOLVED_CALL, expression.getCalleeExpression());
|
||||||
if (resolvedCall != null) {
|
if (resolvedCall != null) {
|
||||||
return pushMethodArguments(resolvedCall, valueParameterTypes);
|
return pushMethodArguments(resolvedCall, valueParameterTypes);
|
||||||
}
|
}
|
||||||
@@ -1901,7 +1969,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
StackValue leftValue = gen(expr);
|
StackValue leftValue = gen(expr);
|
||||||
FunctionDescriptor op = (FunctionDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference());
|
FunctionDescriptor op =
|
||||||
|
(FunctionDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference());
|
||||||
assert op != null;
|
assert op != null;
|
||||||
Type type = asmType(op.getValueParameters().get(0).getType());
|
Type type = asmType(op.getValueParameters().get(0).getType());
|
||||||
if (type.getSize() == 1) {
|
if (type.getSize() == 1) {
|
||||||
@@ -2015,7 +2084,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isPrimitive(leftType)) // both are primitive
|
if (isPrimitive(leftType)) // both are primitive
|
||||||
|
{
|
||||||
return generateEqualsForExpressionsOnStack(opToken, leftType, rightType, false, false);
|
return generateEqualsForExpressionsOnStack(opToken, leftType, rightType, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
assert leftJetType != null;
|
assert leftJetType != null;
|
||||||
assert rightJetType != null;
|
assert rightJetType != null;
|
||||||
@@ -2038,7 +2109,13 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
return StackValue.onStack(Type.BOOLEAN_TYPE);
|
return StackValue.onStack(Type.BOOLEAN_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public StackValue generateEqualsForExpressionsOnStack(IElementType opToken, Type leftType, Type rightType, boolean leftNullable, boolean rightNullable) {
|
public StackValue generateEqualsForExpressionsOnStack(
|
||||||
|
IElementType opToken,
|
||||||
|
Type leftType,
|
||||||
|
Type rightType,
|
||||||
|
boolean leftNullable,
|
||||||
|
boolean rightNullable
|
||||||
|
) {
|
||||||
if ((isNumberPrimitive(leftType) || leftType.getSort() == Type.BOOLEAN) && leftType == rightType) {
|
if ((isNumberPrimitive(leftType) || leftType.getSort() == Type.BOOLEAN) && leftType == rightType) {
|
||||||
return compareExpressionsOnStack(opToken, leftType);
|
return compareExpressionsOnStack(opToken, leftType);
|
||||||
}
|
}
|
||||||
@@ -2216,7 +2293,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void callAugAssignMethod(JetBinaryExpression expression, CallableMethod callable, Type lhsType, final boolean keepReturnValue) {
|
private void callAugAssignMethod(JetBinaryExpression expression, CallableMethod callable, Type lhsType, final boolean keepReturnValue) {
|
||||||
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference());
|
ResolvedCall<? extends CallableDescriptor> resolvedCall =
|
||||||
|
bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference());
|
||||||
assert resolvedCall != null;
|
assert resolvedCall != null;
|
||||||
|
|
||||||
StackValue value = gen(expression.getLeft());
|
StackValue value = gen(expression.getLeft());
|
||||||
@@ -2305,7 +2383,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
return invokeOperation(expression, (FunctionDescriptor) op, callableMethod);
|
return invokeOperation(expression, (FunctionDescriptor) op, callableMethod);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference());
|
ResolvedCall<? extends CallableDescriptor> resolvedCall =
|
||||||
|
bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference());
|
||||||
assert resolvedCall != null;
|
assert resolvedCall != null;
|
||||||
|
|
||||||
StackValue value = gen(expression.getBaseExpression());
|
StackValue value = gen(expression.getBaseExpression());
|
||||||
@@ -2327,7 +2406,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
if (functionLocalIndex >= 0) {
|
if (functionLocalIndex >= 0) {
|
||||||
stackValueForLocal(op, functionLocalIndex).put(ClosureCodegen.getInternalClassName(op).getAsmType(), v);
|
stackValueForLocal(op, functionLocalIndex).put(ClosureCodegen.getInternalClassName(op).getAsmType(), v);
|
||||||
}
|
}
|
||||||
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference());
|
ResolvedCall<? extends CallableDescriptor> resolvedCall =
|
||||||
|
bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference());
|
||||||
assert resolvedCall != null;
|
assert resolvedCall != null;
|
||||||
genThisAndReceiverFromResolvedCall(StackValue.none(), resolvedCall, callable);
|
genThisAndReceiverFromResolvedCall(StackValue.none(), resolvedCall, callable);
|
||||||
pushMethodArguments(resolvedCall, callable.getValueParameterTypes());
|
pushMethodArguments(resolvedCall, callable.getValueParameterTypes());
|
||||||
@@ -2350,9 +2430,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
v.mark(ok);
|
v.mark(ok);
|
||||||
return StackValue.onStack(base.type);
|
return StackValue.onStack(base.type);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
return base;
|
return base;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
DeclarationDescriptor op = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference());
|
DeclarationDescriptor op = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference());
|
||||||
if (op instanceof FunctionDescriptor) {
|
if (op instanceof FunctionDescriptor) {
|
||||||
final Type asmType = expressionType(expression);
|
final Type asmType = expressionType(expression);
|
||||||
@@ -2373,7 +2454,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
return StackValue.onStack(asmType); // old value
|
return StackValue.onStack(asmType); // old value
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference());
|
ResolvedCall<? extends CallableDescriptor> resolvedCall =
|
||||||
|
bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference());
|
||||||
assert resolvedCall != null;
|
assert resolvedCall != null;
|
||||||
|
|
||||||
final Callable callable = resolveToCallable((FunctionDescriptor) op, false);
|
final Callable callable = resolveToCallable((FunctionDescriptor) op, false);
|
||||||
@@ -2386,24 +2468,30 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
|
|
||||||
switch (value.receiverSize()) {
|
switch (value.receiverSize()) {
|
||||||
case 0:
|
case 0:
|
||||||
if (type.getSize() == 2)
|
if (type.getSize() == 2) {
|
||||||
v.dup2();
|
v.dup2();
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
v.dup();
|
v.dup();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
if (type.getSize() == 2)
|
if (type.getSize() == 2) {
|
||||||
v.dup2X1();
|
v.dup2X1();
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
v.dupX1();
|
v.dupX1();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
if (type.getSize() == 2)
|
if (type.getSize() == 2) {
|
||||||
v.dup2X2();
|
v.dup2X2();
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
v.dupX2();
|
v.dupX2();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case -1:
|
case -1:
|
||||||
@@ -2462,7 +2550,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
if (property.isScriptDeclaration()) {
|
if (property.isScriptDeclaration()) {
|
||||||
JetScript scriptPsi = property.getScript();
|
JetScript scriptPsi = property.getScript();
|
||||||
JvmClassName scriptClassName = state.getInjector().getClosureAnnotator().classNameForScriptPsi(scriptPsi);
|
JvmClassName scriptClassName = state.getInjector().getClosureAnnotator().classNameForScriptPsi(scriptPsi);
|
||||||
StackValue field = StackValue.field(typeMapper.mapType(variableDescriptor.getType(), MapTypeMode.VALUE), scriptClassName, property.getName(), false);
|
StackValue field = StackValue
|
||||||
|
.field(typeMapper.mapType(variableDescriptor.getType(), MapTypeMode.VALUE), scriptClassName, property.getName(), false);
|
||||||
return StackValue.none();
|
return StackValue.none();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -2474,7 +2563,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
|
|
||||||
sharedVarType = typeMapper.getSharedVarType(variableDescriptor);
|
sharedVarType = typeMapper.getSharedVarType(variableDescriptor);
|
||||||
assert variableDescriptor != null;
|
assert variableDescriptor != null;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Type varType = asmType(variableDescriptor.getType());
|
Type varType = asmType(variableDescriptor.getType());
|
||||||
@@ -2500,13 +2588,18 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
else {
|
else {
|
||||||
v.load(index, TYPE_OBJECT);
|
v.load(index, TYPE_OBJECT);
|
||||||
gen(initializer, varType);
|
gen(initializer, varType);
|
||||||
v.putfield(sharedVarType.getInternalName(), "ref", sharedVarType == TYPE_SHARED_VAR ? "Ljava/lang/Object;" : varType.getDescriptor());
|
v.putfield(sharedVarType.getInternalName(), "ref",
|
||||||
|
sharedVarType == TYPE_SHARED_VAR ? "Ljava/lang/Object;" : varType.getDescriptor());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return StackValue.none();
|
return StackValue.none();
|
||||||
}
|
}
|
||||||
|
|
||||||
private StackValue generateConstructorCall(JetCallExpression expression, JetSimpleNameExpression constructorReference, StackValue receiver) {
|
private StackValue generateConstructorCall(
|
||||||
|
JetCallExpression expression,
|
||||||
|
JetSimpleNameExpression constructorReference,
|
||||||
|
StackValue receiver
|
||||||
|
) {
|
||||||
DeclarationDescriptor constructorDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, constructorReference);
|
DeclarationDescriptor constructorDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, constructorReference);
|
||||||
final PsiElement declaration = BindingContextUtils.descriptorToDeclaration(bindingContext, constructorDescriptor);
|
final PsiElement declaration = BindingContextUtils.descriptorToDeclaration(bindingContext, constructorDescriptor);
|
||||||
Type type;
|
Type type;
|
||||||
@@ -2533,7 +2626,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
receiver.put(receiver.type, v);
|
receiver.put(receiver.type, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
CallableMethod method = typeMapper.mapToCallableMethod((ConstructorDescriptor) constructorDescriptor, OwnerKind.IMPLEMENTATION, typeMapper.hasThis0(((ConstructorDescriptor) constructorDescriptor).getContainingDeclaration()));
|
CallableMethod method = typeMapper
|
||||||
|
.mapToCallableMethod((ConstructorDescriptor) constructorDescriptor, OwnerKind.IMPLEMENTATION, typeMapper
|
||||||
|
.hasThis0(((ConstructorDescriptor) constructorDescriptor).getContainingDeclaration()));
|
||||||
invokeMethodWithArguments(method, expression, StackValue.none());
|
invokeMethodWithArguments(method, expression, StackValue.none());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2563,8 +2658,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
|
|
||||||
public void generateNewArray(JetCallExpression expression, JetType arrayType) {
|
public void generateNewArray(JetCallExpression expression, JetType arrayType) {
|
||||||
List<JetExpression> args = new ArrayList<JetExpression>();
|
List<JetExpression> args = new ArrayList<JetExpression>();
|
||||||
for(ValueArgument va : expression.getValueArguments())
|
for (ValueArgument va : expression.getValueArguments()) {
|
||||||
args.add(va.getArgumentExpression());
|
args.add(va.getArgumentExpression());
|
||||||
|
}
|
||||||
args.addAll(expression.getFunctionLiteralArguments());
|
args.addAll(expression.getFunctionLiteralArguments());
|
||||||
|
|
||||||
boolean isArray = JetStandardLibraryNames.ARRAY.is(arrayType);
|
boolean isArray = JetStandardLibraryNames.ARRAY.is(arrayType);
|
||||||
@@ -2634,7 +2730,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
final List<JetExpression> indices = expression.getIndexExpressions();
|
final List<JetExpression> indices = expression.getIndexExpressions();
|
||||||
FunctionDescriptor operationDescriptor = (FunctionDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, expression);
|
FunctionDescriptor operationDescriptor = (FunctionDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, expression);
|
||||||
assert operationDescriptor != null;
|
assert operationDescriptor != null;
|
||||||
if (arrayType.getSort() == Type.ARRAY && indices.size() == 1 && JetStandardLibraryNames.INT.is(operationDescriptor.getValueParameters().get(0).getType())) {
|
if (arrayType.getSort() == Type.ARRAY &&
|
||||||
|
indices.size() == 1 &&
|
||||||
|
JetStandardLibraryNames.INT.is(operationDescriptor.getValueParameters().get(0).getType())) {
|
||||||
gen(array, arrayType);
|
gen(array, arrayType);
|
||||||
for (JetExpression index : indices) {
|
for (JetExpression index : indices) {
|
||||||
gen(index, Type.INT_TYPE);
|
gen(index, Type.INT_TYPE);
|
||||||
@@ -2665,8 +2763,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
int index = 0;
|
int index = 0;
|
||||||
if (isGetter) {
|
if (isGetter) {
|
||||||
Callable callable = resolveToCallable(getterDescriptor, false);
|
Callable callable = resolveToCallable(getterDescriptor, false);
|
||||||
if (callable instanceof CallableMethod)
|
if (callable instanceof CallableMethod) {
|
||||||
genThisAndReceiverFromResolvedCall(receiver, resolvedGetCall, (CallableMethod) callable);
|
genThisAndReceiverFromResolvedCall(receiver, resolvedGetCall, (CallableMethod) callable);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
assert getterDescriptor != null;
|
assert getterDescriptor != null;
|
||||||
gen(array, asmType(((ClassDescriptor) getterDescriptor.getContainingDeclaration()).getDefaultType()));
|
gen(array, asmType(((ClassDescriptor) getterDescriptor.getContainingDeclaration()).getDefaultType()));
|
||||||
@@ -2684,8 +2783,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
if (callable instanceof CallableMethod) {
|
if (callable instanceof CallableMethod) {
|
||||||
genThisAndReceiverFromResolvedCall(receiver, resolvedSetCall, (CallableMethod) callable);
|
genThisAndReceiverFromResolvedCall(receiver, resolvedSetCall, (CallableMethod) callable);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
gen(array, arrayType);
|
gen(array, arrayType);
|
||||||
|
}
|
||||||
|
|
||||||
if (setterDescriptor.getReceiverParameter().exists()) {
|
if (setterDescriptor.getReceiverParameter().exists()) {
|
||||||
index++;
|
index++;
|
||||||
@@ -2877,8 +2977,10 @@ The "returned" value of try expression with no finally is either the last expres
|
|||||||
}
|
}
|
||||||
|
|
||||||
// on entering the function, expressionToMatch is already placed on stack, and we should consume it
|
// on entering the function, expressionToMatch is already placed on stack, and we should consume it
|
||||||
private StackValue generatePatternMatch(JetPattern pattern, boolean negated, StackValue expressionToMatch,
|
private StackValue generatePatternMatch(
|
||||||
boolean expressionToMatchIsNullable, @Nullable Label nextEntry) {
|
JetPattern pattern, boolean negated, StackValue expressionToMatch,
|
||||||
|
boolean expressionToMatchIsNullable, @Nullable Label nextEntry
|
||||||
|
) {
|
||||||
if (pattern instanceof JetTypePattern) {
|
if (pattern instanceof JetTypePattern) {
|
||||||
JetTypeReference typeReference = ((JetTypePattern) pattern).getTypeReference();
|
JetTypeReference typeReference = ((JetTypePattern) pattern).getTypeReference();
|
||||||
JetType jetType = bindingContext.get(BindingContext.TYPE, typeReference);
|
JetType jetType = bindingContext.get(BindingContext.TYPE, typeReference);
|
||||||
@@ -2911,7 +3013,8 @@ The "returned" value of try expression with no finally is either the last expres
|
|||||||
patternIsNullable = condJetType != null && condJetType.isNullable();
|
patternIsNullable = condJetType != null && condJetType.isNullable();
|
||||||
}
|
}
|
||||||
gen(condExpression, condType);
|
gen(condExpression, condType);
|
||||||
return generateEqualsForExpressionsOnStack(JetTokens.EQEQ, subjectType, condType, expressionToMatchIsNullable, patternIsNullable);
|
return generateEqualsForExpressionsOnStack(JetTokens.EQEQ, subjectType, condType, expressionToMatchIsNullable,
|
||||||
|
patternIsNullable);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
JetExpression condExpression = ((JetExpressionPattern) pattern).getExpression();
|
JetExpression condExpression = ((JetExpressionPattern) pattern).getExpression();
|
||||||
@@ -2938,8 +3041,10 @@ The "returned" value of try expression with no finally is either the last expres
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private StackValue generateTuplePatternMatch(JetTuplePattern pattern, boolean negated, StackValue expressionToMatch,
|
private StackValue generateTuplePatternMatch(
|
||||||
@Nullable Label nextEntry) {
|
JetTuplePattern pattern, boolean negated, StackValue expressionToMatch,
|
||||||
|
@Nullable Label nextEntry
|
||||||
|
) {
|
||||||
final List<JetTuplePatternEntry> entries = pattern.getEntries();
|
final List<JetTuplePatternEntry> entries = pattern.getEntries();
|
||||||
|
|
||||||
Label lblFail = new Label();
|
Label lblFail = new Label();
|
||||||
@@ -3068,8 +3173,10 @@ The "returned" value of try expression with no finally is either the last expres
|
|||||||
return StackValue.onStack(resultType);
|
return StackValue.onStack(resultType);
|
||||||
}
|
}
|
||||||
|
|
||||||
private StackValue generateWhenCondition(Type subjectType, int subjectLocal, boolean subjectIsNullable,
|
private StackValue generateWhenCondition(
|
||||||
JetWhenCondition condition, @Nullable Label nextEntry) {
|
Type subjectType, int subjectLocal, boolean subjectIsNullable,
|
||||||
|
JetWhenCondition condition, @Nullable Label nextEntry
|
||||||
|
) {
|
||||||
if (condition instanceof JetWhenConditionInRange) {
|
if (condition instanceof JetWhenConditionInRange) {
|
||||||
JetWhenConditionInRange conditionInRange = (JetWhenConditionInRange) condition;
|
JetWhenConditionInRange conditionInRange = (JetWhenConditionInRange) condition;
|
||||||
JetExpression rangeExpression = conditionInRange.getRangeExpression();
|
JetExpression rangeExpression = conditionInRange.getRangeExpression();
|
||||||
@@ -3081,7 +3188,8 @@ The "returned" value of try expression with no finally is either the last expres
|
|||||||
getInIntRange(new StackValue.Local(subjectLocal, subjectType), (JetBinaryExpression) rangeExpression, inverted);
|
getInIntRange(new StackValue.Local(subjectLocal, subjectType), (JetBinaryExpression) rangeExpression, inverted);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
FunctionDescriptor op = (FunctionDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, conditionInRange.getOperationReference());
|
FunctionDescriptor op =
|
||||||
|
(FunctionDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, conditionInRange.getOperationReference());
|
||||||
genToJVMStack(rangeExpression);
|
genToJVMStack(rangeExpression);
|
||||||
new StackValue.Local(subjectLocal, subjectType).put(TYPE_OBJECT, v);
|
new StackValue.Local(subjectLocal, subjectType).put(TYPE_OBJECT, v);
|
||||||
invokeFunctionNoParams(op, Type.BOOLEAN_TYPE, v);
|
invokeFunctionNoParams(op, Type.BOOLEAN_TYPE, v);
|
||||||
|
|||||||
@@ -84,8 +84,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
if (myClass instanceof JetClass) {
|
if (myClass instanceof JetClass) {
|
||||||
JetClass jetClass = (JetClass) myClass;
|
JetClass jetClass = (JetClass) myClass;
|
||||||
if (jetClass.hasModifier(JetTokens.ABSTRACT_KEYWORD))
|
if (jetClass.hasModifier(JetTokens.ABSTRACT_KEYWORD)) {
|
||||||
isAbstract = true;
|
isAbstract = true;
|
||||||
|
}
|
||||||
if (jetClass.isTrait()) {
|
if (jetClass.isTrait()) {
|
||||||
isAbstract = true;
|
isAbstract = true;
|
||||||
isInterface = true;
|
isInterface = true;
|
||||||
@@ -170,7 +171,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
if (descriptor.getClassObjectDescriptor() != null) {
|
if (descriptor.getClassObjectDescriptor() != null) {
|
||||||
int innerClassAccess = ACC_PUBLIC | ACC_FINAL | ACC_STATIC;
|
int innerClassAccess = ACC_PUBLIC | ACC_FINAL | ACC_STATIC;
|
||||||
String outerClassInernalName = typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName();
|
String outerClassInernalName = typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName();
|
||||||
v.visitInnerClass(outerClassInernalName + JvmAbi.CLASS_OBJECT_SUFFIX, outerClassInernalName, JvmAbi.CLASS_OBJECT_CLASS_NAME, innerClassAccess);
|
v.visitInnerClass(outerClassInernalName + JvmAbi.CLASS_OBJECT_SUFFIX, outerClassInernalName, JvmAbi.CLASS_OBJECT_CLASS_NAME,
|
||||||
|
innerClassAccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
AnnotationCodegen.forClass(v.getVisitor(), typeMapper).genAnnotations(descriptor);
|
AnnotationCodegen.forClass(v.getVisitor(), typeMapper).genAnnotations(descriptor);
|
||||||
@@ -245,7 +247,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
signatureVisitor.writeSupersEnd();
|
signatureVisitor.writeSupersEnd();
|
||||||
|
|
||||||
return new JvmClassSignature(jvmName(), superClass, superInterfaces, signatureVisitor.makeJavaString(), signatureVisitor.makeKotlinClassSignature());
|
return new JvmClassSignature(jvmName(), superClass, superInterfaces, signatureVisitor.makeJavaString(),
|
||||||
|
signatureVisitor.makeKotlinClassSignature());
|
||||||
}
|
}
|
||||||
|
|
||||||
private String jvmName() {
|
private String jvmName() {
|
||||||
@@ -261,8 +264,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
List<JetDelegationSpecifier> delegationSpecifiers = myClass.getDelegationSpecifiers();
|
List<JetDelegationSpecifier> delegationSpecifiers = myClass.getDelegationSpecifiers();
|
||||||
|
|
||||||
if (myClass instanceof JetClass && ((JetClass) myClass).isTrait())
|
if (myClass instanceof JetClass && ((JetClass) myClass).isTrait()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (kind != OwnerKind.IMPLEMENTATION) {
|
if (kind != OwnerKind.IMPLEMENTATION) {
|
||||||
throw new IllegalStateException("must be impl to reach this code: " + kind);
|
throw new IllegalStateException("must be impl to reach this code: " + kind);
|
||||||
@@ -282,10 +286,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (superClassType == null) {
|
if (superClassType == null) {
|
||||||
if (myClass instanceof JetClass && ((JetClass) myClass).hasModifier(JetTokens.ENUM_KEYWORD)) {
|
if (descriptor.getKind() == ClassKind.ENUM_CLASS) {
|
||||||
superClassType = JetStandardLibrary.getInstance().getEnumType(descriptor.getDefaultType());
|
superClassType = JetStandardLibrary.getInstance().getEnumType(descriptor.getDefaultType());
|
||||||
superClass = typeMapper.mapType(superClassType, MapTypeMode.VALUE).getInternalName();
|
superClass = typeMapper.mapType(superClassType, MapTypeMode.VALUE).getInternalName();
|
||||||
}
|
}
|
||||||
|
if (descriptor.getKind() == ClassKind.ENUM_ENTRY) {
|
||||||
|
superClassType = descriptor.getTypeConstructor().getSupertypes().iterator().next();
|
||||||
|
superClass = typeMapper.mapType(superClassType, MapTypeMode.VALUE).getInternalName();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,12 +325,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
private void generateEnumMethods() {
|
private void generateEnumMethods() {
|
||||||
if (myEnumConstants.size() > 0) {
|
if (myEnumConstants.size() > 0) {
|
||||||
{
|
{
|
||||||
Type type = typeMapper.mapType(JetStandardLibrary.getInstance().getArrayType(descriptor.getDefaultType()), MapTypeMode.IMPL);
|
Type type =
|
||||||
|
typeMapper.mapType(JetStandardLibrary.getInstance().getArrayType(descriptor.getDefaultType()), MapTypeMode.IMPL);
|
||||||
|
|
||||||
MethodVisitor mv =
|
MethodVisitor mv =
|
||||||
v.newMethod(myClass, ACC_PUBLIC | ACC_STATIC, "values", "()" + type.getDescriptor(), null, null);
|
v.newMethod(myClass, ACC_PUBLIC | ACC_STATIC, "values", "()" + type.getDescriptor(), null, null);
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
mv.visitFieldInsn(GETSTATIC, typeMapper.mapType(descriptor.getDefaultType(),MapTypeMode.VALUE).getInternalName(), VALUES, type.getDescriptor());
|
mv.visitFieldInsn(GETSTATIC, typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), VALUES,
|
||||||
|
type.getDescriptor());
|
||||||
mv.visitMethodInsn(INVOKEVIRTUAL, type.getInternalName(), "clone", "()Ljava/lang/Object;");
|
mv.visitMethodInsn(INVOKEVIRTUAL, type.getInternalName(), "clone", "()Ljava/lang/Object;");
|
||||||
mv.visitTypeInsn(CHECKCAST, type.getInternalName());
|
mv.visitTypeInsn(CHECKCAST, type.getInternalName());
|
||||||
mv.visitInsn(ARETURN);
|
mv.visitInsn(ARETURN);
|
||||||
@@ -393,10 +403,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
Method method = typeMapper.mapGetterSignature(bridge, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod();
|
Method method = typeMapper.mapGetterSignature(bridge, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod();
|
||||||
JvmPropertyAccessorSignature originalSignature = typeMapper.mapGetterSignature(original, OwnerKind.IMPLEMENTATION);
|
JvmPropertyAccessorSignature originalSignature = typeMapper.mapGetterSignature(original, OwnerKind.IMPLEMENTATION);
|
||||||
Method originalMethod = originalSignature.getJvmMethodSignature().getAsmMethod();
|
Method originalMethod = originalSignature.getJvmMethodSignature().getAsmMethod();
|
||||||
MethodVisitor mv = v.newMethod(null, ACC_BRIDGE | ACC_SYNTHETIC | ACC_STATIC, method.getName(), method.getDescriptor(), null, null);
|
MethodVisitor mv =
|
||||||
|
v.newMethod(null, ACC_BRIDGE | ACC_SYNTHETIC | ACC_STATIC, method.getName(), method.getDescriptor(), null, null);
|
||||||
PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature.getPropertyTypeKotlinSignature(),
|
PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature.getPropertyTypeKotlinSignature(),
|
||||||
originalSignature.getJvmMethodSignature().getKotlinTypeParameter(),
|
originalSignature.getJvmMethodSignature().getKotlinTypeParameter(),
|
||||||
original, ((PropertyDescriptor) entry.getValue()).getGetter().getVisibility());
|
original,
|
||||||
|
((PropertyDescriptor) entry.getValue()).getGetter().getVisibility());
|
||||||
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
|
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
|
||||||
StubCodegen.generateStubCode(mv);
|
StubCodegen.generateStubCode(mv);
|
||||||
}
|
}
|
||||||
@@ -406,25 +418,30 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||||
|
|
||||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||||
if (original.getVisibility() == Visibilities.PRIVATE)
|
if (original.getVisibility() == Visibilities.PRIVATE) {
|
||||||
iv.getfield(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(), original.getName().getName(), originalMethod.getReturnType().getDescriptor());
|
iv.getfield(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(), original.getName().getName(),
|
||||||
else
|
originalMethod.getReturnType().getDescriptor());
|
||||||
iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(), originalMethod.getName(), originalMethod.getDescriptor());
|
}
|
||||||
|
else {
|
||||||
|
iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(),
|
||||||
|
originalMethod.getName(), originalMethod.getDescriptor());
|
||||||
|
}
|
||||||
|
|
||||||
iv.areturn(method.getReturnType());
|
iv.areturn(method.getReturnType());
|
||||||
FunctionCodegen.endVisit(iv, "accessor", null);
|
FunctionCodegen.endVisit(iv, "accessor", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bridge.isVar())
|
if (bridge.isVar()) {
|
||||||
{
|
|
||||||
Method method = typeMapper.mapSetterSignature(bridge, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod();
|
Method method = typeMapper.mapSetterSignature(bridge, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod();
|
||||||
JvmPropertyAccessorSignature originalSignature2 = typeMapper.mapSetterSignature(original, OwnerKind.IMPLEMENTATION);
|
JvmPropertyAccessorSignature originalSignature2 = typeMapper.mapSetterSignature(original, OwnerKind.IMPLEMENTATION);
|
||||||
Method originalMethod = originalSignature2.getJvmMethodSignature().getAsmMethod();
|
Method originalMethod = originalSignature2.getJvmMethodSignature().getAsmMethod();
|
||||||
MethodVisitor mv = v.newMethod(null, ACC_STATIC | ACC_BRIDGE | ACC_FINAL, method.getName(), method.getDescriptor(), null, null);
|
MethodVisitor mv =
|
||||||
|
v.newMethod(null, ACC_STATIC | ACC_BRIDGE | ACC_FINAL, method.getName(), method.getDescriptor(), null, null);
|
||||||
PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature2.getPropertyTypeKotlinSignature(),
|
PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature2.getPropertyTypeKotlinSignature(),
|
||||||
originalSignature2.getJvmMethodSignature().getKotlinTypeParameter(),
|
originalSignature2.getJvmMethodSignature().getKotlinTypeParameter(),
|
||||||
original, ((PropertyDescriptor) entry.getValue()).getSetter().getVisibility());
|
original,
|
||||||
|
((PropertyDescriptor) entry.getValue()).getSetter().getVisibility());
|
||||||
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
|
if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) {
|
||||||
StubCodegen.generateStubCode(mv);
|
StubCodegen.generateStubCode(mv);
|
||||||
}
|
}
|
||||||
@@ -441,10 +458,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
//noinspection AssignmentToForLoopParameter
|
//noinspection AssignmentToForLoopParameter
|
||||||
reg += argType.getSize();
|
reg += argType.getSize();
|
||||||
}
|
}
|
||||||
if (original.getVisibility() == Visibilities.PRIVATE && original.getModality() == Modality.FINAL)
|
if (original.getVisibility() == Visibilities.PRIVATE && original.getModality() == Modality.FINAL) {
|
||||||
iv.putfield(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(), original.getName().getName(), originalMethod.getArgumentTypes()[0].getDescriptor());
|
iv.putfield(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(), original.getName().getName(),
|
||||||
else
|
originalMethod.getArgumentTypes()[0].getDescriptor());
|
||||||
iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(), originalMethod.getName(), originalMethod.getDescriptor());
|
}
|
||||||
|
else {
|
||||||
|
iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(),
|
||||||
|
originalMethod.getName(), originalMethod.getDescriptor());
|
||||||
|
}
|
||||||
|
|
||||||
iv.areturn(method.getReturnType());
|
iv.areturn(method.getReturnType());
|
||||||
FunctionCodegen.endVisit(iv, "accessor", null);
|
FunctionCodegen.endVisit(iv, "accessor", null);
|
||||||
@@ -471,7 +492,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
v.putstatic(name, "$instance", typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getDescriptor());
|
v.putstatic(name, "$instance", typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getDescriptor());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -501,8 +521,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
protected void generatePrimaryConstructor() {
|
protected void generatePrimaryConstructor() {
|
||||||
if (myClass instanceof JetClass) {
|
if (myClass instanceof JetClass) {
|
||||||
JetClass aClass = (JetClass) myClass;
|
JetClass aClass = (JetClass) myClass;
|
||||||
if (aClass.isTrait())
|
if (aClass.isTrait()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
if (aClass.isAnnotation()) {
|
if (aClass.isAnnotation()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -529,7 +550,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
if (hasThis0) {
|
if (hasThis0) {
|
||||||
signatureWriter.writeParameterType(JvmMethodParameterKind.THIS0);
|
signatureWriter.writeParameterType(JvmMethodParameterKind.THIS0);
|
||||||
typeMapper.mapType(typeMapper.getClosureAnnotator().getEclosingClassDescriptor(descriptor).getDefaultType(), signatureWriter, MapTypeMode.VALUE);
|
typeMapper
|
||||||
|
.mapType(typeMapper.getClosureAnnotator().getEclosingClassDescriptor(descriptor).getDefaultType(), signatureWriter,
|
||||||
|
MapTypeMode.VALUE);
|
||||||
signatureWriter.writeParameterTypeEnd();
|
signatureWriter.writeParameterTypeEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -538,10 +561,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
signatureWriter.writeVoidReturn();
|
signatureWriter.writeVoidReturn();
|
||||||
|
|
||||||
constructorMethod = signatureWriter.makeJvmMethodSignature("<init>");
|
constructorMethod = signatureWriter.makeJvmMethodSignature("<init>");
|
||||||
callableMethod = new CallableMethod(JvmClassName.byInternalName("Ignored"), null, null, constructorMethod, INVOKESPECIAL, null, null, null);
|
callableMethod =
|
||||||
|
new CallableMethod(JvmClassName.byInternalName("Ignored"), null, null, constructorMethod, INVOKESPECIAL, null, null,
|
||||||
|
null);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
callableMethod = typeMapper.mapToCallableMethod(constructorDescriptor, kind, typeMapper.hasThis0(constructorDescriptor.getContainingDeclaration()));
|
callableMethod = typeMapper.mapToCallableMethod(constructorDescriptor, kind,
|
||||||
|
typeMapper.hasThis0(constructorDescriptor.getContainingDeclaration()));
|
||||||
constructorMethod = callableMethod.getSignature();
|
constructorMethod = callableMethod.getSignature();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -566,22 +592,28 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
ObjectOrClosureCodegen closure = context.closure;
|
ObjectOrClosureCodegen closure = context.closure;
|
||||||
int firstSuperArgument = -1;
|
int firstSuperArgument = -1;
|
||||||
final LinkedList<JvmMethodParameterSignature> consArgTypes = new LinkedList<JvmMethodParameterSignature>(constructorMethod.getKotlinParameterTypes());
|
final LinkedList<JvmMethodParameterSignature> consArgTypes =
|
||||||
|
new LinkedList<JvmMethodParameterSignature>(constructorMethod.getKotlinParameterTypes());
|
||||||
|
|
||||||
int insert = 0;
|
int insert = 0;
|
||||||
if (closure != null) {
|
if (closure != null) {
|
||||||
if (closure.captureThis != null) {
|
if (closure.captureThis != null) {
|
||||||
if (!hasThis0)
|
if (!hasThis0) {
|
||||||
consArgTypes.add(insert, new JvmMethodParameterSignature(Type.getObjectType(context.getThisDescriptor().getName().getName()), "", JvmMethodParameterKind.THIS0));
|
consArgTypes.add(insert,
|
||||||
|
new JvmMethodParameterSignature(Type.getObjectType(context.getThisDescriptor().getName().getName()),
|
||||||
|
"", JvmMethodParameterKind.THIS0));
|
||||||
|
}
|
||||||
insert++;
|
insert++;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (hasThis0)
|
if (hasThis0) {
|
||||||
insert++;
|
insert++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (closure.captureReceiver != null)
|
if (closure.captureReceiver != null) {
|
||||||
consArgTypes.add(insert++, new JvmMethodParameterSignature(closure.captureReceiver, "", JvmMethodParameterKind.RECEIVER));
|
consArgTypes.add(insert++, new JvmMethodParameterSignature(closure.captureReceiver, "", JvmMethodParameterKind.RECEIVER));
|
||||||
|
}
|
||||||
|
|
||||||
for (DeclarationDescriptor descriptor : closure.closure.keySet()) {
|
for (DeclarationDescriptor descriptor : closure.closure.keySet()) {
|
||||||
if (descriptor instanceof VariableDescriptor && !(descriptor instanceof PropertyDescriptor)) {
|
if (descriptor instanceof VariableDescriptor && !(descriptor instanceof PropertyDescriptor)) {
|
||||||
@@ -591,7 +623,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
type = sharedVarType;
|
type = sharedVarType;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
type = state.getInjector().getJetTypeMapper().mapType(((VariableDescriptor) descriptor).getType(), MapTypeMode.VALUE);
|
type = state.getInjector().getJetTypeMapper()
|
||||||
|
.mapType(((VariableDescriptor) descriptor).getType(), MapTypeMode.VALUE);
|
||||||
}
|
}
|
||||||
consArgTypes.add(insert++, new JvmMethodParameterSignature(type, "", JvmMethodParameterKind.SHARED_VAR));
|
consArgTypes.add(insert++, new JvmMethodParameterSignature(type, "", JvmMethodParameterKind.SHARED_VAR));
|
||||||
}
|
}
|
||||||
@@ -603,14 +636,18 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
if (myClass instanceof JetObjectDeclaration && ((JetObjectDeclaration) myClass).isObjectLiteral()) {
|
if (myClass instanceof JetObjectDeclaration && ((JetObjectDeclaration) myClass).isObjectLiteral()) {
|
||||||
if (superCall instanceof JetDelegatorToSuperCall) {
|
if (superCall instanceof JetDelegatorToSuperCall) {
|
||||||
if (closure != null)
|
if (closure != null) {
|
||||||
closure.superCall = (JetDelegatorToSuperCall) superCall;
|
closure.superCall = (JetDelegatorToSuperCall) superCall;
|
||||||
DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) superCall).getCalleeExpression().getConstructorReferenceExpression());
|
}
|
||||||
|
DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET,
|
||||||
|
((JetDelegatorToSuperCall) superCall).getCalleeExpression()
|
||||||
|
.getConstructorReferenceExpression());
|
||||||
if (declarationDescriptor instanceof ClassDescriptor) {
|
if (declarationDescriptor instanceof ClassDescriptor) {
|
||||||
declarationDescriptor = ((ClassDescriptorFromSource) declarationDescriptor).getUnsubstitutedPrimaryConstructor();
|
declarationDescriptor = ((ClassDescriptorFromSource) declarationDescriptor).getUnsubstitutedPrimaryConstructor();
|
||||||
}
|
}
|
||||||
ConstructorDescriptor superConstructor = (ConstructorDescriptor) declarationDescriptor;
|
ConstructorDescriptor superConstructor = (ConstructorDescriptor) declarationDescriptor;
|
||||||
CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION, typeMapper.hasThis0(superConstructor.getContainingDeclaration()));
|
CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION, typeMapper
|
||||||
|
.hasThis0(superConstructor.getContainingDeclaration()));
|
||||||
firstSuperArgument = insert;
|
firstSuperArgument = insert;
|
||||||
for (Type t : superCallable.getSignature().getAsmMethod().getArgumentTypes()) {
|
for (Type t : superCallable.getSignature().getAsmMethod().getArgumentTypes()) {
|
||||||
consArgTypes.add(insert++, new JvmMethodParameterSignature(t, "", JvmMethodParameterKind.SHARED_VAR));
|
consArgTypes.add(insert++, new JvmMethodParameterSignature(t, "", JvmMethodParameterKind.SHARED_VAR));
|
||||||
@@ -621,7 +658,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int flags = JetTypeMapper.getAccessModifiers(constructorDescriptor, 0);
|
int flags = JetTypeMapper.getAccessModifiers(constructorDescriptor, 0);
|
||||||
final MethodVisitor mv = v.newMethod(myClass, flags, constructorMethod.getName(), constructorMethod.getAsmMethod().getDescriptor(), constructorMethod.getGenericsSignature(), null);
|
final MethodVisitor mv = v.newMethod(myClass, flags, constructorMethod.getName(), constructorMethod.getAsmMethod().getDescriptor(),
|
||||||
|
constructorMethod.getGenericsSignature(), null);
|
||||||
if (state.getClassBuilderMode() == ClassBuilderMode.SIGNATURES) return;
|
if (state.getClassBuilderMode() == ClassBuilderMode.SIGNATURES) return;
|
||||||
|
|
||||||
AnnotationVisitor jetConstructorVisitor = mv.visitAnnotation(JvmStdlibNames.JET_CONSTRUCTOR.getDescriptor(), true);
|
AnnotationVisitor jetConstructorVisitor = mv.visitAnnotation(JvmStdlibNames.JET_CONSTRUCTOR.getDescriptor(), true);
|
||||||
@@ -642,13 +680,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(myClass instanceof JetClass && ((JetClass)myClass).hasModifier(JetTokens.ENUM_KEYWORD)) {
|
if (descriptor.getKind() == ClassKind.ENUM_CLASS || descriptor.getKind() == ClassKind.ENUM_ENTRY) {
|
||||||
i += 2;
|
i += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ValueParameterDescriptor valueParameter : constructorDescriptor.getValueParameters()) {
|
for (ValueParameterDescriptor valueParameter : constructorDescriptor.getValueParameters()) {
|
||||||
AnnotationCodegen.forParameter(i, mv, state.getInjector().getJetTypeMapper()).genAnnotations(valueParameter);
|
AnnotationCodegen.forParameter(i, mv, state.getInjector().getJetTypeMapper()).genAnnotations(valueParameter);
|
||||||
JetValueParameterAnnotationWriter jetValueParameterAnnotation = JetValueParameterAnnotationWriter.visitParameterAnnotation(mv, i);
|
JetValueParameterAnnotationWriter jetValueParameterAnnotation =
|
||||||
|
JetValueParameterAnnotationWriter.visitParameterAnnotation(mv, i);
|
||||||
jetValueParameterAnnotation.writeName(valueParameter.getName().getName());
|
jetValueParameterAnnotation.writeName(valueParameter.getName().getName());
|
||||||
jetValueParameterAnnotation.writeHasDefaultValue(valueParameter.declaresDefaultValue());
|
jetValueParameterAnnotation.writeHasDefaultValue(valueParameter.declaresDefaultValue());
|
||||||
jetValueParameterAnnotation.writeType(constructorMethod.getKotlinParameterType(i));
|
jetValueParameterAnnotation.writeType(constructorMethod.getKotlinParameterType(i));
|
||||||
@@ -694,7 +733,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
if (superCall == null) {
|
if (superCall == null) {
|
||||||
iv.load(0, Type.getType("L" + superClass + ";"));
|
iv.load(0, Type.getType("L" + superClass + ";"));
|
||||||
if(descriptor.getKind() == ClassKind.ENUM_CLASS) {
|
if (descriptor.getKind() == ClassKind.ENUM_CLASS || descriptor.getKind() == ClassKind.ENUM_ENTRY) {
|
||||||
iv.load(1, JetTypeMapper.JL_STRING_TYPE);
|
iv.load(1, JetTypeMapper.JL_STRING_TYPE);
|
||||||
iv.load(2, Type.INT_TYPE);
|
iv.load(2, Type.INT_TYPE);
|
||||||
iv.invokespecial(superClass, "<init>", "(Ljava/lang/String;I)V");
|
iv.invokespecial(superClass, "<init>", "(Ljava/lang/String;I)V");
|
||||||
@@ -711,14 +750,20 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
||||||
if (typeMapper.hasThis0(superClassDescriptor)) {
|
if (typeMapper.hasThis0(superClassDescriptor)) {
|
||||||
iv.load(1, JetTypeMapper.TYPE_OBJECT);
|
iv.load(1, JetTypeMapper.TYPE_OBJECT);
|
||||||
parameterTypes.add(typeMapper.mapType(typeMapper.getClosureAnnotator().getEclosingClassDescriptor(descriptor).getDefaultType(), MapTypeMode.VALUE));
|
parameterTypes.add(typeMapper.mapType(
|
||||||
|
typeMapper.getClosureAnnotator().getEclosingClassDescriptor(descriptor).getDefaultType(), MapTypeMode.VALUE));
|
||||||
}
|
}
|
||||||
Method superCallMethod = new Method("<init>", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()]));
|
Method superCallMethod = new Method("<init>", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()]));
|
||||||
iv.invokespecial(typeMapper.mapType(superClassDescriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), "<init>", superCallMethod.getDescriptor());
|
iv.invokespecial(typeMapper.mapType(superClassDescriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), "<init>",
|
||||||
|
superCallMethod.getDescriptor());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ConstructorDescriptor constructorDescriptor1 = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) superCall).getCalleeExpression().getConstructorReferenceExpression());
|
ConstructorDescriptor constructorDescriptor1 = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET,
|
||||||
generateDelegatorToConstructorCall(iv, codegen, (JetDelegatorToSuperCall) superCall, constructorDescriptor1, frameMap, firstSuperArgument);
|
((JetDelegatorToSuperCall) superCall)
|
||||||
|
.getCalleeExpression()
|
||||||
|
.getConstructorReferenceExpression());
|
||||||
|
generateDelegatorToConstructorCall(iv, codegen, (JetDelegatorToSuperCall) superCall, constructorDescriptor1, frameMap,
|
||||||
|
firstSuperArgument);
|
||||||
}
|
}
|
||||||
|
|
||||||
final ClassDescriptor outerDescriptor = typeMapper.getClosureAnnotator().getEclosingClassDescriptor(descriptor);
|
final ClassDescriptor outerDescriptor = typeMapper.getClosureAnnotator().getEclosingClassDescriptor(descriptor);
|
||||||
@@ -738,7 +783,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
if (closure.captureReceiver != null) {
|
if (closure.captureReceiver != null) {
|
||||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||||
iv.load(1, closure.captureReceiver);
|
iv.load(1, closure.captureReceiver);
|
||||||
iv.putfield(typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), "receiver$0", closure.captureReceiver.getDescriptor());
|
iv.putfield(typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), "receiver$0",
|
||||||
|
closure.captureReceiver.getDescriptor());
|
||||||
k += closure.captureReceiver.getSize();
|
k += closure.captureReceiver.getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -752,7 +798,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||||
iv.load(k, StackValue.refType(sharedVarType));
|
iv.load(k, StackValue.refType(sharedVarType));
|
||||||
k += StackValue.refType(sharedVarType).getSize();
|
k += StackValue.refType(sharedVarType).getSize();
|
||||||
iv.putfield(typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), "$" + varDescr.getName(), sharedVarType.getDescriptor());
|
iv.putfield(typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(),
|
||||||
|
"$" + varDescr.getName(), sharedVarType.getDescriptor());
|
||||||
l++;
|
l++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -760,8 +807,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
int n = 0;
|
int n = 0;
|
||||||
for (JetDelegationSpecifier specifier : myClass.getDelegationSpecifiers()) {
|
for (JetDelegationSpecifier specifier : myClass.getDelegationSpecifiers()) {
|
||||||
if (specifier == superCall)
|
if (specifier == superCall) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (specifier instanceof JetDelegatorByExpressionSpecifier) {
|
if (specifier instanceof JetDelegatorByExpressionSpecifier) {
|
||||||
iv.load(0, classType);
|
iv.load(0, classType);
|
||||||
@@ -779,8 +827,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
JetClass superClass = (JetClass) BindingContextUtils.classDescriptorToDeclaration(bindingContext, superClassDescriptor);
|
JetClass superClass = (JetClass) BindingContextUtils.classDescriptorToDeclaration(bindingContext, superClassDescriptor);
|
||||||
final CodegenContext delegateContext = context.intoClass(superClassDescriptor,
|
final CodegenContext delegateContext = context.intoClass(superClassDescriptor,
|
||||||
new OwnerKind.DelegateKind(StackValue.field(fieldType, classname, delegateField, false),
|
new OwnerKind.DelegateKind(StackValue.field(fieldType, classname,
|
||||||
typeMapper.mapType(superClassDescriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName()), state.getInjector().getJetTypeMapper());
|
delegateField, false),
|
||||||
|
typeMapper.mapType(superClassDescriptor
|
||||||
|
.getDefaultType(),
|
||||||
|
MapTypeMode.IMPL)
|
||||||
|
.getInternalName()),
|
||||||
|
state.getInjector().getJetTypeMapper());
|
||||||
generateDelegates(superClass, delegateContext, field);
|
generateDelegates(superClass, delegateContext, field);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -803,12 +856,15 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
mv.visitInsn(RETURN);
|
mv.visitInsn(RETURN);
|
||||||
FunctionCodegen.endVisit(mv, "constructor", myClass);
|
FunctionCodegen.endVisit(mv, "constructor", myClass);
|
||||||
|
|
||||||
FunctionCodegen.generateDefaultIfNeeded(constructorContext, state, v, constructorMethod.getAsmMethod(), constructorDescriptor, OwnerKind.IMPLEMENTATION);
|
FunctionCodegen.generateDefaultIfNeeded(constructorContext, state, v, constructorMethod.getAsmMethod(), constructorDescriptor,
|
||||||
|
OwnerKind.IMPLEMENTATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateTraitMethods() {
|
private void generateTraitMethods() {
|
||||||
if (myClass instanceof JetClass && (((JetClass)myClass).isTrait() || ((JetClass)myClass).hasModifier(JetTokens.ABSTRACT_KEYWORD)))
|
if (myClass instanceof JetClass &&
|
||||||
|
(((JetClass) myClass).isTrait() || ((JetClass) myClass).hasModifier(JetTokens.ABSTRACT_KEYWORD))) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (Pair<CallableMemberDescriptor, CallableMemberDescriptor> needDelegates : getTraitImplementations(descriptor)) {
|
for (Pair<CallableMemberDescriptor, CallableMemberDescriptor> needDelegates : getTraitImplementations(descriptor)) {
|
||||||
CallableMemberDescriptor callableDescriptor = needDelegates.first;
|
CallableMemberDescriptor callableDescriptor = needDelegates.first;
|
||||||
@@ -843,11 +899,15 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
PropertyDescriptor property = ((PropertyAccessorDescriptor) fun).getCorrespondingProperty();
|
PropertyDescriptor property = ((PropertyAccessorDescriptor) fun).getCorrespondingProperty();
|
||||||
if (fun instanceof PropertyGetterDescriptor) {
|
if (fun instanceof PropertyGetterDescriptor) {
|
||||||
function = typeMapper.mapGetterSignature(property, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod();
|
function = typeMapper.mapGetterSignature(property, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod();
|
||||||
functionOriginal = typeMapper.mapGetterSignature(property.getOriginal(), OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod();
|
functionOriginal =
|
||||||
|
typeMapper.mapGetterSignature(property.getOriginal(), OwnerKind.IMPLEMENTATION).getJvmMethodSignature()
|
||||||
|
.getAsmMethod();
|
||||||
}
|
}
|
||||||
else if (fun instanceof PropertySetterDescriptor) {
|
else if (fun instanceof PropertySetterDescriptor) {
|
||||||
function = typeMapper.mapSetterSignature(property, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod();
|
function = typeMapper.mapSetterSignature(property, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod();
|
||||||
functionOriginal = typeMapper.mapSetterSignature(property.getOriginal(), OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod();
|
functionOriginal =
|
||||||
|
typeMapper.mapSetterSignature(property.getOriginal(), OwnerKind.IMPLEMENTATION).getJvmMethodSignature()
|
||||||
|
.getAsmMethod();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new IllegalStateException("Accessor is neither getter, nor setter, what is it?");
|
throw new IllegalStateException("Accessor is neither getter, nor setter, what is it?");
|
||||||
@@ -861,14 +921,16 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
final MethodVisitor mv = v.newMethod(myClass, flags, function.getName(), function.getDescriptor(), null, null);
|
final MethodVisitor mv = v.newMethod(myClass, flags, function.getName(), function.getDescriptor(), null, null);
|
||||||
AnnotationCodegen.forMethod(mv, state.getInjector().getJetTypeMapper()).genAnnotations(fun);
|
AnnotationCodegen.forMethod(mv, state.getInjector().getJetTypeMapper()).genAnnotations(fun);
|
||||||
|
|
||||||
JvmMethodSignature jvmSignature = typeMapper.mapToCallableMethod(inheritedFun, false, OwnerKind.IMPLEMENTATION).getSignature();
|
JvmMethodSignature jvmSignature =
|
||||||
|
typeMapper.mapToCallableMethod(inheritedFun, false, OwnerKind.IMPLEMENTATION).getSignature();
|
||||||
JetMethodAnnotationWriter aw = JetMethodAnnotationWriter.visitAnnotation(mv);
|
JetMethodAnnotationWriter aw = JetMethodAnnotationWriter.visitAnnotation(mv);
|
||||||
BitSet kotlinFlags = CodegenUtil.getFlagsForVisibility(fun.getVisibility());
|
BitSet kotlinFlags = CodegenUtil.getFlagsForVisibility(fun.getVisibility());
|
||||||
if (fun instanceof PropertyAccessorDescriptor) {
|
if (fun instanceof PropertyAccessorDescriptor) {
|
||||||
kotlinFlags.set(JvmStdlibNames.FLAG_PROPERTY_BIT);
|
kotlinFlags.set(JvmStdlibNames.FLAG_PROPERTY_BIT);
|
||||||
aw.writeTypeParameters(jvmSignature.getKotlinTypeParameter());
|
aw.writeTypeParameters(jvmSignature.getKotlinTypeParameter());
|
||||||
aw.writePropertyType(jvmSignature.getKotlinReturnType());
|
aw.writePropertyType(jvmSignature.getKotlinReturnType());
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
aw.writeNullableReturnType(fun.getReturnType().isNullable());
|
aw.writeNullableReturnType(fun.getReturnType().isNullable());
|
||||||
aw.writeTypeParameters(jvmSignature.getKotlinTypeParameter());
|
aw.writeTypeParameters(jvmSignature.getKotlinTypeParameter());
|
||||||
aw.writeReturnType(jvmSignature.getKotlinReturnType());
|
aw.writeReturnType(jvmSignature.getKotlinReturnType());
|
||||||
@@ -882,7 +944,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
else if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
|
else if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
FrameMap frameMap = context.prepareFrame(state.getInjector().getJetTypeMapper());
|
FrameMap frameMap = context.prepareFrame(state.getInjector().getJetTypeMapper());
|
||||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, jvmSignature.getAsmMethod().getReturnType(), context, state);
|
ExpressionCodegen codegen =
|
||||||
|
new ExpressionCodegen(mv, frameMap, jvmSignature.getAsmMethod().getReturnType(), context, state);
|
||||||
codegen.generateThisOrOuter(descriptor); // ??? wouldn't it be a good idea to put it?
|
codegen.generateThisOrOuter(descriptor); // ??? wouldn't it be a good idea to put it?
|
||||||
|
|
||||||
Type[] argTypes = function.getArgumentTypes();
|
Type[] argTypes = function.getArgumentTypes();
|
||||||
@@ -905,9 +968,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String fdescriptor = functionOriginal.getDescriptor().replace("(", "(" + type.getDescriptor());
|
String fdescriptor = functionOriginal.getDescriptor().replace("(", "(" + type.getDescriptor());
|
||||||
Type type1 = typeMapper.mapType(((ClassDescriptor) fun.getContainingDeclaration()).getDefaultType(), MapTypeMode.TRAIT_IMPL);
|
Type type1 =
|
||||||
|
typeMapper.mapType(((ClassDescriptor) fun.getContainingDeclaration()).getDefaultType(), MapTypeMode.TRAIT_IMPL);
|
||||||
iv.invokestatic(type1.getInternalName(), function.getName(), fdescriptor);
|
iv.invokestatic(type1.getInternalName(), function.getName(), fdescriptor);
|
||||||
if (function.getReturnType().getSort() == Type.OBJECT && !function.getReturnType().equals(functionOriginal.getReturnType())) {
|
if (function.getReturnType().getSort() == Type.OBJECT &&
|
||||||
|
!function.getReturnType().equals(functionOriginal.getReturnType())) {
|
||||||
iv.checkcast(function.getReturnType());
|
iv.checkcast(function.getReturnType());
|
||||||
}
|
}
|
||||||
iv.areturn(function.getReturnType());
|
iv.areturn(function.getReturnType());
|
||||||
@@ -919,26 +984,36 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateDelegatorToConstructorCall(InstructionAdapter iv, ExpressionCodegen codegen, JetCallElement constructorCall,
|
private void generateDelegatorToConstructorCall(
|
||||||
|
InstructionAdapter iv, ExpressionCodegen codegen, JetCallElement constructorCall,
|
||||||
ConstructorDescriptor constructorDescriptor,
|
ConstructorDescriptor constructorDescriptor,
|
||||||
ConstructorFrameMap frameMap, int firstSuperArgument) {
|
ConstructorFrameMap frameMap, int firstSuperArgument
|
||||||
|
) {
|
||||||
ClassDescriptor classDecl = constructorDescriptor.getContainingDeclaration();
|
ClassDescriptor classDecl = constructorDescriptor.getContainingDeclaration();
|
||||||
|
|
||||||
iv.load(0, TYPE_OBJECT);
|
iv.load(0, TYPE_OBJECT);
|
||||||
if(classDecl.getKind() == ClassKind.ENUM_CLASS) {
|
if (classDecl.getKind() == ClassKind.ENUM_CLASS || classDecl.getKind() == ClassKind.ENUM_ENTRY) {
|
||||||
iv.load(1, JetTypeMapper.TYPE_OBJECT);
|
iv.load(1, JetTypeMapper.TYPE_OBJECT);
|
||||||
iv.load(2, Type.INT_TYPE);
|
iv.load(2, Type.INT_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (classDecl.getContainingDeclaration() instanceof ClassDescriptor) {
|
if (classDecl.getContainingDeclaration() instanceof ClassDescriptor) {
|
||||||
iv.load(frameMap.getOuterThisIndex(), typeMapper.mapType(((ClassDescriptor) descriptor.getContainingDeclaration()).getDefaultType(), MapTypeMode.IMPL));
|
iv.load(frameMap.getOuterThisIndex(),
|
||||||
|
typeMapper.mapType(((ClassDescriptor) descriptor.getContainingDeclaration()).getDefaultType(), MapTypeMode.IMPL));
|
||||||
}
|
}
|
||||||
|
|
||||||
CallableMethod method = typeMapper.mapToCallableMethod(constructorDescriptor, kind, typeMapper.hasThis0(constructorDescriptor.getContainingDeclaration()));
|
CallableMethod method = typeMapper
|
||||||
|
.mapToCallableMethod(constructorDescriptor, kind, typeMapper.hasThis0(constructorDescriptor.getContainingDeclaration()));
|
||||||
|
|
||||||
if (myClass instanceof JetObjectDeclaration && superCall instanceof JetDelegatorToSuperCall && ((JetObjectDeclaration) myClass).isObjectLiteral()) {
|
if (myClass instanceof JetObjectDeclaration &&
|
||||||
ConstructorDescriptor superConstructor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) superCall).getCalleeExpression().getConstructorReferenceExpression());
|
superCall instanceof JetDelegatorToSuperCall &&
|
||||||
CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION, typeMapper.hasThis0(superConstructor.getContainingDeclaration()));
|
((JetObjectDeclaration) myClass).isObjectLiteral()) {
|
||||||
|
ConstructorDescriptor superConstructor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET,
|
||||||
|
((JetDelegatorToSuperCall) superCall)
|
||||||
|
.getCalleeExpression()
|
||||||
|
.getConstructorReferenceExpression());
|
||||||
|
CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION,
|
||||||
|
typeMapper.hasThis0(superConstructor.getContainingDeclaration()));
|
||||||
int nextVar = firstSuperArgument + 1;
|
int nextVar = firstSuperArgument + 1;
|
||||||
for (Type t : superCallable.getSignature().getAsmMethod().getArgumentTypes()) {
|
for (Type t : superCallable.getSignature().getAsmMethod().getArgumentTypes()) {
|
||||||
iv.load(nextVar, t);
|
iv.load(nextVar, t);
|
||||||
@@ -999,7 +1074,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
iv.iconst(ordinal);
|
iv.iconst(ordinal);
|
||||||
|
|
||||||
// TODO type and constructor parameters
|
// TODO type and constructor parameters
|
||||||
String implClass = typeMapper.mapType(myType, MapTypeMode.IMPL).getInternalName();
|
ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, enumConstant);
|
||||||
|
String implClass = typeMapper.mapType(classDescriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName();
|
||||||
|
|
||||||
final List<JetDelegationSpecifier> delegationSpecifiers = enumConstant.getDelegationSpecifiers();
|
final List<JetDelegationSpecifier> delegationSpecifiers = enumConstant.getDelegationSpecifiers();
|
||||||
if (delegationSpecifiers.size() > 1) {
|
if (delegationSpecifiers.size() > 1) {
|
||||||
@@ -1016,8 +1092,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
final JetDelegationSpecifier specifier = delegationSpecifiers.get(0);
|
final JetDelegationSpecifier specifier = delegationSpecifiers.get(0);
|
||||||
if (specifier instanceof JetDelegatorToSuperCall) {
|
if (specifier instanceof JetDelegatorToSuperCall) {
|
||||||
final JetDelegatorToSuperCall superCall = (JetDelegatorToSuperCall) specifier;
|
final JetDelegatorToSuperCall superCall = (JetDelegatorToSuperCall) specifier;
|
||||||
ConstructorDescriptor constructorDescriptor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, superCall.getCalleeExpression().getConstructorReferenceExpression());
|
ConstructorDescriptor constructorDescriptor = (ConstructorDescriptor) bindingContext
|
||||||
CallableMethod method = typeMapper.mapToCallableMethod(constructorDescriptor, OwnerKind.IMPLEMENTATION, typeMapper.hasThis0(constructorDescriptor.getContainingDeclaration()));
|
.get(BindingContext.REFERENCE_TARGET, superCall.getCalleeExpression().getConstructorReferenceExpression());
|
||||||
|
CallableMethod method = typeMapper.mapToCallableMethod(constructorDescriptor, OwnerKind.IMPLEMENTATION, typeMapper
|
||||||
|
.hasThis0(constructorDescriptor.getContainingDeclaration()));
|
||||||
codegen.invokeMethodWithArguments(method, superCall, StackValue.none());
|
codegen.invokeMethodWithArguments(method, superCall, StackValue.none());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -1028,14 +1106,16 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
iv.invokespecial(implClass, "<init>", "(Ljava/lang/String;I)V");
|
iv.invokespecial(implClass, "<init>", "(Ljava/lang/String;I)V");
|
||||||
}
|
}
|
||||||
iv.dup();
|
iv.dup();
|
||||||
iv.putstatic(implClass, enumConstant.getName(), "L" + implClass + ";");
|
iv.putstatic(myAsmType.getInternalName(), enumConstant.getName(), "L" + myAsmType.getInternalName() + ";");
|
||||||
iv.astore(TYPE_OBJECT);
|
iv.astore(TYPE_OBJECT);
|
||||||
}
|
}
|
||||||
iv.putstatic(myAsmType.getInternalName(), "$VALUES", arrayAsmType.getDescriptor());
|
iv.putstatic(myAsmType.getInternalName(), "$VALUES", arrayAsmType.getDescriptor());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void generateInitializers(@NotNull ExpressionCodegen codegen, @NotNull InstructionAdapter iv, @NotNull List<JetDeclaration> declarations,
|
public static void generateInitializers(
|
||||||
@NotNull BindingContext bindingContext, @NotNull JetTypeMapper typeMapper) {
|
@NotNull ExpressionCodegen codegen, @NotNull InstructionAdapter iv, @NotNull List<JetDeclaration> declarations,
|
||||||
|
@NotNull BindingContext bindingContext, @NotNull JetTypeMapper typeMapper
|
||||||
|
) {
|
||||||
for (JetDeclaration declaration : declarations) {
|
for (JetDeclaration declaration : declarations) {
|
||||||
if (declaration instanceof JetProperty) {
|
if (declaration instanceof JetProperty) {
|
||||||
final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) bindingContext.get(BindingContext.VARIABLE, declaration);
|
final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) bindingContext.get(BindingContext.VARIABLE, declaration);
|
||||||
@@ -1049,33 +1129,43 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
Type type = typeMapper.mapType(propertyDescriptor.getType(), MapTypeMode.VALUE);
|
Type type = typeMapper.mapType(propertyDescriptor.getType(), MapTypeMode.VALUE);
|
||||||
if (JetTypeMapper.isPrimitive(type)) {
|
if (JetTypeMapper.isPrimitive(type)) {
|
||||||
if (!propertyDescriptor.getType().isNullable() && value instanceof Number) {
|
if (!propertyDescriptor.getType().isNullable() && value instanceof Number) {
|
||||||
if (type == Type.INT_TYPE && ((Number)value).intValue() == 0)
|
if (type == Type.INT_TYPE && ((Number) value).intValue() == 0) {
|
||||||
continue;
|
|
||||||
if (type == Type.BYTE_TYPE && ((Number)value).byteValue() == 0)
|
|
||||||
continue;
|
|
||||||
if (type == Type.LONG_TYPE && ((Number)value).longValue() == 0L)
|
|
||||||
continue;
|
|
||||||
if (type == Type.SHORT_TYPE && ((Number)value).shortValue() == 0)
|
|
||||||
continue;
|
|
||||||
if (type == Type.DOUBLE_TYPE && ((Number)value).doubleValue() == 0d)
|
|
||||||
continue;
|
|
||||||
if (type == Type.FLOAT_TYPE && ((Number)value).byteValue() == 0f)
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (type == Type.BOOLEAN_TYPE && value instanceof Boolean && !((Boolean)value))
|
if (type == Type.BYTE_TYPE && ((Number) value).byteValue() == 0) {
|
||||||
continue;
|
continue;
|
||||||
if (type == Type.CHAR_TYPE && value instanceof Character && ((Character)value) == 0)
|
}
|
||||||
|
if (type == Type.LONG_TYPE && ((Number) value).longValue() == 0L) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (type == Type.SHORT_TYPE && ((Number) value).shortValue() == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (type == Type.DOUBLE_TYPE && ((Number) value).doubleValue() == 0d) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (type == Type.FLOAT_TYPE && ((Number) value).byteValue() == 0f) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (type == Type.BOOLEAN_TYPE && value instanceof Boolean && !((Boolean) value)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (type == Type.CHAR_TYPE && value instanceof Character && ((Character) value) == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
if (value == null)
|
if (value == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||||
Type type = codegen.expressionType(initializer);
|
Type type = codegen.expressionType(initializer);
|
||||||
if (propertyDescriptor.getType().isNullable())
|
if (propertyDescriptor.getType().isNullable()) {
|
||||||
type = JetTypeMapper.boxType(type);
|
type = JetTypeMapper.boxType(type);
|
||||||
|
}
|
||||||
codegen.gen(initializer, type);
|
codegen.gen(initializer, type);
|
||||||
// @todo write directly to the field. Fix test excloset.jet::test6
|
// @todo write directly to the field. Fix test excloset.jet::test6
|
||||||
JvmClassName owner = typeMapper.getOwner(propertyDescriptor, OwnerKind.IMPLEMENTATION);
|
JvmClassName owner = typeMapper.getOwner(propertyDescriptor, OwnerKind.IMPLEMENTATION);
|
||||||
@@ -1083,7 +1173,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
StackValue.property(propertyDescriptor.getName().getName(), owner, owner,
|
StackValue.property(propertyDescriptor.getName().getName(), owner, owner,
|
||||||
propType, false, false, false, null, null, 0).store(propType, iv);
|
propType, false, false, false, null, null, 0).store(propType, iv);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (declaration instanceof JetClassInitializer) {
|
else if (declaration instanceof JetClassInitializer) {
|
||||||
@@ -1105,7 +1194,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
for (CallableMemberDescriptor overriddenDescriptor : overriddenDescriptors) {
|
for (CallableMemberDescriptor overriddenDescriptor : overriddenDescriptors) {
|
||||||
if (overriddenDescriptor.getContainingDeclaration() == classDescriptor) {
|
if (overriddenDescriptor.getContainingDeclaration() == classDescriptor) {
|
||||||
if (declaration instanceof PropertyDescriptor) {
|
if (declaration instanceof PropertyDescriptor) {
|
||||||
propertyCodegen.genDelegate((PropertyDescriptor) declaration, (PropertyDescriptor) overriddenDescriptor, field);
|
propertyCodegen
|
||||||
|
.genDelegate((PropertyDescriptor) declaration, (PropertyDescriptor) overriddenDescriptor, field);
|
||||||
}
|
}
|
||||||
else if (declaration instanceof SimpleFunctionDescriptor) {
|
else if (declaration instanceof SimpleFunctionDescriptor) {
|
||||||
functionCodegen.genDelegate((SimpleFunctionDescriptor) declaration, overriddenDescriptor, field);
|
functionCodegen.genDelegate((SimpleFunctionDescriptor) declaration, overriddenDescriptor, field);
|
||||||
@@ -1141,7 +1231,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Collection<CallableMemberDescriptor> overriddenDeclarations = OverridingUtil.getOverriddenDeclarations(callableMemberDescriptor);
|
Collection<CallableMemberDescriptor> overriddenDeclarations =
|
||||||
|
OverridingUtil.getOverriddenDeclarations(callableMemberDescriptor);
|
||||||
for (CallableMemberDescriptor overriddenDeclaration : overriddenDeclarations) {
|
for (CallableMemberDescriptor overriddenDeclaration : overriddenDeclarations) {
|
||||||
if (overriddenDeclaration.getModality() != Modality.ABSTRACT) {
|
if (overriddenDeclaration.getModality() != Modality.ABSTRACT) {
|
||||||
if (!CodegenUtil.isInterface(overriddenDeclaration.getContainingDeclaration())) {
|
if (!CodegenUtil.isInterface(overriddenDeclaration.getContainingDeclaration())) {
|
||||||
@@ -1159,5 +1250,4 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -306,11 +306,13 @@ public class JetTypeMapper {
|
|||||||
return JvmClassName.byInternalName(r.toString());
|
return JvmClassName.byInternalName(r.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull public Type mapReturnType(@NotNull final JetType jetType) {
|
@NotNull
|
||||||
|
public Type mapReturnType(@NotNull final JetType jetType) {
|
||||||
return mapReturnType(jetType, null);
|
return mapReturnType(jetType, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull private Type mapReturnType(@NotNull final JetType jetType, @Nullable BothSignatureWriter signatureVisitor) {
|
@NotNull
|
||||||
|
private Type mapReturnType(@NotNull final JetType jetType, @Nullable BothSignatureWriter signatureVisitor) {
|
||||||
if (jetType.equals(JetStandardClasses.getUnitType())) {
|
if (jetType.equals(JetStandardClasses.getUnitType())) {
|
||||||
if (signatureVisitor != null) {
|
if (signatureVisitor != null) {
|
||||||
signatureVisitor.writeAsmType(Type.VOID_TYPE, false);
|
signatureVisitor.writeAsmType(Type.VOID_TYPE, false);
|
||||||
@@ -375,9 +377,14 @@ public class JetTypeMapper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (klass.getKind() == ClassKind.ENUM_ENTRY) {
|
else if (klass.getKind() == ClassKind.ENUM_ENTRY) {
|
||||||
|
if (closureAnnotator.enumEntryNeedSubclass(klass)) {
|
||||||
|
return getJvmInternalFQName(klass.getContainingDeclaration()) + "$" + klass.getName().getName();
|
||||||
|
}
|
||||||
|
else {
|
||||||
return getJvmInternalFQName(klass.getContainingDeclaration());
|
return getJvmInternalFQName(klass.getContainingDeclaration());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DeclarationDescriptor container = descriptor.getContainingDeclaration();
|
DeclarationDescriptor container = descriptor.getContainingDeclaration();
|
||||||
|
|
||||||
@@ -511,7 +518,8 @@ public class JetTypeMapper {
|
|||||||
|
|
||||||
Type type = mapType(((TypeParameterDescriptor) descriptor).getUpperBoundsAsType(), kind);
|
Type type = mapType(((TypeParameterDescriptor) descriptor).getUpperBoundsAsType(), kind);
|
||||||
if (signatureVisitor != null) {
|
if (signatureVisitor != null) {
|
||||||
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) jetType.getConstructor().getDeclarationDescriptor();
|
TypeParameterDescriptor typeParameterDescriptor =
|
||||||
|
(TypeParameterDescriptor) jetType.getConstructor().getDeclarationDescriptor();
|
||||||
assert typeParameterDescriptor != null;
|
assert typeParameterDescriptor != null;
|
||||||
signatureVisitor.writeTypeVariable(typeParameterDescriptor.getName(), jetType.isNullable(), type);
|
signatureVisitor.writeTypeVariable(typeParameterDescriptor.getName(), jetType.isNullable(), type);
|
||||||
}
|
}
|
||||||
@@ -584,7 +592,9 @@ public class JetTypeMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public CallableMethod mapToCallableMethod(FunctionDescriptor functionDescriptor, boolean superCall, OwnerKind kind) {
|
public CallableMethod mapToCallableMethod(FunctionDescriptor functionDescriptor, boolean superCall, OwnerKind kind) {
|
||||||
if (functionDescriptor == null) { return null; }
|
if (functionDescriptor == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
final DeclarationDescriptor functionParent = functionDescriptor.getOriginal().getContainingDeclaration();
|
final DeclarationDescriptor functionParent = functionDescriptor.getOriginal().getContainingDeclaration();
|
||||||
|
|
||||||
@@ -614,7 +624,8 @@ public class JetTypeMapper {
|
|||||||
thisClass = null;
|
thisClass = null;
|
||||||
}
|
}
|
||||||
else if (functionParent instanceof ScriptDescriptor) {
|
else if (functionParent instanceof ScriptDescriptor) {
|
||||||
thisClass = owner = ownerForDefaultParam = ownerForDefaultImpl = closureAnnotator.classNameForScriptDescriptor((ScriptDescriptor) functionParent);
|
thisClass = owner =
|
||||||
|
ownerForDefaultParam = ownerForDefaultImpl = closureAnnotator.classNameForScriptDescriptor((ScriptDescriptor) functionParent);
|
||||||
invokeOpcode = INVOKEVIRTUAL;
|
invokeOpcode = INVOKEVIRTUAL;
|
||||||
}
|
}
|
||||||
else if (functionParent instanceof ClassDescriptor) {
|
else if (functionParent instanceof ClassDescriptor) {
|
||||||
@@ -673,7 +684,9 @@ public class JetTypeMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isAccessor(FunctionDescriptor functionDescriptor) {
|
private static boolean isAccessor(FunctionDescriptor functionDescriptor) {
|
||||||
return functionDescriptor instanceof AccessorForFunctionDescriptor || functionDescriptor instanceof AccessorForPropertyDescriptor.Getter || functionDescriptor instanceof AccessorForPropertyDescriptor.Setter;
|
return functionDescriptor instanceof AccessorForFunctionDescriptor ||
|
||||||
|
functionDescriptor instanceof AccessorForPropertyDescriptor.Getter ||
|
||||||
|
functionDescriptor instanceof AccessorForPropertyDescriptor.Setter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -763,7 +776,8 @@ public class JetTypeMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void writeFormalTypeParameter(TypeParameterDescriptor typeParameterDescriptor, BothSignatureWriter signatureVisitor) {
|
private void writeFormalTypeParameter(TypeParameterDescriptor typeParameterDescriptor, BothSignatureWriter signatureVisitor) {
|
||||||
signatureVisitor.writeFormalTypeParameter(typeParameterDescriptor.getName().getName(), typeParameterDescriptor.getVariance(), typeParameterDescriptor.isReified());
|
signatureVisitor.writeFormalTypeParameter(typeParameterDescriptor.getName().getName(), typeParameterDescriptor.getVariance(),
|
||||||
|
typeParameterDescriptor.isReified());
|
||||||
|
|
||||||
classBound:
|
classBound:
|
||||||
{
|
{
|
||||||
@@ -801,7 +815,6 @@ public class JetTypeMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
signatureVisitor.writeFormalTypeParameterEnd();
|
signatureVisitor.writeFormalTypeParameterEnd();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public JvmMethodSignature mapSignature(Name name, FunctionDescriptor f) {
|
public JvmMethodSignature mapSignature(Name name, FunctionDescriptor f) {
|
||||||
@@ -863,7 +876,8 @@ public class JetTypeMapper {
|
|||||||
else {
|
else {
|
||||||
if (descriptor instanceof AccessorForPropertyDescriptor) {
|
if (descriptor instanceof AccessorForPropertyDescriptor) {
|
||||||
signatureWriter.writeParameterType(JvmMethodParameterKind.THIS);
|
signatureWriter.writeParameterType(JvmMethodParameterKind.THIS);
|
||||||
mapType(((ClassifierDescriptor)descriptor.getContainingDeclaration()).getDefaultType(), signatureWriter, MapTypeMode.VALUE);
|
mapType(((ClassifierDescriptor) descriptor.getContainingDeclaration()).getDefaultType(), signatureWriter,
|
||||||
|
MapTypeMode.VALUE);
|
||||||
signatureWriter.writeParameterTypeEnd();
|
signatureWriter.writeParameterTypeEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -910,7 +924,8 @@ public class JetTypeMapper {
|
|||||||
else {
|
else {
|
||||||
if (descriptor instanceof AccessorForPropertyDescriptor) {
|
if (descriptor instanceof AccessorForPropertyDescriptor) {
|
||||||
signatureWriter.writeParameterType(JvmMethodParameterKind.THIS);
|
signatureWriter.writeParameterType(JvmMethodParameterKind.THIS);
|
||||||
mapType(((ClassifierDescriptor)descriptor.getContainingDeclaration()).getDefaultType(), signatureWriter, MapTypeMode.VALUE);
|
mapType(((ClassifierDescriptor) descriptor.getContainingDeclaration()).getDefaultType(), signatureWriter,
|
||||||
|
MapTypeMode.VALUE);
|
||||||
signatureWriter.writeParameterTypeEnd();
|
signatureWriter.writeParameterTypeEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -930,7 +945,8 @@ public class JetTypeMapper {
|
|||||||
signatureWriter.writeVoidReturn();
|
signatureWriter.writeVoidReturn();
|
||||||
|
|
||||||
JvmMethodSignature jvmMethodSignature = signatureWriter.makeJvmMethodSignature(name);
|
JvmMethodSignature jvmMethodSignature = signatureWriter.makeJvmMethodSignature(name);
|
||||||
return new JvmPropertyAccessorSignature(jvmMethodSignature, jvmMethodSignature.getKotlinParameterType(jvmMethodSignature.getParameterCount() - 1));
|
return new JvmPropertyAccessorSignature(jvmMethodSignature,
|
||||||
|
jvmMethodSignature.getKotlinParameterType(jvmMethodSignature.getParameterCount() - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
private JvmMethodSignature mapConstructorSignature(ConstructorDescriptor descriptor, boolean hasThis0) {
|
private JvmMethodSignature mapConstructorSignature(ConstructorDescriptor descriptor, boolean hasThis0) {
|
||||||
@@ -947,11 +963,12 @@ public class JetTypeMapper {
|
|||||||
ClassDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
ClassDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
||||||
if (hasThis0) {
|
if (hasThis0) {
|
||||||
signatureWriter.writeParameterType(JvmMethodParameterKind.THIS0);
|
signatureWriter.writeParameterType(JvmMethodParameterKind.THIS0);
|
||||||
mapType(closureAnnotator.getEclosingClassDescriptor(containingDeclaration).getDefaultType(), signatureWriter, MapTypeMode.VALUE);
|
mapType(closureAnnotator.getEclosingClassDescriptor(containingDeclaration).getDefaultType(), signatureWriter,
|
||||||
|
MapTypeMode.VALUE);
|
||||||
signatureWriter.writeParameterTypeEnd();
|
signatureWriter.writeParameterTypeEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(containingDeclaration.getKind() == ClassKind.ENUM_CLASS) {
|
if (containingDeclaration.getKind() == ClassKind.ENUM_CLASS || containingDeclaration.getKind() == ClassKind.ENUM_ENTRY) {
|
||||||
signatureWriter.writeParameterType(JvmMethodParameterKind.ENUM_NAME);
|
signatureWriter.writeParameterType(JvmMethodParameterKind.ENUM_NAME);
|
||||||
mapType(JetStandardLibrary.getInstance().getStringType(), signatureWriter, MapTypeMode.VALUE);
|
mapType(JetStandardLibrary.getInstance().getStringType(), signatureWriter, MapTypeMode.VALUE);
|
||||||
signatureWriter.writeParameterTypeEnd();
|
signatureWriter.writeParameterTypeEnd();
|
||||||
@@ -983,7 +1000,8 @@ public class JetTypeMapper {
|
|||||||
|
|
||||||
for (ScriptDescriptor importedScript : importedScripts) {
|
for (ScriptDescriptor importedScript : importedScripts) {
|
||||||
signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE);
|
signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE);
|
||||||
mapType(closureAnnotator.classDescriptorForScriptDescriptor(importedScript).getDefaultType(), signatureWriter, MapTypeMode.VALUE);
|
mapType(closureAnnotator.classDescriptorForScriptDescriptor(importedScript).getDefaultType(), signatureWriter,
|
||||||
|
MapTypeMode.VALUE);
|
||||||
signatureWriter.writeParameterTypeEnd();
|
signatureWriter.writeParameterTypeEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1064,19 +1082,22 @@ public class JetTypeMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isGenericsArray(JetType type) {
|
public static boolean isGenericsArray(JetType type) {
|
||||||
return JetStandardLibraryNames.ARRAY.is(type) && type.getArguments().get(0).getType().getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor;
|
return JetStandardLibraryNames.ARRAY.is(type) &&
|
||||||
|
type.getArguments().get(0).getType().getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type getSharedVarType(DeclarationDescriptor descriptor) {
|
public Type getSharedVarType(DeclarationDescriptor descriptor) {
|
||||||
if (descriptor instanceof PropertyDescriptor) {
|
if (descriptor instanceof PropertyDescriptor) {
|
||||||
return StackValue.sharedTypeForType(mapType(((PropertyDescriptor) descriptor).getReceiverParameter().getType(), MapTypeMode.VALUE));
|
return StackValue
|
||||||
|
.sharedTypeForType(mapType(((PropertyDescriptor) descriptor).getReceiverParameter().getType(), MapTypeMode.VALUE));
|
||||||
}
|
}
|
||||||
else if (descriptor instanceof SimpleFunctionDescriptor && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) {
|
else if (descriptor instanceof SimpleFunctionDescriptor && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) {
|
||||||
PsiElement psiElement = BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor);
|
PsiElement psiElement = BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor);
|
||||||
return closureAnnotator.classNameForAnonymousClass((JetElement) psiElement).getAsmType();
|
return closureAnnotator.classNameForAnonymousClass((JetElement) psiElement).getAsmType();
|
||||||
}
|
}
|
||||||
else if (descriptor instanceof FunctionDescriptor) {
|
else if (descriptor instanceof FunctionDescriptor) {
|
||||||
return StackValue.sharedTypeForType(mapType(((FunctionDescriptor) descriptor).getReceiverParameter().getType(), MapTypeMode.VALUE));
|
return StackValue
|
||||||
|
.sharedTypeForType(mapType(((FunctionDescriptor) descriptor).getReceiverParameter().getType(), MapTypeMode.VALUE));
|
||||||
}
|
}
|
||||||
else if (descriptor instanceof VariableDescriptor && isVarCapturedInClosure(descriptor)) {
|
else if (descriptor instanceof VariableDescriptor && isVarCapturedInClosure(descriptor)) {
|
||||||
JetType outType = ((VariableDescriptor) descriptor).getType();
|
JetType outType = ((VariableDescriptor) descriptor).getType();
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
fun box() = IssueState.DEFAULT.ToString() + IssueState.FIXED.ToString()
|
||||||
|
|
||||||
|
open enum class IssueState {
|
||||||
|
DEFAULT
|
||||||
|
FIXED {
|
||||||
|
override fun ToString() = "K"
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun ToString() : String = "O"
|
||||||
|
}
|
||||||
@@ -100,4 +100,35 @@ public class EnumGenTest extends CodegenTestCase {
|
|||||||
public void testInClassObj() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
|
public void testInClassObj() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
|
||||||
blackBoxFile("enum/inclassobj.kt");
|
blackBoxFile("enum/inclassobj.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testAbstractMethod()
|
||||||
|
throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
|
||||||
|
blackBoxFile("enum/abstractmethod.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNoClassForSimpleEnum()
|
||||||
|
throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException {
|
||||||
|
loadFile("enum/name.kt");
|
||||||
|
Class cls = loadImplementationClass(generateClassesInFile(), "State");
|
||||||
|
Field field = cls.getField("O");
|
||||||
|
assertEquals("State", field.get(null).getClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testYesClassForComplexEnum()
|
||||||
|
throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException {
|
||||||
|
loadFile("enum/abstractmethod.kt");
|
||||||
|
Class cls = loadImplementationClass(generateClassesInFile(), "IssueState");
|
||||||
|
Field field = cls.getField("DEFAULT");
|
||||||
|
assertEquals("IssueState", field.get(null).getClass().getName());
|
||||||
|
field = cls.getField("FIXED");
|
||||||
|
assertEquals("IssueState", field.getType().getName());
|
||||||
|
assertEquals("IssueState$FIXED", field.get(null).getClass().getName());
|
||||||
|
assertNotNull(cls.getClassLoader().loadClass("IssueState$FIXED"));
|
||||||
|
try {
|
||||||
|
cls.getClassLoader().loadClass("IssueState$DEFAULT");
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
catch (ClassNotFoundException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user