@Override
  public void visitObjectLiteralExpression(JetObjectLiteralExpression expression) {
    ClassDescriptor classDescriptor = bindingContext.get(CLASS, expression.getObjectDeclaration());
    if (classDescriptor == null) {
      // working around a problem with shallow analysis
      super.visitObjectLiteralExpression(expression);
      return;
    }

    final String name = inventAnonymousClassName(expression.getObjectDeclaration());
    recordClosure(
        bindingTrace,
        expression.getObjectDeclaration(),
        classDescriptor,
        peekFromStack(classStack),
        JvmClassName.byInternalName(name),
        false);

    classStack.push(classDescriptor);
    //noinspection ConstantConditions
    nameStack.push(bindingContext.get(FQN, classDescriptor).getInternalName());
    super.visitObjectLiteralExpression(expression);
    nameStack.pop();
    classStack.pop();
  }
Example #2
0
      @Override
      public StackValue innerValue(
          DeclarationDescriptor d,
          LocalLookup localLookup,
          GenerationState state,
          MutableClosure closure,
          Type classType) {
        FunctionDescriptor vd = (FunctionDescriptor) d;

        boolean idx = localLookup != null && localLookup.lookupLocal(vd);
        if (!idx) return null;

        BindingContext bindingContext = state.getBindingContext();
        Type localType = asmTypeForAnonymousClass(bindingContext, vd);

        MutableClosure localFunClosure =
            bindingContext.get(CLOSURE, bindingContext.get(CLASS_FOR_FUNCTION, vd));
        if (localFunClosure != null && JvmCodegenUtil.isConst(localFunClosure)) {
          // This is an optimization: we can obtain an instance of a const closure simply by
          // GETSTATIC ...$instance
          // (instead of passing this instance to the constructor and storing as a field)
          return StackValue.field(localType, localType, JvmAbi.INSTANCE_FIELD, true);
        }

        String fieldName = "$" + vd.getName();
        StackValue innerValue = StackValue.field(localType, classType, fieldName, false);

        closure.recordField(fieldName, localType);
        closure.captureVariable(new EnclosedValueDescriptor(fieldName, d, innerValue, localType));

        return innerValue;
      }
  @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;
  }
