Far better but not finished, it will now get function and class declaration in outline
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpeclipse / phpeditor / php / PHPCodeScanner.java
1 /**********************************************************************
2 Copyright (c) 2000, 2002 IBM Corp. 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://www.eclipse.org/legal/cpl-v10.html
7
8 Contributors:
9     IBM Corporation - Initial implementation
10     Klaus Hartlage - www.eclipseproject.de
11 **********************************************************************/
12 package net.sourceforge.phpeclipse.phpeditor.php;
13
14 import java.util.ArrayList;
15 import java.util.List;
16 import java.util.Vector;
17
18 import net.sourceforge.phpeclipse.IPreferenceConstants;
19 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
20 import net.sourceforge.phpeclipse.phpeditor.PHPSyntaxRdr;
21 import net.sourceforge.phpeclipse.phpeditor.util.PHPColorProvider;
22 import net.sourceforge.phpeclipse.phpeditor.util.PHPWhitespaceDetector;
23 import net.sourceforge.phpeclipse.phpeditor.util.PHPWordDetector;
24
25 import org.eclipse.jface.preference.IPreferenceStore;
26 import org.eclipse.jface.preference.PreferenceConverter;
27 import org.eclipse.jface.text.TextAttribute;
28 import org.eclipse.jface.text.rules.EndOfLineRule;
29 import org.eclipse.jface.text.rules.ICharacterScanner;
30 import org.eclipse.jface.text.rules.IRule;
31 import org.eclipse.jface.text.rules.IToken;
32 import org.eclipse.jface.text.rules.IWordDetector;
33 import org.eclipse.jface.text.rules.MultiLineRule;
34 import org.eclipse.jface.text.rules.RuleBasedScanner;
35 import org.eclipse.jface.text.rules.SingleLineRule;
36 import org.eclipse.jface.text.rules.Token;
37 import org.eclipse.jface.text.rules.WhitespaceRule;
38 import org.eclipse.jface.text.rules.WordRule;
39 import org.eclipse.swt.SWT;
40 import org.eclipse.swt.graphics.Color;
41
42 /**
43  * PHP Code Scanner
44  */
45 public class PHPCodeScanner extends RuleBasedScanner implements IPreferenceConstants {
46
47   private static Token variable;
48   private static Token keyword;
49   private static Token type;
50   private static Token constant;
51   private static Token functionName;
52   private static Token string;
53   private static Token comment;
54   private static Token multi_comment;
55   private static Token other;
56
57   private class PHPWordRule extends WordRule {
58     private StringBuffer fBuffer = new StringBuffer();
59
60     public PHPWordRule(IWordDetector detector) {
61       super(detector, Token.UNDEFINED);
62     }
63
64     public PHPWordRule(IWordDetector detector, IToken defaultToken) {
65       super(detector, defaultToken);
66     }
67
68     public IToken evaluate(ICharacterScanner scanner) {
69       int c = scanner.read();
70       boolean isVariable = false;
71       if (fDetector.isWordStart((char) c)) {
72         if (c == '$') {
73           isVariable = true;
74         }
75         if (fColumn == UNDEFINED || (fColumn == scanner.getColumn() - 1)) {
76
77           fBuffer.setLength(0);
78           do {
79             fBuffer.append((char) c);
80             c = scanner.read();
81           } while (c != ICharacterScanner.EOF && fDetector.isWordPart((char) c));
82           scanner.unread();
83
84           if (isVariable) {
85             return variable;
86           }
87           IToken token = (IToken) fWords.get(fBuffer.toString());
88           if (token != null)
89             return token;
90
91           if (fDefaultToken.isUndefined())
92             unreadBuffer(scanner);
93
94           return fDefaultToken;
95         }
96       }
97
98       scanner.unread();
99       return Token.UNDEFINED;
100     }
101   }
102
103   private PHPColorProvider fColorProvider;
104
105   /**
106         * Creates a PHP code scanner
107         */
108   public PHPCodeScanner(PHPColorProvider provider) {
109     final IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore();
110     Color BackgroundColor = provider.getColor(PreferenceConverter.getColor(store, PHP_EDITOR_BACKGROUND));
111     variable =
112       new Token(
113         new TextAttribute(
114           provider.getColor(PreferenceConverter.getColor(store, PHP_VARIABLE)),
115           BackgroundColor,
116           (store.getBoolean(PHP_VARIABLE_BOLD) ? SWT.BOLD : SWT.NONE)
117             + (store.getBoolean(PHP_VARIABLE_ITALIC) ? SWT.ITALIC : SWT.NONE)));
118       keyword =
119         new Token(new TextAttribute(
120           provider.getColor(PreferenceConverter.getColor(store, PHP_KEYWORD)),
121           BackgroundColor,
122     //SWT.NONE));
123    (store.getBoolean(PHP_KEYWORD_BOLD) ? SWT.BOLD : SWT.NONE) + (store.getBoolean(PHP_KEYWORD_ITALIC) ? SWT.ITALIC : SWT.NONE)));
124       type =
125         new Token(new TextAttribute(
126           provider.getColor(PreferenceConverter.getColor(store, PHP_TYPE)),
127           BackgroundColor,
128     //SWT.NONE));
129    (store.getBoolean(PHP_TYPE_BOLD) ? SWT.BOLD : SWT.NONE) + (store.getBoolean(PHP_TYPE_ITALIC) ? SWT.ITALIC : SWT.NONE)));
130       functionName =
131         new Token(new TextAttribute(
132           provider.getColor(PreferenceConverter.getColor(store, PHP_FUNCTIONNAME)),
133           BackgroundColor,
134     //SWT.NONE));
135   (store.getBoolean(PHP_FUNCTIONNAME_BOLD) ? SWT.BOLD : SWT.NONE)
136     + (store.getBoolean(PHP_FUNCTIONNAME_ITALIC) ? SWT.ITALIC : SWT.NONE)));
137       constant =
138         new Token(new TextAttribute(
139           provider.getColor(PreferenceConverter.getColor(store, PHP_CONSTANT)),
140           BackgroundColor,
141     //SWT.NONE));
142    (store.getBoolean(PHP_CONSTANT_BOLD) ? SWT.BOLD : SWT.NONE) + (store.getBoolean(PHP_CONSTANT_ITALIC) ? SWT.ITALIC : SWT.NONE)));
143       string =
144         new Token(new TextAttribute(
145           provider.getColor(PreferenceConverter.getColor(store, PHP_STRING)),
146           BackgroundColor,
147     //SWT.NONE));
148    (store.getBoolean(PHP_STRING_BOLD) ? SWT.BOLD : SWT.NONE ) + (store.getBoolean(PHP_STRING_ITALIC) ? SWT.ITALIC : SWT.NONE)));
149       comment =
150         new Token(new TextAttribute(
151           provider.getColor(PreferenceConverter.getColor(store, PHP_SINGLELINE_COMMENT)),
152           BackgroundColor,
153     //SWT.NONE));
154   (store.getBoolean(PHP_SINGLELINE_COMMENT_BOLD) ? SWT.BOLD : SWT.NONE )
155     + (store.getBoolean(PHP_SINGLELINE_COMMENT_ITALIC) ? SWT.ITALIC : SWT.NONE)));
156       multi_comment =
157         new Token(new TextAttribute(
158           provider.getColor(PreferenceConverter.getColor(store, PHP_MULTILINE_COMMENT)),
159           BackgroundColor,
160     //SWT.NONE));
161   (store.getBoolean(PHP_MULTILINE_COMMENT_BOLD) ? SWT.BOLD : SWT.NONE)
162     + (store.getBoolean(PHP_MULTILINE_COMMENT_ITALIC) ? SWT.ITALIC : SWT.NONE)));
163       other =
164         new Token(new TextAttribute(
165           provider.getColor(PreferenceConverter.getColor(store, PHP_DEFAULT)),
166           BackgroundColor,
167     //SWT.NONE));
168    (store.getBoolean(PHP_DEFAULT_BOLD) ? SWT.BOLD : SWT.NONE) + (store.getBoolean(PHP_DEFAULT_ITALIC) ? SWT.ITALIC : SWT.NONE)));
169     updateWordRules();
170   }
171
172   public void updateToken(PHPColorProvider provider) {
173     final IPreferenceStore store = PHPeclipsePlugin.getDefault().getPreferenceStore();
174
175     Color BackgroundColor = provider.getColor(PreferenceConverter.getColor(store, PHP_EDITOR_BACKGROUND));
176
177     variable.setData(
178       new TextAttribute(
179         provider.getColor(PreferenceConverter.getColor(store, PHP_VARIABLE)),
180         BackgroundColor,
181         (store.getBoolean(PHP_VARIABLE_BOLD) ? SWT.BOLD : SWT.NONE)
182           + (store.getBoolean(PHP_VARIABLE_ITALIC) ? SWT.ITALIC : SWT.NONE)));
183     keyword.setData(
184       new TextAttribute(
185         provider.getColor(PreferenceConverter.getColor(store, PHP_KEYWORD)),
186         BackgroundColor,
187         (store.getBoolean(PHP_KEYWORD_BOLD) ? SWT.BOLD : SWT.NONE)
188           + (store.getBoolean(PHP_KEYWORD_ITALIC) ? SWT.ITALIC : SWT.NONE)));
189     type.setData(
190       new TextAttribute(
191         provider.getColor(PreferenceConverter.getColor(store, PHP_TYPE)),
192         BackgroundColor,
193         (store.getBoolean(PHP_TYPE_BOLD) ? SWT.BOLD : SWT.NONE) + (store.getBoolean(PHP_TYPE_ITALIC) ? SWT.ITALIC : SWT.NONE)));
194     functionName.setData(
195       new TextAttribute(
196         provider.getColor(PreferenceConverter.getColor(store, PHP_FUNCTIONNAME)),
197         BackgroundColor,
198         (store.getBoolean(PHP_FUNCTIONNAME_BOLD) ? SWT.BOLD : SWT.NONE)
199           + (store.getBoolean(PHP_FUNCTIONNAME_ITALIC) ? SWT.ITALIC : SWT.NONE)));
200     constant.setData(
201       new TextAttribute(
202         provider.getColor(PreferenceConverter.getColor(store, PHP_CONSTANT)),
203         BackgroundColor,
204         (store.getBoolean(PHP_CONSTANT_BOLD) ? SWT.BOLD : SWT.NONE)
205           + (store.getBoolean(PHP_CONSTANT_ITALIC) ? SWT.ITALIC : SWT.NONE)));
206     string.setData(
207       new TextAttribute(
208         provider.getColor(PreferenceConverter.getColor(store, PHP_STRING)),
209         BackgroundColor,
210         (store.getBoolean(PHP_STRING_BOLD) ? SWT.BOLD : SWT.NONE) + (store.getBoolean(PHP_STRING_ITALIC) ? SWT.ITALIC : SWT.NONE)));
211     comment.setData(
212       new TextAttribute(
213         provider.getColor(PreferenceConverter.getColor(store, PHP_SINGLELINE_COMMENT)),
214         BackgroundColor,
215         (store.getBoolean(PHP_SINGLELINE_COMMENT_BOLD) ? SWT.BOLD : SWT.NONE)
216           + (store.getBoolean(PHP_SINGLELINE_COMMENT_ITALIC) ? SWT.ITALIC : SWT.NONE)));
217     multi_comment.setData(
218       new TextAttribute(
219         provider.getColor(PreferenceConverter.getColor(store, PHP_MULTILINE_COMMENT)),
220         BackgroundColor,
221         (store.getBoolean(PHP_MULTILINE_COMMENT_BOLD) ? SWT.BOLD : SWT.NONE)
222           + (store.getBoolean(PHP_MULTILINE_COMMENT_ITALIC) ? SWT.ITALIC : SWT.NONE)));
223     other.setData(
224       new TextAttribute(
225         provider.getColor(PreferenceConverter.getColor(store, PHP_DEFAULT)),
226         BackgroundColor,
227         (store.getBoolean(PHP_DEFAULT_BOLD) ? SWT.BOLD : SWT.NONE)
228           + (store.getBoolean(PHP_DEFAULT_ITALIC) ? SWT.ITALIC : SWT.NONE)));
229   }
230
231   public void updateWordRules() {
232     List rules = new ArrayList();
233     // Add rule for single line comments.
234     rules.add(new EndOfLineRule("//", comment)); //$NON-NLS-1$
235     rules.add(new EndOfLineRule("#", comment));
236     // Add rule for strings and character constants.
237     rules.add(new MultiLineRule("\"", "\"", string, '\\')); //$NON-NLS-2$ //$NON-NLS-1$
238     rules.add(new SingleLineRule("'", "'", string, '\\')); //$NON-NLS-2$ //$NON-NLS-1$
239     // rules.add(new SingleLineRule("//", "//", php_comment));
240     rules.add(new MultiLineRule("/*", "*/", multi_comment));
241     // Add generic whitespace rule.
242     rules.add(new WhitespaceRule(new PHPWhitespaceDetector()));
243     // Add word rule for keywords, types, and constants.
244     PHPWordRule wordRule = new PHPWordRule(new PHPWordDetector(), other);
245
246     PHPSyntaxRdr.readInSyntax();
247     Vector buffer = PHPSyntaxRdr.getsyntaxdata();
248     String strbuffer = null;
249     PHPElement elbuffer = null;
250     while ((buffer != null) && (!buffer.isEmpty() && ((elbuffer = (PHPElement) buffer.remove(0)) != null))) {
251       if (elbuffer instanceof PHPKeyword)
252         wordRule.addWord(((PHPKeyword) elbuffer).getName(), keyword);
253       if (elbuffer instanceof PHPFunction)
254         wordRule.addWord(((PHPFunction) elbuffer).getName(), functionName);
255       if (elbuffer instanceof PHPType)
256         wordRule.addWord(elbuffer.getName(), type);
257       if (elbuffer instanceof PHPConstant)
258         wordRule.addWord(elbuffer.getName(), constant);
259     }
260     rules.add(wordRule);
261     IRule[] result = new IRule[rules.size()];
262     rules.toArray(result);
263     setRules(result);
264   }
265 }