Skip to content

Commit

Permalink
🐞 fix: Fix toString() for ast number
Browse files Browse the repository at this point in the history
  • Loading branch information
caoccao committed May 17, 2024
1 parent e27b2a3 commit c6a43de
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@
public class Swc4jAstNumber
extends Swc4jAst
implements ISwc4jAstLit, ISwc4jAstPropName, ISwc4jAstTsLit, ISwc4jAstCoercionPrimitive {
protected static final Pattern PATTERN_ALL_ZEROS =
Pattern.compile("^0+$", Pattern.CASE_INSENSITIVE);
protected static final Pattern PATTERN_DECIMAL_ZEROS =
Pattern.compile("^(\\d+)\\.0*$", Pattern.CASE_INSENSITIVE);
protected static final Pattern PATTERN_SCIENTIFIC_NOTATION =
protected static final Pattern PATTERN_SCIENTIFIC_NOTATION_WITHOUT_FRACTION =
Pattern.compile("^(\\d+)e([\\+\\-]?)(\\d+)$", Pattern.CASE_INSENSITIVE);
protected static final Pattern PATTERN_SCIENTIFIC_NOTATION_WITH_FRACTION =
Pattern.compile("^(\\d+)\\.(\\d*)e([\\+\\-]?)(\\d+)$", Pattern.CASE_INSENSITIVE);
@Jni2RustField(componentAtom = true)
protected Optional<String> raw;
Expand All @@ -59,24 +59,57 @@ public static Swc4jAstNumber create(int value) {
}

public static Swc4jAstNumber create(double value) {
return new Swc4jAstNumber(value, getNormalizedNumberString(Double.toString(value)), Swc4jSpan.DUMMY);
return new Swc4jAstNumber(value, null, Swc4jSpan.DUMMY);
}

public static Swc4jAstNumber create(double value, String raw) {
return new Swc4jAstNumber(value, raw, Swc4jSpan.DUMMY);
}

protected static String getNormalizedNumberString(String raw) {
Matcher matcher = PATTERN_SCIENTIFIC_NOTATION.matcher(raw);
public static String getNormalizedNumberString(String raw) {
Matcher matcher = PATTERN_SCIENTIFIC_NOTATION_WITH_FRACTION.matcher(raw);
if (matcher.matches()) {
String sign = StringUtils.isEmpty(matcher.group(3)) ? "+" : matcher.group(3);
if (StringUtils.isEmpty(matcher.group(2))) {
return matcher.group(1) + "e" + sign + matcher.group(4);
} else if (PATTERN_ALL_ZEROS.matcher(matcher.group(2)).matches()) {
return matcher.group(1) + "e" + sign + matcher.group(4);
} else {
return matcher.group(1) + "." + matcher.group(2) + "e" + sign + matcher.group(4);
String integer = matcher.group(1);
String fraction = matcher.group(2);
int additionalExponent = 0;
while (fraction.endsWith("0")) {
fraction = fraction.substring(0, fraction.length() - 1);
}
while (integer.startsWith("0")) {
integer = integer.substring(1);
}
if (integer.length() > 1) {
additionalExponent += integer.length() - 1;
fraction = integer.substring(1) + fraction;
integer = integer.substring(0, 1);
}
if (StringUtils.isNotEmpty(fraction)) {
fraction = "." + fraction;
}
long exponent = Long.parseLong(matcher.group(4)) + additionalExponent;
return integer + fraction + "e" + sign + exponent;
}
matcher = PATTERN_SCIENTIFIC_NOTATION_WITHOUT_FRACTION.matcher(raw);
if (matcher.matches()) {
String sign = StringUtils.isEmpty(matcher.group(2)) ? "+" : matcher.group(2);
String integer = matcher.group(1);
String fraction = "";
int additionalExponent = 0;
while (integer.startsWith("0")) {
integer = integer.substring(1);
}
while (integer.endsWith("0")) {
++additionalExponent;
integer = integer.substring(0, integer.length() - 1);
}
if (integer.length() > 1) {
additionalExponent += integer.length() - 1;
fraction = "." + integer.substring(1);
integer = integer.substring(0, 1);
}
long exponent = Long.parseLong(matcher.group(3)) + additionalExponent;
return integer + fraction + "e" + sign + exponent;
}
matcher = PATTERN_DECIMAL_ZEROS.matcher(raw);
if (matcher.matches()) {
Expand Down Expand Up @@ -122,7 +155,7 @@ public short asShort() {

@Override
public String asString() {
return getNormalizedNumberString(Double.toString(value));
return toString();
}

@Override
Expand Down Expand Up @@ -162,7 +195,7 @@ public Swc4jAstNumber setValue(double value) {

@Override
public String toString() {
return raw.orElse(Double.toString(value));
return getNormalizedNumberString(raw.orElse(Double.toString(value)));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,17 +135,17 @@ public Swc4jAstVisitorResponse visitUnaryExpr(Swc4jAstUnaryExpr node) {
break;
case Number: {
Swc4jAstNumber number = arg.as(Swc4jAstNumber.class);
newNode = Swc4jAstNumber.create(number.getValue());
newNode = Swc4jAstNumber.create(number.getValue(), number.getRaw().orElse(null));
}
break;
case Str: {
Swc4jAstStr str = arg.as(Swc4jAstStr.class);
double value;
try {
double value = Double.parseDouble(str.getValue());
newNode = Swc4jAstNumber.create(value);
value = Double.parseDouble(arg.as(Swc4jAstStr.class).getValue());
} catch (Throwable t) {
newNode = Swc4jAstNumber.create(Double.NaN);
value = Double.NaN;
}
newNode = Swc4jAstNumber.create(value);
}
break;
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,14 @@ public class TestSwc4jAstNumber extends BaseTestSuiteSwc4jAst {
public void testCoercion() {
assertEquals("0", Swc4jAstNumber.create(0).getRaw().get());
assertEquals("1", Swc4jAstNumber.create(1).getRaw().get());
assertEquals("1.1", Swc4jAstNumber.create(1.1D).getRaw().get());
assertEquals("1.1", Swc4jAstNumber.create(1.1D).toString());
assertEquals("1.1e+20", Swc4jAstNumber.create(1.1e20D).toString());
assertEquals("1.23e+21", Swc4jAstNumber.create(12.30e20D).toString());
assertEquals("1.234e+21", Swc4jAstNumber.create(12.340e20D, "12.340e20").toString());
assertEquals("1.234e+21", Swc4jAstNumber.create(12.340e20D, "012.34000e20").toString());
assertEquals("1.1e-20", Swc4jAstNumber.create(1.1e-20D).toString());
assertEquals(1, Swc4jAstNumber.create(1.1D).asInt());
assertEquals("NaN", Swc4jAstNumber.create(Double.NaN).getRaw().get());
assertEquals("NaN", Swc4jAstNumber.create(Double.NaN).toString());
assertEquals(0, Swc4jAstNumber.create(Double.NaN).asInt());
}

Expand Down

0 comments on commit c6a43de

Please sign in to comment.