fcl-js: omit brackets on associative operations (a||b)||(c||d), (a&&b)&&(c&&d), (a|b)|c, (a&b)&c, (a^b)^c, (a+b)+c, (a-b)-c, (a*b)*c

git-svn-id: trunk@40707 -
This commit is contained in:
Mattias Gaertner 2018-12-30 09:39:46 +00:00
parent bd4b7a6bc4
commit b1752fb4ce
2 changed files with 71 additions and 3 deletions

View File

@ -1255,6 +1255,7 @@ procedure TJSWriter.WriteBinary(El: TJSBinary);
Var Var
S : String; S : String;
AllowCompact, WithBrackets: Boolean; AllowCompact, WithBrackets: Boolean;
ElC: TClass;
begin begin
{$IFDEF VerboseJSWriter} {$IFDEF VerboseJSWriter}
System.writeln('TJSWriter.WriteBinary SkipRoundBrackets=',FSkipRoundBrackets); System.writeln('TJSWriter.WriteBinary SkipRoundBrackets=',FSkipRoundBrackets);
@ -1263,6 +1264,18 @@ begin
if WithBrackets then if WithBrackets then
Write('('); Write('(');
FSkipRoundBrackets:=false; FSkipRoundBrackets:=false;
ElC:=El.ClassType;
if El.A is TJSBinaryExpression then
if (El.A.ClassType=ElC)
and ((ElC=TJSLogicalOrExpression)
or (ElC=TJSLogicalAndExpression)
or (ElC=TJSBitwiseAndExpression)
or (ElC=TJSBitwiseOrExpression)
or (ElC=TJSBitwiseXOrExpression)
or (ElC=TJSAdditiveExpressionPlus)
or (ElC=TJSAdditiveExpressionMinus)
or (ElC=TJSMultiplicativeExpressionMul)) then
FSkipRoundBrackets:=true;
WriteJS(El.A); WriteJS(El.A);
Writer.CurElement:=El; Writer.CurElement:=El;
AllowCompact:=False; AllowCompact:=False;
@ -1279,6 +1292,13 @@ begin
S:=' '+S+' '; S:=' '+S+' ';
end; end;
FSkipRoundBrackets:=false; FSkipRoundBrackets:=false;
ElC:=El.ClassType;
if El.B is TJSBinaryExpression then
if (El.B.ClassType=ElC)
and ((ElC=TJSLogicalOrExpression)
or (ElC=TJSLogicalAndExpression)) then
FSkipRoundBrackets:=true;
// Note: a+(b+c) <> a+b+c e.g. floats, 0+string
Write(S); Write(S);
WriteJS(El.B); WriteJS(El.B);
Writer.CurElement:=El; Writer.CurElement:=El;

View File

