diff --git a/rewrite-csharp/src/main/java/org/openrewrite/csharp/service/CSharpNamingService.java b/rewrite-csharp/src/main/java/org/openrewrite/csharp/service/CSharpNamingService.java new file mode 100644 index 0000000..f53a44b --- /dev/null +++ b/rewrite-csharp/src/main/java/org/openrewrite/csharp/service/CSharpNamingService.java @@ -0,0 +1,58 @@ +/* + * Copyright 2023 the original author or authors. + *
+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *
+ * https://www.apache.org/licenses/LICENSE-2.0 + *
+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.csharp.service; + +import org.openrewrite.internal.NameCaseConvention; +import org.openrewrite.internal.NamingService; + +import java.util.regex.Pattern; + +public class CSharpNamingService implements NamingService { + + private static final Pattern SNAKE_CASE = Pattern.compile("^[a-zA-Z0-9]+_\\w+$"); + + @Override + public String getMethodName(String oldMethodName) { + StringBuilder result = new StringBuilder(); + if (SNAKE_CASE.matcher(oldMethodName).matches()) { + result.append(NameCaseConvention.format(NameCaseConvention.UPPER_CAMEL, oldMethodName)); + } else { + int nameLength = oldMethodName.length(); + for (int i = 0; i < nameLength; i++) { + char c = oldMethodName.charAt(i); + + if (i == 0) { + // the java specification requires identifiers to start with [a-zA-Z$_] + if (c != '$' && c != '_') { + result.append(Character.toUpperCase(c)); + } + } else { + if (!Character.isLetterOrDigit(c)) { + while (i < nameLength && (!Character.isLetterOrDigit(c) || c > 'z')) { + c = oldMethodName.charAt(i++); + } + if (i < nameLength) { + result.append(Character.toUpperCase(c)); + } + } else { + result.append(c); + } + } + } + } + return result.toString(); + } +} diff --git a/rewrite-csharp/src/main/java/org/openrewrite/csharp/service/package-info.java b/rewrite-csharp/src/main/java/org/openrewrite/csharp/service/package-info.java new file mode 100644 index 0000000..6c389d6 --- /dev/null +++ b/rewrite-csharp/src/main/java/org/openrewrite/csharp/service/package-info.java @@ -0,0 +1,21 @@ +/* + * Copyright 2023 the original author or authors. + *
+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *
+ * https://www.apache.org/licenses/LICENSE-2.0 + *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+@NullMarked
+@NonNullFields
+package org.openrewrite.csharp.service;
+
+import org.jspecify.annotations.NullMarked;
+import org.openrewrite.internal.lang.NonNullFields;
diff --git a/rewrite-csharp/src/main/java/org/openrewrite/csharp/tree/Cs.java b/rewrite-csharp/src/main/java/org/openrewrite/csharp/tree/Cs.java
index f287aef..f093797 100644
--- a/rewrite-csharp/src/main/java/org/openrewrite/csharp/tree/Cs.java
+++ b/rewrite-csharp/src/main/java/org/openrewrite/csharp/tree/Cs.java
@@ -22,9 +22,10 @@
import org.openrewrite.*;
import org.openrewrite.csharp.CSharpPrinter;
import org.openrewrite.csharp.CSharpVisitor;
+import org.openrewrite.csharp.service.CSharpNamingService;
+import org.openrewrite.internal.NamingService;
import org.openrewrite.java.JavaPrinter;
import org.openrewrite.java.JavaTypeVisitor;
-import org.openrewrite.java.JavaVisitor;
import org.openrewrite.java.internal.TypesInUse;
import org.openrewrite.java.tree.*;
import org.openrewrite.marker.Markers;
@@ -74,7 +75,7 @@ final class CompilationUnit implements Cs, JavaSourceFile {
@Nullable
@NonFinal
- transient WeakReference J acceptCSharp(CSharpVisitor v, P p) {
return v.visitInterpolation(this, p);
}
- public Padding getPadding() {
+ public Padding getPadding() {
Padding p;
if (this.padding == null) {
p = new Padding(this);
@@ -1798,7 +1810,7 @@ public PropertyDeclaration withType(@Nullable JavaType type) {
}
public @Nullable NameTree getInterfaceSpecifier() {
- return interfaceSpecifier!= null ? interfaceSpecifier.getElement() : null;
+ return interfaceSpecifier != null ? interfaceSpecifier.getElement() : null;
}
public PropertyDeclaration withInterfaceSpecifier(@Nullable NameTree interfaceSpecifier) {
@@ -1890,8 +1902,7 @@ public PropertyDeclaration withInitializer(@Nullable JLeftPadded J acceptCSharp(CSharpVisitor v, P p) {
* // use result
* }
*
- *
+ *
* Example 2: Deconstruction declaration:
*
* Example in out variable:
*
* Example in deconstruction:
* J acceptCSharp(CSharpVisitor v, P p) {
@Override
public SingleVariableDesignation withType(@Nullable JavaType type) {
- return this.getType() == type ? this : new Cs.SingleVariableDesignation(
+ return this.getType() == type ? this : new Cs.SingleVariableDesignation(
id,
prefix,
markers,
@@ -2733,12 +2743,12 @@ public CoordinateBuilder.Expression getCoordinates() {
/**
* Represents a parenthesized list of variable declarations used in deconstruction patterns.
* Can contain both single variables and nested deconstruction patterns.
- *
+ *
* Example of simple deconstruction:
*
* Example of nested deconstruction:
*
* Examples:
* ```csharp
* // Tuple construction
* var point = (1, 2);
- *
+ *
* // Named tuple elements
* var person = (name: "John", age: 25);
- *
+ *
* // Nested tuples
* var nested = (1, (2, 3));
- *
+ *
* // Tuple type with multiple elements
* (string name, int age) person = ("John", 25);
* ```
@@ -3145,15 +3155,15 @@ public Cs.Unary withOperator(JLeftPadded
* Examples:
* ```csharp
* class Person {
- * // Constructor with 'this' initializer
- * public Person(string name) : this(name, 0) { }
- *
- * // Constructor with 'base' initializer
- * public Person(string name, int age) : base(name) { }
+ * // Constructor with 'this' initializer
+ * public Person(string name) : this(name, 0) { }
+ *
+ * // Constructor with 'base' initializer
+ * public Person(string name, int age) : base(name) { }
* }
* ```
*/
T service(Class service) {
+ if (NamingService.class.getName().equals(service.getName())) {
+ return (T) new CSharpNamingService();
+ }
+ return JavaSourceFile.super.service(service);
+ }
+
@RequiredArgsConstructor
- public static class Padding implements JavaSourceFile.Padding {
+ public static class Padding implements JavaSourceFile.Padding {
private final Cs.CompilationUnit t;
@Override
@@ -337,7 +347,9 @@ final class Argument implements Cs, Expression {
@With
Keyword refKindKeyword;
- public J.@Nullable Identifier getNameColumn() { return nameColumn == null ? null : nameColumn.getElement(); }
+ public J.@Nullable Identifier getNameColumn() {
+ return nameColumn == null ? null : nameColumn.getElement();
+ }
public Argument withNameColumn(J.@Nullable Identifier nameColumn) {
return getPadding().withNameColumn(JRightPadded.withElement(this.nameColumn, nameColumn));
@@ -1434,7 +1446,7 @@ public
* (int x, string y) = point;
@@ -2663,6 +2672,7 @@ public CoordinateBuilder.Expression getCoordinates() {
/**
* Interface for variable designators in declaration expressions.
* This can be either a single variable name or a parenthesized list of designators for deconstruction.
+ *
* @see SingleVariableDesignation
* @see ParenthesizedVariableDesignation
*/
@@ -2672,12 +2682,12 @@ interface VariableDesignation extends Expression, Cs {
/**
* Represents a single variable declaration within a declaration expression.
* Used both for simple out variable declarations and as elements within deconstruction declarations.
- *
+ *
* int.TryParse(s, out int x) // 'int x' is the SingleVariable
*
- *
+ *
* (int x, string y) = point; // both 'int x' and 'string y' are SingleVariables
@@ -2716,7 +2726,7 @@ public
* (int x, string y) = point;
*
- *
+ *
* (int count, (string name, int age)) = GetPersonDetails();
@@ -2880,18 +2890,18 @@ public CoordinateBuilder.Expression getCoordinates() {
/**
* Represents a tuple expression in C#.
* Can be used in tuple construction, deconstruction and tuple literals.
- *
+ *