@Override
  public void visitClassType(String name, boolean nullable, boolean forceReal) {
    String ourName = name.replace('/', '.');

    this.classDescriptor = null;
    if (this.classDescriptor == null && !forceReal) {
      this.classDescriptor =
          this.javaSemanticServices
              .getTypeTransformer()
              .getPrimitiveWrappersClassDescriptorMap()
              .get(ourName);
    }

    if (this.classDescriptor == null && ourName.equals("java.lang.Object") && !forceReal) {
      this.classDescriptor = JetStandardClasses.getAny();
    }

    if (classDescriptor == null) {
      // TODO: this is the worst code in Kotlin project
      Matcher matcher = Pattern.compile("jet\\.Function(\\d+)").matcher(ourName);
      if (matcher.matches()) {
        classDescriptor = JetStandardClasses.getFunction(Integer.parseInt(matcher.group(1)));
      }
    }

    if (classDescriptor == null) {
      Matcher matcher = Pattern.compile("jet\\.Tuple(\\d+)").matcher(ourName);
      if (matcher.matches()) {
        classDescriptor = JetStandardClasses.getTuple(Integer.parseInt(matcher.group(1)));
      }
    }

    if (this.classDescriptor == null) {
      this.classDescriptor = javaDescriptorResolver.resolveClass(ourName);
    }

    if (this.classDescriptor == null) {
      throw new IllegalStateException(
          "class not found by name: " + ourName); // TODO: wrong exception
    }
    this.nullable = nullable;
    this.typeArguments = new ArrayList<TypeProjection>();
  }
  private List<ValueParameterDescriptor> createValueParameterDescriptors(
      ExpressionTypingContext context,
      JetFunctionLiteral functionLiteral,
      FunctionDescriptorImpl functionDescriptor,
      boolean functionTypeExpected) {
    List<ValueParameterDescriptor> valueParameterDescriptors = Lists.newArrayList();
    List<JetParameter> declaredValueParameters = functionLiteral.getValueParameters();

    List<ValueParameterDescriptor> expectedValueParameters =
        (functionTypeExpected)
            ? JetStandardClasses.getValueParameters(functionDescriptor, context.expectedType)
            : null;

    boolean hasDeclaredValueParameters = functionLiteral.getValueParameterList() != null;
    if (functionTypeExpected
        && !hasDeclaredValueParameters
        && expectedValueParameters.size() == 1) {
      ValueParameterDescriptor valueParameterDescriptor = expectedValueParameters.get(0);
      ValueParameterDescriptor it =
          new ValueParameterDescriptorImpl(
              functionDescriptor,
              0,
              Collections.<AnnotationDescriptor>emptyList(),
              "it",
              false,
              valueParameterDescriptor.getOutType(),
              valueParameterDescriptor.hasDefaultValue(),
              valueParameterDescriptor.getVarargElementType());
      valueParameterDescriptors.add(it);
      context.trace.record(AUTO_CREATED_IT, it);
    } else {
      for (int i = 0; i < declaredValueParameters.size(); i++) {
        JetParameter declaredParameter = declaredValueParameters.get(i);
        JetTypeReference typeReference = declaredParameter.getTypeReference();

        JetType type;
        if (typeReference != null) {
          type = context.getTypeResolver().resolveType(context.scope, typeReference);
        } else {
          if (expectedValueParameters != null && i < expectedValueParameters.size()) {
            type = expectedValueParameters.get(i).getOutType();
          } else {
            context.trace.report(CANNOT_INFER_PARAMETER_TYPE.on(declaredParameter));
            type = ErrorUtils.createErrorType("Cannot be inferred");
          }
        }
        ValueParameterDescriptor valueParameterDescriptor =
            context
                .getDescriptorResolver()
                .resolveValueParameterDescriptor(functionDescriptor, declaredParameter, i, type);
        valueParameterDescriptors.add(valueParameterDescriptor);
      }
    }
    return valueParameterDescriptors;
  }
