From 5e2b7c9830700b4bbf6da2e272d24024394098a7 Mon Sep 17 00:00:00 2001 From: alkoleft Date: Wed, 2 Nov 2022 11:54:12 +0300 Subject: [PATCH 1/2] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B2=D0=B0=D1=8F=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=BF=D1=8B=D1=82=D0=BA=D0=B0=20=D0=BE=D1=80=D0=B3?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D1=8C=20=D0=BA?= =?UTF-8?q?=D0=BE=D0=BD=D1=82=D0=B5=D0=BA=D1=81=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../languageserver/scope/AbstractContext.java | 38 ++++++ .../bsl/languageserver/scope/Capability.java | 7 ++ .../scope/ConfigurationContext.java | 56 +++++++++ .../languageserver/scope/FilteredContext.java | 5 + .../bsl/languageserver/scope/IScope.java | 48 ++++++++ .../bsl/languageserver/scope/IScopeOwner.java | 24 ++++ .../languageserver/scope/ScopeResolver.java | 111 ++++++++++++++++++ .../languageserver/scope/UnionContext.java | 41 +++++++ .../scope/ScopeResolverTest.java | 47 ++++++++ 9 files changed, 377 insertions(+) create mode 100644 src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/AbstractContext.java create mode 100644 src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/Capability.java create mode 100644 src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/ConfigurationContext.java create mode 100644 src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/FilteredContext.java create mode 100644 src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/IScope.java create mode 100644 src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/IScopeOwner.java create mode 100644 src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/ScopeResolver.java create mode 100644 src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/UnionContext.java create mode 100644 src/test/java/com/github/_1c_syntax/bsl/languageserver/scope/ScopeResolverTest.java diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/AbstractContext.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/AbstractContext.java new file mode 100644 index 00000000000..e48e49c757b --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/AbstractContext.java @@ -0,0 +1,38 @@ +package com.github._1c_syntax.bsl.languageserver.scope; + +import com.github._1c_syntax.bsl.languageserver.context.symbol.MethodSymbol; +import org.apache.commons.collections4.map.CaseInsensitiveMap; + +import java.util.Optional; +import java.util.Set; +import java.util.stream.Stream; + +public class AbstractContext implements IScope { + protected final CaseInsensitiveMap methods = new CaseInsensitiveMap<>(); + protected final CaseInsensitiveMap properties = new CaseInsensitiveMap<>(); + + @Override + public Set getCapabilities() { + return null; + } + + @Override + public Stream getMethods() { + return methods.values().stream(); + } + + @Override + public Stream getProperties() { + return properties.values().stream(); + } + + @Override + public Optional getMethod(String name) { + return Optional.of(methods.get(name)); + } + + @Override + public IScopeOwner getProperty(String name) { + return properties.get(name); + } +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/Capability.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/Capability.java new file mode 100644 index 00000000000..ece66a1c14d --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/Capability.java @@ -0,0 +1,7 @@ +package com.github._1c_syntax.bsl.languageserver.scope; + +public enum Capability { + CLIENT, + SERVER, + PUBLIC +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/ConfigurationContext.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/ConfigurationContext.java new file mode 100644 index 00000000000..b606740b26c --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/ConfigurationContext.java @@ -0,0 +1,56 @@ +package com.github._1c_syntax.bsl.languageserver.scope; + +import com.github._1c_syntax.bsl.languageserver.context.ServerContext; +import com.github._1c_syntax.bsl.languageserver.context.symbol.MethodSymbol; +import com.github._1c_syntax.mdclasses.mdo.MDCommonModule; + +import java.util.Collection; +import java.util.Collections; +import java.util.Optional; + +public class ConfigurationContext extends AbstractContext { + + private final ServerContext serverContext; + private final ScopeResolver scopeResolver; + + public ConfigurationContext(ServerContext serverContext, ScopeResolver scopeResolver) { + this.serverContext = serverContext; + this.scopeResolver = scopeResolver; + for (var module : serverContext.getConfiguration().getCommonModules().values()) { + if (module.isGlobal()) { + appendGlobalCommonModule(module); + } else { + appendCommonModule(module); + } + } + } + + void appendCommonModule(MDCommonModule module) { + properties.put(module.getName(), IScopeOwner.create(module, scopeResolver.createSCope(module))); + } + + void appendGlobalCommonModule(MDCommonModule module) { + for (var method : getMethods(module, serverContext)) { + methods.put(method.getName(), method); + } + } + + static Collection getMethods(MDCommonModule module, ServerContext serverContext) { + var url = module.getModules().get(0).getUri(); + var document = serverContext.getDocument(url); + if (document == null) { + return Collections.emptyList(); + } + + return document.getSymbolTree().getMethods(); + } + + static Optional getMethod(MDCommonModule module, ServerContext serverContext, String name) { + var url = module.getModules().get(0).getUri(); + var document = serverContext.getDocument(url); + if (document == null) { + return Optional.empty(); + } + return document.getSymbolTree().getMethodSymbol(name); + } +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/FilteredContext.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/FilteredContext.java new file mode 100644 index 00000000000..edcdc30c32b --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/FilteredContext.java @@ -0,0 +1,5 @@ +package com.github._1c_syntax.bsl.languageserver.scope; + +public class FilteredContext { + +} \ No newline at end of file diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/IScope.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/IScope.java new file mode 100644 index 00000000000..44572ac14bd --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/IScope.java @@ -0,0 +1,48 @@ +package com.github._1c_syntax.bsl.languageserver.scope; + +import com.github._1c_syntax.bsl.languageserver.context.symbol.MethodSymbol; + +import java.util.Collections; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Stream; + +public interface IScope { + IScope EMPTY = new IScope() { + + @Override + public Set getCapabilities() { + return Collections.emptySet(); + } + + @Override + public Stream getMethods() { + return Stream.empty(); + } + + @Override + public Stream getProperties() { + return Stream.empty(); + } + + @Override + public Optional getMethod(String name) { + return Optional.empty(); + } + + @Override + public IScopeOwner getProperty(String name) { + return null; + } + }; + + Set getCapabilities(); + + Stream getMethods(); + + Stream getProperties(); + + Optional getMethod(String name); + + IScopeOwner getProperty(String name); +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/IScopeOwner.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/IScopeOwner.java new file mode 100644 index 00000000000..f1c001c8733 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/IScopeOwner.java @@ -0,0 +1,24 @@ +package com.github._1c_syntax.bsl.languageserver.scope; + +import com.github._1c_syntax.bsl.mdo.MDObject; +import lombok.RequiredArgsConstructor; + +public interface IScopeOwner { + + static IScopeOwner create(MDObject object, IScope scope) { + return new MDObjectScopeOwner(object, scope); + } + + IScope getScope(); + + @RequiredArgsConstructor + class MDObjectScopeOwner implements IScopeOwner { + private final MDObject owner; + private final IScope scope; + + @Override + public IScope getScope() { + return scope; + } + } +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/ScopeResolver.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/ScopeResolver.java new file mode 100644 index 00000000000..425338af0a0 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/ScopeResolver.java @@ -0,0 +1,111 @@ +package com.github._1c_syntax.bsl.languageserver.scope; + +import com.github._1c_syntax.bsl.languageserver.context.DocumentContext; +import com.github._1c_syntax.bsl.languageserver.context.ServerContext; +import com.github._1c_syntax.bsl.languageserver.context.symbol.MethodSymbol; +import com.github._1c_syntax.mdclasses.mdo.MDCommonModule; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +import java.util.Collection; +import java.util.Collections; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Stream; + +@Component +@RequiredArgsConstructor +public class ScopeResolver { + + private final ServerContext serverContext; + + public IScope getScope(DocumentContext document) { + return UnionContext.builder() + .innerScope(getFilteredScope(getGlobalScope(), getCapabilities(document))) + .innerScope(getPrivateScope(document)) + .build(); + + } + + public IScope getGlobalScope() { + return UnionContext.builder() + .innerScope(getConfigurationScope()) + .innerScope(getPlatformScope()) + .build(); + } + + public IScope getConfigurationScope() { + return new ConfigurationContext(serverContext, this); + } + + public IScope getPlatformScope() { + return IScope.EMPTY; + } + + public IScope getPrivateScope(DocumentContext document) { + return IScope.EMPTY; + } + + private IScope getFilteredScope(IScope scope, Set capabilities) { + return IScope.EMPTY; + } + + private Set getCapabilities(DocumentContext document) { + return Collections.emptySet(); + } + + static Collection getMethods(MDCommonModule module, ServerContext serverContext) { + var url = module.getModules().get(0).getUri(); + var document = serverContext.getDocument(url); + if (document == null) { + return Collections.emptyList(); + } + + return document.getSymbolTree().getMethods(); + } + + static Optional getMethod(MDCommonModule module, ServerContext serverContext, String name) { + var url = module.getModules().get(0).getUri(); + var document = serverContext.getDocument(url); + if (document == null) { + return Optional.empty(); + } + return document.getSymbolTree().getMethodSymbol(name); + } + + IScope createSCope(MDCommonModule module) { + return new CommonModuleScope(module, serverContext); + } + + @RequiredArgsConstructor + static class CommonModuleScope implements IScope { + + private final MDCommonModule module; + private final ServerContext serverContext; + + @Override + public Set getCapabilities() { + return Collections.emptySet(); + } + + @Override + public Stream getMethods() { + return ScopeResolver.getMethods(module, serverContext).stream(); + } + + @Override + public Stream getProperties() { + return Stream.empty(); + } + + @Override + public Optional getMethod(String name) { + return ScopeResolver.getMethod(module, serverContext, name); + } + + @Override + public IScopeOwner getProperty(String name) { + return null; + } + } +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/UnionContext.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/UnionContext.java new file mode 100644 index 00000000000..64ade079a1f --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/UnionContext.java @@ -0,0 +1,41 @@ +package com.github._1c_syntax.bsl.languageserver.scope; + +import com.github._1c_syntax.bsl.languageserver.context.symbol.MethodSymbol; +import lombok.Builder; +import lombok.Singular; + +import java.util.Collection; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Stream; + +@Builder +public class UnionContext implements IScope{ + @Singular + private CollectioninnerScopes; + + @Override + public Set getCapabilities() { + return null; + } + + @Override + public Stream getMethods() { + return null; + } + + @Override + public Stream getProperties() { + return null; + } + + @Override + public Optional getMethod(String name) { + return Optional.empty(); + } + + @Override + public IScopeOwner getProperty(String name) { + return null; + } +} diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/scope/ScopeResolverTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/scope/ScopeResolverTest.java new file mode 100644 index 00000000000..9105f035762 --- /dev/null +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/scope/ScopeResolverTest.java @@ -0,0 +1,47 @@ +package com.github._1c_syntax.bsl.languageserver.scope; + +import com.github._1c_syntax.bsl.languageserver.context.ServerContext; +import com.github._1c_syntax.bsl.languageserver.util.CleanupContextBeforeClassAndAfterClass; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import javax.annotation.PostConstruct; +import java.nio.file.Paths; + +import static com.github._1c_syntax.bsl.languageserver.util.TestUtils.PATH_TO_METADATA; + +@SpringBootTest +@CleanupContextBeforeClassAndAfterClass +class ScopeResolverTest { + + @Autowired + ScopeResolver resolver; + + @Autowired + private ServerContext serverContext; + + private static final String PATH_TO_FILE = "./src/test/resources/providers/references.bsl"; + + @PostConstruct + void prepareServerContext() { + serverContext.setConfigurationRoot(Paths.get(PATH_TO_METADATA)); + serverContext.populateContext(); + } + + @Test + void getConfigurationScope(){ + var configurationScope = resolver.getConfigurationScope(); + configurationScope.getMethod("ГлобальнаяСервернаяПроцедура"); + configurationScope.getProperty("ПервыйОбщийМодуль"); + configurationScope.getProperty("Документы").getScope().getProperty("Документ1"); + configurationScope.getProperty("Catalogs").getScope().getProperty("Справочник1").getScope().getMethod("ТестЭкспортная"); + + configurationScope = resolver.getGlobalScope(); + configurationScope.getMethod("ГлобальнаяСервернаяПроцедура"); + configurationScope.getProperty("ПервыйОбщийМодуль"); + configurationScope.getProperty("Документы").getScope().getProperty("Документ1"); + configurationScope.getProperty("Catalogs").getScope().getProperty("Справочник1").getScope().getMethod("ТестЭкспортная"); + } + +} \ No newline at end of file From 5dac47935921ecff46fed7c9fc1a9a7aed7a2889 Mon Sep 17 00:00:00 2001 From: alkoleft Date: Mon, 7 Nov 2022 12:43:43 +0300 Subject: [PATCH 2/2] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D1=80=D0=B0=D0=B1?= =?UTF-8?q?=D0=BE=D1=82=D0=B0=D0=BB=20=D0=BC=D0=B5=D1=85=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D0=B7=D0=BC=20=D0=BA=D0=BE=D0=BD=D1=82=D0=B5=D0=BA=D1=81=D1=82?= =?UTF-8?q?=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bsl/languageserver/scope/BaseScope.java | 35 +++++ .../scope/ConfigurationContext.java | 56 -------- .../scope/ConfigurationScope.java | 62 ++++++++ .../bsl/languageserver/scope/IScope.java | 31 +--- .../bsl/languageserver/scope/IScopeOwner.java | 25 ++-- .../languageserver/scope/ScopeProvider.java | 40 ++++++ .../languageserver/scope/ScopeResolver.java | 134 +++++++++++------- ...{AbstractContext.java => SimpleScope.java} | 12 +- ...edContext.java => ThisObjectResolver.java} | 4 +- .../languageserver/scope/UnionContext.java | 31 ++-- .../bsl/languageserver/scope/Utils.java | 45 ++++++ ...solverTest.java => ScopeProviderTest.java} | 36 +++-- 12 files changed, 322 insertions(+), 189 deletions(-) create mode 100644 src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/BaseScope.java delete mode 100644 src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/ConfigurationContext.java create mode 100644 src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/ConfigurationScope.java create mode 100644 src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/ScopeProvider.java rename src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/{AbstractContext.java => SimpleScope.java} (77%) rename src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/{FilteredContext.java => ThisObjectResolver.java} (61%) create mode 100644 src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/Utils.java rename src/test/java/com/github/_1c_syntax/bsl/languageserver/scope/{ScopeResolverTest.java => ScopeProviderTest.java} (50%) diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/BaseScope.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/BaseScope.java new file mode 100644 index 00000000000..264270220fe --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/BaseScope.java @@ -0,0 +1,35 @@ +package com.github._1c_syntax.bsl.languageserver.scope; + +import com.github._1c_syntax.bsl.languageserver.context.symbol.MethodSymbol; + +import java.util.Collections; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Stream; + +public class BaseScope implements IScope { + @Override + public Set getCapabilities() { + return Collections.emptySet(); + } + + @Override + public Stream getMethods() { + return Stream.empty(); + } + + @Override + public Stream getProperties() { + return Stream.empty(); + } + + @Override + public Optional getMethod(String name) { + return Optional.empty(); + } + + @Override + public Optional getProperty(String name) { + return Optional.empty(); + } +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/ConfigurationContext.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/ConfigurationContext.java deleted file mode 100644 index b606740b26c..00000000000 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/ConfigurationContext.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.github._1c_syntax.bsl.languageserver.scope; - -import com.github._1c_syntax.bsl.languageserver.context.ServerContext; -import com.github._1c_syntax.bsl.languageserver.context.symbol.MethodSymbol; -import com.github._1c_syntax.mdclasses.mdo.MDCommonModule; - -import java.util.Collection; -import java.util.Collections; -import java.util.Optional; - -public class ConfigurationContext extends AbstractContext { - - private final ServerContext serverContext; - private final ScopeResolver scopeResolver; - - public ConfigurationContext(ServerContext serverContext, ScopeResolver scopeResolver) { - this.serverContext = serverContext; - this.scopeResolver = scopeResolver; - for (var module : serverContext.getConfiguration().getCommonModules().values()) { - if (module.isGlobal()) { - appendGlobalCommonModule(module); - } else { - appendCommonModule(module); - } - } - } - - void appendCommonModule(MDCommonModule module) { - properties.put(module.getName(), IScopeOwner.create(module, scopeResolver.createSCope(module))); - } - - void appendGlobalCommonModule(MDCommonModule module) { - for (var method : getMethods(module, serverContext)) { - methods.put(method.getName(), method); - } - } - - static Collection getMethods(MDCommonModule module, ServerContext serverContext) { - var url = module.getModules().get(0).getUri(); - var document = serverContext.getDocument(url); - if (document == null) { - return Collections.emptyList(); - } - - return document.getSymbolTree().getMethods(); - } - - static Optional getMethod(MDCommonModule module, ServerContext serverContext, String name) { - var url = module.getModules().get(0).getUri(); - var document = serverContext.getDocument(url); - if (document == null) { - return Optional.empty(); - } - return document.getSymbolTree().getMethodSymbol(name); - } -} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/ConfigurationScope.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/ConfigurationScope.java new file mode 100644 index 00000000000..41bc6cd3faf --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/ConfigurationScope.java @@ -0,0 +1,62 @@ +package com.github._1c_syntax.bsl.languageserver.scope; + +import com.github._1c_syntax.bsl.languageserver.context.ServerContext; +import com.github._1c_syntax.bsl.types.MDOType; +import com.github._1c_syntax.mdclasses.mdo.MDCommonModule; + +import java.util.Collection; +import java.util.Set; + +public class ConfigurationScope extends SimpleScope { + + private static final Collection rootProperties = Set.of( + MDOType.EXCHANGE_PLAN, + MDOType.CONSTANT, + MDOType.CATALOG, + MDOType.DOCUMENT, + MDOType.DOCUMENT_JOURNAL, + MDOType.ENUM, + MDOType.REPORT, + MDOType.DATA_PROCESSOR, + MDOType.CHART_OF_CHARACTERISTIC_TYPES, + MDOType.CHART_OF_ACCOUNTS, + MDOType.CHART_OF_CALCULATION_TYPES, + MDOType.INFORMATION_REGISTER, + MDOType.ACCUMULATION_REGISTER, + MDOType.ACCOUNTING_REGISTER, + MDOType.CALCULATION_REGISTER, + MDOType.BUSINESS_PROCESS, + MDOType.TASK, + MDOType.EXTERNAL_DATA_SOURCE); + + private final ServerContext serverContext; + + public ConfigurationScope(ServerContext serverContext) { + this.serverContext = serverContext; + + for (var module : serverContext.getConfiguration().getCommonModules().values()) { + if (module.isGlobal()) { + appendGlobalCommonModule(module); + } else { + appendCommonModule(module); + } + } + + for (var type : rootProperties) { + var property = IScopeOwner.create(type); + properties.put(type.getGroupName(), property); + properties.put(type.getGroupNameRu(), property); + } + + } + + private void appendCommonModule(MDCommonModule module) { + properties.put(module.getName(), IScopeOwner.create(module)); + } + + private void appendGlobalCommonModule(MDCommonModule module) { + for (var method : Utils.getMethods(module, serverContext)) { + methods.put(method.getName(), method); + } + } +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/IScope.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/IScope.java index 44572ac14bd..15312745bae 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/IScope.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/IScope.java @@ -2,39 +2,12 @@ import com.github._1c_syntax.bsl.languageserver.context.symbol.MethodSymbol; -import java.util.Collections; import java.util.Optional; import java.util.Set; import java.util.stream.Stream; public interface IScope { - IScope EMPTY = new IScope() { - - @Override - public Set getCapabilities() { - return Collections.emptySet(); - } - - @Override - public Stream getMethods() { - return Stream.empty(); - } - - @Override - public Stream getProperties() { - return Stream.empty(); - } - - @Override - public Optional getMethod(String name) { - return Optional.empty(); - } - - @Override - public IScopeOwner getProperty(String name) { - return null; - } - }; + IScope EMPTY = new BaseScope(); Set getCapabilities(); @@ -44,5 +17,5 @@ public IScopeOwner getProperty(String name) { Optional getMethod(String name); - IScopeOwner getProperty(String name); + Optional getProperty(String name); } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/IScopeOwner.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/IScopeOwner.java index f1c001c8733..ce0da171985 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/IScopeOwner.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/IScopeOwner.java @@ -1,24 +1,17 @@ package com.github._1c_syntax.bsl.languageserver.scope; -import com.github._1c_syntax.bsl.mdo.MDObject; -import lombok.RequiredArgsConstructor; +import lombok.Getter; -public interface IScopeOwner { +public class IScopeOwner { - static IScopeOwner create(MDObject object, IScope scope) { - return new MDObjectScopeOwner(object, scope); + public static IScopeOwner create(Object owner) { + return new IScopeOwner(owner); } - IScope getScope(); - - @RequiredArgsConstructor - class MDObjectScopeOwner implements IScopeOwner { - private final MDObject owner; - private final IScope scope; - - @Override - public IScope getScope() { - return scope; - } + private IScopeOwner(Object owner) { + this.owner = owner; } + + @Getter + private final Object owner; } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/ScopeProvider.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/ScopeProvider.java new file mode 100644 index 00000000000..b70e394970c --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/ScopeProvider.java @@ -0,0 +1,40 @@ +package com.github._1c_syntax.bsl.languageserver.scope; + +import com.github._1c_syntax.bsl.languageserver.context.DocumentContext; +import com.github._1c_syntax.utils.Lazy; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class ScopeProvider { + + private final ScopeResolver resolver; + private final Lazy configurationScope = new Lazy<>(this::createConfigurationScope); + + public IScope getGlobalScope() { + return UnionContext.builder() + .innerScope(getConfigurationScope()) + .innerScope(resolver.getPlatformScope()) + .build(); + } + + public IScope getConfigurationScope() { + return configurationScope.getOrCompute(); + } + + public IScope getScope(DocumentContext document) { + return UnionContext.builder() + .innerScope(resolver.createFilteredScope(getGlobalScope(), resolver.getCapabilities(document))) + .innerScope(resolver.createScope(document)) + .build(); + } + + public IScope getScope(IScopeOwner owner) { + return resolver.createScope(owner); + } + + private ConfigurationScope createConfigurationScope(){ + return resolver.createConfigurationScope(); + } +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/ScopeResolver.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/ScopeResolver.java index 425338af0a0..3aca21e2824 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/ScopeResolver.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/ScopeResolver.java @@ -3,11 +3,16 @@ import com.github._1c_syntax.bsl.languageserver.context.DocumentContext; import com.github._1c_syntax.bsl.languageserver.context.ServerContext; import com.github._1c_syntax.bsl.languageserver.context.symbol.MethodSymbol; +import com.github._1c_syntax.bsl.mdo.MDObject; +import com.github._1c_syntax.bsl.mdo.ModuleOwner; +import com.github._1c_syntax.bsl.types.MDOType; import com.github._1c_syntax.mdclasses.mdo.MDCommonModule; +import com.github._1c_syntax.mdclasses.mdo.MDOHasChildren; +import com.github._1c_syntax.mdclasses.mdo.attributes.AbstractMDOAttribute; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; -import java.util.Collection; +import java.net.URI; import java.util.Collections; import java.util.Optional; import java.util.Set; @@ -19,93 +24,124 @@ public class ScopeResolver { private final ServerContext serverContext; - public IScope getScope(DocumentContext document) { - return UnionContext.builder() - .innerScope(getFilteredScope(getGlobalScope(), getCapabilities(document))) - .innerScope(getPrivateScope(document)) - .build(); - - } - - public IScope getGlobalScope() { - return UnionContext.builder() - .innerScope(getConfigurationScope()) - .innerScope(getPlatformScope()) - .build(); - } - - public IScope getConfigurationScope() { - return new ConfigurationContext(serverContext, this); - } - public IScope getPlatformScope() { return IScope.EMPTY; } - public IScope getPrivateScope(DocumentContext document) { + public IScope createScope(IScopeOwner owner) { + if (owner.getOwner() instanceof MDOType) { + return new MDOTypeScope((MDOType) owner.getOwner(), serverContext); + } else if (owner.getOwner() instanceof MDObject) { + return createScope((MDObject) owner.getOwner()); + } return IScope.EMPTY; } - private IScope getFilteredScope(IScope scope, Set capabilities) { + public IScope createScope(DocumentContext document) { return IScope.EMPTY; } - private Set getCapabilities(DocumentContext document) { - return Collections.emptySet(); + IScope createFilteredScope(IScope scope, Set capabilities) { + return scope; + } + + ConfigurationScope createConfigurationScope() { + return new ConfigurationScope(serverContext); } - static Collection getMethods(MDCommonModule module, ServerContext serverContext) { - var url = module.getModules().get(0).getUri(); - var document = serverContext.getDocument(url); - if (document == null) { - return Collections.emptyList(); + IScope createScope(MDObject object) { + var builder = UnionContext.builder(); + + if (object instanceof MDCommonModule) { + builder.innerScope(new CommonModuleScope((MDCommonModule) object, serverContext)); + } else if (object instanceof ModuleOwner) { + var uri = Utils.getManagerModuleURI((ModuleOwner) object, serverContext); + if (uri != null) { + builder.innerScope(new ModuleScope(uri, serverContext)); + } } +// if (object instanceof MDOHasChildren) { +// builder.innerScope(new MDOHasChildrenScope((MDOHasChildren) object)); +// } - return document.getSymbolTree().getMethods(); + return builder.build(); } - static Optional getMethod(MDCommonModule module, ServerContext serverContext, String name) { - var url = module.getModules().get(0).getUri(); - var document = serverContext.getDocument(url); - if (document == null) { - return Optional.empty(); - } - return document.getSymbolTree().getMethodSymbol(name); + Set getCapabilities(DocumentContext document) { + return Collections.emptySet(); } - IScope createSCope(MDCommonModule module) { - return new CommonModuleScope(module, serverContext); + @RequiredArgsConstructor + static class MDOTypeScope extends BaseScope { + private final MDOType type; + private final ServerContext serverContext; + + @Override + public Stream getProperties() { + return serverContext.getConfiguration().getOrderedTopMDObjects().get(type).stream() + .map(IScopeOwner::create); + } + + @Override + public Optional getProperty(String name) { + return serverContext.getConfiguration().getOrderedTopMDObjects().get(type).stream() + .filter(abstractMDObjectBase -> abstractMDObjectBase.getName().equalsIgnoreCase(name)) + .map(IScopeOwner::create) + .findFirst(); + } } @RequiredArgsConstructor - static class CommonModuleScope implements IScope { + static class CommonModuleScope extends BaseScope { private final MDCommonModule module; private final ServerContext serverContext; @Override - public Set getCapabilities() { - return Collections.emptySet(); + public Stream getMethods() { + return Utils.getMethods(module, serverContext).stream(); } @Override - public Stream getMethods() { - return ScopeResolver.getMethods(module, serverContext).stream(); + public Optional getMethod(String name) { + return Utils.getMethod(module, serverContext, name); } + } + + @RequiredArgsConstructor + static class ModuleScope extends BaseScope { + private final URI moduleUri; + private final ServerContext serverContext; @Override - public Stream getProperties() { - return Stream.empty(); + public Stream getMethods() { + return Utils.getMethods(moduleUri, serverContext).stream(); } @Override public Optional getMethod(String name) { - return ScopeResolver.getMethod(module, serverContext, name); + return Utils.getMethod(moduleUri, serverContext, name); + } + } + + @RequiredArgsConstructor + static class MDOHasChildrenScope extends BaseScope { + private final MDOHasChildren object; + + @Override + public Stream getProperties() { + return object.getChildren().stream() + .filter(AbstractMDOAttribute.class::isInstance) + .map(IScopeOwner::create); } @Override - public IScopeOwner getProperty(String name) { - return null; + public Optional getProperty(String name) { + return object.getChildren().stream() + .filter(AbstractMDOAttribute.class::isInstance) + .filter(it -> it.getName().equalsIgnoreCase(name)) + .map(IScopeOwner::create) + .findFirst(); } } } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/AbstractContext.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/SimpleScope.java similarity index 77% rename from src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/AbstractContext.java rename to src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/SimpleScope.java index e48e49c757b..62d875cea3f 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/AbstractContext.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/SimpleScope.java @@ -4,18 +4,12 @@ import org.apache.commons.collections4.map.CaseInsensitiveMap; import java.util.Optional; -import java.util.Set; import java.util.stream.Stream; -public class AbstractContext implements IScope { +public class SimpleScope extends BaseScope { protected final CaseInsensitiveMap methods = new CaseInsensitiveMap<>(); protected final CaseInsensitiveMap properties = new CaseInsensitiveMap<>(); - @Override - public Set getCapabilities() { - return null; - } - @Override public Stream getMethods() { return methods.values().stream(); @@ -32,7 +26,7 @@ public Optional getMethod(String name) { } @Override - public IScopeOwner getProperty(String name) { - return properties.get(name); + public Optional getProperty(String name) { + return Optional.ofNullable(properties.get(name)); } } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/FilteredContext.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/ThisObjectResolver.java similarity index 61% rename from src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/FilteredContext.java rename to src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/ThisObjectResolver.java index edcdc30c32b..9e85dec761e 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/FilteredContext.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/ThisObjectResolver.java @@ -1,5 +1,5 @@ package com.github._1c_syntax.bsl.languageserver.scope; -public class FilteredContext { +public class ThisObjectResolver { -} \ No newline at end of file +} diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/UnionContext.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/UnionContext.java index 64ade079a1f..0dc23e028eb 100644 --- a/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/UnionContext.java +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/UnionContext.java @@ -6,36 +6,41 @@ import java.util.Collection; import java.util.Optional; -import java.util.Set; import java.util.stream.Stream; @Builder -public class UnionContext implements IScope{ - @Singular - private CollectioninnerScopes; +public class UnionContext extends BaseScope { - @Override - public Set getCapabilities() { - return null; - } + @Singular + private Collection innerScopes; @Override public Stream getMethods() { - return null; + return innerScopes.stream() + .flatMap(IScope::getMethods); } @Override public Stream getProperties() { - return null; + return innerScopes.stream() + .flatMap(IScope::getProperties); } @Override public Optional getMethod(String name) { - return Optional.empty(); + return innerScopes.stream() + .map(it -> it.getMethod(name)) + .filter(Optional::isPresent) + .findFirst() + .orElseGet(Optional::empty); } @Override - public IScopeOwner getProperty(String name) { - return null; + public Optional getProperty(String name) { + return innerScopes.stream() + .map(it -> it.getProperty(name)) + .filter(Optional::isPresent) + .findFirst() + .orElseGet(Optional::empty); } } diff --git a/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/Utils.java b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/Utils.java new file mode 100644 index 00000000000..ec065383e84 --- /dev/null +++ b/src/main/java/com/github/_1c_syntax/bsl/languageserver/scope/Utils.java @@ -0,0 +1,45 @@ +package com.github._1c_syntax.bsl.languageserver.scope; + +import com.github._1c_syntax.bsl.languageserver.context.ServerContext; +import com.github._1c_syntax.bsl.languageserver.context.symbol.MethodSymbol; +import com.github._1c_syntax.bsl.mdo.ModuleOwner; +import com.github._1c_syntax.bsl.types.ModuleType; +import com.github._1c_syntax.mdclasses.mdo.MDCommonModule; + +import java.net.URI; +import java.util.Collection; +import java.util.Collections; +import java.util.Optional; + +public class Utils { + + public static Collection getMethods(MDCommonModule module, ServerContext serverContext) { + return getMethods(module.getModules().get(0).getUri(), serverContext); + } + + public static Collection getMethods(URI moduleUri, ServerContext serverContext) { + var document = serverContext.getDocument(moduleUri); + if (document == null) { + return Collections.emptyList(); + } + + return document.getSymbolTree().getMethods(); + } + + public static Optional getMethod(MDCommonModule module, ServerContext serverContext, String name) { + return getMethod(module.getModules().get(0).getUri(), serverContext, name); + } + + public static Optional getMethod(URI moduleUri, ServerContext serverContext, String name) { + var document = serverContext.getDocument(moduleUri); + if (document == null) { + return Optional.empty(); + } + return document.getSymbolTree().getMethodSymbol(name); + } + + public static URI getManagerModuleURI(ModuleOwner object, ServerContext serverContext) { + var modules = serverContext.getConfiguration().getModulesByMDORef(object.getMdoReference().getMdoRef()); + return modules.get(ModuleType.ManagerModule); + } +} diff --git a/src/test/java/com/github/_1c_syntax/bsl/languageserver/scope/ScopeResolverTest.java b/src/test/java/com/github/_1c_syntax/bsl/languageserver/scope/ScopeProviderTest.java similarity index 50% rename from src/test/java/com/github/_1c_syntax/bsl/languageserver/scope/ScopeResolverTest.java rename to src/test/java/com/github/_1c_syntax/bsl/languageserver/scope/ScopeProviderTest.java index 9105f035762..6826e50779a 100644 --- a/src/test/java/com/github/_1c_syntax/bsl/languageserver/scope/ScopeResolverTest.java +++ b/src/test/java/com/github/_1c_syntax/bsl/languageserver/scope/ScopeProviderTest.java @@ -10,13 +10,13 @@ import java.nio.file.Paths; import static com.github._1c_syntax.bsl.languageserver.util.TestUtils.PATH_TO_METADATA; +import static org.junit.jupiter.api.Assertions.*; @SpringBootTest @CleanupContextBeforeClassAndAfterClass -class ScopeResolverTest { - +class ScopeProviderTest { @Autowired - ScopeResolver resolver; + ScopeProvider provider; @Autowired private ServerContext serverContext; @@ -30,18 +30,24 @@ void prepareServerContext() { } @Test - void getConfigurationScope(){ - var configurationScope = resolver.getConfigurationScope(); - configurationScope.getMethod("ГлобальнаяСервернаяПроцедура"); - configurationScope.getProperty("ПервыйОбщийМодуль"); - configurationScope.getProperty("Документы").getScope().getProperty("Документ1"); - configurationScope.getProperty("Catalogs").getScope().getProperty("Справочник1").getScope().getMethod("ТестЭкспортная"); - - configurationScope = resolver.getGlobalScope(); - configurationScope.getMethod("ГлобальнаяСервернаяПроцедура"); - configurationScope.getProperty("ПервыйОбщийМодуль"); - configurationScope.getProperty("Документы").getScope().getProperty("Документ1"); - configurationScope.getProperty("Catalogs").getScope().getProperty("Справочник1").getScope().getMethod("ТестЭкспортная"); + void getConfigurationScope() { + + var configurationScope = provider.getConfigurationScope(); + configurationScope.getMethod("ГлобальнаяСервернаяПроцедура").get(); + + var property = configurationScope.getProperty("ПервыйОбщийМодуль").get(); + provider.getScope(property).getMethod("НеУстаревшаяПроцедура").get(); + provider.getScope(property).getMethod("УстаревшаяФункция").get(); + + property = configurationScope.getProperty("Документы").get(); + provider.getScope(property).getProperty("Документ1").get(); + + property = configurationScope.getProperty("Catalogs").get(); + property = provider.getScope(property).getProperty("Справочник1").get(); + + var catalogScope = provider.getScope(property); + catalogScope.getMethod("ТестЭкспортная").get(); + catalogScope.getProperty("Реквизит1").get(); } } \ No newline at end of file