Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,35 @@ public void addMethodCall(URI uri, String mdoRef, ModuleType moduleType, String
locationRepository.updateLocation(symbolOccurrence);
}

/**
* Добавить ссылку на модуль в индекс.
*
* @param uri URI документа, откуда произошло обращение к модулю.
* @param mdoRef Ссылка на объект-метаданных модуля (например, CommonModule.ОбщийМодуль1).
* @param moduleType Тип модуля (например, {@link ModuleType#CommonModule}).
* @param range Диапазон, в котором происходит обращение к модулю.
*/
public void addModuleReference(URI uri, String mdoRef, ModuleType moduleType, Range range) {
var symbol = Symbol.builder()
.mdoRef(mdoRef)
.moduleType(moduleType)
.scopeName("")
.symbolKind(SymbolKind.Module)
.symbolName("")
.build()
.intern();

var location = new Location(uri, range);
var symbolOccurrence = SymbolOccurrence.builder()
.occurrenceType(OccurrenceType.REFERENCE)
.symbol(symbol)
.location(location)
.build();

symbolOccurrenceRepository.save(symbolOccurrence);
locationRepository.updateLocation(symbolOccurrence);
}

/**
* Добавить обращение к переменной в индекс.
*
Expand Down Expand Up @@ -269,6 +298,12 @@ private Optional<SourceDefinedSymbol> getSourceDefinedSymbol(Symbol symbolEntity
.or(() -> symbolTree.getVariableSymbol(symbolName, symbolTree.getModule())));
}

if (symbolEntity.symbolKind() == SymbolKind.Module) {
return serverContext.getDocument(mdoRef, moduleType)
.map(DocumentContext::getSymbolTree)
.map(SymbolTree::getModule);
}

return serverContext.getDocument(mdoRef, moduleType)
.map(DocumentContext::getSymbolTree)
.flatMap(symbolTree -> symbolTree.getMethodSymbol(symbolName));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.github._1c_syntax.bsl.languageserver.context.events.DocumentContextContentChangedEvent;
import com.github._1c_syntax.bsl.languageserver.context.symbol.SourceDefinedSymbol;
import com.github._1c_syntax.bsl.languageserver.context.symbol.VariableSymbol;
import com.github._1c_syntax.bsl.languageserver.utils.CommonModuleReference;
import com.github._1c_syntax.bsl.languageserver.utils.MdoRefBuilder;
import com.github._1c_syntax.bsl.languageserver.utils.Methods;
import com.github._1c_syntax.bsl.languageserver.utils.Modules;
Expand All @@ -47,7 +48,10 @@

import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
Expand Down Expand Up @@ -263,6 +267,7 @@ private class VariableSymbolReferenceIndexFinder extends BSLParserBaseVisitor<BS

private final DocumentContext documentContext;
private SourceDefinedSymbol currentScope;
private final Map<String, String> variableToCommonModuleMap = new HashMap<>();

@Override
public BSLParserRuleContext visitModuleVarDeclaration(BSLParser.ModuleVarDeclarationContext ctx) {
Expand Down Expand Up @@ -296,6 +301,37 @@ public BSLParserRuleContext visitSub(BSLParser.SubContext ctx) {
return result;
}

@Override
public BSLParserRuleContext visitAssignment(BSLParser.AssignmentContext ctx) {
// Detect pattern: Variable = ОбщегоНазначения.ОбщийМодуль("ModuleName") or Variable = ОбщийМодуль("ModuleName")
var lValue = ctx.lValue();
var expression = ctx.expression();

if (lValue != null && lValue.IDENTIFIER() != null && expression != null) {
if (CommonModuleReference.isCommonModuleExpression(expression)) {
var variableName = lValue.IDENTIFIER().getText();
CommonModuleReference.extractCommonModuleName(expression)
.flatMap(moduleName -> documentContext.getServerContext()
.getConfiguration()
.findCommonModule(moduleName))
.ifPresent(commonModule -> {
var mdoRef = commonModule.getMdoReference().getMdoRef();
variableToCommonModuleMap.put(variableName.toLowerCase(Locale.ENGLISH), mdoRef);

// Добавляем ссылку на модуль в индекс
index.addModuleReference(
documentContext.getUri(),
mdoRef,
ModuleType.CommonModule,
Ranges.create(expression)
);
});
}
}

return super.visitAssignment(ctx);
}

@Override
public BSLParserRuleContext visitLValue(BSLParser.LValueContext ctx) {
if (ctx.IDENTIFIER() == null) {
Expand Down Expand Up @@ -323,6 +359,21 @@ public BSLParserRuleContext visitCallStatement(BSLParser.CallStatementContext ct
}

var variableName = ctx.IDENTIFIER().getText();

// Check if variable references a common module
var commonModuleMdoRef = variableToCommonModuleMap.get(variableName.toLowerCase(Locale.ENGLISH));

if (commonModuleMdoRef != null) {
// Process method calls on the common module variable
// Check both modifiers and accessCall
if (!ctx.modifier().isEmpty()) {
processCommonModuleMethodCalls(ctx.modifier(), commonModuleMdoRef);
}
if (ctx.accessCall() != null) {
processCommonModuleAccessCall(ctx.accessCall(), commonModuleMdoRef);
}
}

findVariableSymbol(variableName)
.ifPresent(s -> addVariableUsage(
s.getRootParent(SymbolKind.Method), variableName, Ranges.create(ctx.IDENTIFIER()), true
Expand All @@ -338,6 +389,22 @@ public BSLParserRuleContext visitComplexIdentifier(BSLParser.ComplexIdentifierCo
}

var variableName = ctx.IDENTIFIER().getText();

// Check if we are inside a callStatement - if so, skip processing here to avoid duplication
var parentCallStatement = Trees.getRootParent(ctx, BSLParser.RULE_callStatement);
var isInsideCallStatement = false;
if (parentCallStatement instanceof BSLParser.CallStatementContext callStmt) {
isInsideCallStatement = callStmt.IDENTIFIER() != null
&& callStmt.IDENTIFIER().getText().equals(variableName);
}

// Check if variable references a common module
var commonModuleMdoRef = variableToCommonModuleMap.get(variableName.toLowerCase(Locale.ENGLISH));
if (commonModuleMdoRef != null && !ctx.modifier().isEmpty() && !isInsideCallStatement) {
// Process method calls on the common module variable
processCommonModuleMethodCalls(ctx.modifier(), commonModuleMdoRef);
}

findVariableSymbol(variableName)
.ifPresent(s -> addVariableUsage(
s.getRootParent(SymbolKind.Method), variableName, Ranges.create(ctx.IDENTIFIER()), true
Expand Down Expand Up @@ -435,5 +502,30 @@ private void addVariableUsage(Optional<SourceDefinedSymbol> methodSymbol,
!usage
);
}

private void processCommonModuleMethodCalls(List<? extends BSLParser.ModifierContext> modifiers, String mdoRef) {
for (var modifier : modifiers) {
var accessCall = modifier.accessCall();
if (accessCall != null) {
processCommonModuleAccessCall(accessCall, mdoRef);
}
}
}

private void processCommonModuleAccessCall(BSLParser.AccessCallContext accessCall, String mdoRef) {
var methodCall = accessCall.methodCall();
if (methodCall != null && methodCall.methodName() != null) {
var methodNameToken = methodCall.methodName().IDENTIFIER();
if (methodNameToken != null) {
index.addMethodCall(
documentContext.getUri(),
mdoRef,
ModuleType.CommonModule,
methodNameToken.getText(),
Ranges.create(methodNameToken)
);
}
}
}
}
}
Loading
Loading