Example #3
0
 public Map<String, JetType> getClassTypesMap() {
   if (classTypesMap == null) {
     classTypesMap = new HashMap<String, JetType>();
     for (JvmPrimitiveType jvmPrimitiveType : JvmPrimitiveType.values()) {
       PrimitiveType primitiveType = jvmPrimitiveType.getPrimitiveType();
       classTypesMap.put(
           jvmPrimitiveType.getWrapper().getFqName(),
           standardLibrary.getNullablePrimitiveJetType(primitiveType));
     }
     classTypesMap.put("java.lang.Object", JetStandardClasses.getNullableAnyType());
     classTypesMap.put("java.lang.String", standardLibrary.getNullableStringType());
     classTypesMap.put("java.lang.CharSequence", standardLibrary.getNullableCharSequenceType());
     classTypesMap.put("java.lang.Throwable", standardLibrary.getThrowableType());
   }
   return classTypesMap;
 }
Example #4
0
 public Map<String, JetType> getPrimitiveTypesMap() {
   if (primitiveTypesMap == null) {
     primitiveTypesMap = new HashMap<String, JetType>();
     for (JvmPrimitiveType jvmPrimitiveType : JvmPrimitiveType.values()) {
       PrimitiveType primitiveType = jvmPrimitiveType.getPrimitiveType();
       primitiveTypesMap.put(
           jvmPrimitiveType.getName(), standardLibrary.getPrimitiveJetType(primitiveType));
       primitiveTypesMap.put(
           "[" + jvmPrimitiveType.getName(),
           standardLibrary.getPrimitiveArrayJetType(primitiveType));
       primitiveTypesMap.put(
           jvmPrimitiveType.getWrapper().getFqName(),
           standardLibrary.getNullablePrimitiveJetType(primitiveType));
     }
     primitiveTypesMap.put("void", JetStandardClasses.getUnitType());
   }
   return primitiveTypesMap;
 }
  private NamedFunctionDescriptorImpl createFunctionDescriptor(
      JetFunctionLiteralExpression expression,
      ExpressionTypingContext context,
      boolean functionTypeExpected) {
    JetFunctionLiteral functionLiteral = expression.getFunctionLiteral();
    JetTypeReference receiverTypeRef = functionLiteral.getReceiverTypeRef();
    NamedFunctionDescriptorImpl functionDescriptor =
        new NamedFunctionDescriptorImpl(
            context.scope.getContainingDeclaration(),
            Collections.<AnnotationDescriptor>emptyList(),
            "<anonymous>",
            CallableMemberDescriptor.Kind.DECLARATION);

    List<ValueParameterDescriptor> valueParameterDescriptors =
        createValueParameterDescriptors(
            context, functionLiteral, functionDescriptor, functionTypeExpected);

    JetType effectiveReceiverType;
    if (receiverTypeRef == null) {
      if (functionTypeExpected) {
        effectiveReceiverType = JetStandardClasses.getReceiverType(context.expectedType);
      } else {
        effectiveReceiverType = null;
      }
    } else {
      effectiveReceiverType = context.getTypeResolver().resolveType(context.scope, receiverTypeRef);
    }
    functionDescriptor.initialize(
        effectiveReceiverType,
        NO_RECEIVER,
        Collections.<TypeParameterDescriptor>emptyList(),
        valueParameterDescriptors,
        null,
        Modality.FINAL,
        Visibility.LOCAL);
    context.trace.record(BindingContext.FUNCTION, expression, functionDescriptor);
    return functionDescriptor;
  }
 private JetType getPrimitiveType(char descriptor, boolean nullable) {
   if (!nullable) {
     for (JvmPrimitiveType jvmPrimitiveType : JvmPrimitiveType.values()) {
       if (jvmPrimitiveType.getJvmLetter() == descriptor) {
         return jetStandardLibrary.getPrimitiveJetType(jvmPrimitiveType.getPrimitiveType());
       }
     }
     if (descriptor == 'V') {
       return JetStandardClasses.getUnitType();
     }
   } else {
     for (JvmPrimitiveType jvmPrimitiveType : JvmPrimitiveType.values()) {
       if (jvmPrimitiveType.getJvmLetter() == descriptor) {
         return jetStandardLibrary.getNullablePrimitiveJetType(
             jvmPrimitiveType.getPrimitiveType());
       }
     }
     if (descriptor == 'V') {
       throw new IllegalStateException("incorrect signature: nullable void");
     }
   }
   throw new IllegalStateException("incorrect signature");
 }
  @Override
  public JetType visitFunctionLiteralExpression(
      JetFunctionLiteralExpression expression, ExpressionTypingContext context) {
    JetFunctionLiteral functionLiteral = expression.getFunctionLiteral();
    JetBlockExpression bodyExpression = functionLiteral.getBodyExpression();
    if (bodyExpression == null) return null;

    JetType expectedType = context.expectedType;
    boolean functionTypeExpected =
        expectedType != TypeUtils.NO_EXPECTED_TYPE
            && JetStandardClasses.isFunctionType(expectedType);

    NamedFunctionDescriptorImpl functionDescriptor =
        createFunctionDescriptor(expression, context, functionTypeExpected);

    List<JetType> parameterTypes = Lists.newArrayList();
    List<ValueParameterDescriptor> valueParameters = functionDescriptor.getValueParameters();
    for (ValueParameterDescriptor valueParameter : valueParameters) {
      parameterTypes.add(valueParameter.getOutType());
    }
    ReceiverDescriptor receiverParameter = functionDescriptor.getReceiverParameter();
    JetType receiver = receiverParameter != NO_RECEIVER ? receiverParameter.getType() : null;

    JetType returnType = TypeUtils.NO_EXPECTED_TYPE;
    JetScope functionInnerScope =
        FunctionDescriptorUtil.getFunctionInnerScope(
            context.scope, functionDescriptor, context.trace);
    JetTypeReference returnTypeRef = functionLiteral.getReturnTypeRef();
    if (returnTypeRef != null) {
      returnType = context.getTypeResolver().resolveType(context.scope, returnTypeRef);
      context
          .getServices()
          .checkFunctionReturnType(
              expression,
              context
                  .replaceScope(functionInnerScope)
                  .replaceExpectedType(returnType)
                  .replaceExpectedReturnType(returnType)
                  .replaceDataFlowInfo(context.dataFlowInfo));
    } else {
      if (functionTypeExpected) {
        returnType = JetStandardClasses.getReturnTypeFromFunctionType(expectedType);
      }
      returnType =
          context
              .getServices()
              .getBlockReturnedType(
                  functionInnerScope,
                  bodyExpression,
                  CoercionStrategy.COERCION_TO_UNIT,
                  context.replaceExpectedType(returnType).replaceExpectedReturnType(returnType));
    }
    JetType safeReturnType =
        returnType == null ? ErrorUtils.createErrorType("<return type>") : returnType;
    functionDescriptor.setReturnType(safeReturnType);

    boolean hasDeclaredValueParameters = functionLiteral.getValueParameterList() != null;
    if (!hasDeclaredValueParameters && functionTypeExpected) {
      JetType expectedReturnType = JetStandardClasses.getReturnTypeFromFunctionType(expectedType);
      if (JetStandardClasses.isUnit(expectedReturnType)) {
        functionDescriptor.setReturnType(JetStandardClasses.getUnitType());
        return DataFlowUtils.checkType(
            JetStandardClasses.getFunctionType(
                Collections.<AnnotationDescriptor>emptyList(),
                receiver,
                parameterTypes,
                JetStandardClasses.getUnitType()),
            expression,
            context);
      }
    }
    return DataFlowUtils.checkType(
        JetStandardClasses.getFunctionType(
            Collections.<AnnotationDescriptor>emptyList(),
            receiver,
            parameterTypes,
            safeReturnType),
        expression,
        context);
  }