/* * Copyright (c) 2014 Google Inc. * * All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse * Public License v1.0 which accompanies this distribution, and is available at * * http://www.eclipse.org/legal/epl-v10.html */ package com.google.eclipse.protobuf.model.util; import static org.eclipse.xtext.nodemodel.util.NodeModelUtils.findNodesForFeature; import com.google.inject.Singleton; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.xtext.AbstractRule; import org.eclipse.xtext.RuleCall; import org.eclipse.xtext.TerminalRule; import org.eclipse.xtext.nodemodel.ILeafNode; import org.eclipse.xtext.nodemodel.INode; import java.util.List; /** * Utility methods related to <code>{@link INode}</code>s. * * @author alruiz@google.com (Alex Ruiz) */ @Singleton public class INodes { /** * Returns the first node that was used to assign values to the given feature for the given object. * @param o the given object. * @param feature the given feature. * @return the first node that was used to assign values to the given feature for the given object, or {@code null} if * a node cannot be found. */ public INode firstNodeForFeature(EObject o, EStructuralFeature feature) { List<INode> nodes = findNodesForFeature(o, feature); if (nodes.isEmpty()) { return null; } return nodes.get(0); } /** * Indicates whether the given node belongs to a string, or a single- or multi-line comment. * @param node the node to check. * @return {@code true} if the given node belongs to a string, or a single- or multi-line comment; {@code false} * otherwise. */ public boolean isCommentOrString(INode node) { return isComment(node) || isString(node); } /** * Indicates whether the given node belongs to a single- or multiple-line comment. * @param node the node to check. * @return {@code true} if the given node belongs to a single- or multiple-line comment; {@code false} otherwise. */ public boolean isComment(INode node) { return isSingleLineComment(node) || isMultipleLineComment(node); } /** * Indicates whether the given node belongs to a single-line comment. * @param node the node to check. * @return {@code true} if the given node belongs to a single-line comment; {@code false} otherwise. */ public boolean isSingleLineComment(INode node) { return isComment(node, "SL_COMMENT"); } /** * Indicates whether the given node belongs to a multiple-line comment. * @param node the node to check. * @return {@code true} if the given node belongs to a multiple-line comment; {@code false} otherwise. */ public boolean isMultipleLineComment(INode node) { return isComment(node, "ML_COMMENT"); } private static boolean isComment(INode node, String commentRuleName) { if (!(node instanceof ILeafNode)) { return false; } EObject o = node.getGrammarElement(); if (!(o instanceof TerminalRule)) { return false; } TerminalRule rule = (TerminalRule) o; return commentRuleName.equals(rule.getName()); } /** * Indicates whether the given node belongs to a string. * @param node the node to check. * @return {@code true} if the given node belongs to a string; {@code false} otherwise. */ public boolean isString(INode node) { EObject grammarElement = node.getGrammarElement(); if (!(grammarElement instanceof RuleCall)) { return false; } AbstractRule rule = ((RuleCall) grammarElement).getRule(); if (!(rule instanceof TerminalRule)) { return false; } TerminalRule terminalRule = (TerminalRule) rule; return "StringLiteral".equals(terminalRule.getName()) || "CHUNK".equals(terminalRule.getName()); } /** * Indicates whether the given node is a hidden leaf node. * @param node the node to check. * @return {@code true} if the given node is a hidden leaf node; {@code false} otherwise. */ public boolean isHiddenLeafNode(INode node) { if (node instanceof ILeafNode) { return ((ILeafNode) node).isHidden(); } return false; } /** * Returns the text of the given node, with leading and trailing whitespace omitted. * @param node the given node, may be {@code null}. * @return the text of the given node, with leading and trailing whitespace omitted. */ public String textOf(INode node) { if (node == null) { return null; } String text = node.getText(); return (text == null) ? null : text.trim(); } }