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

org.eclipse.xtext.grammaranalysis.impl.GrammarElementTitleSwitch Maven / Gradle / Ivy

There is a newer version: 2.4.3
Show newest version
/*******************************************************************************
 * Copyright (c) 2009 itemis AG (http://www.itemis.eu) and others.
 * 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 org.eclipse.xtext.grammaranalysis.impl;

import java.util.List;
import java.util.Map;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.AbstractElement;
import org.eclipse.xtext.AbstractRule;
import org.eclipse.xtext.Action;
import org.eclipse.xtext.Alternatives;
import org.eclipse.xtext.Assignment;
import org.eclipse.xtext.CompoundElement;
import org.eclipse.xtext.CrossReference;
import org.eclipse.xtext.EcoreUtil2;
import org.eclipse.xtext.GrammarUtil;
import org.eclipse.xtext.Group;
import org.eclipse.xtext.Keyword;
import org.eclipse.xtext.RuleCall;
import org.eclipse.xtext.UnorderedGroup;
import org.eclipse.xtext.serializer.analysis.Context2NameFunction;
import org.eclipse.xtext.util.XtextSwitch;

import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

/**
 * @author Moritz Eysholdt - Initial contribution and API
 */
public class GrammarElementTitleSwitch extends XtextSwitch implements Function {

	protected static class Node {
		protected List children = Lists.newArrayList();
		protected CompoundElement compound;
		protected String text;

		public Node(CompoundElement compound, String text) {
			super();
			this.compound = compound;
			this.text = text;
		}

		@Override
		public String toString() {
			if (text != null)
				return text;
			if (children.size() == 1)
				return children.get(0).toString();
			if (compound instanceof Group)
				return "(" + Joiner.on(" ").join(children) + ")";
			if (compound instanceof UnorderedGroup)
				return "(" + Joiner.on("&").join(children) + ")";
			if (compound instanceof Alternatives)
				return "(" + Joiner.on("|").join(children) + ")";
			return "";
		}
	}

	protected boolean showActionAsRuleCall = false;

	protected boolean showAssignment = false;

	protected boolean showCardinality = true;

	protected boolean showQualified = false;

	protected boolean showRule = false;

	protected String valueForNull = "(null)";

	protected String addAssignemnt(String result, AbstractElement ele) {
		if (!showAssignment)
			return result;
		Assignment ass = GrammarUtil.containingAssignment(ele);
		result = ass != null ? ass.getFeature() + ass.getOperator() + result : result;
		return addQualified(result, ele);
	}

	protected String addCrossRef(String result, AbstractElement ele) {
		if (!showAssignment)
			return result;
		CrossReference cr = GrammarUtil.containingCrossReference(ele);
		if (cr == null)
			return result;
		String name = cr.getType() != null && cr.getType().getClassifier() != null ? cr.getType().getClassifier()
				.getName() : "null";
		return "[" + name + "|" + result + "]";
	}

	protected String addCrossRefOrAssignemnt(String result, AbstractElement ele) {
		return addAssignemnt(addCrossRef(result, ele), ele);
	}

	protected String addQualified(String result, AbstractElement ele) {
		if (!showQualified && !showRule)
			return result;
		AbstractRule rule = GrammarUtil.containingRule(ele);
		if (!showQualified)
			return result + ":" + rule.getName();
		GrammarElementTitleSwitch others = copy();
		others.showQualified = false;
		others.showRule = false;
		List elementsWithSameName = Lists.newArrayList();
		for (AbstractElement candidate : EcoreUtil2.getAllContentsOfType(rule, ele.getClass()))
			if (candidate == ele || result.equals(others.doSwitch(candidate)))
				elementsWithSameName.add(candidate);
		if (elementsWithSameName.size() < 2) {
			if (showRule)
				return rule.getName() + ":" + result;
			return result;
		}
		Map nodes = Maps.newHashMap();
		for (AbstractElement collision : elementsWithSameName) {
			EObject current = EcoreUtil2.getContainerOfType(collision, CompoundElement.class);
			Node node = new Node(null, collision == ele ? result : "");
			while (current instanceof CompoundElement) {
				CompoundElement container = (CompoundElement) current;
				Node cntNode = nodes.get(container);
				if (cntNode == null)
					nodes.put(container, cntNode = new Node(container, null));
				if (!cntNode.children.contains(node))
					cntNode.children.add(node);
				node = cntNode;
				current = current.eContainer();
			}
		}
		if (showRule)
			return rule.getName() + ":" + nodes.get(rule.getAlternatives());
		return nodes.get(rule.getAlternatives()).toString();
	}

