1 /**********************************************************************
2 Copyright (c) 2002 Widespace, OU and others.
3 All rights reserved. This program and the accompanying materials
4 are made available under the terms of the Common Public License v1.0
5 which accompanies this distribution, and is available at
6 http://solareclipse.sourceforge.net/legal/cpl-v10.html
9 Igor Malinin - initial contribution
11 $Id: PHPPartitionScanner.java,v 1.26 2005-05-05 14:06:38 axelcl Exp $
12 **********************************************************************/
13 package net.sourceforge.phpeclipse.phpeditor.php;
15 import java.util.HashMap;
18 import net.sourceforge.phpeclipse.ui.text.rules.AbstractPartitioner;
20 import org.eclipse.core.internal.indexing.AbstractPagePolicy;
21 import org.eclipse.jface.text.Assert;
22 import org.eclipse.jface.text.BadLocationException;
23 import org.eclipse.jface.text.IDocument;
24 import org.eclipse.jface.text.rules.ICharacterScanner;
25 import org.eclipse.jface.text.rules.IPartitionTokenScanner;
26 import org.eclipse.jface.text.rules.IToken;
27 import org.eclipse.jface.text.rules.Token;
32 * @author Igor Malinin
34 public class PHPPartitionScanner implements IPartitionTokenScanner {
35 // public static final String JSP_DIRECTIVE = "__jsp_directive";
36 // public static final String JSP_COMMENT = "__jsp_comment";
37 //// public static final String JSP_TAG = "__jsp_tag";
38 // public static final String JSP_DECLARATION = "__jsp_declaration";
39 public static final String PHP_SCRIPTING_AREA = "__php_scripting_area ";
41 // public static final String JSP_EXPRESSION = "__jsp_expression";
43 public static final int STATE_DEFAULT = 0;
45 // public static final int STATE_TAG = 1;
46 // public static final int STATE_SCRIPT = 2;
48 private IDocument document;
62 private Map tokens = new HashMap();
64 public PHPPartitionScanner() {
68 * @see org.eclipse.jface.text.rules.ITokenScanner#nextToken()
70 public IToken nextToken() {
74 * switch (state) { case STATE_TAG: return nextTagToken(); }
78 case ICharacterScanner.EOF:
79 state = STATE_DEFAULT;
80 return getToken(null);
84 case ICharacterScanner.EOF:
85 state = STATE_DEFAULT;
86 return getToken(null);
88 case '?': // <%SCRIPLET <%@DIRECTIVE <%!DECLARATION <%=EXPRESSION <%--COMMENT
90 // if (Character.isWhitespace((char)ch)) {
91 // return nextJSPToken(PHP_SCRIPTING_AREA);
94 case ICharacterScanner.EOF:
95 state = STATE_DEFAULT;
96 return getToken(PHP_SCRIPTING_AREA);
98 // case '-': // <%- <%--COMMENT
100 // case ICharacterScanner.EOF:
102 // return nextCommentToken();
108 return scanUntilPHPEndToken(PHP_SCRIPTING_AREA);
116 case ICharacterScanner.EOF:
117 state = STATE_DEFAULT;
118 return getToken(null);
122 case ICharacterScanner.EOF:
123 state = STATE_DEFAULT;
124 return getToken(null);
139 state = STATE_DEFAULT;
140 return getToken(null);
145 private IToken scanUntilPHPEndToken(String token) {
149 case ICharacterScanner.EOF:
150 state = STATE_DEFAULT;
151 return getToken(token);
152 case '"': // double quoted string
153 // read until end of double quoted string
154 if (!readUntilEscapedDQ()) {
155 state = STATE_DEFAULT;
156 return getToken(token);
159 case '\'': // single quoted string
160 // read until end of single quoted string
161 if (!readUntilEscapedSQ()) {
162 state = STATE_DEFAULT;
163 return getToken(token);
166 case '/': // comment start?
169 case ICharacterScanner.EOF:
172 // read until end of line
176 // read until end of comment
177 readMultiLineComment();
183 case '#': // line comment
184 // read until end of line
190 case ICharacterScanner.EOF:
192 state = STATE_DEFAULT;
193 return getToken(token);
204 // private IToken nextCommentToken() {
206 // loop: while (true) {
208 // case ICharacterScanner.EOF:
211 // case '-': // - --%>
214 // case ICharacterScanner.EOF:
217 // case '-': // -- --%>
220 // case ICharacterScanner.EOF:
223 // case '%': // --% --%>
226 // case ICharacterScanner.EOF:
233 // case '-': // --- ---%>
246 // return getToken(JSP_COMMENT);
249 private IToken getToken(String type) {
250 length = position - offset;
257 return Token.UNDEFINED;
260 IToken token = (IToken) tokens.get(type);
262 token = new Token(type);
263 tokens.put(type, token);
270 if (position >= end) {
271 return ICharacterScanner.EOF;
275 return document.getChar(position++);
276 } catch (BadLocationException e) {
278 return ICharacterScanner.EOF;
282 private boolean readUntilEscapedDQ() {
283 // search last double quoted character
284 if (position >= end) {
290 ch = document.getChar(position++);
292 ch = document.getChar(position++); // ignore escaped character
293 } else if (ch == '"') {
297 } catch (BadLocationException e) {
303 private boolean readUntilEscapedSQ() {
304 // search last single quoted character
305 if (position >= end) {
311 ch = document.getChar(position++);
313 ch = document.getChar(position++); // ignore escaped character
314 } else if (ch == '\'') {
318 } catch (BadLocationException e) {
324 private void readSingleLine() {
325 if (position >= end) {
329 while (document.getChar(position++) != '\n') {
332 } catch (BadLocationException e) {
338 private void readMultiLineComment() {
339 if (position >= end) {
345 ch = document.getChar(position++);
347 if (document.getChar(position) == '/') {
353 } catch (BadLocationException e) {
359 private void unread() {
364 * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenOffset()
366 public int getTokenOffset() {
367 if (AbstractPartitioner.DEBUG) {
368 Assert.isTrue(offset >= 0, Integer.toString(offset));
374 * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenLength()
376 public int getTokenLength() {
381 * @see org.eclipse.jface.text.rules.ITokenScanner#setRange(IDocument, int, int)
383 public void setRange(IDocument document, int offset, int length) {
384 this.document = document;
386 this.end = offset + length;
388 this.offset = offset;
389 this.position = offset;
394 * @see org.eclipse.jface.text.rules.IPartitionTokenScanner
396 public void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset) {
397 state = STATE_DEFAULT;
398 // if (partitionOffset > -1) {
399 // int delta= offset - partitionOffset;
401 // this.setRange(document, partitionOffset, length + delta);
405 setRange(document, partitionOffset, length);
408 // private boolean isContinuationPartition(IDocument document, int offset) {
410 // String type = document.getContentType(offset - 1);
412 // if (type != IDocument.DEFAULT_CONTENT_TYPE) {
415 // } catch (BadLocationException e) {}