예제 #1
0
  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);
      }
    }
  }
예제 #4
0
 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);
     }
   }
 }
예제 #5
0
 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);
   }
 }
예제 #6
0
  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);
    }
  }
예제 #7
0
 @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;
 }