All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.intellij.codeInsight.template.emmet.EmmetParser Maven / Gradle / Ivy

Go to download

A packaging of the IntelliJ Community Edition xml library. This is release number 1 of trunk branch 142.

The newest version!
/*
 * Copyright 2000-2014 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.intellij.codeInsight.template.emmet;

import com.intellij.codeInsight.template.CustomTemplateCallback;
import com.intellij.codeInsight.template.emmet.generators.ZenCodingGenerator;
import com.intellij.codeInsight.template.emmet.nodes.*;
import com.intellij.codeInsight.template.emmet.tokens.*;
import com.intellij.codeInsight.template.impl.TemplateImpl;
import org.jetbrains.annotations.Nullable;

import java.util.List;

/**
 * User: zolotov
 * Date: 1/25/13
 */
public abstract class EmmetParser {
  private final List myTokens;
  protected final CustomTemplateCallback myCallback;
  protected final ZenCodingGenerator myGenerator;

  private int myIndex = 0;

  public EmmetParser(List tokens, CustomTemplateCallback callback, ZenCodingGenerator generator) {
    myTokens = tokens;
    myCallback = callback;
    myGenerator = generator;
  }

  public int getIndex() {
    return myIndex;
  }

  @Nullable
  public ZenCodingNode parse() {
    ZenCodingNode add = parseAddOrMore();
    if (add == null) {
      return null;
    }

    ZenCodingNode result = add;

    while (true) {
      ZenCodingToken token = getToken();
      if (token != ZenCodingTokens.PIPE) {
        return result;
      }

      advance();
      token = getToken();
      if (!(token instanceof IdentifierToken)) {
        return null;
      }

      final String filterSuffix = ((IdentifierToken)token).getText();
      if (ZenCodingUtil.checkFilterSuffix(filterSuffix)) {
        result = new FilterNode(result, filterSuffix);
      }

      advance();
    }
  }

  @Nullable
  protected ZenCodingNode parseAddOrMore() {
    ZenCodingNode mul = parseMul();

    ZenCodingToken operationToken = getToken();
    if (operationToken == ZenCodingTokens.OPENING_R_BRACKET) {
      mul = new MoreOperationNode(notNullNode(mul), notNullNode(parseExpression()));
      operationToken = getToken();
    }
    if (!(operationToken instanceof OperationToken)) {
      return mul;
    }
    char sign = ((OperationToken)operationToken).getSign();

    if (sign == '^') {
      return parseClimbUpOperation(mul);
    }
    if (sign == '+') {
      advance();
      ZenCodingNode add2 = parseAddOrMore();
      if (add2 == null) {
        return mul;
      }
      return new AddOperationNode(notNullNode(mul), add2);
    }
    if (sign == '>') {
      return parseMoreOperation(mul);
    }
    return null;
  }

  protected ZenCodingNode parseClimbUpOperation(@Nullable ZenCodingNode leftPart) {
    advance();
    leftPart = notNullNode(leftPart);
    ZenCodingNode rightPart = parseAddOrMore();
    if (rightPart == null) {
      return leftPart;
    }
    return new ClimbUpOperationNode(leftPart, rightPart);
  }

  protected ZenCodingNode parseMoreOperation(@Nullable ZenCodingNode leftPart) {
    advance();
    leftPart = notNullNode(leftPart);
    ZenCodingNode rightPart = parseAddOrMore();
    if (rightPart == null) {
      return leftPart;
    }
    return new MoreOperationNode(leftPart, rightPart);
  }

  private static ZenCodingNode notNullNode(ZenCodingNode node) {
    return node != null ? node : ZenEmptyNode.INSTANCE;
  }

  protected int advance() {
    return myIndex++;
  }

  @Nullable
  private ZenCodingNode parseMul() {
    ZenCodingNode exp = parseExpression();
    if (exp == null) {
      return null;
    }
    ZenCodingToken operationToken = getToken();
    if (!(operationToken instanceof OperationToken)) {
      return exp;
    }
    if (((OperationToken)operationToken).getSign() != '*') {
      return exp;
    }
    advance();
    ZenCodingToken numberToken = getToken();
    if (numberToken instanceof NumberToken) {
      advance();
      return new MulOperationNode(exp, ((NumberToken)numberToken).getNumber());
    }
    return new UnaryMulOperationNode(exp);
  }

  @Nullable
  private ZenCodingNode parseExpression() {
    ZenCodingToken token = getToken();
    if (token == ZenCodingTokens.OPENING_R_BRACKET) {
      advance();
      ZenCodingNode add = parseAddOrMore();
      if (add == null) {
        return null;
      }
      ZenCodingToken closingBrace = getToken();
      if (closingBrace != ZenCodingTokens.CLOSING_R_BRACKET) {
        return null;
      }
      advance();
      return add;
    }
    else if (token instanceof TextToken) {
      advance();
      return new TextNode((TextToken)token);
    }

    final ZenCodingNode templateNode = parseTemplate();
    if (templateNode == null) {
      return null;
    }

    token = getToken();
    if (token instanceof TextToken) {
      advance();
      return new MoreOperationNode(templateNode, new TextNode((TextToken)token));
    }
    return templateNode;
  }

  @Nullable
  protected ZenCodingNode parseTemplate() {
    ZenCodingToken token = getToken();
    if (!(token instanceof IdentifierToken)) {
      return null;
    }
    String templateKey = ((IdentifierToken)token).getText();
    advance();

    TemplateImpl template = myCallback.findApplicableTemplate(templateKey);
    if (template == null && !ZenCodingUtil.isXML11ValidQName(templateKey)) {
      return null;
    }

    final TemplateToken templateToken = new TemplateToken(templateKey);
    if (!setTemplate(templateToken, template)) {
      return null;
    }
    return new TemplateNode(templateToken);
  }

  protected boolean setTemplate(final TemplateToken token, TemplateImpl template) {
    if (template == null) {
      template = myGenerator.createTemplateByKey(token.getKey());
    }
    if (template == null) {
      return false;
    }
    return token.setTemplate(template, myCallback);
  }

  @Nullable
  protected ZenCodingToken getToken() {
    if (myIndex < myTokens.size()) {
      return myTokens.get(myIndex);
    }
    return null;
  }
  
  
  @Nullable
  protected ZenCodingToken nextToken(int i) {
    if (myIndex + i < myTokens.size()) {
      return myTokens.get(myIndex + i);
    }
    return null;
  }

  protected int getCurrentPosition() {
    return myIndex;
  }

  protected void restorePosition(int position) {
    myIndex = position;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy