2 * This program and the accompanying materials
3 * are made available under the terms of the Common Public License v1.0
4 * which accompanies this distribution, and is available at
5 * http://www.eclipse.org/legal/cpl-v10.html
6 * Created on 05.03.2003
8 * @author Stefan Langer (musk)
9 * @version $Revision: 1.12 $
11 package net.sourceforge.phpeclipse.phpeditor.php;
15 import org.eclipse.jface.text.*;
16 import org.eclipse.jface.text.rules.*;
21 public class PHPPartitionScanner implements IPartitionTokenScanner
23 private static final boolean DEBUG = false;
24 private IDocument fDocument = null;
25 private int fOffset = -1;
26 private String fContentType = IPHPPartitionScannerConstants.HTML;
27 private String fPrevContentType;
29 private boolean partitionBorder = false;
30 private int fTokenOffset;
31 private int fEnd = -1;
33 private Map tokens = new HashMap();
35 public PHPPartitionScanner()
38 IPHPPartitionScannerConstants.PHP,
39 new Token(IPHPPartitionScannerConstants.PHP));
41 IPHPPartitionScannerConstants.PHP_MULTILINE_COMMENT,
42 new Token(IPHPPartitionScannerConstants.PHP_MULTILINE_COMMENT));
44 IPHPPartitionScannerConstants.HTML,
45 new Token(IPHPPartitionScannerConstants.HTML));
47 IPHPPartitionScannerConstants.HTML_MULTILINE_COMMENT,
48 new Token(IPHPPartitionScannerConstants.HTML_MULTILINE_COMMENT));
50 IDocument.DEFAULT_CONTENT_TYPE,
51 new Token(IDocument.DEFAULT_CONTENT_TYPE));
54 private IToken getToken(String type)
56 fLength = fOffset - fTokenOffset;
57 IToken token = (IToken) this.tokens.get(type);
58 Assert.isNotNull(token, "Token for type \"" + type + "\" not found!");
62 "Partition: fTokenOffset="
73 * @see org.eclipse.jface.text.rules.IPartitionTokenScanner#setPartialRange(org.eclipse.jface.text.IDocument, int, int, java.lang.String, int)
75 public void setPartialRange(
82 this.setRange(document, offset, length);
86 "PartialRange: contentType="
92 if (this.tokens.containsKey(contentType))
93 fContentType = contentType;
94 // TODO Calculate previouse contenttype
95 if (partitionOffset > -1)
97 partitionBorder = false;
98 fTokenOffset = partitionOffset;
103 * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenLength()
105 public int getTokenLength()
111 * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenOffset()
113 public int getTokenOffset()
119 * @see org.eclipse.jface.text.rules.ITokenScanner#nextToken()
121 public IToken nextToken()
125 // check if we are not allready at the end of the
127 if ((c = read()) == ICharacterScanner.EOF)
129 partitionBorder = false;
137 fTokenOffset = fOffset;
138 partitionBorder = false;
141 while ((c = read()) != ICharacterScanner.EOF)
147 != IPHPPartitionScannerConstants.PHP_MULTILINE_COMMENT
148 && checkPattern(new char[] { '?', 'p', 'h', 'p' }, true))
150 if (fContentType != IPHPPartitionScannerConstants.PHP
154 IToken token = getToken(fContentType);
155 // save previouse contenttype
156 fPrevContentType = fContentType;
158 fContentType = IPHPPartitionScannerConstants.PHP;
163 fContentType = IPHPPartitionScannerConstants.PHP;
165 // remember offset of this partition
166 fTokenOffset = fOffset - 5;
168 else if (checkPattern(new char[] { '!', '-', '-' }))
170 // return previouse partition
172 != IPHPPartitionScannerConstants
173 .HTML_MULTILINE_COMMENT
177 IToken token = getToken(fContentType);
180 IPHPPartitionScannerConstants
181 .HTML_MULTILINE_COMMENT;
186 IPHPPartitionScannerConstants
187 .HTML_MULTILINE_COMMENT;
189 fTokenOffset = fOffset - 4;
193 if (fContentType == IPHPPartitionScannerConstants.PHP)
195 if ((c = read()) == '>')
196 { // TODO Actually calculate the previouse contenttype from the document
197 if(fPrevContentType != null)
198 fContentType = fPrevContentType;
200 fContentType = IPHPPartitionScannerConstants.HTML;
201 partitionBorder = true;
202 return getToken(IPHPPartitionScannerConstants.PHP);
204 else if (c != ICharacterScanner.EOF)
210 == IPHPPartitionScannerConstants.HTML_MULTILINE_COMMENT
211 && checkPattern(new char[] { '-', '>' }))
213 fContentType = IPHPPartitionScannerConstants.HTML;
214 partitionBorder = true;
216 IPHPPartitionScannerConstants
217 .HTML_MULTILINE_COMMENT);
221 if ((c = read()) == '*')
222 { // MULTINE COMMENT JAVASCRIPT, CSS, PHP
223 if (fContentType == IPHPPartitionScannerConstants.PHP
227 IToken token = getToken(fContentType);
230 IPHPPartitionScannerConstants
231 .PHP_MULTILINE_COMMENT;
237 == IPHPPartitionScannerConstants
238 .PHP_MULTILINE_COMMENT)
241 fTokenOffset = fOffset - 2;
245 else if (c != ICharacterScanner.EOF)
249 if ((c = read()) == '/')
252 == IPHPPartitionScannerConstants
253 .PHP_MULTILINE_COMMENT)
255 fContentType = IPHPPartitionScannerConstants.PHP;
256 partitionBorder = true;
259 IPHPPartitionScannerConstants
260 .PHP_MULTILINE_COMMENT);
264 == IPHPPartitionScannerConstants
265 .CSS_MULTILINE_COMMENT)
270 == IPHPPartitionScannerConstants
271 .JS_MULTILINE_COMMENT)
275 else if (c != ICharacterScanner.EOF)
281 // end of file reached but we have to return the
283 return getToken(fContentType);
286 * @see org.eclipse.jface.text.rules.ITokenScanner#setRange(org.eclipse.jface.text.IDocument, int, int)
288 public void setRange(IDocument document, int offset, int length)
293 "SET RANGE: offset=" + offset + " length=" + length);
296 fDocument = document;
298 fTokenOffset = offset;
300 fEnd = fOffset + length;
301 //partitionBorder = false;
310 return fDocument.getChar(fOffset++);
312 return ICharacterScanner.EOF;
314 catch (BadLocationException e)
316 // should never happen
317 // TODO write stacktrace to log
319 return ICharacterScanner.EOF;
323 private void unread()
328 private boolean checkPattern(char[] pattern)
330 return checkPattern(pattern, false);
334 * Check if next character sequence read from document is equals to
335 * the provided pattern. Pattern is read from left to right until the
336 * first character read doesn't match. If this happens all read characters are
338 * @param pattern The pattern to check.
339 * @return <code>true</code> if pattern is equals else returns <code>false</code>.
341 private boolean checkPattern(char[] pattern, boolean ignoreCase)
343 int prevOffset = fOffset;
344 for (int i = 0; i < pattern.length; i++)
348 if (c == ICharacterScanner.EOF
349 || !letterEquals(c, pattern[i], ignoreCase))
351 fOffset = prevOffset;
359 private boolean letterEquals(int test, char letter, boolean ignoreCase)
365 && Character.isLowerCase(letter)
366 && test == Character.toUpperCase(letter))
370 && Character.isUpperCase(letter)
371 && test == Character.toLowerCase(letter))