setta 0.0.1__py3-none-any.whl → 0.0.2__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- setta/__init__.py +1 -1
- setta/cli/__init__.py +1 -0
- setta/cli/connect.py +43 -0
- setta/cli/logger.py +225 -0
- setta/code_gen/__init__.py +0 -0
- setta/code_gen/create_runnable_scripts.py +466 -0
- setta/code_gen/export_selected.py +776 -0
- setta/code_gen/find_placeholders.py +13 -0
- setta/code_gen/python/__init__.py +0 -0
- setta/code_gen/python/ast_utils.py +183 -0
- setta/code_gen/python/check_scope.py +187 -0
- setta/code_gen/python/generate_code.py +280 -0
- setta/code_gen/python/make_parseable.py +97 -0
- setta/code_gen/python/position_line_col.py +33 -0
- setta/code_gen/python/validate_imports.py +87 -0
- setta/code_gen/utils.py +120 -0
- setta/code_gen/yaml/__init__.py +0 -0
- setta/code_gen/yaml/generate_yaml.py +23 -0
- setta/code_gen/yaml/section_dict.py +93 -0
- setta/database/__init__.py +0 -0
- setta/database/backup.py +80 -0
- setta/database/db/__init__.py +0 -0
- setta/database/db/artifacts/__init__.py +0 -0
- setta/database/db/artifacts/load.py +93 -0
- setta/database/db/artifacts/save.py +85 -0
- setta/database/db/artifacts/save_or_create.py +68 -0
- setta/database/db/artifacts/utils.py +13 -0
- setta/database/db/codeInfo/__init__.py +0 -0
- setta/database/db/codeInfo/copy.py +26 -0
- setta/database/db/codeInfo/load.py +65 -0
- setta/database/db/codeInfo/save.py +75 -0
- setta/database/db/codeInfo/utils.py +33 -0
- setta/database/db/evRefs/__init__.py +0 -0
- setta/database/db/evRefs/load.py +45 -0
- setta/database/db/evRefs/save.py +95 -0
- setta/database/db/projects/__init__.py +0 -0
- setta/database/db/projects/copy.py +36 -0
- setta/database/db/projects/delete.py +7 -0
- setta/database/db/projects/load.py +184 -0
- setta/database/db/projects/save.py +267 -0
- setta/database/db/projects/saveAs.py +40 -0
- setta/database/db/projects/utils.py +135 -0
- setta/database/db/sectionVariants/__init__.py +0 -0
- setta/database/db/sectionVariants/copy.py +28 -0
- setta/database/db/sectionVariants/load.py +139 -0
- setta/database/db/sectionVariants/save.py +140 -0
- setta/database/db/sectionVariants/utils.py +44 -0
- setta/database/db/sections/__init__.py +0 -0
- setta/database/db/sections/copy.py +70 -0
- setta/database/db/sections/jsonSource.py +119 -0
- setta/database/db/sections/load.py +350 -0
- setta/database/db/sections/save.py +204 -0
- setta/database/db/sections/utils.py +13 -0
- setta/database/db/uiTypes/__init__.py +0 -0
- setta/database/db/uiTypes/copy.py +33 -0
- setta/database/db/uiTypes/load.py +51 -0
- setta/database/db/uiTypes/save.py +99 -0
- setta/database/db/uiTypes/utils.py +27 -0
- setta/database/db_init.py +36 -0
- setta/database/db_objs.py +102 -0
- setta/database/db_path.py +8 -0
- setta/database/export_db/__init__.py +0 -0
- setta/database/export_db/export_db.py +43 -0
- setta/database/export_db/export_raw.py +53 -0
- setta/database/export_db/export_readable.py +242 -0
- setta/database/export_db/utils.py +16 -0
- setta/database/import_db.py +28 -0
- setta/database/seed.py +41 -0
- setta/database/settings_file.py +118 -0
- setta/database/utils.py +32 -0
- setta/lsp/__init__.py +0 -0
- setta/lsp/file_watcher.py +113 -0
- setta/lsp/reader.py +184 -0
- setta/lsp/reader_fns/__init__.py +0 -0
- setta/lsp/reader_fns/completion.py +84 -0
- setta/lsp/reader_fns/definition.py +2 -0
- setta/lsp/reader_fns/diagnostics.py +99 -0
- setta/lsp/reader_fns/documentHighlight.py +25 -0
- setta/lsp/reader_fns/references.py +34 -0
- setta/lsp/reader_fns/signatureHelp.py +99 -0
- setta/lsp/server.py +150 -0
- setta/lsp/utils.py +60 -0
- setta/lsp/writer.py +306 -0
- setta/routers/__init__.py +11 -0
- setta/routers/artifact.py +105 -0
- setta/routers/code_info.py +32 -0
- setta/routers/dependencies.py +49 -0
- setta/routers/in_memory_fn_stdout_websocket.py +21 -0
- setta/routers/interactive.py +119 -0
- setta/routers/lsp.py +14 -0
- setta/routers/projects.py +188 -0
- setta/routers/reference_renaming.py +111 -0
- setta/routers/sections.py +174 -0
- setta/routers/settings.py +40 -0
- setta/routers/terminals.py +83 -0
- setta/routers/websocket.py +36 -0
- setta/server.py +141 -0
- setta/start.py +112 -0
- setta/static/constants/BaseUITypes.json +153 -0
- setta/static/constants/Settings.json +113 -0
- setta/static/constants/constants.json +117 -0
- setta/static/constants/db_init.sql +249 -0
- setta/static/constants/defaultValues.json +125 -0
- setta/static/constants/settingsProject.json +276 -0
- setta/static/frontend/android-chrome-192x192.png +0 -0
- setta/static/frontend/android-chrome-512x512.png +0 -0
- setta/static/frontend/apple-touch-icon.png +0 -0
- setta/static/frontend/assets/KaTeX_AMS-Regular-0cdd387c.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_AMS-Regular-30da91e8.woff +0 -0
- setta/static/frontend/assets/KaTeX_AMS-Regular-68534840.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Caligraphic-Bold-07d8e303.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Caligraphic-Bold-1ae6bd74.woff +0 -0
- setta/static/frontend/assets/KaTeX_Caligraphic-Bold-de7701e4.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Caligraphic-Regular-3398dd02.woff +0 -0
- setta/static/frontend/assets/KaTeX_Caligraphic-Regular-5d53e70a.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Caligraphic-Regular-ed0b7437.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Fraktur-Bold-74444efd.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Fraktur-Bold-9163df9c.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Fraktur-Bold-9be7ceb8.woff +0 -0
- setta/static/frontend/assets/KaTeX_Fraktur-Regular-1e6f9579.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Fraktur-Regular-51814d27.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Fraktur-Regular-5e28753b.woff +0 -0
- setta/static/frontend/assets/KaTeX_Main-Bold-0f60d1b8.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Main-Bold-138ac28d.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Main-Bold-c76c5d69.woff +0 -0
- setta/static/frontend/assets/KaTeX_Main-BoldItalic-70ee1f64.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Main-BoldItalic-99cd42a3.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Main-BoldItalic-a6f7ec0d.woff +0 -0
- setta/static/frontend/assets/KaTeX_Main-Italic-0d85ae7c.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Main-Italic-97479ca6.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Main-Italic-f1d6ef86.woff +0 -0
- setta/static/frontend/assets/KaTeX_Main-Regular-c2342cd8.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Main-Regular-c6368d87.woff +0 -0
- setta/static/frontend/assets/KaTeX_Main-Regular-d0332f52.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Math-BoldItalic-850c0af5.woff +0 -0
- setta/static/frontend/assets/KaTeX_Math-BoldItalic-dc47344d.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Math-BoldItalic-f9377ab0.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Math-Italic-08ce98e5.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Math-Italic-7af58c5e.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Math-Italic-8a8d2445.woff +0 -0
- setta/static/frontend/assets/KaTeX_SansSerif-Bold-1ece03f7.ttf +0 -0
- setta/static/frontend/assets/KaTeX_SansSerif-Bold-e99ae511.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_SansSerif-Bold-ece03cfd.woff +0 -0
- setta/static/frontend/assets/KaTeX_SansSerif-Italic-00b26ac8.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_SansSerif-Italic-3931dd81.ttf +0 -0
- setta/static/frontend/assets/KaTeX_SansSerif-Italic-91ee6750.woff +0 -0
- setta/static/frontend/assets/KaTeX_SansSerif-Regular-11e4dc8a.woff +0 -0
- setta/static/frontend/assets/KaTeX_SansSerif-Regular-68e8c73e.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_SansSerif-Regular-f36ea897.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Script-Regular-036d4e95.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Script-Regular-1c67f068.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Script-Regular-d96cdf2b.woff +0 -0
- setta/static/frontend/assets/KaTeX_Size1-Regular-6b47c401.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Size1-Regular-95b6d2f1.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Size1-Regular-c943cc98.woff +0 -0
- setta/static/frontend/assets/KaTeX_Size2-Regular-2014c523.woff +0 -0
- setta/static/frontend/assets/KaTeX_Size2-Regular-a6b2099f.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Size2-Regular-d04c5421.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Size3-Regular-500e04d5.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Size3-Regular-6ab6b62e.woff +0 -0
- setta/static/frontend/assets/KaTeX_Size4-Regular-99f9c675.woff +0 -0
- setta/static/frontend/assets/KaTeX_Size4-Regular-a4af7d41.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Size4-Regular-c647367d.ttf +0 -0
- setta/static/frontend/assets/KaTeX_Typewriter-Regular-71d517d6.woff2 +0 -0
- setta/static/frontend/assets/KaTeX_Typewriter-Regular-e14fed02.woff +0 -0
- setta/static/frontend/assets/KaTeX_Typewriter-Regular-f01f3e87.ttf +0 -0
- setta/static/frontend/assets/cormorant-garamond-all-700-italic-c9b58582.woff +0 -0
- setta/static/frontend/assets/cormorant-garamond-cyrillic-700-italic-9101ad5f.woff2 +0 -0
- setta/static/frontend/assets/cormorant-garamond-cyrillic-ext-700-italic-950de0d6.woff2 +0 -0
- setta/static/frontend/assets/cormorant-garamond-latin-700-italic-0bc53e12.woff2 +0 -0
- setta/static/frontend/assets/cormorant-garamond-latin-ext-700-italic-525738e0.woff2 +0 -0
- setta/static/frontend/assets/cormorant-garamond-vietnamese-700-italic-99563037.woff2 +0 -0
- setta/static/frontend/assets/erase-5e0448ea.svg +15 -0
- setta/static/frontend/assets/index-1d4b4ecf.css +32 -0
- setta/static/frontend/assets/index-ee99dc72.js +678 -0
- setta/static/frontend/assets/inter-all-400-normal-054f12d0.woff +0 -0
- setta/static/frontend/assets/inter-all-600-normal-c03769e5.woff +0 -0
- setta/static/frontend/assets/inter-all-800-normal-15dc6e4b.woff +0 -0
- setta/static/frontend/assets/inter-cyrillic-400-normal-a4eee61a.woff2 +0 -0
- setta/static/frontend/assets/inter-cyrillic-600-normal-8b14f703.woff2 +0 -0
- setta/static/frontend/assets/inter-cyrillic-800-normal-e706eaaa.woff2 +0 -0
- setta/static/frontend/assets/inter-cyrillic-ext-400-normal-70047a3b.woff2 +0 -0
- setta/static/frontend/assets/inter-cyrillic-ext-600-normal-d4ab9bc4.woff2 +0 -0
- setta/static/frontend/assets/inter-cyrillic-ext-800-normal-eae7515a.woff2 +0 -0
- setta/static/frontend/assets/inter-greek-400-normal-381ea30d.woff2 +0 -0
- setta/static/frontend/assets/inter-greek-600-normal-601f93a2.woff2 +0 -0
- setta/static/frontend/assets/inter-greek-800-normal-7af4fb64.woff2 +0 -0
- setta/static/frontend/assets/inter-greek-ext-400-normal-27027b17.woff2 +0 -0
- setta/static/frontend/assets/inter-greek-ext-600-normal-f2ddf9de.woff2 +0 -0
- setta/static/frontend/assets/inter-greek-ext-800-normal-4cb6189e.woff2 +0 -0
- setta/static/frontend/assets/inter-latin-400-normal-d56fec21.woff2 +0 -0
- setta/static/frontend/assets/inter-latin-600-normal-ff769fa6.woff2 +0 -0
- setta/static/frontend/assets/inter-latin-800-normal-5eea1309.woff2 +0 -0
- setta/static/frontend/assets/inter-latin-ext-400-normal-bb698d85.woff2 +0 -0
- setta/static/frontend/assets/inter-latin-ext-600-normal-ca4808f9.woff2 +0 -0
- setta/static/frontend/assets/inter-latin-ext-800-normal-ebdacc0f.woff2 +0 -0
- setta/static/frontend/assets/logo/logo.svg +8 -0
- setta/static/frontend/assets/pen-455d7d8a.svg +19 -0
- setta/static/frontend/assets/source-code-pro-all-500-normal-6bdaa03b.woff +0 -0
- setta/static/frontend/assets/source-code-pro-cyrillic-500-normal-288a0d68.woff2 +0 -0
- setta/static/frontend/assets/source-code-pro-cyrillic-ext-500-normal-b110a13b.woff2 +0 -0
- setta/static/frontend/assets/source-code-pro-greek-500-normal-04328acb.woff2 +0 -0
- setta/static/frontend/assets/source-code-pro-latin-500-normal-06edef1e.woff2 +0 -0
- setta/static/frontend/assets/source-code-pro-latin-ext-500-normal-6dc60d5e.woff2 +0 -0
- setta/static/frontend/assets/web-vitals-44a8e082.js +1 -0
- setta/static/frontend/assets/work-sans-all-400-normal-38034a3c.woff +0 -0
- setta/static/frontend/assets/work-sans-all-500-normal-550d64e5.woff +0 -0
- setta/static/frontend/assets/work-sans-all-600-normal-ccf14060.woff +0 -0
- setta/static/frontend/assets/work-sans-all-700-normal-494c2971.woff +0 -0
- setta/static/frontend/assets/work-sans-latin-400-normal-36735bc1.woff2 +0 -0
- setta/static/frontend/assets/work-sans-latin-500-normal-3790bfda.woff2 +0 -0
- setta/static/frontend/assets/work-sans-latin-600-normal-5fba494e.woff2 +0 -0
- setta/static/frontend/assets/work-sans-latin-700-normal-a5033d0a.woff2 +0 -0
- setta/static/frontend/assets/work-sans-latin-ext-400-normal-c20f571a.woff2 +0 -0
- setta/static/frontend/assets/work-sans-latin-ext-500-normal-0f5ac96c.woff2 +0 -0
- setta/static/frontend/assets/work-sans-latin-ext-600-normal-97a237d1.woff2 +0 -0
- setta/static/frontend/assets/work-sans-latin-ext-700-normal-103e112c.woff2 +0 -0
- setta/static/frontend/browserconfig.xml +9 -0
- setta/static/frontend/favicon-16x16.png +0 -0
- setta/static/frontend/favicon-32x32.png +0 -0
- setta/static/frontend/favicon.ico +0 -0
- setta/static/frontend/index.html +30 -0
- setta/static/frontend/manifest.json +25 -0
- setta/static/frontend/mstile-144x144.png +0 -0
- setta/static/frontend/mstile-150x150.png +0 -0
- setta/static/frontend/mstile-310x150.png +0 -0
- setta/static/frontend/mstile-310x310.png +0 -0
- setta/static/frontend/mstile-70x70.png +0 -0
- setta/static/frontend/robots.txt +3 -0
- setta/static/frontend/safari-pinned-tab.svg +18 -0
- setta/static/frontend/site.webmanifest +19 -0
- setta/static/seed/.DS_Store +0 -0
- setta/static/seed/examples/.DS_Store +0 -0
- setta/tasks/__init__.py +0 -0
- setta/tasks/fns/__init__.py +9 -0
- setta/tasks/fns/codeAreaAutocomplete.py +209 -0
- setta/tasks/fns/codeAreaFindTemplateVars.py +128 -0
- setta/tasks/fns/codeAreaInitializeCode.py +98 -0
- setta/tasks/fns/findEVRefs.py +236 -0
- setta/tasks/fns/parametersRequest.py +71 -0
- setta/tasks/fns/textFieldAutocomplete.py +210 -0
- setta/tasks/fns/textFieldInitializeCode.py +99 -0
- setta/tasks/fns/typeCheck.py +40 -0
- setta/tasks/fns/utils.py +134 -0
- setta/tasks/task_runner.py +29 -0
- setta/tasks/tasks.py +152 -0
- setta/tasks/utils.py +178 -0
- setta/terminals/__init__.py +0 -0
- setta/terminals/terminals.py +242 -0
- setta/terminals/utils.py +37 -0
- setta/utils/__init__.py +0 -0
- setta/utils/constants.py +148 -0
- setta/utils/generate_memorable_string.py +431 -0
- setta/utils/generate_new_filename.py +80 -0
- setta/utils/section_contents.py +133 -0
- setta/utils/utils.py +271 -0
- setta/utils/websocket_manager.py +91 -0
- setta-0.0.2.dist-info/LICENSE +201 -0
- setta-0.0.2.dist-info/METADATA +24 -0
- setta-0.0.2.dist-info/RECORD +263 -0
- {setta-0.0.1.dist-info → setta-0.0.2.dist-info}/WHEEL +1 -1
- setta-0.0.2.dist-info/entry_points.txt +2 -0
- setta-0.0.1.dist-info/METADATA +0 -18
- setta-0.0.1.dist-info/RECORD +0 -5
- {setta-0.0.1.dist-info → setta-0.0.2.dist-info}/top_level.txt +0 -0
setta/database/seed.py
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
import glob
|
2
|
+
import json
|
3
|
+
|
4
|
+
from setta.database.db.projects.utils import add_defaults_to_project
|
5
|
+
from setta.utils.constants import BASE_UI_TYPES, SEED_FOLDER
|
6
|
+
from setta.utils.utils import get_absolute_path
|
7
|
+
|
8
|
+
from .db.projects.save import save_project_details
|
9
|
+
from .db.uiTypes.save import save_ui_types
|
10
|
+
|
11
|
+
|
12
|
+
def seed_base_ui_types(db):
|
13
|
+
save_ui_types(db, BASE_UI_TYPES)
|
14
|
+
|
15
|
+
|
16
|
+
def seed_examples(db):
|
17
|
+
example_jsons = glob.glob(
|
18
|
+
str(get_absolute_path(__file__, SEED_FOLDER / "examples/**/*.json"))
|
19
|
+
)
|
20
|
+
for filepath in example_jsons:
|
21
|
+
# if (
|
22
|
+
# "reviews" not in filepath
|
23
|
+
# and "medical" not in filepath
|
24
|
+
# and "financial" not in filepath
|
25
|
+
# ):
|
26
|
+
# continue
|
27
|
+
# if "hf" not in filepath:
|
28
|
+
# continue
|
29
|
+
# if "img_to_img" not in filepath:
|
30
|
+
# continue
|
31
|
+
with open(filepath, "r") as f:
|
32
|
+
data = json.load(f)
|
33
|
+
add_defaults_to_project(data) # json files don't have all the defaults
|
34
|
+
save_project_details(db, data)
|
35
|
+
|
36
|
+
|
37
|
+
def seed(db, with_examples=False, with_base_ui_types=False):
|
38
|
+
if with_base_ui_types:
|
39
|
+
seed_base_ui_types(db)
|
40
|
+
if with_examples:
|
41
|
+
seed_examples(db)
|
@@ -0,0 +1,118 @@
|
|
1
|
+
import json
|
2
|
+
import logging
|
3
|
+
import os
|
4
|
+
|
5
|
+
from setta.code_gen.export_selected import get_selected_section_variant
|
6
|
+
from setta.database.db.projects.utils import (
|
7
|
+
add_defaults_to_project_and_load_json_sources,
|
8
|
+
filter_data_for_json_export,
|
9
|
+
)
|
10
|
+
from setta.database.db.sections.jsonSource import (
|
11
|
+
remove_json_source_data,
|
12
|
+
save_json_source_data,
|
13
|
+
)
|
14
|
+
from setta.utils.constants import CONSTANTS_FOLDER, USER_SETTINGS
|
15
|
+
from setta.utils.utils import get_absolute_path, save_json_to_file
|
16
|
+
|
17
|
+
logger = logging.getLogger(__name__)
|
18
|
+
|
19
|
+
|
20
|
+
class SettingsFile:
|
21
|
+
def __init__(self):
|
22
|
+
self.meta_settings_file = MetaSettingsFile()
|
23
|
+
self.load_settings()
|
24
|
+
|
25
|
+
def save_settings(self, settings):
|
26
|
+
logger.debug("Saving settings")
|
27
|
+
paths = self.meta_settings_file.get_settings_paths()
|
28
|
+
to_be_saved = {}
|
29
|
+
for settings_slice, path in paths.items():
|
30
|
+
if path not in to_be_saved:
|
31
|
+
to_be_saved[path] = {}
|
32
|
+
to_be_saved[path].update({settings_slice: settings[settings_slice]})
|
33
|
+
|
34
|
+
for filename, data in to_be_saved.items():
|
35
|
+
save_json_to_file(filename, data)
|
36
|
+
|
37
|
+
USER_SETTINGS.update(settings)
|
38
|
+
|
39
|
+
def load_settings(self):
|
40
|
+
logger.debug("Loading settings")
|
41
|
+
paths = self.meta_settings_file.get_settings_paths()
|
42
|
+
output = {}
|
43
|
+
for settings_slice, path in paths.items():
|
44
|
+
with open(path, "r") as f:
|
45
|
+
output[settings_slice] = json.load(f)[settings_slice]
|
46
|
+
|
47
|
+
USER_SETTINGS.update(output)
|
48
|
+
return output
|
49
|
+
|
50
|
+
def load_settings_project(self):
|
51
|
+
return self.meta_settings_file.load_settings_project()
|
52
|
+
|
53
|
+
def save_settings_project(self, p):
|
54
|
+
self.meta_settings_file.save_settings_project(p)
|
55
|
+
return self.load_settings()
|
56
|
+
|
57
|
+
|
58
|
+
class MetaSettingsFile:
|
59
|
+
def __init__(self):
|
60
|
+
self.path_seed_settings = get_absolute_path(
|
61
|
+
__file__, CONSTANTS_FOLDER / "Settings.json"
|
62
|
+
)
|
63
|
+
self.path_seed_meta_settings = get_absolute_path(
|
64
|
+
__file__, CONSTANTS_FOLDER / "settingsProject.json"
|
65
|
+
)
|
66
|
+
self.path_default_settings = "setta-settings.json"
|
67
|
+
self.path_meta_settings = "setta-meta-settings.json"
|
68
|
+
self.load_seed_files()
|
69
|
+
|
70
|
+
def get_settings_paths(self):
|
71
|
+
settings_slice_to_path = {}
|
72
|
+
p = self.load_meta_settings()
|
73
|
+
for k in self.obj_seed_settings.keys():
|
74
|
+
path = self.find_path_for_settings_slice(p, k)
|
75
|
+
if not path:
|
76
|
+
self.seed_settings(self.path_default_settings)
|
77
|
+
elif not os.path.exists(path):
|
78
|
+
self.seed_settings(path)
|
79
|
+
settings_slice_to_path[k] = path
|
80
|
+
return settings_slice_to_path
|
81
|
+
|
82
|
+
def find_path_for_settings_slice(self, p, slice):
|
83
|
+
for sectionId, section in p["sections"].items():
|
84
|
+
if section["jsonSourceKeys"] == [slice]:
|
85
|
+
variant = get_selected_section_variant(p, sectionId)
|
86
|
+
return variant["name"]
|
87
|
+
return None
|
88
|
+
|
89
|
+
def seed_settings(self, path):
|
90
|
+
if not os.path.exists(path):
|
91
|
+
save_json_to_file(path, self.obj_seed_settings)
|
92
|
+
|
93
|
+
def seed_meta_settings(self):
|
94
|
+
if not os.path.exists(self.path_meta_settings):
|
95
|
+
save_json_to_file(self.path_meta_settings, self.obj_seed_meta_settings)
|
96
|
+
|
97
|
+
def load_meta_settings(self):
|
98
|
+
logger.debug("Loading meta settings")
|
99
|
+
self.seed_meta_settings()
|
100
|
+
with open(self.path_meta_settings, "r") as f:
|
101
|
+
return json.load(f)
|
102
|
+
|
103
|
+
def load_settings_project(self):
|
104
|
+
p = self.load_meta_settings()
|
105
|
+
add_defaults_to_project_and_load_json_sources(p)
|
106
|
+
return p
|
107
|
+
|
108
|
+
def load_seed_files(self):
|
109
|
+
with open(self.path_seed_settings, "r") as f:
|
110
|
+
self.obj_seed_settings = json.load(f)
|
111
|
+
with open(self.path_seed_meta_settings, "r") as f:
|
112
|
+
self.obj_seed_meta_settings = json.load(f)
|
113
|
+
|
114
|
+
def save_settings_project(self, p):
|
115
|
+
save_json_source_data(p)
|
116
|
+
remove_json_source_data(p, keepCodeInfoThatHaveUITypes=False)
|
117
|
+
filter_data_for_json_export(p)
|
118
|
+
save_json_to_file(self.path_meta_settings, p)
|
setta/database/utils.py
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
import copy
|
2
|
+
from uuid import uuid4
|
3
|
+
|
4
|
+
|
5
|
+
def create_new_id():
|
6
|
+
return str(uuid4())
|
7
|
+
|
8
|
+
|
9
|
+
def maybe_new_id(x):
|
10
|
+
return x if x else create_new_id()
|
11
|
+
|
12
|
+
|
13
|
+
def rename_keys(x, to_rename):
|
14
|
+
output = copy.deepcopy(x)
|
15
|
+
for old_key in to_rename.keys():
|
16
|
+
new_key = to_rename[old_key]
|
17
|
+
if old_key in output and new_key != old_key:
|
18
|
+
output[new_key] = output[old_key]
|
19
|
+
del output[old_key]
|
20
|
+
return output
|
21
|
+
|
22
|
+
|
23
|
+
def create_id_map(old_ids):
|
24
|
+
return dict((x, create_new_id()) for x in old_ids)
|
25
|
+
|
26
|
+
|
27
|
+
def remap_ids(x, old_ids=None):
|
28
|
+
if old_ids is None:
|
29
|
+
old_ids = list(x.keys())
|
30
|
+
id_map = create_id_map(old_ids)
|
31
|
+
new_obj = rename_keys(x, id_map)
|
32
|
+
return new_obj, id_map
|
setta/lsp/__init__.py
ADDED
File without changes
|
@@ -0,0 +1,113 @@
|
|
1
|
+
import asyncio
|
2
|
+
import os
|
3
|
+
import site
|
4
|
+
from pathlib import Path
|
5
|
+
from typing import Set
|
6
|
+
|
7
|
+
from watchdog.events import FileSystemEvent, FileSystemEventHandler
|
8
|
+
from watchdog.observers import Observer
|
9
|
+
|
10
|
+
|
11
|
+
class LSPFileWatcher:
|
12
|
+
def __init__(self, notify_callback):
|
13
|
+
"""
|
14
|
+
Initialize the file watcher.
|
15
|
+
|
16
|
+
Args:
|
17
|
+
notify_callback: Callback function that sends notifications to the LSP server.
|
18
|
+
Should accept FileSystemEvent as parameter.
|
19
|
+
"""
|
20
|
+
self.observer = Observer()
|
21
|
+
self.watched_paths: Set[str] = set()
|
22
|
+
self.handler = LSPEventHandler(notify_callback, asyncio.get_event_loop())
|
23
|
+
|
24
|
+
def add_workspace_folder(self, path: str) -> None:
|
25
|
+
"""
|
26
|
+
Add a workspace folder to watch.
|
27
|
+
|
28
|
+
Args:
|
29
|
+
path: Path to the workspace folder
|
30
|
+
"""
|
31
|
+
if not os.path.exists(path):
|
32
|
+
raise ValueError(f"Path does not exist: {path}")
|
33
|
+
|
34
|
+
absolute_path = os.path.abspath(path)
|
35
|
+
if absolute_path not in self.watched_paths:
|
36
|
+
self.watched_paths.add(absolute_path)
|
37
|
+
self.observer.schedule(self.handler, absolute_path, recursive=True)
|
38
|
+
|
39
|
+
def add_python_site_packages(self) -> None:
|
40
|
+
"""Add Python site-packages directories to watched paths."""
|
41
|
+
for path in site.getsitepackages():
|
42
|
+
try:
|
43
|
+
self.add_workspace_folder(path)
|
44
|
+
except ValueError:
|
45
|
+
continue # Skip if path doesn't exist
|
46
|
+
|
47
|
+
def start(self) -> None:
|
48
|
+
"""Start the file watcher."""
|
49
|
+
self.observer.start()
|
50
|
+
|
51
|
+
def stop(self) -> None:
|
52
|
+
"""Stop the file watcher."""
|
53
|
+
self.observer.stop()
|
54
|
+
self.observer.join()
|
55
|
+
|
56
|
+
def is_watching(self, path: str) -> bool:
|
57
|
+
"""
|
58
|
+
Check if a path is being watched.
|
59
|
+
|
60
|
+
Args:
|
61
|
+
path: Path to check
|
62
|
+
|
63
|
+
Returns:
|
64
|
+
bool: True if the path is being watched
|
65
|
+
"""
|
66
|
+
absolute_path = os.path.abspath(path)
|
67
|
+
return any(
|
68
|
+
absolute_path.startswith(watched_path)
|
69
|
+
for watched_path in self.watched_paths
|
70
|
+
)
|
71
|
+
|
72
|
+
|
73
|
+
class LSPEventHandler(FileSystemEventHandler):
|
74
|
+
def __init__(self, callback, loop):
|
75
|
+
self.callback = callback
|
76
|
+
self.loop = loop
|
77
|
+
|
78
|
+
def on_any_event(self, event: FileSystemEvent):
|
79
|
+
if event.is_directory:
|
80
|
+
return
|
81
|
+
|
82
|
+
changes = [
|
83
|
+
{
|
84
|
+
"uri": self._path_to_uri(event.src_path),
|
85
|
+
"type": self._get_change_type(event),
|
86
|
+
}
|
87
|
+
]
|
88
|
+
|
89
|
+
if asyncio.iscoroutinefunction(self.callback):
|
90
|
+
self.loop.call_soon_threadsafe(
|
91
|
+
lambda: self.loop.create_task(self.callback(changes))
|
92
|
+
)
|
93
|
+
else:
|
94
|
+
self.callback(changes)
|
95
|
+
|
96
|
+
def _path_to_uri(self, path: str) -> str:
|
97
|
+
"""Convert file path to URI format."""
|
98
|
+
return Path(path).as_uri()
|
99
|
+
|
100
|
+
def _get_change_type(self, event: FileSystemEvent) -> int:
|
101
|
+
"""
|
102
|
+
Convert watchdog event type to LSP change type.
|
103
|
+
1: Created
|
104
|
+
2: Changed
|
105
|
+
3: Deleted
|
106
|
+
"""
|
107
|
+
if event.event_type == "created":
|
108
|
+
return 1
|
109
|
+
elif event.event_type == "modified":
|
110
|
+
return 2
|
111
|
+
elif event.event_type == "deleted":
|
112
|
+
return 3
|
113
|
+
return 2 # Default to changed
|
setta/lsp/reader.py
ADDED
@@ -0,0 +1,184 @@
|
|
1
|
+
import asyncio
|
2
|
+
import json
|
3
|
+
import logging
|
4
|
+
|
5
|
+
from setta.lsp.reader_fns.completion import process_completion_response
|
6
|
+
from setta.lsp.reader_fns.definition import process_definition_response
|
7
|
+
from setta.lsp.reader_fns.diagnostics import process_diagnostics_response
|
8
|
+
from setta.lsp.reader_fns.documentHighlight import process_document_highlight_response
|
9
|
+
from setta.lsp.reader_fns.references import process_references_response
|
10
|
+
from setta.lsp.reader_fns.signatureHelp import process_signature_help_response
|
11
|
+
from setta.utils.constants import C
|
12
|
+
|
13
|
+
from .server import LanguageServerInteractor
|
14
|
+
|
15
|
+
logger = logging.getLogger(__name__)
|
16
|
+
|
17
|
+
|
18
|
+
class LanguageServerReader(LanguageServerInteractor):
|
19
|
+
def __init__(self, server, websocket_manager):
|
20
|
+
self.server = server
|
21
|
+
self.websocket_manager = websocket_manager
|
22
|
+
self.stop_event = asyncio.Event()
|
23
|
+
self.started = asyncio.Event()
|
24
|
+
self.reader_task = None
|
25
|
+
|
26
|
+
async def start_listener(self):
|
27
|
+
logger.debug(f"Starting {self.server.name} language server reader")
|
28
|
+
self.stop_event.clear() # Reset the stop event
|
29
|
+
self.reader_task = asyncio.create_task(self.read_response())
|
30
|
+
await self.started.wait()
|
31
|
+
|
32
|
+
async def stop(self):
|
33
|
+
logger.debug(f"Stopping {self.server.name} language server reader")
|
34
|
+
self.stop_event.set()
|
35
|
+
self.started.clear()
|
36
|
+
if self.reader_task:
|
37
|
+
self.reader_task.cancel()
|
38
|
+
try:
|
39
|
+
await self.reader_task
|
40
|
+
except asyncio.CancelledError:
|
41
|
+
pass
|
42
|
+
|
43
|
+
async def read_response(self):
|
44
|
+
self.started.set()
|
45
|
+
while not self.stop_event.is_set():
|
46
|
+
try:
|
47
|
+
await self.read_and_process_message()
|
48
|
+
except Exception as e:
|
49
|
+
logging.error(f"Error reading from language server: {e}")
|
50
|
+
# Optional: add a small delay to prevent tight loop if there's a persistent error
|
51
|
+
await asyncio.sleep(0.1)
|
52
|
+
|
53
|
+
async def read_and_process_message(self):
|
54
|
+
headers = b""
|
55
|
+
while not self.stop_event.is_set():
|
56
|
+
chunk = await self.server.stdout.read(1)
|
57
|
+
if not chunk:
|
58
|
+
# Server stdout closed/EOF reached
|
59
|
+
self.stop_event.set() # Signal to stop
|
60
|
+
return
|
61
|
+
headers += chunk
|
62
|
+
if headers.endswith(b"\r\n\r\n"):
|
63
|
+
break
|
64
|
+
|
65
|
+
if self.stop_event.is_set():
|
66
|
+
return
|
67
|
+
|
68
|
+
headers_str = headers.decode("utf-8")
|
69
|
+
header_parts = headers_str.split("\r\n")
|
70
|
+
content_length = 0
|
71
|
+
for header in header_parts:
|
72
|
+
if header.startswith("Content-Length:"):
|
73
|
+
content_length = int(header.split(":")[1].strip())
|
74
|
+
break
|
75
|
+
|
76
|
+
response = b""
|
77
|
+
while len(response) < content_length and not self.stop_event.is_set():
|
78
|
+
chunk = await self.server.stdout.read(content_length - len(response))
|
79
|
+
if not chunk:
|
80
|
+
# Server stdout closed/EOF reached
|
81
|
+
self.stop_event.set() # Signal to stop
|
82
|
+
return
|
83
|
+
response += chunk
|
84
|
+
|
85
|
+
if self.stop_event.is_set():
|
86
|
+
return
|
87
|
+
|
88
|
+
try:
|
89
|
+
response = json.loads(response.decode("utf-8"))
|
90
|
+
await self.process_response(response)
|
91
|
+
except json.JSONDecodeError as e:
|
92
|
+
logger.debug(f"Error decoding JSON response: {e}")
|
93
|
+
return
|
94
|
+
except Exception as e:
|
95
|
+
logger.debug(f"Error processing response: {e}")
|
96
|
+
return
|
97
|
+
|
98
|
+
async def process_response(self, response):
|
99
|
+
logger.debug(f"Processing response: {response}")
|
100
|
+
id = response.get("id", None)
|
101
|
+
method = response.get("method", None)
|
102
|
+
if id:
|
103
|
+
output = self.process_response_with_id(id, method, response)
|
104
|
+
else:
|
105
|
+
output = self.process_response_without_id(method, response)
|
106
|
+
|
107
|
+
if id in self.pending_requests:
|
108
|
+
self.pending_requests[id].set_result(output["content"])
|
109
|
+
elif output["websocket_method"] == "return_to_requester":
|
110
|
+
await self.websocket_manager.send_message_to_requester(
|
111
|
+
output["websocket_return_id"], output["content"]
|
112
|
+
)
|
113
|
+
elif output["websocket_method"] == "broadcast":
|
114
|
+
await self.websocket_manager.broadcast(
|
115
|
+
{
|
116
|
+
"messageType": output["websocket_message_type"],
|
117
|
+
"content": output["content"],
|
118
|
+
}
|
119
|
+
)
|
120
|
+
|
121
|
+
def process_response_with_id(self, id, method, response):
|
122
|
+
metadata = self.msg_id_to_metadata.pop(id, {})
|
123
|
+
method = method if method else metadata["method"]
|
124
|
+
content = None
|
125
|
+
websocket_return_id = id
|
126
|
+
websocket_method = None
|
127
|
+
websocket_message_type = None
|
128
|
+
if (
|
129
|
+
not self.server.is_initialized
|
130
|
+
and id == self.server.initialization_request_id
|
131
|
+
):
|
132
|
+
self.server.is_initialized = True
|
133
|
+
content = "Initialized"
|
134
|
+
websocket_method = "broadcast"
|
135
|
+
websocket_message_type = C.WS_LSP_STATUS
|
136
|
+
elif method == "textDocument/completion":
|
137
|
+
content = process_completion_response(response, metadata)
|
138
|
+
websocket_method = "return_to_requester"
|
139
|
+
elif method == "textDocument/signatureHelp":
|
140
|
+
content = process_signature_help_response(response)
|
141
|
+
websocket_method = "return_to_requester"
|
142
|
+
elif method == "textDocument/references":
|
143
|
+
content, websocket_return_id = process_references_response(
|
144
|
+
response, metadata
|
145
|
+
)
|
146
|
+
websocket_method = "return_to_requester"
|
147
|
+
elif method == "textDocument/documentHighlight":
|
148
|
+
content, websocket_return_id = process_document_highlight_response(
|
149
|
+
response, metadata
|
150
|
+
)
|
151
|
+
websocket_method = "return_to_requester"
|
152
|
+
elif method == "textDocument/definition":
|
153
|
+
content = process_definition_response(response)
|
154
|
+
websocket_method = "return_to_requester"
|
155
|
+
|
156
|
+
content = {"data": content, "otherData": metadata.get("otherData")}
|
157
|
+
|
158
|
+
return {
|
159
|
+
"content": content,
|
160
|
+
"websocket_return_id": websocket_return_id,
|
161
|
+
"websocket_method": websocket_method,
|
162
|
+
"websocket_message_type": websocket_message_type,
|
163
|
+
}
|
164
|
+
|
165
|
+
def process_response_without_id(self, method, response):
|
166
|
+
content = None
|
167
|
+
websocket_return_id = None
|
168
|
+
websocket_method = None
|
169
|
+
websocket_message_type = None
|
170
|
+
|
171
|
+
if method == "textDocument/publishDiagnostics":
|
172
|
+
content, needsDiagnostics = process_diagnostics_response(
|
173
|
+
response, self.get_code_metadata
|
174
|
+
)
|
175
|
+
if needsDiagnostics:
|
176
|
+
websocket_method = "broadcast"
|
177
|
+
websocket_message_type = C.WS_LSP_DIAGNOSTICS
|
178
|
+
|
179
|
+
return {
|
180
|
+
"content": content,
|
181
|
+
"websocket_return_id": websocket_return_id,
|
182
|
+
"websocket_method": websocket_method,
|
183
|
+
"websocket_message_type": websocket_message_type,
|
184
|
+
}
|
File without changes
|
@@ -0,0 +1,84 @@
|
|
1
|
+
from setta.code_gen.python.position_line_col import line_col_to_position_batch
|
2
|
+
|
3
|
+
|
4
|
+
def process_completion_response(response, metadata):
|
5
|
+
content = []
|
6
|
+
if response["result"] and response["result"]["items"]:
|
7
|
+
code = metadata["code"]
|
8
|
+
content = process_completion(
|
9
|
+
code,
|
10
|
+
response["result"]["items"],
|
11
|
+
metadata["generated_var_names"],
|
12
|
+
metadata["referencable_var_names"],
|
13
|
+
metadata["cursor_offset"],
|
14
|
+
)
|
15
|
+
return content
|
16
|
+
|
17
|
+
|
18
|
+
def process_completion(
|
19
|
+
code, items, generated_var_names, referencable_var_names, cursor_offset
|
20
|
+
):
|
21
|
+
content = []
|
22
|
+
line_cols = []
|
23
|
+
content_idx_with_text_edit = {}
|
24
|
+
for x in items:
|
25
|
+
if x["label"] in generated_var_names:
|
26
|
+
continue
|
27
|
+
c = {"label": x["label"], "type": type_mapping[x["kind"]]}
|
28
|
+
if "textEdit" in x:
|
29
|
+
content_idx_with_text_edit[len(content)] = len(line_cols)
|
30
|
+
r = x["textEdit"]["range"]
|
31
|
+
line_cols.append(
|
32
|
+
(
|
33
|
+
r["start"]["line"],
|
34
|
+
r["start"]["character"],
|
35
|
+
)
|
36
|
+
)
|
37
|
+
line_cols.append((r["end"]["line"], r["end"]["character"]))
|
38
|
+
|
39
|
+
content.append(c)
|
40
|
+
|
41
|
+
if len(line_cols) > 0:
|
42
|
+
# use the raw line/character values because the code
|
43
|
+
# contains generated code
|
44
|
+
positions = line_col_to_position_batch(code, line_cols)
|
45
|
+
for i, j in content_idx_with_text_edit.items():
|
46
|
+
# shift it back by cursor_offset so that it's ready
|
47
|
+
# for the frontend
|
48
|
+
content[i]["from"] = positions[j] - cursor_offset
|
49
|
+
content[i]["to"] = positions[j + 1] - cursor_offset
|
50
|
+
|
51
|
+
for x in referencable_var_names:
|
52
|
+
content.append({"label": x, "type": "variable"})
|
53
|
+
|
54
|
+
return content
|
55
|
+
|
56
|
+
|
57
|
+
type_mapping = {
|
58
|
+
1: "File",
|
59
|
+
2: "Module",
|
60
|
+
3: "Namespace",
|
61
|
+
4: "Package",
|
62
|
+
5: "Class",
|
63
|
+
6: "Method",
|
64
|
+
7: "Property",
|
65
|
+
8: "Field",
|
66
|
+
9: "Constructor",
|
67
|
+
10: "Enum",
|
68
|
+
11: "Interface",
|
69
|
+
12: "Function",
|
70
|
+
13: "Variable",
|
71
|
+
14: "Constant",
|
72
|
+
15: "String",
|
73
|
+
16: "Number",
|
74
|
+
17: "Boolean",
|
75
|
+
18: "Array",
|
76
|
+
19: "Object",
|
77
|
+
20: "Key",
|
78
|
+
21: "Null",
|
79
|
+
22: "EnumMember",
|
80
|
+
23: "Struct",
|
81
|
+
24: "Event",
|
82
|
+
25: "Operator",
|
83
|
+
26: "TypeParameter",
|
84
|
+
}
|
@@ -0,0 +1,99 @@
|
|
1
|
+
import re
|
2
|
+
|
3
|
+
from setta.code_gen.export_selected import get_gen_code_template_var
|
4
|
+
from setta.code_gen.python.position_line_col import line_col_to_position_batch
|
5
|
+
|
6
|
+
|
7
|
+
def process_diagnostics_response(response, get_code_metadata):
|
8
|
+
params = response["params"]
|
9
|
+
metadata = get_code_metadata(params["uri"])
|
10
|
+
if not metadata["needsDiagnostics"] or metadata["version"] != params["version"]:
|
11
|
+
return None, False
|
12
|
+
|
13
|
+
convert_diagnostic_line_cols_to_positions(metadata["code"], params["diagnostics"])
|
14
|
+
|
15
|
+
code_split = metadata["code"].split("\n")
|
16
|
+
diagnostics = process_diagnostics(
|
17
|
+
params["diagnostics"],
|
18
|
+
code_split,
|
19
|
+
metadata["codeJson"],
|
20
|
+
metadata["ref_template_var_positions"],
|
21
|
+
)
|
22
|
+
|
23
|
+
return {
|
24
|
+
"projectConfigId": metadata["projectConfigId"],
|
25
|
+
"codeSectionId": metadata["codeSectionId"],
|
26
|
+
"diagnostics": diagnostics,
|
27
|
+
}, True
|
28
|
+
|
29
|
+
|
30
|
+
def process_diagnostics(diagnostics, code_split, codeJson, ref_template_var_positions):
|
31
|
+
output = []
|
32
|
+
gen_code_template_var = get_gen_code_template_var(
|
33
|
+
ref_template_var_positions["templateVars"]
|
34
|
+
)
|
35
|
+
if gen_code_template_var:
|
36
|
+
gen_code_start = gen_code_template_var["startPos"]
|
37
|
+
gen_code_end = gen_code_start + len(gen_code_template_var["value"])
|
38
|
+
for d in diagnostics:
|
39
|
+
start, end = d["range"]["start"], d["range"]["end"]
|
40
|
+
if gen_code_template_var and gen_code_start <= start["position"] < gen_code_end:
|
41
|
+
result = process_gen_code_diagnostic(d, code_split, codeJson, start, end)
|
42
|
+
output.extend(result)
|
43
|
+
# TODO: process diagnostics for non-generated code:
|
44
|
+
# else:
|
45
|
+
# output.append(d)
|
46
|
+
|
47
|
+
return output
|
48
|
+
|
49
|
+
|
50
|
+
def process_gen_code_diagnostic(d, code_split, codeJson, start, end):
|
51
|
+
if "code" not in d or not codeJson:
|
52
|
+
return []
|
53
|
+
if d["code"] == "reportArgumentType":
|
54
|
+
problem_var = code_split[start["line"]][
|
55
|
+
start["character"] : end["character"]
|
56
|
+
].strip()
|
57
|
+
return [get_message_with_ids(codeJson, problem_var, d["message"])]
|
58
|
+
elif d["code"] == "reportCallIssue" and "missing" in d["message"]:
|
59
|
+
missing_params = extract_parameters(d["message"])
|
60
|
+
# get variable to the left of the equal sign
|
61
|
+
assigned_to = code_split[start["line"]].split("=")[0].strip()
|
62
|
+
unusedParams = codeJson[assigned_to]["value"]["unusedParams"]
|
63
|
+
output = []
|
64
|
+
for potential_problem_var in unusedParams:
|
65
|
+
if codeJson[potential_problem_var]["name"] in missing_params:
|
66
|
+
output.append(
|
67
|
+
get_message_with_ids(codeJson, potential_problem_var, d["message"])
|
68
|
+
)
|
69
|
+
return output
|
70
|
+
return []
|
71
|
+
|
72
|
+
|
73
|
+
def get_message_with_ids(code_json, problem_var, message):
|
74
|
+
section_id, param_info_id = (
|
75
|
+
code_json[problem_var]["sectionId"],
|
76
|
+
code_json[problem_var]["paramInfoId"],
|
77
|
+
)
|
78
|
+
return {"sectionId": section_id, "paramInfoId": param_info_id, "message": message}
|
79
|
+
|
80
|
+
|
81
|
+
def extract_parameters(error_string):
|
82
|
+
pattern = r'"([^"]+)"'
|
83
|
+
parameters = re.findall(pattern, error_string)
|
84
|
+
return parameters
|
85
|
+
|
86
|
+
|
87
|
+
def convert_diagnostic_line_cols_to_positions(code, diagnostics):
|
88
|
+
line_cols = []
|
89
|
+
for d in diagnostics:
|
90
|
+
x = d["range"]["start"]
|
91
|
+
line_cols.append((x["line"], x["character"]))
|
92
|
+
x = d["range"]["end"]
|
93
|
+
line_cols.append((x["line"], x["character"]))
|
94
|
+
|
95
|
+
positions = line_col_to_position_batch(code, line_cols)
|
96
|
+
|
97
|
+
for i, d in enumerate(diagnostics):
|
98
|
+
d["range"]["start"]["position"] = positions[i * 2]
|
99
|
+
d["range"]["end"]["position"] = positions[(i * 2) + 1]
|