	public String apply(AbstractElement from) {
		return doSwitch(from);
	}

	protected String card(AbstractElement ele) {
		if (!showCardinality)
			return "";
		return ele.getCardinality() == null ? "" : ele.getCardinality();
	}

	@Override
	public String caseAbstractElement(AbstractElement object) {
		return object.eClass().getName() + card(object);
	}

	@Override
	public String caseAbstractRule(AbstractRule object) {
		String classifier = object.getType().getClassifier().getName();
		if (object.getName().equals(classifier))
			return object.getName() + ":";
		return object.getName() + " returns " + classifier + ":";
	}

	@Override
	public String caseAction(Action object) {
		String f = object.getFeature();
		String o = object.getOperator();
		o = (o == null) ? "" : o;
		String result;
		if (showActionAsRuleCall && f != null) {
			result = f + o + new Context2NameFunction().apply(object) + card(object);
		} else {
			String t = object.getType() != null && object.getType().getClassifier() != null ? object.getType()
					.getClassifier().getName() : "null";
			t = (t == null) ? "" : t;
			f = (f == null) ? "" : "." + f;
			result = "{" + t + f + o + "}" + card(object);
		}
		return addQualified(result, object);
	}

	@Override
	public String caseAlternatives(Alternatives object) {
		return "\\|" + card(object);
	}

	@Override
	public String caseAssignment(Assignment object) {
		String result = object.getFeature() + object.getOperator() + " " + card(object);
		return addQualified(result, object);
	}

	@Override
	public String caseCrossReference(CrossReference object) {
		String cr = "[" + object.getType().getClassifier().getName() + "]";
		return addAssignemnt(cr, object) + card(object);
	}

	@Override
	public String caseGroup(Group object) {
		return "( )" + card(object);
	}

	@Override
	public String caseKeyword(Keyword object) {
		return addCrossRefOrAssignemnt("'" + object.getValue() + "'", object) + card(object);
	}

	@Override
	public String caseRuleCall(RuleCall object) {
		return addCrossRefOrAssignemnt(object.getRule().getName(), object) + card(object);
	}

	@Override
	public String caseUnorderedGroup(UnorderedGroup object) {
		return "\\&" + card(object);
	}

	protected GrammarElementTitleSwitch copy() {
		GrammarElementTitleSwitch result = new GrammarElementTitleSwitch();
		result.showActionAsRuleCall = showActionAsRuleCall;
		result.showAssignment = showAssignment;
		result.showCardinality = showCardinality;
		result.showQualified = showQualified;
		result.showRule = showRule;
		return result;
	}

	@Override
	public String defaultCase(EObject object) {
		return object.eClass().getName();
	}

	@Override
	public String doSwitch(EObject theEObject) {
		if (theEObject == null)
			return valueForNull;
		return super.doSwitch(theEObject);
	}

	public GrammarElementTitleSwitch hideCardinality() {
		showCardinality = false;
		return this;
	}

	public GrammarElementTitleSwitch setValueForNull(String value) {
		valueForNull = value;
		return this;
	}

	public GrammarElementTitleSwitch showActionsAsRuleCalls() {
		showActionAsRuleCall = true;
		return this;
	}

	public GrammarElementTitleSwitch showAssignments() {
		showAssignment = true;
		return this;
	}

	public GrammarElementTitleSwitch showQualified() {
		showQualified = true;
		return this;
	}

	public GrammarElementTitleSwitch showRule() {
		showRule = true;
		return this;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy