mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Parse element indexes and attribute names in new style substitution chunk name fields Add tests
This commit is contained in:
@@ -180,11 +180,9 @@ public class PyStringFormatParser {
|
||||
}
|
||||
}
|
||||
public static class NewStyleSubstitutionChunk extends SubstitutionChunk {
|
||||
@Nullable private String myMappingKey;
|
||||
@Nullable private String myConversion;
|
||||
@Nullable private String myWidth;
|
||||
@Nullable private String myPrecision;
|
||||
@Nullable private Integer myPosition;
|
||||
@Nullable private String myFieldNameAttribute;
|
||||
@Nullable private String myMappingKeyElementIndex;
|
||||
private char myConversionType;
|
||||
private boolean signOption;
|
||||
private boolean zeroPadding;
|
||||
@@ -195,15 +193,6 @@ public class PyStringFormatParser {
|
||||
super(startIndex, startIndex);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getMappingKey() {
|
||||
return myMappingKey;
|
||||
}
|
||||
|
||||
public void setMappingKey(@Nullable String mappingKey) {
|
||||
myMappingKey = mappingKey;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getConversion() {
|
||||
return myConversion;
|
||||
@@ -213,24 +202,6 @@ public class PyStringFormatParser {
|
||||
myConversion = conversion;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getWidth() {
|
||||
return myWidth;
|
||||
}
|
||||
|
||||
public void setWidth(@Nullable String width) {
|
||||
myWidth = width;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getPrecision() {
|
||||
return myPrecision;
|
||||
}
|
||||
|
||||
public void setPrecision(@Nullable String precision) {
|
||||
myPrecision = precision;
|
||||
}
|
||||
|
||||
public boolean hasSignOption() {
|
||||
return signOption;
|
||||
}
|
||||
@@ -270,6 +241,24 @@ public class PyStringFormatParser {
|
||||
public void setThousandsSeparator(boolean thousandsSeparator) {
|
||||
this.thousandsSeparator = thousandsSeparator;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getFieldNameAttribute() {
|
||||
return myFieldNameAttribute;
|
||||
}
|
||||
|
||||
public void setFieldNameAttribute(@NotNull String fieldNameAttribute) {
|
||||
myFieldNameAttribute = fieldNameAttribute;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getMappingKeyElementIndex() {
|
||||
return myMappingKeyElementIndex;
|
||||
}
|
||||
|
||||
public void setMappingKeyElementIndex(@Nullable String mappingKeyElementIndex) {
|
||||
myMappingKeyElementIndex = mappingKeyElementIndex;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull private final String myLiteral;
|
||||
@@ -371,6 +360,48 @@ public class PyStringFormatParser {
|
||||
autoPositionedFieldsCount++;
|
||||
}
|
||||
|
||||
// parse field name attribute name
|
||||
if (isAt('.') ) {
|
||||
myPos++;
|
||||
|
||||
final int attributeEnd = StringUtil.indexOfAny(myLiteral, "!:.[}", myPos, end);
|
||||
if (attributeEnd > 0 && myPos < attributeEnd) {
|
||||
final String attributeName = myLiteral.substring(myPos, attributeEnd);
|
||||
chunk.setFieldNameAttribute(attributeName);
|
||||
myPos = attributeEnd;
|
||||
}
|
||||
}
|
||||
|
||||
// parse field name element indexes
|
||||
if (isAt('[')) {
|
||||
myPos++;
|
||||
|
||||
final int indexElementEnd = StringUtil.indexOfAny(myLiteral, "!:.]", myPos, end);
|
||||
if (indexElementEnd > 0 && myPos < indexElementEnd) {
|
||||
final String index = myLiteral.substring(myPos, indexElementEnd);
|
||||
chunk.setMappingKeyElementIndex(index);
|
||||
myPos = indexElementEnd + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// skip other attribute names and element indexes
|
||||
while (isAt('.') || isAt('[')) {
|
||||
if (isAt('.')) {
|
||||
myPos++;
|
||||
final int attributeEnd = StringUtil.indexOfAny(myLiteral, "!:.[", myPos, end);
|
||||
if (attributeEnd > 0 && myPos < attributeEnd) {
|
||||
myPos = attributeEnd;
|
||||
}
|
||||
}
|
||||
else {
|
||||
myPos++;
|
||||
final int attributeEnd = StringUtil.indexOf(myLiteral, ']', myPos, end);
|
||||
if (attributeEnd > 0 && myPos < attributeEnd) {
|
||||
myPos = attributeEnd + 1;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// conversion
|
||||
myPos = Math.max(myPos, StringUtil.indexOf(myLiteral, '!', myPos, end) + 1);
|
||||
final int conversionEnd = StringUtil.indexOfAny(myLiteral, ":}", myPos, end);
|
||||
@@ -436,12 +467,12 @@ public class PyStringFormatParser {
|
||||
int mappingEnd = myLiteral.indexOf(')', myPos+1);
|
||||
if (mappingEnd < 0) {
|
||||
chunk.setEndIndex(myLiteral.length());
|
||||
chunk.setMappingKey(myLiteral.substring(myPos+1));
|
||||
chunk.setMappingKey(myLiteral.substring(myPos + 1));
|
||||
chunk.setUnclosedMapping(true);
|
||||
myPos = myLiteral.length();
|
||||
return;
|
||||
}
|
||||
chunk.setMappingKey(myLiteral.substring(myPos+1, mappingEnd));
|
||||
chunk.setMappingKey(myLiteral.substring(myPos + 1, mappingEnd));
|
||||
myPos = mappingEnd+1;
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -499,4 +499,57 @@ public class PyStringFormatParserTest extends TestCase {
|
||||
assertEquals("2", ((NewStyleSubstitutionChunk)chunks.get(0)).getPrecision());
|
||||
assertEquals('d', ((NewStyleSubstitutionChunk)chunks.get(0)).getConversionType());
|
||||
}
|
||||
|
||||
public void testNewStyleFiledNameWithAttribute() {
|
||||
final List<FormatStringChunk> chunks = parseNewStyleFormat("{foo.a}");
|
||||
assertEquals(1, chunks.size());
|
||||
final NewStyleSubstitutionChunk chunk = (NewStyleSubstitutionChunk)chunks.get(0);
|
||||
assertEquals(TextRange.create(0, 7), chunk.getTextRange());
|
||||
assertEquals("foo", chunk.getMappingKey());
|
||||
assertNotNull(chunk.getFieldNameAttribute());
|
||||
assertEquals("a", chunk.getFieldNameAttribute());
|
||||
}
|
||||
|
||||
public void testNewStyleFiledNameWithElementIndex() {
|
||||
final List<FormatStringChunk> chunks = parseNewStyleFormat("{foo[a]}");
|
||||
assertEquals(1, chunks.size());
|
||||
final NewStyleSubstitutionChunk chunk = (NewStyleSubstitutionChunk)chunks.get(0);
|
||||
assertEquals(TextRange.create(0, 8), chunk.getTextRange());
|
||||
assertEquals("foo", chunk.getMappingKey());
|
||||
assertNotNull(chunk.getMappingKeyElementIndex());
|
||||
assertEquals("a", chunk.getMappingKeyElementIndex());
|
||||
}
|
||||
|
||||
public void testNewStyleFiledNameWithAttributeWithFormatSpec() {
|
||||
final List<FormatStringChunk> chunks = parseNewStyleFormat("{foo.a:d}");
|
||||
assertEquals(1, chunks.size());
|
||||
final NewStyleSubstitutionChunk chunk = (NewStyleSubstitutionChunk)chunks.get(0);
|
||||
assertEquals(TextRange.create(0, 9), chunk.getTextRange());
|
||||
assertEquals("foo", chunk.getMappingKey());
|
||||
assertNotNull(chunk.getFieldNameAttribute());
|
||||
assertEquals("a", chunk.getFieldNameAttribute());
|
||||
assertEquals('d', chunk.getConversionType());
|
||||
}
|
||||
|
||||
public void testNewStyleFiledNameWithElementIndexWithFormatSpec() {
|
||||
final List<FormatStringChunk> chunks = parseNewStyleFormat("{foo[a]:d}");
|
||||
assertEquals(1, chunks.size());
|
||||
final NewStyleSubstitutionChunk chunk = (NewStyleSubstitutionChunk)chunks.get(0);
|
||||
assertEquals(TextRange.create(0, 10), chunk.getTextRange());
|
||||
assertEquals("foo", chunk.getMappingKey());
|
||||
assertNotNull(chunk.getMappingKeyElementIndex());
|
||||
assertEquals("a", chunk.getMappingKeyElementIndex());
|
||||
assertEquals('d', chunk.getConversionType());
|
||||
}
|
||||
|
||||
public void testNewStyleFieldNameWithNestedElementIndex() {
|
||||
final List<FormatStringChunk> chunks = parseNewStyleFormat("{foo[a][1].a[1]:d}");
|
||||
assertEquals(1, chunks.size());
|
||||
final NewStyleSubstitutionChunk chunk = (NewStyleSubstitutionChunk)chunks.get(0);
|
||||
assertEquals(TextRange.create(0, 18), chunk.getTextRange());
|
||||
assertEquals("foo", chunk.getMappingKey());
|
||||
assertNotNull(chunk.getMappingKeyElementIndex());
|
||||
assertEquals("a", chunk.getMappingKeyElementIndex());
|
||||
assertEquals('d', chunk.getConversionType());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user