1 /******************************************************************************* 2 * Copyright (c) 2000, 2007 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 *******************************************************************************/ 14 package org.eclipse.jface.text.rules; 15 16 17 import org.eclipse.core.runtime.Assert; 18 19 20 21 /** 22 * A specific single line rule which stipulates that the start 23 * and end sequence occur within a single word, as defined by a word detector. 24 * 25 * @see IWordDetector 26 */ 27 public class WordPatternRule extends SingleLineRule { 28 29 /** The word detector used by this rule */ 30 protected IWordDetector fDetector; 31 /** The internal buffer used for pattern detection */ 32 private StringBuilder fBuffer= new StringBuilder(); 33 34 /** 35 * Creates a rule for the given starting and ending word 36 * pattern which, if detected, will return the specified token. 37 * A word detector is used to identify words. 38 * 39 * @param detector the word detector to be used 40 * @param startSequence the start sequence of the word pattern 41 * @param endSequence the end sequence of the word pattern 42 * @param token the token to be returned on success 43 */ WordPatternRule(IWordDetector detector, String startSequence, String endSequence, IToken token)44 public WordPatternRule(IWordDetector detector, String startSequence, String endSequence, IToken token) { 45 this(detector, startSequence, endSequence, token, (char)0); 46 } 47 48 /** 49 /** 50 * Creates a rule for the given starting and ending word 51 * pattern which, if detected, will return the specified token. 52 * A word detector is used to identify words. 53 * Any character which follows the given escapeCharacter will be ignored. 54 * 55 * @param detector the word detector to be used 56 * @param startSequence the start sequence of the word pattern 57 * @param endSequence the end sequence of the word pattern 58 * @param token the token to be returned on success 59 * @param escapeCharacter the escape character 60 */ WordPatternRule(IWordDetector detector, String startSequence, String endSequence, IToken token, char escapeCharacter)61 public WordPatternRule(IWordDetector detector, String startSequence, String endSequence, IToken token, char escapeCharacter) { 62 super(startSequence, endSequence, token, escapeCharacter); 63 Assert.isNotNull(detector); 64 fDetector= detector; 65 } 66 67 /** 68 * Returns whether the end sequence was detected. 69 * The rule acquires the rest of the word, using the 70 * provided word detector, and tests to determine if 71 * it ends with the end sequence. 72 * 73 * @param scanner the scanner to be used 74 * @return <code>true</code> if the word ends on the given end sequence 75 */ 76 @Override endSequenceDetected(ICharacterScanner scanner)77 protected boolean endSequenceDetected(ICharacterScanner scanner) { 78 fBuffer.setLength(0); 79 int c= scanner.read(); 80 while (fDetector.isWordPart((char) c)) { 81 fBuffer.append((char) c); 82 c= scanner.read(); 83 } 84 scanner.unread(); 85 86 if (fBuffer.length() >= fEndSequence.length) { 87 for (int i=fEndSequence.length - 1, j= fBuffer.length() - 1; i >= 0; i--, j--) { 88 if (fEndSequence[i] != fBuffer.charAt(j)) { 89 unreadBuffer(scanner); 90 return false; 91 } 92 } 93 return true; 94 } 95 96 unreadBuffer(scanner); 97 return false; 98 } 99 100 /** 101 * Returns the characters in the buffer to the scanner. 102 * Note that the rule must also return the characters 103 * read in as part of the start sequence expect the first one. 104 * 105 * @param scanner the scanner to be used 106 */ unreadBuffer(ICharacterScanner scanner)107 protected void unreadBuffer(ICharacterScanner scanner) { 108 fBuffer.insert(0, fStartSequence); 109 for (int i= fBuffer.length() - 1; i > 0; i--) 110 scanner.unread(); 111 } 112 } 113