|
From: Christopher W. <caw...@us...> - 2006-05-12 21:39:39
|
Update of /cvsroot/rubyeclipse/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text In directory sc8-pr-cvs9.sourceforge.net:/tmp/cvs-serv31010/src/org/rubypeople/rdt/internal/ui/text Modified Files: RubyPartitionScanner.java IRubyPartitions.java Added Files: PercentSyntaxRule.java Removed Files: RubyContentAssistPreference.java Log Message: --- NEW FILE: PercentSyntaxRule.java --- package org.rubypeople.rdt.internal.ui.text; import org.eclipse.jface.text.rules.ICharacterScanner; import org.eclipse.jface.text.rules.IRule; import org.eclipse.jface.text.rules.IToken; import org.eclipse.jface.text.rules.Token; public class PercentSyntaxRule implements IRule { public IToken evaluate(ICharacterScanner scanner) { int c = scanner.read(); if (((char) c) == '%') { c = scanner.read(); // get next char switch ((char) c) { case 'r': // regular expression return detectToken(scanner, IRubyPartitions.RUBY_REGEX); case 'x': // commands return detectToken(scanner, IRubyPartitions.RUBY_COMMAND); case 'q': case 'Q': // strings return detectToken(scanner, IRubyPartitions.RUBY_STRING); default: // special case of string (no letter following percent) scanner.unread(); return detectToken(scanner, IRubyPartitions.RUBY_STRING); } } scanner.unread(); return Token.UNDEFINED; } private IToken detectToken(ICharacterScanner scanner, String tokenType) { int c = scanner.read(); // get delimeter int lastChar = c; char endChar = getMatchingBracket((char) c); // Read until EOF, End character or EOL while (true) { c = scanner.read(); // FIXME This is a big hack. Expression substitution actually needs to be returned as normal ruby code (and repartitioned) if ((char) c == '#') { // Try to handle expression substitution char d = (char) scanner.read(); if (d == '{') { // read until '}' do { d = (char)scanner.read(); } while (d != '}'); continue; } else if (d == '@' || d == '$') { // read until whitespace do { d = (char) scanner.read(); } while (d != ' '); continue; } else {// not expression subst. scanner.unread(); } } // TODO Stop at EOL,char[][] originalDelimiters= // scanner.getLegalLineDelimiters(); if (c == ICharacterScanner.EOF) break; // we're done if ((char) c == endChar && ((char) lastChar != '\\')) break; // we found matching bracket lastChar = c; } return new Token(tokenType); } /** * Returns whether the next characters to be read by the character scanner * are an exact match with the given sequence. No escape characters are * allowed within the sequence. If specified the sequence is considered to * be found when reading the EOF character. * * @param scanner * the character scanner to be used * @param sequence * the sequence to be detected * @param eofAllowed * indicated whether EOF terminates the pattern * @return <code>true</code> if the given sequence has been detected */ protected boolean sequenceDetected(ICharacterScanner scanner, char[] sequence, boolean eofAllowed) { for (int i = 1; i < sequence.length; i++) { int c = scanner.read(); if (c == ICharacterScanner.EOF && eofAllowed) { return true; } else if (c != sequence[i]) { // Non-matching character detected, rewind the scanner back to // the start. // Do not unread the first character. scanner.unread(); for (int j = i - 1; j > 0; j--) scanner.unread(); return false; } } return true; } private char getMatchingBracket(char c) { switch (c) { case '(': return ')'; case '{': return '}'; case '[': return ']'; case '<': return '>'; default: return c; } } } --- RubyContentAssistPreference.java DELETED --- Index: RubyPartitionScanner.java =================================================================== RCS file: /cvsroot/rubyeclipse/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/RubyPartitionScanner.java,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** RubyPartitionScanner.java 24 Apr 2006 21:24:21 -0000 1.11 --- RubyPartitionScanner.java 12 May 2006 21:39:35 -0000 1.12 *************** *** 4,28 **** import java.util.List; import org.eclipse.jface.text.rules.EndOfLineRule; import org.eclipse.jface.text.rules.IPredicateRule; import org.eclipse.jface.text.rules.IToken; import org.eclipse.jface.text.rules.MultiLineRule; ! import org.eclipse.jface.text.rules.RuleBasedPartitionScanner; import org.eclipse.jface.text.rules.SingleLineRule; import org.eclipse.jface.text.rules.Token; import org.eclipse.jface.text.rules.WordPatternRule; ! public class RubyPartitionScanner extends RuleBasedPartitionScanner { - public final static String RUBY_STRING = IRubyPartitions.RUBY_STRING; public final static String RUBY_MULTI_LINE_COMMENT = IRubyPartitions.RUBY_MULTI_LINE_COMMENT; public static final String RUBY_SINGLE_LINE_COMMENT = IRubyPartitions.RUBY_SINGLE_LINE_COMMENT; ! public static final String RUBY_REGULAR_EXPRESSION = "partition_scanner_ruby_regular_expression"; ! public static final String RUBY_COMMAND = "partition_scanner_ruby_command"; public static final String HERE_DOC = "partition_scanner_here_doc"; ! ! public static final String[] LEGAL_CONTENT_TYPES = {RUBY_STRING, RUBY_MULTI_LINE_COMMENT, RUBY_SINGLE_LINE_COMMENT, RUBY_REGULAR_EXPRESSION, RUBY_COMMAND}; ! public RubyPartitionScanner() { super(); --- 4,45 ---- import java.util.List; + import org.eclipse.jface.text.IDocument; + import org.eclipse.jface.text.rules.BufferedRuleBasedScanner; import org.eclipse.jface.text.rules.EndOfLineRule; + import org.eclipse.jface.text.rules.IPartitionTokenScanner; import org.eclipse.jface.text.rules.IPredicateRule; + import org.eclipse.jface.text.rules.IRule; import org.eclipse.jface.text.rules.IToken; import org.eclipse.jface.text.rules.MultiLineRule; ! import org.eclipse.jface.text.rules.PatternRule; import org.eclipse.jface.text.rules.SingleLineRule; import org.eclipse.jface.text.rules.Token; import org.eclipse.jface.text.rules.WordPatternRule; ! public class RubyPartitionScanner extends BufferedRuleBasedScanner implements ! IPartitionTokenScanner { ! ! /** The content type of the partition in which to resume scanning. */ ! protected String fContentType; ! ! /** The offset of the partition inside which to resume. */ ! protected int fPartitionOffset; public final static String RUBY_STRING = IRubyPartitions.RUBY_STRING; + public final static String RUBY_MULTI_LINE_COMMENT = IRubyPartitions.RUBY_MULTI_LINE_COMMENT; + public static final String RUBY_SINGLE_LINE_COMMENT = IRubyPartitions.RUBY_SINGLE_LINE_COMMENT; ! ! public static final String RUBY_REGULAR_EXPRESSION = IRubyPartitions.RUBY_REGEX; ! ! public static final String RUBY_COMMAND = IRubyPartitions.RUBY_COMMAND; ! public static final String HERE_DOC = "partition_scanner_here_doc"; ! ! public static final String[] LEGAL_CONTENT_TYPES = { RUBY_STRING, ! RUBY_MULTI_LINE_COMMENT, RUBY_SINGLE_LINE_COMMENT, ! RUBY_REGULAR_EXPRESSION, RUBY_COMMAND }; ! public RubyPartitionScanner() { super(); *************** *** 36,40 **** IToken regexp = new Token(RUBY_REGULAR_EXPRESSION); IToken command = new Token(RUBY_COMMAND); ! IToken hereDoc = new Token(RUBY_STRING) ; List rules = new ArrayList(); --- 53,57 ---- IToken regexp = new Token(RUBY_REGULAR_EXPRESSION); IToken command = new Token(RUBY_COMMAND); ! IToken hereDoc = new Token(RUBY_STRING); List rules = new ArrayList(); *************** *** 43,89 **** // strings (and therefore have quotes inside them which don't end the // partition) ! // Strings ! rules.add(new SingleLineRule("\"", "\"", string, '\\')); ! rules.add(new SingleLineRule("'", "'", string, '\\')); ! createGeneralDelimitedRules(rules, "%q", string, '\\'); ! createGeneralDelimitedRules(rules, "%Q", string, '\\'); ! createGeneralDelimitedRules(rules, "%", string, '\\'); // Regular expressions ! createRuleWithOptionalEndChars(rules, "/", "/", new char[] {'s', 'u', 'e', 'n', 'x', 'm', 'o', 'i'}, regexp, '\\'); ! rules.add(new SingleLineRule("/", "/", regexp, '\\')); ! createGeneralDelimitedRules(rules, "%r", regexp, '\\'); ! // Commands rules.add(new SingleLineRule("`", "`", command, '\\')); ! createGeneralDelimitedRules(rules, "%x", command, '\\'); ! ! // Single line comments ! // ?# evaluates to the asiic value of # ! rules.add(new WordPatternRule(new NumberSignDetector(),"?", "#", Token.UNDEFINED)) ; rules.add(new EndOfLineRule("#", singleLineComment)); // Multiline comments ! MultiLineRule multiLineCommentRule = new MultiLineRule("=begin", "=end", multiLineComment) ; ! multiLineCommentRule.setColumnConstraint(0) ; rules.add(multiLineCommentRule); ! ! rules.add(new HereDocPatternRule(hereDoc)) ; ! ! IPredicateRule[] result = new IPredicateRule[rules.size()]; rules.toArray(result); ! setPredicateRules(result); } ! private void createRuleWithOptionalEndChars(List rules, String prefix, String endString, char[] options, IToken token, char escapeChar) { ! for (int i = 0; i < options.length; i++) { ! rules.add(new SingleLineRule(prefix, endString + options[i], token, escapeChar)); } } ! private void createGeneralDelimitedRules(List rules, String prefix, IToken token, char escapeChar) { ! rules.add(new MultiLineRule(prefix + "[", "]", token, escapeChar)); ! rules.add(new MultiLineRule(prefix + "{", "}", token, escapeChar)); ! rules.add(new MultiLineRule(prefix + "(", ")", token, escapeChar)); ! rules.add(new MultiLineRule(prefix + "<", ">", token, escapeChar)); } } \ No newline at end of file --- 60,168 ---- // strings (and therefore have quotes inside them which don't end the // partition) ! // Strings ! rules.add(new PatternRule("\"", "\"", string, '\\', false, false)); ! rules.add(new PatternRule("'", "'", string, '\\', false, false)); ! // Regular expressions ! // TODO Work with options: 's', 'u', 'e', 'n', 'x', 'm', 'o', 'i' ! rules.add(new SingleLineRule("/", "/", regexp, '\\')); ! // Commands rules.add(new SingleLineRule("`", "`", command, '\\')); ! ! // Catch all the wacky Percent Syntax (Strings/commands/regexps) ! rules.add(new PercentSyntaxRule()); ! ! // Single line comments ! // ?# evaluates to the ascii value of # ! rules.add(new WordPatternRule(new NumberSignDetector(), "?", "#", ! Token.UNDEFINED)); rules.add(new EndOfLineRule("#", singleLineComment)); // Multiline comments ! MultiLineRule multiLineCommentRule = new MultiLineRule("=begin", ! "=end", multiLineComment); ! multiLineCommentRule.setColumnConstraint(0); rules.add(multiLineCommentRule); ! ! rules.add(new HereDocPatternRule(hereDoc)); ! ! // FIXME Create Hyrbid of RuleBasedPartitionScanner which allows IRule ! // or IPredicateRule and will only evaluate IPredicateRules if success ! // token matches content type ! IRule[] result = new IRule[rules.size()]; rules.toArray(result); ! setRules(result); } ! /* ! * @see ITokenScanner#setRange(IDocument, int, int) ! */ ! public void setRange(IDocument document, int offset, int length) { ! setPartialRange(document, offset, length, null, -1); ! } ! ! /* ! * @see IPartitionTokenScanner#setPartialRange(IDocument, int, int, String, ! * int) ! */ ! public void setPartialRange(IDocument document, int offset, int length, ! String contentType, int partitionOffset) { ! fContentType = contentType; ! fPartitionOffset = partitionOffset; ! if (partitionOffset > -1) { ! int delta = offset - partitionOffset; ! if (delta > 0) { ! super.setRange(document, partitionOffset, length + delta); ! fOffset = offset; ! return; ! } } + super.setRange(document, offset, length); } ! /* ! * @see ITokenScanner#nextToken() ! */ ! public IToken nextToken() { ! ! if (fContentType == null || fRules == null) { ! // don't try to resume ! return super.nextToken(); ! } ! ! // inside a partition ! ! fColumn = UNDEFINED; ! boolean resume = (fPartitionOffset > -1 && fPartitionOffset < fOffset); ! fTokenOffset = resume ? fPartitionOffset : fOffset; ! ! IRule rule; ! IToken token; ! ! for (int i = 0; i < fRules.length; i++) { ! rule = (IRule) fRules[i]; ! if (rule instanceof IPredicateRule) { ! IPredicateRule predRule = (IPredicateRule) rule; ! token = predRule.getSuccessToken(); ! if (fContentType.equals(token.getData())) { ! token = predRule.evaluate(this, resume); ! if (!token.isUndefined()) { ! fContentType = null; ! return token; ! } ! } ! } else { ! token= rule.evaluate(this); ! if (!token.isUndefined()) ! return token; ! } ! } ! ! // haven't found any rule for this type of partition ! fContentType = null; ! if (resume) ! fOffset = fPartitionOffset; ! return super.nextToken(); } } \ No newline at end of file Index: IRubyPartitions.java =================================================================== RCS file: /cvsroot/rubyeclipse/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/IRubyPartitions.java,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** IRubyPartitions.java 10 Feb 2006 20:14:43 -0000 1.3 --- IRubyPartitions.java 12 May 2006 21:39:35 -0000 1.4 *************** *** 17,20 **** --- 17,24 ---- */ public final static String RUBY_PARTITIONING= "___ruby_partitioning"; //$NON-NLS-1$ + + public static final String RUBY_REGEX = "__ruby_regular_expression"; //$NON-NLS-1$ + + public static final String RUBY_COMMAND = "__ruby_command"; //$NON-NLS-1$ /** |