Пример #1
0
  @NotNull
  public static String getElementTextWithContext(@NotNull JetElement element) {
    if (element instanceof JetFile) {
      return element.getContainingFile().getText();
    }

    // Find parent for element among file children
    PsiElement inFileParent =
        PsiTreeUtil.findFirstParent(
            element,
            new Condition<PsiElement>() {
              @Override
              public boolean value(PsiElement parentCandidate) {
                return parentCandidate != null && parentCandidate.getParent() instanceof JetFile;
              }
            });

    assert inFileParent != null
        : "For non-file element we should always be able to find parent in file children";

    int startContextOffset = inFileParent.getTextRange().getStartOffset();
    int elementContextOffset = element.getTextRange().getStartOffset();

    int inFileParentOffset = elementContextOffset - startContextOffset;

    return new StringBuilder(inFileParent.getText())
        .insert(inFileParentOffset, "<caret>")
        .toString();
  }
Пример #2
0
 public static <D> void visitChildren(
     @NotNull JetElement element, @NotNull JetTreeVisitor<D> visitor, D data) {
   PsiElement child = element.getFirstChild();
   while (child != null) {
     if (child instanceof JetElement) {
       ((JetElement) child).accept(visitor, data);
     }
     child = child.getNextSibling();
   }
 }
Пример #3
0
  @Nullable
  public static JetElement getOutermostDescendantElement(
      @Nullable PsiElement root, boolean first, final @NotNull Predicate<JetElement> predicate) {
    if (!(root instanceof JetElement)) return null;

    final List<JetElement> results = Lists.newArrayList();

    ((JetElement) root)
        .accept(
            new JetVisitorVoid() {
              @Override
              public void visitJetElement(@NotNull JetElement element) {
                if (predicate.apply(element)) {
                  //noinspection unchecked
                  results.add(element);
                } else {
                  element.acceptChildren(this);
                }
              }
            });

    if (results.isEmpty()) return null;

    return first ? results.get(0) : results.get(results.size() - 1);
  }
Пример #4
0
  @Nullable
  public static String getPackageName(@NotNull JetElement element) {
    JetFile file = (JetFile) element.getContainingFile();
    JetNamespaceHeader header = PsiTreeUtil.findChildOfType(file, JetNamespaceHeader.class);

    return header != null ? header.getQualifiedName() : null;
  }
Пример #5
0
  @NotNull
  public static Set<JetElement> findRootExpressions(
      @NotNull Collection<JetElement> unreachableElements) {
    Set<JetElement> rootElements = new HashSet<JetElement>();
    final Set<JetElement> shadowedElements = new HashSet<JetElement>();
    JetVisitorVoid shadowAllChildren =
        new JetVisitorVoid() {
          @Override
          public void visitJetElement(@NotNull JetElement element) {
            if (shadowedElements.add(element)) {
              element.acceptChildren(this);
            }
          }
        };

    for (JetElement element : unreachableElements) {
      if (shadowedElements.contains(element)) continue;
      element.acceptChildren(shadowAllChildren);

      rootElements.removeAll(shadowedElements);
      rootElements.add(element);
    }
    return rootElements;
  }
Пример #6
0
 public static boolean isImplicitlyUsed(@NotNull JetElement element) {
   PsiElement parent = element.getParent();
   if (!(parent instanceof JetBlockExpression)) return true;
   JetBlockExpression block = (JetBlockExpression) parent;
   List<JetElement> statements = block.getStatements();
   if (statements.get(statements.size() - 1) == element) {
     JetExpression expression = getDirectParentOfTypeForBlock(block, JetIfExpression.class);
     if (expression == null) {
       expression = getDirectParentOfTypeForBlock(block, JetWhenExpression.class);
     }
     if (expression == null) {
       expression = getDirectParentOfTypeForBlock(block, JetFunctionLiteral.class);
     }
     if (expression == null) {
       expression = getDirectParentOfTypeForBlock(block, JetTryExpression.class);
     }
     if (expression != null) {
       return isImplicitlyUsed(expression);
     }
   }
   return false;
 }
Пример #7
0
  private InlineResult inlineCall(SMAPAndMethodNode nodeAndSmap) {
    MethodNode node = nodeAndSmap.getNode();
    ReifiedTypeParametersUsages reificationResult =
        reifiedTypeInliner.reifyInstructions(node.instructions);
    generateClosuresBodies();

    // through generation captured parameters will be added to invocationParamBuilder
    putClosureParametersOnStack();

    addInlineMarker(codegen.v, true);

    Parameters parameters = invocationParamBuilder.buildParameters();

    InliningContext info =
        new RootInliningContext(
            expressionMap,
            state,
            codegen.getInlineNameGenerator().subGenerator(functionDescriptor.getName().asString()),
            codegen.getContext(),
            callElement,
            codegen.getParentCodegen().getClassName(),
            reifiedTypeInliner);

    MethodInliner inliner =
        new MethodInliner(
            node,
            parameters,
            info,
            new FieldRemapper(null, null, parameters),
            isSameModule,
            "Method inlining " + callElement.getText(),
            createNestedSourceMapper(nodeAndSmap)); // with captured

    LocalVarRemapper remapper = new LocalVarRemapper(parameters, initialFrameSize);

    MethodNode adapter = InlineCodegenUtil.createEmptyMethodNode();
    // hack to keep linenumber info, otherwise jdi will skip begin of linenumber chain
    adapter.visitInsn(Opcodes.NOP);

    InlineResult result = inliner.doInline(adapter, remapper, true, LabelOwner.SKIP_ALL);
    result.getReifiedTypeParametersUsages().mergeAll(reificationResult);

    CallableMemberDescriptor descriptor = codegen.getContext().getContextDescriptor();
    final Set<String> labels =
        getDeclarationLabels(
            DescriptorToSourceUtils.descriptorToDeclaration(descriptor), descriptor);
    LabelOwner labelOwner =
        new LabelOwner() {
          @Override
          public boolean isMyLabel(@NotNull String name) {
            return labels.contains(name);
          }
        };

    List<MethodInliner.PointForExternalFinallyBlocks> infos =
        MethodInliner.processReturns(adapter, labelOwner, true, null);
    generateAndInsertFinallyBlocks(
        adapter,
        infos,
        ((StackValue.Local) remapper.remap(parameters.totalSize() + 1).value).index);
    removeFinallyMarkers(adapter);

    adapter.accept(new InliningInstructionAdapter(codegen.v));

    addInlineMarker(codegen.v, false);

    return result;
  }