From 47e61ef3af5e900e64936cb194bc5eb6d7481631 Mon Sep 17 00:00:00 2001 From: LakshanWeerasinghe Date: Tue, 2 Jul 2024 08:25:04 +0530 Subject: [PATCH 1/8] Impl add to Config.toml code action --- .../providers/AddToConfigTomlCodeAction.java | 288 ++++++++++++++++++ .../langserver/common/ConfigurableFinder.java | 119 ++++++++ .../common/constants/CommandConstants.java | 6 + .../utils/ConfigTomlValueGenerationUtil.java | 163 ++++++++++ 4 files changed, 576 insertions(+) create mode 100644 language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/codeaction/providers/AddToConfigTomlCodeAction.java create mode 100644 language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/common/ConfigurableFinder.java create mode 100644 language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/common/utils/ConfigTomlValueGenerationUtil.java diff --git a/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/codeaction/providers/AddToConfigTomlCodeAction.java b/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/codeaction/providers/AddToConfigTomlCodeAction.java new file mode 100644 index 000000000000..94eec3099ce4 --- /dev/null +++ b/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/codeaction/providers/AddToConfigTomlCodeAction.java @@ -0,0 +1,288 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.ballerinalang.langserver.codeaction.providers; + +import io.ballerina.compiler.api.SemanticModel; +import io.ballerina.compiler.api.TypeBuilder; +import io.ballerina.compiler.api.Types; +import io.ballerina.compiler.api.symbols.Qualifier; +import io.ballerina.compiler.api.symbols.Symbol; +import io.ballerina.compiler.api.symbols.TypeSymbol; +import io.ballerina.compiler.api.symbols.VariableSymbol; +import io.ballerina.compiler.syntax.tree.ModuleVariableDeclarationNode; +import io.ballerina.compiler.syntax.tree.SyntaxKind; +import io.ballerina.projects.Module; +import io.ballerina.projects.ModuleName; +import io.ballerina.projects.Project; +import io.ballerina.projects.ProjectKind; +import io.ballerina.toml.api.Toml; +import io.ballerina.toml.semantic.TomlType; +import io.ballerina.toml.semantic.ast.TomlTableNode; +import io.ballerina.toml.semantic.ast.TopLevelNode; +import io.ballerina.tools.text.LinePosition; +import org.ballerinalang.annotation.JavaSPIService; +import org.ballerinalang.langserver.codeaction.CodeActionUtil; +import org.ballerinalang.langserver.common.ConfigurableFinder; +import org.ballerinalang.langserver.common.constants.CommandConstants; +import org.ballerinalang.langserver.common.utils.ConfigTomlValueGenerationUtil; +import org.ballerinalang.langserver.common.utils.PositionUtil; +import org.ballerinalang.langserver.commons.CodeActionContext; +import org.ballerinalang.langserver.commons.codeaction.spi.RangeBasedCodeActionProvider; +import org.ballerinalang.langserver.commons.codeaction.spi.RangeBasedPositionDetails; +import org.eclipse.lsp4j.CodeAction; +import org.eclipse.lsp4j.CodeActionKind; +import org.eclipse.lsp4j.Command; +import org.eclipse.lsp4j.Position; +import org.eclipse.lsp4j.Range; +import org.eclipse.lsp4j.TextEdit; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +/** + * Code Action to undefined configurables into Config.toml file. + * + * @since 2201.10.0 + */ +@JavaSPIService("org.ballerinalang.langserver.commons.codeaction.spi.LSCodeActionProvider") +public class AddToConfigTomlCodeAction implements RangeBasedCodeActionProvider { + + private static final String NAME = "Add to Config.toml"; + private static final String CONFIG_TOML = "Config.toml"; + + @Override + public List getSyntaxKinds() { + return List.of(SyntaxKind.MODULE_VAR_DECL); + } + + @Override + public boolean validate(CodeActionContext context, RangeBasedPositionDetails positionDetails) { + return context.currentModule().isPresent() + && hasConfigurableQualifier((ModuleVariableDeclarationNode) positionDetails.matchedCodeActionNode()); + } + + @Override + public List getCodeActions(CodeActionContext context, RangeBasedPositionDetails posDetails) { + String orgName; + try { + Project project = context.workspace().loadProject(context.filePath()); + if (project.kind() == ProjectKind.SINGLE_FILE_PROJECT) { + return Collections.emptyList(); + } + orgName = project.currentPackage().packageOrg().value(); + } catch (Exception e) { + return Collections.emptyList(); + } + SemanticModel semanticModel = context.currentSemanticModel().get(); + Types types = semanticModel.types(); + TypeBuilder builder = types.builder(); + TypeSymbol basicType = builder.UNION_TYPE.withMemberTypes(types.INT, types.STRING, types.BOOLEAN, + types.BYTE, types.FLOAT, types.DECIMAL, types.XML).build(); + TypeSymbol anyDataOrJsonType = builder.UNION_TYPE.withMemberTypes(types.ANYDATA, types.JSON).build(); + + Optional confSymbol = semanticModel.symbol(posDetails.matchedCodeActionNode()); + if (confSymbol.isEmpty()) { + return Collections.emptyList(); + } + + ConfigurableFinder.ModuleConfigDetails moduleConfigDetails = ConfigurableFinder.getModuleConfigDetails(context); + Map configVarMap = moduleConfigDetails.configVariables(); + VariableSymbol variableSymbol = (VariableSymbol) confSymbol.get(); + ConfigurableFinder.ConfigVariable selectedConf = configVarMap.get(variableSymbol.getName().get()); + + Path configTomlPath = context.workspace().projectRoot(context.filePath()).resolve(CONFIG_TOML); + if (!configTomlPath.toFile().exists()) { + if (configVarMap.isEmpty()) { + return Collections.emptyList(); + } + return withoutConfigTomlCodeActions(basicType, anyDataOrJsonType, moduleConfigDetails, + selectedConf, configTomlPath); + } + + Optional toml = readToml(configTomlPath); + if (toml.isEmpty()) { + return Collections.emptyList(); + } + Module module = context.currentModule().get(); + int lastNodeLine = module.isDefaultModule() ? rootModuleConfigDiff(toml.get(), + orgName, module.moduleName().toString(), configVarMap) + : nonRootModuleConfigDiff(toml.get(), orgName, module.moduleName(), configVarMap); + + if (configVarMap.isEmpty() || !configVarMap.containsKey(selectedConf.name())) { + return Collections.emptyList(); + } + + return withConfigTomlCodeActions(basicType, anyDataOrJsonType, moduleConfigDetails, selectedConf, + configTomlPath, toml.get(), module, lastNodeLine); + } + + private List withConfigTomlCodeActions(TypeSymbol basicType, TypeSymbol anyDataOrJsonType, + ConfigurableFinder.ModuleConfigDetails moduleConfigDetails, + ConfigurableFinder.ConfigVariable selectedConf, + Path configTomlPath, Toml toml, + Module module, int lastNodeLine) { + Position position; + boolean hasAtLeastOneEntry = lastNodeLine != 0; + if (lastNodeLine == 0 && !module.isDefaultModule()) { + Map entries = toml.rootNode().entries(); + for (TopLevelNode node : entries.values()) { + int nodeLine = node.location().lineRange().endLine().line(); + if (nodeLine > lastNodeLine) { + lastNodeLine = nodeLine; + } + } + position = PositionUtil.toPosition( + LinePosition.from(lastNodeLine == 0 ? 0 : lastNodeLine + 3, 0)); + } else { + position = PositionUtil.toPosition( + LinePosition.from(lastNodeLine == 0 ? 0 : lastNodeLine + 1, 0)); + } + + List codeActions = new ArrayList<>(); + if (selectedConf.isRequired()) { + TextEdit textEdit = new TextEdit(new Range(position, position), + getEdits(moduleConfigDetails, basicType, anyDataOrJsonType, hasAtLeastOneEntry)); + CodeAction codeAction = CodeActionUtil.createCodeAction(CommandConstants.ADD_ALL_TO_CONFIG_TOML, + List.of(textEdit), configTomlPath.toUri().getPath()); + codeActions.add(codeAction); + } + TextEdit textEdit = new TextEdit(new Range(position, position), + getTableEntryEdit(selectedConf, basicType, anyDataOrJsonType)); + CodeAction codeAction = CodeActionUtil.createCodeAction(CommandConstants.ADD_TO_CONFIG_TOML, + List.of(textEdit), configTomlPath.toUri().getPath()); + codeActions.add(codeAction); + + return codeActions; + } + + private static List withoutConfigTomlCodeActions(TypeSymbol basicType, TypeSymbol anyDataOrJsonType, + ConfigurableFinder.ModuleConfigDetails moduleConfigDetails, + ConfigurableFinder.ConfigVariable selectedConf, + Path configTomlPath) { + List codeActions = new ArrayList<>(); + if (selectedConf.isRequired()) { + String newText = getEdits(moduleConfigDetails, basicType, anyDataOrJsonType); + CodeAction codeAction = CodeActionUtil.createCodeAction(CommandConstants.ADD_ALL_TO_CONFIG_TOML, + new Command(NAME, CommandConstants.CREATE_CONFIG_TOML_COMMAND, + List.of(configTomlPath.toString(), newText)), CodeActionKind.Empty); + codeActions.add(codeAction); + } + String newText = getTableEntryEdit(selectedConf, basicType, anyDataOrJsonType); + CodeAction codeAction = CodeActionUtil.createCodeAction(CommandConstants.ADD_TO_CONFIG_TOML, + new Command(NAME, CommandConstants.CREATE_CONFIG_TOML_COMMAND, + List.of(configTomlPath.toString(), newText)), CodeActionKind.Empty); + codeActions.add(codeAction); + return codeActions; + } + + private static String getEdits(ConfigurableFinder.ModuleConfigDetails moduleConfigDetails, TypeSymbol basicType, + TypeSymbol anydataOrJson) { + return getEdits(moduleConfigDetails, basicType, anydataOrJson, false); + } + + private static String getEdits(ConfigurableFinder.ModuleConfigDetails moduleConfigDetails, TypeSymbol basicType, + TypeSymbol anydataOrJson, boolean hasAtLeastOneEntry) { + StringBuilder basicKeyValueBuilder = new StringBuilder(); + StringBuilder complexValueBuilder = new StringBuilder(); + if (!moduleConfigDetails.isDefaultModule() && !hasAtLeastOneEntry) { + basicKeyValueBuilder.append(String.format("[%s]%n", moduleConfigDetails.moduleName())); + } + + moduleConfigDetails.configVariables().values().stream().sorted() + .forEach(variable -> { + if (variable.isRequired()) { + ConfigTomlValueGenerationUtil.TomlEntryValue tableEntry = ConfigTomlValueGenerationUtil.getDefaultValueStr(variable.type(), + basicType, anydataOrJson, variable.name()); + if (tableEntry.keyValue()) { + basicKeyValueBuilder.append( + String.format("%s = %s%n", variable.name(), tableEntry.value())); + } else { + complexValueBuilder.append(String.format("%n%s%n", tableEntry.value())); + } + } + }); + + basicKeyValueBuilder.append(complexValueBuilder); + return basicKeyValueBuilder.toString(); + } + + private static String getTableEntryEdit(ConfigurableFinder.ConfigVariable variable, TypeSymbol basicType, + TypeSymbol anydataOrJson) { + ConfigTomlValueGenerationUtil.TomlEntryValue defaultValueStr = ConfigTomlValueGenerationUtil.getDefaultValueStr(variable.type(), + basicType, anydataOrJson, variable.name()); + return defaultValueStr.keyValue() ? String.format("%s = %s%n", variable.name(), defaultValueStr.value()) + : String.format("%n%s%n", defaultValueStr.value()); + } + + private static int rootModuleConfigDiff(Toml baseToml, String orgName, String moduleName, + Map configVariables) { + String orgModuleKey = orgName + "." + moduleName; + Optional table = baseToml.getTable(orgModuleKey); + table.ifPresent(toml -> configDiff(configVariables, toml.rootNode())); // [org.default-module-name] + table = baseToml.getTable(moduleName); + table.ifPresent(toml -> configDiff(configVariables, toml.rootNode())); // [default-module-name] + return configDiff(configVariables, baseToml.rootNode()); // without name + } + + private static int nonRootModuleConfigDiff(Toml baseToml, String orgName, ModuleName moduleName, + Map configVariables) { + String moduleNameStr = moduleName.toString(); + String orgModuleKey = orgName + "." + moduleNameStr; + Optional table; + table = baseToml.getTable(orgModuleKey); + table.ifPresent(toml -> configDiff(configVariables, toml.rootNode())); // [org.default-module-name.module-name] + table = baseToml.getTable(moduleNameStr); + table.ifPresent(toml -> configDiff(configVariables, toml.rootNode())); // [default-module-name.module-name] + table = baseToml.getTable(moduleName.moduleNamePart()); + return table.map(toml -> configDiff(configVariables, toml.rootNode())).orElse(0); // [module-name] + } + + private static int configDiff(Map configVariables, + TomlTableNode moduleNode) { + int lastNodeLine = 0; + for (Map.Entry entry: moduleNode.entries().entrySet()) { + if (entry.getValue().kind() == TomlType.KEY_VALUE) { + lastNodeLine = entry.getValue().location().lineRange().endLine().line(); + } + configVariables.remove(entry.getKey()); + } + return lastNodeLine; + } + + private static boolean hasConfigurableQualifier(ModuleVariableDeclarationNode node) { + return node.qualifiers().stream().anyMatch(q -> q.text().equals(Qualifier.CONFIGURABLE.getValue())); + } + + private static Optional readToml(Path path) { + try { + return Optional.ofNullable(Toml.read(path)); + } catch (IOException e) { + return Optional.empty(); + } + } + + @Override + public String getName() { + return NAME; + } +} diff --git a/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/common/ConfigurableFinder.java b/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/common/ConfigurableFinder.java new file mode 100644 index 000000000000..b7d15bc1f9eb --- /dev/null +++ b/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/common/ConfigurableFinder.java @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.ballerinalang.langserver.common; + +import io.ballerina.compiler.api.SemanticModel; +import io.ballerina.compiler.api.symbols.Qualifier; +import io.ballerina.compiler.api.symbols.Symbol; +import io.ballerina.compiler.api.symbols.TypeSymbol; +import io.ballerina.compiler.api.symbols.VariableSymbol; +import io.ballerina.compiler.syntax.tree.ModulePartNode; +import io.ballerina.compiler.syntax.tree.ModuleVariableDeclarationNode; +import io.ballerina.compiler.syntax.tree.NonTerminalNode; +import io.ballerina.compiler.syntax.tree.SyntaxKind; +import io.ballerina.projects.Document; +import io.ballerina.projects.DocumentId; +import io.ballerina.projects.Module; +import org.ballerinalang.langserver.common.utils.CommonUtil; +import org.ballerinalang.langserver.commons.CodeActionContext; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +/** + * Util used to find configurable variables defined in a module. + * + * @since 2201.10.0 + */ +public final class ConfigurableFinder { + + private ConfigurableFinder() { + } + + /** + * Get all configurables in the current selected module. + * + * @param context Current code action context + * @return all the configurable variables and module details + */ + public static ModuleConfigDetails getModuleConfigDetails(CodeActionContext context) { + SemanticModel semanticModel = context.currentSemanticModel().get(); + Module module = context.currentModule().get(); + Map configVariables = new HashMap<>(); + int index = 0; + for (DocumentId documentId : module.documentIds()) { + Document document = module.document(documentId); + ModulePartNode modulePartNode = document.syntaxTree().rootNode(); + for (NonTerminalNode member: modulePartNode.members()) { + if (member.kind() != SyntaxKind.MODULE_VAR_DECL) { + continue; + } + ModuleVariableDeclarationNode moduleVar = (ModuleVariableDeclarationNode) member; + if (hasConfigurableQualifier(moduleVar)) { + Optional symbol = semanticModel.symbol(moduleVar); + if (symbol.isEmpty()) { + continue; + } + VariableSymbol variableSymbol = (VariableSymbol) symbol.get(); + TypeSymbol type = CommonUtil.getRawType(variableSymbol.typeDescriptor()); + + boolean isRequiredVariable = moduleVar.initializer().stream() + .anyMatch(var -> var.kind() == SyntaxKind.REQUIRED_EXPRESSION); + String varName = variableSymbol.getName().get(); + ConfigVariable configVariable = new ConfigVariable(varName, type, isRequiredVariable, index++); + configVariables.put(varName, configVariable); + } + } + } + String moduleName = module.isDefaultModule() ? "" : module.moduleName().moduleNamePart(); + return new ModuleConfigDetails(moduleName, module.isDefaultModule(), configVariables); + } + + private static boolean hasConfigurableQualifier(ModuleVariableDeclarationNode node) { + return node.qualifiers().stream().anyMatch(q -> q.text().equals(Qualifier.CONFIGURABLE.getValue())); + } + + /** + * Holder to store information about a configurable variable + * + * @param name name of the configurable + * @param type type symbol of the configurable + * @param isRequired value is required + * @param index order of the configurable + */ + public record ConfigVariable(String name, TypeSymbol type, boolean isRequired, int index) + implements Comparable { + + @Override + public int compareTo(ConfigurableFinder.ConfigVariable o) { + return this.index() - o.index(); + } + } + + /** + * Holder to store information about module and configurable variables in the module. + * + * @param moduleName name of the module + * @param isDefaultModule module is default or not + * @param configVariables configurable variables in the module + */ + public record ModuleConfigDetails(String moduleName, boolean isDefaultModule, + Map configVariables){ + } +} diff --git a/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/common/constants/CommandConstants.java b/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/common/constants/CommandConstants.java index fc0ed3e592bd..721faa9e2714 100644 --- a/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/common/constants/CommandConstants.java +++ b/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/common/constants/CommandConstants.java @@ -218,4 +218,10 @@ public class CommandConstants { public static final String RENAME_COMMAND_TITLE_FOR_CONFIGURABLE = "Rename configurable"; public static final String CONVERT_TO_CONFIGURABLE = "Convert to configurable"; + + public static final String ADD_TO_CONFIG_TOML = "Add to Config.toml"; + + public static final String ADD_ALL_TO_CONFIG_TOML = "Add all to Config.toml"; + + public static final String CREATE_CONFIG_TOML_COMMAND = "create.config.toml"; } diff --git a/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/common/utils/ConfigTomlValueGenerationUtil.java b/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/common/utils/ConfigTomlValueGenerationUtil.java new file mode 100644 index 000000000000..519890382658 --- /dev/null +++ b/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/common/utils/ConfigTomlValueGenerationUtil.java @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.ballerinalang.langserver.common.utils; + +import io.ballerina.compiler.api.symbols.ArrayTypeSymbol; +import io.ballerina.compiler.api.symbols.RecordFieldSymbol; +import io.ballerina.compiler.api.symbols.RecordTypeSymbol; +import io.ballerina.compiler.api.symbols.TypeDescKind; +import io.ballerina.compiler.api.symbols.TypeSymbol; +import io.ballerina.compiler.api.symbols.UnionTypeSymbol; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +/** + * Util used to generate value entries for Config.toml keys. + * + * @since 2201.10.0 + */ +public final class ConfigTomlValueGenerationUtil { + + private ConfigTomlValueGenerationUtil() { + } + + /** + * Get {@link TomlEntryValue} for a configurable {@link TypeSymbol}. + * + * @param type Type symbol of the configurable + * @param basicType union of basic types + * @param anydataOrJson union of anydata and json + * @param confName name of the configurable + * @return value string wrapped in {@link TomlEntryValue} + */ + public static TomlEntryValue getDefaultValueStr(TypeSymbol type, TypeSymbol basicType, + TypeSymbol anydataOrJson, String confName) { + switch (type.typeKind()) { + case BOOLEAN -> { + return new TomlEntryValue("false", true); + } + case BYTE, INT, INT_SIGNED8, INT_SIGNED32, INT_UNSIGNED8, INT_UNSIGNED16, INT_UNSIGNED32, INT_SIGNED16 -> { + return new TomlEntryValue("0", true); + } + case FLOAT, DECIMAL -> { + return new TomlEntryValue("0.0", true); + } + case STRING, XML, ANYDATA, JSON, SINGLETON -> { + return new TomlEntryValue("\"\"", true); + } + case TUPLE -> { + return new TomlEntryValue("[]", true); + } + case ARRAY -> { + ArrayTypeSymbol arrayTypeSymbol = (ArrayTypeSymbol) type; + TypeSymbol memberType = CommonUtil.getRawType(arrayTypeSymbol.memberTypeDescriptor()); + if (memberType.typeKind() == TypeDescKind.UNION) { + memberType = ((UnionTypeSymbol) memberType).memberTypeDescriptors().get(0); + } + if (memberType.subtypeOf(basicType) || basicType.subtypeOf(anydataOrJson)) { + return new TomlEntryValue("[]", true); + } + return new TomlEntryValue(String.format("[[%s]]%n", confName), false); // records and maps + } + case MAP -> { + return new TomlEntryValue(String.format("[%s]%n", confName), false); + } + case RECORD -> { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append(String.format("[%s]%n", confName)); + getRecordFields((RecordTypeSymbol) type, stringBuilder, ""); + return new TomlEntryValue(stringBuilder.toString(), false); + } + case TABLE -> { + return new TomlEntryValue(String.format("[[%s]]%n", confName), false); + } + case UNION -> { + return getDefaultValueStr(((UnionTypeSymbol) type).memberTypeDescriptors().get(0), + basicType, anydataOrJson, confName); + } + case TYPE_REFERENCE -> { + return getDefaultValueStr(CommonUtil.getRawType(type), basicType, anydataOrJson, confName); + } + default -> { + return new TomlEntryValue("", true); + } + } + } + + private static StringBuilder getRecordFields(RecordTypeSymbol recordTypeSymbol, StringBuilder + builder, String prefix) { + List> recordTypeSymbols = + RecordUtil.getRecordTypeSymbols(recordTypeSymbol); + + List validFields = new ArrayList<>(); + Map fields; + for (RawTypeSymbolWrapper symbol : recordTypeSymbols) { + fields = RecordUtil.getRecordFields(symbol, Collections.emptyList()); + validFields.addAll(fields.values()); + } + for (RecordFieldSymbol recordFieldSymbol : validFields) { + TypeSymbol typeSymbol = CommonUtil.getRawType(recordFieldSymbol.typeDescriptor()); + if (typeSymbol.typeKind() == TypeDescKind.RECORD) { + String nestedPrefix = prefix + recordFieldSymbol.getName().get() + "."; + getRecordFields((RecordTypeSymbol) typeSymbol, builder, nestedPrefix); + } else { + builder.append(String.format("%s%s = %s%n", prefix, + recordFieldSymbol.getName().get(), getValueForObjectKey(typeSymbol))); + } + } + return builder; + } + + private static String getValueForObjectKey(TypeSymbol type) { + switch (type.typeKind()) { + case BOOLEAN -> { + return"false"; + } + case BYTE, INT, INT_SIGNED8, INT_SIGNED32, INT_UNSIGNED8, INT_UNSIGNED16, INT_UNSIGNED32, INT_SIGNED16 -> { + return"0"; + } + case FLOAT, DECIMAL -> { + return "0.0"; + } + case STRING, XML, ANYDATA, JSON, SINGLETON -> { + return "\"\""; + } + case TUPLE, ARRAY, TABLE -> { + return "[]"; + } + case MAP -> { + return "{}"; + } + default -> { + return ""; + } + } + } + + /** + * Wrapper for toml entry value and specify its for a key or not. + * + * @param value entry value + * @param keyValue is the entry for a key + */ + public record TomlEntryValue(String value, boolean keyValue) { + } +} From 395db4c2d5e7a5a239e7d2f080e304e3563e8127 Mon Sep 17 00:00:00 2001 From: LakshanWeerasinghe Date: Mon, 8 Jul 2024 17:52:27 +0530 Subject: [PATCH 2/8] Add test for add to config toml code action --- .../codeaction/AbstractCodeActionTest.java | 25 ++++++ .../codeaction/AddToConfigTomlTest.java | 83 +++++++++++++++++++ .../config/add_to_config_toml_negative1.json | 12 +++ .../config/add_to_config_toml_negative2.json | 12 +++ .../config/add_to_config_toml_negative3.json | 12 +++ .../with_config_toml_default_module1.json | 28 +++++++ .../with_config_toml_default_module2.json | 28 +++++++ .../with_config_toml_default_module3.json | 28 +++++++ .../with_config_toml_default_module4.json | 28 +++++++ .../with_config_toml_default_module5.json | 28 +++++++ .../with_config_toml_default_module6.json | 28 +++++++ .../with_config_toml_non_default_module1.json | 28 +++++++ .../with_config_toml_non_default_module2.json | 28 +++++++ .../with_config_toml_non_default_module3.json | 28 +++++++ .../with_config_toml_non_default_module4.json | 28 +++++++ .../with_config_toml_non_default_module5.json | 28 +++++++ .../with_config_toml_non_default_module6.json | 28 +++++++ .../without_config_toml_default_module1.json | 22 +++++ .../without_config_toml_default_module2.json | 22 +++++ .../without_config_toml_default_module3.json | 22 +++++ ...thout_config_toml_non_default_module1.json | 22 +++++ ...thout_config_toml_non_default_module2.json | 22 +++++ ...thout_config_toml_non_default_module3.json | 22 +++++ .../source/project1/Ballerina.toml | 5 ++ .../source/project1/file1.bal | 36 ++++++++ .../source/project1/file2.bal | 25 ++++++ .../source/project1/modules/mod1/mod1.bal | 21 +++++ .../source/project1/modules/mod2/mod2.bal | 0 .../source/project2/Ballerina.toml | 5 ++ .../source/project2/Config.toml | 14 ++++ .../source/project2/file1.bal | 36 ++++++++ .../source/project2/file2.bal | 25 ++++++ .../source/project2/modules/mod1/mod1.bal | 22 +++++ .../source/project3/Ballerina.toml | 5 ++ .../source/project3/Config.toml | 20 +++++ .../source/project3/file1.bal | 36 ++++++++ .../source/project3/file2.bal | 25 ++++++ .../source/project3/modules/mod1/mod1.bal | 22 +++++ .../source/single_file_project.bal | 2 + 39 files changed, 911 insertions(+) create mode 100644 language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/codeaction/AddToConfigTomlTest.java create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/add_to_config_toml_negative1.json create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/add_to_config_toml_negative2.json create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/add_to_config_toml_negative3.json create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_default_module1.json create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_default_module2.json create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_default_module3.json create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_default_module4.json create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_default_module5.json create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_default_module6.json create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_non_default_module1.json create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_non_default_module2.json create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_non_default_module3.json create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_non_default_module4.json create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_non_default_module5.json create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_non_default_module6.json create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/without_config_toml_default_module1.json create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/without_config_toml_default_module2.json create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/without_config_toml_default_module3.json create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/without_config_toml_non_default_module1.json create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/without_config_toml_non_default_module2.json create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/without_config_toml_non_default_module3.json create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project1/Ballerina.toml create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project1/file1.bal create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project1/file2.bal create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project1/modules/mod1/mod1.bal create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project1/modules/mod2/mod2.bal create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project2/Ballerina.toml create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project2/Config.toml create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project2/file1.bal create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project2/file2.bal create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project2/modules/mod1/mod1.bal create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project3/Ballerina.toml create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project3/Config.toml create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project3/file1.bal create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project3/file2.bal create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project3/modules/mod1/mod1.bal create mode 100644 language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/single_file_project.bal diff --git a/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/codeaction/AbstractCodeActionTest.java b/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/codeaction/AbstractCodeActionTest.java index ec7cc806984f..f4ff9230c43c 100644 --- a/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/codeaction/AbstractCodeActionTest.java +++ b/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/codeaction/AbstractCodeActionTest.java @@ -437,6 +437,9 @@ protected boolean validateAndModifyArguments(JsonObject actualCommand, } return actualArgs.size() == 4 && validateExtractCmd(actualCommand, actualArgs, expArgs, sourceRoot) && actualArgs.get(3).getAsJsonObject().equals(expArgs.get(3).getAsJsonObject()); + } else if (CommandConstants.CREATE_CONFIG_TOML_COMMAND.equals(actualCommand.get("command").getAsString())) { + return actualArgs.size() == 2 + && validateCreateConfigTomlCommand(actualCommand, actualArgs, expArgs, sourceRoot); } for (JsonElement actualArg : actualArgs) { @@ -479,4 +482,26 @@ private boolean validateExtractCmd(JsonObject actualCommand, JsonArray actualArg actualCommand.add("arguments", newArgs); return false; } + + private boolean validateCreateConfigTomlCommand(JsonObject actualCommand, JsonArray actualArgs, JsonArray expArgs, + Path sourceRoot) { + String actualFilePath = actualArgs.get(0).getAsString().replace(sourceRoot.toString(), ""); + if (actualFilePath.startsWith("/") || actualFilePath.startsWith("\\")) { + actualFilePath = actualFilePath.substring(1); + } + String expectedFilePath = expArgs.get(0).getAsString(); + + String actualTextEdit = actualArgs.get(1).getAsString(); + String expectedTextEdit = expArgs.get(1).getAsString(); + + if (actualFilePath.equals(expectedFilePath) && actualTextEdit.equals(expectedTextEdit)) { + return true; + } + + JsonArray newArgs = new JsonArray(); + newArgs.add(actualFilePath); + newArgs.add(actualTextEdit); + actualCommand.add("arguments", newArgs); + return false; + } } diff --git a/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/codeaction/AddToConfigTomlTest.java b/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/codeaction/AddToConfigTomlTest.java new file mode 100644 index 000000000000..6fb819a69bf5 --- /dev/null +++ b/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/codeaction/AddToConfigTomlTest.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.ballerinalang.langserver.codeaction; + +import org.ballerinalang.langserver.commons.workspace.WorkspaceDocumentException; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.io.IOException; + +/** + * Tests cases for {@link org.ballerinalang.langserver.codeaction.providers.AddToConfigTomlCodeAction}. + * + * @since 2201.10.0 + */ +public class AddToConfigTomlTest extends AbstractCodeActionTest { + + @Override + @Test(dataProvider = "codeaction-data-provider") + public void test(String config) throws IOException, WorkspaceDocumentException { + super.test(config); + } + + @Override + @Test(dataProvider = "negative-test-data-provider") + public void negativeTest(String config) throws IOException, WorkspaceDocumentException { + super.negativeTest(config); + } + + @DataProvider(name = "codeaction-data-provider") + @Override + public Object[][] dataProvider() { + return new Object[][]{ + {"without_config_toml_default_module1.json"}, + {"without_config_toml_default_module2.json"}, + {"without_config_toml_default_module3.json"}, + {"without_config_toml_non_default_module1.json"}, + {"without_config_toml_non_default_module2.json"}, + {"without_config_toml_non_default_module3.json"}, + {"with_config_toml_default_module1.json"}, + {"with_config_toml_default_module2.json"}, + {"with_config_toml_default_module3.json"}, + {"with_config_toml_default_module4.json"}, + {"with_config_toml_default_module5.json"}, + {"with_config_toml_default_module6.json"}, + {"with_config_toml_non_default_module1.json"}, + {"with_config_toml_non_default_module2.json"}, + {"with_config_toml_non_default_module3.json"}, + {"with_config_toml_non_default_module4.json"}, + {"with_config_toml_non_default_module5.json"}, + {"with_config_toml_non_default_module6.json"} + }; + } + + @DataProvider(name = "negative-test-data-provider") + public Object[][] negativeDataProvider() { + return new Object[][]{ + {"add_to_config_toml_negative1.json"}, + {"add_to_config_toml_negative2.json"}, + {"add_to_config_toml_negative3.json"} + }; + } + + @Override + public String getResourceDir() { + return "add-to-config-toml"; + } +} diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/add_to_config_toml_negative1.json b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/add_to_config_toml_negative1.json new file mode 100644 index 000000000000..4158f0cc55fc --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/add_to_config_toml_negative1.json @@ -0,0 +1,12 @@ +{ + "position": { + "line": 2, + "character": 8 + }, + "source": "project2/file1.bal", + "expected": [ + { + "title": "Add to Config.toml" + } + ] +} diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/add_to_config_toml_negative2.json b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/add_to_config_toml_negative2.json new file mode 100644 index 000000000000..e5da99268a69 --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/add_to_config_toml_negative2.json @@ -0,0 +1,12 @@ +{ + "position": { + "line": 2, + "character": 8 + }, + "source": "project2/file1.bal", + "expected": [ + { + "title": "Add all to Config.toml" + } + ] +} diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/add_to_config_toml_negative3.json b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/add_to_config_toml_negative3.json new file mode 100644 index 000000000000..c938de560068 --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/add_to_config_toml_negative3.json @@ -0,0 +1,12 @@ +{ + "position": { + "line": 0, + "character": 5 + }, + "source": "single_file_project.bal", + "expected": [ + { + "title": "Add all to Config.toml" + } + ] +} diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_default_module1.json b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_default_module1.json new file mode 100644 index 000000000000..a4e458846896 --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_default_module1.json @@ -0,0 +1,28 @@ +{ + "position": { + "line": 4, + "character": 6 + }, + "source": "project2/file1.bal", + "expected": [ + { + "title": "Add to Config.toml", + "edits": [ + { + "range": { + "start": { + "line": 6, + "character": 0 + }, + "end": { + "line": 6, + "character": 0 + } + }, + "newText": "bools = []\n" + } + ], + "resolvable": false + } + ] +} diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_default_module2.json b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_default_module2.json new file mode 100644 index 000000000000..9d8a416b874b --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_default_module2.json @@ -0,0 +1,28 @@ +{ + "position": { + "line": 4, + "character": 6 + }, + "source": "project2/file1.bal", + "expected": [ + { + "title": "Add all to Config.toml", + "edits": [ + { + "range": { + "start": { + "line": 6, + "character": 0 + }, + "end": { + "line": 6, + "character": 0 + } + }, + "newText": "xmls = []\nbools = []\ndecimals = []\nstrs = []\ntuple = []\nmapArray = []\npeople = []\nuserTeams = []\nb = 0\nf = 0.0\nd = 0.0\ns = \"\"\nx = \"\"\nints = []\nbytes = []\nfloats = []\n\n[input]\nfood.b.cake = \"\"\nfood.b.bake = \"\"\nfood.name = \"\"\nfood.cal = 0\nage = 0\n\n" + } + ], + "resolvable": false + } + ] +} diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_default_module3.json b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_default_module3.json new file mode 100644 index 000000000000..bc872bf5183a --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_default_module3.json @@ -0,0 +1,28 @@ +{ + "position": { + "line": 0, + "character": 1 + }, + "source": "project2/file1.bal", + "expected": [ + { + "title": "Add to Config.toml", + "edits": [ + { + "range": { + "start": { + "line": 6, + "character": 0 + }, + "end": { + "line": 6, + "character": 0 + } + }, + "newText": "bool = false\n" + } + ], + "resolvable": false + } + ] +} diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_default_module4.json b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_default_module4.json new file mode 100644 index 000000000000..3caceed20648 --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_default_module4.json @@ -0,0 +1,28 @@ +{ + "position": { + "line": 4, + "character": 6 + }, + "source": "project3/file1.bal", + "expected": [ + { + "title": "Add to Config.toml", + "edits": [ + { + "range": { + "start": { + "line": 0, + "character": 0 + }, + "end": { + "line": 0, + "character": 0 + } + }, + "newText": "bools = []\n" + } + ], + "resolvable": false + } + ] +} diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_default_module5.json b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_default_module5.json new file mode 100644 index 000000000000..594e6f7d3ba8 --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_default_module5.json @@ -0,0 +1,28 @@ +{ + "position": { + "line": 4, + "character": 6 + }, + "source": "project3/file1.bal", + "expected": [ + { + "title": "Add all to Config.toml", + "edits": [ + { + "range": { + "start": { + "line": 0, + "character": 0 + }, + "end": { + "line": 0, + "character": 0 + } + }, + "newText": "xmls = []\nbools = []\ndecimals = []\nstrs = []\ntuple = []\nmapArray = []\npeople = []\nuserTeams = []\nb = 0\nf = 0.0\nd = 0.0\ns = \"\"\nx = \"\"\nints = []\nbytes = []\nfloats = []\n\n[input]\nfood.b.cake = \"\"\nfood.b.bake = \"\"\nfood.name = \"\"\nfood.cal = 0\nage = 0\n\n" + } + ], + "resolvable": false + } + ] +} diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_default_module6.json b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_default_module6.json new file mode 100644 index 000000000000..8bb13fddd101 --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_default_module6.json @@ -0,0 +1,28 @@ +{ + "position": { + "line": 0, + "character": 1 + }, + "source": "project3/file1.bal", + "expected": [ + { + "title": "Add to Config.toml", + "edits": [ + { + "range": { + "start": { + "line": 0, + "character": 0 + }, + "end": { + "line": 0, + "character": 0 + } + }, + "newText": "bool = false\n" + } + ], + "resolvable": false + } + ] +} diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_non_default_module1.json b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_non_default_module1.json new file mode 100644 index 000000000000..700e5c09ccdf --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_non_default_module1.json @@ -0,0 +1,28 @@ +{ + "position": { + "line": 4, + "character": 6 + }, + "source": "project2/modules/mod1/mod1.bal", + "expected": [ + { + "title": "Add to Config.toml", + "edits": [ + { + "range": { + "start": { + "line": 16, + "character": 0 + }, + "end": { + "line": 16, + "character": 0 + } + }, + "newText": "b = 0\n" + } + ], + "resolvable": false + } + ] +} diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_non_default_module2.json b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_non_default_module2.json new file mode 100644 index 000000000000..7c47ce46ff1f --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_non_default_module2.json @@ -0,0 +1,28 @@ +{ + "position": { + "line": 4, + "character": 6 + }, + "source": "project2/modules/mod1/mod1.bal", + "expected": [ + { + "title": "Add all to Config.toml", + "edits": [ + { + "range": { + "start": { + "line": 16, + "character": 0 + }, + "end": { + "line": 16, + "character": 0 + } + }, + "newText": "[mod1]\ni = 0\npp = 0\nb = 0\nf = 0.0\nd = 0.0\ns = \"\"\n\n[input]\nfood.name = \"\"\nfood.cal = 0\nage = 0\n\n" + } + ], + "resolvable": false + } + ] +} diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_non_default_module3.json b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_non_default_module3.json new file mode 100644 index 000000000000..7c47ce46ff1f --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_non_default_module3.json @@ -0,0 +1,28 @@ +{ + "position": { + "line": 4, + "character": 6 + }, + "source": "project2/modules/mod1/mod1.bal", + "expected": [ + { + "title": "Add all to Config.toml", + "edits": [ + { + "range": { + "start": { + "line": 16, + "character": 0 + }, + "end": { + "line": 16, + "character": 0 + } + }, + "newText": "[mod1]\ni = 0\npp = 0\nb = 0\nf = 0.0\nd = 0.0\ns = \"\"\n\n[input]\nfood.name = \"\"\nfood.cal = 0\nage = 0\n\n" + } + ], + "resolvable": false + } + ] +} diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_non_default_module4.json b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_non_default_module4.json new file mode 100644 index 000000000000..163fca980c5a --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_non_default_module4.json @@ -0,0 +1,28 @@ +{ + "position": { + "line": 4, + "character": 6 + }, + "source": "project3/modules/mod1/mod1.bal", + "expected": [ + { + "title": "Add to Config.toml", + "edits": [ + { + "range": { + "start": { + "line": 20, + "character": 0 + }, + "end": { + "line": 20, + "character": 0 + } + }, + "newText": "b = 0\n" + } + ], + "resolvable": false + } + ] +} diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_non_default_module5.json b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_non_default_module5.json new file mode 100644 index 000000000000..b8796628d421 --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_non_default_module5.json @@ -0,0 +1,28 @@ +{ + "position": { + "line": 4, + "character": 6 + }, + "source": "project3/modules/mod1/mod1.bal", + "expected": [ + { + "title": "Add all to Config.toml", + "edits": [ + { + "range": { + "start": { + "line": 20, + "character": 0 + }, + "end": { + "line": 20, + "character": 0 + } + }, + "newText": "i = 0\npp = 0\nb = 0\nf = 0.0\n\n[input]\nfood.name = \"\"\nfood.cal = 0\nage = 0\n\n" + } + ], + "resolvable": false + } + ] +} diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_non_default_module6.json b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_non_default_module6.json new file mode 100644 index 000000000000..b8796628d421 --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/with_config_toml_non_default_module6.json @@ -0,0 +1,28 @@ +{ + "position": { + "line": 4, + "character": 6 + }, + "source": "project3/modules/mod1/mod1.bal", + "expected": [ + { + "title": "Add all to Config.toml", + "edits": [ + { + "range": { + "start": { + "line": 20, + "character": 0 + }, + "end": { + "line": 20, + "character": 0 + } + }, + "newText": "i = 0\npp = 0\nb = 0\nf = 0.0\n\n[input]\nfood.name = \"\"\nfood.cal = 0\nage = 0\n\n" + } + ], + "resolvable": false + } + ] +} diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/without_config_toml_default_module1.json b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/without_config_toml_default_module1.json new file mode 100644 index 000000000000..59a7d098e293 --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/without_config_toml_default_module1.json @@ -0,0 +1,22 @@ +{ + "position": { + "line": 1, + "character": 12 + }, + "source": "project1/file1.bal", + "expected": [ + { + "title": "Add to Config.toml", + "kind": "", + "command": { + "title": "Add to Config.toml", + "command": "create.config.toml", + "arguments": [ + "project1/Config.toml", + "i = 0\n" + ] + }, + "resolvable": false + } + ] +} diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/without_config_toml_default_module2.json b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/without_config_toml_default_module2.json new file mode 100644 index 000000000000..3cd471da3fb6 --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/without_config_toml_default_module2.json @@ -0,0 +1,22 @@ +{ + "position": { + "line": 1, + "character": 12 + }, + "source": "project1/file1.bal", + "expected": [ + { + "title": "Add all to Config.toml", + "kind": "", + "command": { + "title": "Add to Config.toml", + "command": "create.config.toml", + "arguments": [ + "project1/Config.toml", + "i = 0\npp = 0\nxmls = []\nbools = []\ndecimals = []\nstrs = []\ntuple = []\nmapArray = []\npeople = []\nuserTeams = []\ncountry = \"\"\nb = 0\nf = 0.0\nd = 0.0\ns = \"\"\nx = \"\"\nints = []\nbytes = []\nfloats = []\ncode = 0\ndata = \"\"\npayload = \"\"\n\n[intMap]\n\n\n[person]\nname = \"\"\nid = \"\"\n\n\n[[users]]\n\n\n[input]\nfood.b.cake = \"\"\nfood.b.bake = \"\"\nfood.name = \"\"\nfood.cal = 0\nage = 0\n\n" + ] + }, + "resolvable": false + } + ] +} diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/without_config_toml_default_module3.json b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/without_config_toml_default_module3.json new file mode 100644 index 000000000000..d9278dc41744 --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/without_config_toml_default_module3.json @@ -0,0 +1,22 @@ +{ + "position": { + "line": 0, + "character": 9 + }, + "source": "project1/file1.bal", + "expected": [ + { + "title": "Add to Config.toml", + "kind": "", + "command": { + "title": "Add to Config.toml", + "command": "create.config.toml", + "arguments": [ + "project1/Config.toml", + "bool = false\n" + ] + }, + "resolvable": false + } + ] +} diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/without_config_toml_non_default_module1.json b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/without_config_toml_non_default_module1.json new file mode 100644 index 000000000000..03f6fd30b552 --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/without_config_toml_non_default_module1.json @@ -0,0 +1,22 @@ +{ + "position": { + "line": 3, + "character": 4 + }, + "source": "project1/modules/mod1/mod1.bal", + "expected": [ + { + "title": "Add to Config.toml", + "kind": "", + "command": { + "title": "Add to Config.toml", + "command": "create.config.toml", + "arguments": [ + "project1/Config.toml", + "pp = 0\n" + ] + }, + "resolvable": false + } + ] +} diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/without_config_toml_non_default_module2.json b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/without_config_toml_non_default_module2.json new file mode 100644 index 000000000000..57a5e306966a --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/without_config_toml_non_default_module2.json @@ -0,0 +1,22 @@ +{ + "position": { + "line": 3, + "character": 4 + }, + "source": "project1/modules/mod1/mod1.bal", + "expected": [ + { + "title": "Add all to Config.toml", + "kind": "", + "command": { + "title": "Add to Config.toml", + "command": "create.config.toml", + "arguments": [ + "project1/Config.toml", + "[mod1]\ni = 0\npp = 0\nb = 0\nf = 0.0\nd = 0.0\ns = \"\"\nx = \"\"\n\n[input]\nfood.name = \"\"\nfood.cal = 0\nage = 0\n\n" + ] + }, + "resolvable": false + } + ] +} diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/without_config_toml_non_default_module3.json b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/without_config_toml_non_default_module3.json new file mode 100644 index 000000000000..b251afb1d293 --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/config/without_config_toml_non_default_module3.json @@ -0,0 +1,22 @@ +{ + "position": { + "line": 0, + "character": 6 + }, + "source": "project1/modules/mod1/mod1.bal", + "expected": [ + { + "title": "Add to Config.toml", + "kind": "", + "command": { + "title": "Add to Config.toml", + "command": "create.config.toml", + "arguments": [ + "project1/Config.toml", + "xc = \"\"\n" + ] + }, + "resolvable": false + } + ] +} diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project1/Ballerina.toml b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project1/Ballerina.toml new file mode 100644 index 000000000000..8d2693b6e708 --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project1/Ballerina.toml @@ -0,0 +1,5 @@ +[package] +org = "wso2" +name = "project1" +version = "0.1.0" +distribution = "2201.10.0" diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project1/file1.bal b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project1/file1.bal new file mode 100644 index 000000000000..6408e64fd17f --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project1/file1.bal @@ -0,0 +1,36 @@ +configurable boolean bool = false; +configurable int i = ?; +configurable int:Signed16 pp = ?; +configurable xml[] xmls = ?; +configurable boolean[] bools = ?; +configurable decimal[] decimals = ?; +configurable string[] strs = ?; +configurable [string, float, float...] tuple = ?; + +configurable map intMap = ?; +configurable map[] mapArray = ?; + +type Person record {| + string id; + string name; +|}; + +configurable Person person = ?; + +type Bake record {| + string bake; + string cake; +|}; + +configurable Person[] people = ?; + +configurable table> users = ?; + +configurable table>[] userTeams = ?; + +enum Country { + LK = "Sri Lanka", + US = "United States" +} + +configurable Country country = ?; diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project1/file2.bal b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project1/file2.bal new file mode 100644 index 000000000000..f34a681fb547 --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project1/file2.bal @@ -0,0 +1,25 @@ +configurable byte b = ?; +configurable float f = ?; +configurable decimal d = ?; +configurable string s = ?; +configurable xml x = ?; +configurable int[] ints = ?; +configurable byte[] bytes = ?; +configurable float[] floats = ?; + +type Food record { + string name; + int cal; + Bake b; +}; + +type Diet record { + Food food; + int age; +}; + +configurable Diet input = ?; + +configurable int|string code = ?; +configurable anydata data = ?; +configurable json payload = ?; diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project1/modules/mod1/mod1.bal b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project1/modules/mod1/mod1.bal new file mode 100644 index 000000000000..032f1527a70f --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project1/modules/mod1/mod1.bal @@ -0,0 +1,21 @@ +configurable string xc = "skamsm"; +configurable boolean bool = false; +configurable int i = ?; +configurable int:Signed16 pp = ?; +configurable byte b = ?; +configurable float f = ?; +configurable decimal d = ?; +configurable string s = ?; +configurable xml x = ?; +configurable Diet input = ?; + +type Food record { + string name; + int cal; + Bake b; +}; + +type Diet record { + Food food; + int age; +}; diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project1/modules/mod2/mod2.bal b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project1/modules/mod2/mod2.bal new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project2/Ballerina.toml b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project2/Ballerina.toml new file mode 100644 index 000000000000..ff4ad23540a5 --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project2/Ballerina.toml @@ -0,0 +1,5 @@ +[package] +org = "wso2" +name = "project2" +version = "0.1.0" +distribution = "2201.10.0" diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project2/Config.toml b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project2/Config.toml new file mode 100644 index 000000000000..4060fa72fa54 --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project2/Config.toml @@ -0,0 +1,14 @@ +i = 0 +pp = 0 +country = "" +code = 0 +data = "" +payload = "" + +[intMap] + +[person] +name = "" +id = "" + +[[users]] diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project2/file1.bal b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project2/file1.bal new file mode 100644 index 000000000000..6408e64fd17f --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project2/file1.bal @@ -0,0 +1,36 @@ +configurable boolean bool = false; +configurable int i = ?; +configurable int:Signed16 pp = ?; +configurable xml[] xmls = ?; +configurable boolean[] bools = ?; +configurable decimal[] decimals = ?; +configurable string[] strs = ?; +configurable [string, float, float...] tuple = ?; + +configurable map intMap = ?; +configurable map[] mapArray = ?; + +type Person record {| + string id; + string name; +|}; + +configurable Person person = ?; + +type Bake record {| + string bake; + string cake; +|}; + +configurable Person[] people = ?; + +configurable table> users = ?; + +configurable table>[] userTeams = ?; + +enum Country { + LK = "Sri Lanka", + US = "United States" +} + +configurable Country country = ?; diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project2/file2.bal b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project2/file2.bal new file mode 100644 index 000000000000..f34a681fb547 --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project2/file2.bal @@ -0,0 +1,25 @@ +configurable byte b = ?; +configurable float f = ?; +configurable decimal d = ?; +configurable string s = ?; +configurable xml x = ?; +configurable int[] ints = ?; +configurable byte[] bytes = ?; +configurable float[] floats = ?; + +type Food record { + string name; + int cal; + Bake b; +}; + +type Diet record { + Food food; + int age; +}; + +configurable Diet input = ?; + +configurable int|string code = ?; +configurable anydata data = ?; +configurable json payload = ?; diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project2/modules/mod1/mod1.bal b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project2/modules/mod1/mod1.bal new file mode 100644 index 000000000000..dc1ebaafca5a --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project2/modules/mod1/mod1.bal @@ -0,0 +1,22 @@ +configurable string xc = "host"; +configurable boolean bool = false; +configurable int i = ?; +configurable int:Signed16 pp = ?; +configurable byte b = ?; +configurable float f = ?; +configurable decimal d = ?; +configurable string s = ?; +configurable xml x = + +type Food record { + string name; + int cal; + Bake b; +}; + +type Diet record { + Food food; + int age; +}; + +configurable Diet input = ?; diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project3/Ballerina.toml b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project3/Ballerina.toml new file mode 100644 index 000000000000..eea121d0de0e --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project3/Ballerina.toml @@ -0,0 +1,5 @@ +[package] +org = "wso2" +name = "project3" +version = "0.1.0" +distribution = "2201.10.0" diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project3/Config.toml b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project3/Config.toml new file mode 100644 index 000000000000..f22f9dfde06a --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project3/Config.toml @@ -0,0 +1,20 @@ +[project3] +i = 0 +pp = 0 +country = "" +code = 0 +data = "" +payload = "" + +[intMap] + +[person] +name = "" +id = "" + +[[users]] + +[mod1] +d = 0.0 +s = "" +x = "" diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project3/file1.bal b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project3/file1.bal new file mode 100644 index 000000000000..6408e64fd17f --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project3/file1.bal @@ -0,0 +1,36 @@ +configurable boolean bool = false; +configurable int i = ?; +configurable int:Signed16 pp = ?; +configurable xml[] xmls = ?; +configurable boolean[] bools = ?; +configurable decimal[] decimals = ?; +configurable string[] strs = ?; +configurable [string, float, float...] tuple = ?; + +configurable map intMap = ?; +configurable map[] mapArray = ?; + +type Person record {| + string id; + string name; +|}; + +configurable Person person = ?; + +type Bake record {| + string bake; + string cake; +|}; + +configurable Person[] people = ?; + +configurable table> users = ?; + +configurable table>[] userTeams = ?; + +enum Country { + LK = "Sri Lanka", + US = "United States" +} + +configurable Country country = ?; diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project3/file2.bal b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project3/file2.bal new file mode 100644 index 000000000000..f34a681fb547 --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project3/file2.bal @@ -0,0 +1,25 @@ +configurable byte b = ?; +configurable float f = ?; +configurable decimal d = ?; +configurable string s = ?; +configurable xml x = ?; +configurable int[] ints = ?; +configurable byte[] bytes = ?; +configurable float[] floats = ?; + +type Food record { + string name; + int cal; + Bake b; +}; + +type Diet record { + Food food; + int age; +}; + +configurable Diet input = ?; + +configurable int|string code = ?; +configurable anydata data = ?; +configurable json payload = ?; diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project3/modules/mod1/mod1.bal b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project3/modules/mod1/mod1.bal new file mode 100644 index 000000000000..dc1ebaafca5a --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/project3/modules/mod1/mod1.bal @@ -0,0 +1,22 @@ +configurable string xc = "host"; +configurable boolean bool = false; +configurable int i = ?; +configurable int:Signed16 pp = ?; +configurable byte b = ?; +configurable float f = ?; +configurable decimal d = ?; +configurable string s = ?; +configurable xml x = + +type Food record { + string name; + int cal; + Bake b; +}; + +type Diet record { + Food food; + int age; +}; + +configurable Diet input = ?; diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/single_file_project.bal b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/single_file_project.bal new file mode 100644 index 000000000000..e9b7200b4f15 --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/add-to-config-toml/source/single_file_project.bal @@ -0,0 +1,2 @@ +configurable int port = 8000; +configurable string host = ?; From d1bb23696a75c58c4e5949c845adf04349012bbc Mon Sep 17 00:00:00 2001 From: LakshanWeerasinghe Date: Wed, 10 Jul 2024 14:26:25 +0530 Subject: [PATCH 3/8] Fix checkstyles failures --- .../providers/AddToConfigTomlCodeAction.java | 11 +++++++---- .../langserver/common/ConfigurableFinder.java | 4 ++-- .../common/utils/ConfigTomlValueGenerationUtil.java | 4 ++-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/codeaction/providers/AddToConfigTomlCodeAction.java b/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/codeaction/providers/AddToConfigTomlCodeAction.java index 94eec3099ce4..798fe61e089d 100644 --- a/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/codeaction/providers/AddToConfigTomlCodeAction.java +++ b/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/codeaction/providers/AddToConfigTomlCodeAction.java @@ -90,9 +90,10 @@ public List getCodeActions(CodeActionContext context, RangeBasedPosi return Collections.emptyList(); } orgName = project.currentPackage().packageOrg().value(); - } catch (Exception e) { + } catch (Throwable e) { return Collections.emptyList(); } + SemanticModel semanticModel = context.currentSemanticModel().get(); Types types = semanticModel.types(); TypeBuilder builder = types.builder(); @@ -211,7 +212,8 @@ private static String getEdits(ConfigurableFinder.ModuleConfigDetails moduleConf moduleConfigDetails.configVariables().values().stream().sorted() .forEach(variable -> { if (variable.isRequired()) { - ConfigTomlValueGenerationUtil.TomlEntryValue tableEntry = ConfigTomlValueGenerationUtil.getDefaultValueStr(variable.type(), + ConfigTomlValueGenerationUtil.TomlEntryValue tableEntry = + ConfigTomlValueGenerationUtil.getDefaultValueStr(variable.type(), basicType, anydataOrJson, variable.name()); if (tableEntry.keyValue()) { basicKeyValueBuilder.append( @@ -228,7 +230,8 @@ private static String getEdits(ConfigurableFinder.ModuleConfigDetails moduleConf private static String getTableEntryEdit(ConfigurableFinder.ConfigVariable variable, TypeSymbol basicType, TypeSymbol anydataOrJson) { - ConfigTomlValueGenerationUtil.TomlEntryValue defaultValueStr = ConfigTomlValueGenerationUtil.getDefaultValueStr(variable.type(), + ConfigTomlValueGenerationUtil.TomlEntryValue defaultValueStr = + ConfigTomlValueGenerationUtil.getDefaultValueStr(variable.type(), basicType, anydataOrJson, variable.name()); return defaultValueStr.keyValue() ? String.format("%s = %s%n", variable.name(), defaultValueStr.value()) : String.format("%n%s%n", defaultValueStr.value()); @@ -245,7 +248,7 @@ private static int rootModuleConfigDiff(Toml baseToml, String orgName, String mo } private static int nonRootModuleConfigDiff(Toml baseToml, String orgName, ModuleName moduleName, - Map configVariables) { + Map configVariables) { String moduleNameStr = moduleName.toString(); String orgModuleKey = orgName + "." + moduleNameStr; Optional table; diff --git a/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/common/ConfigurableFinder.java b/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/common/ConfigurableFinder.java index b7d15bc1f9eb..2fcdc24d9da9 100644 --- a/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/common/ConfigurableFinder.java +++ b/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/common/ConfigurableFinder.java @@ -90,7 +90,7 @@ private static boolean hasConfigurableQualifier(ModuleVariableDeclarationNode no } /** - * Holder to store information about a configurable variable + * Holder to store information about a configurable variable. * * @param name name of the configurable * @param type type symbol of the configurable @@ -114,6 +114,6 @@ public int compareTo(ConfigurableFinder.ConfigVariable o) { * @param configVariables configurable variables in the module */ public record ModuleConfigDetails(String moduleName, boolean isDefaultModule, - Map configVariables){ + Map configVariables) { } } diff --git a/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/common/utils/ConfigTomlValueGenerationUtil.java b/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/common/utils/ConfigTomlValueGenerationUtil.java index 519890382658..d5bb6b445a21 100644 --- a/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/common/utils/ConfigTomlValueGenerationUtil.java +++ b/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/common/utils/ConfigTomlValueGenerationUtil.java @@ -129,10 +129,10 @@ private static StringBuilder getRecordFields(RecordTypeSymbol recordTypeSymbol, private static String getValueForObjectKey(TypeSymbol type) { switch (type.typeKind()) { case BOOLEAN -> { - return"false"; + return "false"; } case BYTE, INT, INT_SIGNED8, INT_SIGNED32, INT_UNSIGNED8, INT_UNSIGNED16, INT_UNSIGNED32, INT_SIGNED16 -> { - return"0"; + return "0"; } case FLOAT, DECIMAL -> { return "0.0"; From 9eb9e66ce8780a44e956c3100f642df0a73e16c1 Mon Sep 17 00:00:00 2001 From: LakshanWeerasinghe Date: Wed, 24 Jul 2024 14:07:42 +0530 Subject: [PATCH 4/8] Fix failing tests --- .../codeaction/AbstractCodeActionTest.java | 14 ++++++++------ .../langserver/codeaction/AddToConfigTomlTest.java | 14 +++++++------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/codeaction/AbstractCodeActionTest.java b/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/codeaction/AbstractCodeActionTest.java index f4ff9230c43c..6f2b319580a5 100644 --- a/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/codeaction/AbstractCodeActionTest.java +++ b/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/codeaction/AbstractCodeActionTest.java @@ -485,15 +485,17 @@ private boolean validateExtractCmd(JsonObject actualCommand, JsonArray actualArg private boolean validateCreateConfigTomlCommand(JsonObject actualCommand, JsonArray actualArgs, JsonArray expArgs, Path sourceRoot) { + String actualTextEdit = actualArgs.get(1).getAsString(); + String expectedTextEdit = expArgs.get(1).getAsString(); + String expectedFilePath = expArgs.get(0).getAsString(); String actualFilePath = actualArgs.get(0).getAsString().replace(sourceRoot.toString(), ""); - if (actualFilePath.startsWith("/") || actualFilePath.startsWith("\\")) { + if (actualFilePath.startsWith("/")) { + actualFilePath = actualFilePath.substring(1); + } else if (actualFilePath.startsWith("\\")) { actualFilePath = actualFilePath.substring(1); + actualFilePath = actualFilePath.replace("\\", "/"); + actualTextEdit = actualTextEdit.replaceAll(System.lineSeparator(), "\n"); } - String expectedFilePath = expArgs.get(0).getAsString(); - - String actualTextEdit = actualArgs.get(1).getAsString(); - String expectedTextEdit = expArgs.get(1).getAsString(); - if (actualFilePath.equals(expectedFilePath) && actualTextEdit.equals(expectedTextEdit)) { return true; } diff --git a/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/codeaction/AddToConfigTomlTest.java b/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/codeaction/AddToConfigTomlTest.java index 6fb819a69bf5..cdebfd1887a0 100644 --- a/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/codeaction/AddToConfigTomlTest.java +++ b/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/codeaction/AddToConfigTomlTest.java @@ -46,12 +46,6 @@ public void negativeTest(String config) throws IOException, WorkspaceDocumentExc @Override public Object[][] dataProvider() { return new Object[][]{ - {"without_config_toml_default_module1.json"}, - {"without_config_toml_default_module2.json"}, - {"without_config_toml_default_module3.json"}, - {"without_config_toml_non_default_module1.json"}, - {"without_config_toml_non_default_module2.json"}, - {"without_config_toml_non_default_module3.json"}, {"with_config_toml_default_module1.json"}, {"with_config_toml_default_module2.json"}, {"with_config_toml_default_module3.json"}, @@ -63,7 +57,13 @@ public Object[][] dataProvider() { {"with_config_toml_non_default_module3.json"}, {"with_config_toml_non_default_module4.json"}, {"with_config_toml_non_default_module5.json"}, - {"with_config_toml_non_default_module6.json"} + {"with_config_toml_non_default_module6.json"}, + {"without_config_toml_default_module1.json"}, + {"without_config_toml_default_module2.json"}, + {"without_config_toml_default_module3.json"}, + {"without_config_toml_non_default_module1.json"}, + {"without_config_toml_non_default_module2.json"}, + {"without_config_toml_non_default_module3.json"} }; } From 9a04ab6780bcf1c3d642cd4767871bee0ee112c7 Mon Sep 17 00:00:00 2001 From: LakshanWeerasinghe Date: Tue, 30 Jul 2024 10:52:59 +0530 Subject: [PATCH 5/8] Address review suggestion --- .../providers/AddToConfigTomlCodeAction.java | 57 ++++++++++--------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/codeaction/providers/AddToConfigTomlCodeAction.java b/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/codeaction/providers/AddToConfigTomlCodeAction.java index 798fe61e089d..d6a8274032d0 100644 --- a/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/codeaction/providers/AddToConfigTomlCodeAction.java +++ b/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/codeaction/providers/AddToConfigTomlCodeAction.java @@ -67,7 +67,6 @@ @JavaSPIService("org.ballerinalang.langserver.commons.codeaction.spi.LSCodeActionProvider") public class AddToConfigTomlCodeAction implements RangeBasedCodeActionProvider { - private static final String NAME = "Add to Config.toml"; private static final String CONFIG_TOML = "Config.toml"; @Override @@ -133,32 +132,17 @@ public List getCodeActions(CodeActionContext context, RangeBasedPosi return Collections.emptyList(); } - return withConfigTomlCodeActions(basicType, anyDataOrJsonType, moduleConfigDetails, selectedConf, + return getWithConfigTomlCodeActions(basicType, anyDataOrJsonType, moduleConfigDetails, selectedConf, configTomlPath, toml.get(), module, lastNodeLine); } - private List withConfigTomlCodeActions(TypeSymbol basicType, TypeSymbol anyDataOrJsonType, - ConfigurableFinder.ModuleConfigDetails moduleConfigDetails, - ConfigurableFinder.ConfigVariable selectedConf, - Path configTomlPath, Toml toml, - Module module, int lastNodeLine) { - Position position; - boolean hasAtLeastOneEntry = lastNodeLine != 0; - if (lastNodeLine == 0 && !module.isDefaultModule()) { - Map entries = toml.rootNode().entries(); - for (TopLevelNode node : entries.values()) { - int nodeLine = node.location().lineRange().endLine().line(); - if (nodeLine > lastNodeLine) { - lastNodeLine = nodeLine; - } - } - position = PositionUtil.toPosition( - LinePosition.from(lastNodeLine == 0 ? 0 : lastNodeLine + 3, 0)); - } else { - position = PositionUtil.toPosition( - LinePosition.from(lastNodeLine == 0 ? 0 : lastNodeLine + 1, 0)); - } - + private List getWithConfigTomlCodeActions(TypeSymbol basicType, TypeSymbol anyDataOrJsonType, + ConfigurableFinder.ModuleConfigDetails moduleConfigDetails, + ConfigurableFinder.ConfigVariable selectedConf, + Path configTomlPath, Toml toml, + Module module, int lastNodeLine) { + boolean hasAtLeastOneEntry = lastNodeLine > 0; + Position position = getTomlInsertPosition(toml, module, lastNodeLine); List codeActions = new ArrayList<>(); if (selectedConf.isRequired()) { TextEdit textEdit = new TextEdit(new Range(position, position), @@ -176,6 +160,25 @@ private List withConfigTomlCodeActions(TypeSymbol basicType, TypeSym return codeActions; } + private static Position getTomlInsertPosition(Toml toml, Module module, int lastNodeLine) { + Position position; + if (lastNodeLine == 0 && !module.isDefaultModule()) { + Map entries = toml.rootNode().entries(); + for (TopLevelNode node : entries.values()) { + int nodeLine = node.location().lineRange().endLine().line(); + if (nodeLine > lastNodeLine) { + lastNodeLine = nodeLine; + } + } + position = PositionUtil.toPosition( + LinePosition.from(lastNodeLine == 0 ? 0 : lastNodeLine + 3, 0)); + } else { + position = PositionUtil.toPosition( + LinePosition.from(lastNodeLine == 0 ? 0 : lastNodeLine + 1, 0)); + } + return position; + } + private static List withoutConfigTomlCodeActions(TypeSymbol basicType, TypeSymbol anyDataOrJsonType, ConfigurableFinder.ModuleConfigDetails moduleConfigDetails, ConfigurableFinder.ConfigVariable selectedConf, @@ -184,13 +187,13 @@ private static List withoutConfigTomlCodeActions(TypeSymbol basicTyp if (selectedConf.isRequired()) { String newText = getEdits(moduleConfigDetails, basicType, anyDataOrJsonType); CodeAction codeAction = CodeActionUtil.createCodeAction(CommandConstants.ADD_ALL_TO_CONFIG_TOML, - new Command(NAME, CommandConstants.CREATE_CONFIG_TOML_COMMAND, + new Command(CommandConstants.ADD_TO_CONFIG_TOML, CommandConstants.CREATE_CONFIG_TOML_COMMAND, List.of(configTomlPath.toString(), newText)), CodeActionKind.Empty); codeActions.add(codeAction); } String newText = getTableEntryEdit(selectedConf, basicType, anyDataOrJsonType); CodeAction codeAction = CodeActionUtil.createCodeAction(CommandConstants.ADD_TO_CONFIG_TOML, - new Command(NAME, CommandConstants.CREATE_CONFIG_TOML_COMMAND, + new Command(CommandConstants.ADD_TO_CONFIG_TOML, CommandConstants.CREATE_CONFIG_TOML_COMMAND, List.of(configTomlPath.toString(), newText)), CodeActionKind.Empty); codeActions.add(codeAction); return codeActions; @@ -286,6 +289,6 @@ private static Optional readToml(Path path) { @Override public String getName() { - return NAME; + return CommandConstants.ADD_TO_CONFIG_TOML; } } From 4409311fefc953a687bba7c434d3ac88ae2b46ad Mon Sep 17 00:00:00 2001 From: LakshanWeerasinghe Date: Tue, 30 Jul 2024 15:02:59 +0530 Subject: [PATCH 6/8] Remove project loading using file path --- .../providers/AddToConfigTomlCodeAction.java | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/codeaction/providers/AddToConfigTomlCodeAction.java b/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/codeaction/providers/AddToConfigTomlCodeAction.java index d6a8274032d0..3ae307bc9865 100644 --- a/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/codeaction/providers/AddToConfigTomlCodeAction.java +++ b/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/codeaction/providers/AddToConfigTomlCodeAction.java @@ -82,17 +82,12 @@ public boolean validate(CodeActionContext context, RangeBasedPositionDetails pos @Override public List getCodeActions(CodeActionContext context, RangeBasedPositionDetails posDetails) { - String orgName; - try { - Project project = context.workspace().loadProject(context.filePath()); - if (project.kind() == ProjectKind.SINGLE_FILE_PROJECT) { - return Collections.emptyList(); - } - orgName = project.currentPackage().packageOrg().value(); - } catch (Throwable e) { + Module module = context.currentModule().get(); + Project project = module.project(); + if (project.kind() == ProjectKind.SINGLE_FILE_PROJECT) { return Collections.emptyList(); } - + String orgName = project.currentPackage().packageOrg().value(); SemanticModel semanticModel = context.currentSemanticModel().get(); Types types = semanticModel.types(); TypeBuilder builder = types.builder(); @@ -123,7 +118,6 @@ public List getCodeActions(CodeActionContext context, RangeBasedPosi if (toml.isEmpty()) { return Collections.emptyList(); } - Module module = context.currentModule().get(); int lastNodeLine = module.isDefaultModule() ? rootModuleConfigDiff(toml.get(), orgName, module.moduleName().toString(), configVarMap) : nonRootModuleConfigDiff(toml.get(), orgName, module.moduleName(), configVarMap); From 8425e067a6b0b1921a40ca589d32275c6c42ffe0 Mon Sep 17 00:00:00 2001 From: LakshanWeerasinghe Date: Wed, 31 Jul 2024 22:11:21 +0530 Subject: [PATCH 7/8] Address review suggestions --- .../codeaction/providers/AddToConfigTomlCodeAction.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/codeaction/providers/AddToConfigTomlCodeAction.java b/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/codeaction/providers/AddToConfigTomlCodeAction.java index 3ae307bc9865..82b1e016ee44 100644 --- a/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/codeaction/providers/AddToConfigTomlCodeAction.java +++ b/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/codeaction/providers/AddToConfigTomlCodeAction.java @@ -82,6 +82,9 @@ public boolean validate(CodeActionContext context, RangeBasedPositionDetails pos @Override public List getCodeActions(CodeActionContext context, RangeBasedPositionDetails posDetails) { + if (context.currentModule().isEmpty()) { + return Collections.emptyList(); + } Module module = context.currentModule().get(); Project project = module.project(); if (project.kind() == ProjectKind.SINGLE_FILE_PROJECT) { @@ -115,14 +118,14 @@ public List getCodeActions(CodeActionContext context, RangeBasedPosi } Optional toml = readToml(configTomlPath); - if (toml.isEmpty()) { + if (toml.isEmpty() || configVarMap.isEmpty()) { return Collections.emptyList(); } int lastNodeLine = module.isDefaultModule() ? rootModuleConfigDiff(toml.get(), orgName, module.moduleName().toString(), configVarMap) : nonRootModuleConfigDiff(toml.get(), orgName, module.moduleName(), configVarMap); - if (configVarMap.isEmpty() || !configVarMap.containsKey(selectedConf.name())) { + if (!configVarMap.containsKey(selectedConf.name())) { return Collections.emptyList(); } From 9cb4538e11fcd1b09daddb210feed88b6219de3f Mon Sep 17 00:00:00 2001 From: LakshanWeerasinghe Date: Thu, 1 Aug 2024 19:15:45 +0530 Subject: [PATCH 8/8] Address review suggestions --- .../providers/AddToConfigTomlCodeAction.java | 21 ++++++++++--------- .../utils/ConfigTomlValueGenerationUtil.java | 13 +++++------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/codeaction/providers/AddToConfigTomlCodeAction.java b/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/codeaction/providers/AddToConfigTomlCodeAction.java index 82b1e016ee44..fb76b1f7c911 100644 --- a/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/codeaction/providers/AddToConfigTomlCodeAction.java +++ b/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/codeaction/providers/AddToConfigTomlCodeAction.java @@ -158,7 +158,6 @@ private List getWithConfigTomlCodeActions(TypeSymbol basicType, Type } private static Position getTomlInsertPosition(Toml toml, Module module, int lastNodeLine) { - Position position; if (lastNodeLine == 0 && !module.isDefaultModule()) { Map entries = toml.rootNode().entries(); for (TopLevelNode node : entries.values()) { @@ -167,13 +166,11 @@ private static Position getTomlInsertPosition(Toml toml, Module module, int last lastNodeLine = nodeLine; } } - position = PositionUtil.toPosition( - LinePosition.from(lastNodeLine == 0 ? 0 : lastNodeLine + 3, 0)); + lastNodeLine = lastNodeLine == 0 ? 0 : lastNodeLine + 3; } else { - position = PositionUtil.toPosition( - LinePosition.from(lastNodeLine == 0 ? 0 : lastNodeLine + 1, 0)); + lastNodeLine = lastNodeLine == 0 ? 0 : lastNodeLine + 1; } - return position; + return PositionUtil.toPosition(LinePosition.from(lastNodeLine, 0)); } private static List withoutConfigTomlCodeActions(TypeSymbol basicType, TypeSymbol anyDataOrJsonType, @@ -237,8 +234,10 @@ private static String getTableEntryEdit(ConfigurableFinder.ConfigVariable variab : String.format("%n%s%n", defaultValueStr.value()); } - private static int rootModuleConfigDiff(Toml baseToml, String orgName, String moduleName, - Map configVariables) { + private static int rootModuleConfigDiff(Toml baseToml, + String orgName, + String moduleName, + Map configVariables) { String orgModuleKey = orgName + "." + moduleName; Optional table = baseToml.getTable(orgModuleKey); table.ifPresent(toml -> configDiff(configVariables, toml.rootNode())); // [org.default-module-name] @@ -247,7 +246,9 @@ private static int rootModuleConfigDiff(Toml baseToml, String orgName, String mo return configDiff(configVariables, baseToml.rootNode()); // without name } - private static int nonRootModuleConfigDiff(Toml baseToml, String orgName, ModuleName moduleName, + private static int nonRootModuleConfigDiff(Toml baseToml, + String orgName, + ModuleName moduleName, Map configVariables) { String moduleNameStr = moduleName.toString(); String orgModuleKey = orgName + "." + moduleNameStr; @@ -261,7 +262,7 @@ private static int nonRootModuleConfigDiff(Toml baseToml, String orgName, Module } private static int configDiff(Map configVariables, - TomlTableNode moduleNode) { + TomlTableNode moduleNode) { int lastNodeLine = 0; for (Map.Entry entry: moduleNode.entries().entrySet()) { if (entry.getValue().kind() == TomlType.KEY_VALUE) { diff --git a/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/common/utils/ConfigTomlValueGenerationUtil.java b/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/common/utils/ConfigTomlValueGenerationUtil.java index d5bb6b445a21..2967a511e51a 100644 --- a/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/common/utils/ConfigTomlValueGenerationUtil.java +++ b/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/common/utils/ConfigTomlValueGenerationUtil.java @@ -27,7 +27,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Map; /** * Util used to generate value entries for Config.toml keys. @@ -49,7 +48,7 @@ private ConfigTomlValueGenerationUtil() { * @return value string wrapped in {@link TomlEntryValue} */ public static TomlEntryValue getDefaultValueStr(TypeSymbol type, TypeSymbol basicType, - TypeSymbol anydataOrJson, String confName) { + TypeSymbol anydataOrJson, String confName) { switch (type.typeKind()) { case BOOLEAN -> { return new TomlEntryValue("false", true); @@ -102,16 +101,14 @@ public static TomlEntryValue getDefaultValueStr(TypeSymbol type, TypeSymbol basi } } - private static StringBuilder getRecordFields(RecordTypeSymbol recordTypeSymbol, StringBuilder - builder, String prefix) { + private static StringBuilder getRecordFields(RecordTypeSymbol recordTypeSymbol, StringBuilder builder, + String prefix) { List> recordTypeSymbols = RecordUtil.getRecordTypeSymbols(recordTypeSymbol); List validFields = new ArrayList<>(); - Map fields; for (RawTypeSymbolWrapper symbol : recordTypeSymbols) { - fields = RecordUtil.getRecordFields(symbol, Collections.emptyList()); - validFields.addAll(fields.values()); + validFields.addAll(RecordUtil.getRecordFields(symbol, Collections.emptyList()).values()); } for (RecordFieldSymbol recordFieldSymbol : validFields) { TypeSymbol typeSymbol = CommonUtil.getRawType(recordFieldSymbol.typeDescriptor()); @@ -153,7 +150,7 @@ private static String getValueForObjectKey(TypeSymbol type) { } /** - * Wrapper for toml entry value and specify its for a key or not. + * Wrapper for toml entry value that specifies whether it's for a key or not. * * @param value entry value * @param keyValue is the entry for a key