Jedi Code Format: Deal with imbalanced bracket comments. Issue #39116, patch by Udo Sommer.

git-svn-id: trunk@65340 -
This commit is contained in:
juha 2021-07-02 08:38:09 +00:00
parent ca3ae84782
commit 8644ddb16b
5 changed files with 156 additions and 27 deletions

View File

@ -112,7 +112,7 @@ implementation
uses
{ local }
JcfStringUtils, JcfSystemUtils,
JcfRegistrySettings;
JcfRegistrySettings, ParseError;
const
CurlyLeft = '{'; //widechar(123);
@ -225,15 +225,30 @@ end;
function TBuildTokenList.TryBracketStarComment(const pcToken: TSourceToken): boolean;
var
liCommentLength: integer;
liCommentLength, lNestedDepth: integer;
bPossiblyImbalanced: Boolean;
procedure MoveToCommentEnd;
var
sCurrentStr: string;
begin
{ comment is ended by *) or by EOF (bad source) }
while True do
begin
if EndOfFileAfter(liCommentLength) then
begin
if bPossiblyImbalanced then
begin
// $ (US): 2021-06-28 15:48:59 $
// Although it is not a parse error, but I do not want to introduce
// another exception class.
raise TEParseError.Create('Unable to recover from imbalanced bracket star comment.', pcToken);
end else
begin
bPossiblyImbalanced := True;
end;
break;
end;
if CheckMultiByte(ForwardChar(liCommentLength)) then
begin
@ -241,8 +256,18 @@ var
continue;
end;
if ForwardChars(liCommentLength, 2) = '*)' then
break;
sCurrentStr := ForwardChars(liCommentLength, 2);
if '(*' = sCurrentStr then
begin
Inc(lNestedDepth);
end else if '*)' = sCurrentStr then
begin
Dec(lNestedDepth);
if (lNestedDepth = 0) or bPossiblyImbalanced then
begin
break;
end;
end;
inc(liCommentLength);
end;
@ -262,10 +287,17 @@ begin
if CurrentChars(2) <> '(*' then
exit;
lNestedDepth := 1;
{ if the comment starts with (*) that is not the end of the comment }
liCommentLength := 2;
MoveToCommentEnd;
if bPossiblyImbalanced then
begin
lNestedDepth := 1;
liCommentLength := 2;
MoveToCommentEnd;
end;
pcToken.TokenType := ttComment;
pcToken.CommentStyle := eBracketStar;
@ -278,6 +310,7 @@ end;
function TBuildTokenList.TryCurlyComment(const pcToken: TSourceToken): boolean;
var
liCommentLength, lNestedDepth: integer;
bPossiblyImbalanced: Boolean;
procedure MoveToCommentEnd;
var
@ -287,7 +320,19 @@ var
while True do
begin
if EndOfFileAfter(liCommentLength) then
begin
if bPossiblyImbalanced then
begin
// $ (US): 2021-06-28 15:48:59 $
// Although it is not a parse error, but I do not want to introduce
// another exception class.
raise TEParseError.Create('Unable to recover from imbalanced curly comment.', pcToken);
end else
begin
bPossiblyImbalanced := True;
end;
break;
end;
lForwardChar:=ForwardChar(liCommentLength);
if CheckMultiByte(lForwardChar) then
begin
@ -299,7 +344,7 @@ var
Inc(lNestedDepth)
else if lForwardChar = CurlyRight then begin
Dec(lNestedDepth);
if (lNestedDepth = 0) then
if (lNestedDepth = 0) or bPossiblyImbalanced then
break;
end;
end;
@ -312,6 +357,8 @@ begin
if Current <> '{' then
exit;
bPossiblyImbalanced := False;
pcToken.TokenType := ttComment;
lNestedDepth := 1;
liCommentLength := 1;
@ -324,6 +371,12 @@ begin
pcToken.CommentStyle := eCurlyBrace;
MoveToCommentEnd;
if bPossiblyImbalanced then
begin
lNestedDepth := 1;
liCommentLength := 1;
MoveToCommentEnd;
end;
pcToken.SourceCode := CurrentChars(liCommentLength);
Consume(liCommentLength);

View File

