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

org.eclipse.xtext.service.AbstractElementFinder Maven / Gradle / Ivy

/*******************************************************************************
 * 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.service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Stack;

import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.AbstractRule;
import org.eclipse.xtext.Assignment;
import org.eclipse.xtext.CrossReference;
import org.eclipse.xtext.EcoreUtil2;
import org.eclipse.xtext.GrammarUtil;
import org.eclipse.xtext.IGrammarAccess;
import org.eclipse.xtext.IGrammarAccess.IEnumRuleAccess;
import org.eclipse.xtext.IGrammarAccess.IParserRuleAccess;
import org.eclipse.xtext.Keyword;
import org.eclipse.xtext.ParserRule;
import org.eclipse.xtext.RuleCall;
import org.eclipse.xtext.util.Pair;
import org.eclipse.xtext.util.Tuples;

import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;

/**
 * @author Moritz Eysholdt - Initial contribution and API
 */
public abstract class AbstractElementFinder {

	public static abstract class AbstractEnumRuleElementFinder extends AbstractElementFinder implements IEnumRuleAccess {
		@Override
		protected Iterable getRules() {
			return Collections.singletonList(getRule());
		}
	}

	public static abstract class AbstractGrammarElementFinder extends AbstractElementFinder implements IGrammarAccess {
		@Override
		protected Iterable getRules() {
			return GrammarUtil.allRules(getGrammar());
		}

	}

	public static abstract class AbstractParserRuleElementFinder extends AbstractElementFinder implements
			IParserRuleAccess {
		@Override
		protected Iterable getRules() {
			return Collections.singletonList(getRule());
		}

	}

	public List findAssignments(AbstractRule... calledRules) {
		return findByNestedRuleCall(Assignment.class, calledRules);
	}

	@SuppressWarnings("unchecked")
	protected  List findByNestedRuleCall(Class clazz, AbstractRule... rule) {
		Set rls = new HashSet(Arrays.asList(rule));
		ArrayList r = new ArrayList();
		for (AbstractRule ar : getRules()) {
			TreeIterator i = ar.eAllContents();
			while (i.hasNext()) {
				EObject o = i.next();
				if (clazz.isInstance(o)) {
					TreeIterator ct = o.eAllContents();
					while (ct.hasNext()) {
						EObject cto = ct.next();
						if (cto instanceof RuleCall && rls.contains(((RuleCall) cto).getRule())) {
							r.add((T) o);
							break;
						}
					}
					i.prune();
				}
			}
		}
		return r;
	}

	public List findCrossReferences(AbstractRule... rule) {
		return findByNestedRuleCall(CrossReference.class, rule);
	}

	public List findCrossReferences(EClassifier... targetEClassifiers) {
		Set classifiers = new HashSet(Arrays.asList(targetEClassifiers));
		Collection classes = Lists.newArrayList(Iterables.filter(classifiers, EClass.class));
		ArrayList r = new ArrayList();
		for (AbstractRule ar : getRules()) {
			TreeIterator i = ar.eAllContents();
			while (i.hasNext()) {
				EObject o = i.next();
				if (o instanceof CrossReference) {
					CrossReference c = (CrossReference) o;
					if (classifiers.contains(c.getType().getClassifier()))
						r.add(c);
					else if (c.getType().getClassifier() instanceof EClass)
						for (EClass cls : classes)
							if (EcoreUtil2.isAssignableFrom(cls,(EClass) c.getType().getClassifier())) {
								r.add(c);
								break;
							}
					i.prune();
				}
			}
		}
		return r;

	}

	public List> findKeywordPairs(String leftKw, String rightKw) {
		ArrayList> pairs = new ArrayList>();
		for (AbstractRule ar : getRules())
			if (ar instanceof ParserRule && !GrammarUtil.isDatatypeRule((ParserRule) ar)) {
				Stack openings = new Stack();
				TreeIterator i = ar.eAllContents();
				while (i.hasNext()) {
					EObject o = i.next();
					if (o instanceof Keyword) {
						Keyword k = (Keyword) o;
						if (leftKw.equals(k.getValue()))
							openings.push(k);
						else if (rightKw.equals(k.getValue())) {
							if (openings.size() > 0)
								pairs.add(Tuples.create(openings.pop(), k));
						}
					}
				}
			}
		return pairs;
	}

	public List findKeywords(String... keywords) {
		Set kwds = new HashSet(Arrays.asList(keywords));
		ArrayList r = new ArrayList();
		for (AbstractRule ar : getRules()) {
			TreeIterator i = ar.eAllContents();
			while (i.hasNext()) {
				EObject o = i.next();
				if (o instanceof Keyword) {
					Keyword k = (Keyword) o;
					if (kwds.contains(k.getValue()))
						r.add(k);
				}
			}
		}
		return r;
	}

	public List findRuleCalls(AbstractRule... rules) {
		Set rls = new HashSet(Arrays.asList(rules));
		ArrayList r = new ArrayList();
		for (AbstractRule ar : getRules()) {
			TreeIterator i = ar.eAllContents();
			while (i.hasNext()) {
				EObject o = i.next();
				if (o instanceof RuleCall) {
					RuleCall c = (RuleCall) o;
					if (rls.contains(c.getRule()))
						r.add(c);
				}
			}
		}
		return r;
	}

	// FIXME: Before uncommenting this code, it should pay attention to EClasses
	//	public Iterable findAssignments(EStructuralFeature feature) {
	//		return findAssignments(feature.getName());
	//	}
	//	
	//	private Iterable findAssignments(String feature) {
	//		ArrayList r = new ArrayList();
	//		TreeIterator i = getRules().eAllContents();
	//		while (i.hasNext()) {
	//			EObject o = i.next();
	//			if (o instanceof Assignment) {
	//				Assignment a = (Assignment) o;
	//				if (feature.equals(a.getFeature()))
	//					r.add(a);
	//			}
	//		}
	//		return r;
	//	}

	protected abstract Iterable getRules();

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy