Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch refactoring-tool-script Excluding Merge-Ins
This is equivalent to a diff from 005eb1cbc0 to 7b85160c52
2012-06-27
| ||
08:48 | поправлена группировка слова "function" check-in: e704b0c444 user: metaeditor tags: trunk | |
2012-06-25
| ||
04:16 | Скрипт для выполнения рефакторинга кода 1С по просьбам перенесен в основную ветку. check-in: 8c40cf72ad user: kuntashov tags: trunk | |
04:13 | Убрал вызов отладчика. Leaf check-in: 7b85160c52 user: kuntashov tags: refactoring-tool-script | |
04:04 | Синхронизировано с trunk. check-in: 708535a257 user: kuntashov tags: refactoring-tool-script | |
2012-06-24
| ||
13:32 | SciColorerV8\SciColorerV8.dll check-in: 005eb1cbc0 user: metaeditor tags: trunk | |
12:29 | SciColorerV8\SciColorerV8.dll check-in: b4608296fa user: metaeditor tags: trunk | |
Changes to Libs/SyntaxAnalysis.js.
267 267 var method = this.context.getMethodByName(methodName); 268 268 if (!method) return undefined; 269 269 return this.textWindow.Range(method.StartLine + 1, 1, method.EndLine + 1).GetText(); 270 270 } 271 271 272 272 /* Возвращает таблицу значений с описаниями методов модуля. */ 273 273 _1CModule.prototype.getMethodsTable = function() { 274 - return this.context._vtAllMethods; 274 + return this.context._vtAllMethods.Copy(); 275 275 } 276 276 277 277 /* Возвращает описание метода по номеру строки, находящейся внутри метода. */ 278 278 _1CModule.prototype.getMethodByLineNumber = function (lineNo) { 279 279 280 280 var methods = this.context.Methods; 281 281
Changes to Tests/Automated/SyntaxAnalysis/testSyntaxAnalysis.js.
13 13 } 14 14 15 15 function tearDown() { 16 16 } 17 17 //} setUp/tearDown 18 18 19 19 //{ tests of AnalyseModule 20 - 21 20 function macrosTestAnalyseModule1() { 22 21 23 22 var moduleText = "" 24 23 + "Перем мПеременнаяМодуля;\n\n" 25 24 + "Перем ЕщеОднаПеременная;\n" 26 25 + "Перем ЭкспортнаяПеременная Экспорт;\n" 27 26 + "Перем ЭкспортныйМассив[10] Экспорт, ЛокальныйМассив[3], ПростоПеременная;\n" ................................................................................ 249 248 250 249 var cnt = SyntaxAnalysis.AnalyseModule(moduleText); 251 250 252 251 assertEquals('Неправильно определено количество методов!', 1, cnt.Methods.length); 253 252 assertEquals('Неправильно определено количество переменных модуля!', 0, cnt.ModuleVars.length); 254 253 } 255 254 256 -function macrosTestAnalyseModule10_ОпределениеПараметровМетодаНаРазныхСтроках() { 255 +function macrosTestAnalyseModule10_ОпределениеМетодаНаРазныхСтроках2() { 256 + var moduleText = "" 257 + + "Процедура Проверки ( Перем1, \n" 258 + + " Перем2, Перем3)\n" 259 + + "КонецПроцедуры" 260 + 261 + var cnt = SyntaxAnalysis.AnalyseModule(moduleText); 262 + 263 + assertEquals('Неправильно определено количество методов!', 1, cnt.Methods.length); 264 + assertEquals('Неправильно определено количество переменных модуля!', 0, cnt.ModuleVars.length); 265 +} 266 + 267 +function macrosTestAnalyseModule11_ОпределениеПараметровМетодаНаРазныхСтроках() { 257 268 var moduleText = "" 258 269 + "Процедура Проверки ( Перем1, \n" 259 270 + " Перем2, Перем3)\n" 260 271 + "КонецПроцедуры" 261 272 //debugger 262 273 var cnt = SyntaxAnalysis.AnalyseModule(moduleText); 263 274 ................................................................................ 264 275 assertEquals('Неправильно определено количество методов!', 1, cnt.Methods.length); 265 276 assertEquals('Неправильно определено количество переменных модуля!', 0, cnt.ModuleVars.length); 266 277 var proc = cnt.getMethodByName('Проверки'); 267 278 assertNotNull("Метод Проверки не найден", proc); 268 279 assertArrayEqualsIgnoringOrder(['Перем1', 'Перем2', 'Перем3'], proc.Params); 269 280 } 270 281 271 -function macrosTestAnalyseModule11_ОпределениеПеременныхМетодаПоУмолчанию() { 282 +function macrosTestAnalyseModule12_ОпределениеПеременныхМетодаПоУмолчанию() { 272 283 var moduleText = "" 273 284 + "Процедура Проверки (Знач Парам1, Парам2 = Ложь)\n" 274 285 + "КонецПроцедуры" 275 286 //debugger 276 287 var cnt = SyntaxAnalysis.AnalyseModule(moduleText); 277 288 278 289 assertEquals('Неправильно определено количество методов!', 1, cnt.Methods.length); ................................................................................ 279 290 assertEquals('Неправильно определено количество переменных модуля!', 0, cnt.ModuleVars.length); 280 291 var proc = cnt.getMethodByName('Проверки'); 281 292 assertNotNull("Метод Проверки не найден", proc); 282 293 assertArrayEqualsIgnoringOrder(['Парам1', 'Парам2'], proc.Params); 283 294 284 295 } 285 296 286 -function macrosTestAnalyseModule12_ОпределениеКонеткстаКомпиляции() { 297 +function macrosTestAnalyseModule13_ОпределениеКонеткстаКомпиляции() { 287 298 var moduleText = "" 288 299 + "&НаКлиенте\n" 289 300 + "Процедура Проверки (Знач Парам1, Парам2 = Ложь)\n" 290 301 + "КонецПроцедуры" 291 302 var cnt = SyntaxAnalysis.AnalyseModule(moduleText); 292 303 293 304 assertEquals('Неправильно определено количество методов!', 1, cnt.Methods.length); ................................................................................ 294 305 assertEquals('Неправильно определено количество переменных модуля!', 0, cnt.ModuleVars.length); 295 306 var proc = cnt.getMethodByName('Проверки'); 296 307 assertNotNull("Метод Проверки не найден", proc); 297 308 assertEquals("Конетекст компиляции не обнаружен", "НаКлиенте", proc.Context) 298 309 assertArrayEqualsIgnoringOrder(['Парам1', 'Парам2'], proc.Params); 299 310 300 311 } 301 -function macrosTestAnalyseModule13_ОпределениеПараметровМетодаНаРазныхСтрокахСКомментариями() { 312 +function macrosTestAnalyseModule14_ОпределениеПараметровМетодаНаРазныхСтрокахСКомментариями() { 302 313 var moduleText = "" 303 314 + "Процедура Проверки ( Перем1, //Текстовый комментарий перемменной, да и такое может быть. \n" 304 315 + " Перем2, Перем3)\n" 305 316 + "КонецПроцедуры" 306 317 debugger 307 318 var cnt = SyntaxAnalysis.AnalyseModule(moduleText); 308 319 ................................................................................ 309 320 assertEquals('Неправильно определено количество методов!', 1, cnt.Methods.length); 310 321 assertEquals('Неправильно определено количество переменных модуля!', 0, cnt.ModuleVars.length); 311 322 var proc = cnt.getMethodByName('Проверки'); 312 323 assertNotNull("Метод Проверки не найден", proc); 313 324 assertArrayEqualsIgnoringOrder(['Перем1', 'Перем2', 'Перем3'], proc.Params); 314 325 } 315 326 316 -function macrosTestAnalyseModule14_ОпределениеПараметровМетодаНаРазныхСтрокахСКомментариямиИСкобками() { 327 +function macrosTestAnalyseModule15_ОпределениеПараметровМетодаНаРазныхСтрокахСКомментариямиИСкобками() { 317 328 var moduleText = "" 318 329 + "Процедура Проверки ( Перем1, //Текстовый комментарий перемменной, да и такое может быть. \n" 319 330 + " Перем2, // Любой текст и ссылка на процедуру или функцию МояПроцедура()\n" 320 331 + " Перем3)\n" 321 332 + "КонецПроцедуры" 322 333 323 334 var cnt = SyntaxAnalysis.AnalyseModule(moduleText); ................................................................................ 324 335 325 336 assertEquals('Неправильно определено количество методов!', 1, cnt.Methods.length); 326 337 assertEquals('Неправильно определено количество переменных модуля!', 0, cnt.ModuleVars.length); 327 338 var proc = cnt.getMethodByName('Проверки'); 328 339 assertNotNull("Метод Проверки не найден", proc); 329 340 assertArrayEqualsIgnoringOrder(['Перем1', 'Перем2', 'Перем3'], proc.Params); 330 341 } 331 - 332 342 333 343 334 344 //} tests of AnalyseModule 335 345
Added refactoring.extractMethod.ssf.
cannot compute difference between binary files
Added refactoring.js.
1 +$engine JScript 2 +$uname Refactoring 3 +$dname Рефакторинг 4 +$addin global 5 +$addin stdlib 6 +$addin vbs 7 + 8 +//////////////////////////////////////////////////////////////////////////////////////// 9 +////{ Cкрипт "Рефакторинг" (refactoring.js) для проекта "Снегопат" 10 +//// 11 +//// Описание: Реализует простейшие инструменты рефакторинга. 12 +//// Автор: Александр Кунташов <kuntashov@gmail.com>, http://compaud.ru/blog 13 +////} 14 +//////////////////////////////////////////////////////////////////////////////////////// 15 + 16 +stdlib.require('TextWindow.js', SelfScript); 17 +stdlib.require('SettingsManagement.js', SelfScript); 18 + 19 +stdlib.require('SyntaxAnalysis.js', SelfScript); 20 +//Для отладки: stdlib.require(profileRoot.getValue("Snegopat/MainFolder") + 'user\\Libs\\SyntaxAnalysis.js', SelfScript); 21 + 22 +global.connectGlobals(SelfScript); 23 + 24 +//////////////////////////////////////////////////////////////////////////////////////// 25 +////{ Макросы 26 +//// 27 + 28 +SelfScript.self['macrosВыделить метод (extract method)'] = function () { 29 + refactor(ExtractMethodRefactoring); 30 +} 31 + 32 +SelfScript.self['macrosПоказать список процедур и функций модуля'] = function () { 33 + var tw = GetTextWindow(); 34 + if (!tw) return; 35 + var module = SyntaxAnalysis.AnalyseTextDocument(tw); 36 + var methList = new MethodListForm(module); 37 + if (methList.selectMethod()) 38 + Message(methList.SelectedMethod.Name); 39 +} 40 + 41 +SelfScript.self['macrosСоздать заглушку для несуществующего метода'] = function () { 42 + refactor(CreateMethodStubRefactoring, true); 43 +} 44 + 45 +////} Макросы 46 + 47 +function refactor(refactorerClass, withoutSelection) { 48 + 49 + var tw = GetTextWindow(); 50 + if (!tw) return; 51 + 52 + var selText = tw.GetSelectedText(); 53 + if (!selText && !withoutSelection) 54 + { 55 + Message("Не выделен текст, к которому применяется рефакторинг!"); 56 + return; 57 + } 58 + 59 + var module = SyntaxAnalysis.AnalyseTextDocument(tw); 60 + var refactorer = new refactorerClass(module); 61 + refactorer.refactor(selText); 62 +} 63 + 64 +//////////////////////////////////////////////////////////////////////////////////////// 65 +////{ MethodListForm 66 +//// 67 + 68 +function MethodListForm(module) { 69 + 70 + this.module = module; 71 + this.originalMethodList = module.getMethodsTable(); 72 + 73 + this.form = loadScriptForm(SelfScript.fullPath.replace(/\.js$/, '.methodList.ssf'), this); 74 + this.SelectedMethod = undefined; 75 + 76 + this.settings = SettingsManagement.CreateManager(SelfScript.uniqueName + "/MethodListForm", { 77 + 'DoNotFilter': false, 'SortByName' : false 78 + }); 79 + 80 + this.settings.LoadSettings(); 81 + 82 + var methListForm = this; 83 + this.tcWatcher = new TextChangesWatcher(this.form.Controls.SearchText, 3, function(t){methListForm.fillMethodList(t)}); 84 + 85 + this.icons = { 86 + 'Proc': this.form.Controls.picProc.Picture, 87 + 'Func': this.form.Controls.picFunc.Picture 88 + } 89 + 90 + this.fillMethodList(); 91 +} 92 + 93 +MethodListForm.prototype.selectMethod = function () { 94 + this.SelectedMethod = this.form.DoModal(); 95 + return this.SelectedMethod ? true : false; 96 +} 97 + 98 +MethodListForm.prototype.MethodListSelection = function (Control, SelectedRow, Column, DefaultHandler) { 99 + this.form.Close(SelectedRow.val._method); 100 +} 101 + 102 +MethodListForm.prototype.MethodListOnRowOutput = function (Control, RowAppearance, RowData) { 103 + var nameCell = RowAppearance.val.Cells.Name; 104 + nameCell.SetPicture( RowData.val.IsProc ? this.icons.Proc : this.icons.Func); 105 +} 106 + 107 +MethodListForm.prototype.CmdBarSortByName = function (button) { 108 + button.val.Check = !button.val.Check; 109 + this.form.SortByName = button.val.Check; 110 + this.sortMethodList(button.val.Check); 111 +} 112 + 113 +MethodListForm.prototype.CmdBarDoNotFilter = function (button) { 114 + button.val.Check = !button.val.Check; 115 + this.form.DoNotFilter = button.val.Check; 116 + this.fillMethodList(this.form.SearchText); 117 +} 118 + 119 +MethodListForm.prototype.CmdBarMainОК = function (Кнопка) { 120 + var SelectedRow = this.form.Controls.MethodList.CurrentRow; 121 + if (SelectedRow) 122 + this.form.Close(SelectedRow._method); 123 + else 124 + this.form.CurrentControl = this.form.Controls.SearchText; 125 +} 126 + 127 +MethodListForm.prototype.OnOpen = function () { 128 + 129 + this.settings.ApplyToForm(this.form); 130 + 131 + this.form.Controls.CmdBar.Buttons.SortByName.Check = this.form.SortByName; 132 + this.form.Controls.CmdBar.Buttons.DoNotFilter.Check = this.form.DoNotFilter; 133 + 134 + this.loadedOnOpen = true; 135 + this.tcWatcher.start(); 136 +} 137 + 138 +MethodListForm.prototype.BeforeClose = function (Cancel, StandardHandler) { 139 + this.tcWatcher.stop(); 140 + this.saveSettings(); 141 +} 142 + 143 +MethodListForm.prototype.fillMethodList = function (newText) { 144 + 145 + if (!newText || newText.match(/^\s*$/)) 146 + { 147 + if (this.loadedOnOpen) 148 + this.loadedOnOpen = false; 149 + else 150 + this.form.Controls.MethodList.Value = this.originalMethodList.Copy(); 151 + } 152 + else 153 + { 154 + var a = newText.split(/\s+/); 155 + for (var i=0; i<a.length; i++) 156 + a[i] = StringUtils.addSlashes(a[i]); 157 + 158 + var re = new RegExp(a.join(".*?"), 'i'); 159 + 160 + if (this.form.DoNotFilter) 161 + { 162 + var currentRow = undefined; 163 + 164 + var methList = this.originalMethodList.Copy(); 165 + for (var rowNo = 0; rowNo < methList.Count(); rowNo++) 166 + { 167 + var row = methList.Get(rowNo); 168 + if (re.test(row.Name)) 169 + { 170 + currentRow = row; 171 + break; 172 + } 173 + } 174 + 175 + this.form.Controls.MethodList.Value = methList; 176 + if (currentRow) 177 + this.form.Controls.MethodList.CurrentRow = currentRow; 178 + } 179 + else 180 + { 181 + var methList = this.form.Controls.MethodList.Value; 182 + methList.Clear(); 183 + for (var rowNo = 0; rowNo < this.originalMethodList.Count(); rowNo++) 184 + { 185 + var row = this.originalMethodList.Get(rowNo); 186 + if (re.test(row.Name)) 187 + FillPropertyValues(methList.Add(), row); 188 + } 189 + } 190 + } 191 + 192 + this.sortMethodList(this.form.SortByName); 193 +} 194 + 195 +MethodListForm.prototype.sortMethodList = function (sortByName) { 196 + this.form.MethodList.Sort(sortByName ? 'Name' : 'StartLine'); 197 +} 198 + 199 +MethodListForm.prototype.saveSettings = function () { 200 + this.settings.ReadFromForm(this.form); 201 + this.settings.SaveSettings(); 202 +} 203 + 204 +////} MethodListForm 205 + 206 +//////////////////////////////////////////////////////////////////////////////////////// 207 +////{ CreateMethodStubRefactoring 208 +//// 209 + 210 +function CreateMethodStubRefactoring(module) { 211 + 212 + this.module = module; 213 + this.textWindow = this.module.textWindow; 214 +} 215 + 216 +CreateMethodStubRefactoring.prototype.refactor = function (selectedText) { 217 + 218 + var methodName, methodSignature, matches; 219 + 220 + methodName = this.textWindow.GetWordUnderCursor(); 221 + if (!methodName) 222 + return; 223 + 224 + var method_call_proc = new RegExp("(?:;\\s*|^\\s*)" + methodName + '(\\(.+?\\))'); 225 + var method_call_func = new RegExp(methodName + "(\\(.*?\\))"); 226 + 227 + var line = this.textWindow.GetLine(this.textWindow.GetCaretPos().beginRow); 228 + 229 + var matches = line.match(method_call_proc); 230 + var isProc = (matches != null); 231 + 232 + if (!isProc) 233 + { 234 + matches = line.match(method_call_func); 235 + if (!matches) 236 + return; 237 + } 238 + 239 + methodSignature = methodName + matches[1]; 240 + 241 + var procTemplate = "\n" 242 + + "Процедура ИмяМетода()\n" 243 + + "\t//TODO: Добавьте исходный код процедуры.\n" 244 + + "КонецПроцедуры\n"; 245 + 246 + var funcTemplate = "\n" 247 + + "Функция ИмяМетода()\n" 248 + + "\t//TODO: Добавьте исходный код функции.\n" 249 + + "\tВозврат Неопределено;\n" 250 + + "КонецФункции\n"; 251 + 252 + var stubCode = isProc ? procTemplate : funcTemplate; 253 + stubCode = stubCode.replace('ИмяМетода()', methodSignature); 254 + 255 + var methodList = new MethodListForm(this.module); 256 + if (methodList.selectMethod()) 257 + { 258 + var insertLineIndex = methodList.SelectedMethod.EndLine + 1; 259 + this.textWindow.InsertLine(insertLineIndex + 1, stubCode); 260 + this.textWindow.SetCaretPos(insertLineIndex + 3, 1); 261 + } 262 +} 263 + 264 +////} CreateMethodRefactoring 265 + 266 +//////////////////////////////////////////////////////////////////////////////////////// 267 +////{ ExtractMethodRefactoring 268 +//// 269 + 270 +function ExtractMethodRefactoring(module) { 271 + this.module = module; 272 + this.form = loadScriptForm(SelfScript.fullPath.replace(/\.js$/, '.extractMethod.ssf'), this); 273 + this.Params = this.form.Params; 274 + this.ReturnValue = this.form.ReturnValue; 275 + this.SignaturePreview = this.form.SignaturePreview; 276 +} 277 + 278 +ExtractMethodRefactoring.prototype.getVarRe = function (varName) { 279 + return new RegExp("([^\\w\\dА-я\.]|^)" + varName + "([^\\w\\dА-я]|$)", 'i'); 280 +} 281 + 282 +ExtractMethodRefactoring.prototype.refactor = function (selectedText) { 283 + 284 + var sel = this.module.textWindow.GetSelection(); 285 + 286 + // 0. Определить переменные внутри выделенного блока кода (распарсить его). 287 + var extContext = this.getCodeContext(selectedText); 288 + var extVars = extContext.AutomaticVars; 289 + 290 + // 1. Определить локальные переменные части кода метода выше выделяемого кода. 291 + // 2. Определить параметры метода, из которого выделяется код. 292 + var curMethod = this.module.getActiveLineMethod(); 293 + 294 + var codeBefore = this.module.textWindow.Range(curMethod.StartLine, 1, sel.beginRow-1).GetText(); 295 + var contextBefore = this.getCodeContext(codeBefore); 296 + 297 + // 3. Определить, какие 1+2 инициализируются в 0 (AutomaticVars), а какие используются 298 + this.fillParams(contextBefore.AutomaticVars, extVars, selectedText); 299 + this.fillParams(curMethod.Params, extVars, selectedText); 300 + 301 + // 4. Те переменные, которые используются в остальной части кода - возвращаемые значения. 302 + var codeAfter = this.module.textWindow.Range(sel.endRow + 1, 1, curMethod.EndLine).GetText(); 303 + var contextAfter = this.getCodeContext(codeAfter); 304 + 305 + this.fillReturnValues(contextAfter.AutomaticVars, extVars, codeAfter); 306 + 307 + if (this.form.DoModal()) 308 + this.extractMethod(selectedText); 309 +} 310 + 311 +ExtractMethodRefactoring.prototype.fillParams = function (extArgs, extVars, source) { 312 + for (var i=0; i<extArgs.length; i++) 313 + { 314 + var varName = extArgs[i]; 315 + var re = this.getVarRe(varName); 316 + if (re.test(source) && extVars.indexOf(varName) == -1) 317 + this.addParam(varName, true, false); 318 + } 319 +} 320 + 321 +ExtractMethodRefactoring.prototype.fillReturnValues = function (extArgs, extVars, source) { 322 + //debugger; 323 + for (var i=0; i<extVars.length; i++) 324 + { 325 + var varName = extVars[i]; 326 + var re = this.getVarRe(varName); 327 + if (re.test(source) && extArgs.indexOf(varName) == -1) 328 + this.addReturnValue(varName); 329 + } 330 +} 331 + 332 +ExtractMethodRefactoring.prototype.getCodeContext = function (code) { 333 + var extractedCode = "Процедура ВыделенныйМетод()\n" + code + "\nКонецПроцедуры"; 334 + var extractedContext = SyntaxAnalysis.AnalyseModule(extractedCode, false); 335 + return extractedContext.getMethodByName("ВыделенныйМетод"); 336 +} 337 + 338 +ExtractMethodRefactoring.prototype.addParam = function (paramName, isParam, isVal) { 339 + if (!this.Params.Find(paramName, 'Name')) 340 + { 341 + var paramRow = this.Params.Add(); 342 + paramRow.Name = paramName; 343 + paramRow.isParam = isParam ? true : false; 344 + paramRow.isVal = isVal ? true : false; 345 + } 346 +} 347 + 348 +ExtractMethodRefactoring.prototype.addReturnValue = function (varName) { 349 + if (!this.ReturnValue.Find(varName, 'Name')) 350 + { 351 + var row = this.ReturnValue.Add(); 352 + row.Name = varName; 353 + } 354 +} 355 + 356 +ExtractMethodRefactoring.prototype.BtOKClick = function (Control) { 357 + 358 + if (!this.form.Name.match(/^[_\wА-я](?:[_\w\dА-я]*)$/)) 359 + { 360 + DoMessageBox("Имя метода должно быть правильным идентификатором!"); 361 + return; 362 + } 363 + 364 + this.form.Close(true); 365 +} 366 + 367 +ExtractMethodRefactoring.prototype.BtCancelClick = function (Control) { 368 + this.form.Close(false); 369 +} 370 + 371 +ExtractMethodRefactoring.prototype.extractMethod = function(source) { 372 + 373 + var tw = this.module.textWindow; 374 + var sel = tw.GetSelection(); 375 + 376 + var params = new Array; 377 + for (var i=0; i<this.Params.Count(); i++) 378 + { 379 + var paramRow = this.Params.Get(i); 380 + if (paramRow.IsParam) 381 + params.push((paramRow.IsVal ? 'Знач ' : '') + paramRow.Name); 382 + } 383 + 384 + // Откорректируем отступ. 385 + var srcIndent = StringUtils.getIndent(source); 386 + source = StringUtils.shiftLeft(source, srcIndent); 387 + source = StringUtils.shiftRight(source, "\t"); 388 + 389 + // Сформируем исходный код определения выделенного метода. 390 + var newMethod = this.form.IsProc ? 'Процедура' : 'Функция'; 391 + newMethod += ' ' + this.form.Name + '(' + params.join(', ') + ')'; 392 + if (this.form.Exported) 393 + newMethod += " Экспорт"; 394 + 395 + newMethod += "\n\n" + this.prepareSource(source) + "\n\n"; 396 + 397 + if (this.form.IsProc) 398 + { 399 + newMethod += 'КонецПроцедуры'; 400 + 401 + } 402 + else 403 + { 404 + var retVal = "Неопределено"; 405 + if (this.ReturnValue.Count() > 0) { 406 + retVal = this.ReturnValue.Get(0).Name; 407 + } 408 + newMethod += "\tВозврат " + retVal + ";"; 409 + newMethod += "\n\n" + 'КонецФункции'; 410 + } 411 + 412 + // Получим метод, внутри которого мы находимся. 413 + var curMethod = this.module.getActiveLineMethod(); 414 + 415 + // Добавим в модуль определение выделенного метода. 416 + tw.InsertLine(curMethod.EndLine + 2, "\n" + newMethod); 417 + 418 + // Заменим выделенный код на вызов нового метода. 419 + var methCall = this.form.Name + '(' + params.join(', ') + ");\n"; 420 + 421 + if (!this.form.IsProc && this.ReturnValue.Count() > 0) { 422 + retVal = this.ReturnValue.Get(0).Name; 423 + methCall = retVal + ' = ' + methCall; 424 + } 425 + 426 + tw.SetSelection(sel.beginRow, sel.beginCol, sel.endRow, sel.endCol); 427 + tw.SetSelectedText(srcIndent + methCall); 428 +} 429 + 430 +ExtractMethodRefactoring.prototype.prepareSource = function(source) { 431 + 432 + var lines = StringUtils.toLines(source); 433 + if (lines.length < 2) 434 + return source; 435 + 436 + var startIndex = 0; 437 + while (startIndex < lines.length && lines[startIndex].match(/^\s*$/)) 438 + startIndex++; 439 + 440 + var endIndex = lines.length - 1; 441 + while (endIndex > 0 && lines[endIndex].match(/^\s*$/)) 442 + endIndex--; 443 + 444 + if (startIndex <= endIndex) 445 + return StringUtils.fromLines(lines.splice(startIndex, endIndex - startIndex + 1)); 446 + 447 + return source; 448 +} 449 + 450 +////} ExtractMethodRefactoring 451 + 452 +//////////////////////////////////////////////////////////////////////////////////////// 453 +////{ TextChangesWatcher (Александр Орефков) 454 +//// 455 + 456 +// Класс для отслеживания изменения текста в поле ввода, для замены 457 +// события АвтоПодборТекста. Штатное событие плохо тем, что не возникает 458 +// - при установке пустого текста 459 +// - при изменении текста путем вставки/вырезания из/в буфера обмена 460 +// - при отмене редактирования (Ctrl+Z) 461 +// не позволяет регулировать задержку 462 +// Параметры конструктора 463 +// field - элемент управления поле ввода, чье изменение хотим отслеживать 464 +// ticks - величина задержки после ввода текста в десятых секунды (т.е. 3 - 300 мсек) 465 +// invoker - функция обратного вызова, вызывается после окончания изменения текста, 466 +// новый текст передается параметром функции 467 +function TextChangesWatcher(field, ticks, invoker) 468 +{ 469 + this.ticks = ticks 470 + this.invoker = invoker 471 + this.field = field 472 +} 473 + 474 +// Начать отслеживание изменения текста 475 +TextChangesWatcher.prototype.start = function() 476 +{ 477 + this.lastText = this.field.Значение.replace(/^\s*|\s*$/g, '').toLowerCase() 478 + this.noChangesTicks = 0 479 + this.timerID = createTimer(100, this, "onTimer") 480 +} 481 +// Остановить отслеживание изменения текста 482 +TextChangesWatcher.prototype.stop = function() 483 +{ 484 + killTimer(this.timerID) 485 +} 486 +// Обработчик события таймера 487 +TextChangesWatcher.prototype.onTimer = function() 488 +{ 489 + // Получим текущий текст из поля ввода 490 + vbs.var0 = this.field 491 + vbs.DoExecute("var0.GetTextSelectionBounds var1, var2, var3, var4") 492 + this.field.УстановитьГраницыВыделения(1, 1, 1, 10000) 493 + var newText = this.field.ВыделенныйТекст.replace(/^\s*|\s*$/g, '').toLowerCase() 494 + this.field.УстановитьГраницыВыделения(vbs.var1, vbs.var2, vbs.var3, vbs.var4) 495 + // Проверим, изменился ли текст по сравению с прошлым разом 496 + if(newText != this.lastText) 497 + { 498 + // изменился, запомним его 499 + this.lastText = newText 500 + this.noChangesTicks = 0 501 + } 502 + else 503 + { 504 + // Текст не изменился. Если мы еще не сигнализировали об этом, то увеличим счетчик тиков 505 + if(this.noChangesTicks <= this.ticks) 506 + { 507 + if(++this.noChangesTicks > this.ticks) // Достигли заданного количества тиков. 508 + this.invoker(newText) // Отрапортуем 509 + } 510 + } 511 +} 512 + 513 +//// 514 +////} TextChangesWatcher (Александр Орефков) 515 +//////////////////////////////////////////////////////////////////////////////////////// 516 + 517 +//////////////////////////////////////////////////////////////////////////////////////// 518 +////{ Вспомогательные функции 519 +//// 520 + 521 + 522 + 523 +////} Вспомогательные функции
Added refactoring.methodList.ssf.
cannot compute difference between binary files