h2pas: finished tool to add named types for implicit types

git-svn-id: trunk@10379 -
This commit is contained in:
mattias 2007-01-05 14:36:42 +00:00
parent 4c41489aae
commit 5c09d7b773
3 changed files with 651 additions and 412 deletions

View File

@ -111,6 +111,32 @@ type
} }
TReplaceImplicitTypes = class(TCustomTextConverterTool) TReplaceImplicitTypes = class(TCustomTextConverterTool)
private
Src: String;
ImplicitTypes: TAvgLvlTree;// tree of TImplicitType
ExplicitTypes: TAvgLvlTree;// tree of TImplicitType
TypeStart: LongInt;
TypeEnd: integer; // 0 means invalid
ConstSectionStart: LongInt;
ConstSectionEnd: LongInt; // 0 means invalid
function FindNextImplicitType(var Position: integer;
out aTypeStart, aTypeEnd: integer): boolean;
function SearchImplicitParameterTypes(
var ModalResult: TModalResult): boolean;
function PosToStr(Position: integer): string;
procedure AdjustMinPositions(const Identifier: string);
function ReadWord(var Position: integer): boolean;
function ReadUntilAtom(var Position: integer;
const StopAtom: string; SkipBrackets: boolean = true): boolean;
function ReadRecord(var Position: integer): boolean;
function ReadClass(var Position: integer): boolean;
function ReadTypeDefinition(var Position: integer): boolean;
function ReadConstSection(var Position: integer): boolean;
function FindExplicitTypesAndConstants(
var ModalResult: TModalResult): boolean;
function InsertNewTypes(var ModalResult: TModalResult): boolean;
function FindInsertPosition(MinPos: integer): integer;
function UseNewTypes(var ModalResult: TModalResult): boolean;
public public
class function ClassDescription: string; override; class function ClassDescription: string; override;
function Execute(aText: TIDETextConverter): TModalResult; override; function Execute(aText: TIDETextConverter): TModalResult; override;
@ -1816,6 +1842,7 @@ type
Code: string; Code: string;
MinPosition: integer; MinPosition: integer;
MaxPosition: integer; MaxPosition: integer;
MinPositionNeedsTypeSection: boolean;
end; end;
function CompareImplicitTypeNames(Type1, Type2: Pointer): integer; function CompareImplicitTypeNames(Type1, Type2: Pointer): integer;
@ -1831,6 +1858,11 @@ begin
PChar(TImplicitType(ImplicitType).Name)); PChar(TImplicitType(ImplicitType).Name));
end; end;
function CompareImplicitTypeMinPositions(Type1, Type2: Pointer): integer;
begin
Result:=TImplicitType(Type1).MinPosition-TImplicitType(Type2).MinPosition;
end;
{ TReplaceImplicitParameterTypes } { TReplaceImplicitParameterTypes }
class function TReplaceImplicitTypes.ClassDescription: string; class function TReplaceImplicitTypes.ClassDescription: string;
@ -1844,20 +1876,15 @@ begin
+' Tarray_0to2_of_char = array[0..2] of char'; +' Tarray_0to2_of_char = array[0..2] of char';
end; end;
function TReplaceImplicitTypes.Execute(aText: TIDETextConverter function TReplaceImplicitTypes.FindNextImplicitType(var Position: integer;
): TModalResult; out aTypeStart, aTypeEnd: integer): boolean;
var var
Src: String;
ImplicitTypes: TAvgLvlTree;// tree of TImplicitType
ExplicitTypes: TAvgLvlTree;// tree of TImplicitType
function FindNextImplicitType(var Position: integer;
out TypeStart, TypeEnd: integer): boolean;
var
AtomStart: LongInt; AtomStart: LongInt;
CurAtom: string; CurAtom: string;
begin begin
Result:=false; Result:=false;
aTypeStart:=0;
aTypeEnd:=0;
AtomStart:=Position; AtomStart:=Position;
repeat repeat
CurAtom:=ReadNextPascalAtom(Src,Position,AtomStart); CurAtom:=ReadNextPascalAtom(Src,Position,AtomStart);
@ -1866,7 +1893,7 @@ var
// var, const, out declaration // var, const, out declaration
CurAtom:=ReadNextPascalAtom(Src,Position,AtomStart); CurAtom:=ReadNextPascalAtom(Src,Position,AtomStart);
if CurAtom='' then break; if CurAtom='' then break;
TypeStart:=AtomStart; aTypeStart:=AtomStart;
if CompareIdentifiers(PChar(CurAtom),'array')=0 then begin if CompareIdentifiers(PChar(CurAtom),'array')=0 then begin
// :array // :array
CurAtom:=ReadNextPascalAtom(Src,Position,AtomStart); CurAtom:=ReadNextPascalAtom(Src,Position,AtomStart);
@ -1884,7 +1911,7 @@ var
end else if (length(CurAtom)=1) and (CurAtom[1] in [';',')',']']) end else if (length(CurAtom)=1) and (CurAtom[1] in [';',')',']'])
then begin then begin
// type end found // type end found
TypeEnd:=AtomStart; aTypeEnd:=AtomStart;
Result:=true; Result:=true;
exit; exit;
end; end;
@ -1893,22 +1920,23 @@ var
end; end;
end; end;
until CurAtom=''; until CurAtom='';
end; end;
function SearchImplicitParameterTypes(var ModalResult: TModalResult): boolean; function TReplaceImplicitTypes.SearchImplicitParameterTypes(
var var ModalResult: TModalResult): boolean;
var
Position: Integer; Position: Integer;
StartPos, EndPos: integer; StartPos, EndPos: integer;
TypeCode: String; TypeCode: String;
TypeName: String; TypeName: String;
NewType: TImplicitType; NewType: TImplicitType;
begin begin
Result:=false; Result:=false;
ModalResult:=mrCancel; ModalResult:=mrCancel;
Position:=1; Position:=1;
while FindNextImplicitType(Position,StartPos,EndPos) do begin while FindNextImplicitType(Position,StartPos,EndPos) do begin
TypeCode:=copy(Src,StartPos,EndPos-StartPos); TypeCode:=copy(Src,StartPos,EndPos-StartPos);
DebugLn(['SearchImplicitParameterTypes ',StartPos,' TypeCode="',TypeCode,'"']); //DebugLn(['SearchImplicitParameterTypes ',StartPos,' TypeCode="',TypeCode,'"']);
TypeName:=CodeToIdentifier(TypeCode); TypeName:=CodeToIdentifier(TypeCode);
if TypeName='' then continue; if TypeName='' then continue;
if (ImplicitTypes<>nil) if (ImplicitTypes<>nil)
@ -1919,7 +1947,7 @@ var
continue; continue;
end; end;
// add new type // add new type
DebugLn(['SearchImplicitParameterTypes Adding new type ',StartPos,' TypeName=',TypeName,' TypeCode="',TypeCode,'"']); //DebugLn(['SearchImplicitParameterTypes Adding new type ',StartPos,' TypeName=',TypeName,' TypeCode="',TypeCode,'"']);
NewType:=TImplicitType.Create; NewType:=TImplicitType.Create;
NewType.Name:=TypeName; NewType.Name:=TypeName;
NewType.Code:=TypeCode; NewType.Code:=TypeCode;
@ -1930,36 +1958,31 @@ var
end; end;
ModalResult:=mrOk; ModalResult:=mrOk;
Result:=true; Result:=true;
end; end;
function FindExplicitTypesAndConstants(var ModalResult: TModalResult): boolean; function TReplaceImplicitTypes.PosToStr(Position: integer): string;
{ every implicit type can contian references to explicit types and constants var
For example: array[0..3] of bogus
If 'bogus' is defined in this source, then the new type must be defined
after 'bogus'.
=> Search all explicit types
}
var
TypeStart: LongInt;
TypeEnd: integer; // 0 means invalid
function PosToStr(Position: integer): string;
var
Line, Col: integer; Line, Col: integer;
begin begin
SrcPosToLineCol(Src,Position,Line,Col); SrcPosToLineCol(Src,Position,Line,Col);
Result:='(y='+IntToStr(Line)+',x='+IntToStr(Col)+')'; Result:='(y='+IntToStr(Line)+',x='+IntToStr(Col)+')';
end; end;
procedure AdjustMinPositions(const Identifier: string); procedure TReplaceImplicitTypes.AdjustMinPositions(const Identifier: string);
var var
Node: TAvgLvlTreeNode; Node: TAvgLvlTreeNode;
Item: TImplicitType; Item: TImplicitType;
Position: Integer; Position: Integer;
AtomStart: LongInt; AtomStart: LongInt;
CurAtom: String; CurAtom: String;
begin MinPos: LongInt;
if TypeEnd<1 then exit; begin
if TypeEnd>0 then
MinPos:=TypeEnd
else if ConstSectionEnd>0 then
MinPos:=ConstSectionEnd
else
exit;
//DebugLn(['AdjustMinPositions Identifier=',Identifier]); //DebugLn(['AdjustMinPositions Identifier=',Identifier]);
// search Identifier in all implicit type definitions // search Identifier in all implicit type definitions
@ -1977,27 +2000,27 @@ var
if CompareIdentifiers(PChar(Identifier),PChar(CurAtom))=0 then begin if CompareIdentifiers(PChar(Identifier),PChar(CurAtom))=0 then begin
// this implicit type depends on an explicit type defined // this implicit type depends on an explicit type defined
// prior in this source file // prior in this source file
DebugLn(['AdjustMinPositions "',Item.Name,'=',Item.Code,'"', {DebugLn(['AdjustMinPositions "',Item.Name,'=',Item.Code,'"',
' depends on ',Identifier, ' depends on ',Identifier,
' defined at ',PosToStr(TypeStart),'-',PosToStr(TypeEnd), ' defined at ',PosToStr(MinPos),
' as "',copy(Src,TypeStart,30),'"']); ' as "',copy(Src,MinPos,30),'"']);}
if Item.MinPosition<TypeEnd then if Item.MinPosition<MinPos then begin
Item.MinPosition:=TypeEnd; Item.MinPosition:=MinPos;
Item.MinPositionNeedsTypeSection:=TypeEnd<1;
end;
break; break;
end; end;
until false; until false;
end; end;
Node:=ImplicitTypes.FindSuccessor(Node); Node:=ImplicitTypes.FindSuccessor(Node);
end; end;
end; end;
function ReadTypeDefinition(var Position: integer): boolean; forward; function TReplaceImplicitTypes.ReadWord(var Position: integer): boolean;
var
function ReadWord(var Position: integer): boolean;
var
AtomStart: LongInt; AtomStart: LongInt;
CurAtom: String; CurAtom: String;
begin begin
AtomStart:=Position; AtomStart:=Position;
CurAtom:=ReadNextPascalAtom(Src,Position,AtomStart); CurAtom:=ReadNextPascalAtom(Src,Position,AtomStart);
if (CurAtom<>'') and IsIdentStartChar[CurAtom[1]] then if (CurAtom<>'') and IsIdentStartChar[CurAtom[1]] then
@ -2006,32 +2029,42 @@ var
DebugLn(['ReadWord word not found at ',PosToStr(AtomStart)]); DebugLn(['ReadWord word not found at ',PosToStr(AtomStart)]);
Result:=false; Result:=false;
end; end;
end; end;
function ReadUntilAtom(var Position: integer; function TReplaceImplicitTypes.ReadUntilAtom(var Position: integer;
const StopAtom: string): boolean; const StopAtom: string; SkipBrackets: boolean = true): boolean;
var var
AtomStart: LongInt; AtomStart: LongInt;
CurAtom: String; CurAtom: String;
StartPos: LongInt; StartPos: LongInt;
begin begin
Result:=false;
StartPos:=Position; StartPos:=Position;
AtomStart:=Position; AtomStart:=Position;
repeat repeat
CurAtom:=ReadNextPascalAtom(Src,Position,AtomStart); CurAtom:=ReadNextPascalAtom(Src,Position,AtomStart);
if CurAtom='' then begin if CurAtom='' then begin
DebugLn(['ReadUntilAtom atom not found: "',StopAtom,'" (starting at ',PosToStr(StartPos),')']); DebugLn(['ReadUntilAtom atom not found: "',StopAtom,'" (starting at ',PosToStr(StartPos),')']);
exit(false); exit;
end;
if SkipBrackets then begin
if CurAtom='(' then begin
// skip round bracket open
if not ReadUntilAtom(Position,')') then exit;
end else if CurAtom='[' then begin
// skip edged bracket open
if not ReadUntilAtom(Position,']') then exit;
end;
end; end;
until CurAtom=StopAtom; until CurAtom=StopAtom;
Result:=true; Result:=true;
end; end;
function ReadRecord(var Position: integer): boolean; function TReplaceImplicitTypes.ReadRecord(var Position: integer): boolean;
var var
AtomStart: LongInt; AtomStart: LongInt;
CurAtom: String; CurAtom: String;
begin begin
Result:=false; Result:=false;
AtomStart:=Position; AtomStart:=Position;
repeat repeat
@ -2081,13 +2114,13 @@ var
end; end;
until CompareIdentifiers(PChar(CurAtom),'END')=0; until CompareIdentifiers(PChar(CurAtom),'END')=0;
Result:=true; Result:=true;
end; end;
function ReadClass(var Position: integer): boolean; function TReplaceImplicitTypes.ReadClass(var Position: integer): boolean;
var var
AtomStart: LongInt; AtomStart: LongInt;
CurAtom: String; CurAtom: String;
begin begin
//DebugLn(['ReadClass at ',PosToStr(Position)]); //DebugLn(['ReadClass at ',PosToStr(Position)]);
Result:=false; Result:=false;
AtomStart:=Position; AtomStart:=Position;
@ -2117,14 +2150,16 @@ var
end; end;
until CompareIdentifiers(PChar(CurAtom),'END')=0; until CompareIdentifiers(PChar(CurAtom),'END')=0;
Result:=true; Result:=true;
end; end;
function ReadTypeDefinition(var Position: integer): boolean; function TReplaceImplicitTypes.ReadTypeDefinition(
var var Position: integer): boolean;
// Position must be after the colon
var
AtomStart: LongInt; AtomStart: LongInt;
CurAtom: String; CurAtom: String;
Enum: String; Enum: String;
begin begin
//DebugLn(['ReadTypeDefinition reading type definition at ',PosToStr(Position)]); //DebugLn(['ReadTypeDefinition reading type definition at ',PosToStr(Position)]);
Result:=false; Result:=false;
AtomStart:=Position; AtomStart:=Position;
@ -2171,20 +2206,87 @@ var
end else if CurAtom='[' then begin end else if CurAtom='[' then begin
// skip edged bracket open // skip edged bracket open
if not ReadUntilAtom(Position,']') then exit; if not ReadUntilAtom(Position,']') then exit;
end else if CurAtom=';' then end else if (length(CurAtom)=1) and (CurAtom[1] in [';',')',']']) then
break; break;
CurAtom:=ReadNextPascalAtom(Src,Position,AtomStart); CurAtom:=ReadNextPascalAtom(Src,Position,AtomStart);
until false; until false;
Result:=true; Result:=true;
end; end;
var function TReplaceImplicitTypes.ReadConstSection(var Position: integer): boolean;
// Position must be after the 'const' keyword
var
AtomStart: LongInt;
CurAtom: String;
ConstStart: LongInt;
begin
Result:=false;
AtomStart:=Position;
repeat
CurAtom:=ReadNextPascalAtom(Src,Position,AtomStart);
if CurAtom='' then begin
DebugLn(['ReadConstSection end not found']);
exit;
end;
if IsIdentStartChar[CurAtom[1]] then begin
// const identifier(s) or end of const section
//DebugLn(['ReadConstSection Const name ',CurAtom,' at ',PosToStr(AtomStart)]);
ConstStart:=AtomStart;
// for example: a,b,c: integer = 1; d=1, e:integer=0;
CurAtom:=ReadNextPascalAtom(Src,Position,AtomStart);
if (length(CurAtom)<>1) or (not (CurAtom[1] in [',','=',':'])) then
begin
// end of const section
Position:=ConstStart;
Result:=true;
exit;
end;
Position:=ConstStart;
repeat
CurAtom:=ReadNextPascalAtom(Src,Position,AtomStart);
// read identifier
if (CurAtom<>'') and IsIdentStartChar[CurAtom[1]] then begin
// identifier
AdjustMinPositions(CurAtom);
end else begin
DebugLn(['ReadConstSection end of section missing']);
exit;
end;
CurAtom:=ReadNextPascalAtom(Src,Position,AtomStart);
if (CurAtom='=') or (CurAtom=':') then begin
// skip type and expression
if not ReadUntilAtom(Position,';') then exit;
break;
end else if CurAtom=',' then begin
// next const name
end else begin
DebugLn(['ReadConstSection end of section missing']);
exit;
end;
until false;
end else begin
// end of const section
break;
end;
until false;
Result:=true;
end;
function TReplaceImplicitTypes.FindExplicitTypesAndConstants(
var ModalResult: TModalResult): boolean;
{ every implicit type can contian references to explicit types and constants
For example: array[0..3] of bogus
If 'bogus' is defined in this source, then the new type must be defined
after 'bogus'.
=> Search all explicit types
}
var
Position: Integer; Position: Integer;
AtomStart: LongInt; AtomStart: LongInt;
CurAtom: String; CurAtom: String;
Identifier: String; Identifier: String;
TypeDefStart: LongInt; TypeDefStart: LongInt;
begin begin
Result:=false; Result:=false;
ModalResult:=mrCancel; ModalResult:=mrCancel;
@ -2202,14 +2304,14 @@ var
if (Identifier<>'') and (IsIdentStartChar[Identifier[1]]) then begin if (Identifier<>'') and (IsIdentStartChar[Identifier[1]]) then begin
// word found (can be an identifier or start of next section) // word found (can be an identifier or start of next section)
TypeStart:=AtomStart; TypeStart:=AtomStart;
TypeEnd:=0;
CurAtom:=ReadNextPascalAtom(Src,Position,AtomStart); CurAtom:=ReadNextPascalAtom(Src,Position,AtomStart);
if CurAtom<>'=' then begin if CurAtom<>'=' then begin
DebugLn(['FindExplicitTypes type section ended at ',PosToStr(AtomStart)]); //DebugLn(['FindExplicitTypes type section ended at ',PosToStr(AtomStart)]);
break; break;
end; end;
// Identifier is a type => find end of type definition // Identifier is a type => find end of type definition
//DebugLn(['FindExplicitTypes type definition found: ',Identifier,' at ',PosToStr(TypeStart)]); //DebugLn(['FindExplicitTypes type definition found: ',Identifier,' at ',PosToStr(TypeStart)]);
TypeEnd:=0;
TypeDefStart:=Position; TypeDefStart:=Position;
Result:=ReadTypeDefinition(Position); Result:=ReadTypeDefinition(Position);
if not Result then begin if not Result then begin
@ -2233,65 +2335,189 @@ var
end; end;
// skip semicolon // skip semicolon
Position:=TypeEnd; Position:=TypeEnd;
TypeEnd:=0;
end; end;
until false; until false;
end end
else if CompareIdentifiers(PChar(CurAtom),'const')=0 then begin else if CompareIdentifiers(PChar(CurAtom),'const')=0 then begin
{ ToDo ConstSectionStart:=Position;
repeat ConstSectionEnd:=0;
Identifier:=ReadNextPascalAtom(Src,Position,AtomStart); // find end of const section
if (Identifier<>'') and (IsIdentStartChar[Identifier[1]]) then begin //DebugLn(['TReplaceImplicitTypes.FindExplicitTypesAndConstants finding end of const section ...']);
end else if CurAtom=':' then begin Result:=ReadConstSection(Position);
if not Result then begin
end else begin DebugLn(['FindExplicitTypes FAILED reading const section at ',PosToStr(ConstSectionStart)]);
exit;
end; end;
until false;} ConstSectionEnd:=Position;
// reread the section for the identifiers
Position:=ConstSectionStart;
//DebugLn(['TReplaceImplicitTypes.FindExplicitTypesAndConstants collecting const identifiers ...']);
Result:=ReadConstSection(Position);
if not Result then begin
DebugLn(['FindExplicitTypes FAILED reading const section at ',PosToStr(ConstSectionStart)]);
exit;
end;
ConstSectionEnd:=0;
end; end;
until false; until false;
ModalResult:=mrOk; ModalResult:=mrOk;
Result:=true; Result:=true;
end;
function TReplaceImplicitTypes.InsertNewTypes(var ModalResult: TModalResult
): boolean;
function CreateCode(Item: TImplicitType): string;
begin
Result:=' '+Item.Name+' = '+Item.Code+';';
end; end;
function AdjustMinPositions(var ModalResult: TModalResult): boolean; var
var
Node: TAvgLvlTreeNode; Node: TAvgLvlTreeNode;
begin Item: TImplicitType;
InsertPos: integer;
NextItem: TImplicitType;
NextInsertPos: integer;
NewCode: String;
begin
Result:=false; Result:=false;
ModalResult:=mrCancel; ModalResult:=mrCancel;
if (ImplicitTypes<>nil) then begin if (ImplicitTypes<>nil) then begin
// find all explicit types // re-sort the ImplicitTypes for MinPosition
// ToDo: find constants, use constant section end as MinPosition ImplicitTypes.OnCompare:=@CompareImplicitTypeMinPositions;
if not FindExplicitTypesAndConstants(ModalResult) then exit; try
// Insert every type
// now all min and max positions for the new types are known Node:=ImplicitTypes.FindHighest;
// ToDo: resort the ImplicitTypes for MinPosition
// ToDo: Insert every type
Node:=ImplicitTypes.FindLowest;
while Node<>nil do begin while Node<>nil do begin
Item:=TImplicitType(Node.Data);
NewCode:=CreateCode(Item);
if Item.MinPositionNeedsTypeSection or (Item.MinPosition=0) then
NewCode:='type'+LineEnding+NewCode;
InsertPos:=FindInsertPosition(Item.MinPosition);
// add all items at the same position
repeat
Node:=ImplicitTypes.FindPrecessor(Node);
if (Node=nil) then break;
NextItem:=TImplicitType(Node.Data);
NextInsertPos:=FindLineEndOrCodeAfterPosition(Src,NextItem.MinPosition,
length(Src)+1,false);
if InsertPos>NextInsertPos then
break;
NewCode:=NewCode+LineEnding+CreateCode(NextItem);
until false;
Node:=ImplicitTypes.FindSuccessor(Node); // insert line ends
if (InsertPos>1) and (InsertPos<length(Src))
and (not (Src[InsertPos-1] in [#10,#13])) then
NewCode:=LineEnding+NewCode;
if (InsertPos<=length(Src)) and (not (Src[InsertPos] in [#10,#13])) then
NewCode:=NewCode+LineEnding;
// insert code
DebugLn(['TReplaceImplicitTypes.InsertNewTypes Insert at ',PosToStr(InsertPos),' NewCode="',NewCode,'"']);
Src:=copy(Src,1,InsertPos-1)+NewCode+copy(Src,InsertPos,length(Src));
end;
finally
// re-sort the ImplicitTypes for Names
ImplicitTypes.OnCompare:=@CompareImplicitTypeNames;
end; end;
end; end;
ModalResult:=mrOk; ModalResult:=mrOk;
Result:=true; Result:=true;
end; end;
function TReplaceImplicitTypes.FindInsertPosition(MinPos: integer): integer;
var
Position: Integer;
AtomStart: LongInt;
CurAtom: String;
begin begin
{$IFNDEF EnableReplaceImplicitTypes} if MinPos>0 then begin
exit(mrOk); Result:=FindLineEndOrCodeAfterPosition(Src,MinPos,length(Src)+1,false);
{$ENDIF} end else begin
// find insert position for a first type section
Result:=1;
Position:=1;
AtomStart:=Position;
repeat
CurAtom:=ReadNextPascalAtom(Src,Position,AtomStart);
if CurAtom='' then break;
if (CompareIdentifiers(PChar(CurAtom),'UNIT')=0)
or (CompareIdentifiers(PChar(CurAtom),'PROGRAM')=0)
or (CompareIdentifiers(PChar(CurAtom),'LIBRARY')=0)
or (CompareIdentifiers(PChar(CurAtom),'PACKAGE')=0)
or (CompareIdentifiers(PChar(CurAtom),'USES')=0)
then begin
ReadUntilAtom(Position,';');
Result:=Position;
end
else if (CompareIdentifiers(PChar(CurAtom),'INTERFACE')=0)
or (CompareIdentifiers(PChar(CurAtom),'IMPLEMENTATION')=0)
then begin
Result:=Position;
break;
end else
break;
until false;
end;
end;
function TReplaceImplicitTypes.UseNewTypes(var ModalResult: TModalResult
): boolean;
var
Position: Integer;
StartPos: Integer;
EndPos: Integer;
TypeCode: String;
TypeName: String;
Node: TAvgLvlTreeNode;
Item: TImplicitType;
begin
Result:=false;
ModalResult:=mrCancel;
if (ImplicitTypes<>nil) then begin
Position:=1;
StartPos:=1;
EndPos:=1;
while FindNextImplicitType(Position,StartPos,EndPos) do begin
TypeCode:=copy(Src,StartPos,EndPos-StartPos);
//DebugLn(['UseNewTypes ',StartPos,' TypeCode="',TypeCode,'"']);
TypeName:=CodeToIdentifier(TypeCode);
if TypeName='' then continue;
Node:=ImplicitTypes.FindKey(Pointer(TypeName),
@CompareImplicitTypeStringAndName);
if Node<>nil then begin
// replace
Item:=TImplicitType(Node.Data);
Src:=copy(Src,1,StartPos-1)+Item.Name+copy(Src,EndPos,length(Src));
Position:=StartPos+length(Item.Name);
end;
end;
end;
ModalResult:=mrOk;
Result:=true;
end;
function TReplaceImplicitTypes.Execute(aText: TIDETextConverter
): TModalResult;
begin
Src:=aText.Source; Src:=aText.Source;
if Src='' then exit(mrOk); if Src='' then exit(mrOk);
ImplicitTypes:=nil; ImplicitTypes:=nil;
ExplicitTypes:=nil; ExplicitTypes:=nil;
TypeEnd:=0;
ConstSectionEnd:=0;
try try
if not SearchImplicitParameterTypes(Result) then exit; if not SearchImplicitParameterTypes(Result) then exit;
if not AdjustMinPositions(Result) then exit; if (ImplicitTypes<>nil) then begin
if not FindExplicitTypesAndConstants(Result) then exit;
if not InsertNewTypes(Result) then exit;
if not UseNewTypes(Result) then exit;
aText.Source:=Src;
end;
finally finally
if ImplicitTypes<>nil then begin if ImplicitTypes<>nil then begin
ImplicitTypes.FreeAndClear; ImplicitTypes.FreeAndClear;

View File

@ -1,3 +1,10 @@
unit h2pastest;
interface
const
MinValue = 0;
MaxValue = 5;
type type
TMyClass = class; TMyClass = class;
@ -17,9 +24,10 @@ type
false: (AsWord: word); false: (AsWord: word);
end; end;
// this procedure contains an explicit/anoymous type, which is not allowed // these procedures contain explicit/anoymous types, which are not allowed
// in FreePascal. The TReplaceImplicitTypes tool will replace it with a // in FreePascal. The TReplaceImplicitTypes tool will replace them with
// named type // named types
procedure DoSomething(var a: array[0..3] of TMyClass); procedure DoSomething1(var a: array[0..3] of TMyClass);
procedure DoSomething2(var a: array[MinValue..MaxValue] of char);

View File

@ -39,7 +39,7 @@
<PackageName Value="CodeTools"/> <PackageName Value="CodeTools"/>
</Item3> </Item3>
</RequiredPackages> </RequiredPackages>
<Units Count="17"> <Units Count="18">
<Unit0> <Unit0>
<Filename Value="testh2pastool.lpr"/> <Filename Value="testh2pastool.lpr"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
@ -47,7 +47,7 @@
<CursorPos X="23" Y="36"/> <CursorPos X="23" Y="36"/>
<TopLine Value="21"/> <TopLine Value="21"/>
<EditorIndex Value="0"/> <EditorIndex Value="0"/>
<UsageCount Value="27"/> <UsageCount Value="31"/>
<Loaded Value="True"/> <Loaded Value="True"/>
</Unit0> </Unit0>
<Unit1> <Unit1>
@ -100,11 +100,11 @@
</Unit7> </Unit7>
<Unit8> <Unit8>
<Filename Value="files/h2pastest.pas"/> <Filename Value="files/h2pastest.pas"/>
<UnitName Value="h2pasTest"/> <UnitName Value="h2pastest"/>
<CursorPos X="53" Y="23"/> <CursorPos X="10" Y="3"/>
<TopLine Value="1"/> <TopLine Value="1"/>
<EditorIndex Value="4"/> <EditorIndex Value="2"/>
<UsageCount Value="24"/> <UsageCount Value="26"/>
<Loaded Value="True"/> <Loaded Value="True"/>
</Unit8> </Unit8>
<Unit9> <Unit9>
@ -117,10 +117,10 @@
<Unit10> <Unit10>
<Filename Value="../../h2pas/h2pasconvert.pas"/> <Filename Value="../../h2pas/h2pasconvert.pas"/>
<UnitName Value="H2PasConvert"/> <UnitName Value="H2PasConvert"/>
<CursorPos X="32" Y="2240"/> <CursorPos X="10" Y="2457"/>
<TopLine Value="2213"/> <TopLine Value="2433"/>
<EditorIndex Value="1"/> <EditorIndex Value="1"/>
<UsageCount Value="13"/> <UsageCount Value="15"/>
<Loaded Value="True"/> <Loaded Value="True"/>
</Unit10> </Unit10>
<Unit11> <Unit11>
@ -133,8 +133,8 @@
<Unit12> <Unit12>
<Filename Value="../../codetools/basiccodetools.pas"/> <Filename Value="../../codetools/basiccodetools.pas"/>
<UnitName Value="BasicCodeTools"/> <UnitName Value="BasicCodeTools"/>
<CursorPos X="1" Y="2050"/> <CursorPos X="10" Y="95"/>
<TopLine Value="2026"/> <TopLine Value="75"/>
<EditorIndex Value="3"/> <EditorIndex Value="3"/>
<UsageCount Value="13"/> <UsageCount Value="13"/>
<Loaded Value="True"/> <Loaded Value="True"/>
@ -162,13 +162,18 @@
</Unit15> </Unit15>
<Unit16> <Unit16>
<Filename Value="../../../packager/globallinks/simpleideintf-0.lpl"/> <Filename Value="../../../packager/globallinks/simpleideintf-0.lpl"/>
<CursorPos X="53" Y="1"/> <CursorPos X="12" Y="1"/>
<TopLine Value="1"/> <TopLine Value="1"/>
<EditorIndex Value="2"/>
<UsageCount Value="10"/> <UsageCount Value="10"/>
<Loaded Value="True"/>
<SyntaxHighlighter Value="None"/> <SyntaxHighlighter Value="None"/>
</Unit16> </Unit16>
<Unit17>
<Filename Value="../../../lcl/avglvltree.pas"/>
<UnitName Value="AvgLvlTree"/>
<CursorPos X="23" Y="93"/>
<TopLine Value="65"/>
<UsageCount Value="10"/>
</Unit17>
</Units> </Units>
<JumpHistory Count="0" HistoryIndex="-1"/> <JumpHistory Count="0" HistoryIndex="-1"/>
</ProjectOptions> </ProjectOptions>