Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions docs/diagnostics/DeprecatedHttpConnectionMethod.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Устаревшие методы объекта HTTPСоединение (DeprecatedHttpConnectionMethod)

<!-- Блоки выше заполняются автоматически, не трогать -->
## Описание диагностики

В платформе 8.3.21 методы объекта `HTTPСоединение` объявлены устаревшими в клиентском контексте. Вместо них следует использовать асинхронные аналоги с суффиксом `Асинх`.

Асинхронные методы доступны только на клиенте. Поэтому диагностика срабатывает только в модулях с клиентским контекстом (формы, команды, обычное/управляемое приложение, клиентские общие модули) и только внутри методов, выполняющихся на клиенте (`&НаКлиенте`, `&НаКлиентеНаСервере` или без директивы в клиентском модуле). В методах с директивами `&НаСервере` и `&НаСервереБезКонтекста`, а также в серверных модулях диагностика не срабатывает — там асинхронных аналогов нет.

## Устаревшие методы

- `ВызватьHTTPМетод()` → `ВызватьHTTPМетодАсинх()`
- `Записать()` → `ЗаписатьАсинх()`
- `Изменить()` → `ИзменитьАсинх()`
- `ОтправитьДляОбработки()` → `ОтправитьДляОбработкиАсинх()`
- `Получить()` → `ПолучитьАсинх()`
- `ПолучитьЗаголовки()` → `ПолучитьЗаголовкиАсинх()`
- `Удалить()` → `УдалитьАсинх()`

## Примеры

### Неправильно

```bsl
Соединение = Новый HTTPСоединение("example.com");
Соединение.Получить(Запрос, Ответ);
```

### Правильно

```bsl
Соединение = Новый HTTPСоединение("example.com");
Соединение.ПолучитьАсинх(Запрос, Ответ);
```

## См. также

