calabash-android 0.4.0.pre1 → 0.4.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. data/bin/calabash-android-build.rb +6 -0
  2. data/bin/calabash-android-setup.rb +2 -3
  3. data/lib/calabash-android/canned_steps.md +1 -1
  4. data/lib/calabash-android/helpers.rb +35 -2
  5. data/lib/calabash-android/lib/TestServer.apk +0 -0
  6. data/lib/calabash-android/operations.rb +13 -6
  7. data/lib/calabash-android/version.rb +1 -1
  8. data/test-server/instrumentation-backend/.classpath +2 -1
  9. data/test-server/instrumentation-backend/antlr.sh +2 -0
  10. data/test-server/instrumentation-backend/antlr/UIQuery.g +70 -0
  11. data/test-server/instrumentation-backend/antlr/UIQuery.tokens +12 -0
  12. data/test-server/instrumentation-backend/build-libs/antlr-3.4-complete.jar +0 -0
  13. data/test-server/instrumentation-backend/build-libs/junit.jar +0 -0
  14. data/test-server/instrumentation-backend/build.xml +56 -0
  15. data/test-server/instrumentation-backend/src/org/antlr/runtime/ANTLRFileStream.java +78 -0
  16. data/test-server/instrumentation-backend/src/org/antlr/runtime/ANTLRInputStream.java +70 -0
  17. data/test-server/instrumentation-backend/src/org/antlr/runtime/ANTLRReaderStream.java +95 -0
  18. data/test-server/instrumentation-backend/src/org/antlr/runtime/ANTLRStringStream.java +230 -0
  19. data/test-server/instrumentation-backend/src/org/antlr/runtime/BaseRecognizer.java +894 -0
  20. data/test-server/instrumentation-backend/src/org/antlr/runtime/BitSet.java +325 -0
  21. data/test-server/instrumentation-backend/src/org/antlr/runtime/BufferedTokenStream.java +272 -0
  22. data/test-server/instrumentation-backend/src/org/antlr/runtime/CharStream.java +57 -0
  23. data/test-server/instrumentation-backend/src/org/antlr/runtime/CharStreamState.java +45 -0
  24. data/test-server/instrumentation-backend/src/org/antlr/runtime/ClassicToken.java +141 -0
  25. data/test-server/instrumentation-backend/src/org/antlr/runtime/CommonToken.java +191 -0
  26. data/test-server/instrumentation-backend/src/org/antlr/runtime/CommonTokenStream.java +153 -0
  27. data/test-server/instrumentation-backend/src/org/antlr/runtime/DFA.java +250 -0
  28. data/test-server/instrumentation-backend/src/org/antlr/runtime/EarlyExitException.java +41 -0
  29. data/test-server/instrumentation-backend/src/org/antlr/runtime/FailedPredicateException.java +54 -0
  30. data/test-server/instrumentation-backend/src/org/antlr/runtime/IntStream.java +122 -0
  31. data/test-server/instrumentation-backend/src/org/antlr/runtime/LegacyCommonTokenStream.java +394 -0
  32. data/test-server/instrumentation-backend/src/org/antlr/runtime/Lexer.java +340 -0
  33. data/test-server/instrumentation-backend/src/org/antlr/runtime/MismatchedNotSetException.java +41 -0
  34. data/test-server/instrumentation-backend/src/org/antlr/runtime/MismatchedRangeException.java +45 -0
  35. data/test-server/instrumentation-backend/src/org/antlr/runtime/MismatchedSetException.java +44 -0
  36. data/test-server/instrumentation-backend/src/org/antlr/runtime/MismatchedTokenException.java +45 -0
  37. data/test-server/instrumentation-backend/src/org/antlr/runtime/MismatchedTreeNodeException.java +49 -0
  38. data/test-server/instrumentation-backend/src/org/antlr/runtime/MissingTokenException.java +56 -0
  39. data/test-server/instrumentation-backend/src/org/antlr/runtime/NoViableAltException.java +57 -0
  40. data/test-server/instrumentation-backend/src/org/antlr/runtime/Parser.java +98 -0
  41. data/test-server/instrumentation-backend/src/org/antlr/runtime/ParserRuleReturnScope.java +52 -0
  42. data/test-server/instrumentation-backend/src/org/antlr/runtime/RecognitionException.java +180 -0
  43. data/test-server/instrumentation-backend/src/org/antlr/runtime/RecognizerSharedState.java +144 -0
  44. data/test-server/instrumentation-backend/src/org/antlr/runtime/RuleReturnScope.java +42 -0
  45. data/test-server/instrumentation-backend/src/org/antlr/runtime/SerializedGrammar.java +204 -0
  46. data/test-server/instrumentation-backend/src/org/antlr/runtime/Token.java +92 -0
  47. data/test-server/instrumentation-backend/src/org/antlr/runtime/TokenRewriteStream.java +569 -0
  48. data/test-server/instrumentation-backend/src/org/antlr/runtime/TokenSource.java +54 -0
  49. data/test-server/instrumentation-backend/src/org/antlr/runtime/TokenStream.java +75 -0
  50. data/test-server/instrumentation-backend/src/org/antlr/runtime/UnbufferedTokenStream.java +82 -0
  51. data/test-server/instrumentation-backend/src/org/antlr/runtime/UnwantedTokenException.java +53 -0
  52. data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/BlankDebugEventListener.java +77 -0
  53. data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/DebugEventHub.java +292 -0
  54. data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/DebugEventListener.java +323 -0
  55. data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/DebugEventRepeater.java +88 -0
  56. data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/DebugEventSocketProxy.java +358 -0
  57. data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/DebugParser.java +101 -0
  58. data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/DebugTokenStream.java +156 -0
  59. data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/DebugTreeAdaptor.java +250 -0
  60. data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/DebugTreeNodeStream.java +155 -0
  61. data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/DebugTreeParser.java +112 -0
  62. data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/ParseTreeBuilder.java +109 -0
  63. data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/Profiler.java +772 -0
  64. data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/RemoteDebugEventSocketListener.java +541 -0
  65. data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/TraceDebugEventListener.java +108 -0
  66. data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/Tracer.java +69 -0
  67. data/test-server/instrumentation-backend/src/org/antlr/runtime/misc/DoubleKeyMap.java +62 -0
  68. data/test-server/instrumentation-backend/src/org/antlr/runtime/misc/FastQueue.java +100 -0
  69. data/test-server/instrumentation-backend/src/org/antlr/runtime/misc/IntArray.java +87 -0
  70. data/test-server/instrumentation-backend/src/org/antlr/runtime/misc/LookaheadStream.java +161 -0
  71. data/test-server/instrumentation-backend/src/org/antlr/runtime/misc/Stats.java +189 -0
  72. data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/BaseTree.java +349 -0
  73. data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/BaseTreeAdaptor.java +279 -0
  74. data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/BufferedTreeNodeStream.java +489 -0
  75. data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/CommonErrorNode.java +108 -0
  76. data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/CommonTree.java +185 -0
  77. data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/CommonTreeAdaptor.java +168 -0
  78. data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/CommonTreeNodeStream.java +171 -0
  79. data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/ParseTree.java +119 -0
  80. data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/RewriteCardinalityException.java +47 -0
  81. data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/RewriteEarlyExitException.java +39 -0
  82. data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/RewriteEmptyStreamException.java +35 -0
  83. data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/RewriteRuleElementStream.java +210 -0
  84. data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/RewriteRuleNodeStream.java +70 -0
  85. data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/RewriteRuleSubtreeStream.java +86 -0
  86. data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/RewriteRuleTokenStream.java +76 -0
  87. data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/Tree.java +127 -0
  88. data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreeAdaptor.java +263 -0
  89. data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreeFilter.java +135 -0
  90. data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreeIterator.java +132 -0
  91. data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreeNodeStream.java +106 -0
  92. data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreeParser.java +169 -0
  93. data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreePatternLexer.java +135 -0
  94. data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreePatternParser.java +154 -0
  95. data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreeRewriter.java +124 -0
  96. data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreeRuleReturnScope.java +41 -0
  97. data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreeVisitor.java +69 -0
  98. data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreeVisitorAction.java +47 -0
  99. data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreeWizard.java +531 -0
  100. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/ClearAppData.java +22 -7
  101. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/InstrumentationBackend.java +4 -4
  102. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/Result.java +0 -1
  103. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/HttpServer.java +161 -129
  104. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/activity/SetActivityOrientation.java +5 -7
  105. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/view/GetViewProperty.java +1 -7
  106. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/Query.java +70 -61
  107. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/UIQuery.tokens +12 -0
  108. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ViewMapper.java +63 -0
  109. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/antlr/UIQuery.tokens +10 -0
  110. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/antlr/UIQueryLexer.java +945 -0
  111. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/antlr/UIQueryParser.java +463 -0
  112. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/InvalidUIQueryException.java +10 -0
  113. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryAST.java +8 -0
  114. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryASTClassName.java +115 -0
  115. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryASTWith.java +157 -0
  116. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryDirection.java +5 -0
  117. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryEvaluator.java +205 -0
  118. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryUtils.java +135 -0
  119. data/test-server/instrumentation-backend/tests/sh/calaba/instrumentationbackend/query/tests/UIQueryTest.java +134 -0
  120. metadata +106 -3
  121. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/activity/SetOrientation.java +0 -39
