Support typed config objects - #479
Conversation
Signed-off-by: Tom <tom@temper.systems>
Signed-off-by: Tom <tom@temper.systems>
Signed-off-by: Tom <tom@temper.systems>
Signed-off-by: Tom <tom@temper.systems>
Signed-off-by: Tom <tom@temper.systems>
Signed-off-by: Tom <tom@temper.systems>
Signed-off-by: Tom <tom@temper.systems>
Signed-off-by: Tom <tom@temper.systems>
Signed-off-by: Tom <tom@temper.systems>
* Work toward better std config injection * Move java config def to frontend Signed-off-by: Tom <tom@temper.systems>
| val javaPackageConfigKey = Symbol("javaPackage") | ||
|
|
||
| /** Config key to specify Maven dependencies */ | ||
| val javaDependenciesKey = Symbol("javaDependencies") |
There was a problem hiding this comment.
Moved to config description in frontend to be with the new config type for use in std.
There was a problem hiding this comment.
Moved to config description in frontend to be with the new config type for use in std.
Now in a different file in be-java.
| val pomPath = filePath("pom.xml") | ||
| val pomMime = MimeType("text", "xml") | ||
|
|
||
| override val configBindingsInjector: BindingsInjector = JavaConfigInjector |
There was a problem hiding this comment.
We still want these configured on each backend so that plugged backends also can register them, even if we don't yet have a way for them to do custom config for std.
| (value.stateVector as InstancePropertyRecord).properties.map { instance -> | ||
| (instance.key as SourceName).baseName.nameText to instance.value | ||
| }.toMap() | ||
| } |
There was a problem hiding this comment.
Even if the definitions are in the frontend, we use them from the java backend.
And while sloppy checks here for config type are better than nothing, somehow sneaking this properly into frontend type checking might be nice.
What does get checked in frontend now, though, is the the field types themselves for the JavaConfig instance, and that's likely to be helpful.
| private val libraryArtifact: String get() = cfg(JavaBackend.javaLibraryArtifactConfigKey) ?: libraryName | ||
|
|
||
| private val libraryArtifact: String | ||
| get() = cfg(JavaConfigKeys.ARTIFACT, JavaConfigKeys.libraryArtifactGlobal) ?: libraryName |
There was a problem hiding this comment.
To support fallback for existing temper libs, check both the typed config and if missing then the global config var.
| | class: JavaConfig, | ||
| | package: "com.example", | ||
| | }; | ||
| | ```, |
There was a problem hiding this comment.
If we get target-typed prop bags, we could say this instead:
export let java: JavaConfig = {
package: "com.example",
};I'd rather not rely on unique keys, even though package is unique right now, because I suspect different backend configs could conflict easily in the general sense.
| JavaConfigInjector, | ||
| ) | ||
|
|
||
| private val sharedStdModules = lazy { |
There was a problem hiding this comment.
With sharedStdModules themselves already global here, I didn't feel too bad about making the injectors also global. Note that both are private to this file.
| */ | ||
| fun addBindingsInjector(injector: BindingsInjector) { | ||
| mutableBindingsInjectors.add(injector) | ||
| } |
There was a problem hiding this comment.
Here's comments about me musing on import resolvers.
| dependencies: [ | ||
| "org.junit.jupiter:junit-jupiter:5.9.2", | ||
| ], | ||
| }; |
There was a problem hiding this comment.
Converted std to new style here, which is what needed the schema code being in frontend.
| // Produce exports | ||
| stage == Stage.Export -> true | ||
| stage == Stage.GenerateCode -> true | ||
| else -> false |
There was a problem hiding this comment.
And we discussed this some on discord, but I can't get values into exports unless either:
- Export stage actually provides function values or
- We wait until generate code stage to make exports.
Note that the already existing comment above suggests someone was thinking about exports coming from generate code stage, even though that's not what happens elsewhere.
|
|
||
| private fun TypeShape.isImu(): Boolean { | ||
| return (stayLeaf?.incoming?.source as? DeclTree)?.parts?.let { imuSymbol in it.metadataSymbolMap } == true | ||
| } |
There was a problem hiding this comment.
Not much code needed to produce new values in partial interp for @imu. I don't know what all other functions run, but at least basic values and lists work as shown in this pr. And supporting proper @partialImu usage would be correct here, too, but I didn't look into that in this pr.
I didn't look to see if partial interp support for lists values check @partialImu rules correctly. Lists of strings were already working before any of my recent changes.
| module.addBindingsInjector(injector) | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Do they need to have the authority to affect all modules, or can we just have their effect limited to config modules.
| properties: Map<String, Planting.() -> Any?>, | ||
| ) { | ||
| Call { | ||
| Rn(ParsedName(imuDecorator.name)) |
There was a problem hiding this comment.
Should this be a builtinname? And ExportDecorator.name below?
There was a problem hiding this comment.
Should this be a builtinname? And ExportDecorator.name below?
In at least some cases, I think BuiltinName was failing on me, but I can do a fresh pass to try things out.
There was a problem hiding this comment.
Should this be a builtinname? And ExportDecorator.name below?
In latest checks, BuiltinName worked for imu but not export, so I made the change for imu.
There was a problem hiding this comment.
Thanks for giving that a try.
There was a problem hiding this comment.
It seems less than ideal to have backend-specific stuff outside of that directory.
Is there any way to avoid that?
There was a problem hiding this comment.
It seems less than ideal to have backend-specific stuff outside of that directory.
Is there any way to avoid that?
As I've mentioned, I can't put java config info in be-java and also use it in std, because we don't always have be-java on the classpath.
There was a problem hiding this comment.
As I've mentioned, I can't put java config info in be-java and also use it in std, because we don't always have be-java on the classpath.
And I already linked in the pr description my failed attempt at controlling config injectors from backends.
There was a problem hiding this comment.
@ShawSumma recommends possibly injecting std config content and not just type definitions. Well, full recommendations could be much more elaborate, but that's the simple scope version that maybe I can fit in this pr. So I'll look into that.
* Fail at backend-defined std injectors * Support also injecting std config source * Move java config back to be-java Signed-off-by: Tom <tom@temper.systems>
Signed-off-by: Tom <tom@temper.systems>
Signed-off-by: Tom <tom@temper.systems>
Signed-off-by: Tom <tom@temper.systems>
Signed-off-by: Tom <tom@temper.systems>
| val javaPackageConfigKey = Symbol("javaPackage") | ||
|
|
||
| /** Config key to specify Maven dependencies */ | ||
| val javaDependenciesKey = Symbol("javaDependencies") |
There was a problem hiding this comment.
Moved to config description in frontend to be with the new config type for use in std.
Now in a different file in be-java.
| /** Config key to specify Maven dependencies */ | ||
| const val DEPENDENCIES = "dependencies" | ||
| val dependenciesGlobal = Symbol("javaDependencies") | ||
| } |
There was a problem hiding this comment.
Separated these keys out.
| ) | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
And here's the type definition for java config. Maybe could make this temper source like the bonus config section, but I already had this part working before that was done. That source injection is only for std config. This here is for config typing for any library, including std.
| dependencies: [ | ||
| "org.junit.jupiter:junit-jupiter:5.9.2", | ||
| ], | ||
| }; |
There was a problem hiding this comment.
Backends now can add their own separate config chunk for std, so this also works for plugged in configs. Alternatively, they could use custom backend logic, but seeing config for std that matches config for other libraries can be nice.
| } | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
And the actual helper method that gets called from anywhere that organizes backends (currently 3 places). Most importantly, this provides config for supported backends from the temper cli.
It's also called for funtests and backend tests but without any extra backends listed.
| // This typically is for tests where not all registered backends are on the classpath. | ||
| // In those cases, this message isn't much interesting, but someone's actual environment could be | ||
| // broken, and even in that case, the message should be enough info without a stack dump. | ||
| console.error("Error loading Temper plugin $jvmClassName: ${r.failure}") |
There was a problem hiding this comment.
Shrink error messages for when backends aren't available. This still usually is clear about the issue.
| } | ||
|
|
||
| val defaultBackend: Lazy<Backend.Factory<*>> = | ||
| supportedBackendsGlobal.factories.getValue(BackendId("js")).backend |
There was a problem hiding this comment.
We were only using this in RunTest and not even in the cli, and it was breaking anyone trying to use anything else in this module if be-js wasn't on the classpath, so I removed it.
| properties: Map<String, Planting.() -> Any?>, | ||
| ) { | ||
| Call { | ||
| Rn(ParsedName(imuDecorator.name)) |
There was a problem hiding this comment.
Should this be a builtinname? And ExportDecorator.name below?
In latest checks, BuiltinName worked for imu but not export, so I made the change for imu.
| onError = { error(it) }, | ||
| ) | ||
| // We only get here from backend-specific test classes, so no need for other backends. | ||
| backendOrganization.addSharedStdConfigInjectors(listOf()) |
There was a problem hiding this comment.
For cli, we pass in supportedBackends, but here and for funtests we don't need that, and it causes error messages.
| } | ||
| }, | ||
| ) | ||
| backendOrganization.addSharedStdConfigInjectors(supportedBackends) |
There was a problem hiding this comment.
For main build, inject all extra std config for all supported backends. Otherwise, a unit test case for one backend misses config for others in the same test class. This logic should also be fine for cli needs.
newcalls during partial interp for imu types<groupId>dev.temperlang</groupId>andpackage temper.regex_parser;in generated files):