Skip to content

Commit

Permalink
Add CSharp implementation that is also returned when a NamingService …
Browse files Browse the repository at this point in the history
…is requested from a Cs.CompilationUnit
  • Loading branch information
Laurens-W committed Nov 27, 2024
1 parent 90a65ba commit 1faedcb
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 34 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright 2023 the original author or authors.
* <p>
* 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
* <p>
* https://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright 2023 the original author or authors.
* <p>
* 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
* <p>
* https://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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;
78 changes: 44 additions & 34 deletions rewrite-csharp/src/main/java/org/openrewrite/csharp/tree/Cs.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -74,7 +75,7 @@ final class CompilationUnit implements Cs, JavaSourceFile {

@Nullable
@NonFinal
transient WeakReference<Padding> padding;
transient WeakReference<Padding> padding;

@Getter
@With
Expand Down Expand Up @@ -266,8 +267,17 @@ public Padding getPadding() {
return p;
}

@Override
@Incubating(since = "8.2.0")
public <S, T extends S> T service(Class<S> 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
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -1434,7 +1446,7 @@ public <P> J acceptCSharp(CSharpVisitor<P> v, P p) {
return v.visitInterpolation(this, p);
}

public Padding getPadding() {
public Padding getPadding() {
Padding p;
if (this.padding == null) {
p = new Padding(this);
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -1890,8 +1902,7 @@ public PropertyDeclaration withInitializer(@Nullable JLeftPadded<Expression> ini
}
}

enum KeywordKind
{
enum KeywordKind {
Ref,
Out,
Await,
Expand All @@ -1903,8 +1914,7 @@ enum KeywordKind
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
@RequiredArgsConstructor
final class Keyword implements Cs
{
final class Keyword implements Cs {
@With
@Getter
@EqualsAndHashCode.Include
Expand Down Expand Up @@ -1967,7 +1977,7 @@ public CoordinateBuilder.Statement getCoordinates() {

@Override
public Cs.Lambda withType(@Nullable JavaType type) {
return this.getType() == type ? this : new Cs.Lambda(
return this.getType() == type ? this : new Cs.Lambda(
id,
prefix,
markers,
Expand Down Expand Up @@ -2313,12 +2323,13 @@ public Cs.TypeParameterConstraintClause withTypeParameterConstraints(@Nullable J
}
}

interface TypeParameterConstraint extends J {}
interface TypeParameterConstraint extends J {
}

/**
* Represents a type constraint in a type parameter's constraint clause.
* Example: where T : SomeClass
* where T : IInterface
* where T : IInterface
*/
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@EqualsAndHashCode(callSuper = false, onlyExplicitlyIncluded = true)
Expand Down Expand Up @@ -2396,9 +2407,8 @@ public TypeConstraint withType(TypeTree type) {
/* ------------------ */




interface AllowsConstraint extends J {}
interface AllowsConstraint extends J {
}

/**
* Represents an `allows` constraint in a where clause.
Expand Down Expand Up @@ -2523,8 +2533,7 @@ final class ClassOrStructConstraint implements Cs, TypeParameterConstraint {
@Getter
TypeKind kind;

public enum TypeKind
{
public enum TypeKind {
Class,
Struct
}
Expand Down Expand Up @@ -2602,7 +2611,7 @@ public <P> J acceptCSharp(CSharpVisitor<P> v, P p) {
* // use result
* }
* </pre>
*
* <p>
* Example 2: Deconstruction declaration:
* <pre>
* (int x, string y) = point;
Expand Down Expand Up @@ -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
*/
Expand All @@ -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.
*
* <p>
* Example in out variable:
* <pre>
* int.TryParse(s, out int x) // 'int x' is the SingleVariable
* </pre>
*
* <p>
* Example in deconstruction:
* <pre>
* (int x, string y) = point; // both 'int x' and 'string y' are SingleVariables
Expand Down Expand Up @@ -2716,7 +2726,7 @@ public <P> J acceptCSharp(CSharpVisitor<P> 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,
Expand All @@ -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.
*
* <p>
* Example of simple deconstruction:
* <pre>
* (int x, string y) = point;
* </pre>
*
* <p>
* Example of nested deconstruction:
* <pre>
* (int count, (string name, int age)) = GetPersonDetails();
Expand Down Expand Up @@ -2880,18 +2890,18 @@ public CoordinateBuilder.Expression getCoordinates() {
/**
* Represents a tuple expression in C#.
* Can be used in tuple construction, deconstruction and tuple literals.
*
* <p>
* Examples:
* ```csharp
* // Tuple construction
* var point = (1, 2);
*
* <p>
* // Named tuple elements
* var person = (name: "John", age: 25);
*
* <p>
* // Nested tuples
* var nested = (1, (2, 3));
*
* <p>
* // Tuple type with multiple elements
* (string name, int age) person = ("John", 25);
* ```
Expand Down Expand Up @@ -3145,15 +3155,15 @@ public Cs.Unary withOperator(JLeftPadded<Cs.Unary.Type> operator) {
/**
* Represents a constructor initializer which is a call to another constructor, either in the same class (this)
* or in the base class (base).
*
* <p>
* 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) { }
* <p>
* // Constructor with 'base' initializer
* public Person(string name, int age) : base(name) { }
* }
* ```
*/
Expand Down

0 comments on commit 1faedcb

Please sign in to comment.