Example #4
0
  // TODO: Make it work for properties
  public Collection<DeclarationDescriptor> getJetCallableExtensions(
      @NotNull Condition<String> acceptedNameCondition,
      @NotNull JetSimpleNameExpression expression,
      @NotNull ResolveSession resolveSession,
      @NotNull GlobalSearchScope searchScope) {
    Collection<DeclarationDescriptor> resultDescriptors = new ArrayList<DeclarationDescriptor>();

    BindingContext context = ResolveSessionUtils.resolveToExpression(resolveSession, expression);
    JetExpression receiverExpression = expression.getReceiverExpression();

    if (receiverExpression != null) {
      JetType expressionType = context.get(BindingContext.EXPRESSION_TYPE, receiverExpression);
      JetScope scope = context.get(BindingContext.RESOLUTION_SCOPE, receiverExpression);

      if (expressionType != null && scope != null) {
        Collection<String> extensionFunctionsNames = getAllJetExtensionFunctionsNames(searchScope);

        Set<FqName> functionFQNs = new java.util.HashSet<FqName>();

        // Collect all possible extension function qualified names
        for (String name : extensionFunctionsNames) {
          if (acceptedNameCondition.value(name)) {
            Collection<PsiElement> extensionFunctions =
                getJetExtensionFunctionsByName(name, searchScope);

            for (PsiElement extensionFunction : extensionFunctions) {
              if (extensionFunction instanceof JetNamedFunction) {
                functionFQNs.add(JetPsiUtil.getFQName((JetNamedFunction) extensionFunction));
              } else if (extensionFunction instanceof PsiMethod) {
                FqName functionFQN =
                    JetFromJavaDescriptorHelper.getJetTopLevelDeclarationFQN(
                        (PsiMethod) extensionFunction);
                if (functionFQN != null) {
                  functionFQNs.add(functionFQN);
                }
              }
            }
          }
        }

        // Iterate through the function with attempt to resolve found functions
        for (FqName functionFQN : functionFQNs) {
          for (CallableDescriptor functionDescriptor :
              ExpressionTypingUtils.canFindSuitableCall(
                  functionFQN,
                  project,
                  receiverExpression,
                  expressionType,
                  scope,
                  resolveSession.getModuleConfiguration())) {

            resultDescriptors.add(functionDescriptor);
          }
        }
      }
    }

    return resultDescriptors;
  }
  @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;
  }
  @Nullable
  private static String renderElement(@Nullable PsiElement element) {
    String elementText;
    String containerText = null;

    if (element instanceof JetFile) {
      elementText = ((JetFile) element).getName();
    } else if (element instanceof JetNamedDeclaration) {
      BindingContext bindingContext =
          AnalyzerFacadeWithCache.getContextForElement((JetElement) element);

      DeclarationDescriptor descriptor =
          bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element);
      if (descriptor == null) return null;

      if (element instanceof JetClassOrObject) {
        if (element instanceof JetObjectDeclaration
            && ((JetObjectDeclaration) element).isClassObject()) {
          descriptor = descriptor.getContainingDeclaration();
          if (!(descriptor instanceof ClassDescriptor)) return null;

          elementText = renderClassOrObject((ClassDescriptor) descriptor);
        } else if (element instanceof JetEnumEntry) {
          elementText = ((JetEnumEntry) element).getName();
        } else {
          if (((JetClassOrObject) element).getName() != null) {
            elementText = renderClassOrObject((ClassDescriptor) descriptor);
          } else {
            elementText = "[anonymous]";
          }
        }
      } else if (element instanceof JetNamedFunction) {
        elementText = renderNamedFunction((FunctionDescriptor) descriptor);
      } else if (element instanceof JetProperty) {
        elementText = ((JetProperty) element).getName();
      } else return null;

      DeclarationDescriptor containerDescriptor = descriptor.getContainingDeclaration();
      while (containerDescriptor != null) {
        String name = containerDescriptor.getName().asString();
        if (!name.startsWith("<")) {
          containerText = name;
          break;
        }
        containerDescriptor = containerDescriptor.getContainingDeclaration();
      }
    } else return null;

    if (elementText == null) return null;
    return containerText != null ? containerText + "." + elementText : elementText;
  }
