Skip to content

Commit

Permalink
Fixed Indentation of generated templates, justified details of comple…
Browse files Browse the repository at this point in the history
…tionItems and fixed bug with getDescription
  • Loading branch information
dsalathe committed Sep 28, 2023
1 parent bf72875 commit dd5e4be
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 20 deletions.
2 changes: 1 addition & 1 deletion src/main/resources/logback.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
</appender>

<!-- Root logger settings -->
<root level="info">
<root level="trace"> <!--TODO change to level="info" when releasing first official version-->
<appender-ref ref="FILE"/>
</root>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,54 +15,60 @@ class SDLBCompletionEngineImpl(private val schemaReader: SchemaReader, private v
override def generateCompletionItems(context: SDLBContext): List[CompletionItem] =
val itemSuggestionsFromSchema = schemaReader.retrieveAttributeOrTemplateCollection(context) match
case AttributeCollection(attributes) => generateAttributeSuggestions(attributes, context.getParentContext)
case TemplateCollection(templates, templateType) => generateTemplateSuggestions(templates, templateType)
case TemplateCollection(templates, templateType) => generateTemplateSuggestions(templates, templateType, context.parentPath.size)

val itemSuggestionsFromConfig = contextAdvisor.generateSuggestions(context).map(createCompletionItem)
val itemSuggestionsFromConfigContextSuggestions = contextAdvisor.generateSuggestions(context)
val longestItemLength = itemSuggestionsFromConfigContextSuggestions.maxByOption(_.value.length).map(_.value.length).getOrElse(0)
val itemSuggestionsFromConfig = itemSuggestionsFromConfigContextSuggestions.map(createCompletionItem(_, longestItemLength))
val allItems = itemSuggestionsFromConfig ++ itemSuggestionsFromSchema
if allItems.isEmpty then typeList else allItems //TODO wrong
if allItems.isEmpty then typeList else allItems //TODO too aggressive. Sometimes suggesting nothing is better

private def generateAttributeSuggestions(attributes: Iterable[SchemaItem], parentContext: Option[ConfigValue]): List[CompletionItem] =
val items = parentContext match
case Some(config: ConfigObject) => attributes.filter(item => Option(config.get(item.name)).isEmpty)
case _ => attributes
items.map(createCompletionItem).toList
val longestItemLength = items.maxByOption(_.name.length).map(_.name.length).getOrElse(0)
items.map(createCompletionItem(_, longestItemLength)).toList

private[completion] def generateTemplateSuggestions(templates: Iterable[(String, Iterable[SchemaItem])], templateType: TemplateType): List[CompletionItem] =
private[completion] def generateTemplateSuggestions(templates: Iterable[(String, Iterable[SchemaItem])], templateType: TemplateType, depth: Int): List[CompletionItem] =
val indentDepth = depth + (if templateType == TemplateType.ATTRIBUTES then 0 else 1)
templates.map { case (actionType, attributes) =>
val completionItem = new CompletionItem()
completionItem.setLabel(actionType.toLowerCase)
completionItem.setDetail(" template")
val keyName = if templateType == TemplateType.OBJECT then s"${actionType.toLowerCase}_PLACEHOLDER" else ""
val startObject = if templateType != TemplateType.ATTRIBUTES then "{" else ""
val endObject = if templateType != TemplateType.ATTRIBUTES then "}" else ""
completionItem.setInsertText( //TODO handle indentation
val endObject = if templateType != TemplateType.ATTRIBUTES then (" " * (indentDepth-1)) + "}" else ""
completionItem.setInsertText(
s"""$keyName $startObject
|${
def generatePlaceHolderValue(att: SchemaItem) = {
if att.name == "type" then actionType else att.itemType.defaultValue
}
attributes.map(att => "\t\t" + att.name + " = " + generatePlaceHolderValue(att)).mkString("\n")}\n\t$endObject
|""".stripMargin.replace("\r\n", "\n")) //TODO remove blank lines?
attributes.map(att => (" " * indentDepth) + att.name + " = " + generatePlaceHolderValue(att)).mkString("\n")}\n$endObject
|""".stripMargin.replace("\r\n", "\n").trim)
completionItem.setKind(CompletionItemKind.Snippet)
completionItem
}.toList

private def createCompletionItem(item: SchemaItem): CompletionItem =
private def createCompletionItem(item: SchemaItem, longestItemLength: Int): CompletionItem =
val completionItem = new CompletionItem()
completionItem.setLabel(item.name)
completionItem.setDetail(f" ${if item.required then "required" else ""}%s ${item.itemType.name}%-10s") //TODO check how to justify properly
val trailingSpaces = " " * (2 + longestItemLength - item.name.length)
completionItem.setDetail(trailingSpaces + s"${if item.required then "required" else ""} ${item.itemType.name}")
completionItem.setInsertText(item.name + (if item.itemType == ItemType.OBJECT then " " else " = ") + item.itemType.defaultValue)
completionItem.setKind(CompletionItemKind.Snippet)
completionItem

private def createCompletionItem(item: ContextSuggestion): CompletionItem =
private def createCompletionItem(item: ContextSuggestion, longestItemLength: Int): CompletionItem =
val completionItem = new CompletionItem()
completionItem.setLabel(item.value)
completionItem.setDetail(s" ${item.label}")
val trailingSpaces = " " * (2 + longestItemLength - item.value.length)
completionItem.setDetail(trailingSpaces + s"${item.label}")
completionItem.setInsertText(item.value)
completionItem.setKind(CompletionItemKind.Snippet)
completionItem

private val typeItem = createCompletionItem(SchemaItem("type", ItemType.STRING, " type of object", true))
private val typeItem = createCompletionItem(SchemaItem("type", ItemType.STRING, " type of object", true), 4)
private val typeList = List(typeItem)
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class ContextAdvisorImpl extends ContextAdvisor:
private def retrieveDataObjectIds(context: SDLBContext): List[ContextSuggestion] =
Option(context.textContext.rootConfig.root().get("dataObjects")) match
case Some(asConfigObject: ConfigObject) => asConfigObject.unwrapped().toScala.map { (k, v) => v match
case jMap: JMap[String, Object] => ContextSuggestion(k, Option(jMap.get("type")).map(_.toString).getOrElse(""))
case jMap: JMap[?, ?] => ContextSuggestion(k, Option(jMap.get("type")).map(_.toString).getOrElse(""))
case _ => ContextSuggestion(k, "")
}.toList
case _ => List.empty[ContextSuggestion]
Expand Down
5 changes: 4 additions & 1 deletion src/main/scala/io/smartdatalake/schema/SchemaContext.scala
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,10 @@ private[schema] case class SchemaContext(private val globalSchema: Value, localS
localSchema.obj.get(DESCRIPTION)
.map(_.str)
.orElse(localSchema.obj.get(ADDITIONAL_PROPERTIES)
.flatMap(_.obj.get(DESCRIPTION).map(_.str)))
.flatMap{
case Obj(value) => value.get(DESCRIPTION).map(_.str)
case _ => None
})
.getOrElse("")
private def generateTemplates(oneOf: Value): Iterable[(String, Iterable[SchemaItem])] =
oneOf match
Expand Down
10 changes: 7 additions & 3 deletions src/main/scala/io/smartdatalake/schema/SchemaReaderImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@ class SchemaReaderImpl(val schemaPath: String) extends SchemaReader {
case Some(schemaContext) => schemaContext.generateSchemaSuggestions
override def retrieveDescription(context: SDLBContext): String = if isWordMeaningless(context.word) then "" else
retrieveSchemaContext(context, withWordInPath = true) match
case None => ""
case Some(schemaContext) => schemaContext.getDescription
case None =>
logger.debug("No schema could be retrieved")
""
case Some(schemaContext) =>
logger.debug("Schema retrieved: {}", schemaContext.toString.take(300))
schemaContext.getDescription

/**
* Not a crucial method but useful to speedup query process and might avoid some unwanted crash
Expand All @@ -44,7 +48,7 @@ class SchemaReaderImpl(val schemaPath: String) extends SchemaReader {
logger.debug("path = {}", path)
path.foldLeft((oInitialSchemaContext, rootConfigValue)){(scCv, elementPath) =>
val (newConfigValue, oTypeObject) = moveInConfigAndRetrieveType(scCv._2, elementPath)
if (newConfigValue == null) {logger.error("Error, newConfig is null with pathElement={} and fullPath={}", elementPath, path)}
if (newConfigValue == null) {logger.warn("Error, newConfig is null with pathElement={} and fullPath={}", elementPath, path)}
val newSchemaContext = oTypeObject match
case Some(objectType) =>
val tryUpdateByName = scCv._1.flatMap(_.updateByName(elementPath))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -288,5 +288,10 @@ class SchemaContextSpec extends UnitSpec {
dataFrameIncrementalModeContext.getDescription.take(21) shouldBe "Compares max entry in"
}

it should "remain quiet if executed on the global schema" in {
val globalContext = initialSchemaContext
globalContext.getDescription shouldBe ""
}


}

0 comments on commit dd5e4be

Please sign in to comment.