187 lines
5.2 KiB
Dart
187 lines
5.2 KiB
Dart
/// Naming convention conversion utilities
|
|
library;
|
|
|
|
/// Naming conversion utilities for code generation
|
|
class NamingConverter {
|
|
/// Convert to camelCase
|
|
static String toCamelCase(String input) {
|
|
if (input.isEmpty) return input;
|
|
|
|
// If already camelCase (starts with lowercase), return as-is
|
|
if (RegExp(r'^[a-z][a-zA-Z0-9]*$').hasMatch(input)) {
|
|
return input;
|
|
}
|
|
|
|
// If PascalCase (starts with uppercase), convert to camelCase
|
|
if (RegExp(r'^[A-Z][a-zA-Z0-9]*$').hasMatch(input)) {
|
|
return input[0].toLowerCase() + input.substring(1);
|
|
}
|
|
|
|
// Handle underscore-separated strings
|
|
final parts = input.split('_').where((p) => p.isNotEmpty).toList();
|
|
if (parts.isEmpty) return input;
|
|
|
|
var result = parts.first.toLowerCase();
|
|
for (var i = 1; i < parts.length; i++) {
|
|
final part = parts[i];
|
|
if (part.isNotEmpty) {
|
|
result += part[0].toUpperCase() + part.substring(1).toLowerCase();
|
|
}
|
|
}
|
|
|
|
return result.isEmpty ? input : result;
|
|
}
|
|
|
|
/// Convert to PascalCase
|
|
static String toPascalCase(String input) {
|
|
if (input.isEmpty) return input;
|
|
|
|
// If contains underscores, split and convert each part
|
|
if (input.contains('_')) {
|
|
final parts = input.split('_');
|
|
var result = '';
|
|
for (final part in parts) {
|
|
if (part.isNotEmpty) {
|
|
// Keep original casing, only ensure first letter is uppercase
|
|
if (part[0].toUpperCase() == part[0]) {
|
|
result += part;
|
|
} else {
|
|
result += part[0].toUpperCase() + part.substring(1);
|
|
}
|
|
}
|
|
}
|
|
return result.isEmpty ? input : result;
|
|
}
|
|
|
|
// If already PascalCase (no underscores, starts with uppercase), return
|
|
if (input[0].toUpperCase() == input[0]) {
|
|
return input;
|
|
}
|
|
|
|
// If camelCase (no underscores), convert first letter to uppercase
|
|
if (RegExp(r'^[a-zA-Z][a-zA-Z0-9]*$').hasMatch(input)) {
|
|
return input[0].toUpperCase() + input.substring(1);
|
|
}
|
|
|
|
return input;
|
|
}
|
|
|
|
/// Convert to snake_case
|
|
static String toSnakeCase(String input) {
|
|
if (input.isEmpty) return input;
|
|
|
|
// Handle PascalCase and camelCase
|
|
final result =
|
|
input.replaceAllMapped(RegExp('([A-Z]+)([A-Z][a-z])'), (match) {
|
|
return '${match[1]!.substring(0, match[1]!.length - 1)}_${match[2]}';
|
|
}).replaceAllMapped(RegExp(r'([a-z\d])([A-Z])'), (match) {
|
|
return '${match[1]}_${match[2]}';
|
|
}).toLowerCase();
|
|
|
|
return result;
|
|
}
|
|
|
|
/// Convert to constant name (UPPER_SNAKE_CASE)
|
|
static String toConstantCase(String name) {
|
|
final cleanName = name.replaceAll(RegExp('[^a-zA-Z0-9_]'), '_');
|
|
return toSnakeCase(cleanName).toUpperCase();
|
|
}
|
|
|
|
/// Convert to Dart property name
|
|
static String toDartPropertyName(String propName) {
|
|
// If already camelCase (no underscores, starts with lowercase), return
|
|
if (RegExp(r'^[a-z][a-zA-Z0-9]*$').hasMatch(propName)) {
|
|
return propName;
|
|
}
|
|
|
|
// PascalCase to camelCase
|
|
if (RegExp(r'^[A-Z][a-zA-Z0-9]*$').hasMatch(propName)) {
|
|
return propName[0].toLowerCase() + propName.substring(1);
|
|
}
|
|
|
|
// Handle special characters and numbers at start
|
|
var result = propName;
|
|
|
|
// If starts with number, add prefix
|
|
if (RegExp('^[0-9]').hasMatch(result)) {
|
|
result = 'n$result';
|
|
}
|
|
|
|
// Replace special characters with underscores
|
|
result = result.replaceAll(RegExp('[^a-zA-Z0-9_]'), '_');
|
|
|
|
// Convert to camelCase
|
|
result = toCamelCase(result);
|
|
|
|
// Ensure not empty
|
|
if (result.isEmpty) {
|
|
result = 'property';
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// Generate class name
|
|
static String generateClassName(String name) {
|
|
final cleanName = name.replaceAll(RegExp('[^a-zA-Z0-9_]'), '_');
|
|
return toPascalCase(cleanName);
|
|
}
|
|
|
|
/// Generate file name
|
|
static String generateFileName(String name) {
|
|
return '${toSnakeCase(name)}.dart';
|
|
}
|
|
|
|
/// Generate enum value name
|
|
static String generateEnumValueName(dynamic value, int index) {
|
|
if (value is String) {
|
|
final cleanValue = value.replaceAll(RegExp('[^a-zA-Z0-9_]'), '');
|
|
if (cleanValue.isNotEmpty && isValidDartIdentifier(cleanValue)) {
|
|
return toCamelCase(cleanValue);
|
|
}
|
|
}
|
|
return 'value${index + 1}';
|
|
}
|
|
|
|
/// Validate if string is a valid Dart identifier
|
|
static bool isValidDartIdentifier(String identifier) {
|
|
if (identifier.isEmpty) return false;
|
|
final regex = RegExp(r'^[a-zA-Z_][a-zA-Z0-9_]*$');
|
|
return regex.hasMatch(identifier);
|
|
}
|
|
|
|
/// Pluralize a word
|
|
static String pluralize(String word) {
|
|
if (word.isEmpty) return word;
|
|
|
|
final lowerWord = word.toLowerCase();
|
|
|
|
// Irregular plurals
|
|
const irregularPlurals = {
|
|
'child': 'children',
|
|
'person': 'people',
|
|
'man': 'men',
|
|
'woman': 'women',
|
|
'mouse': 'mice',
|
|
'goose': 'geese',
|
|
};
|
|
|
|
if (irregularPlurals.containsKey(lowerWord)) {
|
|
return irregularPlurals[lowerWord]!;
|
|
}
|
|
|
|
// Regular plurals
|
|
if (lowerWord.endsWith('y')) {
|
|
return '${word.substring(0, word.length - 1)}ies';
|
|
} else if (lowerWord.endsWith('s') ||
|
|
lowerWord.endsWith('sh') ||
|
|
lowerWord.endsWith('ch') ||
|
|
lowerWord.endsWith('x') ||
|
|
lowerWord.endsWith('z')) {
|
|
return '${word}es';
|
|
} else {
|
|
return '${word}s';
|
|
}
|
|
}
|
|
}
|