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.28 2005-05-13 20:19:42 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.jface.text.Assert;
21 import org.eclipse.jface.text.BadLocationException;
22 import org.eclipse.jface.text.IDocument;
23 import org.eclipse.jface.text.rules.ICharacterScanner;
24 import org.eclipse.jface.text.rules.IPartitionTokenScanner;
25 import org.eclipse.jface.text.rules.IToken;
26 import org.eclipse.jface.text.rules.Token;
31 * @author Igor Malinin
33 public class PHPPartitionScanner implements IPartitionTokenScanner {
34 // public static final String JSP_DIRECTIVE = "__jsp_directive";
35 // public static final String JSP_COMMENT = "__jsp_comment";
36 //// public static final String JSP_TAG = "__jsp_tag";
37 // public static final String JSP_DECLARATION = "__jsp_declaration";
38 public static final String PHP_SCRIPTING_AREA = "__php_scripting_area ";
40 // public static final String JSP_EXPRESSION = "__jsp_expression";
42 public static final int STATE_DEFAULT = 0;
44 // public static final int STATE_TAG = 1;
45 // public static final int STATE_SCRIPT = 2;
47 private IDocument document;
61 private Map tokens = new HashMap();
63 public PHPPartitionScanner() {
67 * @see org.eclipse.jface.text.rules.ITokenScanner#nextToken()
69 public IToken nextToken() {
73 * switch (state) { case STATE_TAG: return nextTagToken(); }
77 case ICharacterScanner.EOF:
78 state = STATE_DEFAULT;
79 return getToken(null);
83 case ICharacterScanner.EOF:
84 state = STATE_DEFAULT;
85 return getToken(null);
87 case '?': // <%SCRIPLET <%@DIRECTIVE <%!DECLARATION <%=EXPRESSION <%--COMMENT
89 // if (Character.isWhitespace((char)ch)) {
90 // return nextJSPToken(PHP_SCRIPTING_AREA);
93 case ICharacterScanner.EOF:
94 state = STATE_DEFAULT;
95 return getToken(PHP_SCRIPTING_AREA);
97 // case '-': // <%- <%--COMMENT
99 // case ICharacterScanner.EOF:
101 // return nextCommentToken();
107 return scanUntilPHPEndToken(PHP_SCRIPTING_AREA);
115 case ICharacterScanner.EOF:
116 state = STATE_DEFAULT;
117 return getToken(null);
121 case ICharacterScanner.EOF:
122 state = STATE_DEFAULT;
123 return getToken(null);
138 state = STATE_DEFAULT;
139 return getToken(null);
144 private IToken scanUntilPHPEndToken(String token) {
148 case ICharacterScanner.EOF:
149 state = STATE_DEFAULT;
150 return getToken(token);
151 case '"': // double quoted string
152 // read until end of double quoted string
153 if (!readUntilEscapedDQ()) {
154 state = STATE_DEFAULT;
155 return getToken(token);
158 case '\'': // single quoted string
159 // read until end of single quoted string
160 if (!readUntilEscapedSQ()) {
161 state = STATE_DEFAULT;
162 return getToken(token);
165 case '/': // comment start?
168 case ICharacterScanner.EOF:
171 // read until end of line
172 if (!readSingleLine()) {
173 state = STATE_DEFAULT;
174 return getToken(token);
178 // read until end of comment
179 if (!readMultiLineComment()) {
180 state = STATE_DEFAULT;
181 return getToken(token);
188 case '#': // line comment
189 // read until end of line
190 if (!readSingleLine()) {
191 state = STATE_DEFAULT;
192 return getToken(token);
198 case ICharacterScanner.EOF:
200 state = STATE_DEFAULT;
201 return getToken(token);
214 // private IToken nextCommentToken() {
216 // loop: while (true) {
218 // case ICharacterScanner.EOF:
221 // case '-': // - --%>
224 // case ICharacterScanner.EOF:
227 // case '-': // -- --%>
230 // case ICharacterScanner.EOF:
233 // case '%': // --% --%>
236 // case ICharacterScanner.EOF:
243 // case '-': // --- ---%>
256 // return getToken(JSP_COMMENT);
259 private IToken getToken(String type) {
260 length = position - offset;
268 // System.out.println("Length<0:"+document.get(offset,5)+""+length);
269 // } catch (BadLocationException e) {
270 // e.printStackTrace();
275 return Token.UNDEFINED;
278 IToken token = (IToken) tokens.get(type);
280 token = new Token(type);
281 tokens.put(type, token);
288 if (position >= end) {
289 return ICharacterScanner.EOF;
293 return document.getChar(position++);
294 } catch (BadLocationException e) {
296 return ICharacterScanner.EOF;
300 private boolean readUntilEscapedDQ() {
301 // search last double quoted character
305 if (position >= end) {
308 ch = document.getChar(position++);
310 if (position >= end) {
313 ch = document.getChar(position++); // ignore escaped character
314 } else if (ch == '"') {
318 } catch (BadLocationException e) {
324 private boolean readUntilEscapedSQ() {
325 // search last single quoted character
329 if (position >= end) {
332 ch = document.getChar(position++);
334 if (position >= end) {
337 ch = document.getChar(position++); // ignore escaped character
338 } else if (ch == '\'') {
342 } catch (BadLocationException e) {
348 private boolean readSingleLine() {
351 if (position >= end) {
354 } while (document.getChar(position++) != '\n');
356 } catch (BadLocationException e) {
362 private boolean readMultiLineComment() {
366 if (position >= end) {
369 ch = document.getChar(position++);
371 if (position >= end) {
374 if (document.getChar(position) == '/') {
380 } catch (BadLocationException e) {
386 private void unread() {
391 * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenOffset()
393 public int getTokenOffset() {
394 if (AbstractPartitioner.DEBUG) {
395 Assert.isTrue(offset >= 0, Integer.toString(offset));
401 * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenLength()
403 public int getTokenLength() {
408 * @see org.eclipse.jface.text.rules.ITokenScanner#setRange(IDocument, int, int)
410 public void setRange(IDocument document, int offset, int length) {
411 this.document = document;
413 this.end = offset + length;
415 this.offset = offset;
416 this.position = offset;
421 * @see org.eclipse.jface.text.rules.IPartitionTokenScanner
423 public void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset) {
424 state = STATE_DEFAULT;
425 // if (partitionOffset > -1) {
426 // int delta= offset - partitionOffset;
428 // this.setRange(document, partitionOffset, length + delta);
432 setRange(document, partitionOffset, length);
435 // private boolean isContinuationPartition(IDocument document, int offset) {
437 // String type = document.getContentType(offset - 1);
439 // if (type != IDocument.DEFAULT_CONTENT_TYPE) {
442 // } catch (BadLocationException e) {}