@ -85,7 +85,7 @@ uses
RemoveEmptyComment, AddBeginEnd, AddBlockEndSemicolon, SortUses,
{ warnings }
Warning, WarnEmptyBlock, WarnRealType, WarnAssignToFunctionName,
WarnCaseNoElse, WarnDestroy, WarnUnusedParam,
WarnCaseNoElse, WarnDestroy, WarnUnusedParam, WarnImbalancedComment,
{ caps}
UnitNameCaps, SpecificWordCaps, IdentifierCaps, Capitalisation,
{ returns }
@ -148,8 +148,10 @@ begin
try
if lc.IsIncludedInSettings then
begin
if (lc is TWarning) then
if lc is TWarning then
begin
(lc as TWarning).OnWarning := OnMessage;
end;
fcTreeWalker.Visit(fcRoot, lc);
@ -266,6 +268,8 @@ begin
ApplyVisitorType(TWarnDestroy);
ApplyVisitorType(TWarnUnusedParam);
ApplyVisitorType(TWarnImbalancedComment);
end;
procedure TAllProcesses.Capitalisation;

View File

@ -30,18 +30,29 @@ See http://www.gnu.org/licenses/gpl.html
but there may be more }
{$I JcfGlobal.inc}
{$SCOPEDENUMS ON}
interface
uses JcfSetBase, SettingsStream;
uses Classes, JcfSetBase, SettingsStream;
type
TImbalancedCommentAction = (
Error = 0,
Warn
);
const
DEF_IMBALANCED_COMMENT_ACTION: UInt8 = Ord(TImbalancedCommentAction.Error);
type
{ TSetComments }
TSetComments = class(TSetBase)
private
fbRemoveEmptyDoubleSlashComments: boolean;
fbRemoveEmptyCurlyBraceComments: boolean;
fImbalancedCommentAction: TImbalancedCommentAction;
protected
public
constructor Create;
@ -49,17 +60,25 @@ type
procedure WriteToStream(const pcOut: TSettingsOutput); override;
procedure ReadFromStream(const pcStream: TSettingsInput); override;
procedure GetImbalancedCommentActions(const AValues: TStrings);
property RemoveEmptyDoubleSlashComments: boolean
Read fbRemoveEmptyDoubleSlashComments Write fbRemoveEmptyDoubleSlashComments;
property RemoveEmptyCurlyBraceComments: boolean
Read fbRemoveEmptyCurlyBraceComments Write fbRemoveEmptyCurlyBraceComments;
property ImbalancedCommentAction: TImbalancedCommentAction
Read fImbalancedCommentAction Write fImbalancedCommentAction;
end;
implementation
uses
TypInfo;
const
REG_REMOVE_EMPTY_DOUBLE_SLASH_COMMENTS = 'RemoveEmptyDoubleSlashComments';
REG_REMOVE_EMPTY_CURLY_BRACE_COMMENTS = 'RemoveEmptyCurlyBraceComments';
REG_IMBALANCED_COMMENT_ACTION = 'ImbalancedCommentAction';
constructor TSetComments.Create;
begin
@ -68,6 +87,8 @@ begin
end;
procedure TSetComments.ReadFromStream(const pcStream: TSettingsInput);
var
s: string;
begin
Assert(pcStream <> nil);
@ -75,6 +96,24 @@ begin
pcStream.Read(REG_REMOVE_EMPTY_DOUBLE_SLASH_COMMENTS, True);
fbRemoveEmptyCurlyBraceComments :=
pcStream.Read(REG_REMOVE_EMPTY_CURLY_BRACE_COMMENTS, True);
s := pcStream.Read(REG_IMBALANCED_COMMENT_ACTION,
GetEnumName(TypeInfo(TImbalancedCommentAction), DEF_IMBALANCED_COMMENT_ACTION));
fImbalancedCommentAction :=
TImbalancedCommentAction(GetEnumValue(TypeInfo(TImbalancedCommentAction), s));
end;
procedure TSetComments.GetImbalancedCommentActions(const AValues: TStrings);
var
iter: TImbalancedCommentAction;
begin
Assert(Assigned(AValues));
AValues.Clear();
for iter := Low(TImbalancedCommentAction) to High(TImbalancedCommentAction) do
begin
AValues.Add(GetEnumName(TypeInfo(TImbalancedCommentAction), Ord(iter)));
end;
end;
procedure TSetComments.WriteToStream(const pcOut: TSettingsOutput);
@ -83,6 +122,8 @@ begin
pcOut.Write(REG_REMOVE_EMPTY_DOUBLE_SLASH_COMMENTS, fbRemoveEmptyDoubleSlashComments);
pcOut.Write(REG_REMOVE_EMPTY_CURLY_BRACE_COMMENTS, fbRemoveEmptyCurlyBraceComments);
pcOUt.Write(REG_IMBALANCED_COMMENT_ACTION,
GetEnumName(TypeInfo(TImbalancedCommentAction), Ord(fImbalancedCommentAction)));
end;
end.