@@ -0,0 +1,92 @@
1
+ /*
2
+ [The "BSD license"]
3
+ Copyright (c) 2005-2009 Terence Parr
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions
8
+ are met:
9
+ 1. Redistributions of source code must retain the above copyright
10
+ notice, this list of conditions and the following disclaimer.
11
+ 2. Redistributions in binary form must reproduce the above copyright
12
+ notice, this list of conditions and the following disclaimer in the
13
+ documentation and/or other materials provided with the distribution.
14
+ 3. The name of the author may not be used to endorse or promote products
15
+ derived from this software without specific prior written permission.
16
+
17
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ */
28
+ package org.antlr.runtime;
29
+
30
+ public interface Token {
31
+ public static final int EOR_TOKEN_TYPE = 1;
32
+
33
+ /** imaginary tree navigation type; traverse "get child" link */
34
+ public static final int DOWN = 2;
35
+ /** imaginary tree navigation type; finish with a child list */
36
+ public static final int UP = 3;
37
+
38
+ public static final int MIN_TOKEN_TYPE = UP+1;
39
+
40
+ public static final int EOF = CharStream.EOF;
41
+ // TODO: remove once we go ANTLR v3.3
42
+ public static final Token EOF_TOKEN = new CommonToken(EOF);
43
+
44
+ public static final int INVALID_TOKEN_TYPE = 0;
45
+ public static final Token INVALID_TOKEN = new CommonToken(INVALID_TOKEN_TYPE);
46
+
47
+ /** In an action, a lexer rule can set token to this SKIP_TOKEN and ANTLR
48
+ * will avoid creating a token for this symbol and try to fetch another.
49
+ */
50
+ public static final Token SKIP_TOKEN = new CommonToken(INVALID_TOKEN_TYPE);
51
+
52
+ /** All tokens go to the parser (unless skip() is called in that rule)
53
+ * on a particular "channel". The parser tunes to a particular channel
54
+ * so that whitespace etc... can go to the parser on a "hidden" channel.
55
+ */
56
+ public static final int DEFAULT_CHANNEL = 0;
57
+
58
+ /** Anything on different channel than DEFAULT_CHANNEL is not parsed
59
+ * by parser.
60
+ */
61
+ public static final int HIDDEN_CHANNEL = 99;
62
+
63
+ /** Get the text of the token */
64
+ public String getText();
65
+ public void setText(String text);
66
+
67
+ public int getType();
68
+ public void setType(int ttype);
69
+ /** The line number on which this token was matched; line=1..n */
70
+ public int getLine();
71
+ public void setLine(int line);
72
+
73
+ /** The index of the first character relative to the beginning of the line 0..n-1 */
74
+ public int getCharPositionInLine();
75
+ public void setCharPositionInLine(int pos);
76
+
77
+ public int getChannel();
78
+ public void setChannel(int channel);
79
+
80
+ /** An index from 0..n-1 of the token object in the input stream.
81
+ * This must be valid in order to use the ANTLRWorks debugger.
82
+ */
83
+ public int getTokenIndex();
84
+ public void setTokenIndex(int index);
85
+
86
+ /** From what character stream was this token created? You don't have to
87
+ * implement but it's nice to know where a Token comes from if you have
88
+ * include files etc... on the input.
89
+ */
90
+ public CharStream getInputStream();
91
+ public void setInputStream(CharStream input);
92
+ }
@@ -0,0 +1,569 @@
1
+ /*
2
+ [The "BSD license"]
3
+ Copyright (c) 2005-2009 Terence Parr
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions
8
+ are met:
9
+ 1. Redistributions of source code must retain the above copyright
10
+ notice, this list of conditions and the following disclaimer.
11
+ 2. Redistributions in binary form must reproduce the above copyright
12
+ notice, this list of conditions and the following disclaimer in the
13
+ documentation and/or other materials provided with the distribution.
14
+ 3. The name of the author may not be used to endorse or promote products
15
+ derived from this software without specific prior written permission.
16
+
17
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ */
28
+ package org.antlr.runtime;
29
+
30
+ import java.util.*;
31
+
32
+ /** Useful for dumping out the input stream after doing some
33
+ * augmentation or other manipulations.
34
+ *
35
+ * You can insert stuff, replace, and delete chunks. Note that the
36
+ * operations are done lazily--only if you convert the buffer to a
37
+ * String. This is very efficient because you are not moving data around
38
+ * all the time. As the buffer of tokens is converted to strings, the
39
+ * toString() method(s) check to see if there is an operation at the
40
+ * current index. If so, the operation is done and then normal String
41
+ * rendering continues on the buffer. This is like having multiple Turing
42
+ * machine instruction streams (programs) operating on a single input tape. :)
43
+ *
44
+ * Since the operations are done lazily at toString-time, operations do not
45
+ * screw up the token index values. That is, an insert operation at token
46
+ * index i does not change the index values for tokens i+1..n-1.
47
+ *
48
+ * Because operations never actually alter the buffer, you may always get
49
+ * the original token stream back without undoing anything. Since
50
+ * the instructions are queued up, you can easily simulate transactions and
51
+ * roll back any changes if there is an error just by removing instructions.
52
+ * For example,
53
+ *
54
+ * CharStream input = new ANTLRFileStream("input");
55
+ * TLexer lex = new TLexer(input);
56
+ * TokenRewriteStream tokens = new TokenRewriteStream(lex);
57
+ * T parser = new T(tokens);
58
+ * parser.startRule();
59
+ *
60
+ * Then in the rules, you can execute
61
+ * Token t,u;
62
+ * ...
63
+ * input.insertAfter(t, "text to put after t");}
64
+ * input.insertAfter(u, "text after u");}
65
+ * System.out.println(tokens.toString());
66
+ *
67
+ * Actually, you have to cast the 'input' to a TokenRewriteStream. :(
68
+ *
69
+ * You can also have multiple "instruction streams" and get multiple
70
+ * rewrites from a single pass over the input. Just name the instruction
71
+ * streams and use that name again when printing the buffer. This could be
72
+ * useful for generating a C file and also its header file--all from the
73
+ * same buffer:
74
+ *
75
+ * tokens.insertAfter("pass1", t, "text to put after t");}
76
+ * tokens.insertAfter("pass2", u, "text after u");}
77
+ * System.out.println(tokens.toString("pass1"));
78
+ * System.out.println(tokens.toString("pass2"));
79
+ *
80
+ * If you don't use named rewrite streams, a "default" stream is used as
81
+ * the first example shows.
82
+ */
83
+ public class TokenRewriteStream extends CommonTokenStream {
84
+ public static final String DEFAULT_PROGRAM_NAME = "default";
85
+ public static final int PROGRAM_INIT_SIZE = 100;
86
+ public static final int MIN_TOKEN_INDEX = 0;
87
+
88
+ // Define the rewrite operation hierarchy
89
+
90
+ class RewriteOperation {
91
+ /** What index into rewrites List are we? */
92
+ protected int instructionIndex;
93
+ /** Token buffer index. */
94
+ protected int index;
95
+ protected Object text;
96
+ protected RewriteOperation(int index, Object text) {
97
+ this.index = index;
98
+ this.text = text;
99
+ }
100
+ /** Execute the rewrite operation by possibly adding to the buffer.
101
+ * Return the index of the next token to operate on.
102
+ */
103
+ public int execute(StringBuffer buf) {
104
+ return index;
105
+ }
106
+ public String toString() {
107
+ String opName = getClass().getName();
108
+ int $index = opName.indexOf('$');
109
+ opName = opName.substring($index+1, opName.length());
110
+ return "<"+opName+"@"+index+":\""+text+"\">";
111
+ }
112
+ }
113
+
114
+ class InsertBeforeOp extends RewriteOperation {
115
+ public InsertBeforeOp(int index, Object text) {
116
+ super(index,text);
117
+ }
118
+ public int execute(StringBuffer buf) {
119
+ buf.append(text);
120
+ if ( tokens.get(index).getType()!=Token.EOF ) buf.append(tokens.get(index).getText());
121
+ return index+1;
122
+ }
123
+ }
124
+
125
+ /** I'm going to try replacing range from x..y with (y-x)+1 ReplaceOp
126
+ * instructions.
127
+ */
128
+ class ReplaceOp extends RewriteOperation {
129
+ protected int lastIndex;
130
+ public ReplaceOp(int from, int to, Object text) {
131
+ super(from,text);
132
+ lastIndex = to;
133
+ }
134
+ public int execute(StringBuffer buf) {
135
+ if ( text!=null ) {
136
+ buf.append(text);
137
+ }
138
+ return lastIndex+1;
139
+ }
140
+ public String toString() {
141
+ return "<ReplaceOp@"+index+".."+lastIndex+":\""+text+"\">";
142
+ }
143
+ }
144
+
145
+ class DeleteOp extends ReplaceOp {
146
+ public DeleteOp(int from, int to) {
147
+ super(from, to, null);
148
+ }
149
+ public String toString() {
150
+ return "<DeleteOp@"+index+".."+lastIndex+">";
151
+ }
152
+ }
153
+
154
+ /** You may have multiple, named streams of rewrite operations.
155
+ * I'm calling these things "programs."
156
+ * Maps String (name) -> rewrite (List)
157
+ */
158
+ protected Map programs = null;
159
+
160
+ /** Map String (program name) -> Integer index */
161
+ protected Map lastRewriteTokenIndexes = null;
162
+
163
+ public TokenRewriteStream() {
164
+ init();
165
+ }
166
+
167
+ protected void init() {
168
+ programs = new HashMap();
169
+ programs.put(DEFAULT_PROGRAM_NAME, new ArrayList(PROGRAM_INIT_SIZE));
170
+ lastRewriteTokenIndexes = new HashMap();
171
+ }
172
+
173
+ public TokenRewriteStream(TokenSource tokenSource) {
174
+ super(tokenSource);
175
+ init();
176
+ }
177
+
178
+ public TokenRewriteStream(TokenSource tokenSource, int channel) {
179
+ super(tokenSource, channel);
180
+ init();
181
+ }
182
+
183
+ public void rollback(int instructionIndex) {
184
+ rollback(DEFAULT_PROGRAM_NAME, instructionIndex);
185
+ }
186
+
187
+ /** Rollback the instruction stream for a program so that
188
+ * the indicated instruction (via instructionIndex) is no
189
+ * longer in the stream. UNTESTED!
190
+ */
191
+ public void rollback(String programName, int instructionIndex) {
192
+ List is = (List)programs.get(programName);
193
+ if ( is!=null ) {
194
+ programs.put(programName, is.subList(MIN_TOKEN_INDEX,instructionIndex));
195
+ }
196
+ }
197
+
198
+ public void deleteProgram() {
199
+ deleteProgram(DEFAULT_PROGRAM_NAME);
200
+ }
201
+
202
+ /** Reset the program so that no instructions exist */
203
+ public void deleteProgram(String programName) {
204
+ rollback(programName, MIN_TOKEN_INDEX);
205
+ }
206
+
207
+ public void insertAfter(Token t, Object text) {
208
+ insertAfter(DEFAULT_PROGRAM_NAME, t, text);
209
+ }
210
+
211
+ public void insertAfter(int index, Object text) {
212
+ insertAfter(DEFAULT_PROGRAM_NAME, index, text);
213
+ }
214
+
215
+ public void insertAfter(String programName, Token t, Object text) {
216
+ insertAfter(programName,t.getTokenIndex(), text);
217
+ }
218
+
219
+ public void insertAfter(String programName, int index, Object text) {
220
+ // to insert after, just insert before next index (even if past end)
221
+ insertBefore(programName,index+1, text);
222
+ //addToSortedRewriteList(programName, new InsertAfterOp(index,text));
223
+ }
224
+
225
+ public void insertBefore(Token t, Object text) {
226
+ insertBefore(DEFAULT_PROGRAM_NAME, t, text);
227
+ }
228
+
229
+ public void insertBefore(int index, Object text) {
230
+ insertBefore(DEFAULT_PROGRAM_NAME, index, text);
231
+ }
232
+
233
+ public void insertBefore(String programName, Token t, Object text) {
234
+ insertBefore(programName, t.getTokenIndex(), text);
235
+ }
236
+
237
+ public void insertBefore(String programName, int index, Object text) {
238
+ //addToSortedRewriteList(programName, new InsertBeforeOp(index,text));
239
+ RewriteOperation op = new InsertBeforeOp(index,text);
240
+ List rewrites = getProgram(programName);
241
+ op.instructionIndex = rewrites.size();
242
+ rewrites.add(op);
243
+ }
244
+
245
+ public void replace(int index, Object text) {
246
+ replace(DEFAULT_PROGRAM_NAME, index, index, text);
247
+ }
248
+
249
+ public void replace(int from, int to, Object text) {
250
+ replace(DEFAULT_PROGRAM_NAME, from, to, text);
251
+ }
252
+
253
+ public void replace(Token indexT, Object text) {
254
+ replace(DEFAULT_PROGRAM_NAME, indexT, indexT, text);
255
+ }
256
+
257
+ public void replace(Token from, Token to, Object text) {
258
+ replace(DEFAULT_PROGRAM_NAME, from, to, text);
259
+ }
260
+
261
+ public void replace(String programName, int from, int to, Object text) {
262
+ if ( from > to || from<0 || to<0 || to >= tokens.size() ) {
263
+ throw new IllegalArgumentException("replace: range invalid: "+from+".."+to+"(size="+tokens.size()+")");
264
+ }
265
+ RewriteOperation op = new ReplaceOp(from, to, text);
266
+ List rewrites = getProgram(programName);
267
+ op.instructionIndex = rewrites.size();
268
+ rewrites.add(op);
269
+ }
270
+
271
+ public void replace(String programName, Token from, Token to, Object text) {
272
+ replace(programName,
273
+ from.getTokenIndex(),
274
+ to.getTokenIndex(),
275
+ text);
276
+ }
277
+
278
+ public void delete(int index) {
279
+ delete(DEFAULT_PROGRAM_NAME, index, index);
280
+ }
281
+
282
+ public void delete(int from, int to) {
283
+ delete(DEFAULT_PROGRAM_NAME, from, to);
284
+ }
285
+
286
+ public void delete(Token indexT) {
287
+ delete(DEFAULT_PROGRAM_NAME, indexT, indexT);
288
+ }
289
+
290
+ public void delete(Token from, Token to) {
291
+ delete(DEFAULT_PROGRAM_NAME, from, to);
292
+ }
293
+
294
+ public void delete(String programName, int from, int to) {
295
+ replace(programName,from,to,null);
296
+ }
297
+
298
+ public void delete(String programName, Token from, Token to) {
299
+ replace(programName,from,to,null);
300
+ }
301
+
302
+ public int getLastRewriteTokenIndex() {
303
+ return getLastRewriteTokenIndex(DEFAULT_PROGRAM_NAME);
304
+ }
305
+
306
+ protected int getLastRewriteTokenIndex(String programName) {
307
+ Integer I = (Integer)lastRewriteTokenIndexes.get(programName);
308
+ if ( I==null ) {
309
+ return -1;
310
+ }
311
+ return I.intValue();
312
+ }
313
+
314
+ protected void setLastRewriteTokenIndex(String programName, int i) {
315
+ lastRewriteTokenIndexes.put(programName, new Integer(i));
316
+ }
317
+
318
+ protected List getProgram(String name) {
319
+ List is = (List)programs.get(name);
320
+ if ( is==null ) {
321
+ is = initializeProgram(name);
322
+ }
323
+ return is;
324
+ }
325
+
326
+ private List initializeProgram(String name) {
327
+ List is = new ArrayList(PROGRAM_INIT_SIZE);
328
+ programs.put(name, is);
329
+ return is;
330
+ }
331
+
332
+ public String toOriginalString() {
333
+ fill();
334
+ return toOriginalString(MIN_TOKEN_INDEX, size()-1);
335
+ }
336
+
337
+ public String toOriginalString(int start, int end) {
338
+ StringBuffer buf = new StringBuffer();
339
+ for (int i=start; i>=MIN_TOKEN_INDEX && i<=end && i<tokens.size(); i++) {
340
+ if ( get(i).getType()!=Token.EOF ) buf.append(get(i).getText());
341
+ }
342
+ return buf.toString();
343
+ }
344
+
345
+ public String toString() {
346
+ fill();
347
+ return toString(MIN_TOKEN_INDEX, size()-1);
348
+ }
349
+
350
+ public String toString(String programName) {
351
+ fill();
352
+ return toString(programName, MIN_TOKEN_INDEX, size()-1);
353
+ }
354
+
355
+ public String toString(int start, int end) {
356
+ return toString(DEFAULT_PROGRAM_NAME, start, end);
357
+ }
358
+
359
+ public String toString(String programName, int start, int end) {
360
+ List rewrites = (List)programs.get(programName);
361
+
362
+ // ensure start/end are in range
363
+ if ( end>tokens.size()-1 ) end = tokens.size()-1;
364
+ if ( start<0 ) start = 0;
365
+
366
+ if ( rewrites==null || rewrites.size()==0 ) {
367
+ return toOriginalString(start,end); // no instructions to execute
368
+ }
369
+ StringBuffer buf = new StringBuffer();
370
+
371
+ // First, optimize instruction stream
372
+ Map indexToOp = reduceToSingleOperationPerIndex(rewrites);
373
+
374
+ // Walk buffer, executing instructions and emitting tokens
375
+ int i = start;
376
+ while ( i <= end && i < tokens.size() ) {
377
+ RewriteOperation op = (RewriteOperation)indexToOp.get(new Integer(i));
378
+ indexToOp.remove(new Integer(i)); // remove so any left have index size-1
379
+ Token t = (Token) tokens.get(i);
380
+ if ( op==null ) {
381
+ // no operation at that index, just dump token
382
+ if ( t.getType()!=Token.EOF ) buf.append(t.getText());
383
+ i++; // move to next token
384
+ }
385
+ else {
386
+ i = op.execute(buf); // execute operation and skip
387
+ }
388
+ }
389
+
390
+ // include stuff after end if it's last index in buffer
391
+ // So, if they did an insertAfter(lastValidIndex, "foo"), include
392
+ // foo if end==lastValidIndex.
393
+ if ( end==tokens.size()-1 ) {
394
+ // Scan any remaining operations after last token
395
+ // should be included (they will be inserts).
396
+ Iterator it = indexToOp.values().iterator();
397
+ while (it.hasNext()) {
398
+ RewriteOperation op = (RewriteOperation)it.next();
399
+ if ( op.index >= tokens.size()-1 ) buf.append(op.text);
400
+ }
401
+ }
402
+ return buf.toString();
403
+ }
404
+
405
+ /** We need to combine operations and report invalid operations (like
406
+ * overlapping replaces that are not completed nested). Inserts to
407
+ * same index need to be combined etc... Here are the cases:
408
+ *
409
+ * I.i.u I.j.v leave alone, nonoverlapping
410
+ * I.i.u I.i.v combine: Iivu
411
+ *
412
+ * R.i-j.u R.x-y.v | i-j in x-y delete first R
413
+ * R.i-j.u R.i-j.v delete first R
414
+ * R.i-j.u R.x-y.v | x-y in i-j ERROR
415
+ * R.i-j.u R.x-y.v | boundaries overlap ERROR
416
+ *
417
+ * I.i.u R.x-y.v | i in x-y delete I
418
+ * I.i.u R.x-y.v | i not in x-y leave alone, nonoverlapping
419
+ * R.x-y.v I.i.u | i in x-y ERROR
420
+ * R.x-y.v I.x.u R.x-y.uv (combine, delete I)
421
+ * R.x-y.v I.i.u | i not in x-y leave alone, nonoverlapping
422
+ *
423
+ * I.i.u = insert u before op @ index i
424
+ * R.x-y.u = replace x-y indexed tokens with u
425
+ *
426
+ * First we need to examine replaces. For any replace op:
427
+ *
428
+ * 1. wipe out any insertions before op within that range.
429
+ * 2. Drop any replace op before that is contained completely within
430
+ * that range.
431
+ * 3. Throw exception upon boundary overlap with any previous replace.
432
+ *
433
+ * Then we can deal with inserts:
434
+ *
435
+ * 1. for any inserts to same index, combine even if not adjacent.
436
+ * 2. for any prior replace with same left boundary, combine this
437
+ * insert with replace and delete this replace.
438
+ * 3. throw exception if index in same range as previous replace
439
+ *
440
+ * Don't actually delete; make op null in list. Easier to walk list.
441
+ * Later we can throw as we add to index -> op map.
442
+ *
443
+ * Note that I.2 R.2-2 will wipe out I.2 even though, technically, the
444
+ * inserted stuff would be before the replace range. But, if you
445
+ * add tokens in front of a method body '{' and then delete the method
446
+ * body, I think the stuff before the '{' you added should disappear too.
447
+ *
448
+ * Return a map from token index to operation.
449
+ */
450
+ protected Map reduceToSingleOperationPerIndex(List rewrites) {
451
+ //System.out.println("rewrites="+rewrites);
452
+
453
+ // WALK REPLACES
454
+ for (int i = 0; i < rewrites.size(); i++) {
455
+ RewriteOperation op = (RewriteOperation)rewrites.get(i);
456
+ if ( op==null ) continue;
457
+ if ( !(op instanceof ReplaceOp) ) continue;
458
+ ReplaceOp rop = (ReplaceOp)rewrites.get(i);
459
+ // Wipe prior inserts within range
460
+ List inserts = getKindOfOps(rewrites, InsertBeforeOp.class, i);
461
+ for (int j = 0; j < inserts.size(); j++) {
462
+ InsertBeforeOp iop = (InsertBeforeOp) inserts.get(j);
463
+ if ( iop.index >= rop.index && iop.index <= rop.lastIndex ) {
464
+ // delete insert as it's a no-op.
465
+ rewrites.set(iop.instructionIndex, null);
466
+ }
467
+ }
468
+ // Drop any prior replaces contained within
469
+ List prevReplaces = getKindOfOps(rewrites, ReplaceOp.class, i);
470
+ for (int j = 0; j < prevReplaces.size(); j++) {
471
+ ReplaceOp prevRop = (ReplaceOp) prevReplaces.get(j);
472
+ if ( prevRop.index>=rop.index && prevRop.lastIndex <= rop.lastIndex ) {
473
+ // delete replace as it's a no-op.
474
+ rewrites.set(prevRop.instructionIndex, null);
475
+ continue;
476
+ }
477
+ // throw exception unless disjoint or identical
478
+ boolean disjoint =
479
+ prevRop.lastIndex<rop.index || prevRop.index > rop.lastIndex;
480
+ boolean same =
481
+ prevRop.index==rop.index && prevRop.lastIndex==rop.lastIndex;
482
+ if ( !disjoint && !same ) {
483
+ throw new IllegalArgumentException("replace op boundaries of "+rop+
484
+ " overlap with previous "+prevRop);
485
+ }
486
+ }
487
+ }
488
+
489
+ // WALK INSERTS
490
+ for (int i = 0; i < rewrites.size(); i++) {
491
+ RewriteOperation op = (RewriteOperation)rewrites.get(i);
492
+ if ( op==null ) continue;
493
+ if ( !(op instanceof InsertBeforeOp) ) continue;
494
+ InsertBeforeOp iop = (InsertBeforeOp)rewrites.get(i);
495
+ // combine current insert with prior if any at same index
496
+ List prevInserts = getKindOfOps(rewrites, InsertBeforeOp.class, i);
497
+ for (int j = 0; j < prevInserts.size(); j++) {
498
+ InsertBeforeOp prevIop = (InsertBeforeOp) prevInserts.get(j);
499
+ if ( prevIop.index == iop.index ) { // combine objects
500
+ // convert to strings...we're in process of toString'ing
501
+ // whole token buffer so no lazy eval issue with any templates
502
+ iop.text = catOpText(iop.text,prevIop.text);
503
+ // delete redundant prior insert
504
+ rewrites.set(prevIop.instructionIndex, null);
505
+ }
506
+ }
507
+ // look for replaces where iop.index is in range; error
508
+ List prevReplaces = getKindOfOps(rewrites, ReplaceOp.class, i);
509
+ for (int j = 0; j < prevReplaces.size(); j++) {
510
+ ReplaceOp rop = (ReplaceOp) prevReplaces.get(j);
511
+ if ( iop.index == rop.index ) {
512
+ rop.text = catOpText(iop.text,rop.text);
513
+ rewrites.set(i, null); // delete current insert
514
+ continue;
515
+ }
516
+ if ( iop.index >= rop.index && iop.index <= rop.lastIndex ) {
517
+ throw new IllegalArgumentException("insert op "+iop+
518
+ " within boundaries of previous "+rop);
519
+ }
520
+ }
521
+ }
522
+ // System.out.println("rewrites after="+rewrites);
523
+ Map m = new HashMap();
524
+ for (int i = 0; i < rewrites.size(); i++) {
525
+ RewriteOperation op = (RewriteOperation)rewrites.get(i);
526
+ if ( op==null ) continue; // ignore deleted ops
527
+ if ( m.get(new Integer(op.index))!=null ) {
528
+ throw new Error("should only be one op per index");
529
+ }
530
+ m.put(new Integer(op.index), op);
531
+ }
532
+ //System.out.println("index to op: "+m);
533
+ return m;
534
+ }
535
+
536
+ protected String catOpText(Object a, Object b) {
537
+ String x = "";
538
+ String y = "";
539
+ if ( a!=null ) x = a.toString();
540
+ if ( b!=null ) y = b.toString();
541
+ return x+y;
542
+ }
543
+ protected List getKindOfOps(List rewrites, Class kind) {
544
+ return getKindOfOps(rewrites, kind, rewrites.size());
545
+ }
546
+
547
+ /** Get all operations before an index of a particular kind */
548
+ protected List getKindOfOps(List rewrites, Class kind, int before) {
549
+ List ops = new ArrayList();
550
+ for (int i=0; i<before && i<rewrites.size(); i++) {
551
+ RewriteOperation op = (RewriteOperation)rewrites.get(i);
552
+ if ( op==null ) continue; // ignore deleted
553
+ if ( op.getClass() == kind ) ops.add(op);
554
+ }
555
+ return ops;
556
+ }
557
+
558
+ public String toDebugString() {
559
+ return toDebugString(MIN_TOKEN_INDEX, size()-1);
560
+ }
561
+
562
+ public String toDebugString(int start, int end) {
563
+ StringBuffer buf = new StringBuffer();
564
+ for (int i=start; i>=MIN_TOKEN_INDEX && i<=end && i<tokens.size(); i++) {
565
+ buf.append(get(i));
566
+ }
567
+ return buf.toString();
568
+ }
569
+ }