Beispiel #1
0
  private void makePrimitive(@NotNull PrimitiveType primitiveType) {
    KotlinType type = getBuiltInTypeByClassName(primitiveType.getTypeName().asString());
    KotlinType arrayType = getBuiltInTypeByClassName(primitiveType.getArrayTypeName().asString());

    primitiveTypeToArrayKotlinType.put(primitiveType, arrayType);
    primitiveKotlinTypeToKotlinArrayType.put(type, arrayType);
    kotlinArrayTypeToPrimitiveKotlinType.put(arrayType, type);
  }
Beispiel #2
0
  private void makePrimitive(@NotNull PrimitiveType primitiveType) {
    JetType type = getBuiltInTypeByClassName(primitiveType.getTypeName().asString());
    JetType arrayType = getBuiltInTypeByClassName(primitiveType.getArrayTypeName().asString());

    primitiveTypeToNullableJetType.put(primitiveType, TypeUtils.makeNullable(type));
    primitiveTypeToArrayJetType.put(primitiveType, arrayType);
    primitiveJetTypeToJetArrayType.put(type, arrayType);
    jetArrayTypeToPrimitiveJetType.put(arrayType, type);
  }
Beispiel #3
0
 {
   fqNameToPrimitiveType = new HashMap<FqNameUnsafe, PrimitiveType>(0);
   arrayClassFqNameToPrimitiveType = new HashMap<FqNameUnsafe, PrimitiveType>(0);
   for (PrimitiveType primitiveType : PrimitiveType.values()) {
     fqNameToPrimitiveType.put(
         fqNameUnsafe(primitiveType.getTypeName().asString()), primitiveType);
     arrayClassFqNameToPrimitiveType.put(
         fqNameUnsafe(primitiveType.getArrayTypeName().asString()), primitiveType);
   }
 }
Beispiel #4
0
  @NotNull
  private KotlinTypeChecker createTypeChecker(
      @NotNull List<TypeParameterDescriptor> firstParameters,
      @NotNull List<TypeParameterDescriptor> secondParameters) {
    assert firstParameters.size() == secondParameters.size()
        : "Should be the same number of type parameters: "
            + firstParameters
            + " vs "
            + secondParameters;
    if (firstParameters.isEmpty()) return KotlinTypeChecker.withAxioms(equalityAxioms);

    final Map<TypeConstructor, TypeConstructor> matchingTypeConstructors =
        new HashMap<TypeConstructor, TypeConstructor>();
    for (int i = 0; i < firstParameters.size(); i++) {
      matchingTypeConstructors.put(
          firstParameters.get(i).getTypeConstructor(),
          secondParameters.get(i).getTypeConstructor());
    }

    return KotlinTypeChecker.withAxioms(
        new KotlinTypeChecker.TypeConstructorEquality() {
          @Override
          public boolean equals(@NotNull TypeConstructor a, @NotNull TypeConstructor b) {
            if (equalityAxioms.equals(a, b)) return true;
            TypeConstructor img1 = matchingTypeConstructors.get(a);
            TypeConstructor img2 = matchingTypeConstructors.get(b);
            return (img1 != null && img1.equals(b)) || (img2 != null && img2.equals(a));
          }
        });
  }
Beispiel #5
0
  public void rememberClosure(JetExpression expression, Type type) {
    JetExpression lambda = JetPsiUtil.deparenthesize(expression);
    assert isInlinableParameterExpression(lambda)
        : "Couldn't find inline expression in " + expression.getText();

    LambdaInfo info = new LambdaInfo(lambda, typeMapper);

    ParameterInfo closureInfo = invocationParamBuilder.addNextParameter(type, true, null);
    closureInfo.setLambda(info);
    expressionMap.put(closureInfo.getIndex(), info);
  }
Beispiel #6
0
 @NotNull
 public Map<JetModifierKeywordToken, PsiElement> getTokensCorrespondingToModifiers(
     @NotNull JetModifierList modifierList,
     @NotNull Collection<JetModifierKeywordToken> possibleModifiers) {
   Map<JetModifierKeywordToken, PsiElement> tokens = Maps.newHashMap();
   for (JetModifierKeywordToken modifier : possibleModifiers) {
     if (modifierList.hasModifier(modifier)) {
       tokens.put(modifier, modifierList.getModifier(modifier));
     }
   }
   return tokens;
 }
