|
From: <caw...@us...> - 2007-06-21 14:43:50
|
Revision: 2657
http://svn.sourceforge.net/rubyeclipse/?rev=2657&view=rev
Author: cawilliams
Date: 2007-06-21 07:43:48 -0700 (Thu, 21 Jun 2007)
Log Message:
-----------
add tests and fixes for more advanced code/string substitution scenarios
Modified Paths:
--------------
trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/RubyPartitionScanner.java
trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/text/TC_RubyPartitionScanner.java
Modified: trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/RubyPartitionScanner.java
===================================================================
--- trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/RubyPartitionScanner.java 2007-06-20 21:12:15 UTC (rev 2656)
+++ trunk/org.rubypeople.rdt.ui/src/org/rubypeople/rdt/internal/ui/text/RubyPartitionScanner.java 2007-06-21 14:43:48 UTC (rev 2657)
@@ -66,6 +66,7 @@
private List<QueuedToken> fQueue = new ArrayList<QueuedToken>();
private String fContentType;
+ private boolean inSingleQuote;
// XXX Also do regex partitions!
public final static String RUBY_MULTI_LINE_COMMENT = IRubyPartitions.RUBY_MULTI_LINE_COMMENT;
@@ -115,6 +116,7 @@
lexer.setState(LexState.EXPR_BEG);
parserSupport.initTopLocalVariables();
fQueue.clear();
+ inSingleQuote = false;
}
public int getTokenLength() {
@@ -139,12 +141,12 @@
returnValue = Token.EOF;
} else {
int lexerToken = lexer.token();
- if (lexerToken == Tokens.tSTRING_DVAR) { // we hit a single dynamic variable
+ if (!inSingleQuote && lexerToken == Tokens.tSTRING_DVAR) { // we hit a single dynamic variable
addPoundToken();
scanDynamicVariable();
setLexerPastDynamicSectionOfString();
return popTokenOffQueue();
- } else if (lexerToken == Tokens.tSTRING_DBEG) { // if we hit dynamic code inside a string
+ } else if (!inSingleQuote && lexerToken == Tokens.tSTRING_DBEG) { // if we hit dynamic code inside a string
addPoundBraceToken();
scanTokensInsideDynamicPortion();
addClosingBraceToken();
@@ -216,7 +218,7 @@
private void scanTokensInsideDynamicPortion() {
String possible = new String(fContents.substring(fOffset - origOffset));
- int end = possible.indexOf('}');// TODO Find the end brace '}' in a proper way!
+ int end = findEnd(possible);
if (end != -1) {
possible = possible.substring(0, end);
} else {
@@ -232,6 +234,10 @@
setOffset(fOffset + possible.length());
}
+ private int findEnd(String possible) {
+ return new EndBraceFinder(possible).find();
+ }
+
private void addPoundBraceToken() {
addStringToken(2); // add token for the #{
}
@@ -293,12 +299,17 @@
case Tokens.tSTRING_CONTENT:
return new Token(RUBY_STRING);
case Tokens.tSTRING_BEG:
+ String token = fContents.substring(fOffset, getOffset());
+ if (token.trim().equals("'")) {
+ inSingleQuote = true;
+ }
return new Token(RUBY_STRING);
case Tokens.tQWORDS_BEG:
fContentType = RUBY_STRING;
return new Token(RUBY_STRING);
case Tokens.tSTRING_END:
fContentType = RUBY_DEFAULT;
+ inSingleQuote = false;
return new Token(RUBY_STRING);
case Tokens.tREGEXP_BEG:
return new Token(RUBY_REGULAR_EXPRESSION);
@@ -310,15 +321,6 @@
}
/**
- * Grabs the end of the comment
- * @param comments
- * @return
- */
- private int getEndOfComment(CommentNode comment) {
- return origOffset + comment.getPosition().getEndOffset();
- }
-
- /**
* correct start offset, since when a line with nothing but spaces on it appears before comment,
* we get messed up positions
*/
@@ -365,4 +367,73 @@
setPartialRange(document, offset, length, null, -1);
}
+ private static class EndBraceFinder {
+ private String input;
+ private List<String> stack;
+
+ public EndBraceFinder(String possible) {
+ this.input = possible;
+ stack = new ArrayList<String>();
+ }
+
+ public int find() {
+ for (int i = 0; i < input.length(); i++) {
+ char c = input.charAt(i);
+ switch (c) {
+ case '"':
+ if (topEquals("\"")) {
+ pop();
+ } else {
+ push("\"");
+ }
+ break;
+ case '\'':
+ if (topEquals("'")) {
+ pop();
+ } else {
+ push("'");
+ }
+ break;
+ case '#':
+ // Only add if we're inside a double quote string
+ if (topEquals("\"")) {
+ c = input.charAt(i + 1);
+ if (c == '{')
+ push("#{");
+ }
+ break;
+ case '}':
+ if (stack.isEmpty()) { // if not in open state
+ return i;
+ }
+ if (topEquals("#{")) {
+ pop();
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ return -1;
+ }
+
+ private boolean topEquals(String string) {
+ String open = peek();
+ return open != null && open.equals(string);
+ }
+
+ private boolean push(String string) {
+ return stack.add(string);
+ }
+
+ private String pop() {
+ return stack.remove(stack.size() - 1);
+ }
+
+ private String peek() {
+ if (stack.isEmpty())
+ return null;
+ return stack.get(stack.size() - 1);
+ }
+ }
}
Modified: trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/text/TC_RubyPartitionScanner.java
===================================================================
--- trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/text/TC_RubyPartitionScanner.java 2007-06-20 21:12:15 UTC (rev 2656)
+++ trunk/org.rubypeople.rdt.ui.tests/src/org/rubypeople/rdt/internal/ui/text/TC_RubyPartitionScanner.java 2007-06-21 14:43:48 UTC (rev 2657)
@@ -40,8 +40,8 @@
public void testRecognizeSpecialCase() {
String source = "a,b=?#,'This is not a comment!'\n";
- assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(source, 5));
- assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(source, 6));
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(source, 5));
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(source, 6));
}
public void testMultilineComment() {
@@ -62,43 +62,43 @@
public void testMultilineCommentNotOnFirstColumn() {
String source = " =begin\nComment\n=end";
- assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(source, 0));
- assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(source, 1));
- assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(source, 2));
- assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(source, 10));
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(source, 0));
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(source, 1));
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(source, 2));
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(source, 10));
}
public void testRecognizeDivision() {
String source = "1/3 #This is a comment\n";
- assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(source, 0));
- assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(source, 3));
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(source, 0));
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(source, 3));
assertEquals(RubyPartitionScanner.RUBY_SINGLE_LINE_COMMENT, this.getContentType(source, 5));
}
public void testRecognizeOddballCharacters() {
String source = "?\" #comment\n";
- assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(source, 0));
- assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(source, 2));
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(source, 0));
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(source, 2));
assertEquals(RubyPartitionScanner.RUBY_SINGLE_LINE_COMMENT, this.getContentType(source, 5));
source = "?' #comment\n";
- assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(source, 0));
- assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(source, 2));
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(source, 0));
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(source, 2));
assertEquals(RubyPartitionScanner.RUBY_SINGLE_LINE_COMMENT, this.getContentType(source, 5));
source = "?/ #comment\n";
- assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(source, 0));
- assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(source, 2));
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(source, 0));
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(source, 2));
assertEquals(RubyPartitionScanner.RUBY_SINGLE_LINE_COMMENT, this.getContentType(source, 5));
}
public void testPoundCharacterIsntAComment() {
String source = "?#";
- assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(source, 1));
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(source, 1));
}
public void testSinglelineCommentJustAfterMultilineComment() {
@@ -114,13 +114,13 @@
assertEquals(RubyPartitionScanner.RUBY_SINGLE_LINE_COMMENT, this.getContentType(code, 6));
assertEquals(RubyPartitionScanner.RUBY_SINGLE_LINE_COMMENT, this.getContentType(code, 17));
- assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(code, 26));
- assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(code, 29));
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(code, 26));
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(code, 29));
}
public void testCommentAfterEnd() {
String code = "class Chris\nend # comment\n";
- assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(code, 12));
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(code, 12));
assertEquals(RubyPartitionScanner.RUBY_SINGLE_LINE_COMMENT, this.getContentType(code, 17));
}
@@ -134,7 +134,7 @@
" def thing\r\n" +
" end #ocmm \r\n" +
"end";
- assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(code, 76));
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(code, 76));
assertEquals(RubyPartitionScanner.RUBY_SINGLE_LINE_COMMENT, this.getContentType(code, 83));
}
@@ -144,16 +144,16 @@
" 123\n" +
" }\n" +
"}";
- assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(code, 0));
- assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(code, 4));
- assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(code, 6));
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(code, 0));
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(code, 4));
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(code, 6));
assertEquals(RubyPartitionScanner.RUBY_STRING, this.getContentType(code, 8));
assertEquals(RubyPartitionScanner.RUBY_STRING, this.getContentType(code, 12));
assertEquals(RubyPartitionScanner.RUBY_STRING, this.getContentType(code, 18));
- assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(code, 19));
- assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(code, 22));
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(code, 19));
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(code, 22));
assertEquals(RubyPartitionScanner.RUBY_SINGLE_LINE_COMMENT, this.getContentType(code, 25));
}
@@ -165,8 +165,8 @@
" \n" +
" end";
assertEquals(RubyPartitionScanner.RUBY_SINGLE_LINE_COMMENT, this.getContentType(code, 5));
- assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(code, 14));
- assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(code, 20));
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(code, 14));
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(code, 20));
}
public void testCommentsWithAlotOfPrecedingSpaces() {
@@ -174,7 +174,59 @@
" # caller-requested until.\n" +
"return self\n";
assertEquals(RubyPartitionScanner.RUBY_SINGLE_LINE_COMMENT, this.getContentType(code, 16));
- assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(code, 63));
- assertEquals(IDocument.DEFAULT_CONTENT_TYPE, this.getContentType(code, 70));
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(code, 63));
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(code, 70));
}
+
+ public void testCodeWithinString() {
+ String code = "string = \"here's some code: #{1} there\"";
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(code, 2)); // st'r'...
+ assertEquals(RubyPartitionScanner.RUBY_STRING, this.getContentType(code, 10)); // "'h'er...
+ assertEquals(RubyPartitionScanner.RUBY_STRING, this.getContentType(code, 28)); // '#'{1...
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(code, 30)); // '1'} t...
+ assertEquals(RubyPartitionScanner.RUBY_STRING, this.getContentType(code, 31)); // '}' th...
+ assertEquals(RubyPartitionScanner.RUBY_STRING, this.getContentType(code, 35)); // th'e're..
+ }
+
+ public void testCodeWithinSingleQuoteString() {
+ String code = "string = 'here s some code: #{1} there'";
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(code, 2)); // st'r'...
+ assertEquals(RubyPartitionScanner.RUBY_STRING, this.getContentType(code, 10)); // "'h'er...
+ assertEquals(RubyPartitionScanner.RUBY_STRING, this.getContentType(code, 28)); // '#'{1...
+ assertEquals(RubyPartitionScanner.RUBY_STRING, this.getContentType(code, 30)); // '1'} t...
+ assertEquals(RubyPartitionScanner.RUBY_STRING, this.getContentType(code, 31)); // '}' th...
+ assertEquals(RubyPartitionScanner.RUBY_STRING, this.getContentType(code, 35)); // th'e're..
+ }
+
+ public void testVariableSubstitutionWithinString() {
+ String code = "string = \"here's some code: #$global there\"";
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(code, 2)); // st'r'...
+ assertEquals(RubyPartitionScanner.RUBY_STRING, this.getContentType(code, 10)); // "'h'er...
+ assertEquals(RubyPartitionScanner.RUBY_STRING, this.getContentType(code, 28)); // '#'$glo...
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(code, 29)); // '$'global
+ assertEquals(RubyPartitionScanner.RUBY_STRING, this.getContentType(code, 36));// ' 'there...
+ }
+
+ public void testStringWithinCodeWithinString() {
+ String code = "string = \"here's some code: #{var = 'string'} there\"";
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(code, 2)); // st'r'...
+ assertEquals(RubyPartitionScanner.RUBY_STRING, this.getContentType(code, 10)); // "'h'er...
+ assertEquals(RubyPartitionScanner.RUBY_STRING, this.getContentType(code, 28)); // '#'{var
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(code, 30)); // 'v'ar =
+ assertEquals(RubyPartitionScanner.RUBY_STRING, this.getContentType(code, 36)); // '''string
+ assertEquals(RubyPartitionScanner.RUBY_STRING, this.getContentType(code, 46)); // 't'here
+ }
+
+ public void testStringWithEndBraceWithinCodeWithinString() {
+ String code = "string = \"here's some code: #{var = '}'; 1} there\"";
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(code, 2)); // st'r'...
+ assertEquals(RubyPartitionScanner.RUBY_STRING, this.getContentType(code, 10)); // "'h'er...
+ assertEquals(RubyPartitionScanner.RUBY_STRING, this.getContentType(code, 28)); // '#'{var
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(code, 30)); // 'v'ar =
+ assertEquals(RubyPartitionScanner.RUBY_STRING, this.getContentType(code, 37)); // '}';
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(code, 39)); // ';' 1}
+ assertEquals(RubyPartitionScanner.RUBY_DEFAULT, this.getContentType(code, 41)); // ; '1'}
+ assertEquals(RubyPartitionScanner.RUBY_STRING, this.getContentType(code, 42)); // 1'}' t
+ assertEquals(RubyPartitionScanner.RUBY_STRING, this.getContentType(code, 44)); // 't'here
+ }
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|