public PsiElement createDslElement()

in gradle-dsl-groovy/src/com/android/tools/idea/gradle/dsl/parser/groovy/GroovyDslWriter.java [130:280]


  public PsiElement createDslElement(@NotNull GradleDslElement element) {
    if (element instanceof GradleDslInfixExpression) return createDslInfixExpression((GradleDslInfixExpression) element);
    GroovyPsiElement psiElement = ensureGroovyPsi(element.getPsiElement());
    if (psiElement != null) {
      return psiElement;
    }

    GradleDslAnchor anchorAfter = element.getAnchor();
    if (anchorAfter == null) {
      return null;
    }
    boolean addBefore = false;
    if (element.isNewEmptyBlockElement()) {
      return null; // Avoid creation of an empty block statement.
    }

    // If the parent doesn't have a psi element, the anchor will be used to create the parent in getParentPsi.
    // In this case we want to be placed in the newly made parent so we ignore our anchor.
    GradleDslElement dslParent = anchorAfter.getParentDslElement();
    if (dslParent == null) return null;
    if (needToCreateParent(dslParent)) {
      addBefore = true;
      anchorAfter = new GradleDslAnchor.Start(dslParent);
    }
    PsiElement parentPsiElement = getParentPsi(dslParent);
    if (parentPsiElement == null) return null;

    Project project = parentPsiElement.getProject();
    GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(project);

    ExternalNameInfo externalNameInfo = maybeTrimForParent(element, this);
    String statementText = quotePartsIfNecessary(externalNameInfo);
    assert !statementText.isEmpty() : "Element name can't be empty! This will cause statement creation to error.";

    ExternalNameSyntax syntax = externalNameInfo.syntax;
    switch (syntax) {
      case UNKNOWN: syntax = element.getExternalSyntax(); break;
      default: element.setExternalSyntax(syntax);
    }
    if (element.isBlockElement()) {
      if (element instanceof MavenRepositoryDslElement && element.getContainedElements(true).isEmpty()) {
        statementText += "()";
      }
      else {
        statementText += " {\n}\n";
      }
    }
    else if (syntax == ASSIGNMENT || syntax == AUGMENTED_ASSIGNMENT || syntax == SET_METHOD) {
      if (element.getElementType() == PropertyType.REGULAR) {
        switch (syntax) {
          case ASSIGNMENT: statementText += " = 'abc'"; break;
          case AUGMENTED_ASSIGNMENT: statementText += " += 'abc'"; break;
          case SET_METHOD: statementText += ".set('abc')"; break;
        }
      }
      else if (element.getElementType() == PropertyType.VARIABLE) {
        statementText = "def " + statementText + " = 'abc'";
      }
    }
    else {
      statementText += " \"abc\", \"xyz\"";
    }
    GrStatement statement = factory.createStatementFromText(statementText);
    // TODO: Move these workarounds to a more sensible way of doing things.
    if (statement instanceof GrApplicationStatement applicationStatement) {
      // Workaround to create an application statement.
      applicationStatement.getArgumentList().delete();
    }
    else if (statement instanceof GrAssignmentExpression assignment) {
      // Workaround to create an assignment statement
      if (assignment.getRValue() != null) {
        assignment.getRValue().delete();
      }
    }
    else if (statement instanceof GrVariableDeclaration variableDeclaration) {
      for (GrVariable var : variableDeclaration.getVariables()) {
        if (var.getInitializerGroovy() != null) {
          var.getInitializerGroovy().delete();
          // The '=' gets deleted here, add it back.
          final ASTNode node = var.getNode();
          node.addLeaf(mASSIGN, "=", var.getLastChild().getNode().getTreeNext());
        }
      }
    }
    else if (syntax == SET_METHOD && statement instanceof GrMethodCallExpression methodCallExpression) {
      methodCallExpression.getArgumentList().delete();
    }
    PsiElement lineTerminator = factory.createLineTerminator(1);
    PsiElement addedElement;
    PsiElement anchor = getPsiElementForAnchor(parentPsiElement, anchorAfter);

    if (parentPsiElement instanceof GroovyFile) {
      // Check if the file has a Block Comment and add the psi element after it if true.
      PsiElement firstFileChild = parentPsiElement.getFirstChild();
      if (addBefore) {
        // should really do this for all kinds of parentPsiElement, not just GroovyFile
        addedElement = parentPsiElement.addBefore(statement, anchor);
      }
      else if (firstFileChild != null && firstFileChild.getNode().getElementType() == ML_COMMENT && anchor == null) {
        addedElement = parentPsiElement.addAfter(statement, firstFileChild);
      }
      else {
        addedElement = parentPsiElement.addAfter(statement, anchor);
      }

      if (!isWhiteSpaceOrNls(addedElement.getPrevSibling())) {
        parentPsiElement.addBefore(lineTerminator, addedElement);
      }
      if (addBefore) {
        parentPsiElement.addAfter(lineTerminator, addedElement);
      }
    }
    else if (parentPsiElement instanceof GrClosableBlock) {
      addedElement = parentPsiElement.addAfter(statement, anchor);
      PsiElement prevSibling = addedElement.getPrevSibling();
      if (!(anchorAfter instanceof GradleDslAnchor.Start)) {
        if (!(prevSibling instanceof GrParameterList)) {
          parentPsiElement.addBefore(lineTerminator, addedElement);
        }
      }
      else {
        parentPsiElement.addAfter(lineTerminator, addedElement);
        if (closableBlockNeedsNewline((GrClosableBlock)parentPsiElement)) {
          parentPsiElement.addBefore(lineTerminator, addedElement);
        }
      }
    }
    else {
      addedElement = parentPsiElement.addAfter(statement, anchor);
      parentPsiElement.addBefore(lineTerminator, addedElement);
    }
    if (element.isBlockElement()) {
      GrClosableBlock closableBlock = getClosableBlock(addedElement);
      if (closableBlock != null) {
        element.setPsiElement(closableBlock);
      }
    }
    else {
      if (addedElement instanceof GrApplicationStatement ||
          addedElement instanceof GrAssignmentExpression ||
          addedElement instanceof GrVariableDeclaration) {
        // This is for the workarounds above, this ensures that applyDslLiteral is called to actually add the value to
        // either the application or assignment statement.
        element.setPsiElement(addedElement);
      }
      else if (syntax == SET_METHOD && addedElement instanceof GrMethodCallExpression) {
        element.setPsiElement(addedElement);
      }
    }
    return element.getPsiElement();
  }