Lang spec v3 - #106
Conversation
…tion framework - Added DotGenerator for generating DOT files representing join point hierarchy. - Introduced EntityGenerator for creating user-defined entity and enum classes. - Created GeneratorConfig for managing code generation configurations. - Developed ProviderDefGenerator for generating provider definition interfaces. - Implemented RegistryGenerator for runtime provider lookup. - Added SpecMerger to merge base and weaver-specific specifications. - Created WeaverAbstractGenerator for generating abstract weaver classes. - Introduced JavaSourceBuilder for building Java source code with proper formatting. - Added TypeMapper for mapping LangSpec2 types to Java types. - Updated WeaverInterface with BaseJoinPointSpec and JoinPoint2 for new join point system. - Enhanced WeaverEngine to support the new provider registry pattern. - Updated build.gradle and settings.gradle to include LangSpec2 dependency.
…ed keywords and sanitizing Java identifiers
… with duplicate checks
…ture for attribute and action signatures
…ntinue the migration towards the new WeaverGen2
… proper type safety.
… handling and imports
…proved type handling
…s it was a fundamentally broken concept
…the concrete classes they extend in AbstractJpGenerator
… usage in AbstractJpGenerator
… joinpoint abstracts
…interpretType function
…efix - remove the root-only user abstract joinpoint path - derive WeaverGen2 class names from the spec prefix - keep the generator aligned with the renamed CxxJoinpoint hierarchy
Search recursively under config.basePackage() + ".joinpoints" for the expected concrete class name, derive the package from the matched source file, and fail if multiple matches are found.
…ect sources. Delete unused XML specification files and clean up DefaultWeaver implementation
…pecification and WeaverGenerator
…y treating it as an action instead of the attribute it is defined as.
…to the quirks of the AST enums
- Add recursive discovery for concrete joinpoint sources - Create missing concrete joinpoint classes from the spec model - Validate concrete class declarations against the expected CRTP form - Report extra, duplicate, or malformed Java sources without modifying them - Preserve nested joinpoint packages and imports - Resolve child abstract constructor node types from parent concrete constructors - Add CLI regressions for nested sources, duplicates, bad declarations, and inherited node types
…idate them by running all tests
compatibility-style forwarding APIs that had grown around the previous design. Key changes: - Introduce JoinPointMember, MemberSignature, and WrapperSignature primitives for member naming, signature comparison, and inherited wrapper suppression. - Move joinpoint member method emission and wrapper suppression into JoinPointMemberEmitter. - Add GeneratedArtifactFactory to centralize generated artifact identity and package-to-path handling. - Replace ConcreteJoinPointSources mutable created-file state with ConcreteSourceSync. - Simplify JoinPointTypeRenderer and TypeMapper by removing redundant forwarding helpers. - Store typed signature sets in GenerationProfile instead of raw strings. - Consolidate duplicated test filesystem utilities. - Add focused JoinPointMember tests. - Update the WeaverGen2 architecture notes.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 84f61fe078
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| sb.append("{\n"); | ||
|
|
||
| // Root | ||
| var root = model.getRoot().map(JpClass::getName).orElse("joinpoint"); |
There was a problem hiding this comment.
Default the JSON root to the model's global join point
When a specification does not explicitly call rootJoinPoint, this hard-coded fallback can name a join point that does not exist. BaseJoinPointSpec, for example, defines its global as LaraJoinPoint without setting a root, so the committed LaraJoinPointSpecification.json now reports joinpoint instead of the previous and actual LaraJoinPoint; consumers relying on root or rootAlias will therefore fail to resolve the root. Use model.getGlobal().getName() as the fallback.
Useful? React with 👍 / 👎.
| var validTypeDefs = Set.copyOf(model.getTypeDefs().keySet()); | ||
| var validEnums = Set.copyOf(model.getEnumDefs().keySet()); | ||
|
|
||
| for (var jp : model.getAllJpClasses()) { |
There was a problem hiding this comment.
Validate references used by typedef fields
When a typedef field contains jpRef, typeDefRef, or enumRef, this loop never checks it because validation only visits join-point members. A specification such as typeDef("T").field("x", jpRef("missing")) consequently passes build(), after which TypeDefEmitter generates a reference such as AMissing<?> and the generated project fails to compile. Apply checkTypeRef recursively to every typedef field as well.
Useful? React with 👍 / 👎.
| var args = pt.args().stream() | ||
| .map(a -> toJavaType(a, selfType, jpRefMapper, typeDefRefMapper, enumRefMapper)) | ||
| .toList(); |
There was a problem hiding this comment.
Box primitive types used as generic arguments
The DSL permits natural declarations such as list(INT) and map(STRING, BOOLEAN), but recursively rendering generic arguments here produces illegal Java types such as List<int> and Map<String, boolean>. These specifications validate successfully and only fail when the generated sources are compiled; primitive arguments need to be boxed while rendering a ParameterizedType.
Useful? React with 👍 / 👎.
| if (v.display() != null) { | ||
| sb.line(enumConst + "(\"" + v.display() + "\")" + suffix); | ||
| } else { | ||
| sb.line(enumConst + "(\"" + v.value() + "\")" + suffix); |
There was a problem hiding this comment.
Escape enum display strings before emitting Java
If an enum's display text contains a quote, backslash, newline, or another Java string escape character, concatenating it directly into the generated constructor call produces malformed Java source or changes the display value. The class already has escapeJavaString for the diagnostic text, so both the explicit display and value fallback should be escaped before being placed in literals.
Useful? React with 👍 / 👎.
| if ((typeString.startsWith("Map<") || typeString.startsWith("map<")) && typeString.endsWith(">")) { | ||
| const innerTypes = typeString.slice(4, -1).split(",").map((t) => t.trim()); |
There was a problem hiding this comment.
Parse nested map arguments without splitting inner commas
For a valid nested type such as Map<String, Map<String, Integer>>, splitting the entire argument text on commas yields three entries, so the converter silently falls back to Record<string, any> and discards the generated API's value type. The same occurs when either argument contains any other comma-bearing generic; split only on the top-level comma or parse the generic structure recursively.
Useful? React with 👍 / 👎.



No description provided.