Skip to content

Commit

Permalink
Deduplicate schema dependency loading (#2194)
Browse files Browse the repository at this point in the history
We need to support this in both JSON-based and FIR-based loading, so extract a common function for the logic.
  • Loading branch information
JakeWharton authored Jul 22, 2024
1 parent af7e6ae commit 214c31e
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,19 @@ internal fun loadProtocolSchemaSet(
classLoader: ClassLoader,
): ProtocolSchemaSet {
val schema = loadProtocolSchema(type, classLoader)
val dependencies = schema.taggedDependencies.map { (tag, dependency) ->
loadProtocolSchema(dependency, classLoader, tag)
}
return ParsedProtocolSchemaSet(
schema = schema,
dependencies = dependencies.associateBy { it.type },
)
return loadProtocolSchemaDependencies(schema, classLoader)
}

internal fun loadProtocolSchemaDependencies(
schema: ProtocolSchema,
classLoader: ClassLoader,
): ParsedProtocolSchemaSet {
val dependencies = schema.taggedDependencies.entries
.associate { (tag, type) ->
require(tag != 0) { "Dependency $type tag must be non-zero" }
type to loadProtocolSchema(type, classLoader, tag)
}
return ParsedProtocolSchemaSet(schema, dependencies)
}

internal fun loadProtocolSchema(
Expand Down Expand Up @@ -228,33 +234,14 @@ internal fun parseProtocolSchemaSet(schemaType: KClass<*>): ProtocolSchemaSet {
)
}

val dependencies = schemaAnnotation.dependencies
.associate {
val dependencyTag = it.tag
val dependencyType = it.schema.toFqType()
require(dependencyTag != 0) {
"Dependency $dependencyType tag must not be non-zero"
}

val schema = loadProtocolSchema(
type = dependencyType,
classLoader = schemaType.java.classLoader,
tag = dependencyTag,
)
dependencyTag to schema
}

val schema = ParsedProtocolSchema(
type = schemaType.toFqType(),
scopes = scopes.toList(),
widgets = widgets,
modifiers = modifiers,
taggedDependencies = dependencies.mapValues { (_, schema) -> schema.type },
)
val schemaSet = ParsedProtocolSchemaSet(
schema,
dependencies.values.associateBy { it.type },
taggedDependencies = schemaAnnotation.dependencies.associate { it.tag to it.schema.toFqType() },
)
val schemaSet = loadProtocolSchemaDependencies(schema, schemaType.java.classLoader)

val duplicatedWidgets = schemaSet.all
.flatMap { it.widgets.map { widget -> widget to it } }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,24 +202,7 @@ public fun parseProtocolSchema(
disposable.dispose()

val dependencyClassLoader = URLClassLoader(dependencies.map { it.toURI().toURL() }.toTypedArray())
val dependencySchemas = schema.taggedDependencies.entries
.associate { (dependencyTag, dependencyType) ->
require(dependencyTag != 0) {
"Dependency $dependencyType tag must not be non-zero"
}

val dependency = loadProtocolSchema(
type = dependencyType,
classLoader = dependencyClassLoader,
tag = dependencyTag,
)
dependencyTag to dependency
}

val schemaSet = ParsedProtocolSchemaSet(
schema,
dependencySchemas.values.associateBy { it.type },
)
val schemaSet = loadProtocolSchemaDependencies(schema, dependencyClassLoader)

val duplicatedWidgets = schemaSet.all
.flatMap { it.widgets.map { widget -> widget to it } }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1090,7 +1090,7 @@ class SchemaParserTest(
assertFailure { parser.parse(SchemaDependencyTagZero::class) }
.isInstanceOf<IllegalArgumentException>()
.hasMessage(
"Dependency app.cash.redwood.layout.RedwoodLayout tag must not be non-zero",
"Dependency app.cash.redwood.layout.RedwoodLayout tag must be non-zero",
)
}

Expand Down

0 comments on commit 214c31e

Please sign in to comment.