Example #7
0
  /**
   * Name suggestion types: 1. According to type: 1a. Primitive types to some short name 1b. Class
   * types according to class name camel humps: (AbCd => {abCd, cd}) 1c. Arrays => arrayOfInnerType
   * 2. Reference expressions according to reference name camel humps 3. Method call expression
   * according to method callee expression
   *
   * @param expression to suggest name for variable
   * @param validator to check scope for such names
   * @return possible names
   */
  public static String[] suggestNames(JetExpression expression, JetNameValidator validator) {
    ArrayList<String> result = new ArrayList<String>();

    BindingContext bindingContext =
        AnalyzeSingleFileUtil.getContextForSingleFile((JetFile) expression.getContainingFile());
    JetType jetType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression);
    if (jetType != null) {
      addNamesForType(result, jetType, validator);
    }
    addNamesForExpression(result, expression, validator);

    if (result.isEmpty()) addName(result, "value", validator);
    return ArrayUtil.toStringArray(result);
  }
  private static JetDelegatorToSuperCall findSuperCall(
      BindingContext bindingContext, JetElement classOrObject) {
    if (!(classOrObject instanceof JetClassOrObject)) {
      return null;
    }

    if (classOrObject instanceof JetClass && ((JetClass) classOrObject).isTrait()) {
      return null;
    }
    for (JetDelegationSpecifier specifier :
        ((JetClassOrObject) classOrObject).getDelegationSpecifiers()) {
      if (specifier instanceof JetDelegatorToSuperCall) {
        JetType superType = bindingContext.get(TYPE, specifier.getTypeReference());
        assert superType != null;
        ClassDescriptor superClassDescriptor =
            (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
        assert superClassDescriptor != null;
        if (!isInterface(superClassDescriptor)) {
          return (JetDelegatorToSuperCall) specifier;
        }
      }
    }

    return null;
  }
 @NotNull
 public static JvmClassName classNameForScriptDescriptor(
     BindingContext bindingContext, @NotNull ScriptDescriptor scriptDescriptor) {
   ClassDescriptor classDescriptor = bindingContext.get(CLASS_FOR_SCRIPT, scriptDescriptor);
   //noinspection ConstantConditions
   return fqn(bindingContext, classDescriptor);
 }
  @Override
  public void visitObjectDeclaration(JetObjectDeclaration declaration) {
    if (declaration.getParent() instanceof JetObjectLiteralExpression
        || declaration.getParent() instanceof JetClassObject) {
      super.visitObjectDeclaration(declaration);
    } else {
      ClassDescriptor classDescriptor = bindingContext.get(CLASS, declaration);
      // working around a problem with shallow analysis
      if (classDescriptor == null) return;

      String name = getName(classDescriptor);
      recordClosure(
          bindingTrace,
          declaration,
          classDescriptor,
          peekFromStack(classStack),
          JvmClassName.byInternalName(name),
          false);

      classStack.push(classDescriptor);
      nameStack.push(name);
      super.visitObjectDeclaration(declaration);
      nameStack.pop();
      classStack.pop();
    }
  }
 @SuppressWarnings({"unchecked", "ConstantConditions"})
 private static void checkResolvedCallsInDiagnostics(BindingContext bindingContext) {
   Set<DiagnosticFactory> diagnosticsStoringResolvedCalls1 =
       Sets.<DiagnosticFactory>newHashSet(
           OVERLOAD_RESOLUTION_AMBIGUITY,
           NONE_APPLICABLE,
           CANNOT_COMPLETE_RESOLVE,
           UNRESOLVED_REFERENCE_WRONG_RECEIVER,
           ASSIGN_OPERATOR_AMBIGUITY,
           ITERATOR_AMBIGUITY);
   Set<DiagnosticFactory> diagnosticsStoringResolvedCalls2 =
       Sets.<DiagnosticFactory>newHashSet(
           COMPONENT_FUNCTION_AMBIGUITY,
           DELEGATE_SPECIAL_FUNCTION_AMBIGUITY,
           DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE);
   Diagnostics diagnostics = bindingContext.getDiagnostics();
   for (Diagnostic diagnostic : diagnostics) {
     DiagnosticFactory factory = diagnostic.getFactory();
     if (diagnosticsStoringResolvedCalls1.contains(factory)) {
       assertResolvedCallsAreCompleted(
           diagnostic,
           ((DiagnosticWithParameters1<PsiElement, Collection<? extends ResolvedCall<?>>>)
                   diagnostic)
               .getA());
     }
     if (diagnosticsStoringResolvedCalls2.contains(factory)) {
       assertResolvedCallsAreCompleted(
           diagnostic,
           ((DiagnosticWithParameters2<PsiElement, Object, Collection<? extends ResolvedCall<?>>>)
                   diagnostic)
               .getB());
     }
   }
 }
  private static void checkAllResolvedCallsAreCompleted(
      @NotNull List<JetFile> jetFiles, @NotNull BindingContext bindingContext) {
    for (JetFile file : jetFiles) {
      if (!AnalyzingUtils.getSyntaxErrorRanges(file).isEmpty()) {
        return;
      }
    }

    ImmutableMap<JetElement, ResolvedCall<?>> resolvedCallsEntries =
        bindingContext.getSliceContents(BindingContext.RESOLVED_CALL);
    for (Map.Entry<JetElement, ResolvedCall<?>> entry : resolvedCallsEntries.entrySet()) {
      JetElement element = entry.getKey();
      ResolvedCall<?> resolvedCall = entry.getValue();

      DiagnosticUtils.LineAndColumn lineAndColumn =
          DiagnosticUtils.getLineAndColumnInPsiFile(
              element.getContainingFile(), element.getTextRange());

      assertTrue(
          "Resolved call for '" + element.getText() + "'" + lineAndColumn + " is not completed",
          ((MutableResolvedCall<?>) resolvedCall).isCompleted());
    }

    checkResolvedCallsInDiagnostics(bindingContext);
  }
 public static boolean isVarCapturedInClosure(
     BindingContext bindingContext, DeclarationDescriptor descriptor) {
   if (!(descriptor instanceof VariableDescriptor) || descriptor instanceof PropertyDescriptor)
     return false;
   VariableDescriptor variableDescriptor = (VariableDescriptor) descriptor;
   return bindingContext.get(CAPTURED_IN_CLOSURE, variableDescriptor) != null
       && variableDescriptor.isVar();
 }
 @NotNull
 public static JvmClassName classNameForScriptPsi(
     BindingContext bindingContext, @NotNull JetScript script) {
   ScriptDescriptor scriptDescriptor = bindingContext.get(SCRIPT, script);
   if (scriptDescriptor == null) {
     throw new IllegalStateException("Script descriptor not found by PSI " + script);
   }
   return classNameForScriptDescriptor(bindingContext, scriptDescriptor);
 }
 @Override
 public void visitJetFile(JetFile file) {
   if (file.isScript()) {
     //noinspection ConstantConditions
     final ClassDescriptor classDescriptor =
         bindingContext.get(CLASS_FOR_FUNCTION, bindingContext.get(SCRIPT, file.getScript()));
     classStack.push(classDescriptor);
     //noinspection ConstantConditions
     nameStack.push(classNameForScriptPsi(bindingContext, file.getScript()).getInternalName());
   } else {
     nameStack.push(JetPsiUtil.getFQName(file).getFqName().replace('.', '/'));
   }
   file.acceptChildren(this);
   nameStack.pop();
   if (file.isScript()) {
     classStack.pop();
   }
 }
  @NotNull
  public static JvmClassName classNameForAnonymousClass(
      @NotNull BindingContext bindingContext, @NotNull JetElement expression) {
    if (expression instanceof JetObjectLiteralExpression) {
      JetObjectLiteralExpression jetObjectLiteralExpression =
          (JetObjectLiteralExpression) expression;
      expression = jetObjectLiteralExpression.getObjectDeclaration();
    }

    ClassDescriptor descriptor = bindingContext.get(CLASS, expression);
    if (descriptor == null) {
      SimpleFunctionDescriptor functionDescriptor = bindingContext.get(FUNCTION, expression);
      assert functionDescriptor != null;
      return classNameForAnonymousClass(bindingContext, functionDescriptor);
    }

    return fqn(bindingContext, descriptor);
  }
Example #17
0
  @Override
  public void annotate(@NotNull PsiElement element, @NotNull final AnnotationHolder holder) {
    for (HighlightingVisitor visitor : getBeforeAnalysisVisitors(holder)) {
      element.accept(visitor);
    }

    if (element instanceof JetFile) {
      JetFile file = (JetFile) element;

      try {
        BindingContext bindingContext =
            WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(file).getBindingContext();

        if (errorReportingEnabled) {
          Collection<Diagnostic> diagnostics =
              Sets.newLinkedHashSet(bindingContext.getDiagnostics());
          Set<PsiElement> redeclarations = Sets.newHashSet();
          for (Diagnostic diagnostic : diagnostics) {
            // This is needed because we have the same context for all files
            if (diagnostic.getPsiFile() != file) continue;

            registerDiagnosticAnnotations(diagnostic, redeclarations, holder);
          }
        }

        for (HighlightingVisitor visitor : getAfterAnalysisVisitor(holder, bindingContext)) {
          file.acceptChildren(visitor);
        }
      } catch (ProcessCanceledException e) {
        throw e;
      } catch (AssertionError e) {
        // For failing tests and to notify about idea internal error in -ea mode
        holder.createErrorAnnotation(
            element, e.getClass().getCanonicalName() + ": " + e.getMessage());
        throw e;
      } catch (Throwable e) {
        // TODO
        holder.createErrorAnnotation(
            element, e.getClass().getCanonicalName() + ": " + e.getMessage());
        e.printStackTrace();
      }
    }
  }
  @NotNull
  public static Collection<JetFile> allFilesInNamespaces(
      BindingContext bindingContext, Collection<JetFile> files) {
    // todo: we use Set and add given files but ignoring other scripts because something non-clear
    // kept in binding
    // for scripts especially in case of REPL

    HashSet<FqName> names = new HashSet<FqName>();
    for (JetFile file : files) {
      if (!file.isScript()) {
        names.add(JetPsiUtil.getFQName(file));
      }
    }

    HashSet<JetFile> answer = new HashSet<JetFile>();
    answer.addAll(files);

    for (FqName name : names) {
      NamespaceDescriptor namespaceDescriptor =
          bindingContext.get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, name);
      Collection<JetFile> jetFiles = bindingContext.get(NAMESPACE_TO_FILES, namespaceDescriptor);
      if (jetFiles != null) answer.addAll(jetFiles);
    }

    List<JetFile> sortedAnswer = new ArrayList<JetFile>(answer);
    Collections.sort(
        sortedAnswer,
        new Comparator<JetFile>() {
          @NotNull
          private String path(JetFile file) {
            VirtualFile virtualFile = file.getVirtualFile();
            assert virtualFile != null : "VirtualFile is null for JetFile: " + file.getName();
            return virtualFile.getPath();
          }

          @Override
          public int compare(JetFile first, JetFile second) {
            return path(first).compareTo(path(second));
          }
        });

    return sortedAnswer;
  }
  private static boolean isArgumentTypeValid(
      BindingContext bindingContext, JetValueArgument argument, ValueParameterDescriptor param) {
    if (argument.getArgumentExpression() != null) {
      JetType paramType = getActualParameterType(param);
      JetType exprType =
          bindingContext.get(BindingContext.EXPRESSION_TYPE, argument.getArgumentExpression());
      return exprType == null || JetTypeChecker.INSTANCE.isSubtypeOf(exprType, paramType);
    }

    return false;
  }
 @Override
 @NotNull
 protected Collection<DeclarationDescriptor> getTargetDescriptors(
     @NotNull BindingContext context) {
   ResolvedCall<?> resolvedCall =
       context.get(RESOLVED_CALL, getExpression().getCalleeExpression());
   if (resolvedCall instanceof VariableAsFunctionResolvedCall) {
     return Collections.<DeclarationDescriptor>singleton(
         ((VariableAsFunctionResolvedCall) resolvedCall).getCandidateDescriptor());
   }
   return Collections.emptyList();
 }
