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

org.eclipse.xtext.parser.impl.TokenRegionProvider Maven / Gradle / Ivy

There is a newer version: 2.4.3
Show newest version
/*******************************************************************************
 * Copyright (c) 2012 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.parser.impl;

import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CommonToken;
import org.antlr.runtime.Token;
import org.eclipse.xtext.parser.antlr.Lexer;
import org.eclipse.xtext.parser.antlr.LexerBindings;
import org.eclipse.xtext.util.ITextRegion;
import org.eclipse.xtext.util.ReplaceRegion;
import org.eclipse.xtext.util.TextRegion;

import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.name.Named;

/**
 * Expands a region such that it contains only complete lexer tokens.
 * 
 * @author Jan Koehnlein - Initial contribution and API
 * @since 2.3
 */
public class TokenRegionProvider {

	@Inject
	@Named(LexerBindings.RUNTIME)
	private Provider lexerProvider;

	public ITextRegion getTokenRegion(String text, ITextRegion region) {
		Lexer lexer = lexerProvider.get();
		lexer.setCharStream(new ANTLRStringStream(text));
		int currentStart = 0;
		int currentEnd = 0;
		CommonToken currentToken = (CommonToken) lexer.nextToken();
		int regionStartOffset = region.getOffset();
		int regionEnd = regionStartOffset + region.getLength();
		while (currentToken != Token.EOF_TOKEN) {
			currentStart = currentToken.getStartIndex();
			currentEnd = currentToken.getStopIndex() + 1;
			if (currentToken.getStopIndex() >= regionStartOffset) 
				break;
			currentToken = (CommonToken) lexer.nextToken();
		}
		if (region.getLength() == 0 && regionStartOffset == currentToken.getStopIndex() + 1) {
			currentEnd = currentStart;
		} else {
			// currentToken is first token overlapping with the region or EOF
			while (currentToken != Token.EOF_TOKEN) {
				currentEnd = currentToken.getStopIndex() + 1;
				if (currentEnd >= regionEnd) {
					break;
				}
				currentToken = (CommonToken) lexer.nextToken();
			}
		}
		if (currentStart != regionStartOffset || currentEnd != regionEnd) 
			return new TextRegion(currentStart, currentEnd - currentStart);
		else 
			return region;
	}

	public ReplaceRegion getTokenReplaceRegion(String changedText, ReplaceRegion replaceRegion) {
		int lengthDelta = replaceRegion.getText().length() - replaceRegion.getLength();
		ITextRegion tokenRegion = getTokenRegion(changedText, new TextRegion(replaceRegion.getOffset(), replaceRegion
				.getText().length()));
		if (tokenRegion.getOffset() == replaceRegion.getOffset()
				&& tokenRegion.getLength() == replaceRegion.getText().length())
			return replaceRegion;
		else 
			return new ReplaceRegion(tokenRegion.getOffset(), tokenRegion.getLength() - lengthDelta,
					changedText.substring(tokenRegion.getOffset(), tokenRegion.getOffset() + tokenRegion.getLength()));
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy