Skip to content

Commit 15fdd67

Browse files
committed
Chore: Add imports from the beginning
1 parent 4d0943a commit 15fdd67

File tree

2 files changed

+33
-109
lines changed

2 files changed

+33
-109
lines changed

server/src/__tests__/embedded-languages.test.ts

Lines changed: 11 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { generateParser } from '../tree-sitter/parser'
1313
import { FIXTURE_DOCUMENT } from './fixtures/fixtures'
1414
import { TextDocument } from 'vscode-languageserver-textdocument'
1515
import { type EmbeddedLanguageType } from '../lib/src/types/embedded-languages'
16+
import { imports } from '../embedded-languages/python-support'
1617

1718
describe('Embedded Language Documents file management', () => {
1819
beforeAll(async () => {
@@ -117,22 +118,22 @@ describe('Create various basic embedded python documents', () => {
117118
[
118119
'anonymous',
119120
'python(){\n pass\n}',
120-
'def _ ():\n pass\n '
121+
`${imports}def _ ():\n pass\n `
121122
],
122123
[
123124
'named with python keyword',
124125
'python foo (){\n pass\n}',
125-
'def foo ():\n pass\n '
126+
`${imports}def foo ():\n pass\n `
126127
],
127128
[
128129
'empty',
129130
'python(){\n}',
130-
'def _ ():\n pass\n '
131+
`${imports}def _ ():\n pass\n `
131132
],
132133
[
133134
'with def keyword',
134135
'def foo():\n pass',
135-
'def foo():\n pass'
136+
`${imports}def foo():\n pass`
136137
]
137138
])('%s', async (description, input, result) => {
138139
const embeddedContent = await createEmbeddedContent(input, 'python')
@@ -155,31 +156,31 @@ describe('Create Python embedded language content with inline Python', () => {
155156
'basic',
156157
// eslint-disable-next-line no-template-curly-in-string
157158
'FOO = \'${@"BAR"}\'',
158-
' \n\n"BAR"\n '
159+
`${imports} \n\n"BAR"\n `
159160
],
160161
[
161162
'with spacing',
162163
// eslint-disable-next-line no-template-curly-in-string
163164
'FOO = \'${@ "BAR" }\'',
164-
' \n \n"BAR" \n '
165+
`${imports} \n \n"BAR" \n `
165166
],
166167
[
167168
'multiline',
168169
// eslint-disable-next-line no-template-curly-in-string
169170
'FOO = \'${@"BAR"}\' \\\n1 \\\n2"',
170-
' \n\n"BAR"\n \n \n '
171+
`${imports} \n\n"BAR"\n \n \n `
171172
],
172173
[
173174
'with two embedded python regions',
174175
// eslint-disable-next-line no-template-curly-in-string
175176
'FOO = \'${@"BAR"}${@"BAR"}\'',
176-
' \n\n"BAR"\n \n\n"BAR"\n '
177+
`${imports} \n\n"BAR"\n \n\n"BAR"\n `
177178
],
178179
[
179180
'without surrounding quotes',
180181
// eslint-disable-next-line no-template-curly-in-string
181182
'inherit ${@"test"}',
182-
' \n\n"test"\n'
183+
`${imports} \n\n"test"\n`
183184
]
184185
/* // This is not yet supported by tree-sitter
185186
[
@@ -194,48 +195,6 @@ describe('Create Python embedded language content with inline Python', () => {
194195
})
195196
})
196197

197-
describe('Create Python embedded language content with imports', () => {
198-
beforeAll(async () => {
199-
if (!analyzer.hasParser()) {
200-
const parser = await generateParser()
201-
analyzer.initialize(parser)
202-
}
203-
analyzer.resetAnalyzedDocuments()
204-
await embeddedLanguageDocsManager.setStoragePath(__dirname)
205-
})
206-
207-
test.each([
208-
[
209-
'with bb',
210-
'python(){\n bb.parse.vars_from_file("test")\n}',
211-
'import bb\nfrom bb import parse\nbb.parse = parse\ndef _ ():\n bb.parse.vars_from_file("test")\n '
212-
],
213-
[
214-
'with d',
215-
'python(){\n d.getVar("test")\n}',
216-
'from bb import data_smart\nd = data_smart.DataSmart()\ndef _ ():\n d.getVar("test")\n '
217-
],
218-
[
219-
'with e',
220-
'python(){\n e.data.getVar("test")\n}',
221-
'from bb import data_smart\nd = data_smart.DataSmart()\nfrom bb import event\ne = event.Event()\ne.data = d\ndef _ ():\n e.data.getVar("test")\n '
222-
],
223-
[
224-
'with os',
225-
'python(){\n os.path.dirname("test")\n}',
226-
'import os\ndef _ ():\n os.path.dirname("test")\n '
227-
],
228-
[
229-
'with combination (d and bb)',
230-
'python(){\n d.getVar("test")\n bb.parse.vars_from_file("test")\n}',
231-
'from bb import data_smart\nd = data_smart.DataSmart()\nimport bb\nfrom bb import parse\nbb.parse = parse\ndef _ ():\n d.getVar("test")\n bb.parse.vars_from_file("test")\n '
232-
]
233-
])('%s', async (description, input, result) => {
234-
const embeddedContent = await createEmbeddedContent(input, 'python')
235-
expect(embeddedContent).toEqual(result)
236-
})
237-
})
238-
239198
const createEmbeddedContent = async (content: string, language: EmbeddedLanguageType): Promise<string | undefined> => {
240199
const uri = randomUUID()
241200
const document = TextDocument.create(uri, 'bitbake', 1, content)
@@ -253,7 +212,7 @@ const createEmbeddedContent = async (content: string, language: EmbeddedLanguage
253212
}
254213

255214
const expectedPythonEmbeddedLanguageDoc =
256-
`
215+
`${imports}
257216
258217
def do_foo():
259218
print('123')

server/src/embedded-languages/python-support.ts

Lines changed: 22 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -12,44 +12,52 @@ import * as TreeSitterUtils from '../tree-sitter/utils'
1212
import { embeddedLanguageDocsManager } from './documents-manager'
1313
import { type EmbeddedLanguageDoc, insertTextIntoEmbeddedLanguageDoc, initEmbeddedLanguageDoc } from './utils'
1414

15+
export const imports = [
16+
'import bb',
17+
'from bb import data_smart',
18+
'd = data_smart.DataSmart()',
19+
'from bb import event',
20+
'e = event.Event()',
21+
'e.data = d',
22+
'import os',
23+
''
24+
].join('\n')
25+
1526
export const generatePythonEmbeddedLanguageDoc = async (textDocument: TextDocument): Promise<void> => {
1627
const analyzedDocument = analyzer.getAnalyzedDocument(textDocument.uri)
1728
if (analyzedDocument === undefined) {
1829
return
1930
}
20-
const imports = new Set<string>()
2131
const embeddedLanguageDoc = initEmbeddedLanguageDoc(textDocument, 'python')
2232
TreeSitterUtils.forEach(analyzedDocument.tree.rootNode, (node) => {
2333
switch (node.type) {
2434
case 'python_function_definition':
25-
handlePythonFunctionDefinition(node, embeddedLanguageDoc, imports)
35+
handlePythonFunctionDefinition(node, embeddedLanguageDoc)
2636
return false
2737
case 'anonymous_python_function':
28-
handleAnonymousPythonFunction(node, embeddedLanguageDoc, imports)
38+
handleAnonymousPythonFunction(node, embeddedLanguageDoc)
2939
return false
3040
case 'inline_python':
31-
handleInlinePythonNode(node, embeddedLanguageDoc, imports)
41+
handleInlinePythonNode(node, embeddedLanguageDoc)
3242
return false
3343
default:
3444
return true
3545
}
3646
})
37-
if (imports.size !== 0) {
38-
insertTextIntoEmbeddedLanguageDoc(embeddedLanguageDoc, 0, 0, [...imports].join('\n') + '\n')
39-
}
47+
insertTextIntoEmbeddedLanguageDoc(embeddedLanguageDoc, 0, 0, imports)
4048
await embeddedLanguageDocsManager.saveEmbeddedLanguageDoc(embeddedLanguageDoc)
4149
}
4250

43-
const handlePythonFunctionDefinition = (node: SyntaxNode, embeddedLanguageDoc: EmbeddedLanguageDoc, imports: Set<string>): void => {
51+
const handlePythonFunctionDefinition = (node: SyntaxNode, embeddedLanguageDoc: EmbeddedLanguageDoc): void => {
4452
insertTextIntoEmbeddedLanguageDoc(embeddedLanguageDoc, node.startIndex, node.endIndex, node.text)
4553
node.children.forEach((child) => {
4654
if (child.type === 'block') {
47-
handleBlockNode(child, embeddedLanguageDoc, imports)
55+
handleBlockNode(child, embeddedLanguageDoc)
4856
}
4957
})
5058
}
5159

52-
const handleAnonymousPythonFunction = (node: SyntaxNode, embeddedLanguageDoc: EmbeddedLanguageDoc, imports: Set<string>): void => {
60+
const handleAnonymousPythonFunction = (node: SyntaxNode, embeddedLanguageDoc: EmbeddedLanguageDoc): void => {
5361
insertTextIntoEmbeddedLanguageDoc(embeddedLanguageDoc, node.startIndex, node.endIndex, node.text)
5462
node.children.forEach((child) => {
5563
switch (child.type) {
@@ -72,15 +80,15 @@ const handleAnonymousPythonFunction = (node: SyntaxNode, embeddedLanguageDoc: Em
7280
insertTextIntoEmbeddedLanguageDoc(embeddedLanguageDoc, child.startIndex, child.endIndex, ' ')
7381
break
7482
case 'block':
75-
handleBlockNode(child, embeddedLanguageDoc, imports)
83+
handleBlockNode(child, embeddedLanguageDoc)
7684
break
7785
default:
7886
break
7987
}
8088
})
8189
}
8290

83-
const handleInlinePythonNode = (inlinePythonNode: SyntaxNode, embeddedLanguageDoc: EmbeddedLanguageDoc, imports: Set<string>): void => {
91+
const handleInlinePythonNode = (inlinePythonNode: SyntaxNode, embeddedLanguageDoc: EmbeddedLanguageDoc): void => {
8492
const openingNode = inlinePythonNode.child(0)
8593
const pythonContentNode = inlinePythonNode.child(1)
8694
const closingNode = inlinePythonNode.child(2)
@@ -98,56 +106,13 @@ const handleInlinePythonNode = (inlinePythonNode: SyntaxNode, embeddedLanguageDo
98106
insertTextIntoEmbeddedLanguageDoc(embeddedLanguageDoc, pythonContentNode.startIndex, pythonContentNode.startIndex, '\n') // prevent trailing spaces
99107
insertTextIntoEmbeddedLanguageDoc(embeddedLanguageDoc, pythonContentNode.startIndex, pythonContentNode.endIndex, pythonContentNode.text)
100108
insertTextIntoEmbeddedLanguageDoc(embeddedLanguageDoc, closingNode.startIndex, closingNode.endIndex, '\n')
101-
handleBlockNode(pythonContentNode, embeddedLanguageDoc, imports)
109+
handleBlockNode(pythonContentNode, embeddedLanguageDoc)
102110
}
103111

104-
const handleBlockNode = (blockNode: SyntaxNode, embeddedLanguageDoc: EmbeddedLanguageDoc, imports: Set<string>): void => {
112+
const handleBlockNode = (blockNode: SyntaxNode, embeddedLanguageDoc: EmbeddedLanguageDoc): void => {
105113
if (blockNode.text === '') {
106114
insertTextIntoEmbeddedLanguageDoc(embeddedLanguageDoc, blockNode.startIndex, blockNode.endIndex, '\n pass')
107115
}
108-
handleImports(blockNode, imports)
109-
}
110-
111-
const handleImports = (blockNode: SyntaxNode, imports: Set<string>): void => {
112-
const importBb = (bbNode: SyntaxNode): void => {
113-
if (bbNode.nextSibling?.type === '.' && bbNode.nextNamedSibling?.type === 'python_identifier') {
114-
const importName = bbNode.nextNamedSibling.text
115-
imports.add('import bb')
116-
imports.add(`from bb import ${importName}`)
117-
imports.add(`bb.${importName} = ${importName}`)
118-
}
119-
}
120-
121-
const importD = (): void => {
122-
imports.add('from bb import data_smart')
123-
imports.add('d = data_smart.DataSmart()')
124-
}
125-
126-
const importE = (): void => {
127-
importD()
128-
imports.add('from bb import event')
129-
imports.add('e = event.Event()')
130-
imports.add('e.data = d')
131-
}
132-
133-
const importOs = (): void => {
134-
imports.add('import os')
135-
}
136-
137-
TreeSitterUtils.forEach(blockNode, (child) => {
138-
if (child.type === 'python_identifier') {
139-
if (child.text === 'bb') {
140-
importBb(child)
141-
} else if (child.text === 'd') {
142-
importD()
143-
} else if (child.text === 'e') {
144-
importE()
145-
} else if (child.text === 'os') {
146-
importOs()
147-
}
148-
}
149-
return true
150-
})
151116
}
152117

153118
const handleOverrideNode = (overrideNode: SyntaxNode, embeddedLanguageDoc: EmbeddedLanguageDoc): void => {

0 commit comments

Comments
 (0)