Example #21
0
  @NotNull
  public Collection<ClassDescriptor> getTopLevelObjectsByName(
      @NotNull String name,
      @NotNull JetSimpleNameExpression expression,
      @NotNull ResolveSession resolveSession,
      @NotNull GlobalSearchScope scope) {
    BindingContext context = ResolveSessionUtils.resolveToExpression(resolveSession, expression);
    JetScope jetScope = context.get(BindingContext.RESOLUTION_SCOPE, expression);

    if (jetScope == null) {
      return Collections.emptyList();
    }

    Set<ClassDescriptor> result = Sets.newHashSet();

    Collection<JetObjectDeclaration> topObjects =
        JetTopLevelShortObjectNameIndex.getInstance().get(name, project, scope);
    for (JetObjectDeclaration objectDeclaration : topObjects) {
      FqName fqName = JetPsiUtil.getFQName(objectDeclaration);
      assert fqName != null
          : "Local object declaration in JetTopLevelShortObjectNameIndex:"
              + objectDeclaration.getText();
      result.addAll(
          ResolveSessionUtils.getClassOrObjectDescriptorsByFqName(resolveSession, fqName, true));
    }

    for (PsiClass psiClass :
        JetFromJavaDescriptorHelper.getCompiledClassesForTopLevelObjects(
            project, GlobalSearchScope.allScope(project))) {
      String qualifiedName = psiClass.getQualifiedName();
      if (qualifiedName != null) {
        FqName fqName = new FqName(qualifiedName);
        result.addAll(
            ResolveSessionUtils.getClassOrObjectDescriptorsByFqName(resolveSession, fqName, true));
      }
    }

    return result;
  }
  private JetKeywordToken findVisibilityChangeTo(JetFile file) {
    BindingContext bindingContext = AnalyzeSingleFileUtil.getContextForSingleFile(file);
    DeclarationDescriptor descriptor;
    if (element instanceof JetParameter) {
      descriptor = bindingContext.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, element);
    } else {
      descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element);
    }
    if (!(descriptor instanceof CallableMemberDescriptor)) return null;

    CallableMemberDescriptor memberDescriptor = (CallableMemberDescriptor) descriptor;
    Visibility maxVisibility = null;
    for (CallableMemberDescriptor overriddenDescriptor :
        memberDescriptor.getOverriddenDescriptors()) {
      Visibility overriddenDescriptorVisibility = overriddenDescriptor.getVisibility();
      if (maxVisibility == null) {
        maxVisibility = overriddenDescriptorVisibility;
        continue;
      }
      Integer compare = Visibilities.compare(maxVisibility, overriddenDescriptorVisibility);
      if (compare == null) {
        maxVisibility = Visibilities.PUBLIC;
      } else if (compare < 0) {
        maxVisibility = overriddenDescriptorVisibility;
      }
    }
    if (maxVisibility == memberDescriptor.getVisibility()) {
      return null;
    }
    JetKeywordToken modifier = null;
    if (maxVisibility == Visibilities.PUBLIC) {
      modifier = JetTokens.PUBLIC_KEYWORD;
    } else if (maxVisibility == Visibilities.PROTECTED) {
      modifier = JetTokens.PROTECTED_KEYWORD;
    } else if (maxVisibility == Visibilities.INTERNAL) {
      modifier = JetTokens.INTERNAL_KEYWORD;
    }
    return modifier;
  }