- [Изменения платформы 8.3.21](https://dl04.1c.ru/content/Platform/8_3_21_1140/1cv8upd_8_3_21_1140.htm)
38 changes: 38 additions & 0 deletions docs/en/diagnostics/DeprecatedHttpConnectionMethod.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Deprecated HTTPConnection methods (DeprecatedHttpConnectionMethod)

<!-- Блоки выше заполняются автоматически, не трогать -->
## Diagnostic description

In platform 8.3.21, `HTTPConnection` object methods are deprecated in client context. Use their asynchronous equivalents with the `Async` suffix instead.

Asynchronous methods are only available on the client. Therefore the diagnostic only fires in modules with a client context (forms, commands, ordinary/managed application, client common modules) and only inside methods that execute on the client (`&AtClient`, `&AtClientAtServer` or no directive in a client module). Methods with `&AtServer` and `&AtServerNoContext` directives, as well as server modules, are not reported — there are no asynchronous equivalents available there.

## Deprecated methods

- `CallHTTPMethod()` → `CallHTTPMethodAsync()`
- `Write()` → `WriteAsync()`
- `Change()` → `ChangeAsync()`
- `SendForProcessing()` → `SendForProcessingAsync()`
- `Get()` → `GetAsync()`
- `GetHeaders()` → `GetHeadersAsync()`
- `Delete()` → `DeleteAsync()`

## Examples

### Incorrect

```bsl
Connection = New HTTPConnection("example.com");
Connection.Get(Request, Response);
```

### Correct

```bsl
Connection = New HTTPConnection("example.com");
Connection.GetAsync(Request, Response);
```

## See also

- [Platform 8.3.21 changelog](https://dl04.1c.ru/content/Platform/8_3_21_1140/1cv8upd_8_3_21_1140.htm)
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
/*
* This file is a part of BSL Language Server.
*
* Copyright (c) 2018-2026
* Alexey Sosnoviy <labotamy@gmail.com>, Nikita Fedkin <nixel2007@gmail.com> and contributors
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*
* BSL Language Server is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* BSL Language Server is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with BSL Language Server.
*/
package com.github._1c_syntax.bsl.languageserver.diagnostics;

import com.github._1c_syntax.bsl.languageserver.context.DocumentContext;
import com.github._1c_syntax.bsl.languageserver.context.symbol.annotations.CompilerDirectiveKind;
import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticCompatibilityMode;
import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticMetadata;
import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticScope;
import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticSeverity;
import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticTag;
import com.github._1c_syntax.bsl.languageserver.diagnostics.metadata.DiagnosticType;
import com.github._1c_syntax.bsl.languageserver.types.TypeService;
import com.github._1c_syntax.bsl.parser.BSLParser;
import com.github._1c_syntax.bsl.types.ModuleType;
import com.github._1c_syntax.bsl.mdo.CommonModule;
import com.github._1c_syntax.utils.CaseInsensitivePattern;
import lombok.RequiredArgsConstructor;
import org.antlr.v4.runtime.tree.ParseTree;

import java.util.EnumSet;
import java.util.Set;
import java.util.regex.Pattern;

@DiagnosticMetadata(
type = DiagnosticType.CODE_SMELL,
severity = DiagnosticSeverity.MAJOR,
scope = DiagnosticScope.BSL,
minutesToFix = 5,
compatibilityMode = DiagnosticCompatibilityMode.COMPATIBILITY_MODE_8_3_21,
tags = {
DiagnosticTag.DEPRECATED,
DiagnosticTag.PERFORMANCE
}
)
/**
* Диагностика устаревших методов объекта {@code HTTPСоединение} /
* {@code HTTPConnection}.
* <p>
* В платформе 8.3.21 синхронные методы HTTP-соединения объявлены
* устаревшими в клиентском контексте. Вместо них следует использовать
* асинхронные аналоги с суффиксом {@code Асинх} / {@code Async}.
* <p>
* Асинхронные методы доступны только на клиенте. Чтобы исключить ложные
* срабатывания, диагностика работает только в модулях с клиентским
* контекстом (формы, команды, обычное/управляемое приложение, клиентские
* общие модули) и только внутри методов, выполняющихся на клиенте
* (директивы {@code &НаКлиенте}, {@code &НаКлиентеНаСервере} и методы без
* директивы в клиентском модуле).
* <p>
* Для исключения ложных срабатываний тип-владелец метода резолвится
* через {@link TypeService#memberAt}: диагностика срабатывает только
* если метод вызван на объекте типа {@code HTTPСоединение}.
*
* @see <a href="https://dl04.1c.ru/content/Platform/8_3_21_1140/1cv8upd_8_3_21_1140.htm">
* Изменения платформы 8.3.21</a>
*/
@RequiredArgsConstructor
public class DeprecatedHttpConnectionMethodDiagnostic extends AbstractVisitorDiagnostic {

private static final Pattern MESSAGE_PATTERN = CaseInsensitivePattern.compile(
"(ВызватьHTTPМетод|CallHTTPMethod|"
+ "Записать|Write|"
+ "Изменить|Change|Modify|"
+ "ОтправитьДляОбработки|SendForProcessing|"
+ "Получить|Get|"
+ "ПолучитьЗаголовки|GetHeaders|"
+ "Удалить|Delete)"
);

private static final Pattern HTTP_CONNECTION_PATTERN = CaseInsensitivePattern.compile(
"HTTPСоединение|HTTPConnection"
);

private static final Set<CompilerDirectiveKind> SERVER_COMPILER_DIRECTIVES =
EnumSet.of(CompilerDirectiveKind.AT_SERVER, CompilerDirectiveKind.AT_SERVER_NO_CONTEXT);

private final TypeService typeService;

@Override
public ParseTree visitFile(BSLParser.FileContext ctx) {
if (isServerModule(documentContext)) {
return ctx;
}
return super.visitFile(ctx);
}

@Override
public ParseTree visitSub(BSLParser.SubContext ctx) {
var methodSymbol = documentContext.getSymbolTree().getMethodSymbol(ctx);
if (methodSymbol.isPresent()) {
var compilerDirective = methodSymbol.get().getCompilerDirectiveKind();
if (compilerDirective.isPresent()
&& SERVER_COMPILER_DIRECTIVES.contains(compilerDirective.get())) {
return ctx;
}
}
return super.visitSub(ctx);
}

@Override
public ParseTree visitMethodCall(BSLParser.MethodCallContext ctx) {
var methodName = ctx.methodName();
if (methodName == null) {
return ctx;
}

if (!MESSAGE_PATTERN.matcher(methodName.getText()).matches()) {
return ctx;
}

var identifier = methodName.IDENTIFIER();
if (identifier == null) {
return ctx;
}

var typedMember = typeService.memberAt(documentContext, identifier);
if (typedMember.isEmpty()) {
return ctx;
}

var owner = typedMember.get().owner();
if (owner != null && HTTP_CONNECTION_PATTERN.matcher(owner.qualifiedName()).matches()) {
diagnosticStorage.addDiagnostic(methodName, info.getMessage(methodName.getText()));
}

return ctx;
Comment on lines +121 to +146

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Continue traversal after handling the current call.

Each return ctx stops the visitor at this method-call subtree. Nested deprecated calls in arguments or chained expressions are not inspected. Return super.visitMethodCall(ctx) on lines 74, 78, 83, 88, and 96.

Proposed fix
-      return ctx;
+      return super.visitMethodCall(ctx);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public ParseTree visitMethodCall(BSLParser.MethodCallContext ctx) {
var methodName = ctx.methodName();
if (methodName == null) {
return ctx;
}
if (!MESSAGE_PATTERN.matcher(methodName.getText()).matches()) {
return ctx;
}
var identifier = methodName.IDENTIFIER();
if (identifier == null) {
return ctx;
}
var typedMember = typeService.memberAt(documentContext, identifier);
if (typedMember.isEmpty()) {
return ctx;
}
var owner = typedMember.get().owner();
if (owner != null && HTTP_CONNECTION_PATTERN.matcher(owner.qualifiedName()).matches()) {
diagnosticStorage.addDiagnostic(methodName, info.getMessage(methodName.getText()));
}
return ctx;
public ParseTree visitMethodCall(BSLParser.MethodCallContext ctx) {
var methodName = ctx.methodName();
if (methodName == null) {
return super.visitMethodCall(ctx);
}
if (!MESSAGE_PATTERN.matcher(methodName.getText()).matches()) {
return super.visitMethodCall(ctx);
}
var identifier = methodName.IDENTIFIER();
if (identifier == null) {
return super.visitMethodCall(ctx);
}
var typedMember = typeService.memberAt(documentContext, identifier);
if (typedMember.isEmpty()) {
return super.visitMethodCall(ctx);
}
var owner = typedMember.get().owner();
if (owner != null && HTTP_CONNECTION_PATTERN.matcher(owner.qualifiedName()).matches()) {
diagnosticStorage.addDiagnostic(methodName, info.getMessage(methodName.getText()));
}
return super.visitMethodCall(ctx);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DeprecatedHttpConnectionMethodDiagnostic.java`
around lines 71 - 96, Update visitMethodCall in
DeprecatedHttpConnectionMethodDiagnostic so every early exit and the final
return delegates to super.visitMethodCall(ctx) instead of returning ctx, while
preserving the existing diagnostic checks and recording behavior.

}

private static boolean isServerModule(DocumentContext documentContext) {
return switch (documentContext.getModuleType()) {
case ApplicationModule, CommandModule, FormModule, ManagedApplicationModule -> false;
case CommonModule -> isServerCommonModule(documentContext);
default -> true; // Все прочие модули — строго серверные
};
}

private static boolean isServerCommonModule(DocumentContext documentContext) {
var mdObject = documentContext.getMdObject();

return mdObject.map(CommonModule.class::cast)
.filter(commonModule -> !(commonModule.isClientManagedApplication()
|| commonModule.isClientOrdinaryApplication()))
.isPresent();
}
Comment on lines +149 to +164

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n -C 6 \
  'getMdObject\(\)|ModuleType\.CommonModule|isClientManagedApplication|isClientOrdinaryApplication' \
  src/main/java src/test/java

Repository: 1c-syntax/bsl-language-server

Length of output: 50386


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the diagnostic implementation and targeted tests.
sed -n '1,230p' src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DeprecatedHttpConnectionMethodDiagnostic.java
printf '\n--- target tests ---\n'
fd -i 'DeprecatedHttpConnectionMethod.*Test\.java$' src/test/java -x sh -c 'echo "### $1"; sed -n "1,220p" "$1"' sh {}

# Inspect DocumentContext.getMdObject implementation(s) and CommonModule capability methods.
rg -n 'class DocumentContext|interface DocumentContext|Optional<MD> getMdObject|getMdObject\(' src/main/java/src/test/java 2>/dev/null || rg -n 'getMdObject|class DocumentContext|MdObject' src/main/java src/test/java --glob '*.java' | head -n 200
printf '\n--- CommonModule api declarations usages ---\n'
rg -n 'class CommonModule|interface CommonModule|isClientManagedApplication|isClientOrdinaryApplication|defaultModule|ModuleType\.(CommonModule|CommandModule|FormModule)' src/main/java --glob '*.java' | head -n 250

# Behavioral Java Optional probe if javac/javadoc is unavailable is not needed; use source and tests.

Repository: 1c-syntax/bsl-language-server

Length of output: 42262


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '--- DocumentContext.mdObject implementation ---\n'
sed -n '130,305p' src/main/java/com/github/_1c_syntax/bsl/languageserver/context/DocumentContext.java
printf '\n--- computeMdObject ---\n'
sed -n '430,475p' src/main/java/com/github/_1c_syntax/bsl/languageserver/context/DocumentContext.java

printf '\n--- DocumentContextTest relevant helpers ---\n'
sed -n '1,160p' src/test/java/com/github/_1c_syntax/bsl/languageserver/context/DocumentContextTest.java

printf '\n--- AbstractCommonModuleNameDiagnostic logic ---\n'
sed -n '1,125p' src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/AbstractCommonModuleNameDiagnostic.java

Repository: 1c-syntax/bsl-language-server

Length of output: 258


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- DocumentContext.mdObject implementation ---'
sed -n '130,305p' src/main/java/com/github/_1c_syntax/bsl/languageserver/context/DocumentContext.java
printf '%s\n' ''
printf '%s\n' '--- computeMdObject ---'
sed -n '430,475p' src/main/java/com/github/_1c_syntax/bsl/languageserver/context/DocumentContext.java

printf '%s\n' ''
printf '%s\n' '--- DocumentContextTest relevant helpers ---'
sed -n '1,160p' src	test/java/com/github/_1c_syntax/bsl/languageserver/context/DocumentContextTest.java

printf '%s\n' ''
printf '%s\n' '--- AbstractCommonModuleNameDiagnostic logic ---'
sed -n '1,125p' src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/AbstractCommonModuleNameDiagnostic.java

Repository: 1c-syntax/bsl-language-server

Length of output: 7886


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- DocumentContextTest relevant helpers ---'
sed -n '1,160p' src/test/java/com/github/_1c_syntax/bsl/languageserver/context/DocumentContextTest.java

printf '%s\n' ''
printf '%s\n' '--- AbstractCommonModuleNameDiagnostic logic ---'
sed -n '1,125p' src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/AbstractCommonModuleNameDiagnostic.java

printf '%s\n' ''
printf '%s\n' '--- findChild declarations/usages ---'
rg -n -C 5 'findChild|ConfigurationModule|findChildBy|findDocumentDocument|findDocument|getConfiguration\(' src/main/java --glob '*.java' | head -n 220

Repository: 1c-syntax/bsl-language-server

Length of output: 38408


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- Configuration findChild definitions ---'
rg -n -C 8 'interface Configuration|class .*Configuration|findChild|getModuleTypeByURI' src/main/java --glob '*.java' | sed -n '1,260p'

printf '%s\n' ''
printf '%s\n' '--- getModuleTypeByURI implementations/usages nearby ---'
rg -n -C 5 'getModuleTypeByURI' src/main/java --glob '*.java' | sed -n '1,260p'

Repository: 1c-syntax/bsl-language-server

Length of output: 36574


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- exact findChild/getModuleTypeByURI signatures/classes ---'
rg -n 'interface Configuration|class Abstract.*Configuration|class .*Configuration.*extends|Class<.*Configuration>|findChild\(URI|findChild\(MdoRef|findChild\(' src/main/java --glob '*.java' | head -n 120

printf '%s\n' ''
printf '%s\n' '--- computeConfiguration definitions/classes ---'
rg -n -C 6 'computeConfiguration|getModuleTypeByURI|getChildrenByMdoRef|getModuleTypeFor|ModuleTypeFor|MdoRefMap|mappings' src/main/java --glob '*.java' | head -n 300

Repository: 1c-syntax/bsl-language-server

Length of output: 27369


🌐 Web query:

GitHub com.github._1c_syntax bsl-language-server Configuration getModuleTypeByURI findChild

💡 Result:

In the bsl-language-server project, getModuleTypeByURI and findChild are distinct methods used within different parts of the codebase, primarily related to document context management and type resolution [1][2][3][4]. getModuleTypeByURI This method is primarily associated with resolving the type of a module (e.g., OScriptClass or OScriptModule) based on a document's URI [1][2]. It is notably used within the GlobalScopeProvider and as a fallback mechanism in DocumentContext to identify the module type when standard resolution is insufficient [1][3]. findChild In the context of bsl-language-server, findChild is an internal method used for looking up metadata objects (MD-objects) within the project's configuration structure based on a document's URI [4][5]. Specifically, it is implemented in DocumentContext (often via computeMdObject) to resolve an MD-object for a document [4][5]. Performance optimizations have been applied to this method—such as caching the result via a Lazy wrapper—because it is frequently called during indexing and reference resolution processes [4][5]. It is important to note that findChild is a common naming convention in many programming APIs (such as BeautifulSoup or Figma) [6][7], but in this specific GitHub repository, it refers to the server's internal logic for navigating the 1C configuration hierarchy [4][5].

Citations:


🌐 Web query:

site:github.com/1c-syntax/bsl-language-server "getModuleTypeByURI" ".getModuleTypeByURI" "Configuration"

💡 Result:

The term getModuleTypeByURI refers to an internal method used primarily within the context of the bsl-language-server, a language server project for BSL (1C:Enterprise) and OneScript development [1][2]. While it is not a public-facing configuration option, the method is used internally by the language server's type system and inference engines to determine the module type (such as BSL or OScript) of a document based on its URI [1][2]. Historically, this logic involved analyzing file extensions or paths to map a document to a specific ModuleType, which then influenced how the server provided features like autocompletion, type checking, and member lookup [1]. Recent architectural refactors in the bsl-language-server have evolved how type and module information is handled [3][2]. Modern implementations often rely on centralized services like TypeService or direct interactions with a TypeRegistry, moving away from explicit manual module type resolution where possible [3][2]. In many parts of the codebase, explicit references to ModuleType have been deprecated or reduced in favor of more dynamic or configuration-aware approaches [4][5][6]. In summary, getModuleTypeByURI is an internal programmatic helper method rather than a user-configurable setting. If you are encountering it, it is likely within the source code or debug logs of the language server, where it serves to identify the language context of the current file being processed [1][2].

Citations:


Handle missing common-module metadata before classifying client capability.

DocumentContext.getMdObject() comes from Configuration.findChild(getUri()) and can be empty for an open module without associated metadata. In that case, filter(...).isPresent() treats a client common module as strict server code and visitFile() skips it before client calls are checked. Use map(CommonModule.class::cast).map(common -> ...).orElse(true) or document why empty metadata is impossible for ModuleType.CommonModule, then add regression coverage for missing metadata.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DeprecatedHttpConnectionMethodDiagnostic.java`
around lines 149 - 164, Update isServerCommonModule to handle an empty
documentContext.getMdObject() safely: preserve the existing client-capability
check when CommonModule metadata exists, but return false when metadata is
missing so open common modules are not classified as strictly server-only. Add
regression coverage for a CommonModule with absent metadata and ensure
client-call checking still runs.


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
diagnosticMessage=Method "%s" of HTTPConnection object is deprecated. Use the asynchronous equivalent with "Async" suffix
diagnosticName=Deprecated HTTPConnection methods
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
diagnosticMessage=Метод "%s" объекта HTTPСоединение объявлен устаревшим. Используйте асинхронный аналог с суффиксом "Асинх"
diagnosticName=Устаревшие методы объекта HTTPСоединение
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* This file is a part of BSL Language Server.
*
* Copyright (c) 2018-2026
* Alexey Sosnoviy <labotamy@gmail.com>, Nikita Fedkin <nixel2007@gmail.com> and contributors
*
* SPDX-License-Identifier: LGPL-3.0-or-later
*
* BSL Language Server is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* BSL Language Server is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with BSL Language Server.
*/
package com.github._1c_syntax.bsl.languageserver.diagnostics;

import com.github._1c_syntax.bsl.languageserver.context.DocumentContext;
import com.github._1c_syntax.bsl.languageserver.types.TypeService;
import com.github._1c_syntax.bsl.languageserver.types.model.MemberDescriptor;
import com.github._1c_syntax.bsl.languageserver.types.model.TypeKind;
import com.github._1c_syntax.bsl.languageserver.types.model.TypeRef;
import com.github._1c_syntax.bsl.languageserver.util.TestUtils;
import com.github._1c_syntax.bsl.languageserver.utils.Ranges;
import com.github._1c_syntax.bsl.types.ModuleType;
import org.antlr.v4.runtime.tree.TerminalNode;
import org.eclipse.lsp4j.Diagnostic;
import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.Optional;

import static com.github._1c_syntax.bsl.languageserver.util.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;

class DeprecatedHttpConnectionMethodDiagnosticTest
extends AbstractDiagnosticTest<DeprecatedHttpConnectionMethodDiagnostic> {

DeprecatedHttpConnectionMethodDiagnosticTest() {
super(DeprecatedHttpConnectionMethodDiagnostic.class);
}

@Test
void testOnArrayDoesNotFire() {
initServerContext(TestUtils.PATH_TO_METADATA);
var documentContext = spy(getDocumentContext());
when(documentContext.getModuleType()).thenReturn(ModuleType.FormModule);
List<Diagnostic> diagnostics = getDiagnostics(documentContext);

// Массив.Получить/Удалить совпадают по имени, но TypeService
// резолвит владельца как Массив (не HTTPСоединение) → 0 срабатываний.
assertThat(diagnostics).isEmpty();
Comment on lines +52 to +61

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Add positive diagnostic cases.

This test only verifies that diagnostics are absent for an Array method. It does not verify that a supported HTTPConnection method produces a diagnostic.

Add parameterized positive cases for the supported Russian and English method names. Assert the diagnostic range and message. Keep this non-HTTP owner case.

As per coding guidelines, “Write comprehensive unit tests for each diagnostic including test cases for edge cases”.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DeprecatedHttpConnectionMethodDiagnosticTest.java`
around lines 39 - 47, Add parameterized positive tests alongside
testOnArrayDoesNotFire for supported Russian and English HTTPConnection method
names, asserting both the diagnostic range and message. Reuse the existing
diagnostic setup and expected-value conventions, while preserving the current
non-HTTP Array negative case.

Source: Coding guidelines

}

@Test
void testServerModuleDoesNotFire() {
var documentContext = spy(getDocumentContext());
when(documentContext.getModuleType()).thenReturn(ModuleType.ObjectModule);
List<Diagnostic> diagnostics = getDiagnostics(documentContext);

// Серверный модуль — visitFile возвращает ctx без обхода → 0.
assertThat(diagnostics).isEmpty();
}

@Test
void testServerDirectiveDoesNotFireButClientFires() {
var typeService = mock(TypeService.class);
var owner = new TypeRef(TypeKind.PLATFORM, "HTTPСоединение");
var typedMember = new TypeService.TypedMember(
owner,
MemberDescriptor.method("Получить"),
Ranges.create(0, 0, 8),
0
);
when(typeService.memberAt(any(DocumentContext.class), any(TerminalNode.class)))
.thenReturn(Optional.of(typedMember));

var diagnostic = new DeprecatedHttpConnectionMethodDiagnostic(typeService);
diagnostic.setInfo(diagnosticInstance.getInfo());

var documentContext = spy(getDocumentContext());
when(documentContext.getModuleType()).thenReturn(ModuleType.FormModule);

List<Diagnostic> diagnostics = diagnostic.getDiagnostics(documentContext);

// Фикстура: &НаКлиенте метод (срабатывает), &НаСервере и
// &НаСервереБезКонтекста (не срабатывают) → ровно 1 диагностика.
assertThat(diagnostics).hasSize(1);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
&НаКлиенте
Процедура КлиентскийМетод()
Соединение = Новый HTTPСоединение("example.com");
Соединение.Получить(Запрос, Ответ);
КонецПроцедуры

&НаСервере
Процедура СерверныйМетод()
Соединение = Новый HTTPСоединение("example.com");
Соединение.Получить(Запрос, Ответ);
КонецПроцедуры

&НаСервереБезКонтекста
Функция СервернаяФункция()
Соединение = Новый HTTPСоединение("example.com");
Соединение.ПолучитьЗаголовки(Запрос);
Возврат Истина;
КонецФункции
Loading