Skip to content

Commit

Permalink
#1454 fixing ad-hoc parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
elucash committed May 22, 2023
1 parent 617e17f commit 6b4fc11
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 3 deletions.
62 changes: 59 additions & 3 deletions generator/src/org/immutables/generator/SourceTypes.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,30 @@ public static Entry<String, List<String>> extract(CharSequence typeString) {
StringBuilder typeArgument = new StringBuilder();
List<String> typeArguments = Lists.newArrayList();
int anglesOpened = 0;
int parensOpened = 0;
chars: for (int i = 0; i < typeString.length(); i++) {
char c = typeString.charAt(i);
switch (c) {
case '"':
case '\'':
i = transferStringLiteral(anglesOpened == 0 ? typeName : typeArgument, typeString, c, i + 1) - 1;
break;
case '(':
parensOpened++;
if (anglesOpened == 0) {
typeName.append(c);
} else {
typeArgument.append(c);
}
break;
case ')':
parensOpened--;
if (anglesOpened == 0) {
typeName.append(c);
} else {
typeArgument.append(c);
}
break;
case '<':
if (++anglesOpened > 1) {
typeArgument.append(c);
Expand All @@ -45,15 +66,31 @@ public static Entry<String, List<String>> extract(CharSequence typeString) {
}
break;
case ',':
if (anglesOpened == 1) {
if (parensOpened > 0) {
if (anglesOpened == 0) {
typeName.append(c);
} else {
typeArgument.append(c);
}
} else if (anglesOpened == 1) {
typeArguments.add(typeArgument.toString());
typeArgument = new StringBuilder();
} else {
typeArgument.append(c);
}
break;
case ' ':// not sure about this one
if (anglesOpened > 1) {
case ' ':
if (anglesOpened == 0) {
typeName.append(c);
} else if (anglesOpened == 1) {
if (parensOpened > 0) {
typeArgument.append(c);
} else {
if (typeArgument.length() > 0 && typeArgument.charAt(typeArgument.length() - 1) == ')') {
typeArgument.append(c);
}
}
} else {
typeArgument.append(c);
}
break;
Expand All @@ -72,6 +109,25 @@ public static Entry<String, List<String>> extract(CharSequence typeString) {
return Maps.immutableEntry(typeName.toString(), typeArguments);
}

private static int transferStringLiteral(StringBuilder target, CharSequence typeString, char end, int i) {
target.append(end);
for (; i < typeString.length(); i++) {
char c = typeString.charAt(i);
if (c == '\\') { // for each escape, we expected that next symbol will always exist and
target.append(c);
c = typeString.charAt(++i);
target.append(c);
} else if (c == end) {
target.append(c);
i++;
break;
} else {
target.append(c);
}
}
return i;
}

public static String stringify(Entry<String, ? extends List<String>> types) {
if (types.getValue().isEmpty()) {
return types.getKey();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.immutables.fixture;

import java.util.Map;
import javax.validation.constraints.Size;
import org.immutables.value.Value;

@Value.Immutable
public interface HasTypeAnnotationWithAttributes {
Map<@Size(min = 1, max = 99) String, Integer> map();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.immutables.fixture.generics;

import java.util.Map;
import javax.validation.constraints.Size;
import org.immutables.value.Value;

@Value.Immutable
public interface HasTypeAnnotationWithAttributes {
Map<@Size(min = 1, max = 99) String, Integer> map();
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@
*/
package org.immutables.value.processor.encode;

import java.util.List;
import java.util.Map;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import org.immutables.generator.SourceTypes;
import org.immutables.value.processor.encode.Type.Defined;
import org.immutables.value.processor.encode.Type.Primitive;
import org.immutables.value.processor.encode.Type.Reference;
Expand All @@ -36,6 +39,30 @@ public class TypeTest {

Type.Parser parser = new Type.Parser(factory, parameters);

@Test
public void sourceTypeAdHocParsing() {
Map.Entry<String, List<String>> extract =
SourceTypes.extract("Map<java.lang.@org.it.Size(a=1, b=2) String, Integer>");
check(extract.getKey()).is("Map");
check(extract.getValue()).isOf("java.lang.@org.it.Size(a=1, b=2) String", "Integer");

Map.Entry<String, List<String>> extract2 =
SourceTypes.extract("List<@org.it.Size(a=1, b=2) java.lang.String>");

check(extract2.getKey()).is("List");
check(extract2.getValue()).isOf("@org.it.Size(a=1, b=2) java.lang.String");

Map.Entry<String, List<String>> extract3 =
SourceTypes.extract("Map<List<java.lang.@Max(a=1, b=2) Integer>, String>");

check(extract3.getValue()).isOf("List<java.lang.@Max(a=1, b=2) Integer>", "String");

Map.Entry<String, List<String>> extract4 =
SourceTypes.extract("List<@Size(a='\\'', c=\"abc, z='\") String>");
check(extract4.getKey()).is("List");
check(extract4.getValue()).isOf("@Size(a='\\'', c=\"abc, z='\") String");
}

@Test
public void templateMatch() {
Type template = parser.parse("java.lang.Iterable<A>");
Expand Down

0 comments on commit 6b4fc11

Please sign in to comment.