Beispiel #7
0
  public void generateAndInsertFinallyBlocks(
      @NotNull MethodNode intoNode,
      @NotNull List<MethodInliner.PointForExternalFinallyBlocks> insertPoints,
      int offsetForFinallyLocalVar) {
    if (!codegen.hasFinallyBlocks()) return;

    Map<AbstractInsnNode, MethodInliner.PointForExternalFinallyBlocks> extensionPoints =
        new HashMap<AbstractInsnNode, MethodInliner.PointForExternalFinallyBlocks>();
    for (MethodInliner.PointForExternalFinallyBlocks insertPoint : insertPoints) {
      extensionPoints.put(insertPoint.beforeIns, insertPoint);
    }

    DefaultProcessor processor = new DefaultProcessor(intoNode, offsetForFinallyLocalVar);

    int curFinallyDepth = 0;
    AbstractInsnNode curInstr = intoNode.instructions.getFirst();
    while (curInstr != null) {
      processor.processInstruction(curInstr, true);
      if (InlineCodegenUtil.isFinallyStart(curInstr)) {
        // TODO depth index calc could be more precise
        curFinallyDepth = getConstant(curInstr.getPrevious());
      }

      MethodInliner.PointForExternalFinallyBlocks extension = extensionPoints.get(curInstr);
      if (extension != null) {
        Label start = new Label();

        MethodNode finallyNode = InlineCodegenUtil.createEmptyMethodNode();
        finallyNode.visitLabel(start);

        ExpressionCodegen finallyCodegen =
            new ExpressionCodegen(
                finallyNode,
                codegen.getFrameMap(),
                codegen.getReturnType(),
                codegen.getContext(),
                codegen.getState(),
                codegen.getParentCodegen());
        finallyCodegen.addBlockStackElementsForNonLocalReturns(
            codegen.getBlockStackElements(), curFinallyDepth);

        FrameMap frameMap = finallyCodegen.getFrameMap();
        FrameMap.Mark mark = frameMap.mark();
        while (frameMap.getCurrentSize() < processor.getNextFreeLocalIndex()) {
          frameMap.enterTemp(Type.INT_TYPE);
        }

        finallyCodegen.generateFinallyBlocksIfNeeded(
            extension.returnType, extension.finallyIntervalEnd.getLabel());

        // Exception table for external try/catch/finally blocks will be generated in original
        // codegen after exiting this method
        InlineCodegenUtil.insertNodeBefore(finallyNode, intoNode, curInstr);

        SimpleInterval splitBy =
            new SimpleInterval((LabelNode) start.info, extension.finallyIntervalEnd);
        processor.getTryBlocksMetaInfo().splitCurrentIntervals(splitBy, true);

        // processor.getLocalVarsMetaInfo().splitAndRemoveIntervalsFromCurrents(splitBy);

        mark.dropTo();
      }

      curInstr = curInstr.getNext();
    }

    processor.substituteTryBlockNodes(intoNode);

    // processor.substituteLocalVarTable(intoNode);
  }
