@Override
  public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
    if (!super.isAvailable(project, editor, file)) {
      return false;
    }

    BindingContext context =
        KotlinCacheManager.getInstance(project).getDeclarationsFromProject().getBindingContext();
    AnnotationDescriptor annotationDescriptor =
        context.get(BindingContext.ANNOTATION, annotationEntry);
    if (annotationDescriptor == null) {
      return false;
    }
    annotationType = annotationDescriptor.getType();
    DeclarationDescriptor declarationDescriptor =
        annotationType.getConstructor().getDeclarationDescriptor();
    if (declarationDescriptor == null) {
      return false;
    }
    PsiElement declaration =
        BindingContextUtils.descriptorToDeclaration(context, declarationDescriptor);
    if (declaration instanceof JetClass) {
      annotationClass = (JetClass) declaration;
      return annotationClass.isWritable();
    }
    return false;
  }
Пример #2
0
  @NotNull
  private static Multimap<FqName, Pair<FunctionDescriptor, PsiMethod>>
      getSuperclassToFunctionsMultimap(
          @NotNull PsiMethodWrapper method,
          @NotNull BindingContext bindingContext,
          @NotNull ClassDescriptor containingClass) {
    Multimap<FqName, Pair<FunctionDescriptor, PsiMethod>> result = HashMultimap.create();

    Name functionName = Name.identifier(method.getName());
    int parameterCount = method.getParameters().size();

    for (JetType supertype : TypeUtils.getAllSupertypes(containingClass.getDefaultType())) {
      ClassifierDescriptor klass = supertype.getConstructor().getDeclarationDescriptor();
      assert klass != null;
      FqName fqName = DescriptorUtils.getFQName(klass).toSafe();

      for (FunctionDescriptor fun :
          klass.getDefaultType().getMemberScope().getFunctions(functionName)) {
        if (fun.getKind().isReal() && fun.getValueParameters().size() == parameterCount) {
          PsiElement declaration = BindingContextUtils.descriptorToDeclaration(bindingContext, fun);
          if (declaration instanceof PsiMethod) {
            result.put(fqName, Pair.create(fun, (PsiMethod) declaration));
          } // else declaration is null or JetNamedFunction: both cases are processed later
        }
      }
    }
    return result;
  }
 private static String renderParameter(
     ValueParameterDescriptor descriptor, boolean named, BindingContext bindingContext) {
   StringBuilder builder = new StringBuilder();
   if (named) builder.append("[");
   if (descriptor.getVarargElementType() != null) {
     builder.append("vararg ");
   }
   builder
       .append(descriptor.getName())
       .append(": ")
       .append(DescriptorRenderer.TEXT.renderType(getActualParameterType(descriptor)));
   if (descriptor.hasDefaultValue()) {
     PsiElement element = BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor);
     String defaultExpression = "?";
     if (element instanceof JetParameter) {
       JetParameter parameter = (JetParameter) element;
       JetExpression defaultValue = parameter.getDefaultValue();
       if (defaultValue != null) {
         if (defaultValue instanceof JetConstantExpression) {
           JetConstantExpression constantExpression = (JetConstantExpression) defaultValue;
           defaultExpression = constantExpression.getText();
           if (defaultExpression.length() > 10) {
             if (defaultExpression.startsWith("\"")) defaultExpression = "\"...\"";
             else if (defaultExpression.startsWith("\'")) defaultExpression = "\'...\'";
             else defaultExpression = defaultExpression.substring(0, 7) + "...";
           }
         }
       }
     }
     builder.append(" = ").append(defaultExpression);
   }
   if (named) builder.append("]");
   return builder.toString();
 }
Пример #4
0
 public static boolean isNamedFun(DeclarationDescriptor fd, BindingContext bindingContext) {
   PsiElement psiElement = BindingContextUtils.descriptorToDeclaration(bindingContext, fd);
   if (psiElement instanceof JetNamedFunction) {
     return true;
   }
   return false;
 }
