public void genDelegate( PropertyDescriptor declaration, PropertyDescriptor overriddenDescriptor, StackValue field) { JvmPropertyAccessorSignature jvmPropertyAccessorSignature = state .getInjector() .getJetTypeMapper() .mapGetterSignature(declaration, OwnerKind.IMPLEMENTATION); functionCodegen.genDelegate( declaration, overriddenDescriptor, field, jvmPropertyAccessorSignature.getJvmMethodSignature()); if (declaration.isVar()) { jvmPropertyAccessorSignature = state .getInjector() .getJetTypeMapper() .mapSetterSignature(declaration, OwnerKind.IMPLEMENTATION); functionCodegen.genDelegate( declaration, overriddenDescriptor, field, jvmPropertyAccessorSignature.getJvmMethodSignature()); } }
private void checkPropertyGetter( @NotNull PropertyDescriptor descriptor, @NotNull JetExpression expression) { PropertyGetterDescriptor getter = descriptor.getGetter(); if (getter != null) { checkPropertyAccessor(getter, expression, descriptor.isVar()); } }
private void checkPropertyDescriptor( @NotNull JetExpression expression, @NotNull PropertyDescriptor propertyDescriptor) { // Deprecated for Property if (reportAnnotationIfNeeded(expression, propertyDescriptor, propertyDescriptor.isVar())) { return; } // Deprecated for Getter (val, var), Setter (var) if (!propertyDescriptor.isVar()) { checkPropertyGetter(propertyDescriptor, expression); } else { IElementType operation = null; JetBinaryExpression binaryExpression = PsiTreeUtil.getParentOfType(expression, JetBinaryExpression.class); if (binaryExpression != null) { JetExpression left = binaryExpression.getLeft(); if (left == expression) { operation = binaryExpression.getOperationToken(); } else { JetReferenceExpression[] jetReferenceExpressions = PsiTreeUtil.getChildrenOfType(left, JetReferenceExpression.class); if (jetReferenceExpressions != null) { for (JetReferenceExpression expr : jetReferenceExpressions) { if (expr == expression) { operation = binaryExpression.getOperationToken(); break; } } } } } else { JetUnaryExpression unaryExpression = PsiTreeUtil.getParentOfType(expression, JetUnaryExpression.class); if (unaryExpression != null) { operation = unaryExpression.getOperationReference().getReferencedNameElementType(); } } if (operation != null && PROPERTY_SET_OPERATIONS.contains(operation)) { checkPropertySetter(propertyDescriptor, expression); } else { checkPropertyGetter(propertyDescriptor, expression); } } }
public void gen(JetProperty p) { final VariableDescriptor descriptor = state.getBindingContext().get(BindingContext.VARIABLE, p); if (!(descriptor instanceof PropertyDescriptor)) { throw new UnsupportedOperationException("expect a property to have a property descriptor"); } final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor; if (kind == OwnerKind.NAMESPACE || kind == OwnerKind.IMPLEMENTATION || kind == OwnerKind.TRAIT_IMPL) { if (kind != OwnerKind.TRAIT_IMPL) generateBackingField(p, propertyDescriptor); generateGetter(p, propertyDescriptor); generateSetter(p, propertyDescriptor); } else if (kind instanceof OwnerKind.DelegateKind) { generateDefaultGetter(propertyDescriptor, Opcodes.ACC_PUBLIC, p); if (propertyDescriptor.isVar()) { generateDefaultSetter(propertyDescriptor, Opcodes.ACC_PUBLIC, p); } } }
private void generateSetter(JetProperty p, PropertyDescriptor propertyDescriptor) { final JetPropertyAccessor setter = p.getSetter(); if (setter != null) { if (setter.getBodyExpression() != null) { final PropertySetterDescriptor setterDescriptor = propertyDescriptor.getSetter(); assert setterDescriptor != null; JvmPropertyAccessorSignature signature = state.getInjector().getJetTypeMapper().mapSetterSignature(propertyDescriptor, kind); functionCodegen.generateMethod( setter, signature.getJvmMethodSignature(), true, signature.getPropertyTypeKotlinSignature(), setterDescriptor); } else if (isExternallyAccessible(propertyDescriptor)) { generateDefaultSetter(p); } } else if (isExternallyAccessible(propertyDescriptor) && propertyDescriptor.isVar()) { generateDefaultSetter(p); } }
private void generateBackingField(JetProperty p, PropertyDescriptor propertyDescriptor) { if (state.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) { DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration(); if (CodegenUtil.isInterface(containingDeclaration)) return; Object value = null; final JetExpression initializer = p.getInitializer(); if (initializer != null) { if (initializer instanceof JetConstantExpression) { CompileTimeConstant<?> compileTimeValue = state.getBindingContext().get(BindingContext.COMPILE_TIME_VALUE, initializer); value = compileTimeValue != null ? compileTimeValue.getValue() : null; } } int modifiers; if (kind == OwnerKind.NAMESPACE) { int access = JetTypeMapper.getAccessModifiers(propertyDescriptor, 0); modifiers = access | Opcodes.ACC_STATIC; } else { modifiers = JetTypeMapper.getAccessModifiers(propertyDescriptor, 0); } if (!propertyDescriptor.isVar()) { modifiers |= Opcodes.ACC_FINAL; } if (state.getInjector().getJetStandardLibrary().isVolatile(propertyDescriptor)) { modifiers |= Opcodes.ACC_VOLATILE; } Type type = state .getInjector() .getJetTypeMapper() .mapType(propertyDescriptor.getType(), MapTypeMode.VALUE); FieldVisitor fieldVisitor = v.newField(p, modifiers, p.getName(), type.getDescriptor(), null, value); AnnotationCodegen.forField(fieldVisitor, state.getInjector().getJetTypeMapper()) .genAnnotations(propertyDescriptor); } }
@Override public Boolean computeValue( SlicedMap map, PropertyDescriptor propertyDescriptor, Boolean backingFieldRequired, boolean valueNotFound) { if (propertyDescriptor.getKind() != CallableMemberDescriptor.Kind.DECLARATION) { return false; } backingFieldRequired = valueNotFound ? false : backingFieldRequired; assert backingFieldRequired != null; // TODO: user BindingContextAccessors PsiElement declarationPsiElement = map.get(BindingContextUtils.DESCRIPTOR_TO_DECLARATION, propertyDescriptor); if (declarationPsiElement instanceof JetParameter) { JetParameter jetParameter = (JetParameter) declarationPsiElement; return jetParameter.getValOrVarNode() != null || backingFieldRequired; // this part is unused because we do not allow access to // constructor parameters in member bodies } if (propertyDescriptor.getModality() == Modality.ABSTRACT) return false; PropertyGetterDescriptor getter = propertyDescriptor.getGetter(); PropertySetterDescriptor setter = propertyDescriptor.getSetter(); if (getter == null) { return true; } else if (propertyDescriptor.isVar() && setter == null) { return true; } else if (setter != null && !setter.hasBody() && setter.getModality() != Modality.ABSTRACT) { return true; } else if (!getter.hasBody() && getter.getModality() != Modality.ABSTRACT) { return true; } return backingFieldRequired; }