/* * <copyright> * * Copyright (c) 2005-2006 Sven Efftinge 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 * * Contributors: * Sven Efftinge - Initial API and implementation * * </copyright> */ package org.eclipse.gmf.internal.xpand.editor.scan; import java.util.ArrayList; import java.util.List; import org.eclipse.gmf.internal.xpand.codeassist.XpandTokens; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.rules.ICharacterScanner; import org.eclipse.jface.text.rules.IPartitionTokenScanner; import org.eclipse.jface.text.rules.IPredicateRule; import org.eclipse.jface.text.rules.IToken; import org.eclipse.jface.text.rules.MultiLineRule; import org.eclipse.jface.text.rules.PatternRule; import org.eclipse.jface.text.rules.RuleBasedScanner; import org.eclipse.jface.text.rules.Token; /** * @author Sven Efftinge */ public class XpandPartitionScanner extends RuleBasedScanner implements IPartitionTokenScanner { public final static String TAG = "__tag"; public final static String COMMENT = "__comment"; public XpandPartitionScanner() { final IToken tag = new Token(TAG); final IToken comment = new Token(COMMENT); final List<PatternRule> rules = new ArrayList<PatternRule>(); // TODO we need to handle whitespace like this: '<< REM .... ENDREM >>' rules.add(new MultiLineRule(XpandTokens.LT + XpandTokens.REM, XpandTokens.ENDREM + XpandTokens.RT, comment)); rules.add(new MultiLineRule(XpandTokens.LT + XpandTokens.REM, XpandTokens.ENDREM + '-' + XpandTokens.RT, comment) { @Override public IToken evaluate(ICharacterScanner scanner) { return super.evaluate(scanner); } }); rules.add(new MultiLineRule(XpandTokens.LT, XpandTokens.RT, tag)); setRules(rules.toArray(new IPredicateRule[rules.size()])); } public void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset) { // copied from RuleBasedPartitionScanner, // the idea seems to be to shift range to the start of the partition if (partitionOffset > -1) { int delta = offset - partitionOffset; if (delta > 0) { super.setRange(document, partitionOffset, length + delta); //fOffset = offset; return; } } super.setRange(document, offset, length); } @Override public IToken nextToken() { // copy from superclass, added reseting fOffset to initial value prior to next rule // invocation to protect from badly written rules (e.g. PatternRule) thad do not unread // characters if matched partially fTokenOffset= fOffset; fColumn= UNDEFINED; if (fRules != null) { for (int i= 0; i < fRules.length; i++) { IToken token= (fRules[i].evaluate(this)); if (!token.isUndefined()) { return token; } else { // reset offset for the next rule fOffset = fTokenOffset; } } } if (read() == EOF) return Token.EOF; return fDefaultReturnToken; } }