Пример #5
0
 public static boolean isLocalFun(DeclarationDescriptor fd, BindingContext bindingContext) {
   PsiElement psiElement = BindingContextUtils.descriptorToDeclaration(bindingContext, fd);
   if (psiElement instanceof JetNamedFunction
       && psiElement.getParent() instanceof JetBlockExpression) {
     return true;
   }
   return false;
 }
  @Nullable
  @Override
  public PsiElement findTargetMember(PsiElement element) {
    if (PsiTreeUtil.getParentOfType(element, JetParameterList.class) != null) {
      return PsiTreeUtil.getParentOfType(element, JetFunction.class, JetClass.class);
    }

    JetTypeParameterList typeParameterList =
        PsiTreeUtil.getParentOfType(element, JetTypeParameterList.class);
    if (typeParameterList != null) {
      return PsiTreeUtil.getParentOfType(typeParameterList, JetFunction.class, JetClass.class);
    }

    PsiElement elementParent = element.getParent();
    if (elementParent instanceof JetNamedFunction
        && ((JetNamedFunction) elementParent).getNameIdentifier() == element) {
      return elementParent;
    }
    if (elementParent instanceof JetClass
        && ((JetClass) elementParent).getNameIdentifier() == element) {
      return elementParent;
    }

    JetCallElement call =
        PsiTreeUtil.getParentOfType(
            element, JetCallExpression.class, JetDelegatorToSuperCall.class);
    if (call != null) {
      JetExpression receiverExpr =
          call instanceof JetCallExpression
              ? call.getCalleeExpression()
              : ((JetDelegatorToSuperCall) call)
                  .getCalleeExpression()
                  .getConstructorReferenceExpression();

      if (receiverExpr instanceof JetSimpleNameExpression) {
        BindingContext bindingContext =
            AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) element.getContainingFile())
                .getBindingContext();
        DeclarationDescriptor descriptor =
            bindingContext.get(
                BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) receiverExpr);

        if (descriptor != null) {
          PsiElement declaration =
              BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor);

          if (declaration instanceof JetNamedFunction || declaration instanceof JetClass) {
            return declaration;
          }
        }
      }
    }

    return null;
  }
Пример #7
0
 public static void checkWrappingInRef(
     JetSimpleNameExpression expression, ExpressionTypingContext context) {
   VariableDescriptor variable =
       BindingContextUtils.extractVariableDescriptorIfAny(
           context.trace.getBindingContext(), expression, true);
   if (variable != null && variable.isVar()) {
     DeclarationDescriptor containingDeclaration = variable.getContainingDeclaration();
     if (context.scope.getContainingDeclaration() != containingDeclaration
         && containingDeclaration instanceof CallableDescriptor) {
       context.trace.record(MUST_BE_WRAPPED_IN_A_REF, variable);
     }
   }
 }
Пример #8
0
 /**
  * Add import directive corresponding to a type to file when it is needed.
  *
  * @param type type to import
  * @param file file where import directive should be added
  */
 public static void addImportDirectivesIfNeeded(@NotNull JetType type, @NotNull JetFile file) {
   if (JetPluginUtil.checkTypeIsStandard(type, file.getProject())
       || ErrorUtils.isErrorType(type)) {
     return;
   }
   BindingContext bindingContext = getContextForSingleFile(file);
   PsiElement element =
       BindingContextUtils.descriptorToDeclaration(
           bindingContext, type.getMemberScope().getContainingDeclaration());
   if (element != null
       && element.getContainingFile()
           == file) { // declaration is in the same file, so no import is needed
     return;
   }
   for (ClassDescriptor clazz : TypeUtils.getAllClassDescriptors(type)) {
     addImportDirective(DescriptorUtils.getFQName(getTopLevelClass(clazz)).toSafe(), file);
   }
 }
  @NotNull
  private static AnonymousFunctionDescriptor createFunctionDescriptor(
      @NotNull JetFunctionLiteralExpression expression,
      @NotNull ExpressionTypingContext context,
      boolean functionTypeExpected) {
    JetFunctionLiteral functionLiteral = expression.getFunctionLiteral();
    JetTypeReference receiverTypeRef = functionLiteral.getReceiverTypeRef();
    AnonymousFunctionDescriptor functionDescriptor =
        new AnonymousFunctionDescriptor(
            context.scope.getContainingDeclaration(),
            Collections.<AnnotationDescriptor>emptyList(),
            CallableMemberDescriptor.Kind.DECLARATION);

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

    JetType effectiveReceiverType;
    if (receiverTypeRef == null) {
      if (functionTypeExpected) {
        effectiveReceiverType = KotlinBuiltIns.getInstance().getReceiverType(context.expectedType);
      } else {
        effectiveReceiverType = null;
      }
    } else {
      effectiveReceiverType =
          context
              .expressionTypingServices
              .getTypeResolver()
              .resolveType(context.scope, receiverTypeRef, context.trace, true);
    }
    functionDescriptor.initialize(
        effectiveReceiverType,
        ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER,
        Collections.<TypeParameterDescriptorImpl>emptyList(),
        valueParameterDescriptors,
        /*unsubstitutedReturnType = */ null,
        Modality.FINAL,
        Visibilities.LOCAL);
    BindingContextUtils.recordFunctionDeclarationToDescriptor(
        context.trace, functionLiteral, functionDescriptor);
    return functionDescriptor;
  }
