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.30 2005-09-30 18:10:36 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 PHP_SCRIPTING_AREA = "__php_scripting_area ";
36 public static final int STATE_DEFAULT = 0;
38 // public static final int STATE_TAG = 1;
39 // public static final int STATE_SCRIPT = 2;
41 private IDocument document;
55 private Map tokens = new HashMap();
57 public PHPPartitionScanner() {
61 * @see org.eclipse.jface.text.rules.ITokenScanner#nextToken()
63 public IToken nextToken() {
67 * switch (state) { case STATE_TAG: return nextTagToken(); }
71 case ICharacterScanner.EOF:
72 // state = STATE_DEFAULT;
73 return getToken(null);
77 case ICharacterScanner.EOF:
78 // state = STATE_DEFAULT;
79 return getToken(null);
85 // case ICharacterScanner.EOF:
86 // state = STATE_DEFAULT;
87 // return getToken(PHP_SCRIPTING_AREA);
89 return scanUntilPHPEndToken(PHP_SCRIPTING_AREA);
97 case ICharacterScanner.EOF:
98 // state = STATE_DEFAULT;
99 return getToken(null);
103 case ICharacterScanner.EOF:
104 // state = STATE_DEFAULT;
105 return getToken(null);
120 // state = STATE_DEFAULT;
121 return getToken(null);
126 private IToken scanUntilPHPEndToken(String token) {
130 case ICharacterScanner.EOF:
131 // state = STATE_DEFAULT;
132 return getToken(token);
133 case '"': // double quoted string
134 // read until end of double quoted string
135 if (!readUntilEscapedDQ()) {
136 // state = STATE_DEFAULT;
137 return getToken(token);
140 case '\'': // single quoted string
141 // read until end of single quoted string
142 if (!readUntilEscapedSQ()) {
143 // state = STATE_DEFAULT;
144 return getToken(token);
147 case '/': // comment start?
150 case ICharacterScanner.EOF:
153 // read until end of line
154 if (!readSingleLine()) {
155 // state = STATE_DEFAULT;
156 return getToken(token);
160 // read until end of comment
161 if (!readMultiLineComment()) {
162 // state = STATE_DEFAULT;
163 return getToken(token);
170 case '#': // line comment
171 // read until end of line
172 if (!readSingleLine()) {
173 // state = STATE_DEFAULT;
174 return getToken(token);
180 case ICharacterScanner.EOF:
182 // state = STATE_DEFAULT;
183 return getToken(token);
196 private IToken getToken(String type) {
197 length = position - offset;
205 // System.out.println("Length<0:"+document.get(offset,5)+""+length);
206 // } catch (BadLocationException e) {
207 // e.printStackTrace();
212 return Token.UNDEFINED;
215 IToken token = (IToken) tokens.get(type);
217 token = new Token(type);
218 tokens.put(type, token);
225 if (position >= end) {
226 return ICharacterScanner.EOF;
230 return document.getChar(position++);
231 } catch (BadLocationException e) {
233 return ICharacterScanner.EOF;
237 private boolean readUntilEscapedDQ() {
238 // search last double quoted character
242 if (position >= end) {
245 ch = document.getChar(position++);
247 if (position >= end) {
250 ch = document.getChar(position++); // ignore escaped character
251 } else if (ch == '"') {
255 } catch (BadLocationException e) {
261 private boolean readUntilEscapedSQ() {
262 // search last single quoted character
266 if (position >= end) {
269 ch = document.getChar(position++);
271 if (position >= end) {
274 ch = document.getChar(position++); // ignore escaped character
275 } else if (ch == '\'') {
279 } catch (BadLocationException e) {
285 private boolean readSingleLine() {
288 if (position >= end) {
291 } while (document.getChar(position++) != '\n');
293 } catch (BadLocationException e) {
299 private boolean readMultiLineComment() {
303 if (position >= end) {
306 ch = document.getChar(position++);
308 if (position >= end) {
311 if (document.getChar(position) == '/') {
317 } catch (BadLocationException e) {
323 private void unread() {
328 * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenOffset()
330 public int getTokenOffset() {
331 if (AbstractPartitioner.DEBUG) {
332 Assert.isTrue(offset >= 0, Integer.toString(offset));
338 * @see org.eclipse.jface.text.rules.ITokenScanner#getTokenLength()
340 public int getTokenLength() {
345 * @see org.eclipse.jface.text.rules.ITokenScanner#setRange(IDocument, int, int)
347 public void setRange(IDocument document, int offset, int length) {
348 this.document = document;
349 // this.begin = offset;
350 this.end = offset + length;
352 this.offset = offset;
353 this.position = offset;
358 * @see org.eclipse.jface.text.rules.IPartitionTokenScanner
360 public void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset) {
361 // state = STATE_DEFAULT;
362 if (partitionOffset > -1) {
363 int delta = offset - partitionOffset;
365 setRange(document, partitionOffset, length + delta);
369 setRange(document, partitionOffset, length);
372 // private boolean isContinuationPartition(IDocument document, int offset) {
374 // String type = document.getContentType(offset - 1);
376 // if (type != IDocument.DEFAULT_CONTENT_TYPE) {
379 // } catch (BadLocationException e) {}