mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-10 14:36:09 +02:00
codetools: parse multi dim arrays, patch from Paul W, issue #25045
git-svn-id: branches/fixes_1_8@54720 -
This commit is contained in:
parent
3e9f18c4e3
commit
a659e90a58
@ -9335,7 +9335,7 @@ var
|
|||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
if fdfExtractOperand in Params.Flags then begin
|
if fdfExtractOperand in Params.Flags then begin
|
||||||
// simple copying, todo: expand argument
|
// simple copying, todo: expand argument
|
||||||
Params.AddOperandPart(Copy(Src, CurPos.StartPos, CurAtomBracketEndPos-CurPos.StartPos));
|
Params.AddOperandPart(ExtractBrackets(CurPos.StartPos,[]));
|
||||||
end;
|
end;
|
||||||
if (not (NextAtomType in [vatSpace,vatPoint,vatAs,vatUp,vatRoundBracketClose,
|
if (not (NextAtomType in [vatSpace,vatPoint,vatAs,vatUp,vatRoundBracketClose,
|
||||||
vatRoundBracketOpen,vatEdgedBracketClose,vatEdgedBracketOpen]))
|
vatRoundBracketOpen,vatEdgedBracketClose,vatEdgedBracketOpen]))
|
||||||
@ -9378,6 +9378,27 @@ var
|
|||||||
RaiseIllegalQualifierFound;
|
RaiseIllegalQualifierFound;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
if ExprType.Context.Node.Desc in [ctnRangedArrayType,ctnOpenArrayType] then
|
||||||
|
begin
|
||||||
|
MoveCursorToCleanPos(CurAtom.StartPos);
|
||||||
|
ReadNextAtom; // "["
|
||||||
|
ReadNextAtom;
|
||||||
|
repeat
|
||||||
|
case CurPos.Flag of
|
||||||
|
cafRoundBracketClose: SaveRaiseBracketCloseExpectedButAtomFound(20170425090717);
|
||||||
|
cafRoundBracketOpen,
|
||||||
|
cafEdgedBracketOpen: ReadTilBracketClose(true);
|
||||||
|
cafComma:
|
||||||
|
with ExprType, Context do begin
|
||||||
|
Context:=Tool.FindBaseTypeOfNode(Params,Node.LastChild);
|
||||||
|
if not (Node.Desc in [ctnRangedArrayType,ctnOpenArrayType]) then
|
||||||
|
RaiseIllegalQualifierFound;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
ReadNextAtom;
|
||||||
|
until CurPos.Flag=cafEdgedBracketClose;
|
||||||
|
end;
|
||||||
|
|
||||||
{$IFDEF ShowExprEval}
|
{$IFDEF ShowExprEval}
|
||||||
DebugLn([' FindExpressionTypeOfTerm ResolveEdgedBracketOpen ExprType=',ExprTypeToString(ExprType)]);
|
DebugLn([' FindExpressionTypeOfTerm ResolveEdgedBracketOpen ExprType=',ExprTypeToString(ExprType)]);
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
@ -11370,6 +11391,16 @@ function TFindDeclarationTool.CheckParameterSyntax(StartPos,
|
|||||||
then begin
|
then begin
|
||||||
// parameter list ended in front of Variable => continue search
|
// parameter list ended in front of Variable => continue search
|
||||||
{$IFDEF VerboseCPS}DebugLn('CheckIdentifierAndParameterList parameter list ended in front of cursor');{$ENDIF}
|
{$IFDEF VerboseCPS}DebugLn('CheckIdentifierAndParameterList parameter list ended in front of cursor');{$ENDIF}
|
||||||
|
if CurPos.Flag=cafEdgedBracketClose then begin
|
||||||
|
ReadNextAtom;
|
||||||
|
if CurPos.Flag=cafEdgedBracketOpen then begin
|
||||||
|
// [][] is equal to [,]
|
||||||
|
ParameterStart:=CurPos.EndPos;
|
||||||
|
inc(CurParameterIndex);
|
||||||
|
continue;
|
||||||
|
end else
|
||||||
|
UndoReadNextAtom;
|
||||||
|
end;
|
||||||
exit;
|
exit;
|
||||||
end else begin
|
end else begin
|
||||||
// invalid closing bracket found
|
// invalid closing bracket found
|
||||||
|
@ -4521,42 +4521,60 @@ function TPascalParserTool.KeyWordFuncTypeArray: boolean;
|
|||||||
array[SubRange,SubRange,...] of ...
|
array[SubRange,SubRange,...] of ...
|
||||||
array[Subrange]; // without "of" means array of byte
|
array[Subrange]; // without "of" means array of byte
|
||||||
}
|
}
|
||||||
begin
|
|
||||||
CreateChildNode;
|
function ReadElemType: boolean;
|
||||||
// first set the type to open array (an array type without brackets)
|
begin
|
||||||
CurNode.Desc:=ctnOpenArrayType;
|
|
||||||
ReadNextAtom;
|
|
||||||
if (CurPos.Flag=cafEdgedBracketOpen) then begin
|
|
||||||
repeat
|
|
||||||
ReadNextAtom;
|
|
||||||
// this is a ranged array -> change type
|
|
||||||
CurNode.Desc:=ctnRangedArrayType;
|
|
||||||
CreateChildNode;
|
|
||||||
CurNode.Desc:=ctnRangeType;
|
|
||||||
ReadSubRange(true);
|
|
||||||
CurNode.EndPos:=LastAtoms.GetValueAt(0).EndPos;
|
|
||||||
EndChildNode; // close ctnRangeType
|
|
||||||
if (CurPos.Flag=cafEdgedBracketClose) then break;
|
|
||||||
if (CurPos.Flag<>cafComma) then
|
|
||||||
SaveRaiseCharExpectedButAtomFound(20170421195805,']');
|
|
||||||
until false;
|
|
||||||
ReadNextAtom;
|
|
||||||
if CurPos.Flag in [cafSemicolon,cafRoundBracketClose,cafEdgedBracketClose]
|
if CurPos.Flag in [cafSemicolon,cafRoundBracketClose,cafEdgedBracketClose]
|
||||||
then begin
|
then begin
|
||||||
// array[] without "of" means array[] of byte
|
// array[] without "of" means array[] of byte
|
||||||
CurNode.EndPos:=CurPos.StartPos;
|
CurNode.EndPos:=CurPos.StartPos;
|
||||||
EndChildNode; // close array
|
EndChildNode; // close array
|
||||||
exit(true);
|
Result:=true;
|
||||||
|
end else begin
|
||||||
|
if not UpAtomIs('OF') then
|
||||||
|
SaveRaiseStringExpectedButAtomFound(20170425090708,'"of"');
|
||||||
|
ReadNextAtom;
|
||||||
|
Result:=ParseType(CurPos.StartPos);
|
||||||
|
CurNode.EndPos:=CurPos.StartPos;
|
||||||
|
EndChildNode; // close array
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
if not UpAtomIs('OF') then
|
|
||||||
SaveRaiseStringExpectedButAtomFound(20170421195808,'"of"');
|
function ReadIndexType: boolean;
|
||||||
ReadNextAtom;
|
begin
|
||||||
Result:=ParseType(CurPos.StartPos);
|
ReadNextAtom;
|
||||||
CurNode.EndPos:=CurPos.StartPos;
|
CreateChildNode;
|
||||||
EndChildNode; // close array
|
CurNode.Desc:=ctnRangeType;
|
||||||
//debugln(['TPascalParserTool.KeyWordFuncTypeArray END Atom=',GetAtom,' CurNode=',CurNode.DescAsString]);
|
ReadSubRange(true);
|
||||||
Result:=true;
|
CurNode.EndPos:=LastAtoms.GetValueAt(0).EndPos;
|
||||||
|
EndChildNode; // close ctnRangeType
|
||||||
|
if CurPos.Flag=cafComma then begin
|
||||||
|
// "array [T1,T2]" is equal to "array [T1] of array [T2]"
|
||||||
|
// so they should be parsed to the same CodeTree
|
||||||
|
CreateChildNode;
|
||||||
|
CurNode.Desc:=ctnRangedArrayType;
|
||||||
|
Result:=ReadIndexType();
|
||||||
|
CurNode.EndPos:=LastAtoms.GetValueAt(0).EndPos;
|
||||||
|
EndChildNode; // close ctnRangedArrayType
|
||||||
|
end else begin
|
||||||
|
if CurPos.Flag<>cafEdgedBracketClose then
|
||||||
|
SaveRaiseCharExpectedButAtomFound(20170425090712,']');
|
||||||
|
ReadNextAtom;
|
||||||
|
CurNode.EndPos:=LastAtoms.GetValueAt(0).EndPos;
|
||||||
|
Result:=ReadElemType;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
CreateChildNode;
|
||||||
|
// first set the type to open array (an array type without brackets)
|
||||||
|
CurNode.Desc:=ctnOpenArrayType;
|
||||||
|
if (CurPos.Flag=cafEdgedBracketOpen) then begin
|
||||||
|
CurNode.Desc:=ctnRangedArrayType;
|
||||||
|
Result:=ReadIndexType;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
Result:=ReadElemType;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TPascalParserTool.KeyWordFuncTypeProc: boolean;
|
function TPascalParserTool.KeyWordFuncTypeProc: boolean;
|
||||||
|
@ -263,6 +263,8 @@ type
|
|||||||
// arrays
|
// arrays
|
||||||
function ExtractArrayRange(ArrayNode: TCodeTreeNode;
|
function ExtractArrayRange(ArrayNode: TCodeTreeNode;
|
||||||
Attr: TProcHeadAttributes): string;
|
Attr: TProcHeadAttributes): string;
|
||||||
|
function ExtractArrayRanges(ArrayNode: TCodeTreeNode;
|
||||||
|
Attr: TProcHeadAttributes): string;
|
||||||
|
|
||||||
// module sections
|
// module sections
|
||||||
function ExtractSourceName: string;
|
function ExtractSourceName: string;
|
||||||
@ -3176,6 +3178,32 @@ begin
|
|||||||
Result:=ExtractBrackets(CurPos.StartPos,Attr);
|
Result:=ExtractBrackets(CurPos.StartPos,Attr);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TPascalReaderTool.ExtractArrayRanges(ArrayNode: TCodeTreeNode;
|
||||||
|
Attr: TProcHeadAttributes): string;
|
||||||
|
const
|
||||||
|
AllArrays = [ctnRangedArrayType, ctnOpenArrayType];
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
Result:='';
|
||||||
|
if (ArrayNode=nil) or not (ArrayNode.Desc in AllArrays) then exit;
|
||||||
|
while Assigned(ArrayNode.Parent) and (ArrayNode.Parent.Desc in AllArrays) do
|
||||||
|
ArrayNode:=ArrayNode.Parent;
|
||||||
|
MoveCursorToNodeStart(ArrayNode);
|
||||||
|
if not ReadNextUpAtomIs('ARRAY') then exit;
|
||||||
|
repeat
|
||||||
|
if Result<>'' then Result:=Result+',';
|
||||||
|
if ArrayNode.Desc=ctnRangedArrayType then begin
|
||||||
|
MoveCursorToNodeStart(ArrayNode.FirstChild); // FirstChild=Index type
|
||||||
|
Result:=Result+ExtractNode(ArrayNode.FirstChild,Attr);
|
||||||
|
end else begin
|
||||||
|
Result:=Result+'PtrUInt';
|
||||||
|
end;
|
||||||
|
ArrayNode:=ArrayNode.LastChild;
|
||||||
|
until not (ArrayNode.Desc in AllArrays);
|
||||||
|
Result:='['+Result+']';
|
||||||
|
end;
|
||||||
|
|
||||||
function TPascalReaderTool.PropertyIsDefault(PropertyNode: TCodeTreeNode): boolean;
|
function TPascalReaderTool.PropertyIsDefault(PropertyNode: TCodeTreeNode): boolean;
|
||||||
begin
|
begin
|
||||||
Result:=false;
|
Result:=false;
|
||||||
|
@ -338,8 +338,18 @@ begin
|
|||||||
end;
|
end;
|
||||||
')',']':
|
')',']':
|
||||||
begin
|
begin
|
||||||
|
if BracketLevel=1 then begin
|
||||||
|
if Code[TokenStart]=']' then begin
|
||||||
|
ReadRawNextPascalAtom(Code,TokenEnd,TokenStart);
|
||||||
|
if TokenEnd=TokenStart then exit;
|
||||||
|
if Code[TokenStart]='[' then begin
|
||||||
|
inc(NewParameterIndex);
|
||||||
|
continue; // [][] is full version of [,]
|
||||||
|
end
|
||||||
|
end else
|
||||||
|
exit;// cursor behind procedure call
|
||||||
|
end;
|
||||||
dec(BracketLevel);
|
dec(BracketLevel);
|
||||||
if BracketLevel=0 then exit;// cursor behind procedure call
|
|
||||||
end;
|
end;
|
||||||
',':
|
',':
|
||||||
if BracketLevel=1 then inc(NewParameterIndex);
|
if BracketLevel=1 then inc(NewParameterIndex);
|
||||||
@ -403,14 +413,9 @@ procedure TCodeContextFrm.CreateHints(const CodeContexts: TCodeContextInfo);
|
|||||||
phpWithResultType]);
|
phpWithResultType]);
|
||||||
Result:=true;
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
ctnOpenArrayType:
|
ctnOpenArrayType,ctnRangedArrayType:
|
||||||
begin
|
begin
|
||||||
s:=s+'[Index: PtrUInt]';
|
s:=s+ExprTool.ExtractArrayRanges(ExprNode,[]);
|
||||||
Result:=true;
|
|
||||||
end;
|
|
||||||
ctnRangedArrayType:
|
|
||||||
begin
|
|
||||||
s:=s+ExprTool.ExtractArrayRange(ExprNode,[]);
|
|
||||||
Result:=true;
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -633,10 +638,10 @@ procedure TCodeContextFrm.MarkCurrentParameterInHints(ParameterIndex: integer);
|
|||||||
repeat
|
repeat
|
||||||
inc(p);
|
inc(p);
|
||||||
until (p>=length(Result)) or (Result[p]='''');
|
until (p>=length(Result)) or (Result[p]='''');
|
||||||
'a'..'z','A'..'Z','_':
|
'a'..'z','A'..'Z','_','0'..'9':
|
||||||
if (BracketLevel=1) and (not ReadingType) then begin
|
if (BracketLevel=1) and (not ReadingType) then begin
|
||||||
WordStart:=p;
|
WordStart:=p;
|
||||||
while (p<=length(Result)) and (IsIdentChar[Result[p]]) do
|
while (p<=length(Result)) and IsDottedIdentChar[Result[p]] do
|
||||||
inc(p);
|
inc(p);
|
||||||
WordEnd:=p;
|
WordEnd:=p;
|
||||||
//DebugLn('MarkCurrentParameterInHint Word=',copy(Result,WordStart,WordEnd-WordStart));
|
//DebugLn('MarkCurrentParameterInHint Word=',copy(Result,WordStart,WordEnd-WordStart));
|
||||||
|
Loading…
Reference in New Issue
Block a user