Пример #10
0
 @NotNull
 public static LookupElement createLookupElement(
     @NotNull KotlinCodeAnalyzer analyzer,
     @NotNull BindingContext bindingContext,
     @NotNull DeclarationDescriptor descriptor) {
   if (descriptor instanceof CallableMemberDescriptor) {
     CallableMemberDescriptor callableMemberDescriptor = (CallableMemberDescriptor) descriptor;
     while (callableMemberDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
       // TODO: need to know all of them
       callableMemberDescriptor =
           callableMemberDescriptor.getOverriddenDescriptors().iterator().next();
     }
     descriptor = callableMemberDescriptor;
   }
   return createLookupElement(
       analyzer,
       descriptor,
       BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor));
 }
Пример #11
0
  protected void generatePropertyMetadataArrayFieldIfNeeded(@NotNull Type thisAsmType) {
    List<JetProperty> delegatedProperties = new ArrayList<JetProperty>();
    for (JetDeclaration declaration : ((JetDeclarationContainer) element).getDeclarations()) {
      if (declaration instanceof JetProperty) {
        JetProperty property = (JetProperty) declaration;
        if (property.getDelegate() != null) {
          delegatedProperties.add(property);
        }
      }
    }
    if (delegatedProperties.isEmpty()) return;

    v.newField(
        null,
        ACC_PRIVATE | ACC_STATIC | ACC_FINAL | ACC_SYNTHETIC,
        JvmAbi.PROPERTY_METADATA_ARRAY_NAME,
        "[" + PROPERTY_METADATA_TYPE,
        null,
        null);

    InstructionAdapter iv = createOrGetClInitCodegen().v;
    iv.iconst(delegatedProperties.size());
    iv.newarray(PROPERTY_METADATA_TYPE);

    for (int i = 0, size = delegatedProperties.size(); i < size; i++) {
      VariableDescriptor property =
          BindingContextUtils.getNotNull(bindingContext, VARIABLE, delegatedProperties.get(i));

      iv.dup();
      iv.iconst(i);
      iv.anew(PROPERTY_METADATA_IMPL_TYPE);
      iv.dup();
      iv.visitLdcInsn(property.getName().asString());
      iv.invokespecial(
          PROPERTY_METADATA_IMPL_TYPE.getInternalName(), "<init>", "(Ljava/lang/String;)V");
      iv.astore(PROPERTY_METADATA_IMPL_TYPE);
    }

    iv.putstatic(
        thisAsmType.getInternalName(),
        JvmAbi.PROPERTY_METADATA_ARRAY_NAME,
        "[" + PROPERTY_METADATA_TYPE);
  }
 private static String renderParameter(
     ValueParameterDescriptor parameter, boolean named, BindingContext bindingContext) {
   StringBuilder builder = new StringBuilder();
   if (named) builder.append("[");
   if (parameter.getVarargElementType() != null) {
     builder.append("vararg ");
   }
   builder
       .append(parameter.getName())
       .append(": ")
       .append(
           DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(getActualParameterType(parameter)));
   if (parameter.hasDefaultValue()) {
     PsiElement parameterDeclaration =
         BindingContextUtils.descriptorToDeclaration(bindingContext, parameter);
     builder.append(" = ").append(getDefaultExpressionString(parameterDeclaration));
   }
   if (named) builder.append("]");
   return builder.toString();
 }
 @Override
 public void recordMethod(
     @NotNull JavaMethod method, @NotNull SimpleFunctionDescriptor descriptor) {
   BindingContextUtils.recordFunctionDeclarationToDescriptor(
       trace, ((JavaMethodImpl) method).getPsi(), descriptor);
 }