mito-ai 0.1.50__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mito_ai/__init__.py +114 -0
- mito_ai/_version.py +4 -0
- mito_ai/anthropic_client.py +334 -0
- mito_ai/app_deploy/__init__.py +6 -0
- mito_ai/app_deploy/app_deploy_utils.py +44 -0
- mito_ai/app_deploy/handlers.py +345 -0
- mito_ai/app_deploy/models.py +98 -0
- mito_ai/app_manager/__init__.py +4 -0
- mito_ai/app_manager/handlers.py +167 -0
- mito_ai/app_manager/models.py +71 -0
- mito_ai/app_manager/utils.py +24 -0
- mito_ai/auth/README.md +18 -0
- mito_ai/auth/__init__.py +6 -0
- mito_ai/auth/handlers.py +96 -0
- mito_ai/auth/urls.py +13 -0
- mito_ai/chat_history/handlers.py +63 -0
- mito_ai/chat_history/urls.py +32 -0
- mito_ai/completions/completion_handlers/__init__.py +3 -0
- mito_ai/completions/completion_handlers/agent_auto_error_fixup_handler.py +59 -0
- mito_ai/completions/completion_handlers/agent_execution_handler.py +66 -0
- mito_ai/completions/completion_handlers/chat_completion_handler.py +141 -0
- mito_ai/completions/completion_handlers/code_explain_handler.py +113 -0
- mito_ai/completions/completion_handlers/completion_handler.py +42 -0
- mito_ai/completions/completion_handlers/inline_completer_handler.py +48 -0
- mito_ai/completions/completion_handlers/smart_debug_handler.py +160 -0
- mito_ai/completions/completion_handlers/utils.py +147 -0
- mito_ai/completions/handlers.py +415 -0
- mito_ai/completions/message_history.py +401 -0
- mito_ai/completions/models.py +404 -0
- mito_ai/completions/prompt_builders/__init__.py +3 -0
- mito_ai/completions/prompt_builders/agent_execution_prompt.py +57 -0
- mito_ai/completions/prompt_builders/agent_smart_debug_prompt.py +160 -0
- mito_ai/completions/prompt_builders/agent_system_message.py +472 -0
- mito_ai/completions/prompt_builders/chat_name_prompt.py +15 -0
- mito_ai/completions/prompt_builders/chat_prompt.py +116 -0
- mito_ai/completions/prompt_builders/chat_system_message.py +92 -0
- mito_ai/completions/prompt_builders/explain_code_prompt.py +32 -0
- mito_ai/completions/prompt_builders/inline_completer_prompt.py +197 -0
- mito_ai/completions/prompt_builders/prompt_constants.py +170 -0
- mito_ai/completions/prompt_builders/smart_debug_prompt.py +199 -0
- mito_ai/completions/prompt_builders/utils.py +84 -0
- mito_ai/completions/providers.py +284 -0
- mito_ai/constants.py +63 -0
- mito_ai/db/__init__.py +3 -0
- mito_ai/db/crawlers/__init__.py +6 -0
- mito_ai/db/crawlers/base_crawler.py +61 -0
- mito_ai/db/crawlers/constants.py +43 -0
- mito_ai/db/crawlers/snowflake.py +71 -0
- mito_ai/db/handlers.py +168 -0
- mito_ai/db/models.py +31 -0
- mito_ai/db/urls.py +34 -0
- mito_ai/db/utils.py +185 -0
- mito_ai/docker/mssql/compose.yml +37 -0
- mito_ai/docker/mssql/init/setup.sql +21 -0
- mito_ai/docker/mysql/compose.yml +18 -0
- mito_ai/docker/mysql/init/setup.sql +13 -0
- mito_ai/docker/oracle/compose.yml +17 -0
- mito_ai/docker/oracle/init/setup.sql +20 -0
- mito_ai/docker/postgres/compose.yml +17 -0
- mito_ai/docker/postgres/init/setup.sql +13 -0
- mito_ai/enterprise/__init__.py +3 -0
- mito_ai/enterprise/utils.py +15 -0
- mito_ai/file_uploads/__init__.py +3 -0
- mito_ai/file_uploads/handlers.py +248 -0
- mito_ai/file_uploads/urls.py +21 -0
- mito_ai/gemini_client.py +232 -0
- mito_ai/log/handlers.py +38 -0
- mito_ai/log/urls.py +21 -0
- mito_ai/logger.py +37 -0
- mito_ai/openai_client.py +382 -0
- mito_ai/path_utils.py +70 -0
- mito_ai/rules/handlers.py +44 -0
- mito_ai/rules/urls.py +22 -0
- mito_ai/rules/utils.py +56 -0
- mito_ai/settings/handlers.py +41 -0
- mito_ai/settings/urls.py +20 -0
- mito_ai/settings/utils.py +42 -0
- mito_ai/streamlit_conversion/agent_utils.py +37 -0
- mito_ai/streamlit_conversion/prompts/prompt_constants.py +172 -0
- mito_ai/streamlit_conversion/prompts/prompt_utils.py +10 -0
- mito_ai/streamlit_conversion/prompts/streamlit_app_creation_prompt.py +46 -0
- mito_ai/streamlit_conversion/prompts/streamlit_error_correction_prompt.py +28 -0
- mito_ai/streamlit_conversion/prompts/streamlit_finish_todo_prompt.py +45 -0
- mito_ai/streamlit_conversion/prompts/streamlit_system_prompt.py +56 -0
- mito_ai/streamlit_conversion/prompts/update_existing_app_prompt.py +50 -0
- mito_ai/streamlit_conversion/search_replace_utils.py +94 -0
- mito_ai/streamlit_conversion/streamlit_agent_handler.py +144 -0
- mito_ai/streamlit_conversion/streamlit_utils.py +85 -0
- mito_ai/streamlit_conversion/validate_streamlit_app.py +105 -0
- mito_ai/streamlit_preview/__init__.py +6 -0
- mito_ai/streamlit_preview/handlers.py +111 -0
- mito_ai/streamlit_preview/manager.py +152 -0
- mito_ai/streamlit_preview/urls.py +22 -0
- mito_ai/streamlit_preview/utils.py +29 -0
- mito_ai/tests/__init__.py +3 -0
- mito_ai/tests/chat_history/test_chat_history.py +211 -0
- mito_ai/tests/completions/completion_handlers_utils_test.py +190 -0
- mito_ai/tests/conftest.py +53 -0
- mito_ai/tests/create_agent_system_message_prompt_test.py +22 -0
- mito_ai/tests/data/prompt_lg.py +69 -0
- mito_ai/tests/data/prompt_sm.py +6 -0
- mito_ai/tests/data/prompt_xl.py +13 -0
- mito_ai/tests/data/stock_data.sqlite3 +0 -0
- mito_ai/tests/db/conftest.py +39 -0
- mito_ai/tests/db/connections_test.py +102 -0
- mito_ai/tests/db/mssql_test.py +29 -0
- mito_ai/tests/db/mysql_test.py +29 -0
- mito_ai/tests/db/oracle_test.py +29 -0
- mito_ai/tests/db/postgres_test.py +29 -0
- mito_ai/tests/db/schema_test.py +93 -0
- mito_ai/tests/db/sqlite_test.py +31 -0
- mito_ai/tests/db/test_db_constants.py +61 -0
- mito_ai/tests/deploy_app/test_app_deploy_utils.py +89 -0
- mito_ai/tests/file_uploads/__init__.py +2 -0
- mito_ai/tests/file_uploads/test_handlers.py +282 -0
- mito_ai/tests/message_history/test_generate_short_chat_name.py +120 -0
- mito_ai/tests/message_history/test_message_history_utils.py +469 -0
- mito_ai/tests/open_ai_utils_test.py +152 -0
- mito_ai/tests/performance_test.py +329 -0
- mito_ai/tests/providers/test_anthropic_client.py +447 -0
- mito_ai/tests/providers/test_azure.py +631 -0
- mito_ai/tests/providers/test_capabilities.py +120 -0
- mito_ai/tests/providers/test_gemini_client.py +195 -0
- mito_ai/tests/providers/test_mito_server_utils.py +448 -0
- mito_ai/tests/providers/test_model_resolution.py +130 -0
- mito_ai/tests/providers/test_openai_client.py +57 -0
- mito_ai/tests/providers/test_provider_completion_exception.py +66 -0
- mito_ai/tests/providers/test_provider_limits.py +42 -0
- mito_ai/tests/providers/test_providers.py +382 -0
- mito_ai/tests/providers/test_retry_logic.py +389 -0
- mito_ai/tests/providers/test_stream_mito_server_utils.py +140 -0
- mito_ai/tests/providers/utils.py +85 -0
- mito_ai/tests/rules/conftest.py +26 -0
- mito_ai/tests/rules/rules_test.py +117 -0
- mito_ai/tests/server_limits_test.py +406 -0
- mito_ai/tests/settings/conftest.py +26 -0
- mito_ai/tests/settings/settings_test.py +70 -0
- mito_ai/tests/settings/test_settings_constants.py +9 -0
- mito_ai/tests/streamlit_conversion/__init__.py +3 -0
- mito_ai/tests/streamlit_conversion/test_apply_search_replace.py +240 -0
- mito_ai/tests/streamlit_conversion/test_streamlit_agent_handler.py +246 -0
- mito_ai/tests/streamlit_conversion/test_streamlit_utils.py +193 -0
- mito_ai/tests/streamlit_conversion/test_validate_streamlit_app.py +112 -0
- mito_ai/tests/streamlit_preview/test_streamlit_preview_handler.py +118 -0
- mito_ai/tests/streamlit_preview/test_streamlit_preview_manager.py +292 -0
- mito_ai/tests/test_constants.py +47 -0
- mito_ai/tests/test_telemetry.py +12 -0
- mito_ai/tests/user/__init__.py +2 -0
- mito_ai/tests/user/test_user.py +120 -0
- mito_ai/tests/utils/__init__.py +3 -0
- mito_ai/tests/utils/test_anthropic_utils.py +162 -0
- mito_ai/tests/utils/test_gemini_utils.py +98 -0
- mito_ai/tests/version_check_test.py +169 -0
- mito_ai/user/handlers.py +45 -0
- mito_ai/user/urls.py +21 -0
- mito_ai/utils/__init__.py +3 -0
- mito_ai/utils/anthropic_utils.py +168 -0
- mito_ai/utils/create.py +94 -0
- mito_ai/utils/db.py +74 -0
- mito_ai/utils/error_classes.py +42 -0
- mito_ai/utils/gemini_utils.py +133 -0
- mito_ai/utils/message_history_utils.py +87 -0
- mito_ai/utils/mito_server_utils.py +242 -0
- mito_ai/utils/open_ai_utils.py +200 -0
- mito_ai/utils/provider_utils.py +49 -0
- mito_ai/utils/schema.py +86 -0
- mito_ai/utils/server_limits.py +152 -0
- mito_ai/utils/telemetry_utils.py +480 -0
- mito_ai/utils/utils.py +89 -0
- mito_ai/utils/version_utils.py +94 -0
- mito_ai/utils/websocket_base.py +88 -0
- mito_ai/version_check.py +60 -0
- mito_ai-0.1.50.data/data/etc/jupyter/jupyter_server_config.d/mito_ai.json +7 -0
- mito_ai-0.1.50.data/data/share/jupyter/labextensions/mito_ai/build_log.json +728 -0
- mito_ai-0.1.50.data/data/share/jupyter/labextensions/mito_ai/package.json +243 -0
- mito_ai-0.1.50.data/data/share/jupyter/labextensions/mito_ai/schemas/mito_ai/package.json.orig +238 -0
- mito_ai-0.1.50.data/data/share/jupyter/labextensions/mito_ai/schemas/mito_ai/toolbar-buttons.json +37 -0
- mito_ai-0.1.50.data/data/share/jupyter/labextensions/mito_ai/static/lib_index_js.8f1845da6bf2b128c049.js +21602 -0
- mito_ai-0.1.50.data/data/share/jupyter/labextensions/mito_ai/static/lib_index_js.8f1845da6bf2b128c049.js.map +1 -0
- mito_ai-0.1.50.data/data/share/jupyter/labextensions/mito_ai/static/node_modules_process_browser_js.4b128e94d31a81ebd209.js +198 -0
- mito_ai-0.1.50.data/data/share/jupyter/labextensions/mito_ai/static/node_modules_process_browser_js.4b128e94d31a81ebd209.js.map +1 -0
- mito_ai-0.1.50.data/data/share/jupyter/labextensions/mito_ai/static/remoteEntry.78d3ccb73e7ca1da3aae.js +619 -0
- mito_ai-0.1.50.data/data/share/jupyter/labextensions/mito_ai/static/remoteEntry.78d3ccb73e7ca1da3aae.js.map +1 -0
- mito_ai-0.1.50.data/data/share/jupyter/labextensions/mito_ai/static/style.js +4 -0
- mito_ai-0.1.50.data/data/share/jupyter/labextensions/mito_ai/static/style_index_js.5876024bb17dbd6a3ee6.js +712 -0
- mito_ai-0.1.50.data/data/share/jupyter/labextensions/mito_ai/static/style_index_js.5876024bb17dbd6a3ee6.js.map +1 -0
- mito_ai-0.1.50.data/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_auth_dist_esm_providers_cognito_apis_signOut_mjs-node_module-75790d.688c25857e7b81b1740f.js +533 -0
- mito_ai-0.1.50.data/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_auth_dist_esm_providers_cognito_apis_signOut_mjs-node_module-75790d.688c25857e7b81b1740f.js.map +1 -0
- mito_ai-0.1.50.data/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_auth_dist_esm_providers_cognito_tokenProvider_tokenProvider_-72f1c8.a917210f057fcfe224ad.js +6941 -0
- mito_ai-0.1.50.data/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_auth_dist_esm_providers_cognito_tokenProvider_tokenProvider_-72f1c8.a917210f057fcfe224ad.js.map +1 -0
- mito_ai-0.1.50.data/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_dist_esm_index_mjs.6bac1a8c4cc93f15f6b7.js +1021 -0
- mito_ai-0.1.50.data/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_dist_esm_index_mjs.6bac1a8c4cc93f15f6b7.js.map +1 -0
- mito_ai-0.1.50.data/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_ui-react_dist_esm_index_mjs.4fcecd65bef9e9847609.js +59698 -0
- mito_ai-0.1.50.data/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_aws-amplify_ui-react_dist_esm_index_mjs.4fcecd65bef9e9847609.js.map +1 -0
- mito_ai-0.1.50.data/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_react-dom_client_js-node_modules_aws-amplify_ui-react_dist_styles_css.b43d4249e4d3dac9ad7b.js +7440 -0
- mito_ai-0.1.50.data/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_react-dom_client_js-node_modules_aws-amplify_ui-react_dist_styles_css.b43d4249e4d3dac9ad7b.js.map +1 -0
- mito_ai-0.1.50.data/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_semver_index_js.3f6754ac5116d47de76b.js +2792 -0
- mito_ai-0.1.50.data/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_semver_index_js.3f6754ac5116d47de76b.js.map +1 -0
- mito_ai-0.1.50.data/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_vscode-diff_dist_index_js.ea55f1f9346638aafbcf.js +4859 -0
- mito_ai-0.1.50.data/data/share/jupyter/labextensions/mito_ai/static/vendors-node_modules_vscode-diff_dist_index_js.ea55f1f9346638aafbcf.js.map +1 -0
- mito_ai-0.1.50.dist-info/METADATA +221 -0
- mito_ai-0.1.50.dist-info/RECORD +205 -0
- mito_ai-0.1.50.dist-info/WHEEL +4 -0
- mito_ai-0.1.50.dist-info/entry_points.txt +2 -0
- mito_ai-0.1.50.dist-info/licenses/LICENSE +3 -0
|
@@ -0,0 +1,4859 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
(self["webpackChunkmito_ai"] = self["webpackChunkmito_ai"] || []).push([["vendors-node_modules_vscode-diff_dist_index_js"],{
|
|
3
|
+
|
|
4
|
+
/***/ "./node_modules/vscode-diff/dist/index.js":
|
|
5
|
+
/*!************************************************!*\
|
|
6
|
+
!*** ./node_modules/vscode-diff/dist/index.js ***!
|
|
7
|
+
\************************************************/
|
|
8
|
+
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
14
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
15
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
16
|
+
}
|
|
17
|
+
Object.defineProperty(o, k2, desc);
|
|
18
|
+
}) : (function(o, m, k, k2) {
|
|
19
|
+
if (k2 === undefined) k2 = k;
|
|
20
|
+
o[k2] = m[k];
|
|
21
|
+
}));
|
|
22
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
23
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
26
|
+
__exportStar(__webpack_require__(/*! ./vs/editor/common/diff/linesDiffComputer */ "./node_modules/vscode-diff/dist/vs/editor/common/diff/linesDiffComputer.js"), exports);
|
|
27
|
+
__exportStar(__webpack_require__(/*! ./vs/base/common/diff/diff */ "./node_modules/vscode-diff/dist/vs/base/common/diff/diff.js"), exports);
|
|
28
|
+
__exportStar(__webpack_require__(/*! ./vs/base/common/diff/diffChange */ "./node_modules/vscode-diff/dist/vs/base/common/diff/diffChange.js"), exports);
|
|
29
|
+
__exportStar(__webpack_require__(/*! ./vs/editor/common/diff/legacyLinesDiffComputer */ "./node_modules/vscode-diff/dist/vs/editor/common/diff/legacyLinesDiffComputer.js"), exports);
|
|
30
|
+
__exportStar(__webpack_require__(/*! ./vs/editor/common/diff/advancedLinesDiffComputer */ "./node_modules/vscode-diff/dist/vs/editor/common/diff/advancedLinesDiffComputer.js"), exports);
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
/***/ }),
|
|
34
|
+
|
|
35
|
+
/***/ "./node_modules/vscode-diff/dist/vs/base/common/arrays.js":
|
|
36
|
+
/*!****************************************************************!*\
|
|
37
|
+
!*** ./node_modules/vscode-diff/dist/vs/base/common/arrays.js ***!
|
|
38
|
+
\****************************************************************/
|
|
39
|
+
/***/ ((__unused_webpack_module, exports) => {
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
/*---------------------------------------------------------------------------------------------
|
|
43
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
44
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
45
|
+
*--------------------------------------------------------------------------------------------*/
|
|
46
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
47
|
+
exports.CallbackIterable = exports.reverseOrder = exports.numberComparator = exports.compareBy = exports.CompareResult = exports.findLastIndex = exports.equals = void 0;
|
|
48
|
+
function equals(one, other, itemEquals = (a, b) => a === b) {
|
|
49
|
+
if (one === other) {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
if (!one || !other) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
if (one.length !== other.length) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
for (let i = 0, len = one.length; i < len; i++) {
|
|
59
|
+
if (!itemEquals(one[i], other[i])) {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
exports.equals = equals;
|
|
66
|
+
function findLastIndex(array, fn) {
|
|
67
|
+
for (let i = array.length - 1; i >= 0; i--) {
|
|
68
|
+
const element = array[i];
|
|
69
|
+
if (fn(element)) {
|
|
70
|
+
return i;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return -1;
|
|
74
|
+
}
|
|
75
|
+
exports.findLastIndex = findLastIndex;
|
|
76
|
+
var CompareResult;
|
|
77
|
+
(function (CompareResult) {
|
|
78
|
+
function isLessThan(result) {
|
|
79
|
+
return result < 0;
|
|
80
|
+
}
|
|
81
|
+
CompareResult.isLessThan = isLessThan;
|
|
82
|
+
function isLessThanOrEqual(result) {
|
|
83
|
+
return result <= 0;
|
|
84
|
+
}
|
|
85
|
+
CompareResult.isLessThanOrEqual = isLessThanOrEqual;
|
|
86
|
+
function isGreaterThan(result) {
|
|
87
|
+
return result > 0;
|
|
88
|
+
}
|
|
89
|
+
CompareResult.isGreaterThan = isGreaterThan;
|
|
90
|
+
})(CompareResult || (exports.CompareResult = CompareResult = {}));
|
|
91
|
+
function compareBy(selector, comparator) {
|
|
92
|
+
return (a, b) => comparator(selector(a), selector(b));
|
|
93
|
+
}
|
|
94
|
+
exports.compareBy = compareBy;
|
|
95
|
+
/**
|
|
96
|
+
* The natural order on numbers.
|
|
97
|
+
*/
|
|
98
|
+
const numberComparator = (a, b) => a - b;
|
|
99
|
+
exports.numberComparator = numberComparator;
|
|
100
|
+
function reverseOrder(comparator) {
|
|
101
|
+
return (a, b) => -comparator(a, b);
|
|
102
|
+
}
|
|
103
|
+
exports.reverseOrder = reverseOrder;
|
|
104
|
+
/**
|
|
105
|
+
* This class is faster than an iterator and array for lazy computed data.
|
|
106
|
+
*/
|
|
107
|
+
class CallbackIterable {
|
|
108
|
+
constructor(
|
|
109
|
+
/**
|
|
110
|
+
* Calls the callback for every item.
|
|
111
|
+
* Stops when the callback returns false.
|
|
112
|
+
*/
|
|
113
|
+
iterate) {
|
|
114
|
+
this.iterate = iterate;
|
|
115
|
+
}
|
|
116
|
+
forEach(handler) {
|
|
117
|
+
this.iterate(item => { handler(item); return true; });
|
|
118
|
+
}
|
|
119
|
+
toArray() {
|
|
120
|
+
const result = [];
|
|
121
|
+
this.iterate(item => { result.push(item); return true; });
|
|
122
|
+
return result;
|
|
123
|
+
}
|
|
124
|
+
filter(predicate) {
|
|
125
|
+
return new CallbackIterable(cb => this.iterate(item => predicate(item) ? cb(item) : true));
|
|
126
|
+
}
|
|
127
|
+
map(mapFn) {
|
|
128
|
+
return new CallbackIterable(cb => this.iterate(item => cb(mapFn(item))));
|
|
129
|
+
}
|
|
130
|
+
some(predicate) {
|
|
131
|
+
let result = false;
|
|
132
|
+
this.iterate(item => { result = predicate(item); return !result; });
|
|
133
|
+
return result;
|
|
134
|
+
}
|
|
135
|
+
findFirst(predicate) {
|
|
136
|
+
let result;
|
|
137
|
+
this.iterate(item => {
|
|
138
|
+
if (predicate(item)) {
|
|
139
|
+
result = item;
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
return true;
|
|
143
|
+
});
|
|
144
|
+
return result;
|
|
145
|
+
}
|
|
146
|
+
findLast(predicate) {
|
|
147
|
+
let result;
|
|
148
|
+
this.iterate(item => {
|
|
149
|
+
if (predicate(item)) {
|
|
150
|
+
result = item;
|
|
151
|
+
}
|
|
152
|
+
return true;
|
|
153
|
+
});
|
|
154
|
+
return result;
|
|
155
|
+
}
|
|
156
|
+
findLastMaxBy(comparator) {
|
|
157
|
+
let result;
|
|
158
|
+
let first = true;
|
|
159
|
+
this.iterate(item => {
|
|
160
|
+
if (first || CompareResult.isGreaterThan(comparator(item, result))) {
|
|
161
|
+
first = false;
|
|
162
|
+
result = item;
|
|
163
|
+
}
|
|
164
|
+
return true;
|
|
165
|
+
});
|
|
166
|
+
return result;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
exports.CallbackIterable = CallbackIterable;
|
|
170
|
+
CallbackIterable.empty = new CallbackIterable(_callback => { });
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
/***/ }),
|
|
174
|
+
|
|
175
|
+
/***/ "./node_modules/vscode-diff/dist/vs/base/common/assert.js":
|
|
176
|
+
/*!****************************************************************!*\
|
|
177
|
+
!*** ./node_modules/vscode-diff/dist/vs/base/common/assert.js ***!
|
|
178
|
+
\****************************************************************/
|
|
179
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
/*---------------------------------------------------------------------------------------------
|
|
183
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
184
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
185
|
+
*--------------------------------------------------------------------------------------------*/
|
|
186
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
187
|
+
exports.checkAdjacentItems = exports.assertFn = void 0;
|
|
188
|
+
const errors_1 = __webpack_require__(/*! ./errors */ "./node_modules/vscode-diff/dist/vs/base/common/errors.js");
|
|
189
|
+
/**
|
|
190
|
+
* condition must be side-effect free!
|
|
191
|
+
*/
|
|
192
|
+
function assertFn(condition) {
|
|
193
|
+
if (!condition()) {
|
|
194
|
+
// eslint-disable-next-line no-debugger
|
|
195
|
+
debugger;
|
|
196
|
+
// Reevaluate `condition` again to make debugging easier
|
|
197
|
+
condition();
|
|
198
|
+
(0, errors_1.onUnexpectedError)(new errors_1.BugIndicatingError('Assertion Failed'));
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
exports.assertFn = assertFn;
|
|
202
|
+
function checkAdjacentItems(items, predicate) {
|
|
203
|
+
let i = 0;
|
|
204
|
+
while (i < items.length - 1) {
|
|
205
|
+
const a = items[i];
|
|
206
|
+
const b = items[i + 1];
|
|
207
|
+
if (!predicate(a, b)) {
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
i++;
|
|
211
|
+
}
|
|
212
|
+
return true;
|
|
213
|
+
}
|
|
214
|
+
exports.checkAdjacentItems = checkAdjacentItems;
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
/***/ }),
|
|
218
|
+
|
|
219
|
+
/***/ "./node_modules/vscode-diff/dist/vs/base/common/collections.js":
|
|
220
|
+
/*!*********************************************************************!*\
|
|
221
|
+
!*** ./node_modules/vscode-diff/dist/vs/base/common/collections.js ***!
|
|
222
|
+
\*********************************************************************/
|
|
223
|
+
/***/ ((__unused_webpack_module, exports) => {
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
/*---------------------------------------------------------------------------------------------
|
|
227
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
228
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
229
|
+
*--------------------------------------------------------------------------------------------*/
|
|
230
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
231
|
+
exports.SetMap = void 0;
|
|
232
|
+
class SetMap {
|
|
233
|
+
constructor() {
|
|
234
|
+
this.map = new Map();
|
|
235
|
+
}
|
|
236
|
+
add(key, value) {
|
|
237
|
+
let values = this.map.get(key);
|
|
238
|
+
if (!values) {
|
|
239
|
+
values = new Set();
|
|
240
|
+
this.map.set(key, values);
|
|
241
|
+
}
|
|
242
|
+
values.add(value);
|
|
243
|
+
}
|
|
244
|
+
delete(key, value) {
|
|
245
|
+
const values = this.map.get(key);
|
|
246
|
+
if (!values) {
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
values.delete(value);
|
|
250
|
+
if (values.size === 0) {
|
|
251
|
+
this.map.delete(key);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
forEach(key, fn) {
|
|
255
|
+
const values = this.map.get(key);
|
|
256
|
+
if (!values) {
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
values.forEach(fn);
|
|
260
|
+
}
|
|
261
|
+
get(key) {
|
|
262
|
+
const values = this.map.get(key);
|
|
263
|
+
if (!values) {
|
|
264
|
+
return new Set();
|
|
265
|
+
}
|
|
266
|
+
return values;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
exports.SetMap = SetMap;
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
/***/ }),
|
|
273
|
+
|
|
274
|
+
/***/ "./node_modules/vscode-diff/dist/vs/base/common/diff/diff.js":
|
|
275
|
+
/*!*******************************************************************!*\
|
|
276
|
+
!*** ./node_modules/vscode-diff/dist/vs/base/common/diff/diff.js ***!
|
|
277
|
+
\*******************************************************************/
|
|
278
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
/*---------------------------------------------------------------------------------------------
|
|
282
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
283
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
284
|
+
*--------------------------------------------------------------------------------------------*/
|
|
285
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
286
|
+
exports.LcsDiff = exports.stringDiff = exports.StringDiffSequence = void 0;
|
|
287
|
+
const hash_1 = __webpack_require__(/*! ../hash */ "./node_modules/vscode-diff/dist/vs/base/common/hash.js");
|
|
288
|
+
const diffChange_1 = __webpack_require__(/*! ./diffChange */ "./node_modules/vscode-diff/dist/vs/base/common/diff/diffChange.js");
|
|
289
|
+
class StringDiffSequence {
|
|
290
|
+
constructor(source) {
|
|
291
|
+
this.source = source;
|
|
292
|
+
}
|
|
293
|
+
getElements() {
|
|
294
|
+
const source = this.source;
|
|
295
|
+
const characters = new Int32Array(source.length);
|
|
296
|
+
for (let i = 0, len = source.length; i < len; i++) {
|
|
297
|
+
characters[i] = source.charCodeAt(i);
|
|
298
|
+
}
|
|
299
|
+
return characters;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
exports.StringDiffSequence = StringDiffSequence;
|
|
303
|
+
function stringDiff(original, modified, pretty) {
|
|
304
|
+
return new LcsDiff(new StringDiffSequence(original), new StringDiffSequence(modified)).ComputeDiff(pretty).changes;
|
|
305
|
+
}
|
|
306
|
+
exports.stringDiff = stringDiff;
|
|
307
|
+
//
|
|
308
|
+
// The code below has been ported from a C# implementation in VS
|
|
309
|
+
//
|
|
310
|
+
class Debug {
|
|
311
|
+
static Assert(condition, message) {
|
|
312
|
+
if (!condition) {
|
|
313
|
+
throw new Error(message);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
class MyArray {
|
|
318
|
+
/**
|
|
319
|
+
* Copies a range of elements from an Array starting at the specified source index and pastes
|
|
320
|
+
* them to another Array starting at the specified destination index. The length and the indexes
|
|
321
|
+
* are specified as 64-bit integers.
|
|
322
|
+
* sourceArray:
|
|
323
|
+
* The Array that contains the data to copy.
|
|
324
|
+
* sourceIndex:
|
|
325
|
+
* A 64-bit integer that represents the index in the sourceArray at which copying begins.
|
|
326
|
+
* destinationArray:
|
|
327
|
+
* The Array that receives the data.
|
|
328
|
+
* destinationIndex:
|
|
329
|
+
* A 64-bit integer that represents the index in the destinationArray at which storing begins.
|
|
330
|
+
* length:
|
|
331
|
+
* A 64-bit integer that represents the number of elements to copy.
|
|
332
|
+
*/
|
|
333
|
+
static Copy(sourceArray, sourceIndex, destinationArray, destinationIndex, length) {
|
|
334
|
+
for (let i = 0; i < length; i++) {
|
|
335
|
+
destinationArray[destinationIndex + i] = sourceArray[sourceIndex + i];
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
static Copy2(sourceArray, sourceIndex, destinationArray, destinationIndex, length) {
|
|
339
|
+
for (let i = 0; i < length; i++) {
|
|
340
|
+
destinationArray[destinationIndex + i] = sourceArray[sourceIndex + i];
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* A utility class which helps to create the set of DiffChanges from
|
|
346
|
+
* a difference operation. This class accepts original DiffElements and
|
|
347
|
+
* modified DiffElements that are involved in a particular change. The
|
|
348
|
+
* MarkNextChange() method can be called to mark the separation between
|
|
349
|
+
* distinct changes. At the end, the Changes property can be called to retrieve
|
|
350
|
+
* the constructed changes.
|
|
351
|
+
*/
|
|
352
|
+
class DiffChangeHelper {
|
|
353
|
+
/**
|
|
354
|
+
* Constructs a new DiffChangeHelper for the given DiffSequences.
|
|
355
|
+
*/
|
|
356
|
+
constructor() {
|
|
357
|
+
this.m_changes = [];
|
|
358
|
+
this.m_originalStart = 1073741824 /* Constants.MAX_SAFE_SMALL_INTEGER */;
|
|
359
|
+
this.m_modifiedStart = 1073741824 /* Constants.MAX_SAFE_SMALL_INTEGER */;
|
|
360
|
+
this.m_originalCount = 0;
|
|
361
|
+
this.m_modifiedCount = 0;
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Marks the beginning of the next change in the set of differences.
|
|
365
|
+
*/
|
|
366
|
+
MarkNextChange() {
|
|
367
|
+
// Only add to the list if there is something to add
|
|
368
|
+
if (this.m_originalCount > 0 || this.m_modifiedCount > 0) {
|
|
369
|
+
// Add the new change to our list
|
|
370
|
+
this.m_changes.push(new diffChange_1.DiffChange(this.m_originalStart, this.m_originalCount, this.m_modifiedStart, this.m_modifiedCount));
|
|
371
|
+
}
|
|
372
|
+
// Reset for the next change
|
|
373
|
+
this.m_originalCount = 0;
|
|
374
|
+
this.m_modifiedCount = 0;
|
|
375
|
+
this.m_originalStart = 1073741824 /* Constants.MAX_SAFE_SMALL_INTEGER */;
|
|
376
|
+
this.m_modifiedStart = 1073741824 /* Constants.MAX_SAFE_SMALL_INTEGER */;
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Adds the original element at the given position to the elements
|
|
380
|
+
* affected by the current change. The modified index gives context
|
|
381
|
+
* to the change position with respect to the original sequence.
|
|
382
|
+
* @param originalIndex The index of the original element to add.
|
|
383
|
+
* @param modifiedIndex The index of the modified element that provides corresponding position in the modified sequence.
|
|
384
|
+
*/
|
|
385
|
+
AddOriginalElement(originalIndex, modifiedIndex) {
|
|
386
|
+
// The 'true' start index is the smallest of the ones we've seen
|
|
387
|
+
this.m_originalStart = Math.min(this.m_originalStart, originalIndex);
|
|
388
|
+
this.m_modifiedStart = Math.min(this.m_modifiedStart, modifiedIndex);
|
|
389
|
+
this.m_originalCount++;
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Adds the modified element at the given position to the elements
|
|
393
|
+
* affected by the current change. The original index gives context
|
|
394
|
+
* to the change position with respect to the modified sequence.
|
|
395
|
+
* @param originalIndex The index of the original element that provides corresponding position in the original sequence.
|
|
396
|
+
* @param modifiedIndex The index of the modified element to add.
|
|
397
|
+
*/
|
|
398
|
+
AddModifiedElement(originalIndex, modifiedIndex) {
|
|
399
|
+
// The 'true' start index is the smallest of the ones we've seen
|
|
400
|
+
this.m_originalStart = Math.min(this.m_originalStart, originalIndex);
|
|
401
|
+
this.m_modifiedStart = Math.min(this.m_modifiedStart, modifiedIndex);
|
|
402
|
+
this.m_modifiedCount++;
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Retrieves all of the changes marked by the class.
|
|
406
|
+
*/
|
|
407
|
+
getChanges() {
|
|
408
|
+
if (this.m_originalCount > 0 || this.m_modifiedCount > 0) {
|
|
409
|
+
// Finish up on whatever is left
|
|
410
|
+
this.MarkNextChange();
|
|
411
|
+
}
|
|
412
|
+
return this.m_changes;
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* Retrieves all of the changes marked by the class in the reverse order
|
|
416
|
+
*/
|
|
417
|
+
getReverseChanges() {
|
|
418
|
+
if (this.m_originalCount > 0 || this.m_modifiedCount > 0) {
|
|
419
|
+
// Finish up on whatever is left
|
|
420
|
+
this.MarkNextChange();
|
|
421
|
+
}
|
|
422
|
+
this.m_changes.reverse();
|
|
423
|
+
return this.m_changes;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* An implementation of the difference algorithm described in
|
|
428
|
+
* "An O(ND) Difference Algorithm and its variations" by Eugene W. Myers
|
|
429
|
+
*/
|
|
430
|
+
class LcsDiff {
|
|
431
|
+
/**
|
|
432
|
+
* Constructs the DiffFinder
|
|
433
|
+
*/
|
|
434
|
+
constructor(originalSequence, modifiedSequence, continueProcessingPredicate = null) {
|
|
435
|
+
this.ContinueProcessingPredicate = continueProcessingPredicate;
|
|
436
|
+
this._originalSequence = originalSequence;
|
|
437
|
+
this._modifiedSequence = modifiedSequence;
|
|
438
|
+
const [originalStringElements, originalElementsOrHash, originalHasStrings] = LcsDiff._getElements(originalSequence);
|
|
439
|
+
const [modifiedStringElements, modifiedElementsOrHash, modifiedHasStrings] = LcsDiff._getElements(modifiedSequence);
|
|
440
|
+
this._hasStrings = (originalHasStrings && modifiedHasStrings);
|
|
441
|
+
this._originalStringElements = originalStringElements;
|
|
442
|
+
this._originalElementsOrHash = originalElementsOrHash;
|
|
443
|
+
this._modifiedStringElements = modifiedStringElements;
|
|
444
|
+
this._modifiedElementsOrHash = modifiedElementsOrHash;
|
|
445
|
+
this.m_forwardHistory = [];
|
|
446
|
+
this.m_reverseHistory = [];
|
|
447
|
+
}
|
|
448
|
+
static _isStringArray(arr) {
|
|
449
|
+
return (arr.length > 0 && typeof arr[0] === 'string');
|
|
450
|
+
}
|
|
451
|
+
static _getElements(sequence) {
|
|
452
|
+
const elements = sequence.getElements();
|
|
453
|
+
if (LcsDiff._isStringArray(elements)) {
|
|
454
|
+
const hashes = new Int32Array(elements.length);
|
|
455
|
+
for (let i = 0, len = elements.length; i < len; i++) {
|
|
456
|
+
hashes[i] = (0, hash_1.stringHash)(elements[i], 0);
|
|
457
|
+
}
|
|
458
|
+
return [elements, hashes, true];
|
|
459
|
+
}
|
|
460
|
+
if (elements instanceof Int32Array) {
|
|
461
|
+
return [[], elements, false];
|
|
462
|
+
}
|
|
463
|
+
return [[], new Int32Array(elements), false];
|
|
464
|
+
}
|
|
465
|
+
ElementsAreEqual(originalIndex, newIndex) {
|
|
466
|
+
if (this._originalElementsOrHash[originalIndex] !== this._modifiedElementsOrHash[newIndex]) {
|
|
467
|
+
return false;
|
|
468
|
+
}
|
|
469
|
+
return (this._hasStrings ? this._originalStringElements[originalIndex] === this._modifiedStringElements[newIndex] : true);
|
|
470
|
+
}
|
|
471
|
+
ElementsAreStrictEqual(originalIndex, newIndex) {
|
|
472
|
+
if (!this.ElementsAreEqual(originalIndex, newIndex)) {
|
|
473
|
+
return false;
|
|
474
|
+
}
|
|
475
|
+
const originalElement = LcsDiff._getStrictElement(this._originalSequence, originalIndex);
|
|
476
|
+
const modifiedElement = LcsDiff._getStrictElement(this._modifiedSequence, newIndex);
|
|
477
|
+
return (originalElement === modifiedElement);
|
|
478
|
+
}
|
|
479
|
+
static _getStrictElement(sequence, index) {
|
|
480
|
+
if (typeof sequence.getStrictElement === 'function') {
|
|
481
|
+
return sequence.getStrictElement(index);
|
|
482
|
+
}
|
|
483
|
+
return null;
|
|
484
|
+
}
|
|
485
|
+
OriginalElementsAreEqual(index1, index2) {
|
|
486
|
+
if (this._originalElementsOrHash[index1] !== this._originalElementsOrHash[index2]) {
|
|
487
|
+
return false;
|
|
488
|
+
}
|
|
489
|
+
return (this._hasStrings ? this._originalStringElements[index1] === this._originalStringElements[index2] : true);
|
|
490
|
+
}
|
|
491
|
+
ModifiedElementsAreEqual(index1, index2) {
|
|
492
|
+
if (this._modifiedElementsOrHash[index1] !== this._modifiedElementsOrHash[index2]) {
|
|
493
|
+
return false;
|
|
494
|
+
}
|
|
495
|
+
return (this._hasStrings ? this._modifiedStringElements[index1] === this._modifiedStringElements[index2] : true);
|
|
496
|
+
}
|
|
497
|
+
ComputeDiff(pretty) {
|
|
498
|
+
return this._ComputeDiff(0, this._originalElementsOrHash.length - 1, 0, this._modifiedElementsOrHash.length - 1, pretty);
|
|
499
|
+
}
|
|
500
|
+
/**
|
|
501
|
+
* Computes the differences between the original and modified input
|
|
502
|
+
* sequences on the bounded range.
|
|
503
|
+
* @returns An array of the differences between the two input sequences.
|
|
504
|
+
*/
|
|
505
|
+
_ComputeDiff(originalStart, originalEnd, modifiedStart, modifiedEnd, pretty) {
|
|
506
|
+
const quitEarlyArr = [false];
|
|
507
|
+
let changes = this.ComputeDiffRecursive(originalStart, originalEnd, modifiedStart, modifiedEnd, quitEarlyArr);
|
|
508
|
+
if (pretty) {
|
|
509
|
+
// We have to clean up the computed diff to be more intuitive
|
|
510
|
+
// but it turns out this cannot be done correctly until the entire set
|
|
511
|
+
// of diffs have been computed
|
|
512
|
+
changes = this.PrettifyChanges(changes);
|
|
513
|
+
}
|
|
514
|
+
return {
|
|
515
|
+
quitEarly: quitEarlyArr[0],
|
|
516
|
+
changes: changes
|
|
517
|
+
};
|
|
518
|
+
}
|
|
519
|
+
/**
|
|
520
|
+
* Private helper method which computes the differences on the bounded range
|
|
521
|
+
* recursively.
|
|
522
|
+
* @returns An array of the differences between the two input sequences.
|
|
523
|
+
*/
|
|
524
|
+
ComputeDiffRecursive(originalStart, originalEnd, modifiedStart, modifiedEnd, quitEarlyArr) {
|
|
525
|
+
quitEarlyArr[0] = false;
|
|
526
|
+
// Find the start of the differences
|
|
527
|
+
while (originalStart <= originalEnd && modifiedStart <= modifiedEnd && this.ElementsAreEqual(originalStart, modifiedStart)) {
|
|
528
|
+
originalStart++;
|
|
529
|
+
modifiedStart++;
|
|
530
|
+
}
|
|
531
|
+
// Find the end of the differences
|
|
532
|
+
while (originalEnd >= originalStart && modifiedEnd >= modifiedStart && this.ElementsAreEqual(originalEnd, modifiedEnd)) {
|
|
533
|
+
originalEnd--;
|
|
534
|
+
modifiedEnd--;
|
|
535
|
+
}
|
|
536
|
+
// In the special case where we either have all insertions or all deletions or the sequences are identical
|
|
537
|
+
if (originalStart > originalEnd || modifiedStart > modifiedEnd) {
|
|
538
|
+
let changes;
|
|
539
|
+
if (modifiedStart <= modifiedEnd) {
|
|
540
|
+
Debug.Assert(originalStart === originalEnd + 1, 'originalStart should only be one more than originalEnd');
|
|
541
|
+
// All insertions
|
|
542
|
+
changes = [
|
|
543
|
+
new diffChange_1.DiffChange(originalStart, 0, modifiedStart, modifiedEnd - modifiedStart + 1)
|
|
544
|
+
];
|
|
545
|
+
}
|
|
546
|
+
else if (originalStart <= originalEnd) {
|
|
547
|
+
Debug.Assert(modifiedStart === modifiedEnd + 1, 'modifiedStart should only be one more than modifiedEnd');
|
|
548
|
+
// All deletions
|
|
549
|
+
changes = [
|
|
550
|
+
new diffChange_1.DiffChange(originalStart, originalEnd - originalStart + 1, modifiedStart, 0)
|
|
551
|
+
];
|
|
552
|
+
}
|
|
553
|
+
else {
|
|
554
|
+
Debug.Assert(originalStart === originalEnd + 1, 'originalStart should only be one more than originalEnd');
|
|
555
|
+
Debug.Assert(modifiedStart === modifiedEnd + 1, 'modifiedStart should only be one more than modifiedEnd');
|
|
556
|
+
// Identical sequences - No differences
|
|
557
|
+
changes = [];
|
|
558
|
+
}
|
|
559
|
+
return changes;
|
|
560
|
+
}
|
|
561
|
+
// This problem can be solved using the Divide-And-Conquer technique.
|
|
562
|
+
const midOriginalArr = [0];
|
|
563
|
+
const midModifiedArr = [0];
|
|
564
|
+
const result = this.ComputeRecursionPoint(originalStart, originalEnd, modifiedStart, modifiedEnd, midOriginalArr, midModifiedArr, quitEarlyArr);
|
|
565
|
+
const midOriginal = midOriginalArr[0];
|
|
566
|
+
const midModified = midModifiedArr[0];
|
|
567
|
+
if (result !== null) {
|
|
568
|
+
// Result is not-null when there was enough memory to compute the changes while
|
|
569
|
+
// searching for the recursion point
|
|
570
|
+
return result;
|
|
571
|
+
}
|
|
572
|
+
else if (!quitEarlyArr[0]) {
|
|
573
|
+
// We can break the problem down recursively by finding the changes in the
|
|
574
|
+
// First Half: (originalStart, modifiedStart) to (midOriginal, midModified)
|
|
575
|
+
// Second Half: (midOriginal + 1, minModified + 1) to (originalEnd, modifiedEnd)
|
|
576
|
+
// NOTE: ComputeDiff() is inclusive, therefore the second range starts on the next point
|
|
577
|
+
const leftChanges = this.ComputeDiffRecursive(originalStart, midOriginal, modifiedStart, midModified, quitEarlyArr);
|
|
578
|
+
let rightChanges = [];
|
|
579
|
+
if (!quitEarlyArr[0]) {
|
|
580
|
+
rightChanges = this.ComputeDiffRecursive(midOriginal + 1, originalEnd, midModified + 1, modifiedEnd, quitEarlyArr);
|
|
581
|
+
}
|
|
582
|
+
else {
|
|
583
|
+
// We didn't have time to finish the first half, so we don't have time to compute this half.
|
|
584
|
+
// Consider the entire rest of the sequence different.
|
|
585
|
+
rightChanges = [
|
|
586
|
+
new diffChange_1.DiffChange(midOriginal + 1, originalEnd - (midOriginal + 1) + 1, midModified + 1, modifiedEnd - (midModified + 1) + 1)
|
|
587
|
+
];
|
|
588
|
+
}
|
|
589
|
+
return this.ConcatenateChanges(leftChanges, rightChanges);
|
|
590
|
+
}
|
|
591
|
+
// If we hit here, we quit early, and so can't return anything meaningful
|
|
592
|
+
return [
|
|
593
|
+
new diffChange_1.DiffChange(originalStart, originalEnd - originalStart + 1, modifiedStart, modifiedEnd - modifiedStart + 1)
|
|
594
|
+
];
|
|
595
|
+
}
|
|
596
|
+
WALKTRACE(diagonalForwardBase, diagonalForwardStart, diagonalForwardEnd, diagonalForwardOffset, diagonalReverseBase, diagonalReverseStart, diagonalReverseEnd, diagonalReverseOffset, forwardPoints, reversePoints, originalIndex, originalEnd, midOriginalArr, modifiedIndex, modifiedEnd, midModifiedArr, deltaIsEven, quitEarlyArr) {
|
|
597
|
+
let forwardChanges = null;
|
|
598
|
+
let reverseChanges = null;
|
|
599
|
+
// First, walk backward through the forward diagonals history
|
|
600
|
+
let changeHelper = new DiffChangeHelper();
|
|
601
|
+
let diagonalMin = diagonalForwardStart;
|
|
602
|
+
let diagonalMax = diagonalForwardEnd;
|
|
603
|
+
let diagonalRelative = (midOriginalArr[0] - midModifiedArr[0]) - diagonalForwardOffset;
|
|
604
|
+
let lastOriginalIndex = -1073741824 /* Constants.MIN_SAFE_SMALL_INTEGER */;
|
|
605
|
+
let historyIndex = this.m_forwardHistory.length - 1;
|
|
606
|
+
do {
|
|
607
|
+
// Get the diagonal index from the relative diagonal number
|
|
608
|
+
const diagonal = diagonalRelative + diagonalForwardBase;
|
|
609
|
+
// Figure out where we came from
|
|
610
|
+
if (diagonal === diagonalMin || (diagonal < diagonalMax && forwardPoints[diagonal - 1] < forwardPoints[diagonal + 1])) {
|
|
611
|
+
// Vertical line (the element is an insert)
|
|
612
|
+
originalIndex = forwardPoints[diagonal + 1];
|
|
613
|
+
modifiedIndex = originalIndex - diagonalRelative - diagonalForwardOffset;
|
|
614
|
+
if (originalIndex < lastOriginalIndex) {
|
|
615
|
+
changeHelper.MarkNextChange();
|
|
616
|
+
}
|
|
617
|
+
lastOriginalIndex = originalIndex;
|
|
618
|
+
changeHelper.AddModifiedElement(originalIndex + 1, modifiedIndex);
|
|
619
|
+
diagonalRelative = (diagonal + 1) - diagonalForwardBase; //Setup for the next iteration
|
|
620
|
+
}
|
|
621
|
+
else {
|
|
622
|
+
// Horizontal line (the element is a deletion)
|
|
623
|
+
originalIndex = forwardPoints[diagonal - 1] + 1;
|
|
624
|
+
modifiedIndex = originalIndex - diagonalRelative - diagonalForwardOffset;
|
|
625
|
+
if (originalIndex < lastOriginalIndex) {
|
|
626
|
+
changeHelper.MarkNextChange();
|
|
627
|
+
}
|
|
628
|
+
lastOriginalIndex = originalIndex - 1;
|
|
629
|
+
changeHelper.AddOriginalElement(originalIndex, modifiedIndex + 1);
|
|
630
|
+
diagonalRelative = (diagonal - 1) - diagonalForwardBase; //Setup for the next iteration
|
|
631
|
+
}
|
|
632
|
+
if (historyIndex >= 0) {
|
|
633
|
+
forwardPoints = this.m_forwardHistory[historyIndex];
|
|
634
|
+
diagonalForwardBase = forwardPoints[0]; //We stored this in the first spot
|
|
635
|
+
diagonalMin = 1;
|
|
636
|
+
diagonalMax = forwardPoints.length - 1;
|
|
637
|
+
}
|
|
638
|
+
} while (--historyIndex >= -1);
|
|
639
|
+
// Ironically, we get the forward changes as the reverse of the
|
|
640
|
+
// order we added them since we technically added them backwards
|
|
641
|
+
forwardChanges = changeHelper.getReverseChanges();
|
|
642
|
+
if (quitEarlyArr[0]) {
|
|
643
|
+
// TODO: Calculate a partial from the reverse diagonals.
|
|
644
|
+
// For now, just assume everything after the midOriginal/midModified point is a diff
|
|
645
|
+
let originalStartPoint = midOriginalArr[0] + 1;
|
|
646
|
+
let modifiedStartPoint = midModifiedArr[0] + 1;
|
|
647
|
+
if (forwardChanges !== null && forwardChanges.length > 0) {
|
|
648
|
+
const lastForwardChange = forwardChanges[forwardChanges.length - 1];
|
|
649
|
+
originalStartPoint = Math.max(originalStartPoint, lastForwardChange.getOriginalEnd());
|
|
650
|
+
modifiedStartPoint = Math.max(modifiedStartPoint, lastForwardChange.getModifiedEnd());
|
|
651
|
+
}
|
|
652
|
+
reverseChanges = [
|
|
653
|
+
new diffChange_1.DiffChange(originalStartPoint, originalEnd - originalStartPoint + 1, modifiedStartPoint, modifiedEnd - modifiedStartPoint + 1)
|
|
654
|
+
];
|
|
655
|
+
}
|
|
656
|
+
else {
|
|
657
|
+
// Now walk backward through the reverse diagonals history
|
|
658
|
+
changeHelper = new DiffChangeHelper();
|
|
659
|
+
diagonalMin = diagonalReverseStart;
|
|
660
|
+
diagonalMax = diagonalReverseEnd;
|
|
661
|
+
diagonalRelative = (midOriginalArr[0] - midModifiedArr[0]) - diagonalReverseOffset;
|
|
662
|
+
lastOriginalIndex = 1073741824 /* Constants.MAX_SAFE_SMALL_INTEGER */;
|
|
663
|
+
historyIndex = (deltaIsEven) ? this.m_reverseHistory.length - 1 : this.m_reverseHistory.length - 2;
|
|
664
|
+
do {
|
|
665
|
+
// Get the diagonal index from the relative diagonal number
|
|
666
|
+
const diagonal = diagonalRelative + diagonalReverseBase;
|
|
667
|
+
// Figure out where we came from
|
|
668
|
+
if (diagonal === diagonalMin || (diagonal < diagonalMax && reversePoints[diagonal - 1] >= reversePoints[diagonal + 1])) {
|
|
669
|
+
// Horizontal line (the element is a deletion))
|
|
670
|
+
originalIndex = reversePoints[diagonal + 1] - 1;
|
|
671
|
+
modifiedIndex = originalIndex - diagonalRelative - diagonalReverseOffset;
|
|
672
|
+
if (originalIndex > lastOriginalIndex) {
|
|
673
|
+
changeHelper.MarkNextChange();
|
|
674
|
+
}
|
|
675
|
+
lastOriginalIndex = originalIndex + 1;
|
|
676
|
+
changeHelper.AddOriginalElement(originalIndex + 1, modifiedIndex + 1);
|
|
677
|
+
diagonalRelative = (diagonal + 1) - diagonalReverseBase; //Setup for the next iteration
|
|
678
|
+
}
|
|
679
|
+
else {
|
|
680
|
+
// Vertical line (the element is an insertion)
|
|
681
|
+
originalIndex = reversePoints[diagonal - 1];
|
|
682
|
+
modifiedIndex = originalIndex - diagonalRelative - diagonalReverseOffset;
|
|
683
|
+
if (originalIndex > lastOriginalIndex) {
|
|
684
|
+
changeHelper.MarkNextChange();
|
|
685
|
+
}
|
|
686
|
+
lastOriginalIndex = originalIndex;
|
|
687
|
+
changeHelper.AddModifiedElement(originalIndex + 1, modifiedIndex + 1);
|
|
688
|
+
diagonalRelative = (diagonal - 1) - diagonalReverseBase; //Setup for the next iteration
|
|
689
|
+
}
|
|
690
|
+
if (historyIndex >= 0) {
|
|
691
|
+
reversePoints = this.m_reverseHistory[historyIndex];
|
|
692
|
+
diagonalReverseBase = reversePoints[0]; //We stored this in the first spot
|
|
693
|
+
diagonalMin = 1;
|
|
694
|
+
diagonalMax = reversePoints.length - 1;
|
|
695
|
+
}
|
|
696
|
+
} while (--historyIndex >= -1);
|
|
697
|
+
// There are cases where the reverse history will find diffs that
|
|
698
|
+
// are correct, but not intuitive, so we need shift them.
|
|
699
|
+
reverseChanges = changeHelper.getChanges();
|
|
700
|
+
}
|
|
701
|
+
return this.ConcatenateChanges(forwardChanges, reverseChanges);
|
|
702
|
+
}
|
|
703
|
+
/**
|
|
704
|
+
* Given the range to compute the diff on, this method finds the point:
|
|
705
|
+
* (midOriginal, midModified)
|
|
706
|
+
* that exists in the middle of the LCS of the two sequences and
|
|
707
|
+
* is the point at which the LCS problem may be broken down recursively.
|
|
708
|
+
* This method will try to keep the LCS trace in memory. If the LCS recursion
|
|
709
|
+
* point is calculated and the full trace is available in memory, then this method
|
|
710
|
+
* will return the change list.
|
|
711
|
+
* @param originalStart The start bound of the original sequence range
|
|
712
|
+
* @param originalEnd The end bound of the original sequence range
|
|
713
|
+
* @param modifiedStart The start bound of the modified sequence range
|
|
714
|
+
* @param modifiedEnd The end bound of the modified sequence range
|
|
715
|
+
* @param midOriginal The middle point of the original sequence range
|
|
716
|
+
* @param midModified The middle point of the modified sequence range
|
|
717
|
+
* @returns The diff changes, if available, otherwise null
|
|
718
|
+
*/
|
|
719
|
+
ComputeRecursionPoint(originalStart, originalEnd, modifiedStart, modifiedEnd, midOriginalArr, midModifiedArr, quitEarlyArr) {
|
|
720
|
+
let originalIndex = 0, modifiedIndex = 0;
|
|
721
|
+
let diagonalForwardStart = 0, diagonalForwardEnd = 0;
|
|
722
|
+
let diagonalReverseStart = 0, diagonalReverseEnd = 0;
|
|
723
|
+
// To traverse the edit graph and produce the proper LCS, our actual
|
|
724
|
+
// start position is just outside the given boundary
|
|
725
|
+
originalStart--;
|
|
726
|
+
modifiedStart--;
|
|
727
|
+
// We set these up to make the compiler happy, but they will
|
|
728
|
+
// be replaced before we return with the actual recursion point
|
|
729
|
+
midOriginalArr[0] = 0;
|
|
730
|
+
midModifiedArr[0] = 0;
|
|
731
|
+
// Clear out the history
|
|
732
|
+
this.m_forwardHistory = [];
|
|
733
|
+
this.m_reverseHistory = [];
|
|
734
|
+
// Each cell in the two arrays corresponds to a diagonal in the edit graph.
|
|
735
|
+
// The integer value in the cell represents the originalIndex of the furthest
|
|
736
|
+
// reaching point found so far that ends in that diagonal.
|
|
737
|
+
// The modifiedIndex can be computed mathematically from the originalIndex and the diagonal number.
|
|
738
|
+
const maxDifferences = (originalEnd - originalStart) + (modifiedEnd - modifiedStart);
|
|
739
|
+
const numDiagonals = maxDifferences + 1;
|
|
740
|
+
const forwardPoints = new Int32Array(numDiagonals);
|
|
741
|
+
const reversePoints = new Int32Array(numDiagonals);
|
|
742
|
+
// diagonalForwardBase: Index into forwardPoints of the diagonal which passes through (originalStart, modifiedStart)
|
|
743
|
+
// diagonalReverseBase: Index into reversePoints of the diagonal which passes through (originalEnd, modifiedEnd)
|
|
744
|
+
const diagonalForwardBase = (modifiedEnd - modifiedStart);
|
|
745
|
+
const diagonalReverseBase = (originalEnd - originalStart);
|
|
746
|
+
// diagonalForwardOffset: Geometric offset which allows modifiedIndex to be computed from originalIndex and the
|
|
747
|
+
// diagonal number (relative to diagonalForwardBase)
|
|
748
|
+
// diagonalReverseOffset: Geometric offset which allows modifiedIndex to be computed from originalIndex and the
|
|
749
|
+
// diagonal number (relative to diagonalReverseBase)
|
|
750
|
+
const diagonalForwardOffset = (originalStart - modifiedStart);
|
|
751
|
+
const diagonalReverseOffset = (originalEnd - modifiedEnd);
|
|
752
|
+
// delta: The difference between the end diagonal and the start diagonal. This is used to relate diagonal numbers
|
|
753
|
+
// relative to the start diagonal with diagonal numbers relative to the end diagonal.
|
|
754
|
+
// The Even/Oddn-ness of this delta is important for determining when we should check for overlap
|
|
755
|
+
const delta = diagonalReverseBase - diagonalForwardBase;
|
|
756
|
+
const deltaIsEven = (delta % 2 === 0);
|
|
757
|
+
// Here we set up the start and end points as the furthest points found so far
|
|
758
|
+
// in both the forward and reverse directions, respectively
|
|
759
|
+
forwardPoints[diagonalForwardBase] = originalStart;
|
|
760
|
+
reversePoints[diagonalReverseBase] = originalEnd;
|
|
761
|
+
// Remember if we quit early, and thus need to do a best-effort result instead of a real result.
|
|
762
|
+
quitEarlyArr[0] = false;
|
|
763
|
+
// A couple of points:
|
|
764
|
+
// --With this method, we iterate on the number of differences between the two sequences.
|
|
765
|
+
// The more differences there actually are, the longer this will take.
|
|
766
|
+
// --Also, as the number of differences increases, we have to search on diagonals further
|
|
767
|
+
// away from the reference diagonal (which is diagonalForwardBase for forward, diagonalReverseBase for reverse).
|
|
768
|
+
// --We extend on even diagonals (relative to the reference diagonal) only when numDifferences
|
|
769
|
+
// is even and odd diagonals only when numDifferences is odd.
|
|
770
|
+
for (let numDifferences = 1; numDifferences <= (maxDifferences / 2) + 1; numDifferences++) {
|
|
771
|
+
let furthestOriginalIndex = 0;
|
|
772
|
+
let furthestModifiedIndex = 0;
|
|
773
|
+
// Run the algorithm in the forward direction
|
|
774
|
+
diagonalForwardStart = this.ClipDiagonalBound(diagonalForwardBase - numDifferences, numDifferences, diagonalForwardBase, numDiagonals);
|
|
775
|
+
diagonalForwardEnd = this.ClipDiagonalBound(diagonalForwardBase + numDifferences, numDifferences, diagonalForwardBase, numDiagonals);
|
|
776
|
+
for (let diagonal = diagonalForwardStart; diagonal <= diagonalForwardEnd; diagonal += 2) {
|
|
777
|
+
// STEP 1: We extend the furthest reaching point in the present diagonal
|
|
778
|
+
// by looking at the diagonals above and below and picking the one whose point
|
|
779
|
+
// is further away from the start point (originalStart, modifiedStart)
|
|
780
|
+
if (diagonal === diagonalForwardStart || (diagonal < diagonalForwardEnd && forwardPoints[diagonal - 1] < forwardPoints[diagonal + 1])) {
|
|
781
|
+
originalIndex = forwardPoints[diagonal + 1];
|
|
782
|
+
}
|
|
783
|
+
else {
|
|
784
|
+
originalIndex = forwardPoints[diagonal - 1] + 1;
|
|
785
|
+
}
|
|
786
|
+
modifiedIndex = originalIndex - (diagonal - diagonalForwardBase) - diagonalForwardOffset;
|
|
787
|
+
// Save the current originalIndex so we can test for false overlap in step 3
|
|
788
|
+
const tempOriginalIndex = originalIndex;
|
|
789
|
+
// STEP 2: We can continue to extend the furthest reaching point in the present diagonal
|
|
790
|
+
// so long as the elements are equal.
|
|
791
|
+
while (originalIndex < originalEnd && modifiedIndex < modifiedEnd && this.ElementsAreEqual(originalIndex + 1, modifiedIndex + 1)) {
|
|
792
|
+
originalIndex++;
|
|
793
|
+
modifiedIndex++;
|
|
794
|
+
}
|
|
795
|
+
forwardPoints[diagonal] = originalIndex;
|
|
796
|
+
if (originalIndex + modifiedIndex > furthestOriginalIndex + furthestModifiedIndex) {
|
|
797
|
+
furthestOriginalIndex = originalIndex;
|
|
798
|
+
furthestModifiedIndex = modifiedIndex;
|
|
799
|
+
}
|
|
800
|
+
// STEP 3: If delta is odd (overlap first happens on forward when delta is odd)
|
|
801
|
+
// and diagonal is in the range of reverse diagonals computed for numDifferences-1
|
|
802
|
+
// (the previous iteration; we haven't computed reverse diagonals for numDifferences yet)
|
|
803
|
+
// then check for overlap.
|
|
804
|
+
if (!deltaIsEven && Math.abs(diagonal - diagonalReverseBase) <= (numDifferences - 1)) {
|
|
805
|
+
if (originalIndex >= reversePoints[diagonal]) {
|
|
806
|
+
midOriginalArr[0] = originalIndex;
|
|
807
|
+
midModifiedArr[0] = modifiedIndex;
|
|
808
|
+
if (tempOriginalIndex <= reversePoints[diagonal] && 1447 /* LocalConstants.MaxDifferencesHistory */ > 0 && numDifferences <= (1447 /* LocalConstants.MaxDifferencesHistory */ + 1)) {
|
|
809
|
+
// BINGO! We overlapped, and we have the full trace in memory!
|
|
810
|
+
return this.WALKTRACE(diagonalForwardBase, diagonalForwardStart, diagonalForwardEnd, diagonalForwardOffset, diagonalReverseBase, diagonalReverseStart, diagonalReverseEnd, diagonalReverseOffset, forwardPoints, reversePoints, originalIndex, originalEnd, midOriginalArr, modifiedIndex, modifiedEnd, midModifiedArr, deltaIsEven, quitEarlyArr);
|
|
811
|
+
}
|
|
812
|
+
else {
|
|
813
|
+
// Either false overlap, or we didn't have enough memory for the full trace
|
|
814
|
+
// Just return the recursion point
|
|
815
|
+
return null;
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
// Check to see if we should be quitting early, before moving on to the next iteration.
|
|
821
|
+
const matchLengthOfLongest = ((furthestOriginalIndex - originalStart) + (furthestModifiedIndex - modifiedStart) - numDifferences) / 2;
|
|
822
|
+
if (this.ContinueProcessingPredicate !== null && !this.ContinueProcessingPredicate(furthestOriginalIndex, matchLengthOfLongest)) {
|
|
823
|
+
// We can't finish, so skip ahead to generating a result from what we have.
|
|
824
|
+
quitEarlyArr[0] = true;
|
|
825
|
+
// Use the furthest distance we got in the forward direction.
|
|
826
|
+
midOriginalArr[0] = furthestOriginalIndex;
|
|
827
|
+
midModifiedArr[0] = furthestModifiedIndex;
|
|
828
|
+
if (matchLengthOfLongest > 0 && 1447 /* LocalConstants.MaxDifferencesHistory */ > 0 && numDifferences <= (1447 /* LocalConstants.MaxDifferencesHistory */ + 1)) {
|
|
829
|
+
// Enough of the history is in memory to walk it backwards
|
|
830
|
+
return this.WALKTRACE(diagonalForwardBase, diagonalForwardStart, diagonalForwardEnd, diagonalForwardOffset, diagonalReverseBase, diagonalReverseStart, diagonalReverseEnd, diagonalReverseOffset, forwardPoints, reversePoints, originalIndex, originalEnd, midOriginalArr, modifiedIndex, modifiedEnd, midModifiedArr, deltaIsEven, quitEarlyArr);
|
|
831
|
+
}
|
|
832
|
+
else {
|
|
833
|
+
// We didn't actually remember enough of the history.
|
|
834
|
+
//Since we are quitting the diff early, we need to shift back the originalStart and modified start
|
|
835
|
+
//back into the boundary limits since we decremented their value above beyond the boundary limit.
|
|
836
|
+
originalStart++;
|
|
837
|
+
modifiedStart++;
|
|
838
|
+
return [
|
|
839
|
+
new diffChange_1.DiffChange(originalStart, originalEnd - originalStart + 1, modifiedStart, modifiedEnd - modifiedStart + 1)
|
|
840
|
+
];
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
// Run the algorithm in the reverse direction
|
|
844
|
+
diagonalReverseStart = this.ClipDiagonalBound(diagonalReverseBase - numDifferences, numDifferences, diagonalReverseBase, numDiagonals);
|
|
845
|
+
diagonalReverseEnd = this.ClipDiagonalBound(diagonalReverseBase + numDifferences, numDifferences, diagonalReverseBase, numDiagonals);
|
|
846
|
+
for (let diagonal = diagonalReverseStart; diagonal <= diagonalReverseEnd; diagonal += 2) {
|
|
847
|
+
// STEP 1: We extend the furthest reaching point in the present diagonal
|
|
848
|
+
// by looking at the diagonals above and below and picking the one whose point
|
|
849
|
+
// is further away from the start point (originalEnd, modifiedEnd)
|
|
850
|
+
if (diagonal === diagonalReverseStart || (diagonal < diagonalReverseEnd && reversePoints[diagonal - 1] >= reversePoints[diagonal + 1])) {
|
|
851
|
+
originalIndex = reversePoints[diagonal + 1] - 1;
|
|
852
|
+
}
|
|
853
|
+
else {
|
|
854
|
+
originalIndex = reversePoints[diagonal - 1];
|
|
855
|
+
}
|
|
856
|
+
modifiedIndex = originalIndex - (diagonal - diagonalReverseBase) - diagonalReverseOffset;
|
|
857
|
+
// Save the current originalIndex so we can test for false overlap
|
|
858
|
+
const tempOriginalIndex = originalIndex;
|
|
859
|
+
// STEP 2: We can continue to extend the furthest reaching point in the present diagonal
|
|
860
|
+
// as long as the elements are equal.
|
|
861
|
+
while (originalIndex > originalStart && modifiedIndex > modifiedStart && this.ElementsAreEqual(originalIndex, modifiedIndex)) {
|
|
862
|
+
originalIndex--;
|
|
863
|
+
modifiedIndex--;
|
|
864
|
+
}
|
|
865
|
+
reversePoints[diagonal] = originalIndex;
|
|
866
|
+
// STEP 4: If delta is even (overlap first happens on reverse when delta is even)
|
|
867
|
+
// and diagonal is in the range of forward diagonals computed for numDifferences
|
|
868
|
+
// then check for overlap.
|
|
869
|
+
if (deltaIsEven && Math.abs(diagonal - diagonalForwardBase) <= numDifferences) {
|
|
870
|
+
if (originalIndex <= forwardPoints[diagonal]) {
|
|
871
|
+
midOriginalArr[0] = originalIndex;
|
|
872
|
+
midModifiedArr[0] = modifiedIndex;
|
|
873
|
+
if (tempOriginalIndex >= forwardPoints[diagonal] && 1447 /* LocalConstants.MaxDifferencesHistory */ > 0 && numDifferences <= (1447 /* LocalConstants.MaxDifferencesHistory */ + 1)) {
|
|
874
|
+
// BINGO! We overlapped, and we have the full trace in memory!
|
|
875
|
+
return this.WALKTRACE(diagonalForwardBase, diagonalForwardStart, diagonalForwardEnd, diagonalForwardOffset, diagonalReverseBase, diagonalReverseStart, diagonalReverseEnd, diagonalReverseOffset, forwardPoints, reversePoints, originalIndex, originalEnd, midOriginalArr, modifiedIndex, modifiedEnd, midModifiedArr, deltaIsEven, quitEarlyArr);
|
|
876
|
+
}
|
|
877
|
+
else {
|
|
878
|
+
// Either false overlap, or we didn't have enough memory for the full trace
|
|
879
|
+
// Just return the recursion point
|
|
880
|
+
return null;
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
// Save current vectors to history before the next iteration
|
|
886
|
+
if (numDifferences <= 1447 /* LocalConstants.MaxDifferencesHistory */) {
|
|
887
|
+
// We are allocating space for one extra int, which we fill with
|
|
888
|
+
// the index of the diagonal base index
|
|
889
|
+
let temp = new Int32Array(diagonalForwardEnd - diagonalForwardStart + 2);
|
|
890
|
+
temp[0] = diagonalForwardBase - diagonalForwardStart + 1;
|
|
891
|
+
MyArray.Copy2(forwardPoints, diagonalForwardStart, temp, 1, diagonalForwardEnd - diagonalForwardStart + 1);
|
|
892
|
+
this.m_forwardHistory.push(temp);
|
|
893
|
+
temp = new Int32Array(diagonalReverseEnd - diagonalReverseStart + 2);
|
|
894
|
+
temp[0] = diagonalReverseBase - diagonalReverseStart + 1;
|
|
895
|
+
MyArray.Copy2(reversePoints, diagonalReverseStart, temp, 1, diagonalReverseEnd - diagonalReverseStart + 1);
|
|
896
|
+
this.m_reverseHistory.push(temp);
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
// If we got here, then we have the full trace in history. We just have to convert it to a change list
|
|
900
|
+
// NOTE: This part is a bit messy
|
|
901
|
+
return this.WALKTRACE(diagonalForwardBase, diagonalForwardStart, diagonalForwardEnd, diagonalForwardOffset, diagonalReverseBase, diagonalReverseStart, diagonalReverseEnd, diagonalReverseOffset, forwardPoints, reversePoints, originalIndex, originalEnd, midOriginalArr, modifiedIndex, modifiedEnd, midModifiedArr, deltaIsEven, quitEarlyArr);
|
|
902
|
+
}
|
|
903
|
+
/**
|
|
904
|
+
* Shifts the given changes to provide a more intuitive diff.
|
|
905
|
+
* While the first element in a diff matches the first element after the diff,
|
|
906
|
+
* we shift the diff down.
|
|
907
|
+
*
|
|
908
|
+
* @param changes The list of changes to shift
|
|
909
|
+
* @returns The shifted changes
|
|
910
|
+
*/
|
|
911
|
+
PrettifyChanges(changes) {
|
|
912
|
+
// Shift all the changes down first
|
|
913
|
+
for (let i = 0; i < changes.length; i++) {
|
|
914
|
+
const change = changes[i];
|
|
915
|
+
const originalStop = (i < changes.length - 1) ? changes[i + 1].originalStart : this._originalElementsOrHash.length;
|
|
916
|
+
const modifiedStop = (i < changes.length - 1) ? changes[i + 1].modifiedStart : this._modifiedElementsOrHash.length;
|
|
917
|
+
const checkOriginal = change.originalLength > 0;
|
|
918
|
+
const checkModified = change.modifiedLength > 0;
|
|
919
|
+
while (change.originalStart + change.originalLength < originalStop
|
|
920
|
+
&& change.modifiedStart + change.modifiedLength < modifiedStop
|
|
921
|
+
&& (!checkOriginal || this.OriginalElementsAreEqual(change.originalStart, change.originalStart + change.originalLength))
|
|
922
|
+
&& (!checkModified || this.ModifiedElementsAreEqual(change.modifiedStart, change.modifiedStart + change.modifiedLength))) {
|
|
923
|
+
const startStrictEqual = this.ElementsAreStrictEqual(change.originalStart, change.modifiedStart);
|
|
924
|
+
const endStrictEqual = this.ElementsAreStrictEqual(change.originalStart + change.originalLength, change.modifiedStart + change.modifiedLength);
|
|
925
|
+
if (endStrictEqual && !startStrictEqual) {
|
|
926
|
+
// moving the change down would create an equal change, but the elements are not strict equal
|
|
927
|
+
break;
|
|
928
|
+
}
|
|
929
|
+
change.originalStart++;
|
|
930
|
+
change.modifiedStart++;
|
|
931
|
+
}
|
|
932
|
+
const mergedChangeArr = [null];
|
|
933
|
+
if (i < changes.length - 1 && this.ChangesOverlap(changes[i], changes[i + 1], mergedChangeArr)) {
|
|
934
|
+
changes[i] = mergedChangeArr[0];
|
|
935
|
+
changes.splice(i + 1, 1);
|
|
936
|
+
i--;
|
|
937
|
+
continue;
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
// Shift changes back up until we hit empty or whitespace-only lines
|
|
941
|
+
for (let i = changes.length - 1; i >= 0; i--) {
|
|
942
|
+
const change = changes[i];
|
|
943
|
+
let originalStop = 0;
|
|
944
|
+
let modifiedStop = 0;
|
|
945
|
+
if (i > 0) {
|
|
946
|
+
const prevChange = changes[i - 1];
|
|
947
|
+
originalStop = prevChange.originalStart + prevChange.originalLength;
|
|
948
|
+
modifiedStop = prevChange.modifiedStart + prevChange.modifiedLength;
|
|
949
|
+
}
|
|
950
|
+
const checkOriginal = change.originalLength > 0;
|
|
951
|
+
const checkModified = change.modifiedLength > 0;
|
|
952
|
+
let bestDelta = 0;
|
|
953
|
+
let bestScore = this._boundaryScore(change.originalStart, change.originalLength, change.modifiedStart, change.modifiedLength);
|
|
954
|
+
for (let delta = 1;; delta++) {
|
|
955
|
+
const originalStart = change.originalStart - delta;
|
|
956
|
+
const modifiedStart = change.modifiedStart - delta;
|
|
957
|
+
if (originalStart < originalStop || modifiedStart < modifiedStop) {
|
|
958
|
+
break;
|
|
959
|
+
}
|
|
960
|
+
if (checkOriginal && !this.OriginalElementsAreEqual(originalStart, originalStart + change.originalLength)) {
|
|
961
|
+
break;
|
|
962
|
+
}
|
|
963
|
+
if (checkModified && !this.ModifiedElementsAreEqual(modifiedStart, modifiedStart + change.modifiedLength)) {
|
|
964
|
+
break;
|
|
965
|
+
}
|
|
966
|
+
const touchingPreviousChange = (originalStart === originalStop && modifiedStart === modifiedStop);
|
|
967
|
+
const score = ((touchingPreviousChange ? 5 : 0)
|
|
968
|
+
+ this._boundaryScore(originalStart, change.originalLength, modifiedStart, change.modifiedLength));
|
|
969
|
+
if (score > bestScore) {
|
|
970
|
+
bestScore = score;
|
|
971
|
+
bestDelta = delta;
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
change.originalStart -= bestDelta;
|
|
975
|
+
change.modifiedStart -= bestDelta;
|
|
976
|
+
const mergedChangeArr = [null];
|
|
977
|
+
if (i > 0 && this.ChangesOverlap(changes[i - 1], changes[i], mergedChangeArr)) {
|
|
978
|
+
changes[i - 1] = mergedChangeArr[0];
|
|
979
|
+
changes.splice(i, 1);
|
|
980
|
+
i++;
|
|
981
|
+
continue;
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
// There could be multiple longest common substrings.
|
|
985
|
+
// Give preference to the ones containing longer lines
|
|
986
|
+
if (this._hasStrings) {
|
|
987
|
+
for (let i = 1, len = changes.length; i < len; i++) {
|
|
988
|
+
const aChange = changes[i - 1];
|
|
989
|
+
const bChange = changes[i];
|
|
990
|
+
const matchedLength = bChange.originalStart - aChange.originalStart - aChange.originalLength;
|
|
991
|
+
const aOriginalStart = aChange.originalStart;
|
|
992
|
+
const bOriginalEnd = bChange.originalStart + bChange.originalLength;
|
|
993
|
+
const abOriginalLength = bOriginalEnd - aOriginalStart;
|
|
994
|
+
const aModifiedStart = aChange.modifiedStart;
|
|
995
|
+
const bModifiedEnd = bChange.modifiedStart + bChange.modifiedLength;
|
|
996
|
+
const abModifiedLength = bModifiedEnd - aModifiedStart;
|
|
997
|
+
// Avoid wasting a lot of time with these searches
|
|
998
|
+
if (matchedLength < 5 && abOriginalLength < 20 && abModifiedLength < 20) {
|
|
999
|
+
const t = this._findBetterContiguousSequence(aOriginalStart, abOriginalLength, aModifiedStart, abModifiedLength, matchedLength);
|
|
1000
|
+
if (t) {
|
|
1001
|
+
const [originalMatchStart, modifiedMatchStart] = t;
|
|
1002
|
+
if (originalMatchStart !== aChange.originalStart + aChange.originalLength || modifiedMatchStart !== aChange.modifiedStart + aChange.modifiedLength) {
|
|
1003
|
+
// switch to another sequence that has a better score
|
|
1004
|
+
aChange.originalLength = originalMatchStart - aChange.originalStart;
|
|
1005
|
+
aChange.modifiedLength = modifiedMatchStart - aChange.modifiedStart;
|
|
1006
|
+
bChange.originalStart = originalMatchStart + matchedLength;
|
|
1007
|
+
bChange.modifiedStart = modifiedMatchStart + matchedLength;
|
|
1008
|
+
bChange.originalLength = bOriginalEnd - bChange.originalStart;
|
|
1009
|
+
bChange.modifiedLength = bModifiedEnd - bChange.modifiedStart;
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
return changes;
|
|
1016
|
+
}
|
|
1017
|
+
_findBetterContiguousSequence(originalStart, originalLength, modifiedStart, modifiedLength, desiredLength) {
|
|
1018
|
+
if (originalLength < desiredLength || modifiedLength < desiredLength) {
|
|
1019
|
+
return null;
|
|
1020
|
+
}
|
|
1021
|
+
const originalMax = originalStart + originalLength - desiredLength + 1;
|
|
1022
|
+
const modifiedMax = modifiedStart + modifiedLength - desiredLength + 1;
|
|
1023
|
+
let bestScore = 0;
|
|
1024
|
+
let bestOriginalStart = 0;
|
|
1025
|
+
let bestModifiedStart = 0;
|
|
1026
|
+
for (let i = originalStart; i < originalMax; i++) {
|
|
1027
|
+
for (let j = modifiedStart; j < modifiedMax; j++) {
|
|
1028
|
+
const score = this._contiguousSequenceScore(i, j, desiredLength);
|
|
1029
|
+
if (score > 0 && score > bestScore) {
|
|
1030
|
+
bestScore = score;
|
|
1031
|
+
bestOriginalStart = i;
|
|
1032
|
+
bestModifiedStart = j;
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
if (bestScore > 0) {
|
|
1037
|
+
return [bestOriginalStart, bestModifiedStart];
|
|
1038
|
+
}
|
|
1039
|
+
return null;
|
|
1040
|
+
}
|
|
1041
|
+
_contiguousSequenceScore(originalStart, modifiedStart, length) {
|
|
1042
|
+
let score = 0;
|
|
1043
|
+
for (let l = 0; l < length; l++) {
|
|
1044
|
+
if (!this.ElementsAreEqual(originalStart + l, modifiedStart + l)) {
|
|
1045
|
+
return 0;
|
|
1046
|
+
}
|
|
1047
|
+
score += this._originalStringElements[originalStart + l].length;
|
|
1048
|
+
}
|
|
1049
|
+
return score;
|
|
1050
|
+
}
|
|
1051
|
+
_OriginalIsBoundary(index) {
|
|
1052
|
+
if (index <= 0 || index >= this._originalElementsOrHash.length - 1) {
|
|
1053
|
+
return true;
|
|
1054
|
+
}
|
|
1055
|
+
return (this._hasStrings && /^\s*$/.test(this._originalStringElements[index]));
|
|
1056
|
+
}
|
|
1057
|
+
_OriginalRegionIsBoundary(originalStart, originalLength) {
|
|
1058
|
+
if (this._OriginalIsBoundary(originalStart) || this._OriginalIsBoundary(originalStart - 1)) {
|
|
1059
|
+
return true;
|
|
1060
|
+
}
|
|
1061
|
+
if (originalLength > 0) {
|
|
1062
|
+
const originalEnd = originalStart + originalLength;
|
|
1063
|
+
if (this._OriginalIsBoundary(originalEnd - 1) || this._OriginalIsBoundary(originalEnd)) {
|
|
1064
|
+
return true;
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
return false;
|
|
1068
|
+
}
|
|
1069
|
+
_ModifiedIsBoundary(index) {
|
|
1070
|
+
if (index <= 0 || index >= this._modifiedElementsOrHash.length - 1) {
|
|
1071
|
+
return true;
|
|
1072
|
+
}
|
|
1073
|
+
return (this._hasStrings && /^\s*$/.test(this._modifiedStringElements[index]));
|
|
1074
|
+
}
|
|
1075
|
+
_ModifiedRegionIsBoundary(modifiedStart, modifiedLength) {
|
|
1076
|
+
if (this._ModifiedIsBoundary(modifiedStart) || this._ModifiedIsBoundary(modifiedStart - 1)) {
|
|
1077
|
+
return true;
|
|
1078
|
+
}
|
|
1079
|
+
if (modifiedLength > 0) {
|
|
1080
|
+
const modifiedEnd = modifiedStart + modifiedLength;
|
|
1081
|
+
if (this._ModifiedIsBoundary(modifiedEnd - 1) || this._ModifiedIsBoundary(modifiedEnd)) {
|
|
1082
|
+
return true;
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
return false;
|
|
1086
|
+
}
|
|
1087
|
+
_boundaryScore(originalStart, originalLength, modifiedStart, modifiedLength) {
|
|
1088
|
+
const originalScore = (this._OriginalRegionIsBoundary(originalStart, originalLength) ? 1 : 0);
|
|
1089
|
+
const modifiedScore = (this._ModifiedRegionIsBoundary(modifiedStart, modifiedLength) ? 1 : 0);
|
|
1090
|
+
return (originalScore + modifiedScore);
|
|
1091
|
+
}
|
|
1092
|
+
/**
|
|
1093
|
+
* Concatenates the two input DiffChange lists and returns the resulting
|
|
1094
|
+
* list.
|
|
1095
|
+
* @param The left changes
|
|
1096
|
+
* @param The right changes
|
|
1097
|
+
* @returns The concatenated list
|
|
1098
|
+
*/
|
|
1099
|
+
ConcatenateChanges(left, right) {
|
|
1100
|
+
const mergedChangeArr = [];
|
|
1101
|
+
if (left.length === 0 || right.length === 0) {
|
|
1102
|
+
return (right.length > 0) ? right : left;
|
|
1103
|
+
}
|
|
1104
|
+
else if (this.ChangesOverlap(left[left.length - 1], right[0], mergedChangeArr)) {
|
|
1105
|
+
// Since we break the problem down recursively, it is possible that we
|
|
1106
|
+
// might recurse in the middle of a change thereby splitting it into
|
|
1107
|
+
// two changes. Here in the combining stage, we detect and fuse those
|
|
1108
|
+
// changes back together
|
|
1109
|
+
const result = new Array(left.length + right.length - 1);
|
|
1110
|
+
MyArray.Copy(left, 0, result, 0, left.length - 1);
|
|
1111
|
+
result[left.length - 1] = mergedChangeArr[0];
|
|
1112
|
+
MyArray.Copy(right, 1, result, left.length, right.length - 1);
|
|
1113
|
+
return result;
|
|
1114
|
+
}
|
|
1115
|
+
else {
|
|
1116
|
+
const result = new Array(left.length + right.length);
|
|
1117
|
+
MyArray.Copy(left, 0, result, 0, left.length);
|
|
1118
|
+
MyArray.Copy(right, 0, result, left.length, right.length);
|
|
1119
|
+
return result;
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
/**
|
|
1123
|
+
* Returns true if the two changes overlap and can be merged into a single
|
|
1124
|
+
* change
|
|
1125
|
+
* @param left The left change
|
|
1126
|
+
* @param right The right change
|
|
1127
|
+
* @param mergedChange The merged change if the two overlap, null otherwise
|
|
1128
|
+
* @returns True if the two changes overlap
|
|
1129
|
+
*/
|
|
1130
|
+
ChangesOverlap(left, right, mergedChangeArr) {
|
|
1131
|
+
Debug.Assert(left.originalStart <= right.originalStart, 'Left change is not less than or equal to right change');
|
|
1132
|
+
Debug.Assert(left.modifiedStart <= right.modifiedStart, 'Left change is not less than or equal to right change');
|
|
1133
|
+
if (left.originalStart + left.originalLength >= right.originalStart || left.modifiedStart + left.modifiedLength >= right.modifiedStart) {
|
|
1134
|
+
const originalStart = left.originalStart;
|
|
1135
|
+
let originalLength = left.originalLength;
|
|
1136
|
+
const modifiedStart = left.modifiedStart;
|
|
1137
|
+
let modifiedLength = left.modifiedLength;
|
|
1138
|
+
if (left.originalStart + left.originalLength >= right.originalStart) {
|
|
1139
|
+
originalLength = right.originalStart + right.originalLength - left.originalStart;
|
|
1140
|
+
}
|
|
1141
|
+
if (left.modifiedStart + left.modifiedLength >= right.modifiedStart) {
|
|
1142
|
+
modifiedLength = right.modifiedStart + right.modifiedLength - left.modifiedStart;
|
|
1143
|
+
}
|
|
1144
|
+
mergedChangeArr[0] = new diffChange_1.DiffChange(originalStart, originalLength, modifiedStart, modifiedLength);
|
|
1145
|
+
return true;
|
|
1146
|
+
}
|
|
1147
|
+
else {
|
|
1148
|
+
mergedChangeArr[0] = null;
|
|
1149
|
+
return false;
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1152
|
+
/**
|
|
1153
|
+
* Helper method used to clip a diagonal index to the range of valid
|
|
1154
|
+
* diagonals. This also decides whether or not the diagonal index,
|
|
1155
|
+
* if it exceeds the boundary, should be clipped to the boundary or clipped
|
|
1156
|
+
* one inside the boundary depending on the Even/Odd status of the boundary
|
|
1157
|
+
* and numDifferences.
|
|
1158
|
+
* @param diagonal The index of the diagonal to clip.
|
|
1159
|
+
* @param numDifferences The current number of differences being iterated upon.
|
|
1160
|
+
* @param diagonalBaseIndex The base reference diagonal.
|
|
1161
|
+
* @param numDiagonals The total number of diagonals.
|
|
1162
|
+
* @returns The clipped diagonal index.
|
|
1163
|
+
*/
|
|
1164
|
+
ClipDiagonalBound(diagonal, numDifferences, diagonalBaseIndex, numDiagonals) {
|
|
1165
|
+
if (diagonal >= 0 && diagonal < numDiagonals) {
|
|
1166
|
+
// Nothing to clip, its in range
|
|
1167
|
+
return diagonal;
|
|
1168
|
+
}
|
|
1169
|
+
// diagonalsBelow: The number of diagonals below the reference diagonal
|
|
1170
|
+
// diagonalsAbove: The number of diagonals above the reference diagonal
|
|
1171
|
+
const diagonalsBelow = diagonalBaseIndex;
|
|
1172
|
+
const diagonalsAbove = numDiagonals - diagonalBaseIndex - 1;
|
|
1173
|
+
const diffEven = (numDifferences % 2 === 0);
|
|
1174
|
+
if (diagonal < 0) {
|
|
1175
|
+
const lowerBoundEven = (diagonalsBelow % 2 === 0);
|
|
1176
|
+
return (diffEven === lowerBoundEven) ? 0 : 1;
|
|
1177
|
+
}
|
|
1178
|
+
else {
|
|
1179
|
+
const upperBoundEven = (diagonalsAbove % 2 === 0);
|
|
1180
|
+
return (diffEven === upperBoundEven) ? numDiagonals - 1 : numDiagonals - 2;
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
exports.LcsDiff = LcsDiff;
|
|
1185
|
+
|
|
1186
|
+
|
|
1187
|
+
/***/ }),
|
|
1188
|
+
|
|
1189
|
+
/***/ "./node_modules/vscode-diff/dist/vs/base/common/diff/diffChange.js":
|
|
1190
|
+
/*!*************************************************************************!*\
|
|
1191
|
+
!*** ./node_modules/vscode-diff/dist/vs/base/common/diff/diffChange.js ***!
|
|
1192
|
+
\*************************************************************************/
|
|
1193
|
+
/***/ ((__unused_webpack_module, exports) => {
|
|
1194
|
+
|
|
1195
|
+
|
|
1196
|
+
/*---------------------------------------------------------------------------------------------
|
|
1197
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
1198
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
1199
|
+
*--------------------------------------------------------------------------------------------*/
|
|
1200
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
1201
|
+
exports.DiffChange = void 0;
|
|
1202
|
+
/**
|
|
1203
|
+
* Represents information about a specific difference between two sequences.
|
|
1204
|
+
*/
|
|
1205
|
+
class DiffChange {
|
|
1206
|
+
/**
|
|
1207
|
+
* Constructs a new DiffChange with the given sequence information
|
|
1208
|
+
* and content.
|
|
1209
|
+
*/
|
|
1210
|
+
constructor(originalStart, originalLength, modifiedStart, modifiedLength) {
|
|
1211
|
+
//Debug.Assert(originalLength > 0 || modifiedLength > 0, "originalLength and modifiedLength cannot both be <= 0");
|
|
1212
|
+
this.originalStart = originalStart;
|
|
1213
|
+
this.originalLength = originalLength;
|
|
1214
|
+
this.modifiedStart = modifiedStart;
|
|
1215
|
+
this.modifiedLength = modifiedLength;
|
|
1216
|
+
}
|
|
1217
|
+
/**
|
|
1218
|
+
* The end point (exclusive) of the change in the original sequence.
|
|
1219
|
+
*/
|
|
1220
|
+
getOriginalEnd() {
|
|
1221
|
+
return this.originalStart + this.originalLength;
|
|
1222
|
+
}
|
|
1223
|
+
/**
|
|
1224
|
+
* The end point (exclusive) of the change in the modified sequence.
|
|
1225
|
+
*/
|
|
1226
|
+
getModifiedEnd() {
|
|
1227
|
+
return this.modifiedStart + this.modifiedLength;
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
exports.DiffChange = DiffChange;
|
|
1231
|
+
|
|
1232
|
+
|
|
1233
|
+
/***/ }),
|
|
1234
|
+
|
|
1235
|
+
/***/ "./node_modules/vscode-diff/dist/vs/base/common/errors.js":
|
|
1236
|
+
/*!****************************************************************!*\
|
|
1237
|
+
!*** ./node_modules/vscode-diff/dist/vs/base/common/errors.js ***!
|
|
1238
|
+
\****************************************************************/
|
|
1239
|
+
/***/ ((__unused_webpack_module, exports) => {
|
|
1240
|
+
|
|
1241
|
+
|
|
1242
|
+
/*---------------------------------------------------------------------------------------------
|
|
1243
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
1244
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
1245
|
+
*--------------------------------------------------------------------------------------------*/
|
|
1246
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
1247
|
+
exports.BugIndicatingError = exports.ErrorNoTelemetry = exports.CancellationError = exports.isCancellationError = exports.onUnexpectedError = exports.errorHandler = exports.ErrorHandler = void 0;
|
|
1248
|
+
// Avoid circular dependency on EventEmitter by implementing a subset of the interface.
|
|
1249
|
+
class ErrorHandler {
|
|
1250
|
+
constructor() {
|
|
1251
|
+
this.listeners = [];
|
|
1252
|
+
this.unexpectedErrorHandler = function (e) {
|
|
1253
|
+
setTimeout(() => {
|
|
1254
|
+
if (e.stack) {
|
|
1255
|
+
if (ErrorNoTelemetry.isErrorNoTelemetry(e)) {
|
|
1256
|
+
throw new ErrorNoTelemetry(e.message + '\n\n' + e.stack);
|
|
1257
|
+
}
|
|
1258
|
+
throw new Error(e.message + '\n\n' + e.stack);
|
|
1259
|
+
}
|
|
1260
|
+
throw e;
|
|
1261
|
+
}, 0);
|
|
1262
|
+
};
|
|
1263
|
+
}
|
|
1264
|
+
addListener(listener) {
|
|
1265
|
+
this.listeners.push(listener);
|
|
1266
|
+
return () => {
|
|
1267
|
+
this._removeListener(listener);
|
|
1268
|
+
};
|
|
1269
|
+
}
|
|
1270
|
+
emit(e) {
|
|
1271
|
+
this.listeners.forEach((listener) => {
|
|
1272
|
+
listener(e);
|
|
1273
|
+
});
|
|
1274
|
+
}
|
|
1275
|
+
_removeListener(listener) {
|
|
1276
|
+
this.listeners.splice(this.listeners.indexOf(listener), 1);
|
|
1277
|
+
}
|
|
1278
|
+
setUnexpectedErrorHandler(newUnexpectedErrorHandler) {
|
|
1279
|
+
this.unexpectedErrorHandler = newUnexpectedErrorHandler;
|
|
1280
|
+
}
|
|
1281
|
+
getUnexpectedErrorHandler() {
|
|
1282
|
+
return this.unexpectedErrorHandler;
|
|
1283
|
+
}
|
|
1284
|
+
onUnexpectedError(e) {
|
|
1285
|
+
this.unexpectedErrorHandler(e);
|
|
1286
|
+
this.emit(e);
|
|
1287
|
+
}
|
|
1288
|
+
// For external errors, we don't want the listeners to be called
|
|
1289
|
+
onUnexpectedExternalError(e) {
|
|
1290
|
+
this.unexpectedErrorHandler(e);
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
exports.ErrorHandler = ErrorHandler;
|
|
1294
|
+
exports.errorHandler = new ErrorHandler();
|
|
1295
|
+
function onUnexpectedError(e) {
|
|
1296
|
+
// ignore errors from cancelled promises
|
|
1297
|
+
if (!isCancellationError(e)) {
|
|
1298
|
+
exports.errorHandler.onUnexpectedError(e);
|
|
1299
|
+
}
|
|
1300
|
+
return undefined;
|
|
1301
|
+
}
|
|
1302
|
+
exports.onUnexpectedError = onUnexpectedError;
|
|
1303
|
+
const canceledName = 'Canceled';
|
|
1304
|
+
/**
|
|
1305
|
+
* Checks if the given error is a promise in canceled state
|
|
1306
|
+
*/
|
|
1307
|
+
function isCancellationError(error) {
|
|
1308
|
+
if (error instanceof CancellationError) {
|
|
1309
|
+
return true;
|
|
1310
|
+
}
|
|
1311
|
+
return error instanceof Error && error.name === canceledName && error.message === canceledName;
|
|
1312
|
+
}
|
|
1313
|
+
exports.isCancellationError = isCancellationError;
|
|
1314
|
+
// !!!IMPORTANT!!!
|
|
1315
|
+
// Do NOT change this class because it is also used as an API-type.
|
|
1316
|
+
class CancellationError extends Error {
|
|
1317
|
+
constructor() {
|
|
1318
|
+
super(canceledName);
|
|
1319
|
+
this.name = this.message;
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
exports.CancellationError = CancellationError;
|
|
1323
|
+
/**
|
|
1324
|
+
* Error that when thrown won't be logged in telemetry as an unhandled error.
|
|
1325
|
+
*/
|
|
1326
|
+
class ErrorNoTelemetry extends Error {
|
|
1327
|
+
constructor(msg) {
|
|
1328
|
+
super(msg);
|
|
1329
|
+
this.name = 'CodeExpectedError';
|
|
1330
|
+
}
|
|
1331
|
+
static fromError(err) {
|
|
1332
|
+
if (err instanceof ErrorNoTelemetry) {
|
|
1333
|
+
return err;
|
|
1334
|
+
}
|
|
1335
|
+
const result = new ErrorNoTelemetry();
|
|
1336
|
+
result.message = err.message;
|
|
1337
|
+
result.stack = err.stack;
|
|
1338
|
+
return result;
|
|
1339
|
+
}
|
|
1340
|
+
static isErrorNoTelemetry(err) {
|
|
1341
|
+
return err.name === 'CodeExpectedError';
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
exports.ErrorNoTelemetry = ErrorNoTelemetry;
|
|
1345
|
+
/**
|
|
1346
|
+
* This error indicates a bug.
|
|
1347
|
+
* Do not throw this for invalid user input.
|
|
1348
|
+
* Only catch this error to recover gracefully from bugs.
|
|
1349
|
+
*/
|
|
1350
|
+
class BugIndicatingError extends Error {
|
|
1351
|
+
constructor(message) {
|
|
1352
|
+
super(message || 'An unexpected bug occurred.');
|
|
1353
|
+
Object.setPrototypeOf(this, BugIndicatingError.prototype);
|
|
1354
|
+
// Because we know for sure only buggy code throws this,
|
|
1355
|
+
// we definitely want to break here and fix the bug.
|
|
1356
|
+
// eslint-disable-next-line no-debugger
|
|
1357
|
+
// debugger;
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
exports.BugIndicatingError = BugIndicatingError;
|
|
1361
|
+
|
|
1362
|
+
|
|
1363
|
+
/***/ }),
|
|
1364
|
+
|
|
1365
|
+
/***/ "./node_modules/vscode-diff/dist/vs/base/common/hash.js":
|
|
1366
|
+
/*!**************************************************************!*\
|
|
1367
|
+
!*** ./node_modules/vscode-diff/dist/vs/base/common/hash.js ***!
|
|
1368
|
+
\**************************************************************/
|
|
1369
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
1370
|
+
|
|
1371
|
+
|
|
1372
|
+
/*---------------------------------------------------------------------------------------------
|
|
1373
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
1374
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
1375
|
+
*--------------------------------------------------------------------------------------------*/
|
|
1376
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
1377
|
+
exports.StringSHA1 = exports.toHexString = exports.stringHash = exports.numberHash = exports.doHash = void 0;
|
|
1378
|
+
const strings = __webpack_require__(/*! ./strings */ "./node_modules/vscode-diff/dist/vs/base/common/strings.js");
|
|
1379
|
+
function doHash(obj, hashVal) {
|
|
1380
|
+
switch (typeof obj) {
|
|
1381
|
+
case 'object':
|
|
1382
|
+
if (obj === null) {
|
|
1383
|
+
return numberHash(349, hashVal);
|
|
1384
|
+
}
|
|
1385
|
+
else if (Array.isArray(obj)) {
|
|
1386
|
+
return arrayHash(obj, hashVal);
|
|
1387
|
+
}
|
|
1388
|
+
return objectHash(obj, hashVal);
|
|
1389
|
+
case 'string':
|
|
1390
|
+
return stringHash(obj, hashVal);
|
|
1391
|
+
case 'boolean':
|
|
1392
|
+
return booleanHash(obj, hashVal);
|
|
1393
|
+
case 'number':
|
|
1394
|
+
return numberHash(obj, hashVal);
|
|
1395
|
+
case 'undefined':
|
|
1396
|
+
return numberHash(937, hashVal);
|
|
1397
|
+
default:
|
|
1398
|
+
return numberHash(617, hashVal);
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
exports.doHash = doHash;
|
|
1402
|
+
function numberHash(val, initialHashVal) {
|
|
1403
|
+
return (((initialHashVal << 5) - initialHashVal) + val) | 0; // hashVal * 31 + ch, keep as int32
|
|
1404
|
+
}
|
|
1405
|
+
exports.numberHash = numberHash;
|
|
1406
|
+
function booleanHash(b, initialHashVal) {
|
|
1407
|
+
return numberHash(b ? 433 : 863, initialHashVal);
|
|
1408
|
+
}
|
|
1409
|
+
function stringHash(s, hashVal) {
|
|
1410
|
+
hashVal = numberHash(149417, hashVal);
|
|
1411
|
+
for (let i = 0, length = s.length; i < length; i++) {
|
|
1412
|
+
hashVal = numberHash(s.charCodeAt(i), hashVal);
|
|
1413
|
+
}
|
|
1414
|
+
return hashVal;
|
|
1415
|
+
}
|
|
1416
|
+
exports.stringHash = stringHash;
|
|
1417
|
+
function arrayHash(arr, initialHashVal) {
|
|
1418
|
+
initialHashVal = numberHash(104579, initialHashVal);
|
|
1419
|
+
return arr.reduce((hashVal, item) => doHash(item, hashVal), initialHashVal);
|
|
1420
|
+
}
|
|
1421
|
+
function objectHash(obj, initialHashVal) {
|
|
1422
|
+
initialHashVal = numberHash(181387, initialHashVal);
|
|
1423
|
+
return Object.keys(obj).sort().reduce((hashVal, key) => {
|
|
1424
|
+
hashVal = stringHash(key, hashVal);
|
|
1425
|
+
return doHash(obj[key], hashVal);
|
|
1426
|
+
}, initialHashVal);
|
|
1427
|
+
}
|
|
1428
|
+
function leftRotate(value, bits, totalBits = 32) {
|
|
1429
|
+
// delta + bits = totalBits
|
|
1430
|
+
const delta = totalBits - bits;
|
|
1431
|
+
// All ones, expect `delta` zeros aligned to the right
|
|
1432
|
+
const mask = ~((1 << delta) - 1);
|
|
1433
|
+
// Join (value left-shifted `bits` bits) with (masked value right-shifted `delta` bits)
|
|
1434
|
+
return ((value << bits) | ((mask & value) >>> delta)) >>> 0;
|
|
1435
|
+
}
|
|
1436
|
+
function fill(dest, index = 0, count = dest.byteLength, value = 0) {
|
|
1437
|
+
for (let i = 0; i < count; i++) {
|
|
1438
|
+
dest[index + i] = value;
|
|
1439
|
+
}
|
|
1440
|
+
}
|
|
1441
|
+
function leftPad(value, length, char = '0') {
|
|
1442
|
+
while (value.length < length) {
|
|
1443
|
+
value = char + value;
|
|
1444
|
+
}
|
|
1445
|
+
return value;
|
|
1446
|
+
}
|
|
1447
|
+
function toHexString(bufferOrValue, bitsize = 32) {
|
|
1448
|
+
if (bufferOrValue instanceof ArrayBuffer) {
|
|
1449
|
+
return Array.from(new Uint8Array(bufferOrValue)).map(b => b.toString(16).padStart(2, '0')).join('');
|
|
1450
|
+
}
|
|
1451
|
+
return leftPad((bufferOrValue >>> 0).toString(16), bitsize / 4);
|
|
1452
|
+
}
|
|
1453
|
+
exports.toHexString = toHexString;
|
|
1454
|
+
/**
|
|
1455
|
+
* A SHA1 implementation that works with strings and does not allocate.
|
|
1456
|
+
*/
|
|
1457
|
+
class StringSHA1 {
|
|
1458
|
+
constructor() {
|
|
1459
|
+
this._h0 = 0x67452301;
|
|
1460
|
+
this._h1 = 0xEFCDAB89;
|
|
1461
|
+
this._h2 = 0x98BADCFE;
|
|
1462
|
+
this._h3 = 0x10325476;
|
|
1463
|
+
this._h4 = 0xC3D2E1F0;
|
|
1464
|
+
this._buff = new Uint8Array(64 /* SHA1Constant.BLOCK_SIZE */ + 3 /* to fit any utf-8 */);
|
|
1465
|
+
this._buffDV = new DataView(this._buff.buffer);
|
|
1466
|
+
this._buffLen = 0;
|
|
1467
|
+
this._totalLen = 0;
|
|
1468
|
+
this._leftoverHighSurrogate = 0;
|
|
1469
|
+
this._finished = false;
|
|
1470
|
+
}
|
|
1471
|
+
update(str) {
|
|
1472
|
+
const strLen = str.length;
|
|
1473
|
+
if (strLen === 0) {
|
|
1474
|
+
return;
|
|
1475
|
+
}
|
|
1476
|
+
const buff = this._buff;
|
|
1477
|
+
let buffLen = this._buffLen;
|
|
1478
|
+
let leftoverHighSurrogate = this._leftoverHighSurrogate;
|
|
1479
|
+
let charCode;
|
|
1480
|
+
let offset;
|
|
1481
|
+
if (leftoverHighSurrogate !== 0) {
|
|
1482
|
+
charCode = leftoverHighSurrogate;
|
|
1483
|
+
offset = -1;
|
|
1484
|
+
leftoverHighSurrogate = 0;
|
|
1485
|
+
}
|
|
1486
|
+
else {
|
|
1487
|
+
charCode = str.charCodeAt(0);
|
|
1488
|
+
offset = 0;
|
|
1489
|
+
}
|
|
1490
|
+
while (true) {
|
|
1491
|
+
let codePoint = charCode;
|
|
1492
|
+
if (strings.isHighSurrogate(charCode)) {
|
|
1493
|
+
if (offset + 1 < strLen) {
|
|
1494
|
+
const nextCharCode = str.charCodeAt(offset + 1);
|
|
1495
|
+
if (strings.isLowSurrogate(nextCharCode)) {
|
|
1496
|
+
offset++;
|
|
1497
|
+
codePoint = strings.computeCodePoint(charCode, nextCharCode);
|
|
1498
|
+
}
|
|
1499
|
+
else {
|
|
1500
|
+
// illegal => unicode replacement character
|
|
1501
|
+
codePoint = 65533 /* SHA1Constant.UNICODE_REPLACEMENT */;
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
else {
|
|
1505
|
+
// last character is a surrogate pair
|
|
1506
|
+
leftoverHighSurrogate = charCode;
|
|
1507
|
+
break;
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
else if (strings.isLowSurrogate(charCode)) {
|
|
1511
|
+
// illegal => unicode replacement character
|
|
1512
|
+
codePoint = 65533 /* SHA1Constant.UNICODE_REPLACEMENT */;
|
|
1513
|
+
}
|
|
1514
|
+
buffLen = this._push(buff, buffLen, codePoint);
|
|
1515
|
+
offset++;
|
|
1516
|
+
if (offset < strLen) {
|
|
1517
|
+
charCode = str.charCodeAt(offset);
|
|
1518
|
+
}
|
|
1519
|
+
else {
|
|
1520
|
+
break;
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1523
|
+
this._buffLen = buffLen;
|
|
1524
|
+
this._leftoverHighSurrogate = leftoverHighSurrogate;
|
|
1525
|
+
}
|
|
1526
|
+
_push(buff, buffLen, codePoint) {
|
|
1527
|
+
if (codePoint < 0x0080) {
|
|
1528
|
+
buff[buffLen++] = codePoint;
|
|
1529
|
+
}
|
|
1530
|
+
else if (codePoint < 0x0800) {
|
|
1531
|
+
buff[buffLen++] = 0b11000000 | ((codePoint & 0b00000000000000000000011111000000) >>> 6);
|
|
1532
|
+
buff[buffLen++] = 0b10000000 | ((codePoint & 0b00000000000000000000000000111111) >>> 0);
|
|
1533
|
+
}
|
|
1534
|
+
else if (codePoint < 0x10000) {
|
|
1535
|
+
buff[buffLen++] = 0b11100000 | ((codePoint & 0b00000000000000001111000000000000) >>> 12);
|
|
1536
|
+
buff[buffLen++] = 0b10000000 | ((codePoint & 0b00000000000000000000111111000000) >>> 6);
|
|
1537
|
+
buff[buffLen++] = 0b10000000 | ((codePoint & 0b00000000000000000000000000111111) >>> 0);
|
|
1538
|
+
}
|
|
1539
|
+
else {
|
|
1540
|
+
buff[buffLen++] = 0b11110000 | ((codePoint & 0b00000000000111000000000000000000) >>> 18);
|
|
1541
|
+
buff[buffLen++] = 0b10000000 | ((codePoint & 0b00000000000000111111000000000000) >>> 12);
|
|
1542
|
+
buff[buffLen++] = 0b10000000 | ((codePoint & 0b00000000000000000000111111000000) >>> 6);
|
|
1543
|
+
buff[buffLen++] = 0b10000000 | ((codePoint & 0b00000000000000000000000000111111) >>> 0);
|
|
1544
|
+
}
|
|
1545
|
+
if (buffLen >= 64 /* SHA1Constant.BLOCK_SIZE */) {
|
|
1546
|
+
this._step();
|
|
1547
|
+
buffLen -= 64 /* SHA1Constant.BLOCK_SIZE */;
|
|
1548
|
+
this._totalLen += 64 /* SHA1Constant.BLOCK_SIZE */;
|
|
1549
|
+
// take last 3 in case of UTF8 overflow
|
|
1550
|
+
buff[0] = buff[64 /* SHA1Constant.BLOCK_SIZE */ + 0];
|
|
1551
|
+
buff[1] = buff[64 /* SHA1Constant.BLOCK_SIZE */ + 1];
|
|
1552
|
+
buff[2] = buff[64 /* SHA1Constant.BLOCK_SIZE */ + 2];
|
|
1553
|
+
}
|
|
1554
|
+
return buffLen;
|
|
1555
|
+
}
|
|
1556
|
+
digest() {
|
|
1557
|
+
if (!this._finished) {
|
|
1558
|
+
this._finished = true;
|
|
1559
|
+
if (this._leftoverHighSurrogate) {
|
|
1560
|
+
// illegal => unicode replacement character
|
|
1561
|
+
this._leftoverHighSurrogate = 0;
|
|
1562
|
+
this._buffLen = this._push(this._buff, this._buffLen, 65533 /* SHA1Constant.UNICODE_REPLACEMENT */);
|
|
1563
|
+
}
|
|
1564
|
+
this._totalLen += this._buffLen;
|
|
1565
|
+
this._wrapUp();
|
|
1566
|
+
}
|
|
1567
|
+
return toHexString(this._h0) + toHexString(this._h1) + toHexString(this._h2) + toHexString(this._h3) + toHexString(this._h4);
|
|
1568
|
+
}
|
|
1569
|
+
_wrapUp() {
|
|
1570
|
+
this._buff[this._buffLen++] = 0x80;
|
|
1571
|
+
fill(this._buff, this._buffLen);
|
|
1572
|
+
if (this._buffLen > 56) {
|
|
1573
|
+
this._step();
|
|
1574
|
+
fill(this._buff);
|
|
1575
|
+
}
|
|
1576
|
+
// this will fit because the mantissa can cover up to 52 bits
|
|
1577
|
+
const ml = 8 * this._totalLen;
|
|
1578
|
+
this._buffDV.setUint32(56, Math.floor(ml / 4294967296), false);
|
|
1579
|
+
this._buffDV.setUint32(60, ml % 4294967296, false);
|
|
1580
|
+
this._step();
|
|
1581
|
+
}
|
|
1582
|
+
_step() {
|
|
1583
|
+
const bigBlock32 = StringSHA1._bigBlock32;
|
|
1584
|
+
const data = this._buffDV;
|
|
1585
|
+
for (let j = 0; j < 64 /* 16*4 */; j += 4) {
|
|
1586
|
+
bigBlock32.setUint32(j, data.getUint32(j, false), false);
|
|
1587
|
+
}
|
|
1588
|
+
for (let j = 64; j < 320 /* 80*4 */; j += 4) {
|
|
1589
|
+
bigBlock32.setUint32(j, leftRotate((bigBlock32.getUint32(j - 12, false) ^ bigBlock32.getUint32(j - 32, false) ^ bigBlock32.getUint32(j - 56, false) ^ bigBlock32.getUint32(j - 64, false)), 1), false);
|
|
1590
|
+
}
|
|
1591
|
+
let a = this._h0;
|
|
1592
|
+
let b = this._h1;
|
|
1593
|
+
let c = this._h2;
|
|
1594
|
+
let d = this._h3;
|
|
1595
|
+
let e = this._h4;
|
|
1596
|
+
let f, k;
|
|
1597
|
+
let temp;
|
|
1598
|
+
for (let j = 0; j < 80; j++) {
|
|
1599
|
+
if (j < 20) {
|
|
1600
|
+
f = (b & c) | ((~b) & d);
|
|
1601
|
+
k = 0x5A827999;
|
|
1602
|
+
}
|
|
1603
|
+
else if (j < 40) {
|
|
1604
|
+
f = b ^ c ^ d;
|
|
1605
|
+
k = 0x6ED9EBA1;
|
|
1606
|
+
}
|
|
1607
|
+
else if (j < 60) {
|
|
1608
|
+
f = (b & c) | (b & d) | (c & d);
|
|
1609
|
+
k = 0x8F1BBCDC;
|
|
1610
|
+
}
|
|
1611
|
+
else {
|
|
1612
|
+
f = b ^ c ^ d;
|
|
1613
|
+
k = 0xCA62C1D6;
|
|
1614
|
+
}
|
|
1615
|
+
temp = (leftRotate(a, 5) + f + e + k + bigBlock32.getUint32(j * 4, false)) & 0xffffffff;
|
|
1616
|
+
e = d;
|
|
1617
|
+
d = c;
|
|
1618
|
+
c = leftRotate(b, 30);
|
|
1619
|
+
b = a;
|
|
1620
|
+
a = temp;
|
|
1621
|
+
}
|
|
1622
|
+
this._h0 = (this._h0 + a) & 0xffffffff;
|
|
1623
|
+
this._h1 = (this._h1 + b) & 0xffffffff;
|
|
1624
|
+
this._h2 = (this._h2 + c) & 0xffffffff;
|
|
1625
|
+
this._h3 = (this._h3 + d) & 0xffffffff;
|
|
1626
|
+
this._h4 = (this._h4 + e) & 0xffffffff;
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1629
|
+
exports.StringSHA1 = StringSHA1;
|
|
1630
|
+
StringSHA1._bigBlock32 = new DataView(new ArrayBuffer(320)); // 80 * 4 = 320
|
|
1631
|
+
|
|
1632
|
+
|
|
1633
|
+
/***/ }),
|
|
1634
|
+
|
|
1635
|
+
/***/ "./node_modules/vscode-diff/dist/vs/base/common/strings.js":
|
|
1636
|
+
/*!*****************************************************************!*\
|
|
1637
|
+
!*** ./node_modules/vscode-diff/dist/vs/base/common/strings.js ***!
|
|
1638
|
+
\*****************************************************************/
|
|
1639
|
+
/***/ ((__unused_webpack_module, exports) => {
|
|
1640
|
+
|
|
1641
|
+
|
|
1642
|
+
/*---------------------------------------------------------------------------------------------
|
|
1643
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
1644
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
1645
|
+
*--------------------------------------------------------------------------------------------*/
|
|
1646
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
1647
|
+
exports.computeCodePoint = exports.isLowSurrogate = exports.isHighSurrogate = exports.lastNonWhitespaceIndex = exports.firstNonWhitespaceIndex = void 0;
|
|
1648
|
+
/**
|
|
1649
|
+
* Returns first index of the string that is not whitespace.
|
|
1650
|
+
* If string is empty or contains only whitespaces, returns -1
|
|
1651
|
+
*/
|
|
1652
|
+
function firstNonWhitespaceIndex(str) {
|
|
1653
|
+
for (let i = 0, len = str.length; i < len; i++) {
|
|
1654
|
+
const chCode = str.charCodeAt(i);
|
|
1655
|
+
if (chCode !== 32 /* CharCode.Space */ && chCode !== 9 /* CharCode.Tab */) {
|
|
1656
|
+
return i;
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
return -1;
|
|
1660
|
+
}
|
|
1661
|
+
exports.firstNonWhitespaceIndex = firstNonWhitespaceIndex;
|
|
1662
|
+
/**
|
|
1663
|
+
* Returns last index of the string that is not whitespace.
|
|
1664
|
+
* If string is empty or contains only whitespaces, returns -1
|
|
1665
|
+
*/
|
|
1666
|
+
function lastNonWhitespaceIndex(str, startIndex = str.length - 1) {
|
|
1667
|
+
for (let i = startIndex; i >= 0; i--) {
|
|
1668
|
+
const chCode = str.charCodeAt(i);
|
|
1669
|
+
if (chCode !== 32 /* CharCode.Space */ && chCode !== 9 /* CharCode.Tab */) {
|
|
1670
|
+
return i;
|
|
1671
|
+
}
|
|
1672
|
+
}
|
|
1673
|
+
return -1;
|
|
1674
|
+
}
|
|
1675
|
+
exports.lastNonWhitespaceIndex = lastNonWhitespaceIndex;
|
|
1676
|
+
/**
|
|
1677
|
+
* See http://en.wikipedia.org/wiki/Surrogate_pair
|
|
1678
|
+
*/
|
|
1679
|
+
function isHighSurrogate(charCode) {
|
|
1680
|
+
return (0xD800 <= charCode && charCode <= 0xDBFF);
|
|
1681
|
+
}
|
|
1682
|
+
exports.isHighSurrogate = isHighSurrogate;
|
|
1683
|
+
/**
|
|
1684
|
+
* See http://en.wikipedia.org/wiki/Surrogate_pair
|
|
1685
|
+
*/
|
|
1686
|
+
function isLowSurrogate(charCode) {
|
|
1687
|
+
return (0xDC00 <= charCode && charCode <= 0xDFFF);
|
|
1688
|
+
}
|
|
1689
|
+
exports.isLowSurrogate = isLowSurrogate;
|
|
1690
|
+
/**
|
|
1691
|
+
* See http://en.wikipedia.org/wiki/Surrogate_pair
|
|
1692
|
+
*/
|
|
1693
|
+
function computeCodePoint(highSurrogate, lowSurrogate) {
|
|
1694
|
+
return ((highSurrogate - 0xD800) << 10) + (lowSurrogate - 0xDC00) + 0x10000;
|
|
1695
|
+
}
|
|
1696
|
+
exports.computeCodePoint = computeCodePoint;
|
|
1697
|
+
|
|
1698
|
+
|
|
1699
|
+
/***/ }),
|
|
1700
|
+
|
|
1701
|
+
/***/ "./node_modules/vscode-diff/dist/vs/editor/common/core/lineRange.js":
|
|
1702
|
+
/*!**************************************************************************!*\
|
|
1703
|
+
!*** ./node_modules/vscode-diff/dist/vs/editor/common/core/lineRange.js ***!
|
|
1704
|
+
\**************************************************************************/
|
|
1705
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
1706
|
+
|
|
1707
|
+
|
|
1708
|
+
/*---------------------------------------------------------------------------------------------
|
|
1709
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
1710
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
1711
|
+
*--------------------------------------------------------------------------------------------*/
|
|
1712
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
1713
|
+
exports.LineRange = void 0;
|
|
1714
|
+
const errors_1 = __webpack_require__(/*! ../../../base/common/errors */ "./node_modules/vscode-diff/dist/vs/base/common/errors.js");
|
|
1715
|
+
const offsetRange_1 = __webpack_require__(/*! ./offsetRange */ "./node_modules/vscode-diff/dist/vs/editor/common/core/offsetRange.js");
|
|
1716
|
+
const range_1 = __webpack_require__(/*! ./range */ "./node_modules/vscode-diff/dist/vs/editor/common/core/range.js");
|
|
1717
|
+
/**
|
|
1718
|
+
* A range of lines (1-based).
|
|
1719
|
+
*/
|
|
1720
|
+
class LineRange {
|
|
1721
|
+
static fromRange(range) {
|
|
1722
|
+
return new LineRange(range.startLineNumber, range.endLineNumber);
|
|
1723
|
+
}
|
|
1724
|
+
static subtract(a, b) {
|
|
1725
|
+
if (!b) {
|
|
1726
|
+
return [a];
|
|
1727
|
+
}
|
|
1728
|
+
if (a.startLineNumber < b.startLineNumber && b.endLineNumberExclusive < a.endLineNumberExclusive) {
|
|
1729
|
+
return [
|
|
1730
|
+
new LineRange(a.startLineNumber, b.startLineNumber),
|
|
1731
|
+
new LineRange(b.endLineNumberExclusive, a.endLineNumberExclusive)
|
|
1732
|
+
];
|
|
1733
|
+
}
|
|
1734
|
+
else if (b.startLineNumber <= a.startLineNumber && a.endLineNumberExclusive <= b.endLineNumberExclusive) {
|
|
1735
|
+
return [];
|
|
1736
|
+
}
|
|
1737
|
+
else if (b.endLineNumberExclusive < a.endLineNumberExclusive) {
|
|
1738
|
+
return [new LineRange(Math.max(b.endLineNumberExclusive, a.startLineNumber), a.endLineNumberExclusive)];
|
|
1739
|
+
}
|
|
1740
|
+
else {
|
|
1741
|
+
return [new LineRange(a.startLineNumber, Math.min(b.startLineNumber, a.endLineNumberExclusive))];
|
|
1742
|
+
}
|
|
1743
|
+
}
|
|
1744
|
+
/**
|
|
1745
|
+
* @param lineRanges An array of sorted line ranges.
|
|
1746
|
+
*/
|
|
1747
|
+
static joinMany(lineRanges) {
|
|
1748
|
+
if (lineRanges.length === 0) {
|
|
1749
|
+
return [];
|
|
1750
|
+
}
|
|
1751
|
+
let result = lineRanges[0];
|
|
1752
|
+
for (let i = 1; i < lineRanges.length; i++) {
|
|
1753
|
+
result = this.join(result, lineRanges[i]);
|
|
1754
|
+
}
|
|
1755
|
+
return result;
|
|
1756
|
+
}
|
|
1757
|
+
/**
|
|
1758
|
+
* @param lineRanges1 Must be sorted.
|
|
1759
|
+
* @param lineRanges2 Must be sorted.
|
|
1760
|
+
*/
|
|
1761
|
+
static join(lineRanges1, lineRanges2) {
|
|
1762
|
+
if (lineRanges1.length === 0) {
|
|
1763
|
+
return lineRanges2;
|
|
1764
|
+
}
|
|
1765
|
+
if (lineRanges2.length === 0) {
|
|
1766
|
+
return lineRanges1;
|
|
1767
|
+
}
|
|
1768
|
+
const result = [];
|
|
1769
|
+
let i1 = 0;
|
|
1770
|
+
let i2 = 0;
|
|
1771
|
+
let current = null;
|
|
1772
|
+
while (i1 < lineRanges1.length || i2 < lineRanges2.length) {
|
|
1773
|
+
let next = null;
|
|
1774
|
+
if (i1 < lineRanges1.length && i2 < lineRanges2.length) {
|
|
1775
|
+
const lineRange1 = lineRanges1[i1];
|
|
1776
|
+
const lineRange2 = lineRanges2[i2];
|
|
1777
|
+
if (lineRange1.startLineNumber < lineRange2.startLineNumber) {
|
|
1778
|
+
next = lineRange1;
|
|
1779
|
+
i1++;
|
|
1780
|
+
}
|
|
1781
|
+
else {
|
|
1782
|
+
next = lineRange2;
|
|
1783
|
+
i2++;
|
|
1784
|
+
}
|
|
1785
|
+
}
|
|
1786
|
+
else if (i1 < lineRanges1.length) {
|
|
1787
|
+
next = lineRanges1[i1];
|
|
1788
|
+
i1++;
|
|
1789
|
+
}
|
|
1790
|
+
else {
|
|
1791
|
+
next = lineRanges2[i2];
|
|
1792
|
+
i2++;
|
|
1793
|
+
}
|
|
1794
|
+
if (current === null) {
|
|
1795
|
+
current = next;
|
|
1796
|
+
}
|
|
1797
|
+
else {
|
|
1798
|
+
if (current.endLineNumberExclusive >= next.startLineNumber) {
|
|
1799
|
+
// merge
|
|
1800
|
+
current = new LineRange(current.startLineNumber, Math.max(current.endLineNumberExclusive, next.endLineNumberExclusive));
|
|
1801
|
+
}
|
|
1802
|
+
else {
|
|
1803
|
+
// push
|
|
1804
|
+
result.push(current);
|
|
1805
|
+
current = next;
|
|
1806
|
+
}
|
|
1807
|
+
}
|
|
1808
|
+
}
|
|
1809
|
+
if (current !== null) {
|
|
1810
|
+
result.push(current);
|
|
1811
|
+
}
|
|
1812
|
+
return result;
|
|
1813
|
+
}
|
|
1814
|
+
static ofLength(startLineNumber, length) {
|
|
1815
|
+
return new LineRange(startLineNumber, startLineNumber + length);
|
|
1816
|
+
}
|
|
1817
|
+
/**
|
|
1818
|
+
* @internal
|
|
1819
|
+
*/
|
|
1820
|
+
static deserialize(lineRange) {
|
|
1821
|
+
return new LineRange(lineRange[0], lineRange[1]);
|
|
1822
|
+
}
|
|
1823
|
+
constructor(startLineNumber, endLineNumberExclusive) {
|
|
1824
|
+
if (startLineNumber > endLineNumberExclusive) {
|
|
1825
|
+
throw new errors_1.BugIndicatingError(`startLineNumber ${startLineNumber} cannot be after endLineNumberExclusive ${endLineNumberExclusive}`);
|
|
1826
|
+
}
|
|
1827
|
+
this.startLineNumber = startLineNumber;
|
|
1828
|
+
this.endLineNumberExclusive = endLineNumberExclusive;
|
|
1829
|
+
}
|
|
1830
|
+
/**
|
|
1831
|
+
* Indicates if this line range contains the given line number.
|
|
1832
|
+
*/
|
|
1833
|
+
contains(lineNumber) {
|
|
1834
|
+
return this.startLineNumber <= lineNumber && lineNumber < this.endLineNumberExclusive;
|
|
1835
|
+
}
|
|
1836
|
+
/**
|
|
1837
|
+
* Indicates if this line range is empty.
|
|
1838
|
+
*/
|
|
1839
|
+
get isEmpty() {
|
|
1840
|
+
return this.startLineNumber === this.endLineNumberExclusive;
|
|
1841
|
+
}
|
|
1842
|
+
/**
|
|
1843
|
+
* Moves this line range by the given offset of line numbers.
|
|
1844
|
+
*/
|
|
1845
|
+
delta(offset) {
|
|
1846
|
+
return new LineRange(this.startLineNumber + offset, this.endLineNumberExclusive + offset);
|
|
1847
|
+
}
|
|
1848
|
+
deltaLength(offset) {
|
|
1849
|
+
return new LineRange(this.startLineNumber, this.endLineNumberExclusive + offset);
|
|
1850
|
+
}
|
|
1851
|
+
/**
|
|
1852
|
+
* The number of lines this line range spans.
|
|
1853
|
+
*/
|
|
1854
|
+
get length() {
|
|
1855
|
+
return this.endLineNumberExclusive - this.startLineNumber;
|
|
1856
|
+
}
|
|
1857
|
+
/**
|
|
1858
|
+
* Creates a line range that combines this and the given line range.
|
|
1859
|
+
*/
|
|
1860
|
+
join(other) {
|
|
1861
|
+
return new LineRange(Math.min(this.startLineNumber, other.startLineNumber), Math.max(this.endLineNumberExclusive, other.endLineNumberExclusive));
|
|
1862
|
+
}
|
|
1863
|
+
toString() {
|
|
1864
|
+
return `[${this.startLineNumber},${this.endLineNumberExclusive})`;
|
|
1865
|
+
}
|
|
1866
|
+
/**
|
|
1867
|
+
* The resulting range is empty if the ranges do not intersect, but touch.
|
|
1868
|
+
* If the ranges don't even touch, the result is undefined.
|
|
1869
|
+
*/
|
|
1870
|
+
intersect(other) {
|
|
1871
|
+
const startLineNumber = Math.max(this.startLineNumber, other.startLineNumber);
|
|
1872
|
+
const endLineNumberExclusive = Math.min(this.endLineNumberExclusive, other.endLineNumberExclusive);
|
|
1873
|
+
if (startLineNumber <= endLineNumberExclusive) {
|
|
1874
|
+
return new LineRange(startLineNumber, endLineNumberExclusive);
|
|
1875
|
+
}
|
|
1876
|
+
return undefined;
|
|
1877
|
+
}
|
|
1878
|
+
intersectsStrict(other) {
|
|
1879
|
+
return this.startLineNumber < other.endLineNumberExclusive && other.startLineNumber < this.endLineNumberExclusive;
|
|
1880
|
+
}
|
|
1881
|
+
overlapOrTouch(other) {
|
|
1882
|
+
return this.startLineNumber <= other.endLineNumberExclusive && other.startLineNumber <= this.endLineNumberExclusive;
|
|
1883
|
+
}
|
|
1884
|
+
equals(b) {
|
|
1885
|
+
return this.startLineNumber === b.startLineNumber && this.endLineNumberExclusive === b.endLineNumberExclusive;
|
|
1886
|
+
}
|
|
1887
|
+
toInclusiveRange() {
|
|
1888
|
+
if (this.isEmpty) {
|
|
1889
|
+
return null;
|
|
1890
|
+
}
|
|
1891
|
+
return new range_1.Range(this.startLineNumber, 1, this.endLineNumberExclusive - 1, Number.MAX_SAFE_INTEGER);
|
|
1892
|
+
}
|
|
1893
|
+
toExclusiveRange() {
|
|
1894
|
+
return new range_1.Range(this.startLineNumber, 1, this.endLineNumberExclusive, 1);
|
|
1895
|
+
}
|
|
1896
|
+
mapToLineArray(f) {
|
|
1897
|
+
const result = [];
|
|
1898
|
+
for (let lineNumber = this.startLineNumber; lineNumber < this.endLineNumberExclusive; lineNumber++) {
|
|
1899
|
+
result.push(f(lineNumber));
|
|
1900
|
+
}
|
|
1901
|
+
return result;
|
|
1902
|
+
}
|
|
1903
|
+
forEach(f) {
|
|
1904
|
+
for (let lineNumber = this.startLineNumber; lineNumber < this.endLineNumberExclusive; lineNumber++) {
|
|
1905
|
+
f(lineNumber);
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1908
|
+
/**
|
|
1909
|
+
* @internal
|
|
1910
|
+
*/
|
|
1911
|
+
serialize() {
|
|
1912
|
+
return [this.startLineNumber, this.endLineNumberExclusive];
|
|
1913
|
+
}
|
|
1914
|
+
includes(lineNumber) {
|
|
1915
|
+
return this.startLineNumber <= lineNumber && lineNumber < this.endLineNumberExclusive;
|
|
1916
|
+
}
|
|
1917
|
+
/**
|
|
1918
|
+
* Converts this 1-based line range to a 0-based offset range (subtracts 1!).
|
|
1919
|
+
* @internal
|
|
1920
|
+
*/
|
|
1921
|
+
toOffsetRange() {
|
|
1922
|
+
return new offsetRange_1.OffsetRange(this.startLineNumber - 1, this.endLineNumberExclusive - 1);
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1925
|
+
exports.LineRange = LineRange;
|
|
1926
|
+
|
|
1927
|
+
|
|
1928
|
+
/***/ }),
|
|
1929
|
+
|
|
1930
|
+
/***/ "./node_modules/vscode-diff/dist/vs/editor/common/core/offsetRange.js":
|
|
1931
|
+
/*!****************************************************************************!*\
|
|
1932
|
+
!*** ./node_modules/vscode-diff/dist/vs/editor/common/core/offsetRange.js ***!
|
|
1933
|
+
\****************************************************************************/
|
|
1934
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
1935
|
+
|
|
1936
|
+
|
|
1937
|
+
/*---------------------------------------------------------------------------------------------
|
|
1938
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
1939
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
1940
|
+
*--------------------------------------------------------------------------------------------*/
|
|
1941
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
1942
|
+
exports.OffsetRangeSet = exports.OffsetRange = void 0;
|
|
1943
|
+
const errors_1 = __webpack_require__(/*! ../../../base/common/errors */ "./node_modules/vscode-diff/dist/vs/base/common/errors.js");
|
|
1944
|
+
/**
|
|
1945
|
+
* A range of offsets (0-based).
|
|
1946
|
+
*/
|
|
1947
|
+
class OffsetRange {
|
|
1948
|
+
static addRange(range, sortedRanges) {
|
|
1949
|
+
let i = 0;
|
|
1950
|
+
while (i < sortedRanges.length && sortedRanges[i].endExclusive < range.start) {
|
|
1951
|
+
i++;
|
|
1952
|
+
}
|
|
1953
|
+
let j = i;
|
|
1954
|
+
while (j < sortedRanges.length && sortedRanges[j].start <= range.endExclusive) {
|
|
1955
|
+
j++;
|
|
1956
|
+
}
|
|
1957
|
+
if (i === j) {
|
|
1958
|
+
sortedRanges.splice(i, 0, range);
|
|
1959
|
+
}
|
|
1960
|
+
else {
|
|
1961
|
+
const start = Math.min(range.start, sortedRanges[i].start);
|
|
1962
|
+
const end = Math.max(range.endExclusive, sortedRanges[j - 1].endExclusive);
|
|
1963
|
+
sortedRanges.splice(i, j - i, new OffsetRange(start, end));
|
|
1964
|
+
}
|
|
1965
|
+
}
|
|
1966
|
+
static tryCreate(start, endExclusive) {
|
|
1967
|
+
if (start > endExclusive) {
|
|
1968
|
+
return undefined;
|
|
1969
|
+
}
|
|
1970
|
+
return new OffsetRange(start, endExclusive);
|
|
1971
|
+
}
|
|
1972
|
+
static ofLength(length) {
|
|
1973
|
+
return new OffsetRange(0, length);
|
|
1974
|
+
}
|
|
1975
|
+
constructor(start, endExclusive) {
|
|
1976
|
+
this.start = start;
|
|
1977
|
+
this.endExclusive = endExclusive;
|
|
1978
|
+
if (start > endExclusive) {
|
|
1979
|
+
throw new errors_1.BugIndicatingError(`Invalid range: ${this.toString()}`);
|
|
1980
|
+
}
|
|
1981
|
+
}
|
|
1982
|
+
get isEmpty() {
|
|
1983
|
+
return this.start === this.endExclusive;
|
|
1984
|
+
}
|
|
1985
|
+
delta(offset) {
|
|
1986
|
+
return new OffsetRange(this.start + offset, this.endExclusive + offset);
|
|
1987
|
+
}
|
|
1988
|
+
deltaStart(offset) {
|
|
1989
|
+
return new OffsetRange(this.start + offset, this.endExclusive);
|
|
1990
|
+
}
|
|
1991
|
+
deltaEnd(offset) {
|
|
1992
|
+
return new OffsetRange(this.start, this.endExclusive + offset);
|
|
1993
|
+
}
|
|
1994
|
+
get length() {
|
|
1995
|
+
return this.endExclusive - this.start;
|
|
1996
|
+
}
|
|
1997
|
+
toString() {
|
|
1998
|
+
return `[${this.start}, ${this.endExclusive})`;
|
|
1999
|
+
}
|
|
2000
|
+
equals(other) {
|
|
2001
|
+
return this.start === other.start && this.endExclusive === other.endExclusive;
|
|
2002
|
+
}
|
|
2003
|
+
containsRange(other) {
|
|
2004
|
+
return this.start <= other.start && other.endExclusive <= this.endExclusive;
|
|
2005
|
+
}
|
|
2006
|
+
contains(offset) {
|
|
2007
|
+
return this.start <= offset && offset < this.endExclusive;
|
|
2008
|
+
}
|
|
2009
|
+
/**
|
|
2010
|
+
* for all numbers n: range1.contains(n) or range2.contains(n) => range1.join(range2).contains(n)
|
|
2011
|
+
* The joined range is the smallest range that contains both ranges.
|
|
2012
|
+
*/
|
|
2013
|
+
join(other) {
|
|
2014
|
+
return new OffsetRange(Math.min(this.start, other.start), Math.max(this.endExclusive, other.endExclusive));
|
|
2015
|
+
}
|
|
2016
|
+
/**
|
|
2017
|
+
* for all numbers n: range1.contains(n) and range2.contains(n) <=> range1.intersect(range2).contains(n)
|
|
2018
|
+
*
|
|
2019
|
+
* The resulting range is empty if the ranges do not intersect, but touch.
|
|
2020
|
+
* If the ranges don't even touch, the result is undefined.
|
|
2021
|
+
*/
|
|
2022
|
+
intersect(other) {
|
|
2023
|
+
const start = Math.max(this.start, other.start);
|
|
2024
|
+
const end = Math.min(this.endExclusive, other.endExclusive);
|
|
2025
|
+
if (start <= end) {
|
|
2026
|
+
return new OffsetRange(start, end);
|
|
2027
|
+
}
|
|
2028
|
+
return undefined;
|
|
2029
|
+
}
|
|
2030
|
+
slice(arr) {
|
|
2031
|
+
return arr.slice(this.start, this.endExclusive);
|
|
2032
|
+
}
|
|
2033
|
+
/**
|
|
2034
|
+
* Returns the given value if it is contained in this instance, otherwise the closest value that is contained.
|
|
2035
|
+
* The range must not be empty.
|
|
2036
|
+
*/
|
|
2037
|
+
clip(value) {
|
|
2038
|
+
if (this.isEmpty) {
|
|
2039
|
+
throw new errors_1.BugIndicatingError(`Invalid clipping range: ${this.toString()}`);
|
|
2040
|
+
}
|
|
2041
|
+
return Math.max(this.start, Math.min(this.endExclusive - 1, value));
|
|
2042
|
+
}
|
|
2043
|
+
/**
|
|
2044
|
+
* Returns `r := value + k * length` such that `r` is contained in this range.
|
|
2045
|
+
* The range must not be empty.
|
|
2046
|
+
*
|
|
2047
|
+
* E.g. `[5, 10).clipCyclic(10) === 5`, `[5, 10).clipCyclic(11) === 6` and `[5, 10).clipCyclic(4) === 9`.
|
|
2048
|
+
*/
|
|
2049
|
+
clipCyclic(value) {
|
|
2050
|
+
if (this.isEmpty) {
|
|
2051
|
+
throw new errors_1.BugIndicatingError(`Invalid clipping range: ${this.toString()}`);
|
|
2052
|
+
}
|
|
2053
|
+
if (value < this.start) {
|
|
2054
|
+
return this.endExclusive - ((this.start - value) % this.length);
|
|
2055
|
+
}
|
|
2056
|
+
if (value >= this.endExclusive) {
|
|
2057
|
+
return this.start + ((value - this.start) % this.length);
|
|
2058
|
+
}
|
|
2059
|
+
return value;
|
|
2060
|
+
}
|
|
2061
|
+
}
|
|
2062
|
+
exports.OffsetRange = OffsetRange;
|
|
2063
|
+
class OffsetRangeSet {
|
|
2064
|
+
constructor() {
|
|
2065
|
+
this._sortedRanges = [];
|
|
2066
|
+
}
|
|
2067
|
+
addRange(range) {
|
|
2068
|
+
let i = 0;
|
|
2069
|
+
while (i < this._sortedRanges.length && this._sortedRanges[i].endExclusive < range.start) {
|
|
2070
|
+
i++;
|
|
2071
|
+
}
|
|
2072
|
+
let j = i;
|
|
2073
|
+
while (j < this._sortedRanges.length && this._sortedRanges[j].start <= range.endExclusive) {
|
|
2074
|
+
j++;
|
|
2075
|
+
}
|
|
2076
|
+
if (i === j) {
|
|
2077
|
+
this._sortedRanges.splice(i, 0, range);
|
|
2078
|
+
}
|
|
2079
|
+
else {
|
|
2080
|
+
const start = Math.min(range.start, this._sortedRanges[i].start);
|
|
2081
|
+
const end = Math.max(range.endExclusive, this._sortedRanges[j - 1].endExclusive);
|
|
2082
|
+
this._sortedRanges.splice(i, j - i, new OffsetRange(start, end));
|
|
2083
|
+
}
|
|
2084
|
+
}
|
|
2085
|
+
toString() {
|
|
2086
|
+
return this._sortedRanges.map(r => r.toString()).join(', ');
|
|
2087
|
+
}
|
|
2088
|
+
/**
|
|
2089
|
+
* Returns of there is a value that is contained in this instance and the given range.
|
|
2090
|
+
*/
|
|
2091
|
+
intersectsStrict(other) {
|
|
2092
|
+
// TODO use binary search
|
|
2093
|
+
let i = 0;
|
|
2094
|
+
while (i < this._sortedRanges.length && this._sortedRanges[i].endExclusive <= other.start) {
|
|
2095
|
+
i++;
|
|
2096
|
+
}
|
|
2097
|
+
return i < this._sortedRanges.length && this._sortedRanges[i].start < other.endExclusive;
|
|
2098
|
+
}
|
|
2099
|
+
intersectWithRange(other) {
|
|
2100
|
+
// TODO use binary search + slice
|
|
2101
|
+
const result = new OffsetRangeSet();
|
|
2102
|
+
for (const range of this._sortedRanges) {
|
|
2103
|
+
const intersection = range.intersect(other);
|
|
2104
|
+
if (intersection) {
|
|
2105
|
+
result.addRange(intersection);
|
|
2106
|
+
}
|
|
2107
|
+
}
|
|
2108
|
+
return result;
|
|
2109
|
+
}
|
|
2110
|
+
intersectWithRangeLength(other) {
|
|
2111
|
+
return this.intersectWithRange(other).length;
|
|
2112
|
+
}
|
|
2113
|
+
get length() {
|
|
2114
|
+
return this._sortedRanges.reduce((prev, cur) => prev + cur.length, 0);
|
|
2115
|
+
}
|
|
2116
|
+
}
|
|
2117
|
+
exports.OffsetRangeSet = OffsetRangeSet;
|
|
2118
|
+
|
|
2119
|
+
|
|
2120
|
+
/***/ }),
|
|
2121
|
+
|
|
2122
|
+
/***/ "./node_modules/vscode-diff/dist/vs/editor/common/core/position.js":
|
|
2123
|
+
/*!*************************************************************************!*\
|
|
2124
|
+
!*** ./node_modules/vscode-diff/dist/vs/editor/common/core/position.js ***!
|
|
2125
|
+
\*************************************************************************/
|
|
2126
|
+
/***/ ((__unused_webpack_module, exports) => {
|
|
2127
|
+
|
|
2128
|
+
|
|
2129
|
+
/*---------------------------------------------------------------------------------------------
|
|
2130
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
2131
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
2132
|
+
*--------------------------------------------------------------------------------------------*/
|
|
2133
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
2134
|
+
exports.Position = void 0;
|
|
2135
|
+
/**
|
|
2136
|
+
* A position in the editor.
|
|
2137
|
+
*/
|
|
2138
|
+
class Position {
|
|
2139
|
+
constructor(lineNumber, column) {
|
|
2140
|
+
this.lineNumber = lineNumber;
|
|
2141
|
+
this.column = column;
|
|
2142
|
+
}
|
|
2143
|
+
/**
|
|
2144
|
+
* Create a new position from this position.
|
|
2145
|
+
*
|
|
2146
|
+
* @param newLineNumber new line number
|
|
2147
|
+
* @param newColumn new column
|
|
2148
|
+
*/
|
|
2149
|
+
with(newLineNumber = this.lineNumber, newColumn = this.column) {
|
|
2150
|
+
if (newLineNumber === this.lineNumber && newColumn === this.column) {
|
|
2151
|
+
return this;
|
|
2152
|
+
}
|
|
2153
|
+
else {
|
|
2154
|
+
return new Position(newLineNumber, newColumn);
|
|
2155
|
+
}
|
|
2156
|
+
}
|
|
2157
|
+
/**
|
|
2158
|
+
* Derive a new position from this position.
|
|
2159
|
+
*
|
|
2160
|
+
* @param deltaLineNumber line number delta
|
|
2161
|
+
* @param deltaColumn column delta
|
|
2162
|
+
*/
|
|
2163
|
+
delta(deltaLineNumber = 0, deltaColumn = 0) {
|
|
2164
|
+
return this.with(this.lineNumber + deltaLineNumber, this.column + deltaColumn);
|
|
2165
|
+
}
|
|
2166
|
+
/**
|
|
2167
|
+
* Test if this position equals other position
|
|
2168
|
+
*/
|
|
2169
|
+
equals(other) {
|
|
2170
|
+
return Position.equals(this, other);
|
|
2171
|
+
}
|
|
2172
|
+
/**
|
|
2173
|
+
* Test if position `a` equals position `b`
|
|
2174
|
+
*/
|
|
2175
|
+
static equals(a, b) {
|
|
2176
|
+
if (!a && !b) {
|
|
2177
|
+
return true;
|
|
2178
|
+
}
|
|
2179
|
+
return (!!a &&
|
|
2180
|
+
!!b &&
|
|
2181
|
+
a.lineNumber === b.lineNumber &&
|
|
2182
|
+
a.column === b.column);
|
|
2183
|
+
}
|
|
2184
|
+
/**
|
|
2185
|
+
* Test if this position is before other position.
|
|
2186
|
+
* If the two positions are equal, the result will be false.
|
|
2187
|
+
*/
|
|
2188
|
+
isBefore(other) {
|
|
2189
|
+
return Position.isBefore(this, other);
|
|
2190
|
+
}
|
|
2191
|
+
/**
|
|
2192
|
+
* Test if position `a` is before position `b`.
|
|
2193
|
+
* If the two positions are equal, the result will be false.
|
|
2194
|
+
*/
|
|
2195
|
+
static isBefore(a, b) {
|
|
2196
|
+
if (a.lineNumber < b.lineNumber) {
|
|
2197
|
+
return true;
|
|
2198
|
+
}
|
|
2199
|
+
if (b.lineNumber < a.lineNumber) {
|
|
2200
|
+
return false;
|
|
2201
|
+
}
|
|
2202
|
+
return a.column < b.column;
|
|
2203
|
+
}
|
|
2204
|
+
/**
|
|
2205
|
+
* Test if this position is before other position.
|
|
2206
|
+
* If the two positions are equal, the result will be true.
|
|
2207
|
+
*/
|
|
2208
|
+
isBeforeOrEqual(other) {
|
|
2209
|
+
return Position.isBeforeOrEqual(this, other);
|
|
2210
|
+
}
|
|
2211
|
+
/**
|
|
2212
|
+
* Test if position `a` is before position `b`.
|
|
2213
|
+
* If the two positions are equal, the result will be true.
|
|
2214
|
+
*/
|
|
2215
|
+
static isBeforeOrEqual(a, b) {
|
|
2216
|
+
if (a.lineNumber < b.lineNumber) {
|
|
2217
|
+
return true;
|
|
2218
|
+
}
|
|
2219
|
+
if (b.lineNumber < a.lineNumber) {
|
|
2220
|
+
return false;
|
|
2221
|
+
}
|
|
2222
|
+
return a.column <= b.column;
|
|
2223
|
+
}
|
|
2224
|
+
/**
|
|
2225
|
+
* A function that compares positions, useful for sorting
|
|
2226
|
+
*/
|
|
2227
|
+
static compare(a, b) {
|
|
2228
|
+
const aLineNumber = a.lineNumber | 0;
|
|
2229
|
+
const bLineNumber = b.lineNumber | 0;
|
|
2230
|
+
if (aLineNumber === bLineNumber) {
|
|
2231
|
+
const aColumn = a.column | 0;
|
|
2232
|
+
const bColumn = b.column | 0;
|
|
2233
|
+
return aColumn - bColumn;
|
|
2234
|
+
}
|
|
2235
|
+
return aLineNumber - bLineNumber;
|
|
2236
|
+
}
|
|
2237
|
+
/**
|
|
2238
|
+
* Clone this position.
|
|
2239
|
+
*/
|
|
2240
|
+
clone() {
|
|
2241
|
+
return new Position(this.lineNumber, this.column);
|
|
2242
|
+
}
|
|
2243
|
+
/**
|
|
2244
|
+
* Convert to a human-readable representation.
|
|
2245
|
+
*/
|
|
2246
|
+
toString() {
|
|
2247
|
+
return '(' + this.lineNumber + ',' + this.column + ')';
|
|
2248
|
+
}
|
|
2249
|
+
// ---
|
|
2250
|
+
/**
|
|
2251
|
+
* Create a `Position` from an `IPosition`.
|
|
2252
|
+
*/
|
|
2253
|
+
static lift(pos) {
|
|
2254
|
+
return new Position(pos.lineNumber, pos.column);
|
|
2255
|
+
}
|
|
2256
|
+
/**
|
|
2257
|
+
* Test if `obj` is an `IPosition`.
|
|
2258
|
+
*/
|
|
2259
|
+
static isIPosition(obj) {
|
|
2260
|
+
return (obj
|
|
2261
|
+
&& (typeof obj.lineNumber === 'number')
|
|
2262
|
+
&& (typeof obj.column === 'number'));
|
|
2263
|
+
}
|
|
2264
|
+
}
|
|
2265
|
+
exports.Position = Position;
|
|
2266
|
+
|
|
2267
|
+
|
|
2268
|
+
/***/ }),
|
|
2269
|
+
|
|
2270
|
+
/***/ "./node_modules/vscode-diff/dist/vs/editor/common/core/range.js":
|
|
2271
|
+
/*!**********************************************************************!*\
|
|
2272
|
+
!*** ./node_modules/vscode-diff/dist/vs/editor/common/core/range.js ***!
|
|
2273
|
+
\**********************************************************************/
|
|
2274
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
2275
|
+
|
|
2276
|
+
|
|
2277
|
+
/*---------------------------------------------------------------------------------------------
|
|
2278
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
2279
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
2280
|
+
*--------------------------------------------------------------------------------------------*/
|
|
2281
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
2282
|
+
exports.Range = void 0;
|
|
2283
|
+
const position_1 = __webpack_require__(/*! ./position */ "./node_modules/vscode-diff/dist/vs/editor/common/core/position.js");
|
|
2284
|
+
/**
|
|
2285
|
+
* A range in the editor. (startLineNumber,startColumn) is <= (endLineNumber,endColumn)
|
|
2286
|
+
*/
|
|
2287
|
+
class Range {
|
|
2288
|
+
constructor(startLineNumber, startColumn, endLineNumber, endColumn) {
|
|
2289
|
+
if ((startLineNumber > endLineNumber) || (startLineNumber === endLineNumber && startColumn > endColumn)) {
|
|
2290
|
+
this.startLineNumber = endLineNumber;
|
|
2291
|
+
this.startColumn = endColumn;
|
|
2292
|
+
this.endLineNumber = startLineNumber;
|
|
2293
|
+
this.endColumn = startColumn;
|
|
2294
|
+
}
|
|
2295
|
+
else {
|
|
2296
|
+
this.startLineNumber = startLineNumber;
|
|
2297
|
+
this.startColumn = startColumn;
|
|
2298
|
+
this.endLineNumber = endLineNumber;
|
|
2299
|
+
this.endColumn = endColumn;
|
|
2300
|
+
}
|
|
2301
|
+
}
|
|
2302
|
+
/**
|
|
2303
|
+
* Test if this range is empty.
|
|
2304
|
+
*/
|
|
2305
|
+
isEmpty() {
|
|
2306
|
+
return Range.isEmpty(this);
|
|
2307
|
+
}
|
|
2308
|
+
/**
|
|
2309
|
+
* Test if `range` is empty.
|
|
2310
|
+
*/
|
|
2311
|
+
static isEmpty(range) {
|
|
2312
|
+
return (range.startLineNumber === range.endLineNumber && range.startColumn === range.endColumn);
|
|
2313
|
+
}
|
|
2314
|
+
/**
|
|
2315
|
+
* Test if position is in this range. If the position is at the edges, will return true.
|
|
2316
|
+
*/
|
|
2317
|
+
containsPosition(position) {
|
|
2318
|
+
return Range.containsPosition(this, position);
|
|
2319
|
+
}
|
|
2320
|
+
/**
|
|
2321
|
+
* Test if `position` is in `range`. If the position is at the edges, will return true.
|
|
2322
|
+
*/
|
|
2323
|
+
static containsPosition(range, position) {
|
|
2324
|
+
if (position.lineNumber < range.startLineNumber || position.lineNumber > range.endLineNumber) {
|
|
2325
|
+
return false;
|
|
2326
|
+
}
|
|
2327
|
+
if (position.lineNumber === range.startLineNumber && position.column < range.startColumn) {
|
|
2328
|
+
return false;
|
|
2329
|
+
}
|
|
2330
|
+
if (position.lineNumber === range.endLineNumber && position.column > range.endColumn) {
|
|
2331
|
+
return false;
|
|
2332
|
+
}
|
|
2333
|
+
return true;
|
|
2334
|
+
}
|
|
2335
|
+
/**
|
|
2336
|
+
* Test if `position` is in `range`. If the position is at the edges, will return false.
|
|
2337
|
+
* @internal
|
|
2338
|
+
*/
|
|
2339
|
+
static strictContainsPosition(range, position) {
|
|
2340
|
+
if (position.lineNumber < range.startLineNumber || position.lineNumber > range.endLineNumber) {
|
|
2341
|
+
return false;
|
|
2342
|
+
}
|
|
2343
|
+
if (position.lineNumber === range.startLineNumber && position.column <= range.startColumn) {
|
|
2344
|
+
return false;
|
|
2345
|
+
}
|
|
2346
|
+
if (position.lineNumber === range.endLineNumber && position.column >= range.endColumn) {
|
|
2347
|
+
return false;
|
|
2348
|
+
}
|
|
2349
|
+
return true;
|
|
2350
|
+
}
|
|
2351
|
+
/**
|
|
2352
|
+
* Test if range is in this range. If the range is equal to this range, will return true.
|
|
2353
|
+
*/
|
|
2354
|
+
containsRange(range) {
|
|
2355
|
+
return Range.containsRange(this, range);
|
|
2356
|
+
}
|
|
2357
|
+
/**
|
|
2358
|
+
* Test if `otherRange` is in `range`. If the ranges are equal, will return true.
|
|
2359
|
+
*/
|
|
2360
|
+
static containsRange(range, otherRange) {
|
|
2361
|
+
if (otherRange.startLineNumber < range.startLineNumber || otherRange.endLineNumber < range.startLineNumber) {
|
|
2362
|
+
return false;
|
|
2363
|
+
}
|
|
2364
|
+
if (otherRange.startLineNumber > range.endLineNumber || otherRange.endLineNumber > range.endLineNumber) {
|
|
2365
|
+
return false;
|
|
2366
|
+
}
|
|
2367
|
+
if (otherRange.startLineNumber === range.startLineNumber && otherRange.startColumn < range.startColumn) {
|
|
2368
|
+
return false;
|
|
2369
|
+
}
|
|
2370
|
+
if (otherRange.endLineNumber === range.endLineNumber && otherRange.endColumn > range.endColumn) {
|
|
2371
|
+
return false;
|
|
2372
|
+
}
|
|
2373
|
+
return true;
|
|
2374
|
+
}
|
|
2375
|
+
/**
|
|
2376
|
+
* Test if `range` is strictly in this range. `range` must start after and end before this range for the result to be true.
|
|
2377
|
+
*/
|
|
2378
|
+
strictContainsRange(range) {
|
|
2379
|
+
return Range.strictContainsRange(this, range);
|
|
2380
|
+
}
|
|
2381
|
+
/**
|
|
2382
|
+
* Test if `otherRange` is strictly in `range` (must start after, and end before). If the ranges are equal, will return false.
|
|
2383
|
+
*/
|
|
2384
|
+
static strictContainsRange(range, otherRange) {
|
|
2385
|
+
if (otherRange.startLineNumber < range.startLineNumber || otherRange.endLineNumber < range.startLineNumber) {
|
|
2386
|
+
return false;
|
|
2387
|
+
}
|
|
2388
|
+
if (otherRange.startLineNumber > range.endLineNumber || otherRange.endLineNumber > range.endLineNumber) {
|
|
2389
|
+
return false;
|
|
2390
|
+
}
|
|
2391
|
+
if (otherRange.startLineNumber === range.startLineNumber && otherRange.startColumn <= range.startColumn) {
|
|
2392
|
+
return false;
|
|
2393
|
+
}
|
|
2394
|
+
if (otherRange.endLineNumber === range.endLineNumber && otherRange.endColumn >= range.endColumn) {
|
|
2395
|
+
return false;
|
|
2396
|
+
}
|
|
2397
|
+
return true;
|
|
2398
|
+
}
|
|
2399
|
+
/**
|
|
2400
|
+
* A reunion of the two ranges.
|
|
2401
|
+
* The smallest position will be used as the start point, and the largest one as the end point.
|
|
2402
|
+
*/
|
|
2403
|
+
plusRange(range) {
|
|
2404
|
+
return Range.plusRange(this, range);
|
|
2405
|
+
}
|
|
2406
|
+
/**
|
|
2407
|
+
* A reunion of the two ranges.
|
|
2408
|
+
* The smallest position will be used as the start point, and the largest one as the end point.
|
|
2409
|
+
*/
|
|
2410
|
+
static plusRange(a, b) {
|
|
2411
|
+
let startLineNumber;
|
|
2412
|
+
let startColumn;
|
|
2413
|
+
let endLineNumber;
|
|
2414
|
+
let endColumn;
|
|
2415
|
+
if (b.startLineNumber < a.startLineNumber) {
|
|
2416
|
+
startLineNumber = b.startLineNumber;
|
|
2417
|
+
startColumn = b.startColumn;
|
|
2418
|
+
}
|
|
2419
|
+
else if (b.startLineNumber === a.startLineNumber) {
|
|
2420
|
+
startLineNumber = b.startLineNumber;
|
|
2421
|
+
startColumn = Math.min(b.startColumn, a.startColumn);
|
|
2422
|
+
}
|
|
2423
|
+
else {
|
|
2424
|
+
startLineNumber = a.startLineNumber;
|
|
2425
|
+
startColumn = a.startColumn;
|
|
2426
|
+
}
|
|
2427
|
+
if (b.endLineNumber > a.endLineNumber) {
|
|
2428
|
+
endLineNumber = b.endLineNumber;
|
|
2429
|
+
endColumn = b.endColumn;
|
|
2430
|
+
}
|
|
2431
|
+
else if (b.endLineNumber === a.endLineNumber) {
|
|
2432
|
+
endLineNumber = b.endLineNumber;
|
|
2433
|
+
endColumn = Math.max(b.endColumn, a.endColumn);
|
|
2434
|
+
}
|
|
2435
|
+
else {
|
|
2436
|
+
endLineNumber = a.endLineNumber;
|
|
2437
|
+
endColumn = a.endColumn;
|
|
2438
|
+
}
|
|
2439
|
+
return new Range(startLineNumber, startColumn, endLineNumber, endColumn);
|
|
2440
|
+
}
|
|
2441
|
+
/**
|
|
2442
|
+
* A intersection of the two ranges.
|
|
2443
|
+
*/
|
|
2444
|
+
intersectRanges(range) {
|
|
2445
|
+
return Range.intersectRanges(this, range);
|
|
2446
|
+
}
|
|
2447
|
+
/**
|
|
2448
|
+
* A intersection of the two ranges.
|
|
2449
|
+
*/
|
|
2450
|
+
static intersectRanges(a, b) {
|
|
2451
|
+
let resultStartLineNumber = a.startLineNumber;
|
|
2452
|
+
let resultStartColumn = a.startColumn;
|
|
2453
|
+
let resultEndLineNumber = a.endLineNumber;
|
|
2454
|
+
let resultEndColumn = a.endColumn;
|
|
2455
|
+
const otherStartLineNumber = b.startLineNumber;
|
|
2456
|
+
const otherStartColumn = b.startColumn;
|
|
2457
|
+
const otherEndLineNumber = b.endLineNumber;
|
|
2458
|
+
const otherEndColumn = b.endColumn;
|
|
2459
|
+
if (resultStartLineNumber < otherStartLineNumber) {
|
|
2460
|
+
resultStartLineNumber = otherStartLineNumber;
|
|
2461
|
+
resultStartColumn = otherStartColumn;
|
|
2462
|
+
}
|
|
2463
|
+
else if (resultStartLineNumber === otherStartLineNumber) {
|
|
2464
|
+
resultStartColumn = Math.max(resultStartColumn, otherStartColumn);
|
|
2465
|
+
}
|
|
2466
|
+
if (resultEndLineNumber > otherEndLineNumber) {
|
|
2467
|
+
resultEndLineNumber = otherEndLineNumber;
|
|
2468
|
+
resultEndColumn = otherEndColumn;
|
|
2469
|
+
}
|
|
2470
|
+
else if (resultEndLineNumber === otherEndLineNumber) {
|
|
2471
|
+
resultEndColumn = Math.min(resultEndColumn, otherEndColumn);
|
|
2472
|
+
}
|
|
2473
|
+
// Check if selection is now empty
|
|
2474
|
+
if (resultStartLineNumber > resultEndLineNumber) {
|
|
2475
|
+
return null;
|
|
2476
|
+
}
|
|
2477
|
+
if (resultStartLineNumber === resultEndLineNumber && resultStartColumn > resultEndColumn) {
|
|
2478
|
+
return null;
|
|
2479
|
+
}
|
|
2480
|
+
return new Range(resultStartLineNumber, resultStartColumn, resultEndLineNumber, resultEndColumn);
|
|
2481
|
+
}
|
|
2482
|
+
/**
|
|
2483
|
+
* Test if this range equals other.
|
|
2484
|
+
*/
|
|
2485
|
+
equalsRange(other) {
|
|
2486
|
+
return Range.equalsRange(this, other);
|
|
2487
|
+
}
|
|
2488
|
+
/**
|
|
2489
|
+
* Test if range `a` equals `b`.
|
|
2490
|
+
*/
|
|
2491
|
+
static equalsRange(a, b) {
|
|
2492
|
+
if (!a && !b) {
|
|
2493
|
+
return true;
|
|
2494
|
+
}
|
|
2495
|
+
return (!!a &&
|
|
2496
|
+
!!b &&
|
|
2497
|
+
a.startLineNumber === b.startLineNumber &&
|
|
2498
|
+
a.startColumn === b.startColumn &&
|
|
2499
|
+
a.endLineNumber === b.endLineNumber &&
|
|
2500
|
+
a.endColumn === b.endColumn);
|
|
2501
|
+
}
|
|
2502
|
+
/**
|
|
2503
|
+
* Return the end position (which will be after or equal to the start position)
|
|
2504
|
+
*/
|
|
2505
|
+
getEndPosition() {
|
|
2506
|
+
return Range.getEndPosition(this);
|
|
2507
|
+
}
|
|
2508
|
+
/**
|
|
2509
|
+
* Return the end position (which will be after or equal to the start position)
|
|
2510
|
+
*/
|
|
2511
|
+
static getEndPosition(range) {
|
|
2512
|
+
return new position_1.Position(range.endLineNumber, range.endColumn);
|
|
2513
|
+
}
|
|
2514
|
+
/**
|
|
2515
|
+
* Return the start position (which will be before or equal to the end position)
|
|
2516
|
+
*/
|
|
2517
|
+
getStartPosition() {
|
|
2518
|
+
return Range.getStartPosition(this);
|
|
2519
|
+
}
|
|
2520
|
+
/**
|
|
2521
|
+
* Return the start position (which will be before or equal to the end position)
|
|
2522
|
+
*/
|
|
2523
|
+
static getStartPosition(range) {
|
|
2524
|
+
return new position_1.Position(range.startLineNumber, range.startColumn);
|
|
2525
|
+
}
|
|
2526
|
+
/**
|
|
2527
|
+
* Transform to a user presentable string representation.
|
|
2528
|
+
*/
|
|
2529
|
+
toString() {
|
|
2530
|
+
return '[' + this.startLineNumber + ',' + this.startColumn + ' -> ' + this.endLineNumber + ',' + this.endColumn + ']';
|
|
2531
|
+
}
|
|
2532
|
+
/**
|
|
2533
|
+
* Create a new range using this range's start position, and using endLineNumber and endColumn as the end position.
|
|
2534
|
+
*/
|
|
2535
|
+
setEndPosition(endLineNumber, endColumn) {
|
|
2536
|
+
return new Range(this.startLineNumber, this.startColumn, endLineNumber, endColumn);
|
|
2537
|
+
}
|
|
2538
|
+
/**
|
|
2539
|
+
* Create a new range using this range's end position, and using startLineNumber and startColumn as the start position.
|
|
2540
|
+
*/
|
|
2541
|
+
setStartPosition(startLineNumber, startColumn) {
|
|
2542
|
+
return new Range(startLineNumber, startColumn, this.endLineNumber, this.endColumn);
|
|
2543
|
+
}
|
|
2544
|
+
/**
|
|
2545
|
+
* Create a new empty range using this range's start position.
|
|
2546
|
+
*/
|
|
2547
|
+
collapseToStart() {
|
|
2548
|
+
return Range.collapseToStart(this);
|
|
2549
|
+
}
|
|
2550
|
+
/**
|
|
2551
|
+
* Create a new empty range using this range's start position.
|
|
2552
|
+
*/
|
|
2553
|
+
static collapseToStart(range) {
|
|
2554
|
+
return new Range(range.startLineNumber, range.startColumn, range.startLineNumber, range.startColumn);
|
|
2555
|
+
}
|
|
2556
|
+
/**
|
|
2557
|
+
* Create a new empty range using this range's end position.
|
|
2558
|
+
*/
|
|
2559
|
+
collapseToEnd() {
|
|
2560
|
+
return Range.collapseToEnd(this);
|
|
2561
|
+
}
|
|
2562
|
+
/**
|
|
2563
|
+
* Create a new empty range using this range's end position.
|
|
2564
|
+
*/
|
|
2565
|
+
static collapseToEnd(range) {
|
|
2566
|
+
return new Range(range.endLineNumber, range.endColumn, range.endLineNumber, range.endColumn);
|
|
2567
|
+
}
|
|
2568
|
+
/**
|
|
2569
|
+
* Moves the range by the given amount of lines.
|
|
2570
|
+
*/
|
|
2571
|
+
delta(lineCount) {
|
|
2572
|
+
return new Range(this.startLineNumber + lineCount, this.startColumn, this.endLineNumber + lineCount, this.endColumn);
|
|
2573
|
+
}
|
|
2574
|
+
// ---
|
|
2575
|
+
static fromPositions(start, end = start) {
|
|
2576
|
+
return new Range(start.lineNumber, start.column, end.lineNumber, end.column);
|
|
2577
|
+
}
|
|
2578
|
+
static lift(range) {
|
|
2579
|
+
if (!range) {
|
|
2580
|
+
return null;
|
|
2581
|
+
}
|
|
2582
|
+
return new Range(range.startLineNumber, range.startColumn, range.endLineNumber, range.endColumn);
|
|
2583
|
+
}
|
|
2584
|
+
/**
|
|
2585
|
+
* Test if `obj` is an `IRange`.
|
|
2586
|
+
*/
|
|
2587
|
+
static isIRange(obj) {
|
|
2588
|
+
return (obj
|
|
2589
|
+
&& (typeof obj.startLineNumber === 'number')
|
|
2590
|
+
&& (typeof obj.startColumn === 'number')
|
|
2591
|
+
&& (typeof obj.endLineNumber === 'number')
|
|
2592
|
+
&& (typeof obj.endColumn === 'number'));
|
|
2593
|
+
}
|
|
2594
|
+
/**
|
|
2595
|
+
* Test if the two ranges are touching in any way.
|
|
2596
|
+
*/
|
|
2597
|
+
static areIntersectingOrTouching(a, b) {
|
|
2598
|
+
// Check if `a` is before `b`
|
|
2599
|
+
if (a.endLineNumber < b.startLineNumber || (a.endLineNumber === b.startLineNumber && a.endColumn < b.startColumn)) {
|
|
2600
|
+
return false;
|
|
2601
|
+
}
|
|
2602
|
+
// Check if `b` is before `a`
|
|
2603
|
+
if (b.endLineNumber < a.startLineNumber || (b.endLineNumber === a.startLineNumber && b.endColumn < a.startColumn)) {
|
|
2604
|
+
return false;
|
|
2605
|
+
}
|
|
2606
|
+
// These ranges must intersect
|
|
2607
|
+
return true;
|
|
2608
|
+
}
|
|
2609
|
+
/**
|
|
2610
|
+
* Test if the two ranges are intersecting. If the ranges are touching it returns true.
|
|
2611
|
+
*/
|
|
2612
|
+
static areIntersecting(a, b) {
|
|
2613
|
+
// Check if `a` is before `b`
|
|
2614
|
+
if (a.endLineNumber < b.startLineNumber || (a.endLineNumber === b.startLineNumber && a.endColumn <= b.startColumn)) {
|
|
2615
|
+
return false;
|
|
2616
|
+
}
|
|
2617
|
+
// Check if `b` is before `a`
|
|
2618
|
+
if (b.endLineNumber < a.startLineNumber || (b.endLineNumber === a.startLineNumber && b.endColumn <= a.startColumn)) {
|
|
2619
|
+
return false;
|
|
2620
|
+
}
|
|
2621
|
+
// These ranges must intersect
|
|
2622
|
+
return true;
|
|
2623
|
+
}
|
|
2624
|
+
/**
|
|
2625
|
+
* A function that compares ranges, useful for sorting ranges
|
|
2626
|
+
* It will first compare ranges on the startPosition and then on the endPosition
|
|
2627
|
+
*/
|
|
2628
|
+
static compareRangesUsingStarts(a, b) {
|
|
2629
|
+
if (a && b) {
|
|
2630
|
+
const aStartLineNumber = a.startLineNumber | 0;
|
|
2631
|
+
const bStartLineNumber = b.startLineNumber | 0;
|
|
2632
|
+
if (aStartLineNumber === bStartLineNumber) {
|
|
2633
|
+
const aStartColumn = a.startColumn | 0;
|
|
2634
|
+
const bStartColumn = b.startColumn | 0;
|
|
2635
|
+
if (aStartColumn === bStartColumn) {
|
|
2636
|
+
const aEndLineNumber = a.endLineNumber | 0;
|
|
2637
|
+
const bEndLineNumber = b.endLineNumber | 0;
|
|
2638
|
+
if (aEndLineNumber === bEndLineNumber) {
|
|
2639
|
+
const aEndColumn = a.endColumn | 0;
|
|
2640
|
+
const bEndColumn = b.endColumn | 0;
|
|
2641
|
+
return aEndColumn - bEndColumn;
|
|
2642
|
+
}
|
|
2643
|
+
return aEndLineNumber - bEndLineNumber;
|
|
2644
|
+
}
|
|
2645
|
+
return aStartColumn - bStartColumn;
|
|
2646
|
+
}
|
|
2647
|
+
return aStartLineNumber - bStartLineNumber;
|
|
2648
|
+
}
|
|
2649
|
+
const aExists = (a ? 1 : 0);
|
|
2650
|
+
const bExists = (b ? 1 : 0);
|
|
2651
|
+
return aExists - bExists;
|
|
2652
|
+
}
|
|
2653
|
+
/**
|
|
2654
|
+
* A function that compares ranges, useful for sorting ranges
|
|
2655
|
+
* It will first compare ranges on the endPosition and then on the startPosition
|
|
2656
|
+
*/
|
|
2657
|
+
static compareRangesUsingEnds(a, b) {
|
|
2658
|
+
if (a.endLineNumber === b.endLineNumber) {
|
|
2659
|
+
if (a.endColumn === b.endColumn) {
|
|
2660
|
+
if (a.startLineNumber === b.startLineNumber) {
|
|
2661
|
+
return a.startColumn - b.startColumn;
|
|
2662
|
+
}
|
|
2663
|
+
return a.startLineNumber - b.startLineNumber;
|
|
2664
|
+
}
|
|
2665
|
+
return a.endColumn - b.endColumn;
|
|
2666
|
+
}
|
|
2667
|
+
return a.endLineNumber - b.endLineNumber;
|
|
2668
|
+
}
|
|
2669
|
+
/**
|
|
2670
|
+
* Test if the range spans multiple lines.
|
|
2671
|
+
*/
|
|
2672
|
+
static spansMultipleLines(range) {
|
|
2673
|
+
return range.endLineNumber > range.startLineNumber;
|
|
2674
|
+
}
|
|
2675
|
+
toJSON() {
|
|
2676
|
+
return this;
|
|
2677
|
+
}
|
|
2678
|
+
}
|
|
2679
|
+
exports.Range = Range;
|
|
2680
|
+
|
|
2681
|
+
|
|
2682
|
+
/***/ }),
|
|
2683
|
+
|
|
2684
|
+
/***/ "./node_modules/vscode-diff/dist/vs/editor/common/diff/advancedLinesDiffComputer.js":
|
|
2685
|
+
/*!******************************************************************************************!*\
|
|
2686
|
+
!*** ./node_modules/vscode-diff/dist/vs/editor/common/diff/advancedLinesDiffComputer.js ***!
|
|
2687
|
+
\******************************************************************************************/
|
|
2688
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
2689
|
+
|
|
2690
|
+
|
|
2691
|
+
/*---------------------------------------------------------------------------------------------
|
|
2692
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
2693
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
2694
|
+
*--------------------------------------------------------------------------------------------*/
|
|
2695
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
2696
|
+
exports.findFirstMonotonous = exports.findLastMonotonous = exports.LinesSliceCharSequence = exports.LineSequence = exports.getLineRangeMapping = exports.lineRangeMappingFromRangeMappings = exports.AdvancedLinesDiffComputer = void 0;
|
|
2697
|
+
const arrays_1 = __webpack_require__(/*! ../../../base/common/arrays */ "./node_modules/vscode-diff/dist/vs/base/common/arrays.js");
|
|
2698
|
+
const assert_1 = __webpack_require__(/*! ../../../base/common/assert */ "./node_modules/vscode-diff/dist/vs/base/common/assert.js");
|
|
2699
|
+
const collections_1 = __webpack_require__(/*! ../../../base/common/collections */ "./node_modules/vscode-diff/dist/vs/base/common/collections.js");
|
|
2700
|
+
const errors_1 = __webpack_require__(/*! ../../../base/common/errors */ "./node_modules/vscode-diff/dist/vs/base/common/errors.js");
|
|
2701
|
+
const lineRange_1 = __webpack_require__(/*! ../core/lineRange */ "./node_modules/vscode-diff/dist/vs/editor/common/core/lineRange.js");
|
|
2702
|
+
const offsetRange_1 = __webpack_require__(/*! ../core/offsetRange */ "./node_modules/vscode-diff/dist/vs/editor/common/core/offsetRange.js");
|
|
2703
|
+
const position_1 = __webpack_require__(/*! ../core/position */ "./node_modules/vscode-diff/dist/vs/editor/common/core/position.js");
|
|
2704
|
+
const range_1 = __webpack_require__(/*! ../core/range */ "./node_modules/vscode-diff/dist/vs/editor/common/core/range.js");
|
|
2705
|
+
const diffAlgorithm_1 = __webpack_require__(/*! ../diff/algorithms/diffAlgorithm */ "./node_modules/vscode-diff/dist/vs/editor/common/diff/algorithms/diffAlgorithm.js");
|
|
2706
|
+
const dynamicProgrammingDiffing_1 = __webpack_require__(/*! ../diff/algorithms/dynamicProgrammingDiffing */ "./node_modules/vscode-diff/dist/vs/editor/common/diff/algorithms/dynamicProgrammingDiffing.js");
|
|
2707
|
+
const joinSequenceDiffs_1 = __webpack_require__(/*! ../diff/algorithms/joinSequenceDiffs */ "./node_modules/vscode-diff/dist/vs/editor/common/diff/algorithms/joinSequenceDiffs.js");
|
|
2708
|
+
const myersDiffAlgorithm_1 = __webpack_require__(/*! ../diff/algorithms/myersDiffAlgorithm */ "./node_modules/vscode-diff/dist/vs/editor/common/diff/algorithms/myersDiffAlgorithm.js");
|
|
2709
|
+
const linesDiffComputer_1 = __webpack_require__(/*! ./linesDiffComputer */ "./node_modules/vscode-diff/dist/vs/editor/common/diff/linesDiffComputer.js");
|
|
2710
|
+
class AdvancedLinesDiffComputer {
|
|
2711
|
+
constructor() {
|
|
2712
|
+
this.dynamicProgrammingDiffing = new dynamicProgrammingDiffing_1.DynamicProgrammingDiffing();
|
|
2713
|
+
this.myersDiffingAlgorithm = new myersDiffAlgorithm_1.MyersDiffAlgorithm();
|
|
2714
|
+
}
|
|
2715
|
+
computeDiff(originalLines, modifiedLines, options) {
|
|
2716
|
+
if (originalLines.length <= 1 && (0, arrays_1.equals)(originalLines, modifiedLines, (a, b) => a === b)) {
|
|
2717
|
+
return new linesDiffComputer_1.LinesDiff([], [], false);
|
|
2718
|
+
}
|
|
2719
|
+
if (originalLines.length === 1 && originalLines[0].length === 0 || modifiedLines.length === 1 && modifiedLines[0].length === 0) {
|
|
2720
|
+
return new linesDiffComputer_1.LinesDiff([
|
|
2721
|
+
new linesDiffComputer_1.LineRangeMapping(new lineRange_1.LineRange(1, originalLines.length + 1), new lineRange_1.LineRange(1, modifiedLines.length + 1), [
|
|
2722
|
+
new linesDiffComputer_1.RangeMapping(new range_1.Range(1, 1, originalLines.length, originalLines[0].length + 1), new range_1.Range(1, 1, modifiedLines.length, modifiedLines[0].length + 1))
|
|
2723
|
+
])
|
|
2724
|
+
], [], false);
|
|
2725
|
+
}
|
|
2726
|
+
const timeout = options.maxComputationTimeMs === 0 ? diffAlgorithm_1.InfiniteTimeout.instance : new diffAlgorithm_1.DateTimeout(options.maxComputationTimeMs);
|
|
2727
|
+
const considerWhitespaceChanges = !options.ignoreTrimWhitespace;
|
|
2728
|
+
const perfectHashes = new Map();
|
|
2729
|
+
function getOrCreateHash(text) {
|
|
2730
|
+
let hash = perfectHashes.get(text);
|
|
2731
|
+
if (hash === undefined) {
|
|
2732
|
+
hash = perfectHashes.size;
|
|
2733
|
+
perfectHashes.set(text, hash);
|
|
2734
|
+
}
|
|
2735
|
+
return hash;
|
|
2736
|
+
}
|
|
2737
|
+
const srcDocLines = originalLines.map((l) => getOrCreateHash(l.trim()));
|
|
2738
|
+
const tgtDocLines = modifiedLines.map((l) => getOrCreateHash(l.trim()));
|
|
2739
|
+
const sequence1 = new LineSequence(srcDocLines, originalLines);
|
|
2740
|
+
const sequence2 = new LineSequence(tgtDocLines, modifiedLines);
|
|
2741
|
+
const lineAlignmentResult = (() => {
|
|
2742
|
+
if (sequence1.length + sequence2.length < 1700) {
|
|
2743
|
+
// Use the improved algorithm for small files
|
|
2744
|
+
return this.dynamicProgrammingDiffing.compute(sequence1, sequence2, timeout, (offset1, offset2) => originalLines[offset1] === modifiedLines[offset2]
|
|
2745
|
+
? modifiedLines[offset2].length === 0
|
|
2746
|
+
? 0.1
|
|
2747
|
+
: 1 + Math.log(1 + modifiedLines[offset2].length)
|
|
2748
|
+
: 0.99);
|
|
2749
|
+
}
|
|
2750
|
+
return this.myersDiffingAlgorithm.compute(sequence1, sequence2);
|
|
2751
|
+
})();
|
|
2752
|
+
let lineAlignments = lineAlignmentResult.diffs;
|
|
2753
|
+
let hitTimeout = lineAlignmentResult.hitTimeout;
|
|
2754
|
+
lineAlignments = (0, joinSequenceDiffs_1.optimizeSequenceDiffs)(sequence1, sequence2, lineAlignments);
|
|
2755
|
+
lineAlignments = (0, joinSequenceDiffs_1.removeRandomLineMatches)(sequence1, sequence2, lineAlignments);
|
|
2756
|
+
const alignments = [];
|
|
2757
|
+
const scanForWhitespaceChanges = (equalLinesCount) => {
|
|
2758
|
+
if (!considerWhitespaceChanges) {
|
|
2759
|
+
return;
|
|
2760
|
+
}
|
|
2761
|
+
for (let i = 0; i < equalLinesCount; i++) {
|
|
2762
|
+
const seq1Offset = seq1LastStart + i;
|
|
2763
|
+
const seq2Offset = seq2LastStart + i;
|
|
2764
|
+
if (originalLines[seq1Offset] !== modifiedLines[seq2Offset]) {
|
|
2765
|
+
// This is because of whitespace changes, diff these lines
|
|
2766
|
+
const characterDiffs = this.refineDiff(originalLines, modifiedLines, new diffAlgorithm_1.SequenceDiff(new offsetRange_1.OffsetRange(seq1Offset, seq1Offset + 1), new offsetRange_1.OffsetRange(seq2Offset, seq2Offset + 1)), timeout, considerWhitespaceChanges);
|
|
2767
|
+
for (const a of characterDiffs.mappings) {
|
|
2768
|
+
alignments.push(a);
|
|
2769
|
+
}
|
|
2770
|
+
if (characterDiffs.hitTimeout) {
|
|
2771
|
+
hitTimeout = true;
|
|
2772
|
+
}
|
|
2773
|
+
}
|
|
2774
|
+
}
|
|
2775
|
+
};
|
|
2776
|
+
let seq1LastStart = 0;
|
|
2777
|
+
let seq2LastStart = 0;
|
|
2778
|
+
for (const diff of lineAlignments) {
|
|
2779
|
+
(0, assert_1.assertFn)(() => diff.seq1Range.start - seq1LastStart === diff.seq2Range.start - seq2LastStart);
|
|
2780
|
+
const equalLinesCount = diff.seq1Range.start - seq1LastStart;
|
|
2781
|
+
scanForWhitespaceChanges(equalLinesCount);
|
|
2782
|
+
seq1LastStart = diff.seq1Range.endExclusive;
|
|
2783
|
+
seq2LastStart = diff.seq2Range.endExclusive;
|
|
2784
|
+
const characterDiffs = this.refineDiff(originalLines, modifiedLines, diff, timeout, considerWhitespaceChanges);
|
|
2785
|
+
if (characterDiffs.hitTimeout) {
|
|
2786
|
+
hitTimeout = true;
|
|
2787
|
+
}
|
|
2788
|
+
for (const a of characterDiffs.mappings) {
|
|
2789
|
+
alignments.push(a);
|
|
2790
|
+
}
|
|
2791
|
+
}
|
|
2792
|
+
scanForWhitespaceChanges(originalLines.length - seq1LastStart);
|
|
2793
|
+
const changes = lineRangeMappingFromRangeMappings(alignments, originalLines, modifiedLines);
|
|
2794
|
+
let moves = [];
|
|
2795
|
+
if (options.computeMoves) {
|
|
2796
|
+
moves = this.computeMoves(changes, originalLines, modifiedLines, srcDocLines, tgtDocLines, timeout, considerWhitespaceChanges);
|
|
2797
|
+
}
|
|
2798
|
+
// Make sure all ranges are valid
|
|
2799
|
+
(0, assert_1.assertFn)(() => {
|
|
2800
|
+
function validatePosition(pos, lines) {
|
|
2801
|
+
if (pos.lineNumber < 1 || pos.lineNumber > lines.length) {
|
|
2802
|
+
return false;
|
|
2803
|
+
}
|
|
2804
|
+
const line = lines[pos.lineNumber - 1];
|
|
2805
|
+
if (pos.column < 1 || pos.column > line.length + 1) {
|
|
2806
|
+
return false;
|
|
2807
|
+
}
|
|
2808
|
+
return true;
|
|
2809
|
+
}
|
|
2810
|
+
function validateRange(range, lines) {
|
|
2811
|
+
if (range.startLineNumber < 1 || range.startLineNumber > lines.length + 1) {
|
|
2812
|
+
return false;
|
|
2813
|
+
}
|
|
2814
|
+
if (range.endLineNumberExclusive < 1 || range.endLineNumberExclusive > lines.length + 1) {
|
|
2815
|
+
return false;
|
|
2816
|
+
}
|
|
2817
|
+
return true;
|
|
2818
|
+
}
|
|
2819
|
+
for (const c of changes) {
|
|
2820
|
+
if (!c.innerChanges) {
|
|
2821
|
+
return false;
|
|
2822
|
+
}
|
|
2823
|
+
for (const ic of c.innerChanges) {
|
|
2824
|
+
const valid = validatePosition(ic.modifiedRange.getStartPosition(), modifiedLines) && validatePosition(ic.modifiedRange.getEndPosition(), modifiedLines) &&
|
|
2825
|
+
validatePosition(ic.originalRange.getStartPosition(), originalLines) && validatePosition(ic.originalRange.getEndPosition(), originalLines);
|
|
2826
|
+
if (!valid) {
|
|
2827
|
+
return false;
|
|
2828
|
+
}
|
|
2829
|
+
}
|
|
2830
|
+
if (!validateRange(c.modifiedRange, modifiedLines) || !validateRange(c.originalRange, originalLines)) {
|
|
2831
|
+
return false;
|
|
2832
|
+
}
|
|
2833
|
+
}
|
|
2834
|
+
return true;
|
|
2835
|
+
});
|
|
2836
|
+
return new linesDiffComputer_1.LinesDiff(changes, moves, hitTimeout);
|
|
2837
|
+
}
|
|
2838
|
+
computeMoves(changes, originalLines, modifiedLines, hashedOriginalLines, hashedModifiedLines, timeout, considerWhitespaceChanges) {
|
|
2839
|
+
const moves = [];
|
|
2840
|
+
const deletions = changes
|
|
2841
|
+
.filter(c => c.modifiedRange.isEmpty && c.originalRange.length >= 3)
|
|
2842
|
+
.map(d => new LineRangeFragment(d.originalRange, originalLines, d));
|
|
2843
|
+
const insertions = new Set(changes
|
|
2844
|
+
.filter(c => c.originalRange.isEmpty && c.modifiedRange.length >= 3)
|
|
2845
|
+
.map(d => new LineRangeFragment(d.modifiedRange, modifiedLines, d)));
|
|
2846
|
+
const excludedChanges = new Set();
|
|
2847
|
+
for (const deletion of deletions) {
|
|
2848
|
+
let highestSimilarity = -1;
|
|
2849
|
+
let best;
|
|
2850
|
+
for (const insertion of insertions) {
|
|
2851
|
+
const similarity = deletion.computeSimilarity(insertion);
|
|
2852
|
+
if (similarity > highestSimilarity) {
|
|
2853
|
+
highestSimilarity = similarity;
|
|
2854
|
+
best = insertion;
|
|
2855
|
+
}
|
|
2856
|
+
}
|
|
2857
|
+
if (highestSimilarity > 0.90 && best) {
|
|
2858
|
+
insertions.delete(best);
|
|
2859
|
+
moves.push(new linesDiffComputer_1.SimpleLineRangeMapping(deletion.range, best.range));
|
|
2860
|
+
excludedChanges.add(deletion.source);
|
|
2861
|
+
excludedChanges.add(best.source);
|
|
2862
|
+
}
|
|
2863
|
+
if (!timeout.isValid()) {
|
|
2864
|
+
return [];
|
|
2865
|
+
}
|
|
2866
|
+
}
|
|
2867
|
+
const original3LineHashes = new collections_1.SetMap();
|
|
2868
|
+
for (const change of changes) {
|
|
2869
|
+
if (excludedChanges.has(change)) {
|
|
2870
|
+
continue;
|
|
2871
|
+
}
|
|
2872
|
+
for (let i = change.originalRange.startLineNumber; i < change.originalRange.endLineNumberExclusive - 2; i++) {
|
|
2873
|
+
const key = `${hashedOriginalLines[i - 1]}:${hashedOriginalLines[i + 1 - 1]}:${hashedOriginalLines[i + 2 - 1]}`;
|
|
2874
|
+
original3LineHashes.add(key, { range: new lineRange_1.LineRange(i, i + 3) });
|
|
2875
|
+
}
|
|
2876
|
+
}
|
|
2877
|
+
const possibleMappings = [];
|
|
2878
|
+
changes.sort((0, arrays_1.compareBy)(c => c.modifiedRange.startLineNumber, arrays_1.numberComparator));
|
|
2879
|
+
for (const change of changes) {
|
|
2880
|
+
if (excludedChanges.has(change)) {
|
|
2881
|
+
continue;
|
|
2882
|
+
}
|
|
2883
|
+
let lastMappings = [];
|
|
2884
|
+
for (let i = change.modifiedRange.startLineNumber; i < change.modifiedRange.endLineNumberExclusive - 2; i++) {
|
|
2885
|
+
const key = `${hashedModifiedLines[i - 1]}:${hashedModifiedLines[i + 1 - 1]}:${hashedModifiedLines[i + 2 - 1]}`;
|
|
2886
|
+
const currentModifiedRange = new lineRange_1.LineRange(i, i + 3);
|
|
2887
|
+
const nextMappings = [];
|
|
2888
|
+
original3LineHashes.forEach(key, ({ range }) => {
|
|
2889
|
+
for (const lastMapping of lastMappings) {
|
|
2890
|
+
// does this match extend some last match?
|
|
2891
|
+
if (lastMapping.originalLineRange.endLineNumberExclusive + 1 === range.endLineNumberExclusive &&
|
|
2892
|
+
lastMapping.modifiedLineRange.endLineNumberExclusive + 1 === currentModifiedRange.endLineNumberExclusive) {
|
|
2893
|
+
lastMapping.originalLineRange = new lineRange_1.LineRange(lastMapping.originalLineRange.startLineNumber, range.endLineNumberExclusive);
|
|
2894
|
+
lastMapping.modifiedLineRange = new lineRange_1.LineRange(lastMapping.modifiedLineRange.startLineNumber, currentModifiedRange.endLineNumberExclusive);
|
|
2895
|
+
nextMappings.push(lastMapping);
|
|
2896
|
+
return;
|
|
2897
|
+
}
|
|
2898
|
+
}
|
|
2899
|
+
const mapping = {
|
|
2900
|
+
modifiedLineRange: currentModifiedRange,
|
|
2901
|
+
originalLineRange: range,
|
|
2902
|
+
};
|
|
2903
|
+
possibleMappings.push(mapping);
|
|
2904
|
+
nextMappings.push(mapping);
|
|
2905
|
+
});
|
|
2906
|
+
lastMappings = nextMappings;
|
|
2907
|
+
}
|
|
2908
|
+
if (!timeout.isValid()) {
|
|
2909
|
+
return [];
|
|
2910
|
+
}
|
|
2911
|
+
}
|
|
2912
|
+
possibleMappings.sort((0, arrays_1.reverseOrder)((0, arrays_1.compareBy)(m => m.modifiedLineRange.length, arrays_1.numberComparator)));
|
|
2913
|
+
const modifiedSet = new LineRangeSet();
|
|
2914
|
+
const originalSet = new LineRangeSet();
|
|
2915
|
+
for (const mapping of possibleMappings) {
|
|
2916
|
+
const diffOrigToMod = mapping.modifiedLineRange.startLineNumber - mapping.originalLineRange.startLineNumber;
|
|
2917
|
+
const modifiedSections = modifiedSet.subtractFrom(mapping.modifiedLineRange);
|
|
2918
|
+
const originalTranslatedSections = originalSet.subtractFrom(mapping.originalLineRange).map(r => r.delta(diffOrigToMod));
|
|
2919
|
+
const modifiedIntersectedSections = intersectRanges(modifiedSections, originalTranslatedSections);
|
|
2920
|
+
for (const s of modifiedIntersectedSections) {
|
|
2921
|
+
if (s.length < 3) {
|
|
2922
|
+
continue;
|
|
2923
|
+
}
|
|
2924
|
+
const modifiedLineRange = s;
|
|
2925
|
+
const originalLineRange = s.delta(-diffOrigToMod);
|
|
2926
|
+
moves.push(new linesDiffComputer_1.SimpleLineRangeMapping(originalLineRange, modifiedLineRange));
|
|
2927
|
+
modifiedSet.addRange(modifiedLineRange);
|
|
2928
|
+
originalSet.addRange(originalLineRange);
|
|
2929
|
+
}
|
|
2930
|
+
}
|
|
2931
|
+
// join moves
|
|
2932
|
+
moves.sort((0, arrays_1.compareBy)(m => m.original.startLineNumber, arrays_1.numberComparator));
|
|
2933
|
+
if (moves.length === 0) {
|
|
2934
|
+
return [];
|
|
2935
|
+
}
|
|
2936
|
+
let joinedMoves = [moves[0]];
|
|
2937
|
+
for (let i = 1; i < moves.length; i++) {
|
|
2938
|
+
const last = joinedMoves[joinedMoves.length - 1];
|
|
2939
|
+
const current = moves[i];
|
|
2940
|
+
const originalDist = current.original.startLineNumber - last.original.endLineNumberExclusive;
|
|
2941
|
+
const modifiedDist = current.modified.startLineNumber - last.modified.endLineNumberExclusive;
|
|
2942
|
+
const currentMoveAfterLast = originalDist >= 0 && modifiedDist >= 0;
|
|
2943
|
+
if (currentMoveAfterLast && originalDist + modifiedDist <= 2) {
|
|
2944
|
+
joinedMoves[joinedMoves.length - 1] = last.join(current);
|
|
2945
|
+
continue;
|
|
2946
|
+
}
|
|
2947
|
+
const originalText = current.original.toOffsetRange().slice(originalLines).map(l => l.trim()).join('\n');
|
|
2948
|
+
if (originalText.length <= 10) {
|
|
2949
|
+
// Ignore small moves
|
|
2950
|
+
continue;
|
|
2951
|
+
}
|
|
2952
|
+
joinedMoves.push(current);
|
|
2953
|
+
}
|
|
2954
|
+
// Ignore non moves
|
|
2955
|
+
const originalChanges = MonotonousFinder.createOfSorted(changes, c => c.originalRange.endLineNumberExclusive, arrays_1.numberComparator);
|
|
2956
|
+
joinedMoves = joinedMoves.filter(m => {
|
|
2957
|
+
const diffBeforeOriginalMove = originalChanges.findLastItemBeforeOrEqual(m.original.startLineNumber)
|
|
2958
|
+
|| new linesDiffComputer_1.LineRangeMapping(new lineRange_1.LineRange(1, 1), new lineRange_1.LineRange(1, 1), []);
|
|
2959
|
+
const modifiedDistToPrevDiff = m.modified.startLineNumber - diffBeforeOriginalMove.modifiedRange.endLineNumberExclusive;
|
|
2960
|
+
const originalDistToPrevDiff = m.original.startLineNumber - diffBeforeOriginalMove.originalRange.endLineNumberExclusive;
|
|
2961
|
+
const differentDistances = modifiedDistToPrevDiff !== originalDistToPrevDiff;
|
|
2962
|
+
return differentDistances;
|
|
2963
|
+
});
|
|
2964
|
+
const fullMoves = joinedMoves.map(m => {
|
|
2965
|
+
const moveChanges = this.refineDiff(originalLines, modifiedLines, new diffAlgorithm_1.SequenceDiff(m.original.toOffsetRange(), m.modified.toOffsetRange()), timeout, considerWhitespaceChanges);
|
|
2966
|
+
const mappings = lineRangeMappingFromRangeMappings(moveChanges.mappings, originalLines, modifiedLines, true);
|
|
2967
|
+
return new linesDiffComputer_1.MovedText(m, mappings);
|
|
2968
|
+
});
|
|
2969
|
+
return fullMoves;
|
|
2970
|
+
}
|
|
2971
|
+
refineDiff(originalLines, modifiedLines, diff, timeout, considerWhitespaceChanges) {
|
|
2972
|
+
const slice1 = new LinesSliceCharSequence(originalLines, diff.seq1Range, considerWhitespaceChanges);
|
|
2973
|
+
const slice2 = new LinesSliceCharSequence(modifiedLines, diff.seq2Range, considerWhitespaceChanges);
|
|
2974
|
+
const diffResult = slice1.length + slice2.length < 500
|
|
2975
|
+
? this.dynamicProgrammingDiffing.compute(slice1, slice2, timeout)
|
|
2976
|
+
: this.myersDiffingAlgorithm.compute(slice1, slice2, timeout);
|
|
2977
|
+
let diffs = diffResult.diffs;
|
|
2978
|
+
diffs = (0, joinSequenceDiffs_1.optimizeSequenceDiffs)(slice1, slice2, diffs);
|
|
2979
|
+
diffs = coverFullWords(slice1, slice2, diffs);
|
|
2980
|
+
diffs = (0, joinSequenceDiffs_1.smoothenSequenceDiffs)(slice1, slice2, diffs);
|
|
2981
|
+
diffs = (0, joinSequenceDiffs_1.removeRandomMatches)(slice1, slice2, diffs);
|
|
2982
|
+
const result = diffs.map((d) => new linesDiffComputer_1.RangeMapping(slice1.translateRange(d.seq1Range), slice2.translateRange(d.seq2Range)));
|
|
2983
|
+
// Assert: result applied on original should be the same as diff applied to original
|
|
2984
|
+
return {
|
|
2985
|
+
mappings: result,
|
|
2986
|
+
hitTimeout: diffResult.hitTimeout,
|
|
2987
|
+
};
|
|
2988
|
+
}
|
|
2989
|
+
}
|
|
2990
|
+
exports.AdvancedLinesDiffComputer = AdvancedLinesDiffComputer;
|
|
2991
|
+
class MonotonousFinder {
|
|
2992
|
+
static create(items, itemToDomain, domainComparator) {
|
|
2993
|
+
items.sort((a, b) => domainComparator(itemToDomain(a), itemToDomain(b)));
|
|
2994
|
+
return new MonotonousFinder(items, itemToDomain, domainComparator);
|
|
2995
|
+
}
|
|
2996
|
+
static createOfSorted(items, itemToDomain, domainComparator) {
|
|
2997
|
+
return new MonotonousFinder(items, itemToDomain, domainComparator);
|
|
2998
|
+
}
|
|
2999
|
+
constructor(_items, _itemToDomain, _domainComparator) {
|
|
3000
|
+
this._items = _items;
|
|
3001
|
+
this._itemToDomain = _itemToDomain;
|
|
3002
|
+
this._domainComparator = _domainComparator;
|
|
3003
|
+
this._currentIdx = 0; // All values with index lower than this are smaller than or equal to _lastValue and vice versa.
|
|
3004
|
+
this._lastValue = undefined; // Represents a smallest value.
|
|
3005
|
+
this._hasLastValue = false;
|
|
3006
|
+
}
|
|
3007
|
+
/**
|
|
3008
|
+
* Assumes the values are monotonously increasing.
|
|
3009
|
+
*/
|
|
3010
|
+
findLastItemBeforeOrEqual(value) {
|
|
3011
|
+
if (this._hasLastValue && arrays_1.CompareResult.isLessThan(this._domainComparator(value, this._lastValue))) {
|
|
3012
|
+
// Values must be monotonously increasing
|
|
3013
|
+
throw new errors_1.BugIndicatingError();
|
|
3014
|
+
}
|
|
3015
|
+
this._lastValue = value;
|
|
3016
|
+
this._hasLastValue = true;
|
|
3017
|
+
while (this._currentIdx < this._items.length
|
|
3018
|
+
&& arrays_1.CompareResult.isLessThanOrEqual(this._domainComparator(this._itemToDomain(this._items[this._currentIdx]), value))) {
|
|
3019
|
+
this._currentIdx++;
|
|
3020
|
+
}
|
|
3021
|
+
return this._currentIdx === 0 ? undefined : this._items[this._currentIdx - 1];
|
|
3022
|
+
}
|
|
3023
|
+
}
|
|
3024
|
+
function intersectRanges(ranges1, ranges2) {
|
|
3025
|
+
const result = [];
|
|
3026
|
+
let i1 = 0;
|
|
3027
|
+
let i2 = 0;
|
|
3028
|
+
while (i1 < ranges1.length && i2 < ranges2.length) {
|
|
3029
|
+
const r1 = ranges1[i1];
|
|
3030
|
+
const r2 = ranges2[i2];
|
|
3031
|
+
const i = r1.intersect(r2);
|
|
3032
|
+
if (i && !i.isEmpty) {
|
|
3033
|
+
result.push(i);
|
|
3034
|
+
}
|
|
3035
|
+
if (r1.endLineNumberExclusive < r2.endLineNumberExclusive) {
|
|
3036
|
+
i1++;
|
|
3037
|
+
}
|
|
3038
|
+
else {
|
|
3039
|
+
i2++;
|
|
3040
|
+
}
|
|
3041
|
+
}
|
|
3042
|
+
return result;
|
|
3043
|
+
}
|
|
3044
|
+
// TODO make this fast
|
|
3045
|
+
class LineRangeSet {
|
|
3046
|
+
constructor() {
|
|
3047
|
+
this._normalizedRanges = [];
|
|
3048
|
+
}
|
|
3049
|
+
addRange(range) {
|
|
3050
|
+
// Idea: Find joinRange such that:
|
|
3051
|
+
// replaceRange = _normalizedRanges.replaceRange(joinRange, range.joinAll(joinRange.map(idx => this._normalizedRanges[idx])))
|
|
3052
|
+
// idx of first element that touches range or that is after range
|
|
3053
|
+
const joinRangeStartIdx = mapMinusOne(this._normalizedRanges.findIndex(r => r.endLineNumberExclusive >= range.startLineNumber), this._normalizedRanges.length);
|
|
3054
|
+
// idx of element after { last element that touches range or that is before range }
|
|
3055
|
+
const joinRangeEndIdxExclusive = (0, arrays_1.findLastIndex)(this._normalizedRanges, r => r.startLineNumber <= range.endLineNumberExclusive) + 1;
|
|
3056
|
+
if (joinRangeStartIdx === joinRangeEndIdxExclusive) {
|
|
3057
|
+
// If there is no element that touches range, then joinRangeStartIdx === joinRangeEndIdxExclusive and that value is the index of the element after range
|
|
3058
|
+
this._normalizedRanges.splice(joinRangeStartIdx, 0, range);
|
|
3059
|
+
}
|
|
3060
|
+
else if (joinRangeStartIdx === joinRangeEndIdxExclusive - 1) {
|
|
3061
|
+
// Else, there is an element that touches range and in this case it is both the first and last element. Thus we can replace it
|
|
3062
|
+
const joinRange = this._normalizedRanges[joinRangeStartIdx];
|
|
3063
|
+
this._normalizedRanges[joinRangeStartIdx] = joinRange.join(range);
|
|
3064
|
+
}
|
|
3065
|
+
else {
|
|
3066
|
+
// First and last element are different - we need to replace the entire range
|
|
3067
|
+
const joinRange = this._normalizedRanges[joinRangeStartIdx].join(this._normalizedRanges[joinRangeEndIdxExclusive - 1]).join(range);
|
|
3068
|
+
this._normalizedRanges.splice(joinRangeStartIdx, joinRangeEndIdxExclusive - joinRangeStartIdx, joinRange);
|
|
3069
|
+
}
|
|
3070
|
+
}
|
|
3071
|
+
intersects(range) {
|
|
3072
|
+
for (const r of this._normalizedRanges) {
|
|
3073
|
+
if (r.intersectsStrict(range)) {
|
|
3074
|
+
return true;
|
|
3075
|
+
}
|
|
3076
|
+
}
|
|
3077
|
+
return false;
|
|
3078
|
+
}
|
|
3079
|
+
/**
|
|
3080
|
+
* Subtracts all ranges in this set from `range` and returns the result.
|
|
3081
|
+
*/
|
|
3082
|
+
subtractFrom(range) {
|
|
3083
|
+
// idx of first element that touches range or that is after range
|
|
3084
|
+
const joinRangeStartIdx = mapMinusOne(this._normalizedRanges.findIndex(r => r.endLineNumberExclusive >= range.startLineNumber), this._normalizedRanges.length);
|
|
3085
|
+
// idx of element after { last element that touches range or that is before range }
|
|
3086
|
+
const joinRangeEndIdxExclusive = (0, arrays_1.findLastIndex)(this._normalizedRanges, r => r.startLineNumber <= range.endLineNumberExclusive) + 1;
|
|
3087
|
+
if (joinRangeStartIdx === joinRangeEndIdxExclusive) {
|
|
3088
|
+
return [range];
|
|
3089
|
+
}
|
|
3090
|
+
const result = [];
|
|
3091
|
+
let startLineNumber = range.startLineNumber;
|
|
3092
|
+
for (let i = joinRangeStartIdx; i < joinRangeEndIdxExclusive; i++) {
|
|
3093
|
+
const r = this._normalizedRanges[i];
|
|
3094
|
+
if (r.startLineNumber > startLineNumber) {
|
|
3095
|
+
result.push(new lineRange_1.LineRange(startLineNumber, r.startLineNumber));
|
|
3096
|
+
}
|
|
3097
|
+
startLineNumber = r.endLineNumberExclusive;
|
|
3098
|
+
}
|
|
3099
|
+
if (startLineNumber < range.endLineNumberExclusive) {
|
|
3100
|
+
result.push(new lineRange_1.LineRange(startLineNumber, range.endLineNumberExclusive));
|
|
3101
|
+
}
|
|
3102
|
+
return result;
|
|
3103
|
+
}
|
|
3104
|
+
}
|
|
3105
|
+
function mapMinusOne(idx, mapTo) {
|
|
3106
|
+
return idx === -1 ? mapTo : idx;
|
|
3107
|
+
}
|
|
3108
|
+
function coverFullWords(sequence1, sequence2, sequenceDiffs) {
|
|
3109
|
+
const additional = [];
|
|
3110
|
+
let lastModifiedWord = undefined;
|
|
3111
|
+
function maybePushWordToAdditional() {
|
|
3112
|
+
if (!lastModifiedWord) {
|
|
3113
|
+
return;
|
|
3114
|
+
}
|
|
3115
|
+
const originalLength1 = lastModifiedWord.s1Range.length - lastModifiedWord.deleted;
|
|
3116
|
+
const originalLength2 = lastModifiedWord.s2Range.length - lastModifiedWord.added;
|
|
3117
|
+
if (originalLength1 !== originalLength2) {
|
|
3118
|
+
// TODO figure out why this happens
|
|
3119
|
+
}
|
|
3120
|
+
if (Math.max(lastModifiedWord.deleted, lastModifiedWord.added) + (lastModifiedWord.count - 1) > originalLength1) {
|
|
3121
|
+
additional.push(new diffAlgorithm_1.SequenceDiff(lastModifiedWord.s1Range, lastModifiedWord.s2Range));
|
|
3122
|
+
}
|
|
3123
|
+
lastModifiedWord = undefined;
|
|
3124
|
+
}
|
|
3125
|
+
for (const s of sequenceDiffs) {
|
|
3126
|
+
function processWord(s1Range, s2Range) {
|
|
3127
|
+
if (!lastModifiedWord || !lastModifiedWord.s1Range.containsRange(s1Range) || !lastModifiedWord.s2Range.containsRange(s2Range)) {
|
|
3128
|
+
if (lastModifiedWord && !(lastModifiedWord.s1Range.endExclusive < s1Range.start && lastModifiedWord.s2Range.endExclusive < s2Range.start)) {
|
|
3129
|
+
const s1Added = offsetRange_1.OffsetRange.tryCreate(lastModifiedWord.s1Range.endExclusive, s1Range.start);
|
|
3130
|
+
const s2Added = offsetRange_1.OffsetRange.tryCreate(lastModifiedWord.s2Range.endExclusive, s2Range.start);
|
|
3131
|
+
lastModifiedWord.deleted += s1Added?.length ?? 0;
|
|
3132
|
+
lastModifiedWord.added += s2Added?.length ?? 0;
|
|
3133
|
+
lastModifiedWord.s1Range = lastModifiedWord.s1Range.join(s1Range);
|
|
3134
|
+
lastModifiedWord.s2Range = lastModifiedWord.s2Range.join(s2Range);
|
|
3135
|
+
}
|
|
3136
|
+
else {
|
|
3137
|
+
maybePushWordToAdditional();
|
|
3138
|
+
lastModifiedWord = { added: 0, deleted: 0, count: 0, s1Range: s1Range, s2Range: s2Range };
|
|
3139
|
+
}
|
|
3140
|
+
}
|
|
3141
|
+
const changedS1 = s1Range.intersect(s.seq1Range);
|
|
3142
|
+
const changedS2 = s2Range.intersect(s.seq2Range);
|
|
3143
|
+
lastModifiedWord.count++;
|
|
3144
|
+
lastModifiedWord.deleted += changedS1?.length ?? 0;
|
|
3145
|
+
lastModifiedWord.added += changedS2?.length ?? 0;
|
|
3146
|
+
}
|
|
3147
|
+
const w1Before = sequence1.findWordContaining(s.seq1Range.start - 1);
|
|
3148
|
+
const w2Before = sequence2.findWordContaining(s.seq2Range.start - 1);
|
|
3149
|
+
const w1After = sequence1.findWordContaining(s.seq1Range.endExclusive);
|
|
3150
|
+
const w2After = sequence2.findWordContaining(s.seq2Range.endExclusive);
|
|
3151
|
+
if (w1Before && w1After && w2Before && w2After && w1Before.equals(w1After) && w2Before.equals(w2After)) {
|
|
3152
|
+
processWord(w1Before, w2Before);
|
|
3153
|
+
}
|
|
3154
|
+
else {
|
|
3155
|
+
if (w1Before && w2Before) {
|
|
3156
|
+
processWord(w1Before, w2Before);
|
|
3157
|
+
}
|
|
3158
|
+
if (w1After && w2After) {
|
|
3159
|
+
processWord(w1After, w2After);
|
|
3160
|
+
}
|
|
3161
|
+
}
|
|
3162
|
+
}
|
|
3163
|
+
maybePushWordToAdditional();
|
|
3164
|
+
const merged = mergeSequenceDiffs(sequenceDiffs, additional);
|
|
3165
|
+
return merged;
|
|
3166
|
+
}
|
|
3167
|
+
function mergeSequenceDiffs(sequenceDiffs1, sequenceDiffs2) {
|
|
3168
|
+
const result = [];
|
|
3169
|
+
while (sequenceDiffs1.length > 0 || sequenceDiffs2.length > 0) {
|
|
3170
|
+
const sd1 = sequenceDiffs1[0];
|
|
3171
|
+
const sd2 = sequenceDiffs2[0];
|
|
3172
|
+
let next;
|
|
3173
|
+
if (sd1 && (!sd2 || sd1.seq1Range.start < sd2.seq1Range.start)) {
|
|
3174
|
+
next = sequenceDiffs1.shift();
|
|
3175
|
+
}
|
|
3176
|
+
else {
|
|
3177
|
+
next = sequenceDiffs2.shift();
|
|
3178
|
+
}
|
|
3179
|
+
if (result.length > 0 && result[result.length - 1].seq1Range.endExclusive >= next.seq1Range.start) {
|
|
3180
|
+
result[result.length - 1] = result[result.length - 1].join(next);
|
|
3181
|
+
}
|
|
3182
|
+
else {
|
|
3183
|
+
result.push(next);
|
|
3184
|
+
}
|
|
3185
|
+
}
|
|
3186
|
+
return result;
|
|
3187
|
+
}
|
|
3188
|
+
function lineRangeMappingFromRangeMappings(alignments, originalLines, modifiedLines, dontAssertStartLine = false) {
|
|
3189
|
+
const changes = [];
|
|
3190
|
+
for (const g of group(alignments.map(a => getLineRangeMapping(a, originalLines, modifiedLines)), (a1, a2) => a1.originalRange.overlapOrTouch(a2.originalRange)
|
|
3191
|
+
|| a1.modifiedRange.overlapOrTouch(a2.modifiedRange))) {
|
|
3192
|
+
const first = g[0];
|
|
3193
|
+
const last = g[g.length - 1];
|
|
3194
|
+
changes.push(new linesDiffComputer_1.LineRangeMapping(first.originalRange.join(last.originalRange), first.modifiedRange.join(last.modifiedRange), g.map(a => a.innerChanges[0])));
|
|
3195
|
+
}
|
|
3196
|
+
(0, assert_1.assertFn)(() => {
|
|
3197
|
+
if (!dontAssertStartLine) {
|
|
3198
|
+
if (changes.length > 0 && changes[0].originalRange.startLineNumber !== changes[0].modifiedRange.startLineNumber) {
|
|
3199
|
+
return false;
|
|
3200
|
+
}
|
|
3201
|
+
}
|
|
3202
|
+
return (0, assert_1.checkAdjacentItems)(changes, (m1, m2) => m2.originalRange.startLineNumber - m1.originalRange.endLineNumberExclusive === m2.modifiedRange.startLineNumber - m1.modifiedRange.endLineNumberExclusive &&
|
|
3203
|
+
// There has to be an unchanged line in between (otherwise both diffs should have been joined)
|
|
3204
|
+
m1.originalRange.endLineNumberExclusive < m2.originalRange.startLineNumber &&
|
|
3205
|
+
m1.modifiedRange.endLineNumberExclusive < m2.modifiedRange.startLineNumber);
|
|
3206
|
+
});
|
|
3207
|
+
return changes;
|
|
3208
|
+
}
|
|
3209
|
+
exports.lineRangeMappingFromRangeMappings = lineRangeMappingFromRangeMappings;
|
|
3210
|
+
function getLineRangeMapping(rangeMapping, originalLines, modifiedLines) {
|
|
3211
|
+
let lineStartDelta = 0;
|
|
3212
|
+
let lineEndDelta = 0;
|
|
3213
|
+
// rangeMapping describes the edit that replaces `rangeMapping.originalRange` with `newText := getText(modifiedLines, rangeMapping.modifiedRange)`.
|
|
3214
|
+
// original: ]xxx \n <- this line is not modified
|
|
3215
|
+
// modified: ]xx \n
|
|
3216
|
+
if (rangeMapping.modifiedRange.endColumn === 1 && rangeMapping.originalRange.endColumn === 1
|
|
3217
|
+
&& rangeMapping.originalRange.startLineNumber + lineStartDelta <= rangeMapping.originalRange.endLineNumber
|
|
3218
|
+
&& rangeMapping.modifiedRange.startLineNumber + lineStartDelta <= rangeMapping.modifiedRange.endLineNumber) {
|
|
3219
|
+
// We can only do this if the range is not empty yet
|
|
3220
|
+
lineEndDelta = -1;
|
|
3221
|
+
}
|
|
3222
|
+
// original: xxx[ \n <- this line is not modified
|
|
3223
|
+
// modified: xxx[ \n
|
|
3224
|
+
if (rangeMapping.modifiedRange.startColumn - 1 >= modifiedLines[rangeMapping.modifiedRange.startLineNumber - 1].length
|
|
3225
|
+
&& rangeMapping.originalRange.startColumn - 1 >= originalLines[rangeMapping.originalRange.startLineNumber - 1].length
|
|
3226
|
+
&& rangeMapping.originalRange.startLineNumber <= rangeMapping.originalRange.endLineNumber + lineEndDelta
|
|
3227
|
+
&& rangeMapping.modifiedRange.startLineNumber <= rangeMapping.modifiedRange.endLineNumber + lineEndDelta) {
|
|
3228
|
+
// We can only do this if the range is not empty yet
|
|
3229
|
+
lineStartDelta = 1;
|
|
3230
|
+
}
|
|
3231
|
+
const originalLineRange = new lineRange_1.LineRange(rangeMapping.originalRange.startLineNumber + lineStartDelta, rangeMapping.originalRange.endLineNumber + 1 + lineEndDelta);
|
|
3232
|
+
const modifiedLineRange = new lineRange_1.LineRange(rangeMapping.modifiedRange.startLineNumber + lineStartDelta, rangeMapping.modifiedRange.endLineNumber + 1 + lineEndDelta);
|
|
3233
|
+
return new linesDiffComputer_1.LineRangeMapping(originalLineRange, modifiedLineRange, [rangeMapping]);
|
|
3234
|
+
}
|
|
3235
|
+
exports.getLineRangeMapping = getLineRangeMapping;
|
|
3236
|
+
function* group(items, shouldBeGrouped) {
|
|
3237
|
+
let currentGroup;
|
|
3238
|
+
let last;
|
|
3239
|
+
for (const item of items) {
|
|
3240
|
+
if (last !== undefined && shouldBeGrouped(last, item)) {
|
|
3241
|
+
currentGroup.push(item);
|
|
3242
|
+
}
|
|
3243
|
+
else {
|
|
3244
|
+
if (currentGroup) {
|
|
3245
|
+
yield currentGroup;
|
|
3246
|
+
}
|
|
3247
|
+
currentGroup = [item];
|
|
3248
|
+
}
|
|
3249
|
+
last = item;
|
|
3250
|
+
}
|
|
3251
|
+
if (currentGroup) {
|
|
3252
|
+
yield currentGroup;
|
|
3253
|
+
}
|
|
3254
|
+
}
|
|
3255
|
+
class LineSequence {
|
|
3256
|
+
constructor(trimmedHash, lines) {
|
|
3257
|
+
this.trimmedHash = trimmedHash;
|
|
3258
|
+
this.lines = lines;
|
|
3259
|
+
}
|
|
3260
|
+
getElement(offset) {
|
|
3261
|
+
return this.trimmedHash[offset];
|
|
3262
|
+
}
|
|
3263
|
+
get length() {
|
|
3264
|
+
return this.trimmedHash.length;
|
|
3265
|
+
}
|
|
3266
|
+
getBoundaryScore(length) {
|
|
3267
|
+
const indentationBefore = length === 0 ? 0 : getIndentation(this.lines[length - 1]);
|
|
3268
|
+
const indentationAfter = length === this.lines.length ? 0 : getIndentation(this.lines[length]);
|
|
3269
|
+
return 1000 - (indentationBefore + indentationAfter);
|
|
3270
|
+
}
|
|
3271
|
+
getText(range) {
|
|
3272
|
+
return this.lines.slice(range.start, range.endExclusive).join('\n');
|
|
3273
|
+
}
|
|
3274
|
+
isStronglyEqual(offset1, offset2) {
|
|
3275
|
+
return this.lines[offset1] === this.lines[offset2];
|
|
3276
|
+
}
|
|
3277
|
+
}
|
|
3278
|
+
exports.LineSequence = LineSequence;
|
|
3279
|
+
function getIndentation(str) {
|
|
3280
|
+
let i = 0;
|
|
3281
|
+
while (i < str.length && (str.charCodeAt(i) === 32 /* CharCode.Space */ || str.charCodeAt(i) === 9 /* CharCode.Tab */)) {
|
|
3282
|
+
i++;
|
|
3283
|
+
}
|
|
3284
|
+
return i;
|
|
3285
|
+
}
|
|
3286
|
+
class LinesSliceCharSequence {
|
|
3287
|
+
constructor(lines, lineRange, considerWhitespaceChanges) {
|
|
3288
|
+
// This slice has to have lineRange.length many \n! (otherwise diffing against an empty slice will be problematic)
|
|
3289
|
+
// (Unless it covers the entire document, in that case the other slice also has to cover the entire document ands it's okay)
|
|
3290
|
+
this.lines = lines;
|
|
3291
|
+
this.considerWhitespaceChanges = considerWhitespaceChanges;
|
|
3292
|
+
this.elements = [];
|
|
3293
|
+
this.firstCharOffsetByLineMinusOne = [];
|
|
3294
|
+
// To account for trimming
|
|
3295
|
+
this.additionalOffsetByLine = [];
|
|
3296
|
+
// If the slice covers the end, but does not start at the beginning, we include just the \n of the previous line.
|
|
3297
|
+
let trimFirstLineFully = false;
|
|
3298
|
+
if (lineRange.start > 0 && lineRange.endExclusive >= lines.length) {
|
|
3299
|
+
lineRange = new offsetRange_1.OffsetRange(lineRange.start - 1, lineRange.endExclusive);
|
|
3300
|
+
trimFirstLineFully = true;
|
|
3301
|
+
}
|
|
3302
|
+
this.lineRange = lineRange;
|
|
3303
|
+
for (let i = this.lineRange.start; i < this.lineRange.endExclusive; i++) {
|
|
3304
|
+
let line = lines[i];
|
|
3305
|
+
let offset = 0;
|
|
3306
|
+
if (trimFirstLineFully) {
|
|
3307
|
+
offset = line.length;
|
|
3308
|
+
line = '';
|
|
3309
|
+
trimFirstLineFully = false;
|
|
3310
|
+
}
|
|
3311
|
+
else if (!considerWhitespaceChanges) {
|
|
3312
|
+
const trimmedStartLine = line.trimStart();
|
|
3313
|
+
offset = line.length - trimmedStartLine.length;
|
|
3314
|
+
line = trimmedStartLine.trimEnd();
|
|
3315
|
+
}
|
|
3316
|
+
this.additionalOffsetByLine.push(offset);
|
|
3317
|
+
for (let i = 0; i < line.length; i++) {
|
|
3318
|
+
this.elements.push(line.charCodeAt(i));
|
|
3319
|
+
}
|
|
3320
|
+
// Don't add an \n that does not exist in the document.
|
|
3321
|
+
if (i < lines.length - 1) {
|
|
3322
|
+
this.elements.push('\n'.charCodeAt(0));
|
|
3323
|
+
this.firstCharOffsetByLineMinusOne[i - this.lineRange.start] = this.elements.length;
|
|
3324
|
+
}
|
|
3325
|
+
}
|
|
3326
|
+
// To account for the last line
|
|
3327
|
+
this.additionalOffsetByLine.push(0);
|
|
3328
|
+
}
|
|
3329
|
+
toString() {
|
|
3330
|
+
return `Slice: "${this.text}"`;
|
|
3331
|
+
}
|
|
3332
|
+
get text() {
|
|
3333
|
+
return this.getText(new offsetRange_1.OffsetRange(0, this.length));
|
|
3334
|
+
}
|
|
3335
|
+
getText(range) {
|
|
3336
|
+
return this.elements.slice(range.start, range.endExclusive).map(e => String.fromCharCode(e)).join('');
|
|
3337
|
+
}
|
|
3338
|
+
getElement(offset) {
|
|
3339
|
+
return this.elements[offset];
|
|
3340
|
+
}
|
|
3341
|
+
get length() {
|
|
3342
|
+
return this.elements.length;
|
|
3343
|
+
}
|
|
3344
|
+
getBoundaryScore(length) {
|
|
3345
|
+
// a b c , d e f
|
|
3346
|
+
// 11 0 0 12 15 6 13 0 0 11
|
|
3347
|
+
const prevCategory = getCategory(length > 0 ? this.elements[length - 1] : -1);
|
|
3348
|
+
const nextCategory = getCategory(length < this.elements.length ? this.elements[length] : -1);
|
|
3349
|
+
if (prevCategory === 6 /* CharBoundaryCategory.LineBreakCR */ && nextCategory === 7 /* CharBoundaryCategory.LineBreakLF */) {
|
|
3350
|
+
// don't break between \r and \n
|
|
3351
|
+
return 0;
|
|
3352
|
+
}
|
|
3353
|
+
let score = 0;
|
|
3354
|
+
if (prevCategory !== nextCategory) {
|
|
3355
|
+
score += 10;
|
|
3356
|
+
if (nextCategory === 1 /* CharBoundaryCategory.WordUpper */) {
|
|
3357
|
+
score += 1;
|
|
3358
|
+
}
|
|
3359
|
+
}
|
|
3360
|
+
score += getCategoryBoundaryScore(prevCategory);
|
|
3361
|
+
score += getCategoryBoundaryScore(nextCategory);
|
|
3362
|
+
return score;
|
|
3363
|
+
}
|
|
3364
|
+
translateOffset(offset) {
|
|
3365
|
+
// find smallest i, so that lineBreakOffsets[i] <= offset using binary search
|
|
3366
|
+
if (this.lineRange.isEmpty) {
|
|
3367
|
+
return new position_1.Position(this.lineRange.start + 1, 1);
|
|
3368
|
+
}
|
|
3369
|
+
let i = 0;
|
|
3370
|
+
let j = this.firstCharOffsetByLineMinusOne.length;
|
|
3371
|
+
while (i < j) {
|
|
3372
|
+
const k = Math.floor((i + j) / 2);
|
|
3373
|
+
if (this.firstCharOffsetByLineMinusOne[k] > offset) {
|
|
3374
|
+
j = k;
|
|
3375
|
+
}
|
|
3376
|
+
else {
|
|
3377
|
+
i = k + 1;
|
|
3378
|
+
}
|
|
3379
|
+
}
|
|
3380
|
+
const offsetOfFirstCharInLine = i === 0 ? 0 : this.firstCharOffsetByLineMinusOne[i - 1];
|
|
3381
|
+
return new position_1.Position(this.lineRange.start + i + 1, offset - offsetOfFirstCharInLine + 1 + this.additionalOffsetByLine[i]);
|
|
3382
|
+
}
|
|
3383
|
+
translateRange(range) {
|
|
3384
|
+
return range_1.Range.fromPositions(this.translateOffset(range.start), this.translateOffset(range.endExclusive));
|
|
3385
|
+
}
|
|
3386
|
+
/**
|
|
3387
|
+
* Finds the word that contains the character at the given offset
|
|
3388
|
+
*/
|
|
3389
|
+
findWordContaining(offset) {
|
|
3390
|
+
if (offset < 0 || offset >= this.elements.length) {
|
|
3391
|
+
return undefined;
|
|
3392
|
+
}
|
|
3393
|
+
if (!isWordChar(this.elements[offset])) {
|
|
3394
|
+
return undefined;
|
|
3395
|
+
}
|
|
3396
|
+
// find start
|
|
3397
|
+
let start = offset;
|
|
3398
|
+
while (start > 0 && isWordChar(this.elements[start - 1])) {
|
|
3399
|
+
start--;
|
|
3400
|
+
}
|
|
3401
|
+
// find end
|
|
3402
|
+
let end = offset;
|
|
3403
|
+
while (end < this.elements.length && isWordChar(this.elements[end])) {
|
|
3404
|
+
end++;
|
|
3405
|
+
}
|
|
3406
|
+
return new offsetRange_1.OffsetRange(start, end);
|
|
3407
|
+
}
|
|
3408
|
+
countLinesIn(range) {
|
|
3409
|
+
return this.translateOffset(range.endExclusive).lineNumber - this.translateOffset(range.start).lineNumber;
|
|
3410
|
+
}
|
|
3411
|
+
isStronglyEqual(offset1, offset2) {
|
|
3412
|
+
return this.elements[offset1] === this.elements[offset2];
|
|
3413
|
+
}
|
|
3414
|
+
extendToFullLines(range) {
|
|
3415
|
+
const start = findLastMonotonous(this.firstCharOffsetByLineMinusOne, x => x <= range.start) ?? 0;
|
|
3416
|
+
const end = findFirstMonotonous(this.firstCharOffsetByLineMinusOne, x => range.endExclusive <= x) ?? this.elements.length;
|
|
3417
|
+
return new offsetRange_1.OffsetRange(start, end);
|
|
3418
|
+
}
|
|
3419
|
+
}
|
|
3420
|
+
exports.LinesSliceCharSequence = LinesSliceCharSequence;
|
|
3421
|
+
/**
|
|
3422
|
+
* `arr.map(predicate)` must be like `[true, ..., true, false, ..., false]`!
|
|
3423
|
+
*
|
|
3424
|
+
* @returns -1 if predicate is false for all items
|
|
3425
|
+
*/
|
|
3426
|
+
function findLastIdxMonotonous(arr, predicate) {
|
|
3427
|
+
let i = 0;
|
|
3428
|
+
let j = arr.length;
|
|
3429
|
+
while (i < j) {
|
|
3430
|
+
const k = Math.floor((i + j) / 2);
|
|
3431
|
+
if (predicate(arr[k])) {
|
|
3432
|
+
i = k + 1;
|
|
3433
|
+
}
|
|
3434
|
+
else {
|
|
3435
|
+
j = k;
|
|
3436
|
+
}
|
|
3437
|
+
}
|
|
3438
|
+
return i - 1;
|
|
3439
|
+
}
|
|
3440
|
+
function findLastMonotonous(arr, predicate) {
|
|
3441
|
+
const idx = findLastIdxMonotonous(arr, predicate);
|
|
3442
|
+
return idx === -1 ? undefined : arr[idx];
|
|
3443
|
+
}
|
|
3444
|
+
exports.findLastMonotonous = findLastMonotonous;
|
|
3445
|
+
/**
|
|
3446
|
+
* `arr.map(predicate)` must be like `[false, ..., false, true, ..., true]`!
|
|
3447
|
+
*
|
|
3448
|
+
* @returns arr.length if predicate is false for all items
|
|
3449
|
+
*/
|
|
3450
|
+
function findFirstIdxMonotonous(arr, predicate) {
|
|
3451
|
+
let i = 0;
|
|
3452
|
+
let j = arr.length;
|
|
3453
|
+
while (i < j) {
|
|
3454
|
+
const k = Math.floor((i + j) / 2);
|
|
3455
|
+
if (predicate(arr[k])) {
|
|
3456
|
+
j = k;
|
|
3457
|
+
}
|
|
3458
|
+
else {
|
|
3459
|
+
i = k + 1;
|
|
3460
|
+
}
|
|
3461
|
+
}
|
|
3462
|
+
return i;
|
|
3463
|
+
}
|
|
3464
|
+
function findFirstMonotonous(arr, predicate) {
|
|
3465
|
+
const idx = findFirstIdxMonotonous(arr, predicate);
|
|
3466
|
+
return idx === arr.length ? undefined : arr[idx];
|
|
3467
|
+
}
|
|
3468
|
+
exports.findFirstMonotonous = findFirstMonotonous;
|
|
3469
|
+
function isWordChar(charCode) {
|
|
3470
|
+
return charCode >= 97 /* CharCode.a */ && charCode <= 122 /* CharCode.z */
|
|
3471
|
+
|| charCode >= 65 /* CharCode.A */ && charCode <= 90 /* CharCode.Z */
|
|
3472
|
+
|| charCode >= 48 /* CharCode.Digit0 */ && charCode <= 57 /* CharCode.Digit9 */;
|
|
3473
|
+
}
|
|
3474
|
+
const score = {
|
|
3475
|
+
[0 /* CharBoundaryCategory.WordLower */]: 0,
|
|
3476
|
+
[1 /* CharBoundaryCategory.WordUpper */]: 0,
|
|
3477
|
+
[2 /* CharBoundaryCategory.WordNumber */]: 0,
|
|
3478
|
+
[3 /* CharBoundaryCategory.End */]: 10,
|
|
3479
|
+
[4 /* CharBoundaryCategory.Other */]: 2,
|
|
3480
|
+
[5 /* CharBoundaryCategory.Space */]: 3,
|
|
3481
|
+
[6 /* CharBoundaryCategory.LineBreakCR */]: 10,
|
|
3482
|
+
[7 /* CharBoundaryCategory.LineBreakLF */]: 10,
|
|
3483
|
+
};
|
|
3484
|
+
function getCategoryBoundaryScore(category) {
|
|
3485
|
+
return score[category];
|
|
3486
|
+
}
|
|
3487
|
+
function getCategory(charCode) {
|
|
3488
|
+
if (charCode === 10 /* CharCode.LineFeed */) {
|
|
3489
|
+
return 7 /* CharBoundaryCategory.LineBreakLF */;
|
|
3490
|
+
}
|
|
3491
|
+
else if (charCode === 13 /* CharCode.CarriageReturn */) {
|
|
3492
|
+
return 6 /* CharBoundaryCategory.LineBreakCR */;
|
|
3493
|
+
}
|
|
3494
|
+
else if (isSpace(charCode)) {
|
|
3495
|
+
return 5 /* CharBoundaryCategory.Space */;
|
|
3496
|
+
}
|
|
3497
|
+
else if (charCode >= 97 /* CharCode.a */ && charCode <= 122 /* CharCode.z */) {
|
|
3498
|
+
return 0 /* CharBoundaryCategory.WordLower */;
|
|
3499
|
+
}
|
|
3500
|
+
else if (charCode >= 65 /* CharCode.A */ && charCode <= 90 /* CharCode.Z */) {
|
|
3501
|
+
return 1 /* CharBoundaryCategory.WordUpper */;
|
|
3502
|
+
}
|
|
3503
|
+
else if (charCode >= 48 /* CharCode.Digit0 */ && charCode <= 57 /* CharCode.Digit9 */) {
|
|
3504
|
+
return 2 /* CharBoundaryCategory.WordNumber */;
|
|
3505
|
+
}
|
|
3506
|
+
else if (charCode === -1) {
|
|
3507
|
+
return 3 /* CharBoundaryCategory.End */;
|
|
3508
|
+
}
|
|
3509
|
+
else {
|
|
3510
|
+
return 4 /* CharBoundaryCategory.Other */;
|
|
3511
|
+
}
|
|
3512
|
+
}
|
|
3513
|
+
function isSpace(charCode) {
|
|
3514
|
+
return charCode === 32 /* CharCode.Space */ || charCode === 9 /* CharCode.Tab */;
|
|
3515
|
+
}
|
|
3516
|
+
const chrKeys = new Map();
|
|
3517
|
+
function getKey(chr) {
|
|
3518
|
+
let key = chrKeys.get(chr);
|
|
3519
|
+
if (key === undefined) {
|
|
3520
|
+
key = chrKeys.size;
|
|
3521
|
+
chrKeys.set(chr, key);
|
|
3522
|
+
}
|
|
3523
|
+
return key;
|
|
3524
|
+
}
|
|
3525
|
+
class LineRangeFragment {
|
|
3526
|
+
constructor(range, lines, source) {
|
|
3527
|
+
this.range = range;
|
|
3528
|
+
this.lines = lines;
|
|
3529
|
+
this.source = source;
|
|
3530
|
+
this.histogram = [];
|
|
3531
|
+
let counter = 0;
|
|
3532
|
+
for (let i = range.startLineNumber - 1; i < range.endLineNumberExclusive - 1; i++) {
|
|
3533
|
+
const line = lines[i];
|
|
3534
|
+
for (let j = 0; j < line.length; j++) {
|
|
3535
|
+
counter++;
|
|
3536
|
+
const chr = line[j];
|
|
3537
|
+
const key = getKey(chr);
|
|
3538
|
+
this.histogram[key] = (this.histogram[key] || 0) + 1;
|
|
3539
|
+
}
|
|
3540
|
+
counter++;
|
|
3541
|
+
const key = getKey('\n');
|
|
3542
|
+
this.histogram[key] = (this.histogram[key] || 0) + 1;
|
|
3543
|
+
}
|
|
3544
|
+
this.totalCount = counter;
|
|
3545
|
+
}
|
|
3546
|
+
computeSimilarity(other) {
|
|
3547
|
+
let sumDifferences = 0;
|
|
3548
|
+
const maxLength = Math.max(this.histogram.length, other.histogram.length);
|
|
3549
|
+
for (let i = 0; i < maxLength; i++) {
|
|
3550
|
+
sumDifferences += Math.abs((this.histogram[i] ?? 0) - (other.histogram[i] ?? 0));
|
|
3551
|
+
}
|
|
3552
|
+
return 1 - (sumDifferences / (this.totalCount + other.totalCount));
|
|
3553
|
+
}
|
|
3554
|
+
}
|
|
3555
|
+
|
|
3556
|
+
|
|
3557
|
+
/***/ }),
|
|
3558
|
+
|
|
3559
|
+
/***/ "./node_modules/vscode-diff/dist/vs/editor/common/diff/algorithms/diffAlgorithm.js":
|
|
3560
|
+
/*!*****************************************************************************************!*\
|
|
3561
|
+
!*** ./node_modules/vscode-diff/dist/vs/editor/common/diff/algorithms/diffAlgorithm.js ***!
|
|
3562
|
+
\*****************************************************************************************/
|
|
3563
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
3564
|
+
|
|
3565
|
+
|
|
3566
|
+
/*---------------------------------------------------------------------------------------------
|
|
3567
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3568
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
3569
|
+
*--------------------------------------------------------------------------------------------*/
|
|
3570
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
3571
|
+
exports.DateTimeout = exports.InfiniteTimeout = exports.SequenceDiff = exports.DiffAlgorithmResult = void 0;
|
|
3572
|
+
const errors_1 = __webpack_require__(/*! ../../../../base/common/errors */ "./node_modules/vscode-diff/dist/vs/base/common/errors.js");
|
|
3573
|
+
const offsetRange_1 = __webpack_require__(/*! ../../core/offsetRange */ "./node_modules/vscode-diff/dist/vs/editor/common/core/offsetRange.js");
|
|
3574
|
+
class DiffAlgorithmResult {
|
|
3575
|
+
static trivial(seq1, seq2) {
|
|
3576
|
+
return new DiffAlgorithmResult([new SequenceDiff(new offsetRange_1.OffsetRange(0, seq1.length), new offsetRange_1.OffsetRange(0, seq2.length))], false);
|
|
3577
|
+
}
|
|
3578
|
+
static trivialTimedOut(seq1, seq2) {
|
|
3579
|
+
return new DiffAlgorithmResult([new SequenceDiff(new offsetRange_1.OffsetRange(0, seq1.length), new offsetRange_1.OffsetRange(0, seq2.length))], true);
|
|
3580
|
+
}
|
|
3581
|
+
constructor(diffs,
|
|
3582
|
+
/**
|
|
3583
|
+
* Indicates if the time out was reached.
|
|
3584
|
+
* In that case, the diffs might be an approximation and the user should be asked to rerun the diff with more time.
|
|
3585
|
+
*/
|
|
3586
|
+
hitTimeout) {
|
|
3587
|
+
this.diffs = diffs;
|
|
3588
|
+
this.hitTimeout = hitTimeout;
|
|
3589
|
+
}
|
|
3590
|
+
}
|
|
3591
|
+
exports.DiffAlgorithmResult = DiffAlgorithmResult;
|
|
3592
|
+
class SequenceDiff {
|
|
3593
|
+
constructor(seq1Range, seq2Range) {
|
|
3594
|
+
this.seq1Range = seq1Range;
|
|
3595
|
+
this.seq2Range = seq2Range;
|
|
3596
|
+
}
|
|
3597
|
+
reverse() {
|
|
3598
|
+
return new SequenceDiff(this.seq2Range, this.seq1Range);
|
|
3599
|
+
}
|
|
3600
|
+
toString() {
|
|
3601
|
+
return `${this.seq1Range} <-> ${this.seq2Range}`;
|
|
3602
|
+
}
|
|
3603
|
+
join(other) {
|
|
3604
|
+
return new SequenceDiff(this.seq1Range.join(other.seq1Range), this.seq2Range.join(other.seq2Range));
|
|
3605
|
+
}
|
|
3606
|
+
delta(offset) {
|
|
3607
|
+
if (offset === 0) {
|
|
3608
|
+
return this;
|
|
3609
|
+
}
|
|
3610
|
+
return new SequenceDiff(this.seq1Range.delta(offset), this.seq2Range.delta(offset));
|
|
3611
|
+
}
|
|
3612
|
+
}
|
|
3613
|
+
exports.SequenceDiff = SequenceDiff;
|
|
3614
|
+
class InfiniteTimeout {
|
|
3615
|
+
isValid() {
|
|
3616
|
+
return true;
|
|
3617
|
+
}
|
|
3618
|
+
}
|
|
3619
|
+
exports.InfiniteTimeout = InfiniteTimeout;
|
|
3620
|
+
InfiniteTimeout.instance = new InfiniteTimeout();
|
|
3621
|
+
class DateTimeout {
|
|
3622
|
+
constructor(timeout) {
|
|
3623
|
+
this.timeout = timeout;
|
|
3624
|
+
this.startTime = Date.now();
|
|
3625
|
+
this.valid = true;
|
|
3626
|
+
if (timeout <= 0) {
|
|
3627
|
+
throw new errors_1.BugIndicatingError('timeout must be positive');
|
|
3628
|
+
}
|
|
3629
|
+
}
|
|
3630
|
+
// Recommendation: Set a log-point `{this.disable()}` in the body
|
|
3631
|
+
isValid() {
|
|
3632
|
+
const valid = Date.now() - this.startTime < this.timeout;
|
|
3633
|
+
if (!valid && this.valid) {
|
|
3634
|
+
this.valid = false; // timeout reached
|
|
3635
|
+
// eslint-disable-next-line no-debugger
|
|
3636
|
+
debugger; // WARNING: Most likely debugging caused the timeout. Call `this.disable()` to continue without timing out.
|
|
3637
|
+
}
|
|
3638
|
+
return this.valid;
|
|
3639
|
+
}
|
|
3640
|
+
disable() {
|
|
3641
|
+
this.timeout = Number.MAX_SAFE_INTEGER;
|
|
3642
|
+
this.isValid = () => true;
|
|
3643
|
+
this.valid = true;
|
|
3644
|
+
}
|
|
3645
|
+
}
|
|
3646
|
+
exports.DateTimeout = DateTimeout;
|
|
3647
|
+
|
|
3648
|
+
|
|
3649
|
+
/***/ }),
|
|
3650
|
+
|
|
3651
|
+
/***/ "./node_modules/vscode-diff/dist/vs/editor/common/diff/algorithms/dynamicProgrammingDiffing.js":
|
|
3652
|
+
/*!*****************************************************************************************************!*\
|
|
3653
|
+
!*** ./node_modules/vscode-diff/dist/vs/editor/common/diff/algorithms/dynamicProgrammingDiffing.js ***!
|
|
3654
|
+
\*****************************************************************************************************/
|
|
3655
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
3656
|
+
|
|
3657
|
+
|
|
3658
|
+
/*---------------------------------------------------------------------------------------------
|
|
3659
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3660
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
3661
|
+
*--------------------------------------------------------------------------------------------*/
|
|
3662
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
3663
|
+
exports.DynamicProgrammingDiffing = void 0;
|
|
3664
|
+
const offsetRange_1 = __webpack_require__(/*! ../../core/offsetRange */ "./node_modules/vscode-diff/dist/vs/editor/common/core/offsetRange.js");
|
|
3665
|
+
const diffAlgorithm_1 = __webpack_require__(/*! ./diffAlgorithm */ "./node_modules/vscode-diff/dist/vs/editor/common/diff/algorithms/diffAlgorithm.js");
|
|
3666
|
+
const utils_1 = __webpack_require__(/*! ./utils */ "./node_modules/vscode-diff/dist/vs/editor/common/diff/algorithms/utils.js");
|
|
3667
|
+
/**
|
|
3668
|
+
* A O(MN) diffing algorithm that supports a score function.
|
|
3669
|
+
* The algorithm can be improved by processing the 2d array diagonally.
|
|
3670
|
+
*/
|
|
3671
|
+
class DynamicProgrammingDiffing {
|
|
3672
|
+
compute(sequence1, sequence2, timeout = diffAlgorithm_1.InfiniteTimeout.instance, equalityScore) {
|
|
3673
|
+
if (sequence1.length === 0 || sequence2.length === 0) {
|
|
3674
|
+
return diffAlgorithm_1.DiffAlgorithmResult.trivial(sequence1, sequence2);
|
|
3675
|
+
}
|
|
3676
|
+
/**
|
|
3677
|
+
* lcsLengths.get(i, j): Length of the longest common subsequence of sequence1.substring(0, i + 1) and sequence2.substring(0, j + 1).
|
|
3678
|
+
*/
|
|
3679
|
+
const lcsLengths = new utils_1.Array2D(sequence1.length, sequence2.length);
|
|
3680
|
+
const directions = new utils_1.Array2D(sequence1.length, sequence2.length);
|
|
3681
|
+
const lengths = new utils_1.Array2D(sequence1.length, sequence2.length);
|
|
3682
|
+
// ==== Initializing lcsLengths ====
|
|
3683
|
+
for (let s1 = 0; s1 < sequence1.length; s1++) {
|
|
3684
|
+
for (let s2 = 0; s2 < sequence2.length; s2++) {
|
|
3685
|
+
if (!timeout.isValid()) {
|
|
3686
|
+
return diffAlgorithm_1.DiffAlgorithmResult.trivialTimedOut(sequence1, sequence2);
|
|
3687
|
+
}
|
|
3688
|
+
const horizontalLen = s1 === 0 ? 0 : lcsLengths.get(s1 - 1, s2);
|
|
3689
|
+
const verticalLen = s2 === 0 ? 0 : lcsLengths.get(s1, s2 - 1);
|
|
3690
|
+
let extendedSeqScore;
|
|
3691
|
+
if (sequence1.getElement(s1) === sequence2.getElement(s2)) {
|
|
3692
|
+
if (s1 === 0 || s2 === 0) {
|
|
3693
|
+
extendedSeqScore = 0;
|
|
3694
|
+
}
|
|
3695
|
+
else {
|
|
3696
|
+
extendedSeqScore = lcsLengths.get(s1 - 1, s2 - 1);
|
|
3697
|
+
}
|
|
3698
|
+
if (s1 > 0 && s2 > 0 && directions.get(s1 - 1, s2 - 1) === 3) {
|
|
3699
|
+
// Prefer consecutive diagonals
|
|
3700
|
+
extendedSeqScore += lengths.get(s1 - 1, s2 - 1);
|
|
3701
|
+
}
|
|
3702
|
+
extendedSeqScore += (equalityScore ? equalityScore(s1, s2) : 1);
|
|
3703
|
+
}
|
|
3704
|
+
else {
|
|
3705
|
+
extendedSeqScore = -1;
|
|
3706
|
+
}
|
|
3707
|
+
const newValue = Math.max(horizontalLen, verticalLen, extendedSeqScore);
|
|
3708
|
+
if (newValue === extendedSeqScore) {
|
|
3709
|
+
// Prefer diagonals
|
|
3710
|
+
const prevLen = s1 > 0 && s2 > 0 ? lengths.get(s1 - 1, s2 - 1) : 0;
|
|
3711
|
+
lengths.set(s1, s2, prevLen + 1);
|
|
3712
|
+
directions.set(s1, s2, 3);
|
|
3713
|
+
}
|
|
3714
|
+
else if (newValue === horizontalLen) {
|
|
3715
|
+
lengths.set(s1, s2, 0);
|
|
3716
|
+
directions.set(s1, s2, 1);
|
|
3717
|
+
}
|
|
3718
|
+
else if (newValue === verticalLen) {
|
|
3719
|
+
lengths.set(s1, s2, 0);
|
|
3720
|
+
directions.set(s1, s2, 2);
|
|
3721
|
+
}
|
|
3722
|
+
lcsLengths.set(s1, s2, newValue);
|
|
3723
|
+
}
|
|
3724
|
+
}
|
|
3725
|
+
// ==== Backtracking ====
|
|
3726
|
+
const result = [];
|
|
3727
|
+
let lastAligningPosS1 = sequence1.length;
|
|
3728
|
+
let lastAligningPosS2 = sequence2.length;
|
|
3729
|
+
function reportDecreasingAligningPositions(s1, s2) {
|
|
3730
|
+
if (s1 + 1 !== lastAligningPosS1 || s2 + 1 !== lastAligningPosS2) {
|
|
3731
|
+
result.push(new diffAlgorithm_1.SequenceDiff(new offsetRange_1.OffsetRange(s1 + 1, lastAligningPosS1), new offsetRange_1.OffsetRange(s2 + 1, lastAligningPosS2)));
|
|
3732
|
+
}
|
|
3733
|
+
lastAligningPosS1 = s1;
|
|
3734
|
+
lastAligningPosS2 = s2;
|
|
3735
|
+
}
|
|
3736
|
+
let s1 = sequence1.length - 1;
|
|
3737
|
+
let s2 = sequence2.length - 1;
|
|
3738
|
+
while (s1 >= 0 && s2 >= 0) {
|
|
3739
|
+
if (directions.get(s1, s2) === 3) {
|
|
3740
|
+
reportDecreasingAligningPositions(s1, s2);
|
|
3741
|
+
s1--;
|
|
3742
|
+
s2--;
|
|
3743
|
+
}
|
|
3744
|
+
else {
|
|
3745
|
+
if (directions.get(s1, s2) === 1) {
|
|
3746
|
+
s1--;
|
|
3747
|
+
}
|
|
3748
|
+
else {
|
|
3749
|
+
s2--;
|
|
3750
|
+
}
|
|
3751
|
+
}
|
|
3752
|
+
}
|
|
3753
|
+
reportDecreasingAligningPositions(-1, -1);
|
|
3754
|
+
result.reverse();
|
|
3755
|
+
return new diffAlgorithm_1.DiffAlgorithmResult(result, false);
|
|
3756
|
+
}
|
|
3757
|
+
}
|
|
3758
|
+
exports.DynamicProgrammingDiffing = DynamicProgrammingDiffing;
|
|
3759
|
+
|
|
3760
|
+
|
|
3761
|
+
/***/ }),
|
|
3762
|
+
|
|
3763
|
+
/***/ "./node_modules/vscode-diff/dist/vs/editor/common/diff/algorithms/joinSequenceDiffs.js":
|
|
3764
|
+
/*!*********************************************************************************************!*\
|
|
3765
|
+
!*** ./node_modules/vscode-diff/dist/vs/editor/common/diff/algorithms/joinSequenceDiffs.js ***!
|
|
3766
|
+
\*********************************************************************************************/
|
|
3767
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
3768
|
+
|
|
3769
|
+
|
|
3770
|
+
/*---------------------------------------------------------------------------------------------
|
|
3771
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3772
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
3773
|
+
*--------------------------------------------------------------------------------------------*/
|
|
3774
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
3775
|
+
exports.shiftSequenceDiffs = exports.joinSequenceDiffs = exports.removeRandomMatches = exports.removeRandomLineMatches = exports.smoothenSequenceDiffs = exports.optimizeSequenceDiffs = void 0;
|
|
3776
|
+
const offsetRange_1 = __webpack_require__(/*! ../../core/offsetRange */ "./node_modules/vscode-diff/dist/vs/editor/common/core/offsetRange.js");
|
|
3777
|
+
const diffAlgorithm_1 = __webpack_require__(/*! ../algorithms/diffAlgorithm */ "./node_modules/vscode-diff/dist/vs/editor/common/diff/algorithms/diffAlgorithm.js");
|
|
3778
|
+
function optimizeSequenceDiffs(sequence1, sequence2, sequenceDiffs) {
|
|
3779
|
+
let result = sequenceDiffs;
|
|
3780
|
+
result = joinSequenceDiffs(sequence1, sequence2, result);
|
|
3781
|
+
result = shiftSequenceDiffs(sequence1, sequence2, result);
|
|
3782
|
+
return result;
|
|
3783
|
+
}
|
|
3784
|
+
exports.optimizeSequenceDiffs = optimizeSequenceDiffs;
|
|
3785
|
+
function smoothenSequenceDiffs(sequence1, sequence2, sequenceDiffs) {
|
|
3786
|
+
const result = [];
|
|
3787
|
+
for (const s of sequenceDiffs) {
|
|
3788
|
+
const last = result[result.length - 1];
|
|
3789
|
+
if (!last) {
|
|
3790
|
+
result.push(s);
|
|
3791
|
+
continue;
|
|
3792
|
+
}
|
|
3793
|
+
if (s.seq1Range.start - last.seq1Range.endExclusive <= 2 || s.seq2Range.start - last.seq2Range.endExclusive <= 2) {
|
|
3794
|
+
result[result.length - 1] = new diffAlgorithm_1.SequenceDiff(last.seq1Range.join(s.seq1Range), last.seq2Range.join(s.seq2Range));
|
|
3795
|
+
}
|
|
3796
|
+
else {
|
|
3797
|
+
result.push(s);
|
|
3798
|
+
}
|
|
3799
|
+
}
|
|
3800
|
+
return result;
|
|
3801
|
+
}
|
|
3802
|
+
exports.smoothenSequenceDiffs = smoothenSequenceDiffs;
|
|
3803
|
+
function removeRandomLineMatches(sequence1, _sequence2, sequenceDiffs) {
|
|
3804
|
+
let diffs = sequenceDiffs;
|
|
3805
|
+
if (diffs.length === 0) {
|
|
3806
|
+
return diffs;
|
|
3807
|
+
}
|
|
3808
|
+
let counter = 0;
|
|
3809
|
+
let shouldRepeat;
|
|
3810
|
+
do {
|
|
3811
|
+
shouldRepeat = false;
|
|
3812
|
+
const result = [
|
|
3813
|
+
diffs[0]
|
|
3814
|
+
];
|
|
3815
|
+
for (let i = 1; i < diffs.length; i++) {
|
|
3816
|
+
const cur = diffs[i];
|
|
3817
|
+
const lastResult = result[result.length - 1];
|
|
3818
|
+
function shouldJoinDiffs(before, after) {
|
|
3819
|
+
const unchangedRange = new offsetRange_1.OffsetRange(lastResult.seq1Range.endExclusive, cur.seq1Range.start);
|
|
3820
|
+
const unchangedText = sequence1.getText(unchangedRange);
|
|
3821
|
+
const unchangedTextWithoutWs = unchangedText.replace(/\s/g, '');
|
|
3822
|
+
if (unchangedTextWithoutWs.length <= 4
|
|
3823
|
+
&& (before.seq1Range.length + before.seq2Range.length > 5 || after.seq1Range.length + after.seq2Range.length > 5)) {
|
|
3824
|
+
return true;
|
|
3825
|
+
}
|
|
3826
|
+
return false;
|
|
3827
|
+
}
|
|
3828
|
+
const shouldJoin = shouldJoinDiffs(lastResult, cur);
|
|
3829
|
+
if (shouldJoin) {
|
|
3830
|
+
shouldRepeat = true;
|
|
3831
|
+
result[result.length - 1] = result[result.length - 1].join(cur);
|
|
3832
|
+
}
|
|
3833
|
+
else {
|
|
3834
|
+
result.push(cur);
|
|
3835
|
+
}
|
|
3836
|
+
}
|
|
3837
|
+
diffs = result;
|
|
3838
|
+
} while (counter++ < 10 && shouldRepeat);
|
|
3839
|
+
return diffs;
|
|
3840
|
+
}
|
|
3841
|
+
exports.removeRandomLineMatches = removeRandomLineMatches;
|
|
3842
|
+
function removeRandomMatches(sequence1, sequence2, sequenceDiffs) {
|
|
3843
|
+
let diffs = sequenceDiffs;
|
|
3844
|
+
if (diffs.length === 0) {
|
|
3845
|
+
return diffs;
|
|
3846
|
+
}
|
|
3847
|
+
let counter = 0;
|
|
3848
|
+
let shouldRepeat;
|
|
3849
|
+
do {
|
|
3850
|
+
shouldRepeat = false;
|
|
3851
|
+
const result = [
|
|
3852
|
+
diffs[0]
|
|
3853
|
+
];
|
|
3854
|
+
for (let i = 1; i < diffs.length; i++) {
|
|
3855
|
+
const cur = diffs[i];
|
|
3856
|
+
const lastResult = result[result.length - 1];
|
|
3857
|
+
function shouldJoinDiffs(before, after) {
|
|
3858
|
+
const unchangedRange = new offsetRange_1.OffsetRange(lastResult.seq1Range.endExclusive, cur.seq1Range.start);
|
|
3859
|
+
const unchangedLineCount = sequence1.countLinesIn(unchangedRange);
|
|
3860
|
+
if (unchangedLineCount > 5 || unchangedRange.length > 500) {
|
|
3861
|
+
return false;
|
|
3862
|
+
}
|
|
3863
|
+
const unchangedText = sequence1.getText(unchangedRange).trim();
|
|
3864
|
+
if (unchangedText.length > 20 || unchangedText.split(/\r\n|\r|\n/).length > 1) {
|
|
3865
|
+
return false;
|
|
3866
|
+
}
|
|
3867
|
+
const beforeLineCount1 = sequence1.countLinesIn(before.seq1Range);
|
|
3868
|
+
const beforeSeq1Length = before.seq1Range.length;
|
|
3869
|
+
const beforeLineCount2 = sequence2.countLinesIn(before.seq2Range);
|
|
3870
|
+
const beforeSeq2Length = before.seq2Range.length;
|
|
3871
|
+
const afterLineCount1 = sequence1.countLinesIn(after.seq1Range);
|
|
3872
|
+
const afterSeq1Length = after.seq1Range.length;
|
|
3873
|
+
const afterLineCount2 = sequence2.countLinesIn(after.seq2Range);
|
|
3874
|
+
const afterSeq2Length = after.seq2Range.length;
|
|
3875
|
+
// TODO: Maybe a neural net can be used to derive the result from these numbers
|
|
3876
|
+
const max = 2 * 40 + 50;
|
|
3877
|
+
function cap(v) {
|
|
3878
|
+
return Math.min(v, max);
|
|
3879
|
+
}
|
|
3880
|
+
if (Math.pow(Math.pow(cap(beforeLineCount1 * 40 + beforeSeq1Length), 1.5) + Math.pow(cap(beforeLineCount2 * 40 + beforeSeq2Length), 1.5), 1.5)
|
|
3881
|
+
+ Math.pow(Math.pow(cap(afterLineCount1 * 40 + afterSeq1Length), 1.5) + Math.pow(cap(afterLineCount2 * 40 + afterSeq2Length), 1.5), 1.5) > ((max ** 1.5) ** 1.5) * 1.3) {
|
|
3882
|
+
return true;
|
|
3883
|
+
}
|
|
3884
|
+
return false;
|
|
3885
|
+
}
|
|
3886
|
+
const shouldJoin = shouldJoinDiffs(lastResult, cur);
|
|
3887
|
+
if (shouldJoin) {
|
|
3888
|
+
shouldRepeat = true;
|
|
3889
|
+
result[result.length - 1] = result[result.length - 1].join(cur);
|
|
3890
|
+
}
|
|
3891
|
+
else {
|
|
3892
|
+
result.push(cur);
|
|
3893
|
+
}
|
|
3894
|
+
}
|
|
3895
|
+
diffs = result;
|
|
3896
|
+
} while (counter++ < 10 && shouldRepeat);
|
|
3897
|
+
// Remove short suffixes/prefixes
|
|
3898
|
+
for (let i = 0; i < diffs.length; i++) {
|
|
3899
|
+
const cur = diffs[i];
|
|
3900
|
+
let range1 = cur.seq1Range;
|
|
3901
|
+
let range2 = cur.seq2Range;
|
|
3902
|
+
const fullRange1 = sequence1.extendToFullLines(cur.seq1Range);
|
|
3903
|
+
const prefix = sequence1.getText(new offsetRange_1.OffsetRange(fullRange1.start, cur.seq1Range.start));
|
|
3904
|
+
if (prefix.length > 0 && prefix.trim().length <= 3 && cur.seq1Range.length + cur.seq2Range.length > 100) {
|
|
3905
|
+
range1 = cur.seq1Range.deltaStart(-prefix.length);
|
|
3906
|
+
range2 = cur.seq2Range.deltaStart(-prefix.length);
|
|
3907
|
+
}
|
|
3908
|
+
const suffix = sequence1.getText(new offsetRange_1.OffsetRange(cur.seq1Range.endExclusive, fullRange1.endExclusive));
|
|
3909
|
+
if (suffix.length > 0 && (suffix.trim().length <= 3 && cur.seq1Range.length + cur.seq2Range.length > 150)) {
|
|
3910
|
+
range1 = range1.deltaEnd(suffix.length);
|
|
3911
|
+
range2 = range2.deltaEnd(suffix.length);
|
|
3912
|
+
}
|
|
3913
|
+
diffs[i] = new diffAlgorithm_1.SequenceDiff(range1, range2);
|
|
3914
|
+
}
|
|
3915
|
+
return diffs;
|
|
3916
|
+
}
|
|
3917
|
+
exports.removeRandomMatches = removeRandomMatches;
|
|
3918
|
+
/**
|
|
3919
|
+
* This function fixes issues like this:
|
|
3920
|
+
* ```
|
|
3921
|
+
* import { Baz, Bar } from "foo";
|
|
3922
|
+
* ```
|
|
3923
|
+
* <->
|
|
3924
|
+
* ```
|
|
3925
|
+
* import { Baz, Bar, Foo } from "foo";
|
|
3926
|
+
* ```
|
|
3927
|
+
* Computed diff: [ {Add "," after Bar}, {Add "Foo " after space} }
|
|
3928
|
+
* Improved diff: [{Add ", Foo" after Bar}]
|
|
3929
|
+
*/
|
|
3930
|
+
function joinSequenceDiffs(sequence1, sequence2, sequenceDiffs) {
|
|
3931
|
+
if (sequenceDiffs.length === 0) {
|
|
3932
|
+
return sequenceDiffs;
|
|
3933
|
+
}
|
|
3934
|
+
const result = [];
|
|
3935
|
+
result.push(sequenceDiffs[0]);
|
|
3936
|
+
// First move them all to the left as much as possible and join them if possible
|
|
3937
|
+
for (let i = 1; i < sequenceDiffs.length; i++) {
|
|
3938
|
+
const prevResult = result[result.length - 1];
|
|
3939
|
+
let cur = sequenceDiffs[i];
|
|
3940
|
+
if (cur.seq1Range.isEmpty || cur.seq2Range.isEmpty) {
|
|
3941
|
+
const length = cur.seq1Range.start - prevResult.seq1Range.endExclusive;
|
|
3942
|
+
let d;
|
|
3943
|
+
for (d = 1; d <= length; d++) {
|
|
3944
|
+
if (sequence1.getElement(cur.seq1Range.start - d) !== sequence1.getElement(cur.seq1Range.endExclusive - d) ||
|
|
3945
|
+
sequence2.getElement(cur.seq2Range.start - d) !== sequence2.getElement(cur.seq2Range.endExclusive - d)) {
|
|
3946
|
+
break;
|
|
3947
|
+
}
|
|
3948
|
+
}
|
|
3949
|
+
d--;
|
|
3950
|
+
if (d === length) {
|
|
3951
|
+
// Merge previous and current diff
|
|
3952
|
+
result[result.length - 1] = new diffAlgorithm_1.SequenceDiff(new offsetRange_1.OffsetRange(prevResult.seq1Range.start, cur.seq1Range.endExclusive - length), new offsetRange_1.OffsetRange(prevResult.seq2Range.start, cur.seq2Range.endExclusive - length));
|
|
3953
|
+
continue;
|
|
3954
|
+
}
|
|
3955
|
+
cur = cur.delta(-d);
|
|
3956
|
+
}
|
|
3957
|
+
result.push(cur);
|
|
3958
|
+
}
|
|
3959
|
+
const result2 = [];
|
|
3960
|
+
// Then move them all to the right and join them again if possible
|
|
3961
|
+
for (let i = 0; i < result.length - 1; i++) {
|
|
3962
|
+
const nextResult = result[i + 1];
|
|
3963
|
+
let cur = result[i];
|
|
3964
|
+
if (cur.seq1Range.isEmpty || cur.seq2Range.isEmpty) {
|
|
3965
|
+
const length = nextResult.seq1Range.start - cur.seq1Range.endExclusive;
|
|
3966
|
+
let d;
|
|
3967
|
+
for (d = 0; d < length; d++) {
|
|
3968
|
+
if (sequence1.getElement(cur.seq1Range.start + d) !== sequence1.getElement(cur.seq1Range.endExclusive + d) ||
|
|
3969
|
+
sequence2.getElement(cur.seq2Range.start + d) !== sequence2.getElement(cur.seq2Range.endExclusive + d)) {
|
|
3970
|
+
break;
|
|
3971
|
+
}
|
|
3972
|
+
}
|
|
3973
|
+
if (d === length) {
|
|
3974
|
+
// Merge previous and current diff, write to result!
|
|
3975
|
+
result[i + 1] = new diffAlgorithm_1.SequenceDiff(new offsetRange_1.OffsetRange(cur.seq1Range.start + length, nextResult.seq1Range.endExclusive), new offsetRange_1.OffsetRange(cur.seq2Range.start + length, nextResult.seq2Range.endExclusive));
|
|
3976
|
+
continue;
|
|
3977
|
+
}
|
|
3978
|
+
if (d > 0) {
|
|
3979
|
+
cur = cur.delta(d);
|
|
3980
|
+
}
|
|
3981
|
+
}
|
|
3982
|
+
result2.push(cur);
|
|
3983
|
+
}
|
|
3984
|
+
if (result.length > 0) {
|
|
3985
|
+
result2.push(result[result.length - 1]);
|
|
3986
|
+
}
|
|
3987
|
+
return result2;
|
|
3988
|
+
}
|
|
3989
|
+
exports.joinSequenceDiffs = joinSequenceDiffs;
|
|
3990
|
+
// align character level diffs at whitespace characters
|
|
3991
|
+
// import { IBar } from "foo";
|
|
3992
|
+
// import { I[Arr, I]Bar } from "foo";
|
|
3993
|
+
// ->
|
|
3994
|
+
// import { [IArr, ]IBar } from "foo";
|
|
3995
|
+
// import { ITransaction, observableValue, transaction } from 'vs/base/common/observable';
|
|
3996
|
+
// import { ITransaction, observable[FromEvent, observable]Value, transaction } from 'vs/base/common/observable';
|
|
3997
|
+
// ->
|
|
3998
|
+
// import { ITransaction, [observableFromEvent, ]observableValue, transaction } from 'vs/base/common/observable';
|
|
3999
|
+
// collectBrackets(level + 1, levelPerBracketType);
|
|
4000
|
+
// collectBrackets(level + 1, levelPerBracket[ + 1, levelPerBracket]Type);
|
|
4001
|
+
// ->
|
|
4002
|
+
// collectBrackets(level + 1, [levelPerBracket + 1, ]levelPerBracketType);
|
|
4003
|
+
function shiftSequenceDiffs(sequence1, sequence2, sequenceDiffs) {
|
|
4004
|
+
if (!sequence1.getBoundaryScore || !sequence2.getBoundaryScore) {
|
|
4005
|
+
return sequenceDiffs;
|
|
4006
|
+
}
|
|
4007
|
+
for (let i = 0; i < sequenceDiffs.length; i++) {
|
|
4008
|
+
const prevDiff = (i > 0 ? sequenceDiffs[i - 1] : undefined);
|
|
4009
|
+
const diff = sequenceDiffs[i];
|
|
4010
|
+
const nextDiff = (i + 1 < sequenceDiffs.length ? sequenceDiffs[i + 1] : undefined);
|
|
4011
|
+
const seq1ValidRange = new offsetRange_1.OffsetRange(prevDiff ? prevDiff.seq1Range.start + 1 : 0, nextDiff ? nextDiff.seq1Range.endExclusive - 1 : sequence1.length);
|
|
4012
|
+
const seq2ValidRange = new offsetRange_1.OffsetRange(prevDiff ? prevDiff.seq2Range.start + 1 : 0, nextDiff ? nextDiff.seq2Range.endExclusive - 1 : sequence2.length);
|
|
4013
|
+
if (diff.seq1Range.isEmpty) {
|
|
4014
|
+
sequenceDiffs[i] = shiftDiffToBetterPosition(diff, sequence1, sequence2, seq1ValidRange, seq2ValidRange);
|
|
4015
|
+
}
|
|
4016
|
+
else if (diff.seq2Range.isEmpty) {
|
|
4017
|
+
sequenceDiffs[i] = shiftDiffToBetterPosition(diff.reverse(), sequence2, sequence1, seq2ValidRange, seq1ValidRange).reverse();
|
|
4018
|
+
}
|
|
4019
|
+
}
|
|
4020
|
+
return sequenceDiffs;
|
|
4021
|
+
}
|
|
4022
|
+
exports.shiftSequenceDiffs = shiftSequenceDiffs;
|
|
4023
|
+
function shiftDiffToBetterPosition(diff, sequence1, sequence2, seq1ValidRange, seq2ValidRange) {
|
|
4024
|
+
const maxShiftLimit = 100; // To prevent performance issues
|
|
4025
|
+
// don't touch previous or next!
|
|
4026
|
+
let deltaBefore = 1;
|
|
4027
|
+
while (diff.seq1Range.start - deltaBefore >= seq1ValidRange.start &&
|
|
4028
|
+
diff.seq2Range.start - deltaBefore >= seq2ValidRange.start &&
|
|
4029
|
+
sequence2.isStronglyEqual(diff.seq2Range.start - deltaBefore, diff.seq2Range.endExclusive - deltaBefore) && deltaBefore < maxShiftLimit) {
|
|
4030
|
+
deltaBefore++;
|
|
4031
|
+
}
|
|
4032
|
+
deltaBefore--;
|
|
4033
|
+
let deltaAfter = 0;
|
|
4034
|
+
while (diff.seq1Range.start + deltaAfter < seq1ValidRange.endExclusive &&
|
|
4035
|
+
diff.seq2Range.endExclusive + deltaAfter < seq2ValidRange.endExclusive &&
|
|
4036
|
+
sequence2.isStronglyEqual(diff.seq2Range.start + deltaAfter, diff.seq2Range.endExclusive + deltaAfter) && deltaAfter < maxShiftLimit) {
|
|
4037
|
+
deltaAfter++;
|
|
4038
|
+
}
|
|
4039
|
+
if (deltaBefore === 0 && deltaAfter === 0) {
|
|
4040
|
+
return diff;
|
|
4041
|
+
}
|
|
4042
|
+
// Visualize `[sequence1.text, diff.seq1Range.start + deltaAfter]`
|
|
4043
|
+
// and `[sequence2.text, diff.seq2Range.start + deltaAfter, diff.seq2Range.endExclusive + deltaAfter]`
|
|
4044
|
+
let bestDelta = 0;
|
|
4045
|
+
let bestScore = -1;
|
|
4046
|
+
// find best scored delta
|
|
4047
|
+
for (let delta = -deltaBefore; delta <= deltaAfter; delta++) {
|
|
4048
|
+
const seq2OffsetStart = diff.seq2Range.start + delta;
|
|
4049
|
+
const seq2OffsetEndExclusive = diff.seq2Range.endExclusive + delta;
|
|
4050
|
+
const seq1Offset = diff.seq1Range.start + delta;
|
|
4051
|
+
const score = sequence1.getBoundaryScore(seq1Offset) + sequence2.getBoundaryScore(seq2OffsetStart) + sequence2.getBoundaryScore(seq2OffsetEndExclusive);
|
|
4052
|
+
if (score > bestScore) {
|
|
4053
|
+
bestScore = score;
|
|
4054
|
+
bestDelta = delta;
|
|
4055
|
+
}
|
|
4056
|
+
}
|
|
4057
|
+
return diff.delta(bestDelta);
|
|
4058
|
+
}
|
|
4059
|
+
|
|
4060
|
+
|
|
4061
|
+
/***/ }),
|
|
4062
|
+
|
|
4063
|
+
/***/ "./node_modules/vscode-diff/dist/vs/editor/common/diff/algorithms/myersDiffAlgorithm.js":
|
|
4064
|
+
/*!**********************************************************************************************!*\
|
|
4065
|
+
!*** ./node_modules/vscode-diff/dist/vs/editor/common/diff/algorithms/myersDiffAlgorithm.js ***!
|
|
4066
|
+
\**********************************************************************************************/
|
|
4067
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
4068
|
+
|
|
4069
|
+
|
|
4070
|
+
/*---------------------------------------------------------------------------------------------
|
|
4071
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4072
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4073
|
+
*--------------------------------------------------------------------------------------------*/
|
|
4074
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
4075
|
+
exports.MyersDiffAlgorithm = void 0;
|
|
4076
|
+
const offsetRange_1 = __webpack_require__(/*! ../../core/offsetRange */ "./node_modules/vscode-diff/dist/vs/editor/common/core/offsetRange.js");
|
|
4077
|
+
const diffAlgorithm_1 = __webpack_require__(/*! ../algorithms/diffAlgorithm */ "./node_modules/vscode-diff/dist/vs/editor/common/diff/algorithms/diffAlgorithm.js");
|
|
4078
|
+
/**
|
|
4079
|
+
* An O(ND) diff algorithm that has a quadratic space worst-case complexity.
|
|
4080
|
+
*/
|
|
4081
|
+
class MyersDiffAlgorithm {
|
|
4082
|
+
compute(seq1, seq2, timeout = diffAlgorithm_1.InfiniteTimeout.instance) {
|
|
4083
|
+
// These are common special cases.
|
|
4084
|
+
// The early return improves performance dramatically.
|
|
4085
|
+
if (seq1.length === 0 || seq2.length === 0) {
|
|
4086
|
+
return diffAlgorithm_1.DiffAlgorithmResult.trivial(seq1, seq2);
|
|
4087
|
+
}
|
|
4088
|
+
function getXAfterSnake(x, y) {
|
|
4089
|
+
while (x < seq1.length && y < seq2.length && seq1.getElement(x) === seq2.getElement(y)) {
|
|
4090
|
+
x++;
|
|
4091
|
+
y++;
|
|
4092
|
+
}
|
|
4093
|
+
return x;
|
|
4094
|
+
}
|
|
4095
|
+
let d = 0;
|
|
4096
|
+
// V[k]: X value of longest d-line that ends in diagonal k.
|
|
4097
|
+
// d-line: path from (0,0) to (x,y) that uses exactly d non-diagonals.
|
|
4098
|
+
// diagonal k: Set of points (x,y) with x-y = k.
|
|
4099
|
+
const V = new FastInt32Array();
|
|
4100
|
+
V.set(0, getXAfterSnake(0, 0));
|
|
4101
|
+
const paths = new FastArrayNegativeIndices();
|
|
4102
|
+
paths.set(0, V.get(0) === 0 ? null : new SnakePath(null, 0, 0, V.get(0)));
|
|
4103
|
+
let k = 0;
|
|
4104
|
+
loop: while (true) {
|
|
4105
|
+
d++;
|
|
4106
|
+
if (!timeout.isValid()) {
|
|
4107
|
+
return diffAlgorithm_1.DiffAlgorithmResult.trivialTimedOut(seq1, seq2);
|
|
4108
|
+
}
|
|
4109
|
+
// The paper has `for (k = -d; k <= d; k += 2)`, but we can ignore diagonals that cannot influence the result.
|
|
4110
|
+
const lowerBound = -Math.min(d, seq2.length + (d % 2));
|
|
4111
|
+
const upperBound = Math.min(d, seq1.length + (d % 2));
|
|
4112
|
+
for (k = lowerBound; k <= upperBound; k += 2) {
|
|
4113
|
+
// We can use the X values of (d-1)-lines to compute X value of the longest d-lines.
|
|
4114
|
+
const maxXofDLineTop = k === upperBound ? -1 : V.get(k + 1); // We take a vertical non-diagonal (add a symbol in seq1)
|
|
4115
|
+
const maxXofDLineLeft = k === lowerBound ? -1 : V.get(k - 1) + 1; // We take a horizontal non-diagonal (+1 x) (delete a symbol in seq1)
|
|
4116
|
+
const x = Math.min(Math.max(maxXofDLineTop, maxXofDLineLeft), seq1.length);
|
|
4117
|
+
const y = x - k;
|
|
4118
|
+
if (x > seq1.length || y > seq2.length) {
|
|
4119
|
+
// This diagonal is irrelevant for the result.
|
|
4120
|
+
// TODO: Don't pay the cost for this in the next iteration.
|
|
4121
|
+
continue;
|
|
4122
|
+
}
|
|
4123
|
+
const newMaxX = getXAfterSnake(x, y);
|
|
4124
|
+
V.set(k, newMaxX);
|
|
4125
|
+
const lastPath = x === maxXofDLineTop ? paths.get(k + 1) : paths.get(k - 1);
|
|
4126
|
+
paths.set(k, newMaxX !== x ? new SnakePath(lastPath, x, y, newMaxX - x) : lastPath);
|
|
4127
|
+
if (V.get(k) === seq1.length && V.get(k) - k === seq2.length) {
|
|
4128
|
+
break loop;
|
|
4129
|
+
}
|
|
4130
|
+
}
|
|
4131
|
+
}
|
|
4132
|
+
let path = paths.get(k);
|
|
4133
|
+
const result = [];
|
|
4134
|
+
let lastAligningPosS1 = seq1.length;
|
|
4135
|
+
let lastAligningPosS2 = seq2.length;
|
|
4136
|
+
while (true) {
|
|
4137
|
+
const endX = path ? path.x + path.length : 0;
|
|
4138
|
+
const endY = path ? path.y + path.length : 0;
|
|
4139
|
+
if (endX !== lastAligningPosS1 || endY !== lastAligningPosS2) {
|
|
4140
|
+
result.push(new diffAlgorithm_1.SequenceDiff(new offsetRange_1.OffsetRange(endX, lastAligningPosS1), new offsetRange_1.OffsetRange(endY, lastAligningPosS2)));
|
|
4141
|
+
}
|
|
4142
|
+
if (!path) {
|
|
4143
|
+
break;
|
|
4144
|
+
}
|
|
4145
|
+
lastAligningPosS1 = path.x;
|
|
4146
|
+
lastAligningPosS2 = path.y;
|
|
4147
|
+
path = path.prev;
|
|
4148
|
+
}
|
|
4149
|
+
result.reverse();
|
|
4150
|
+
return new diffAlgorithm_1.DiffAlgorithmResult(result, false);
|
|
4151
|
+
}
|
|
4152
|
+
}
|
|
4153
|
+
exports.MyersDiffAlgorithm = MyersDiffAlgorithm;
|
|
4154
|
+
class SnakePath {
|
|
4155
|
+
constructor(prev, x, y, length) {
|
|
4156
|
+
this.prev = prev;
|
|
4157
|
+
this.x = x;
|
|
4158
|
+
this.y = y;
|
|
4159
|
+
this.length = length;
|
|
4160
|
+
}
|
|
4161
|
+
}
|
|
4162
|
+
/**
|
|
4163
|
+
* An array that supports fast negative indices.
|
|
4164
|
+
*/
|
|
4165
|
+
class FastInt32Array {
|
|
4166
|
+
constructor() {
|
|
4167
|
+
this.positiveArr = new Int32Array(10);
|
|
4168
|
+
this.negativeArr = new Int32Array(10);
|
|
4169
|
+
}
|
|
4170
|
+
get(idx) {
|
|
4171
|
+
if (idx < 0) {
|
|
4172
|
+
idx = -idx - 1;
|
|
4173
|
+
return this.negativeArr[idx];
|
|
4174
|
+
}
|
|
4175
|
+
else {
|
|
4176
|
+
return this.positiveArr[idx];
|
|
4177
|
+
}
|
|
4178
|
+
}
|
|
4179
|
+
set(idx, value) {
|
|
4180
|
+
if (idx < 0) {
|
|
4181
|
+
idx = -idx - 1;
|
|
4182
|
+
if (idx >= this.negativeArr.length) {
|
|
4183
|
+
const arr = this.negativeArr;
|
|
4184
|
+
this.negativeArr = new Int32Array(arr.length * 2);
|
|
4185
|
+
this.negativeArr.set(arr);
|
|
4186
|
+
}
|
|
4187
|
+
this.negativeArr[idx] = value;
|
|
4188
|
+
}
|
|
4189
|
+
else {
|
|
4190
|
+
if (idx >= this.positiveArr.length) {
|
|
4191
|
+
const arr = this.positiveArr;
|
|
4192
|
+
this.positiveArr = new Int32Array(arr.length * 2);
|
|
4193
|
+
this.positiveArr.set(arr);
|
|
4194
|
+
}
|
|
4195
|
+
this.positiveArr[idx] = value;
|
|
4196
|
+
}
|
|
4197
|
+
}
|
|
4198
|
+
}
|
|
4199
|
+
/**
|
|
4200
|
+
* An array that supports fast negative indices.
|
|
4201
|
+
*/
|
|
4202
|
+
class FastArrayNegativeIndices {
|
|
4203
|
+
constructor() {
|
|
4204
|
+
this.positiveArr = [];
|
|
4205
|
+
this.negativeArr = [];
|
|
4206
|
+
}
|
|
4207
|
+
get(idx) {
|
|
4208
|
+
if (idx < 0) {
|
|
4209
|
+
idx = -idx - 1;
|
|
4210
|
+
return this.negativeArr[idx];
|
|
4211
|
+
}
|
|
4212
|
+
else {
|
|
4213
|
+
return this.positiveArr[idx];
|
|
4214
|
+
}
|
|
4215
|
+
}
|
|
4216
|
+
set(idx, value) {
|
|
4217
|
+
if (idx < 0) {
|
|
4218
|
+
idx = -idx - 1;
|
|
4219
|
+
this.negativeArr[idx] = value;
|
|
4220
|
+
}
|
|
4221
|
+
else {
|
|
4222
|
+
this.positiveArr[idx] = value;
|
|
4223
|
+
}
|
|
4224
|
+
}
|
|
4225
|
+
}
|
|
4226
|
+
|
|
4227
|
+
|
|
4228
|
+
/***/ }),
|
|
4229
|
+
|
|
4230
|
+
/***/ "./node_modules/vscode-diff/dist/vs/editor/common/diff/algorithms/utils.js":
|
|
4231
|
+
/*!*********************************************************************************!*\
|
|
4232
|
+
!*** ./node_modules/vscode-diff/dist/vs/editor/common/diff/algorithms/utils.js ***!
|
|
4233
|
+
\*********************************************************************************/
|
|
4234
|
+
/***/ ((__unused_webpack_module, exports) => {
|
|
4235
|
+
|
|
4236
|
+
|
|
4237
|
+
/*---------------------------------------------------------------------------------------------
|
|
4238
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4239
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4240
|
+
*--------------------------------------------------------------------------------------------*/
|
|
4241
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
4242
|
+
exports.Array2D = void 0;
|
|
4243
|
+
class Array2D {
|
|
4244
|
+
constructor(width, height) {
|
|
4245
|
+
this.width = width;
|
|
4246
|
+
this.height = height;
|
|
4247
|
+
this.array = [];
|
|
4248
|
+
this.array = new Array(width * height);
|
|
4249
|
+
}
|
|
4250
|
+
get(x, y) {
|
|
4251
|
+
return this.array[x + y * this.width];
|
|
4252
|
+
}
|
|
4253
|
+
set(x, y, value) {
|
|
4254
|
+
this.array[x + y * this.width] = value;
|
|
4255
|
+
}
|
|
4256
|
+
}
|
|
4257
|
+
exports.Array2D = Array2D;
|
|
4258
|
+
|
|
4259
|
+
|
|
4260
|
+
/***/ }),
|
|
4261
|
+
|
|
4262
|
+
/***/ "./node_modules/vscode-diff/dist/vs/editor/common/diff/legacyLinesDiffComputer.js":
|
|
4263
|
+
/*!****************************************************************************************!*\
|
|
4264
|
+
!*** ./node_modules/vscode-diff/dist/vs/editor/common/diff/legacyLinesDiffComputer.js ***!
|
|
4265
|
+
\****************************************************************************************/
|
|
4266
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
4267
|
+
|
|
4268
|
+
|
|
4269
|
+
/*---------------------------------------------------------------------------------------------
|
|
4270
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4271
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4272
|
+
*--------------------------------------------------------------------------------------------*/
|
|
4273
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
4274
|
+
exports.DiffComputer = exports.LegacyLinesDiffComputer = void 0;
|
|
4275
|
+
const assert_1 = __webpack_require__(/*! ../../../base/common/assert */ "./node_modules/vscode-diff/dist/vs/base/common/assert.js");
|
|
4276
|
+
const diff_1 = __webpack_require__(/*! ../../../base/common/diff/diff */ "./node_modules/vscode-diff/dist/vs/base/common/diff/diff.js");
|
|
4277
|
+
const strings = __webpack_require__(/*! ../../../base/common/strings */ "./node_modules/vscode-diff/dist/vs/base/common/strings.js");
|
|
4278
|
+
const lineRange_1 = __webpack_require__(/*! ../core/lineRange */ "./node_modules/vscode-diff/dist/vs/editor/common/core/lineRange.js");
|
|
4279
|
+
const range_1 = __webpack_require__(/*! ../core/range */ "./node_modules/vscode-diff/dist/vs/editor/common/core/range.js");
|
|
4280
|
+
const linesDiffComputer_1 = __webpack_require__(/*! ./linesDiffComputer */ "./node_modules/vscode-diff/dist/vs/editor/common/diff/linesDiffComputer.js");
|
|
4281
|
+
const MINIMUM_MATCHING_CHARACTER_LENGTH = 3;
|
|
4282
|
+
class LegacyLinesDiffComputer {
|
|
4283
|
+
computeDiff(originalLines, modifiedLines, options) {
|
|
4284
|
+
const diffComputer = new DiffComputer(originalLines, modifiedLines, {
|
|
4285
|
+
maxComputationTime: options.maxComputationTimeMs,
|
|
4286
|
+
shouldIgnoreTrimWhitespace: options.ignoreTrimWhitespace,
|
|
4287
|
+
shouldComputeCharChanges: true,
|
|
4288
|
+
shouldMakePrettyDiff: true,
|
|
4289
|
+
shouldPostProcessCharChanges: true,
|
|
4290
|
+
});
|
|
4291
|
+
const result = diffComputer.computeDiff();
|
|
4292
|
+
const changes = [];
|
|
4293
|
+
let lastChange = null;
|
|
4294
|
+
for (const c of result.changes) {
|
|
4295
|
+
let originalRange;
|
|
4296
|
+
if (c.originalEndLineNumber === 0) {
|
|
4297
|
+
// Insertion
|
|
4298
|
+
originalRange = new lineRange_1.LineRange(c.originalStartLineNumber + 1, c.originalStartLineNumber + 1);
|
|
4299
|
+
}
|
|
4300
|
+
else {
|
|
4301
|
+
originalRange = new lineRange_1.LineRange(c.originalStartLineNumber, c.originalEndLineNumber + 1);
|
|
4302
|
+
}
|
|
4303
|
+
let modifiedRange;
|
|
4304
|
+
if (c.modifiedEndLineNumber === 0) {
|
|
4305
|
+
// Deletion
|
|
4306
|
+
modifiedRange = new lineRange_1.LineRange(c.modifiedStartLineNumber + 1, c.modifiedStartLineNumber + 1);
|
|
4307
|
+
}
|
|
4308
|
+
else {
|
|
4309
|
+
modifiedRange = new lineRange_1.LineRange(c.modifiedStartLineNumber, c.modifiedEndLineNumber + 1);
|
|
4310
|
+
}
|
|
4311
|
+
let change = new linesDiffComputer_1.LineRangeMapping(originalRange, modifiedRange, c.charChanges?.map(c => new linesDiffComputer_1.RangeMapping(new range_1.Range(c.originalStartLineNumber, c.originalStartColumn, c.originalEndLineNumber, c.originalEndColumn), new range_1.Range(c.modifiedStartLineNumber, c.modifiedStartColumn, c.modifiedEndLineNumber, c.modifiedEndColumn))));
|
|
4312
|
+
if (lastChange) {
|
|
4313
|
+
if (lastChange.modifiedRange.endLineNumberExclusive === change.modifiedRange.startLineNumber
|
|
4314
|
+
|| lastChange.originalRange.endLineNumberExclusive === change.originalRange.startLineNumber) {
|
|
4315
|
+
// join touching diffs. Probably moving diffs up/down in the algorithm causes touching diffs.
|
|
4316
|
+
change = new linesDiffComputer_1.LineRangeMapping(lastChange.originalRange.join(change.originalRange), lastChange.modifiedRange.join(change.modifiedRange), lastChange.innerChanges && change.innerChanges ?
|
|
4317
|
+
lastChange.innerChanges.concat(change.innerChanges) : undefined);
|
|
4318
|
+
changes.pop();
|
|
4319
|
+
}
|
|
4320
|
+
}
|
|
4321
|
+
changes.push(change);
|
|
4322
|
+
lastChange = change;
|
|
4323
|
+
}
|
|
4324
|
+
(0, assert_1.assertFn)(() => {
|
|
4325
|
+
return (0, assert_1.checkAdjacentItems)(changes, (m1, m2) => m2.originalRange.startLineNumber - m1.originalRange.endLineNumberExclusive === m2.modifiedRange.startLineNumber - m1.modifiedRange.endLineNumberExclusive &&
|
|
4326
|
+
// There has to be an unchanged line in between (otherwise both diffs should have been joined)
|
|
4327
|
+
m1.originalRange.endLineNumberExclusive < m2.originalRange.startLineNumber &&
|
|
4328
|
+
m1.modifiedRange.endLineNumberExclusive < m2.modifiedRange.startLineNumber);
|
|
4329
|
+
});
|
|
4330
|
+
return new linesDiffComputer_1.LinesDiff(changes, [], result.quitEarly);
|
|
4331
|
+
}
|
|
4332
|
+
}
|
|
4333
|
+
exports.LegacyLinesDiffComputer = LegacyLinesDiffComputer;
|
|
4334
|
+
function computeDiff(originalSequence, modifiedSequence, continueProcessingPredicate, pretty) {
|
|
4335
|
+
const diffAlgo = new diff_1.LcsDiff(originalSequence, modifiedSequence, continueProcessingPredicate);
|
|
4336
|
+
return diffAlgo.ComputeDiff(pretty);
|
|
4337
|
+
}
|
|
4338
|
+
class LineSequence {
|
|
4339
|
+
constructor(lines) {
|
|
4340
|
+
const startColumns = [];
|
|
4341
|
+
const endColumns = [];
|
|
4342
|
+
for (let i = 0, length = lines.length; i < length; i++) {
|
|
4343
|
+
startColumns[i] = getFirstNonBlankColumn(lines[i], 1);
|
|
4344
|
+
endColumns[i] = getLastNonBlankColumn(lines[i], 1);
|
|
4345
|
+
}
|
|
4346
|
+
this.lines = lines;
|
|
4347
|
+
this._startColumns = startColumns;
|
|
4348
|
+
this._endColumns = endColumns;
|
|
4349
|
+
}
|
|
4350
|
+
getElements() {
|
|
4351
|
+
const elements = [];
|
|
4352
|
+
for (let i = 0, len = this.lines.length; i < len; i++) {
|
|
4353
|
+
elements[i] = this.lines[i].substring(this._startColumns[i] - 1, this._endColumns[i] - 1);
|
|
4354
|
+
}
|
|
4355
|
+
return elements;
|
|
4356
|
+
}
|
|
4357
|
+
getStrictElement(index) {
|
|
4358
|
+
return this.lines[index];
|
|
4359
|
+
}
|
|
4360
|
+
getStartLineNumber(i) {
|
|
4361
|
+
return i + 1;
|
|
4362
|
+
}
|
|
4363
|
+
getEndLineNumber(i) {
|
|
4364
|
+
return i + 1;
|
|
4365
|
+
}
|
|
4366
|
+
createCharSequence(shouldIgnoreTrimWhitespace, startIndex, endIndex) {
|
|
4367
|
+
const charCodes = [];
|
|
4368
|
+
const lineNumbers = [];
|
|
4369
|
+
const columns = [];
|
|
4370
|
+
let len = 0;
|
|
4371
|
+
for (let index = startIndex; index <= endIndex; index++) {
|
|
4372
|
+
const lineContent = this.lines[index];
|
|
4373
|
+
const startColumn = (shouldIgnoreTrimWhitespace ? this._startColumns[index] : 1);
|
|
4374
|
+
const endColumn = (shouldIgnoreTrimWhitespace ? this._endColumns[index] : lineContent.length + 1);
|
|
4375
|
+
for (let col = startColumn; col < endColumn; col++) {
|
|
4376
|
+
charCodes[len] = lineContent.charCodeAt(col - 1);
|
|
4377
|
+
lineNumbers[len] = index + 1;
|
|
4378
|
+
columns[len] = col;
|
|
4379
|
+
len++;
|
|
4380
|
+
}
|
|
4381
|
+
if (!shouldIgnoreTrimWhitespace && index < endIndex) {
|
|
4382
|
+
// Add \n if trim whitespace is not ignored
|
|
4383
|
+
charCodes[len] = 10 /* CharCode.LineFeed */;
|
|
4384
|
+
lineNumbers[len] = index + 1;
|
|
4385
|
+
columns[len] = lineContent.length + 1;
|
|
4386
|
+
len++;
|
|
4387
|
+
}
|
|
4388
|
+
}
|
|
4389
|
+
return new CharSequence(charCodes, lineNumbers, columns);
|
|
4390
|
+
}
|
|
4391
|
+
}
|
|
4392
|
+
class CharSequence {
|
|
4393
|
+
constructor(charCodes, lineNumbers, columns) {
|
|
4394
|
+
this._charCodes = charCodes;
|
|
4395
|
+
this._lineNumbers = lineNumbers;
|
|
4396
|
+
this._columns = columns;
|
|
4397
|
+
}
|
|
4398
|
+
toString() {
|
|
4399
|
+
return ('[' + this._charCodes.map((s, idx) => (s === 10 /* CharCode.LineFeed */ ? '\\n' : String.fromCharCode(s)) + `-(${this._lineNumbers[idx]},${this._columns[idx]})`).join(', ') + ']');
|
|
4400
|
+
}
|
|
4401
|
+
_assertIndex(index, arr) {
|
|
4402
|
+
if (index < 0 || index >= arr.length) {
|
|
4403
|
+
throw new Error(`Illegal index`);
|
|
4404
|
+
}
|
|
4405
|
+
}
|
|
4406
|
+
getElements() {
|
|
4407
|
+
return this._charCodes;
|
|
4408
|
+
}
|
|
4409
|
+
getStartLineNumber(i) {
|
|
4410
|
+
if (i > 0 && i === this._lineNumbers.length) {
|
|
4411
|
+
// the start line number of the element after the last element
|
|
4412
|
+
// is the end line number of the last element
|
|
4413
|
+
return this.getEndLineNumber(i - 1);
|
|
4414
|
+
}
|
|
4415
|
+
this._assertIndex(i, this._lineNumbers);
|
|
4416
|
+
return this._lineNumbers[i];
|
|
4417
|
+
}
|
|
4418
|
+
getEndLineNumber(i) {
|
|
4419
|
+
if (i === -1) {
|
|
4420
|
+
// the end line number of the element before the first element
|
|
4421
|
+
// is the start line number of the first element
|
|
4422
|
+
return this.getStartLineNumber(i + 1);
|
|
4423
|
+
}
|
|
4424
|
+
this._assertIndex(i, this._lineNumbers);
|
|
4425
|
+
if (this._charCodes[i] === 10 /* CharCode.LineFeed */) {
|
|
4426
|
+
return this._lineNumbers[i] + 1;
|
|
4427
|
+
}
|
|
4428
|
+
return this._lineNumbers[i];
|
|
4429
|
+
}
|
|
4430
|
+
getStartColumn(i) {
|
|
4431
|
+
if (i > 0 && i === this._columns.length) {
|
|
4432
|
+
// the start column of the element after the last element
|
|
4433
|
+
// is the end column of the last element
|
|
4434
|
+
return this.getEndColumn(i - 1);
|
|
4435
|
+
}
|
|
4436
|
+
this._assertIndex(i, this._columns);
|
|
4437
|
+
return this._columns[i];
|
|
4438
|
+
}
|
|
4439
|
+
getEndColumn(i) {
|
|
4440
|
+
if (i === -1) {
|
|
4441
|
+
// the end column of the element before the first element
|
|
4442
|
+
// is the start column of the first element
|
|
4443
|
+
return this.getStartColumn(i + 1);
|
|
4444
|
+
}
|
|
4445
|
+
this._assertIndex(i, this._columns);
|
|
4446
|
+
if (this._charCodes[i] === 10 /* CharCode.LineFeed */) {
|
|
4447
|
+
return 1;
|
|
4448
|
+
}
|
|
4449
|
+
return this._columns[i] + 1;
|
|
4450
|
+
}
|
|
4451
|
+
}
|
|
4452
|
+
class CharChange {
|
|
4453
|
+
constructor(originalStartLineNumber, originalStartColumn, originalEndLineNumber, originalEndColumn, modifiedStartLineNumber, modifiedStartColumn, modifiedEndLineNumber, modifiedEndColumn) {
|
|
4454
|
+
this.originalStartLineNumber = originalStartLineNumber;
|
|
4455
|
+
this.originalStartColumn = originalStartColumn;
|
|
4456
|
+
this.originalEndLineNumber = originalEndLineNumber;
|
|
4457
|
+
this.originalEndColumn = originalEndColumn;
|
|
4458
|
+
this.modifiedStartLineNumber = modifiedStartLineNumber;
|
|
4459
|
+
this.modifiedStartColumn = modifiedStartColumn;
|
|
4460
|
+
this.modifiedEndLineNumber = modifiedEndLineNumber;
|
|
4461
|
+
this.modifiedEndColumn = modifiedEndColumn;
|
|
4462
|
+
}
|
|
4463
|
+
static createFromDiffChange(diffChange, originalCharSequence, modifiedCharSequence) {
|
|
4464
|
+
const originalStartLineNumber = originalCharSequence.getStartLineNumber(diffChange.originalStart);
|
|
4465
|
+
const originalStartColumn = originalCharSequence.getStartColumn(diffChange.originalStart);
|
|
4466
|
+
const originalEndLineNumber = originalCharSequence.getEndLineNumber(diffChange.originalStart + diffChange.originalLength - 1);
|
|
4467
|
+
const originalEndColumn = originalCharSequence.getEndColumn(diffChange.originalStart + diffChange.originalLength - 1);
|
|
4468
|
+
const modifiedStartLineNumber = modifiedCharSequence.getStartLineNumber(diffChange.modifiedStart);
|
|
4469
|
+
const modifiedStartColumn = modifiedCharSequence.getStartColumn(diffChange.modifiedStart);
|
|
4470
|
+
const modifiedEndLineNumber = modifiedCharSequence.getEndLineNumber(diffChange.modifiedStart + diffChange.modifiedLength - 1);
|
|
4471
|
+
const modifiedEndColumn = modifiedCharSequence.getEndColumn(diffChange.modifiedStart + diffChange.modifiedLength - 1);
|
|
4472
|
+
return new CharChange(originalStartLineNumber, originalStartColumn, originalEndLineNumber, originalEndColumn, modifiedStartLineNumber, modifiedStartColumn, modifiedEndLineNumber, modifiedEndColumn);
|
|
4473
|
+
}
|
|
4474
|
+
}
|
|
4475
|
+
function postProcessCharChanges(rawChanges) {
|
|
4476
|
+
if (rawChanges.length <= 1) {
|
|
4477
|
+
return rawChanges;
|
|
4478
|
+
}
|
|
4479
|
+
const result = [rawChanges[0]];
|
|
4480
|
+
let prevChange = result[0];
|
|
4481
|
+
for (let i = 1, len = rawChanges.length; i < len; i++) {
|
|
4482
|
+
const currChange = rawChanges[i];
|
|
4483
|
+
const originalMatchingLength = currChange.originalStart - (prevChange.originalStart + prevChange.originalLength);
|
|
4484
|
+
const modifiedMatchingLength = currChange.modifiedStart - (prevChange.modifiedStart + prevChange.modifiedLength);
|
|
4485
|
+
// Both of the above should be equal, but the continueProcessingPredicate may prevent this from being true
|
|
4486
|
+
const matchingLength = Math.min(originalMatchingLength, modifiedMatchingLength);
|
|
4487
|
+
if (matchingLength < MINIMUM_MATCHING_CHARACTER_LENGTH) {
|
|
4488
|
+
// Merge the current change into the previous one
|
|
4489
|
+
prevChange.originalLength = (currChange.originalStart + currChange.originalLength) - prevChange.originalStart;
|
|
4490
|
+
prevChange.modifiedLength = (currChange.modifiedStart + currChange.modifiedLength) - prevChange.modifiedStart;
|
|
4491
|
+
}
|
|
4492
|
+
else {
|
|
4493
|
+
// Add the current change
|
|
4494
|
+
result.push(currChange);
|
|
4495
|
+
prevChange = currChange;
|
|
4496
|
+
}
|
|
4497
|
+
}
|
|
4498
|
+
return result;
|
|
4499
|
+
}
|
|
4500
|
+
class LineChange {
|
|
4501
|
+
constructor(originalStartLineNumber, originalEndLineNumber, modifiedStartLineNumber, modifiedEndLineNumber, charChanges) {
|
|
4502
|
+
this.originalStartLineNumber = originalStartLineNumber;
|
|
4503
|
+
this.originalEndLineNumber = originalEndLineNumber;
|
|
4504
|
+
this.modifiedStartLineNumber = modifiedStartLineNumber;
|
|
4505
|
+
this.modifiedEndLineNumber = modifiedEndLineNumber;
|
|
4506
|
+
this.charChanges = charChanges;
|
|
4507
|
+
}
|
|
4508
|
+
static createFromDiffResult(shouldIgnoreTrimWhitespace, diffChange, originalLineSequence, modifiedLineSequence, continueCharDiff, shouldComputeCharChanges, shouldPostProcessCharChanges) {
|
|
4509
|
+
let originalStartLineNumber;
|
|
4510
|
+
let originalEndLineNumber;
|
|
4511
|
+
let modifiedStartLineNumber;
|
|
4512
|
+
let modifiedEndLineNumber;
|
|
4513
|
+
let charChanges = undefined;
|
|
4514
|
+
if (diffChange.originalLength === 0) {
|
|
4515
|
+
originalStartLineNumber = originalLineSequence.getStartLineNumber(diffChange.originalStart) - 1;
|
|
4516
|
+
originalEndLineNumber = 0;
|
|
4517
|
+
}
|
|
4518
|
+
else {
|
|
4519
|
+
originalStartLineNumber = originalLineSequence.getStartLineNumber(diffChange.originalStart);
|
|
4520
|
+
originalEndLineNumber = originalLineSequence.getEndLineNumber(diffChange.originalStart + diffChange.originalLength - 1);
|
|
4521
|
+
}
|
|
4522
|
+
if (diffChange.modifiedLength === 0) {
|
|
4523
|
+
modifiedStartLineNumber = modifiedLineSequence.getStartLineNumber(diffChange.modifiedStart) - 1;
|
|
4524
|
+
modifiedEndLineNumber = 0;
|
|
4525
|
+
}
|
|
4526
|
+
else {
|
|
4527
|
+
modifiedStartLineNumber = modifiedLineSequence.getStartLineNumber(diffChange.modifiedStart);
|
|
4528
|
+
modifiedEndLineNumber = modifiedLineSequence.getEndLineNumber(diffChange.modifiedStart + diffChange.modifiedLength - 1);
|
|
4529
|
+
}
|
|
4530
|
+
if (shouldComputeCharChanges && diffChange.originalLength > 0 && diffChange.originalLength < 20 && diffChange.modifiedLength > 0 && diffChange.modifiedLength < 20 && continueCharDiff()) {
|
|
4531
|
+
// Compute character changes for diff chunks of at most 20 lines...
|
|
4532
|
+
const originalCharSequence = originalLineSequence.createCharSequence(shouldIgnoreTrimWhitespace, diffChange.originalStart, diffChange.originalStart + diffChange.originalLength - 1);
|
|
4533
|
+
const modifiedCharSequence = modifiedLineSequence.createCharSequence(shouldIgnoreTrimWhitespace, diffChange.modifiedStart, diffChange.modifiedStart + diffChange.modifiedLength - 1);
|
|
4534
|
+
if (originalCharSequence.getElements().length > 0 && modifiedCharSequence.getElements().length > 0) {
|
|
4535
|
+
let rawChanges = computeDiff(originalCharSequence, modifiedCharSequence, continueCharDiff, true).changes;
|
|
4536
|
+
if (shouldPostProcessCharChanges) {
|
|
4537
|
+
rawChanges = postProcessCharChanges(rawChanges);
|
|
4538
|
+
}
|
|
4539
|
+
charChanges = [];
|
|
4540
|
+
for (let i = 0, length = rawChanges.length; i < length; i++) {
|
|
4541
|
+
charChanges.push(CharChange.createFromDiffChange(rawChanges[i], originalCharSequence, modifiedCharSequence));
|
|
4542
|
+
}
|
|
4543
|
+
}
|
|
4544
|
+
}
|
|
4545
|
+
return new LineChange(originalStartLineNumber, originalEndLineNumber, modifiedStartLineNumber, modifiedEndLineNumber, charChanges);
|
|
4546
|
+
}
|
|
4547
|
+
}
|
|
4548
|
+
class DiffComputer {
|
|
4549
|
+
constructor(originalLines, modifiedLines, opts) {
|
|
4550
|
+
this.shouldComputeCharChanges = opts.shouldComputeCharChanges;
|
|
4551
|
+
this.shouldPostProcessCharChanges = opts.shouldPostProcessCharChanges;
|
|
4552
|
+
this.shouldIgnoreTrimWhitespace = opts.shouldIgnoreTrimWhitespace;
|
|
4553
|
+
this.shouldMakePrettyDiff = opts.shouldMakePrettyDiff;
|
|
4554
|
+
this.originalLines = originalLines;
|
|
4555
|
+
this.modifiedLines = modifiedLines;
|
|
4556
|
+
this.original = new LineSequence(originalLines);
|
|
4557
|
+
this.modified = new LineSequence(modifiedLines);
|
|
4558
|
+
this.continueLineDiff = createContinueProcessingPredicate(opts.maxComputationTime);
|
|
4559
|
+
this.continueCharDiff = createContinueProcessingPredicate(opts.maxComputationTime === 0 ? 0 : Math.min(opts.maxComputationTime, 5000)); // never run after 5s for character changes...
|
|
4560
|
+
}
|
|
4561
|
+
computeDiff() {
|
|
4562
|
+
if (this.original.lines.length === 1 && this.original.lines[0].length === 0) {
|
|
4563
|
+
// empty original => fast path
|
|
4564
|
+
if (this.modified.lines.length === 1 && this.modified.lines[0].length === 0) {
|
|
4565
|
+
return {
|
|
4566
|
+
quitEarly: false,
|
|
4567
|
+
changes: []
|
|
4568
|
+
};
|
|
4569
|
+
}
|
|
4570
|
+
return {
|
|
4571
|
+
quitEarly: false,
|
|
4572
|
+
changes: [{
|
|
4573
|
+
originalStartLineNumber: 1,
|
|
4574
|
+
originalEndLineNumber: 1,
|
|
4575
|
+
modifiedStartLineNumber: 1,
|
|
4576
|
+
modifiedEndLineNumber: this.modified.lines.length,
|
|
4577
|
+
charChanges: undefined
|
|
4578
|
+
}]
|
|
4579
|
+
};
|
|
4580
|
+
}
|
|
4581
|
+
if (this.modified.lines.length === 1 && this.modified.lines[0].length === 0) {
|
|
4582
|
+
// empty modified => fast path
|
|
4583
|
+
return {
|
|
4584
|
+
quitEarly: false,
|
|
4585
|
+
changes: [{
|
|
4586
|
+
originalStartLineNumber: 1,
|
|
4587
|
+
originalEndLineNumber: this.original.lines.length,
|
|
4588
|
+
modifiedStartLineNumber: 1,
|
|
4589
|
+
modifiedEndLineNumber: 1,
|
|
4590
|
+
charChanges: undefined
|
|
4591
|
+
}]
|
|
4592
|
+
};
|
|
4593
|
+
}
|
|
4594
|
+
const diffResult = computeDiff(this.original, this.modified, this.continueLineDiff, this.shouldMakePrettyDiff);
|
|
4595
|
+
const rawChanges = diffResult.changes;
|
|
4596
|
+
const quitEarly = diffResult.quitEarly;
|
|
4597
|
+
// The diff is always computed with ignoring trim whitespace
|
|
4598
|
+
// This ensures we get the prettiest diff
|
|
4599
|
+
if (this.shouldIgnoreTrimWhitespace) {
|
|
4600
|
+
const lineChanges = [];
|
|
4601
|
+
for (let i = 0, length = rawChanges.length; i < length; i++) {
|
|
4602
|
+
lineChanges.push(LineChange.createFromDiffResult(this.shouldIgnoreTrimWhitespace, rawChanges[i], this.original, this.modified, this.continueCharDiff, this.shouldComputeCharChanges, this.shouldPostProcessCharChanges));
|
|
4603
|
+
}
|
|
4604
|
+
return {
|
|
4605
|
+
quitEarly: quitEarly,
|
|
4606
|
+
changes: lineChanges
|
|
4607
|
+
};
|
|
4608
|
+
}
|
|
4609
|
+
// Need to post-process and introduce changes where the trim whitespace is different
|
|
4610
|
+
// Note that we are looping starting at -1 to also cover the lines before the first change
|
|
4611
|
+
const result = [];
|
|
4612
|
+
let originalLineIndex = 0;
|
|
4613
|
+
let modifiedLineIndex = 0;
|
|
4614
|
+
for (let i = -1 /* !!!! */, len = rawChanges.length; i < len; i++) {
|
|
4615
|
+
const nextChange = (i + 1 < len ? rawChanges[i + 1] : null);
|
|
4616
|
+
const originalStop = (nextChange ? nextChange.originalStart : this.originalLines.length);
|
|
4617
|
+
const modifiedStop = (nextChange ? nextChange.modifiedStart : this.modifiedLines.length);
|
|
4618
|
+
while (originalLineIndex < originalStop && modifiedLineIndex < modifiedStop) {
|
|
4619
|
+
const originalLine = this.originalLines[originalLineIndex];
|
|
4620
|
+
const modifiedLine = this.modifiedLines[modifiedLineIndex];
|
|
4621
|
+
if (originalLine !== modifiedLine) {
|
|
4622
|
+
// These lines differ only in trim whitespace
|
|
4623
|
+
// Check the leading whitespace
|
|
4624
|
+
{
|
|
4625
|
+
let originalStartColumn = getFirstNonBlankColumn(originalLine, 1);
|
|
4626
|
+
let modifiedStartColumn = getFirstNonBlankColumn(modifiedLine, 1);
|
|
4627
|
+
while (originalStartColumn > 1 && modifiedStartColumn > 1) {
|
|
4628
|
+
const originalChar = originalLine.charCodeAt(originalStartColumn - 2);
|
|
4629
|
+
const modifiedChar = modifiedLine.charCodeAt(modifiedStartColumn - 2);
|
|
4630
|
+
if (originalChar !== modifiedChar) {
|
|
4631
|
+
break;
|
|
4632
|
+
}
|
|
4633
|
+
originalStartColumn--;
|
|
4634
|
+
modifiedStartColumn--;
|
|
4635
|
+
}
|
|
4636
|
+
if (originalStartColumn > 1 || modifiedStartColumn > 1) {
|
|
4637
|
+
this._pushTrimWhitespaceCharChange(result, originalLineIndex + 1, 1, originalStartColumn, modifiedLineIndex + 1, 1, modifiedStartColumn);
|
|
4638
|
+
}
|
|
4639
|
+
}
|
|
4640
|
+
// Check the trailing whitespace
|
|
4641
|
+
{
|
|
4642
|
+
let originalEndColumn = getLastNonBlankColumn(originalLine, 1);
|
|
4643
|
+
let modifiedEndColumn = getLastNonBlankColumn(modifiedLine, 1);
|
|
4644
|
+
const originalMaxColumn = originalLine.length + 1;
|
|
4645
|
+
const modifiedMaxColumn = modifiedLine.length + 1;
|
|
4646
|
+
while (originalEndColumn < originalMaxColumn && modifiedEndColumn < modifiedMaxColumn) {
|
|
4647
|
+
const originalChar = originalLine.charCodeAt(originalEndColumn - 1);
|
|
4648
|
+
const modifiedChar = originalLine.charCodeAt(modifiedEndColumn - 1);
|
|
4649
|
+
if (originalChar !== modifiedChar) {
|
|
4650
|
+
break;
|
|
4651
|
+
}
|
|
4652
|
+
originalEndColumn++;
|
|
4653
|
+
modifiedEndColumn++;
|
|
4654
|
+
}
|
|
4655
|
+
if (originalEndColumn < originalMaxColumn || modifiedEndColumn < modifiedMaxColumn) {
|
|
4656
|
+
this._pushTrimWhitespaceCharChange(result, originalLineIndex + 1, originalEndColumn, originalMaxColumn, modifiedLineIndex + 1, modifiedEndColumn, modifiedMaxColumn);
|
|
4657
|
+
}
|
|
4658
|
+
}
|
|
4659
|
+
}
|
|
4660
|
+
originalLineIndex++;
|
|
4661
|
+
modifiedLineIndex++;
|
|
4662
|
+
}
|
|
4663
|
+
if (nextChange) {
|
|
4664
|
+
// Emit the actual change
|
|
4665
|
+
result.push(LineChange.createFromDiffResult(this.shouldIgnoreTrimWhitespace, nextChange, this.original, this.modified, this.continueCharDiff, this.shouldComputeCharChanges, this.shouldPostProcessCharChanges));
|
|
4666
|
+
originalLineIndex += nextChange.originalLength;
|
|
4667
|
+
modifiedLineIndex += nextChange.modifiedLength;
|
|
4668
|
+
}
|
|
4669
|
+
}
|
|
4670
|
+
return {
|
|
4671
|
+
quitEarly: quitEarly,
|
|
4672
|
+
changes: result
|
|
4673
|
+
};
|
|
4674
|
+
}
|
|
4675
|
+
_pushTrimWhitespaceCharChange(result, originalLineNumber, originalStartColumn, originalEndColumn, modifiedLineNumber, modifiedStartColumn, modifiedEndColumn) {
|
|
4676
|
+
if (this._mergeTrimWhitespaceCharChange(result, originalLineNumber, originalStartColumn, originalEndColumn, modifiedLineNumber, modifiedStartColumn, modifiedEndColumn)) {
|
|
4677
|
+
// Merged into previous
|
|
4678
|
+
return;
|
|
4679
|
+
}
|
|
4680
|
+
let charChanges = undefined;
|
|
4681
|
+
if (this.shouldComputeCharChanges) {
|
|
4682
|
+
charChanges = [new CharChange(originalLineNumber, originalStartColumn, originalLineNumber, originalEndColumn, modifiedLineNumber, modifiedStartColumn, modifiedLineNumber, modifiedEndColumn)];
|
|
4683
|
+
}
|
|
4684
|
+
result.push(new LineChange(originalLineNumber, originalLineNumber, modifiedLineNumber, modifiedLineNumber, charChanges));
|
|
4685
|
+
}
|
|
4686
|
+
_mergeTrimWhitespaceCharChange(result, originalLineNumber, originalStartColumn, originalEndColumn, modifiedLineNumber, modifiedStartColumn, modifiedEndColumn) {
|
|
4687
|
+
const len = result.length;
|
|
4688
|
+
if (len === 0) {
|
|
4689
|
+
return false;
|
|
4690
|
+
}
|
|
4691
|
+
const prevChange = result[len - 1];
|
|
4692
|
+
if (prevChange.originalEndLineNumber === 0 || prevChange.modifiedEndLineNumber === 0) {
|
|
4693
|
+
// Don't merge with inserts/deletes
|
|
4694
|
+
return false;
|
|
4695
|
+
}
|
|
4696
|
+
if (prevChange.originalEndLineNumber === originalLineNumber && prevChange.modifiedEndLineNumber === modifiedLineNumber) {
|
|
4697
|
+
if (this.shouldComputeCharChanges && prevChange.charChanges) {
|
|
4698
|
+
prevChange.charChanges.push(new CharChange(originalLineNumber, originalStartColumn, originalLineNumber, originalEndColumn, modifiedLineNumber, modifiedStartColumn, modifiedLineNumber, modifiedEndColumn));
|
|
4699
|
+
}
|
|
4700
|
+
return true;
|
|
4701
|
+
}
|
|
4702
|
+
if (prevChange.originalEndLineNumber + 1 === originalLineNumber && prevChange.modifiedEndLineNumber + 1 === modifiedLineNumber) {
|
|
4703
|
+
prevChange.originalEndLineNumber = originalLineNumber;
|
|
4704
|
+
prevChange.modifiedEndLineNumber = modifiedLineNumber;
|
|
4705
|
+
if (this.shouldComputeCharChanges && prevChange.charChanges) {
|
|
4706
|
+
prevChange.charChanges.push(new CharChange(originalLineNumber, originalStartColumn, originalLineNumber, originalEndColumn, modifiedLineNumber, modifiedStartColumn, modifiedLineNumber, modifiedEndColumn));
|
|
4707
|
+
}
|
|
4708
|
+
return true;
|
|
4709
|
+
}
|
|
4710
|
+
return false;
|
|
4711
|
+
}
|
|
4712
|
+
}
|
|
4713
|
+
exports.DiffComputer = DiffComputer;
|
|
4714
|
+
function getFirstNonBlankColumn(txt, defaultValue) {
|
|
4715
|
+
const r = strings.firstNonWhitespaceIndex(txt);
|
|
4716
|
+
if (r === -1) {
|
|
4717
|
+
return defaultValue;
|
|
4718
|
+
}
|
|
4719
|
+
return r + 1;
|
|
4720
|
+
}
|
|
4721
|
+
function getLastNonBlankColumn(txt, defaultValue) {
|
|
4722
|
+
const r = strings.lastNonWhitespaceIndex(txt);
|
|
4723
|
+
if (r === -1) {
|
|
4724
|
+
return defaultValue;
|
|
4725
|
+
}
|
|
4726
|
+
return r + 2;
|
|
4727
|
+
}
|
|
4728
|
+
function createContinueProcessingPredicate(maximumRuntime) {
|
|
4729
|
+
if (maximumRuntime === 0) {
|
|
4730
|
+
return () => true;
|
|
4731
|
+
}
|
|
4732
|
+
const startTime = Date.now();
|
|
4733
|
+
return () => {
|
|
4734
|
+
return Date.now() - startTime < maximumRuntime;
|
|
4735
|
+
};
|
|
4736
|
+
}
|
|
4737
|
+
|
|
4738
|
+
|
|
4739
|
+
/***/ }),
|
|
4740
|
+
|
|
4741
|
+
/***/ "./node_modules/vscode-diff/dist/vs/editor/common/diff/linesDiffComputer.js":
|
|
4742
|
+
/*!**********************************************************************************!*\
|
|
4743
|
+
!*** ./node_modules/vscode-diff/dist/vs/editor/common/diff/linesDiffComputer.js ***!
|
|
4744
|
+
\**********************************************************************************/
|
|
4745
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
4746
|
+
|
|
4747
|
+
|
|
4748
|
+
/*---------------------------------------------------------------------------------------------
|
|
4749
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
4750
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
4751
|
+
*--------------------------------------------------------------------------------------------*/
|
|
4752
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
4753
|
+
exports.MovedText = exports.SimpleLineRangeMapping = exports.RangeMapping = exports.LineRangeMapping = exports.LinesDiff = void 0;
|
|
4754
|
+
const lineRange_1 = __webpack_require__(/*! ../core/lineRange */ "./node_modules/vscode-diff/dist/vs/editor/common/core/lineRange.js");
|
|
4755
|
+
class LinesDiff {
|
|
4756
|
+
constructor(changes,
|
|
4757
|
+
/**
|
|
4758
|
+
* Sorted by original line ranges.
|
|
4759
|
+
* The original line ranges and the modified line ranges must be disjoint (but can be touching).
|
|
4760
|
+
*/
|
|
4761
|
+
moves,
|
|
4762
|
+
/**
|
|
4763
|
+
* Indicates if the time out was reached.
|
|
4764
|
+
* In that case, the diffs might be an approximation and the user should be asked to rerun the diff with more time.
|
|
4765
|
+
*/
|
|
4766
|
+
hitTimeout) {
|
|
4767
|
+
this.changes = changes;
|
|
4768
|
+
this.moves = moves;
|
|
4769
|
+
this.hitTimeout = hitTimeout;
|
|
4770
|
+
}
|
|
4771
|
+
}
|
|
4772
|
+
exports.LinesDiff = LinesDiff;
|
|
4773
|
+
/**
|
|
4774
|
+
* Maps a line range in the original text model to a line range in the modified text model.
|
|
4775
|
+
*/
|
|
4776
|
+
class LineRangeMapping {
|
|
4777
|
+
static inverse(mapping, originalLineCount, modifiedLineCount) {
|
|
4778
|
+
const result = [];
|
|
4779
|
+
let lastOriginalEndLineNumber = 1;
|
|
4780
|
+
let lastModifiedEndLineNumber = 1;
|
|
4781
|
+
for (const m of mapping) {
|
|
4782
|
+
const r = new LineRangeMapping(new lineRange_1.LineRange(lastOriginalEndLineNumber, m.originalRange.startLineNumber), new lineRange_1.LineRange(lastModifiedEndLineNumber, m.modifiedRange.startLineNumber), undefined);
|
|
4783
|
+
if (!r.modifiedRange.isEmpty) {
|
|
4784
|
+
result.push(r);
|
|
4785
|
+
}
|
|
4786
|
+
lastOriginalEndLineNumber = m.originalRange.endLineNumberExclusive;
|
|
4787
|
+
lastModifiedEndLineNumber = m.modifiedRange.endLineNumberExclusive;
|
|
4788
|
+
}
|
|
4789
|
+
const r = new LineRangeMapping(new lineRange_1.LineRange(lastOriginalEndLineNumber, originalLineCount + 1), new lineRange_1.LineRange(lastModifiedEndLineNumber, modifiedLineCount + 1), undefined);
|
|
4790
|
+
if (!r.modifiedRange.isEmpty) {
|
|
4791
|
+
result.push(r);
|
|
4792
|
+
}
|
|
4793
|
+
return result;
|
|
4794
|
+
}
|
|
4795
|
+
constructor(originalRange, modifiedRange, innerChanges) {
|
|
4796
|
+
this.originalRange = originalRange;
|
|
4797
|
+
this.modifiedRange = modifiedRange;
|
|
4798
|
+
this.innerChanges = innerChanges;
|
|
4799
|
+
}
|
|
4800
|
+
toString() {
|
|
4801
|
+
return `{${this.originalRange.toString()}->${this.modifiedRange.toString()}}`;
|
|
4802
|
+
}
|
|
4803
|
+
get changedLineCount() {
|
|
4804
|
+
return Math.max(this.originalRange.length, this.modifiedRange.length);
|
|
4805
|
+
}
|
|
4806
|
+
flip() {
|
|
4807
|
+
return new LineRangeMapping(this.modifiedRange, this.originalRange, this.innerChanges?.map(c => c.flip()));
|
|
4808
|
+
}
|
|
4809
|
+
}
|
|
4810
|
+
exports.LineRangeMapping = LineRangeMapping;
|
|
4811
|
+
/**
|
|
4812
|
+
* Maps a range in the original text model to a range in the modified text model.
|
|
4813
|
+
*/
|
|
4814
|
+
class RangeMapping {
|
|
4815
|
+
constructor(originalRange, modifiedRange) {
|
|
4816
|
+
this.originalRange = originalRange;
|
|
4817
|
+
this.modifiedRange = modifiedRange;
|
|
4818
|
+
}
|
|
4819
|
+
toString() {
|
|
4820
|
+
return `{${this.originalRange.toString()}->${this.modifiedRange.toString()}}`;
|
|
4821
|
+
}
|
|
4822
|
+
flip() {
|
|
4823
|
+
return new RangeMapping(this.modifiedRange, this.originalRange);
|
|
4824
|
+
}
|
|
4825
|
+
}
|
|
4826
|
+
exports.RangeMapping = RangeMapping;
|
|
4827
|
+
// TODO@hediet: Make LineRangeMapping extend from this!
|
|
4828
|
+
class SimpleLineRangeMapping {
|
|
4829
|
+
constructor(original, modified) {
|
|
4830
|
+
this.original = original;
|
|
4831
|
+
this.modified = modified;
|
|
4832
|
+
}
|
|
4833
|
+
toString() {
|
|
4834
|
+
return `{${this.original.toString()}->${this.modified.toString()}}`;
|
|
4835
|
+
}
|
|
4836
|
+
flip() {
|
|
4837
|
+
return new SimpleLineRangeMapping(this.modified, this.original);
|
|
4838
|
+
}
|
|
4839
|
+
join(other) {
|
|
4840
|
+
return new SimpleLineRangeMapping(this.original.join(other.original), this.modified.join(other.modified));
|
|
4841
|
+
}
|
|
4842
|
+
}
|
|
4843
|
+
exports.SimpleLineRangeMapping = SimpleLineRangeMapping;
|
|
4844
|
+
class MovedText {
|
|
4845
|
+
constructor(lineRangeMapping, changes) {
|
|
4846
|
+
this.lineRangeMapping = lineRangeMapping;
|
|
4847
|
+
this.changes = changes;
|
|
4848
|
+
}
|
|
4849
|
+
flip() {
|
|
4850
|
+
return new MovedText(this.lineRangeMapping.flip(), this.changes.map(c => c.flip()));
|
|
4851
|
+
}
|
|
4852
|
+
}
|
|
4853
|
+
exports.MovedText = MovedText;
|
|
4854
|
+
|
|
4855
|
+
|
|
4856
|
+
/***/ })
|
|
4857
|
+
|
|
4858
|
+
}]);
|
|
4859
|
+
//# sourceMappingURL=vendors-node_modules_vscode-diff_dist_index_js.ea55f1f9346638aafbcf.js.map
|