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

org.eclipse.xtext.conversion.impl.AbstractIDValueConverter Maven / Gradle / Ivy

/*******************************************************************************
 * Copyright (c) 2010 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.conversion.impl;

import java.util.Set;

import org.antlr.runtime.Token;
import org.eclipse.xtext.Grammar;
import org.eclipse.xtext.IGrammarAccess;
import org.eclipse.xtext.conversion.ValueConverterException;
import org.eclipse.xtext.nodemodel.INode;

import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.google.inject.ImplementedBy;
import com.google.inject.Inject;

/**
 * Abstract implementation of a value converter that escapes a string
 * based on a set of values. The strategy to compute this values and how the 
 * the string is found in this set is the responsibility of the concrete 
 * implementation. A common use-case is to collect the keywords in a grammar
 * and match the string against these keywords or to use some ignore-case matching
 * algorithm against the list of normalized keywords.
 *  
 * @author Sebastian Zarnekow - Initial contribution and API
 */
@ImplementedBy(IDValueConverter.class)
public abstract class AbstractIDValueConverter extends AbstractLexerBasedConverter {

	@Inject
	private IGrammarAccess grammarAccess;
	
	private Set valuesToEscape;

	protected AbstractIDValueConverter() {
		super();
	}
	
	protected abstract Set computeValuesToEscape(Grammar grammar);
	
	protected Set getValuesToEscape() {
		if (valuesToEscape == null)
			valuesToEscape = computeValuesToEscape(grammarAccess.getGrammar());
		return valuesToEscape;
	}

	protected abstract boolean mustEscape(String value);
	
	@Override
	protected String toEscapedString(String value) {
		if (mustEscape(value))
			return "^" + value;
		return value;
	}
	
	@Override
	protected void assertValidValue(String value) {
		super.assertValidValue(value);
		if (value.length() == 0) {
			throw new ValueConverterException(getRuleName() + " may not be empty.", null, null);
		}
	}
	
	@Override
	protected ValueConverterException createTokenContentMismatchException(String value, String escapedString, Token token) {
		Set invalidChars = collectInvalidCharacters(value);
		if (invalidChars != null) {
			return new ValueConverterException(getInvalidCharactersMessage(value, invalidChars), null, null);
		}
		return super.createTokenContentMismatchException(value, escapedString, token);
	}

	protected String getInvalidCharactersMessage(String value, Set invalidChars) {
		String chars = Joiner.on(", ").join(Iterables.transform(invalidChars, new Function() {
			public String apply(Character from) {
				return "'" + from + "' (0x" + Integer.toHexString(from) + ")";
			}
		}));
		return "ID '" + value + "' contains invalid characters: " + chars;
	}
	
	protected Set collectInvalidCharacters(String value) {
		Set result = null;
		for (int i = 0; i < value.length(); i++) {
			char c = value.charAt(i);
			if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
				continue;
			if (i != 0 && c >= '0' && c <= '9')
				continue;
			if (c == '_')
				continue;
			if (result == null)
				result = Sets.newHashSet();
			result.add(c);
		}
		return result;
	}
	
	public String toValue(String string, INode node) {
		if (string == null)
			return null;
		return string.startsWith("^") ? string.substring(1) : string;
	}
	
	protected IGrammarAccess getGrammarAccess() {
		return grammarAccess;
	}
	
	public void setGrammarAccess(IGrammarAccess grammarAccess) {
		this.grammarAccess = grammarAccess;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy