ibessonov commented on code in PR #1431:
URL: https://github.com/apache/ignite-3/pull/1431#discussion_r1048102244
##########
modules/configuration/src/main/java/org/apache/ignite/internal/configuration/asm/ConfigurationAsmGenerator.java:
##########
@@ -570,1669 +312,116 @@ private Field internalIdField(Class<?> schemaClass,
Set<Class<?>> schemaExtensio
}
/**
- * Construct a {@link InnerNode} definition for a configuration schema.
+ * Copies field into itself or instantiates it if the field is null. Code
like: {@code this.field == null ? new ValueNode() :
+ * (ValueNode)this.field.copy();}.
*
- * @param schemaClass Configuration schema class.
- * @param internalExtensions Internal extensions of the configuration
schema.
- * @param polymorphicExtensions Polymorphic extensions of the
configuration schema.
- * @param schemaFields Fields of the schema class.
- * @param internalFields Fields of internal extensions of the
configuration schema.
- * @param polymorphicFields Fields of polymorphic extensions of the
configuration schema.
- * @param internalIdField Internal id field or {@code null} if it's
not present.
- * @return Constructed {@link InnerNode} definition for the configuration
schema.
+ * @param schemaField Configuration schema class field.
+ * @param getFieldCode Bytecode of getting the field, for example: {@code
this.field} or {@code this.field.field};
+ * @return Bytecode expression.
*/
- private ClassDefinition createNodeClass(
- Class<?> schemaClass,
- Set<Class<?>> internalExtensions,
- Set<Class<?>> polymorphicExtensions,
- List<Field> schemaFields,
- Collection<Field> internalFields,
- Collection<Field> polymorphicFields,
- @Nullable Field internalIdField
- ) {
- SchemaClassesInfo schemaClassInfo = schemasInfo.get(schemaClass);
-
- // Node class definition.
- ClassDefinition classDef = new ClassDefinition(
- of(PUBLIC, FINAL),
- internalName(schemaClassInfo.nodeClassName),
- type(InnerNode.class),
- nodeClassInterfaces(schemaClass, internalExtensions)
- );
-
- // Spec fields.
- Map<Class<?>, FieldDefinition> specFields = new HashMap<>();
-
- int i = 0;
-
- for (Class<?> clazz : concat(List.of(schemaClass), internalExtensions,
polymorphicExtensions)) {
- specFields.put(clazz, classDef.declareField(of(PRIVATE, FINAL),
"_spec" + i++, clazz));
- }
-
- // Define the rest of the fields.
- Map<String, FieldDefinition> fieldDefs = new HashMap<>();
-
- // To store the id of the polymorphic configuration instance.
- FieldDefinition polymorphicTypeIdFieldDef = null;
-
- // Field with @InjectedName.
- FieldDefinition injectedNameFieldDef = null;
-
- for (Field schemaField : concat(schemaFields, internalFields,
polymorphicFields)) {
- String fieldName = fieldName(schemaField);
-
- FieldDefinition fieldDef = addNodeField(classDef, schemaField,
fieldName);
-
- fieldDefs.put(fieldName, fieldDef);
-
- if (isPolymorphicId(schemaField)) {
- polymorphicTypeIdFieldDef = fieldDef;
- } else if (isInjectedName(schemaField)) {
- injectedNameFieldDef = fieldDef;
- }
- }
-
- // org.apache.ignite.internal.configuration.tree.InnerNode#schemaType
- addNodeSchemaTypeMethod(classDef, schemaClass, polymorphicExtensions,
polymorphicTypeIdFieldDef);
-
- FieldDefinition internalSchemaTypesFieldDef = null;
-
- if (!internalExtensions.isEmpty()) {
- internalSchemaTypesFieldDef = classDef.declareField(
- of(PRIVATE, FINAL),
- "_" + INTERNAL_SCHEMA_TYPES_MTD.getName(),
- Class[].class
- );
- }
-
- // Constructor.
- addNodeConstructor(
- classDef,
- specFields,
- fieldDefs,
- schemaFields,
- internalFields,
- polymorphicFields,
- internalExtensions,
- internalSchemaTypesFieldDef
- );
-
- // Add view method for internal id.
- if (internalIdField != null) {
- addNodeInternalIdMethod(classDef, internalIdField);
- }
-
- // VIEW and CHANGE methods.
- for (Field schemaField : concat(schemaFields, internalFields)) {
- String fieldName = schemaField.getName();
-
- FieldDefinition fieldDef = fieldDefs.get(fieldName);
-
- addNodeViewMethod(
- classDef,
- schemaField,
- viewMtd -> getThisFieldCode(viewMtd, fieldDef),
- null
- );
-
- // Read only.
- if (isPolymorphicId(schemaField) || isInjectedName(schemaField)) {
- continue;
- }
-
- // Add change methods.
- MethodDefinition changeMtd0 = addNodeChangeMethod(
- classDef,
- schemaField,
- changeMtd -> getThisFieldCode(changeMtd, fieldDef),
- (changeMtd, newValue) -> setThisFieldCode(changeMtd,
newValue, fieldDef),
- null
- );
-
- addNodeChangeBridgeMethod(classDef,
changeClassName(schemaField.getDeclaringClass()), changeMtd0);
- }
-
- Map<Class<?>, List<Field>> polymorphicFieldsByExtension = Map.of();
-
- MethodDefinition changePolymorphicTypeIdMtd = null;
-
- if (!polymorphicExtensions.isEmpty()) {
- assert polymorphicTypeIdFieldDef != null : schemaClass.getName();
-
- addNodeSpecificNodeMethod(classDef, polymorphicExtensions,
polymorphicTypeIdFieldDef);
-
- changePolymorphicTypeIdMtd = addNodeChangePolymorphicTypeIdMethod(
- classDef,
- fieldDefs,
- polymorphicExtensions,
- polymorphicFields,
- polymorphicTypeIdFieldDef
- );
-
- addNodeConvertMethods(classDef, schemaClass,
polymorphicExtensions, changePolymorphicTypeIdMtd);
-
- polymorphicFieldsByExtension = new LinkedHashMap<>();
-
- for (Class<?> polymorphicExtension : polymorphicExtensions) {
- polymorphicFieldsByExtension.put(
- polymorphicExtension,
- polymorphicFields.stream()
- .filter(f ->
polymorphicExtension.equals(f.getDeclaringClass()))
- .collect(toList())
- );
- }
- }
-
- // traverseChildren
- addNodeTraverseChildrenMethod(
- classDef,
- schemaClass,
- fieldDefs,
- schemaFields,
- internalFields,
- polymorphicFieldsByExtension,
- polymorphicTypeIdFieldDef
- );
-
- // traverseChild
- addNodeTraverseChildMethod(
- classDef,
- fieldDefs,
- schemaFields,
- internalFields,
- polymorphicFieldsByExtension,
- polymorphicTypeIdFieldDef
- );
-
- // construct
- addNodeConstructMethod(
- classDef,
- fieldDefs,
- schemaFields,
- internalFields,
- polymorphicFieldsByExtension,
- polymorphicTypeIdFieldDef,
- changePolymorphicTypeIdMtd
- );
+ BytecodeExpression newOrCopyNodeField(Field schemaField,
BytecodeExpression getFieldCode) {
+ ParameterizedType nodeType =
typeFromJavaClassName(schemasInfo.get(schemaField.getType()).nodeClassName);
- // constructDefault
- addNodeConstructDefaultMethod(
- schemaClass,
- classDef,
- specFields,
- fieldDefs,
- schemaFields,
- internalFields,
- polymorphicFieldsByExtension,
- polymorphicTypeIdFieldDef
+ // this.field == null ? new ValueNode() : (ValueNode)this.field.copy();
+ return inlineIf(
+ isNull(getFieldCode),
+ newInstance(nodeType),
+ copyNodeField(schemaField, getFieldCode)
);
+ }
- if (injectedNameFieldDef != null) {
- addInjectedNameFieldMethods(classDef, injectedNameFieldDef);
- }
-
- if (polymorphicTypeIdFieldDef != null) {
- addIsPolymorphicMethod(classDef);
- }
-
- if (internalSchemaTypesFieldDef != null) {
- addInternalSchemaTypesMethod(classDef,
internalSchemaTypesFieldDef);
- }
-
- if
(schemaClass.getSuperclass().isAnnotationPresent(AbstractConfiguration.class)) {
- addIsExtendAbstractConfigurationMethod(classDef);
- }
+ /**
+ * Copies field into itself. Code like: {@code
(ValueNode)this.field.copy();}.
+ *
+ * @param schemaField Configuration schema class field.
+ * @param getFieldCode Bytecode of getting the field, for example: {@code
this.field} or {@code this.field.field};
+ * @return Bytecode expression.
+ */
+ BytecodeExpression copyNodeField(Field schemaField, BytecodeExpression
getFieldCode) {
+ ParameterizedType nodeType = isNamedConfigValue(schemaField)
+ ? type(NamedListNode.class) :
typeFromJavaClassName(schemasInfo.get(schemaField.getType()).nodeClassName);
- return classDef;
+ // (ValueNode)this.field.copy();
+ return getFieldCode.invoke(COPY).cast(nodeType);
}
/**
- * Add {@link InnerNode#schemaType} method implementation to the class.
+ * Creates {@code *Node::new} lambda expression with {@link Supplier} type.
*
- * @param classDef Class definition.
- * @param schemaClass Configuration schema class.
- * @param polymorphicExtensions Polymorphic extensions of the
configuration schema.
- * @param polymorphicTypeIdFieldDef Identification field for the
polymorphic configuration instance.
+ * @param nodeClassName Name of the {@code *Node} class.
+ * @return InvokeDynamic bytecode expression.
*/
- private static void addNodeSchemaTypeMethod(
- ClassDefinition classDef,
- Class<?> schemaClass,
- Set<Class<?>> polymorphicExtensions,
- @Nullable FieldDefinition polymorphicTypeIdFieldDef
- ) {
- MethodDefinition schemaTypeMtd = classDef.declareMethod(
- of(PUBLIC),
- "schemaType",
- type(Class.class)
+ @NotNull
+ private static BytecodeExpression newNamedListElementLambda(String
nodeClassName) {
+ return invokeDynamic(
+ LAMBDA_METAFACTORY,
+ asList(
+ getMethodType(getType(Object.class)),
+ new Handle(
+ H_NEWINVOKESPECIAL,
+ internalName(nodeClassName),
+ "<init>",
+ getMethodDescriptor(Type.VOID_TYPE),
+ false
+ ),
+
getMethodType(typeFromJavaClassName(nodeClassName).getAsmType())
+ ),
+ "get",
+ methodType(Supplier.class)
);
-
- BytecodeBlock mtdBody = schemaTypeMtd.getBody();
-
- if (polymorphicExtensions.isEmpty()) {
- mtdBody.append(constantClass(schemaClass)).retObject();
- } else {
- assert polymorphicTypeIdFieldDef != null : classDef.getName();
-
- StringSwitchBuilder switchBuilderTypeId =
typeIdSwitchBuilder(schemaTypeMtd, polymorphicTypeIdFieldDef);
-
- for (Class<?> polymorphicExtension : polymorphicExtensions) {
- switchBuilderTypeId.addCase(
- polymorphicInstanceId(polymorphicExtension),
- constantClass(polymorphicExtension).ret()
- );
- }
-
- mtdBody.append(switchBuilderTypeId.build());
- }
}
/**
- * Declares field that corresponds to configuration value. Depending on
the schema, 5 options possible:
- * <ul>
- * <li>
- * {@code @Value public type fieldName}<br/>becomes<br/>
- * {@code public BoxedType fieldName}
- * </li>
- * <li>
- * {@code @ConfigValue public MyConfigurationSchema
fieldName}<br/>becomes<br/>
- * {@code public MyNode fieldName}
- * </li>
- * <li>
- * {@code @NamedConfigValue public type fieldName}<br/>becomes<br/>
- * {@code public NamedListNode fieldName}
- * </li>
- * <li>
- * {@code @PolymorphicId public String fieldName}<br/>becomes<br/>
- * {@code public String fieldName}
- * </li>
- * <li>
- * {@code @InjectedName public String fieldName}<br/>becomes<br/>
- * {@code public String fieldName}
- * </li>
- * </ul>
+ * Replaces first letter in string with its upper-cased variant.
*
- * @param classDef Node class definition.
- * @param schemaField Configuration Schema class field.
- * @param fieldName Field name.
- * @return Declared field definition.
- * @throws IllegalArgumentException If an unsupported {@code schemaField}
was passed.
+ * @param name Some string.
+ * @return Capitalized version of passed string.
*/
- private FieldDefinition addNodeField(ClassDefinition classDef, Field
schemaField, String fieldName) {
- Class<?> schemaFieldClass = schemaField.getType();
-
- ParameterizedType nodeFieldType;
-
- if (isValue(schemaField) || isPolymorphicId(schemaField) ||
isInjectedName(schemaField)) {
- nodeFieldType = type(box(schemaFieldClass));
- } else if (isConfigValue(schemaField)) {
- nodeFieldType =
typeFromJavaClassName(schemasInfo.get(schemaFieldClass).nodeClassName);
- } else if (isNamedConfigValue(schemaField)) {
- nodeFieldType = type(NamedListNode.class);
- } else {
- throw new IllegalArgumentException("Unsupported field: " +
schemaField);
- }
-
- return classDef.declareField(of(PUBLIC), fieldName, nodeFieldType);
+ private static String capitalize(String name) {
+ return name.substring(0, 1).toUpperCase() + name.substring(1);
}
/**
- * Implements default constructor for the node class. It initializes
{@code _spec} field and every other field that represents named
- * list configuration.
+ * Returns internalized version of class name, replacing dots with slashes.
*
- * @param classDef Node class definition.
- * @param specFields Definition of fields for the {@code _spec#} fields of
the node class. Mapping: configuration schema class -> {@code
- * _spec#} field.
- * @param fieldDefs Field definitions for all fields of node class
excluding {@code _spec}.
- * @param schemaFields Fields of the schema class.
- * @param internalFields Fields of internal extensions of the
configuration schema.
- * @param polymorphicFields Fields of polymorphic extensions of the
configuration schema.
- * @param internalExtensions Internal extensions of the configuration
schema.
- * @param internalSchemaTypesFieldDef Final field which stores {@code
internalExtensions}.
+ * @param className Class name (with package).
+ * @return Internal class name.
+ * @see Type#getInternalName(Class)
*/
- private void addNodeConstructor(
- ClassDefinition classDef,
- Map<Class<?>, FieldDefinition> specFields,
- Map<String, FieldDefinition> fieldDefs,
- Collection<Field> schemaFields,
- Collection<Field> internalFields,
- Collection<Field> polymorphicFields,
- Set<Class<?>> internalExtensions,
- @Nullable FieldDefinition internalSchemaTypesFieldDef
- ) {
- MethodDefinition ctor = classDef.declareConstructor(of(PUBLIC));
-
- BytecodeBlock ctorBody = ctor.getBody();
-
- // super();
- ctorBody
- .append(ctor.getThis())
- .invokeConstructor(InnerNode.class);
-
- // this._spec# = new MyConfigurationSchema();
- for (Map.Entry<Class<?>, FieldDefinition> e : specFields.entrySet()) {
- ctorBody.append(ctor.getThis().setField(e.getValue(),
newInstance(e.getKey())));
- }
-
- for (Field schemaField : concat(schemaFields, internalFields,
polymorphicFields)) {
- if (!isNamedConfigValue(schemaField)) {
- continue;
- }
-
- FieldDefinition fieldDef = fieldDefs.get(fieldName(schemaField));
-
- // this.values = new NamedListNode<>(key, ValueNode::new,
"polymorphicIdFieldName");
- ctorBody.append(setThisFieldCode(ctor,
newNamedListNode(schemaField), fieldDef));
- }
-
- if (!internalExtensions.isEmpty()) {
- assert internalSchemaTypesFieldDef != null : classDef;
-
- // Class[] tmp;
- Variable tmpVar =
ctor.getScope().createTempVariable(Class[].class);
-
- BytecodeBlock initInternalSchemaTypesField = new BytecodeBlock();
-
- // tmp = new Class[size];
-
initInternalSchemaTypesField.append(tmpVar.set(newArray(type(Class[].class),
internalExtensions.size())));
-
- int i = 0;
-
- for (Class<?> extension : internalExtensions) {
- // tmp[i] = InternalTableConfigurationSchema.class;
- initInternalSchemaTypesField.append(set(
- tmpVar,
- constantInt(i++),
- constantClass(extension)
- ));
- }
-
- // this._internalConfigTypes = tmp;
- initInternalSchemaTypesField.append(setThisFieldCode(ctor, tmpVar,
internalSchemaTypesFieldDef));
-
- ctorBody.append(initInternalSchemaTypesField);
- }
-
- // return;
- ctorBody.ret();
+ @NotNull
Review Comment:
Sorry, my bad
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]