@ -180,10 +180,11 @@ type
{ TTestExpressionWriter } { TTestExpressionWriter }
TTestExpressionWriter= class(TTestJSWriter) TTestExpressionWriter = class(TTestJSWriter)
Protected Protected
Procedure TestUnary(Const Msg : String; AClass : TJSUnaryClass; Result : String); Procedure TestUnary(Const Msg : String; AClass : TJSUnaryClass; Result : String);
Procedure TestBinary(Const Msg : String; AClass : TJSBinaryClass; Result : String;ACompact : Boolean); Procedure TestBinary(Const Msg : String; AClass : TJSBinaryClass; Result : String; ACompact : Boolean);
Procedure TestBinaryNested(Const Msg : String; AClass : TJSBinaryClass; Result : String; ACompact : Boolean);
Published Published
Procedure TestIdent; Procedure TestIdent;
Procedure TestThis; Procedure TestThis;
@ -201,8 +202,10 @@ type
Procedure TestPostMinusMinus; Procedure TestPostMinusMinus;
Procedure TestBinaryLogicalOr; Procedure TestBinaryLogicalOr;
Procedure TestBinaryLogicalOrCompact; Procedure TestBinaryLogicalOrCompact;
Procedure TestBinaryLogicalOrNested;
Procedure TestBinaryLogicalAnd; Procedure TestBinaryLogicalAnd;
Procedure TestBinaryLogicalAndCompact; Procedure TestBinaryLogicalAndCompact;
Procedure TestBinaryLogicalAndNested;
Procedure TestBinaryBitwiseOr; Procedure TestBinaryBitwiseOr;
Procedure TestBinaryBitwiseOrCompact; Procedure TestBinaryBitwiseOrCompact;
Procedure TestBinaryBitwiseAnd; Procedure TestBinaryBitwiseAnd;
@ -237,10 +240,13 @@ type
Procedure TestBinaryURShiftOfCompact; Procedure TestBinaryURShiftOfCompact;
Procedure TestBinaryPlus; Procedure TestBinaryPlus;
Procedure TestBinaryPlusCompact; Procedure TestBinaryPlusCompact;
Procedure TestBinaryPlusNested;
Procedure TestBinaryMinus; Procedure TestBinaryMinus;
Procedure TestBinaryMinusCompact; Procedure TestBinaryMinusCompact;
Procedure TestBinaryMinusNested;
Procedure TestBinaryMultiply; Procedure TestBinaryMultiply;
Procedure TestBinaryMultiplyCompact; Procedure TestBinaryMultiplyCompact;
Procedure TestBinaryMultiplyNested;
Procedure TestBinaryDivide; Procedure TestBinaryDivide;
Procedure TestBinaryDivideCompact; Procedure TestBinaryDivideCompact;
Procedure TestBinaryMod; Procedure TestBinaryMod;
@ -291,6 +297,23 @@ begin
AssertWrite(Msg,Result,U); AssertWrite(Msg,Result,U);
end; end;
procedure TTestExpressionWriter.TestBinaryNested(const Msg: String;
AClass: TJSBinaryClass; Result: String; ACompact: Boolean);
var
U: TJSBinary;
begin
if ACompact then
Writer.Options:=Writer.Options+[woCompact];
U:=AClass.Create(0,0);
U.A:=AClass.Create(0,0);
TJSBinary(U.A).A:=CreateIdent('a');
TJSBinary(U.A).B:=CreateIdent('b');
U.B:=AClass.Create(0,0);
TJSBinary(U.B).A:=CreateIdent('c');
TJSBinary(U.B).B:=CreateIdent('d');
AssertWrite(Msg,Result,U);
end;
procedure TTestExpressionWriter.TestIdent; procedure TTestExpressionWriter.TestIdent;
begin begin
@ -373,6 +396,11 @@ begin
TestBinary('logical or',TJSLogicalOrExpression,'(a||b)',True); TestBinary('logical or',TJSLogicalOrExpression,'(a||b)',True);
end; end;
procedure TTestExpressionWriter.TestBinaryLogicalOrNested;
begin
TestBinaryNested('logical or',TJSLogicalOrExpression,'(a||b||c||d)',True);
end;
procedure TTestExpressionWriter.TestBinaryLogicalAnd; procedure TTestExpressionWriter.TestBinaryLogicalAnd;
begin begin
TestBinary('logical or',TJSLogicalAndExpression,'(a && b)',False); TestBinary('logical or',TJSLogicalAndExpression,'(a && b)',False);
@ -383,6 +411,11 @@ begin
TestBinary('logical or',TJSLogicalAndExpression,'(a&&b)',True); TestBinary('logical or',TJSLogicalAndExpression,'(a&&b)',True);
end; end;
procedure TTestExpressionWriter.TestBinaryLogicalAndNested;
begin
TestBinaryNested('logical and',TJSLogicalAndExpression,'(a&&b&&c&&d)',True);
end;
procedure TTestExpressionWriter.TestBinaryBitwiseOr; procedure TTestExpressionWriter.TestBinaryBitwiseOr;
begin begin
TestBinary('Bitwise or',TJSBitwiseOrExpression,'(a | b)',False); TestBinary('Bitwise or',TJSBitwiseOrExpression,'(a | b)',False);
@ -553,6 +586,11 @@ begin
TestBinary('A plus B',TJSAdditiveExpressionPlus,'(a+b)',True); TestBinary('A plus B',TJSAdditiveExpressionPlus,'(a+b)',True);
end; end;
procedure TTestExpressionWriter.TestBinaryPlusNested;
begin
TestBinaryNested('(A+B)+(C+D)',TJSAdditiveExpressionPlus,'(a+b+(c+d))',True);
end;
procedure TTestExpressionWriter.TestBinaryMinus; procedure TTestExpressionWriter.TestBinaryMinus;
begin begin
TestBinary('A minus B',TJSAdditiveExpressionMinus,'(a - b)',False); TestBinary('A minus B',TJSAdditiveExpressionMinus,'(a - b)',False);
@ -563,6 +601,11 @@ begin
TestBinary('A minus B',TJSAdditiveExpressionMinus,'(a-b)',True); TestBinary('A minus B',TJSAdditiveExpressionMinus,'(a-b)',True);
end; end;
procedure TTestExpressionWriter.TestBinaryMinusNested;
begin
TestBinaryNested('(A-B)-(C-D)',TJSAdditiveExpressionMinus,'(a-b-(c-d))',True);
end;
procedure TTestExpressionWriter.TestBinaryMultiply; procedure TTestExpressionWriter.TestBinaryMultiply;
begin begin
TestBinary('A multiply B',TJSMultiplicativeExpressionMul,'(a * b)',False); TestBinary('A multiply B',TJSMultiplicativeExpressionMul,'(a * b)',False);
@ -573,6 +616,11 @@ begin
TestBinary('A multiply B',TJSMultiplicativeExpressionMul,'(a*b)',True); TestBinary('A multiply B',TJSMultiplicativeExpressionMul,'(a*b)',True);
end; end;
procedure TTestExpressionWriter.TestBinaryMultiplyNested;
begin
TestBinaryNested('(A*B)*(C*D)',TJSMultiplicativeExpressionMul,'(a*b*(c*d))',True);
end;
procedure TTestExpressionWriter.TestBinaryDivide; procedure TTestExpressionWriter.TestBinaryDivide;
begin begin
TestBinary('A divide B',TJSMultiplicativeExpressionDiv,'(a / b)',False); TestBinary('A divide B',TJSMultiplicativeExpressionDiv,'(a / b)',False);
@ -2594,7 +2642,7 @@ Var
S : AnsiString; S : AnsiString;
p: Integer; p: Integer;
begin begin
S:=FTextWriter.AsAnsistring; S:=FTextWriter.AsString;
if S=Result then exit; if S=Result then exit;
p:=1; p:=1;
while (p<=length(S)) and (p<=length(Result)) and (S[p]=Result[p]) do inc(p); while (p<=length(S)) and (p<=length(Result)) and (S[p]=Result[p]) do inc(p);