Example #23
0
 private static boolean isDeclaredInJava(
     @NotNull CallableDescriptor callableDescriptor, @NotNull BindingContext context) {
   CallableDescriptor descriptor = callableDescriptor;
   while (true) {
     if (Boolean.TRUE.equals(context.get(BindingContext.IS_DECLARED_IN_JAVA, descriptor))) {
       return true;
     }
     CallableDescriptor original = descriptor.getOriginal();
     if (descriptor == original) break;
     descriptor = original;
   }
   return false;
 }
  @Nullable
  public static JetChangeSignatureDialog createDialog(
      @NotNull PsiElement element, PsiElement context, Project project, Editor editor) {
    if (!CommonRefactoringUtil.checkReadOnlyStatus(project, element)) return null;
    BindingContext bindingContext =
        AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) element.getContainingFile())
            .getBindingContext();
    DeclarationDescriptor descriptor =
        bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element);

    if (descriptor instanceof ClassDescriptor) {
      descriptor = ((ClassDescriptor) descriptor).getUnsubstitutedPrimaryConstructor();
    }
    if (descriptor instanceof FunctionDescriptorImpl) {
      for (ValueParameterDescriptor parameter :
          ((FunctionDescriptor) descriptor).getValueParameters()) {
        if (parameter.getVarargElementType() != null) {
          String message = JetRefactoringBundle.message("error.cant.refactor.vararg.functions");
          CommonRefactoringUtil.showErrorHint(
              project, editor, message, REFACTORING_NAME, HelpID.CHANGE_SIGNATURE);
          return null;
        }
      }

      return new JetChangeSignatureDialog(
          project,
          new JetFunctionPlatformDescriptorImpl((FunctionDescriptor) descriptor, element),
          context);
    } else {
      String message =
          RefactoringBundle.getCannotRefactorMessage(
              JetRefactoringBundle.message(
                  "error.wrong.caret.position.function.or.constructor.name"));
      CommonRefactoringUtil.showErrorHint(
          project, editor, message, REFACTORING_NAME, HelpID.CHANGE_SIGNATURE);
      return null;
    }
  }
  private void appendDescriptor(DeclarationDescriptor descriptor, String indent) {
    int startOffset = myBuilder.length();
    myBuilder.append(DescriptorRenderer.COMPACT.render(descriptor));
    int endOffset = myBuilder.length();

    if (descriptor instanceof FunctionDescriptor || descriptor instanceof PropertyDescriptor) {
      if (((CallableMemberDescriptor) descriptor).getModality() != Modality.ABSTRACT) {
        if (descriptor instanceof FunctionDescriptor) {
          myBuilder.append(" { ").append(DECOMPILED_COMMENT).append(" }");
          endOffset = myBuilder.length();
        } else { // descriptor instanceof PropertyDescriptor
          if (((PropertyDescriptor) descriptor).getModality() != Modality.ABSTRACT) {
            myBuilder.append(" ").append(DECOMPILED_COMMENT);
          }
        }
      }
    } else if (descriptor instanceof ClassDescriptor) {
      myBuilder.append(" {\n");
      ClassDescriptor classDescriptor = (ClassDescriptor) descriptor;
      boolean firstPassed = false;
      String subindent = indent + "    ";
      if (classDescriptor.getClassObjectDescriptor() != null) {
        firstPassed = true;
        myBuilder.append(subindent).append("class ");
        appendDescriptor(classDescriptor.getClassObjectDescriptor(), subindent);
      }
      for (DeclarationDescriptor member :
          sortDeclarations(classDescriptor.getDefaultType().getMemberScope().getAllDescriptors())) {
        if (member.getContainingDeclaration() == descriptor) {
          if (firstPassed) {
            myBuilder.append("\n");
          } else {
            firstPassed = true;
          }
          myBuilder.append(subindent);
          appendDescriptor(member, subindent);
        }
      }
      myBuilder.append(indent).append("}");
      endOffset = myBuilder.length();
    }

    myBuilder.append("\n");
    PsiElement clsMember =
        myBindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor);
    if (clsMember != null) {
      myClsMembersToRanges.put(clsMember, new TextRange(startOffset, endOffset));
    }
  }
  @Override
  public void visitEnumEntry(JetEnumEntry enumEntry) {
    ClassDescriptor descriptor = bindingContext.get(CLASS, enumEntry);
    assert descriptor != null;

    final boolean trivial = enumEntry.getDeclarations().isEmpty();
    if (!trivial) {
      bindingTrace.record(ENUM_ENTRY_CLASS_NEED_SUBCLASS, descriptor);
      super.visitEnumEntry(enumEntry);
    } else {
      JvmClassName jvmClassName = bindingTrace.get(FQN, peekFromStack(classStack));
      assert PsiCodegenPredictor.checkPredictedNameFromPsi(bindingTrace, descriptor, jvmClassName);
      bindingTrace.record(FQN, descriptor, jvmClassName);
    }
  }
  @Override
  public void visitClassObject(JetClassObject classObject) {
    ClassDescriptor classDescriptor = bindingContext.get(CLASS, classObject.getObjectDeclaration());
    assert classDescriptor != null;

    JvmClassName name =
        JvmClassName.byInternalName(peekFromStack(nameStack) + JvmAbi.CLASS_OBJECT_SUFFIX);
    recordClosure(
        bindingTrace, classObject, classDescriptor, peekFromStack(classStack), name, false);

    classStack.push(classDescriptor);
    nameStack.push(name.getInternalName());
    super.visitClassObject(classObject);
    nameStack.pop();
    classStack.pop();
  }
  private static Boolean isResolvedToDescriptor(
      JetValueArgumentList argumentList,
      FunctionDescriptor functionDescriptor,
      BindingContext bindingContext) {
    JetSimpleNameExpression callNameExpression = getCallSimpleNameExpression(argumentList);
    if (callNameExpression != null) {
      DeclarationDescriptor declarationDescriptor =
          bindingContext.get(BindingContext.REFERENCE_TARGET, callNameExpression);
      if (declarationDescriptor != null) {
        if (declarationDescriptor == functionDescriptor) {
          return true;
        }
      }
    }

    return false;
  }
  @Override
  public void visitClass(JetClass klass) {
    ClassDescriptor classDescriptor = bindingContext.get(CLASS, klass);
    // working around a problem with shallow analysis
    if (classDescriptor == null) return;

    String name = getName(classDescriptor);
    recordClosure(
        bindingTrace,
        klass,
        classDescriptor,
        peekFromStack(classStack),
        JvmClassName.byInternalName(name),
        false);

    classStack.push(classDescriptor);
    nameStack.push(name);
    super.visitClass(klass);
    nameStack.pop();
    classStack.pop();
  }
  private String inventAnonymousClassName(JetElement declaration) {
    String top = peekFromStack(nameStack);
    Integer cnt = anonymousSubclassesCount.get(top);
    if (cnt == null) {
      cnt = 0;
    }
    String name = top + "$" + (cnt + 1);
    ClassDescriptor descriptor = bindingContext.get(CLASS, declaration);
    if (descriptor == null) {
      if (declaration instanceof JetFunctionLiteralExpression
          || declaration instanceof JetNamedFunction
          || declaration instanceof JetObjectLiteralExpression) {
      } else {
        throw new IllegalStateException(
            "Class-less declaration which is not JetFunctionLiteralExpression|JetNamedFunction|JetObjectLiteralExpression : "
                + declaration.getClass().getName());
      }
    }
    anonymousSubclassesCount.put(top, cnt + 1);

    return name;
  }