Beispiel #8
0
  @NotNull
  private OverrideCompatibilityInfo isOverridableBy(
      @NotNull CallableDescriptor superDescriptor,
      @NotNull CallableDescriptor subDescriptor,
      boolean checkReturnType) {
    if (superDescriptor instanceof FunctionDescriptor) {
      if (!(subDescriptor instanceof FunctionDescriptor))
        return OverrideCompatibilityInfo.memberKindMismatch();
    } else if (superDescriptor instanceof PropertyDescriptor) {
      if (!(subDescriptor instanceof PropertyDescriptor))
        return OverrideCompatibilityInfo.memberKindMismatch();
    } else {
      throw new IllegalArgumentException(
          "This type of CallableDescriptor cannot be checked for overridability: "
              + superDescriptor);
    }

    // TODO: check outside of this method
    if (!superDescriptor.getName().equals(subDescriptor.getName())) {
      return OverrideCompatibilityInfo.nameMismatch();
    }

    OverrideCompatibilityInfo receiverAndParameterResult =
        checkReceiverAndParameterCount(superDescriptor, subDescriptor);
    if (receiverAndParameterResult != null) {
      return receiverAndParameterResult;
    }

    List<JetType> superValueParameters = compiledValueParameters(superDescriptor);
    List<JetType> subValueParameters = compiledValueParameters(subDescriptor);

    List<TypeParameterDescriptor> superTypeParameters = superDescriptor.getTypeParameters();
    List<TypeParameterDescriptor> subTypeParameters = subDescriptor.getTypeParameters();

    if (superTypeParameters.size() != subTypeParameters.size()) {
      for (int i = 0; i < superValueParameters.size(); ++i) {
        JetType superValueParameterType = getUpperBound(superValueParameters.get(i));
        JetType subValueParameterType = getUpperBound(subValueParameters.get(i));
        // TODO: compare erasure
        if (!JetTypeChecker.DEFAULT.equalTypes(superValueParameterType, subValueParameterType)) {
          return OverrideCompatibilityInfo.typeParameterNumberMismatch();
        }
      }
      return OverrideCompatibilityInfo.valueParameterTypeMismatch(
          null, null, OverrideCompatibilityInfo.Result.CONFLICT);
    }

    final Map<TypeConstructor, TypeConstructor> matchingTypeConstructors =
        new HashMap<TypeConstructor, TypeConstructor>();
    for (int i = 0, typeParametersSize = superTypeParameters.size(); i < typeParametersSize; i++) {
      TypeParameterDescriptor superTypeParameter = superTypeParameters.get(i);
      TypeParameterDescriptor subTypeParameter = subTypeParameters.get(i);
      matchingTypeConstructors.put(
          superTypeParameter.getTypeConstructor(), subTypeParameter.getTypeConstructor());
    }

    JetTypeChecker.TypeConstructorEquality localEqualityAxioms =
        new JetTypeChecker.TypeConstructorEquality() {
          @Override
          public boolean equals(@NotNull TypeConstructor a, @NotNull TypeConstructor b) {
            if (equalityAxioms.equals(a, b)) return true;
            TypeConstructor img1 = matchingTypeConstructors.get(a);
            TypeConstructor img2 = matchingTypeConstructors.get(b);
            if (!(img1 != null && img1.equals(b)) && !(img2 != null && img2.equals(a))) {
              return false;
            }
            return true;
          }
        };

    for (int i = 0, typeParametersSize = superTypeParameters.size(); i < typeParametersSize; i++) {
      TypeParameterDescriptor superTypeParameter = superTypeParameters.get(i);
      TypeParameterDescriptor subTypeParameter = subTypeParameters.get(i);

      if (!areTypesEquivalent(
          superTypeParameter.getUpperBoundsAsType(),
          subTypeParameter.getUpperBoundsAsType(),
          localEqualityAxioms)) {
        return OverrideCompatibilityInfo.boundsMismatch(superTypeParameter, subTypeParameter);
      }
    }

    for (int i = 0, unsubstitutedValueParametersSize = superValueParameters.size();
        i < unsubstitutedValueParametersSize;
        i++) {
      JetType superValueParameter = superValueParameters.get(i);
      JetType subValueParameter = subValueParameters.get(i);

      if (!areTypesEquivalent(superValueParameter, subValueParameter, localEqualityAxioms)) {
        return OverrideCompatibilityInfo.valueParameterTypeMismatch(
            superValueParameter, subValueParameter, INCOMPATIBLE);
      }
    }

    if (checkReturnType) {
      JetType superReturnType = superDescriptor.getReturnType();
      JetType subReturnType = subDescriptor.getReturnType();

      if (superReturnType != null && subReturnType != null) {
        boolean bothErrors = subReturnType.isError() && superReturnType.isError();
        if (!bothErrors
            && !JetTypeChecker.withAxioms(localEqualityAxioms)
                .isSubtypeOf(subReturnType, superReturnType)) {
          return OverrideCompatibilityInfo.returnTypeMismatch(superReturnType, subReturnType);
        }
      }
    }

    for (ExternalOverridabilityCondition externalCondition : EXTERNAL_CONDITIONS) {
      if (!externalCondition.isOverridable(superDescriptor, subDescriptor)) {
        return OverrideCompatibilityInfo.externalConditionFailed(externalCondition.getClass());
      }
    }

    return OverrideCompatibilityInfo.success();
  }