@@ -37,19 +37,24 @@ define(function(require, exports, module) {
3737 * Does the actual extraction. i.e Replacing the text, Creating a variable
3838 * and multi select variable names
3939 */
40- function extract ( scopes , parentStatement , expns , text ) {
40+ function extract ( scopes , parentStatement , expns , text , insertPosition ) {
4141 var varType = "var" ,
4242 varName = RefactoringUtils . getUniqueIdentifierName ( scopes , "extracted" ) ,
4343 varDeclaration = varType + " " + varName + " = " + text + ";\n" ,
44- insertStartPos = session . editor . posFromIndex ( parentStatement . start ) ,
44+ parentStatementStartPos = session . editor . posFromIndex ( parentStatement . start ) ,
45+ insertStartPos = insertPosition || parentStatementStartPos ,
4546 selections = [ ] ,
4647 doc = session . editor . document ,
4748 replaceExpnIndex = 0 ,
48- posToIndent ;
49+ posToIndent ,
50+ edits = [ ] ;
4951
5052 // If parent statement is expression statement, then just append var declaration
5153 // Ex: "add(1, 2)" will become "var extracted = add(1, 2)"
52- if ( parentStatement . type === "ExpressionStatement" && RefactoringUtils . isEqual ( parentStatement . expression , expns [ 0 ] ) ) {
54+ if ( parentStatement . type === "ExpressionStatement" &&
55+ RefactoringUtils . isEqual ( parentStatement . expression , expns [ 0 ] ) &&
56+ insertStartPos . line === parentStatementStartPos . line &&
57+ insertStartPos . ch === parentStatementStartPos . ch ) {
5358 varDeclaration = varType + " " + varName + " = " ;
5459 replaceExpnIndex = 1 ;
5560 }
@@ -63,25 +68,29 @@ define(function(require, exports, module) {
6368 expns [ i ] . start = doc . adjustPosForChange ( expns [ i ] . start , varDeclaration . split ( "\n" ) , insertStartPos , insertStartPos ) ;
6469 expns [ i ] . end = doc . adjustPosForChange ( expns [ i ] . end , varDeclaration . split ( "\n" ) , insertStartPos , insertStartPos ) ;
6570
66- selections . push ( {
67- start : expns [ i ] . start ,
68- end : { line : expns [ i ] . start . line , ch : expns [ i ] . start . ch + varName . length }
71+ edits . push ( {
72+ edit : {
73+ text : varName ,
74+ start : expns [ i ] . start ,
75+ end : expns [ i ] . end
76+ } ,
77+ selection : {
78+ start : expns [ i ] . start ,
79+ end : { line : expns [ i ] . start . line , ch : expns [ i ] . start . ch + varName . length }
80+ }
6981 } ) ;
7082 }
7183
7284 // Replace and multi-select
7385 doc . batchOperation ( function ( ) {
7486 doc . replaceRange ( varDeclaration , insertStartPos ) ;
7587
76- for ( var i = replaceExpnIndex ; i < expns . length ; ++ i ) {
77- doc . replaceRange ( varName , expns [ i ] . start , expns [ i ] . end ) ;
78- }
88+ selections = doc . doMultipleEdits ( edits ) ;
7989 selections . push ( {
8090 start : { line : insertStartPos . line , ch : insertStartPos . ch + varType . length + 1 } ,
8191 end : { line : insertStartPos . line , ch : insertStartPos . ch + varType . length + varName . length + 1 } ,
8292 primary : true
8393 } ) ;
84-
8594 session . editor . setSelections ( selections ) ;
8695 session . editor . _codeMirror . indentLine ( posToIndent . line , "smart" ) ;
8796 } ) ;
@@ -163,6 +172,7 @@ define(function(require, exports, module) {
163172 */
164173 function extractToVariable ( ast , start , end , text , scopes ) {
165174 var doc = session . editor . document ,
175+ editor = EditorManager . getActiveEditor ( ) ,
166176 parentExpn = RefactoringUtils . getExpression ( ast , start , end , doc . getText ( ) ) ,
167177 expns = [ ] ,
168178 parentBlockStatement ,
@@ -178,8 +188,26 @@ define(function(require, exports, module) {
178188 if ( doc . getText ( ) . substr ( parentExpn . start , parentExpn . end - parentExpn . start ) === text ) {
179189 parentBlockStatement = RefactoringUtils . findSurroundASTNode ( ast , parentExpn , [ "BlockStatement" , "Program" ] ) ;
180190 expns = findAllExpressions ( parentBlockStatement , parentExpn , text ) ;
181- parentStatement = RefactoringUtils . findSurroundASTNode ( ast , expns [ 0 ] , [ "Statement" ] ) ;
182- extract ( scopes , parentStatement , expns , text ) ;
191+
192+ RefactoringUtils . getScopeData ( session , editor . posFromIndex ( expns [ 0 ] . start ) ) . done ( function ( scope ) {
193+ var firstExpnsScopes = RefactoringUtils . getAllScopes ( ast , scope , doc . getText ( ) ) ,
194+ insertPostion ;
195+ parentStatement = RefactoringUtils . findSurroundASTNode ( ast , expns [ 0 ] , [ "Statement" ] ) ;
196+ if ( scopes . length < firstExpnsScopes . length ) {
197+ var parentScope ;
198+ if ( expns [ 0 ] . body && expns [ 0 ] . body . type === "BlockStatement" ) {
199+ parentScope = firstExpnsScopes [ firstExpnsScopes . length - scopes . length ] ;
200+ } else {
201+ parentScope = firstExpnsScopes [ firstExpnsScopes . length - scopes . length - 1 ] ;
202+ }
203+
204+ var insertNode = RefactoringUtils . findSurroundASTNode ( ast , parentScope . originNode , [ "Statement" ] ) ;
205+ if ( insertNode ) {
206+ insertPostion = session . editor . posFromIndex ( insertNode . start ) ;
207+ }
208+ }
209+ extract ( scopes , parentStatement , expns , text , insertPostion ) ;
210+ } ) ;
183211 } else {
184212 parentStatement = RefactoringUtils . findSurroundASTNode ( ast , parentExpn , [ "Statement" ] ) ;
185213 extract ( scopes , parentStatement , [ { start : start , end : end } ] , text ) ;
@@ -212,6 +240,16 @@ define(function(require, exports, module) {
212240 expns ,
213241 inlineMenu ;
214242
243+ function callExtractToVariable ( startPos , endPos , value ) {
244+ RefactoringUtils . getScopeData ( session , editor . posFromIndex ( startPos ) )
245+ . done ( function ( expnscope ) {
246+ scopes = RefactoringUtils . getAllScopes ( ast , expnscope , doc . getText ( ) ) ;
247+ extractToVariable ( ast , startPos , endPos , value , scopes ) ;
248+ } ) . fail ( function ( ) {
249+ editor . displayErrorMessageAtCursor ( Strings . ERROR_TERN_FAILED ) ;
250+ } ) ;
251+ }
252+
215253 RefactoringUtils . getScopeData ( session , editor . posFromIndex ( start ) ) . done ( function ( scope ) {
216254 ast = RefactoringUtils . getAST ( doc . getText ( ) ) ;
217255 scopes = RefactoringUtils . getAllScopes ( ast , scope , doc . getText ( ) ) ;
@@ -253,7 +291,7 @@ define(function(require, exports, module) {
253291
254292 // If only one surround expression, extract
255293 if ( expns . length === 1 ) {
256- extractToVariable ( ast , expns [ 0 ] . start , expns [ 0 ] . end , expns [ 0 ] . value , scopes ) ;
294+ callExtractToVariable ( expns [ 0 ] . start , expns [ 0 ] . end , expns [ 0 ] . value ) ;
257295 return ;
258296 }
259297
@@ -271,7 +309,7 @@ define(function(require, exports, module) {
271309 inlineMenu . open ( expns ) ;
272310
273311 inlineMenu . onSelect ( function ( expnId ) {
274- extractToVariable ( ast , expns [ expnId ] . start , expns [ expnId ] . end , expns [ expnId ] . value , scopes ) ;
312+ callExtractToVariable ( expns [ expnId ] . start , expns [ expnId ] . end , expns [ expnId ] . value ) ;
275313 inlineMenu . close ( ) ;
276314 } ) ;
277315
0 commit comments