@@ -10,8 +10,6 @@ var CommandRepl = require('../modes/commandRepl');
10
10
*/
11
11
var WdRepl = function ( ) {
12
12
this . client = new baseDebugger . Client ( ) ;
13
- this . replServer ;
14
- this . cmdRepl ;
15
13
} ;
16
14
17
15
/**
@@ -36,45 +34,122 @@ WdRepl.prototype.initClient_ = function() {
36
34
} ;
37
35
38
36
/**
39
- * Eval function for processing a single step in repl.
37
+ * Instantiate a server to handle IO.
38
+ * @param {number } port The port to start the server.
40
39
* @private
41
- * @param {string } cmd
42
- * @param {object } context
43
- * @param {string } filename
44
- * @param {function } callback
45
40
*/
46
- WdRepl . prototype . stepEval_ = function ( cmd , context , filename , callback ) {
47
- cmd = cmd . slice ( 1 , cmd . length - 2 ) ;
48
- this . cmdRepl . stepEval ( cmd , callback ) ;
41
+ WdRepl . prototype . initServer_ = function ( port ) {
42
+ var net = require ( 'net' ) ;
43
+ var self = this ;
44
+ var cmdRepl = new CommandRepl ( this . client ) ;
45
+
46
+ var received = '' ;
47
+ net . createServer ( function ( sock ) {
48
+ sock . on ( 'data' , function ( data ) {
49
+ received += data . toString ( ) ;
50
+ var eolIndex = received . indexOf ( '\r\n' ) ;
51
+ if ( eolIndex === 0 ) {
52
+ return ;
53
+ }
54
+ var input = received . substring ( 0 , eolIndex ) ;
55
+ received = received . substring ( eolIndex + 2 ) ;
56
+ if ( data [ 0 ] === 0x1D ) {
57
+ // '^]': term command
58
+ self . client . req ( { command : 'disconnect' } , function ( ) {
59
+ // Intentionally blank.
60
+ } ) ;
61
+ sock . end ( ) ;
62
+ } else if ( input [ input . length - 1 ] === '\t' ) {
63
+ // If the last character is the TAB key, this is an autocomplete
64
+ // request. We use everything before the TAB as the init data to feed
65
+ // into autocomplete.
66
+ input = input . substring ( 0 , input . length - 1 ) ;
67
+ cmdRepl . complete ( input , function ( err , res ) {
68
+ if ( err ) {
69
+ sock . write ( 'ERROR: ' + err + '\r\n' ) ;
70
+ } else {
71
+ sock . write ( JSON . stringify ( res ) + '\r\n' ) ;
72
+ }
73
+ } ) ;
74
+ } else {
75
+ // Normal input
76
+ input = input . trim ( ) ;
77
+ cmdRepl . stepEval ( input , function ( err , res ) {
78
+ if ( err ) {
79
+ sock . write ( 'ERROR: ' + err + '\r\n' ) ;
80
+ return ;
81
+ }
82
+ if ( res === undefined ) {
83
+ res = '' ;
84
+ }
85
+ sock . write ( res + '\r\n' ) ;
86
+ } ) ;
87
+ }
88
+ } ) ;
89
+ } ) . listen ( port ) ;
90
+
91
+ console . log ( 'Server listening on 127.0.0.1:' + port ) ;
49
92
} ;
50
93
51
94
/**
52
- * Instantiate all repl objects, and debuggerRepl as current and start repl .
95
+ * Instantiate a repl to handle IO .
53
96
* @private
54
97
*/
55
98
WdRepl . prototype . initRepl_ = function ( ) {
56
99
var self = this ;
57
- this . cmdRepl = new CommandRepl ( this . client ) ;
100
+ var cmdRepl = new CommandRepl ( this . client ) ;
101
+
102
+ // Eval function for processing a single step in repl.
103
+ var stepEval = function ( cmd , context , filename , callback ) {
104
+ // The command that eval feeds is of the form '(CMD\n)', so we trim the
105
+ // double quotes and new line.
106
+ cmd = cmd . slice ( 1 , cmd . length - 2 ) ;
107
+ cmdRepl . stepEval ( cmd , function ( err , res ) {
108
+ // Result is a string representation of the evaluation.
109
+ if ( res !== undefined ) {
110
+ console . log ( res ) ;
111
+ }
112
+ callback ( err , undefined ) ;
113
+ } ) ;
114
+ } ;
58
115
59
- self . replServer = repl . start ( {
60
- prompt : self . cmdRepl . prompt ,
116
+ var replServer = repl . start ( {
117
+ prompt : cmdRepl . prompt ,
61
118
input : process . stdin ,
62
119
output : process . stdout ,
63
- eval : self . stepEval_ . bind ( self ) ,
120
+ eval : stepEval ,
64
121
useGlobal : false ,
65
122
ignoreUndefined : true
66
123
} ) ;
67
124
68
- self . replServer . complete = self . cmdRepl . complete . bind ( self . cmdRepl ) ;
125
+ replServer . complete = cmdRepl . complete . bind ( cmdRepl ) ;
69
126
70
- self . replServer . on ( 'exit' , function ( ) {
127
+ replServer . on ( 'exit' , function ( ) {
71
128
console . log ( 'Exiting...' ) ;
72
129
self . client . req ( { command : 'disconnect' } , function ( ) {
73
130
// Intentionally blank.
74
131
} ) ;
75
132
} ) ;
76
133
} ;
77
134
135
+ /**
136
+ * Instantiate a repl or a server.
137
+ * @private
138
+ */
139
+ WdRepl . prototype . initReplOrServer_ = function ( ) {
140
+ // Note instead of starting either repl or server, another approach is to
141
+ // feed the server socket into the repl as the input/output streams. The
142
+ // advantage is that the process becomes much more realistic because now we're
143
+ // using the normal repl. However, it was not possible to test autocomplete
144
+ // this way since we cannot immitate the TAB key over the wire.
145
+ var debuggerServerPort = process . argv [ 3 ] ;
146
+ if ( debuggerServerPort ) {
147
+ this . initServer_ ( debuggerServerPort ) ;
148
+ } else {
149
+ this . initRepl_ ( ) ;
150
+ }
151
+ } ;
152
+
78
153
/**
79
154
* Initiate the debugger.
80
155
* @public
@@ -85,7 +160,7 @@ WdRepl.prototype.init = function() {
85
160
console . log ( ' e.g., list(by.binding(\'\')) gets all bindings.' ) ;
86
161
87
162
this . initClient_ ( ) ;
88
- this . initRepl_ ( ) ;
163
+ this . initReplOrServer_ ( ) ;
89
164
} ;
90
165
91
166
var wdRepl = new WdRepl ( ) ;
0 commit comments