View File

@ -1,28 +1,56 @@
inherited fComments: TfComments
object fComments: TfComments
Left = 0
Height = 240
Top = 0
Width = 320
ClientHeight = 240
ClientWidth = 320
TabOrder = 0
DesignLeft = 148
DesignTop = 150
object cbRemoveEmptyDoubleSlashComments: TCheckBox[0]
AnchorSideLeft.Control = Owner
AnchorSideTop.Control = Owner
DesignLeft = 415
DesignTop = 270
object cbRemoveEmptyDoubleSlashComments: TCheckBox
Left = 6
Height = 17
Height = 23
Top = 6
Width = 156
Width = 308
Align = alTop
BorderSpacing.Around = 6
Caption = 'Remove empty ''//'' comments'
TabOrder = 0
end
object cbRemoveEmptyCurlyBraceComments: TCheckBox[1]
AnchorSideLeft.Control = Owner
AnchorSideTop.Control = cbRemoveEmptyDoubleSlashComments
AnchorSideTop.Side = asrBottom
object cbRemoveEmptyCurlyBraceComments: TCheckBox
Left = 6
Height = 17
Top = 29
Width = 161
Height = 23
Top = 35
Width = 308
Align = alTop
BorderSpacing.Around = 6
Caption = 'Remove empty ''{ }'' comments'
TabOrder = 1
end
object rgImbalancedCommentAction: TRadioGroup
Left = 6
Height = 96
Top = 64
Width = 308
Align = alTop
AutoFill = True
BorderSpacing.Around = 6
Caption = 'Imbalanced comment action'
ChildSizing.LeftRightSpacing = 6
ChildSizing.EnlargeHorizontal = crsHomogenousChildResize
ChildSizing.EnlargeVertical = crsHomogenousChildResize
ChildSizing.ShrinkHorizontal = crsScaleChilds
ChildSizing.ShrinkVertical = crsScaleChilds
ChildSizing.Layout = cclLeftToRightThenTopToBottom
ChildSizing.ControlsPerLine = 1
ClientHeight = 76
ClientWidth = 306
ItemIndex = 1
Items.Strings = (
'Warn'
'Error'
)
TabOrder = 2
end
end

View File

@ -30,16 +30,16 @@ See http://www.gnu.org/licenses/gpl.html
interface
uses
StdCtrls, Classes,
StdCtrls, ExtCtrls, Classes,
IDEOptionsIntf, IDEOptEditorIntf;
type
{ TfComments }
TfComments = class(TAbstractIDEOptionsEditor)
cbRemoveEmptyDoubleSlashComments: TCheckBox;
cbRemoveEmptyCurlyBraceComments: TCheckBox;
rgImbalancedCommentAction: TRadioGroup;
public
constructor Create(AOwner: TComponent); override;
@ -55,7 +55,7 @@ implementation
{$R *.lfm}
uses
JcfSettings, JcfUIConsts;
JcfSettings, JcfUIConsts, SetComments;
constructor TfComments.Create(AOwner: TComponent);
begin
@ -72,6 +72,7 @@ procedure TfComments.Setup(ADialog: TAbstractOptionsEditorDialog);
begin
cbRemoveEmptyDoubleSlashComments.Caption := lisCommentsRemoveEmptySlashComments;
cbRemoveEmptyCurlyBraceComments.Caption := lisCommentsRemoveEmptyCurlyBracesComments;
FormattingSettings.Comments.GetImbalancedCommentActions(rgImbalancedCommentAction.Items);
end;
procedure TfComments.ReadSettings(AOptions: TAbstractIDEOptions);
@ -80,6 +81,7 @@ begin
begin
cbRemoveEmptyDoubleSlashComments.Checked := RemoveEmptyDoubleSlashComments;
cbRemoveEmptyCurlyBraceComments.Checked := RemoveEmptyCurlyBraceComments;
rgImbalancedCommentAction.ItemIndex := Ord(ImbalancedCommentAction);
end;
end;
@ -89,6 +91,7 @@ begin
begin
RemoveEmptyDoubleSlashComments := cbRemoveEmptyDoubleSlashComments.Checked;
RemoveEmptyCurlyBraceComments := cbRemoveEmptyCurlyBraceComments.Checked;
ImbalancedCommentAction := TImbalancedCommentAction(rgImbalancedCommentAction.ItemIndex);
end;
end;