mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-18 19:29:18 +02:00
fcl-passrc: allow using unit twice with different alias
git-svn-id: trunk@43810 -
This commit is contained in:
parent
9a496c2470
commit
a3a67b13d8
@ -5676,7 +5676,7 @@ end;
|
|||||||
|
|
||||||
procedure TPasResolver.FinishUsesClause;
|
procedure TPasResolver.FinishUsesClause;
|
||||||
var
|
var
|
||||||
Section, CurSection: TPasSection;
|
Section: TPasSection;
|
||||||
i, j: Integer;
|
i, j: Integer;
|
||||||
PublicEl, UseModule: TPasElement;
|
PublicEl, UseModule: TPasElement;
|
||||||
Scope: TPasSectionScope;
|
Scope: TPasSectionScope;
|
||||||
@ -5723,25 +5723,6 @@ begin
|
|||||||
+UseUnit.Name+'->'+GetObjName(PublicEl)+'->'+PublicEl.CustomData.ClassName);
|
+UseUnit.Name+'->'+GetObjName(PublicEl)+'->'+PublicEl.CustomData.ClassName);
|
||||||
UsesScope:=TPasSectionScope(PublicEl.CustomData);
|
UsesScope:=TPasSectionScope(PublicEl.CustomData);
|
||||||
|
|
||||||
// check if module was already used by a different name
|
|
||||||
j:=i;
|
|
||||||
CurSection:=Section;
|
|
||||||
repeat
|
|
||||||
dec(j);
|
|
||||||
if j<0 then
|
|
||||||
begin
|
|
||||||
if CurSection.ClassType<>TImplementationSection then
|
|
||||||
break;
|
|
||||||
CurSection:=CurSection.GetModule.InterfaceSection;
|
|
||||||
if CurSection=nil then break;
|
|
||||||
j:=length(CurSection.UsesClause)-1;
|
|
||||||
if j<0 then break;
|
|
||||||
end;
|
|
||||||
if CurSection.UsesClause[j].Module=UseModule then
|
|
||||||
RaiseMsg(20170503004022,nDuplicateIdentifier,sDuplicateIdentifier,
|
|
||||||
[UseModule.Name,GetElementSourcePosStr(CurSection.UsesClause[j])],UseUnit);
|
|
||||||
until false;
|
|
||||||
|
|
||||||
// add full uses name
|
// add full uses name
|
||||||
AddIdentifier(Scope,UseUnit.Name,UseUnit,pikSimple);
|
AddIdentifier(Scope,UseUnit.Name,UseUnit,pikSimple);
|
||||||
|
|
||||||
|
@ -3792,16 +3792,6 @@ function TPasParser.AddUseUnit(ASection: TPasSection;
|
|||||||
ParseExc(nParserDuplicateIdentifier,SParserDuplicateIdentifier,[AUnitName]);
|
ParseExc(nParserDuplicateIdentifier,SParserDuplicateIdentifier,[AUnitName]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure CheckDuplicateInUsesList(UnitRef: TPasElement; UsesClause: TPasUsesClause);
|
|
||||||
var
|
|
||||||
i: Integer;
|
|
||||||
begin
|
|
||||||
if UsesClause=nil then exit;
|
|
||||||
for i:=0 to length(UsesClause)-1 do
|
|
||||||
if UsesClause[i].Module=UnitRef then
|
|
||||||
ParseExc(nParserDuplicateIdentifier,SParserDuplicateIdentifier,[AUnitName]);
|
|
||||||
end;
|
|
||||||
|
|
||||||
var
|
var
|
||||||
UnitRef: TPasElement;
|
UnitRef: TPasElement;
|
||||||
UsesUnit: TPasUsesUnit;
|
UsesUnit: TPasUsesUnit;
|
||||||
@ -3820,22 +3810,18 @@ begin
|
|||||||
ParseExc(nParserDuplicateIdentifier,SParserDuplicateIdentifier,[AUnitName]);
|
ParseExc(nParserDuplicateIdentifier,SParserDuplicateIdentifier,[AUnitName]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
// Note: The alias (AUnitName) must be unique within a module.
|
||||||
|
// Using an unit module twice with different alias is allowed.
|
||||||
|
CheckDuplicateInUsesList(ASection.UsesClause);
|
||||||
|
if ASection.ClassType=TImplementationSection then
|
||||||
|
CheckDuplicateInUsesList(CurModule.InterfaceSection.UsesClause);
|
||||||
|
|
||||||
UnitRef := Engine.FindModule(AUnitName,NameExpr,InFileExpr);
|
UnitRef := Engine.FindModule(AUnitName,NameExpr,InFileExpr);
|
||||||
if Assigned(UnitRef) then
|
if Assigned(UnitRef) then
|
||||||
begin
|
UnitRef.AddRef{$IFDEF CheckPasTreeRefCount}('TPasUsesUnit.Module'){$ENDIF}
|
||||||
UnitRef.AddRef{$IFDEF CheckPasTreeRefCount}('TPasUsesUnit.Module'){$ENDIF};
|
|
||||||
CheckDuplicateInUsesList(UnitRef,ASection.UsesClause);
|
|
||||||
if ASection.ClassType=TImplementationSection then
|
|
||||||
CheckDuplicateInUsesList(UnitRef,CurModule.InterfaceSection.UsesClause);
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
begin
|
|
||||||
CheckDuplicateInUsesList(ASection.UsesClause);
|
|
||||||
if ASection.ClassType=TImplementationSection then
|
|
||||||
CheckDuplicateInUsesList(CurModule.InterfaceSection.UsesClause);
|
|
||||||
UnitRef := TPasUnresolvedUnitRef(CreateElement(TPasUnresolvedUnitRef,
|
UnitRef := TPasUnresolvedUnitRef(CreateElement(TPasUnresolvedUnitRef,
|
||||||
AUnitName, ASection, NamePos));
|
AUnitName, ASection, NamePos));
|
||||||
end;
|
|
||||||
|
|
||||||
UsesUnit:=TPasUsesUnit(CreateElement(TPasUsesUnit,AUnitName,ASection,NamePos));
|
UsesUnit:=TPasUsesUnit(CreateElement(TPasUsesUnit,AUnitName,ASection,NamePos));
|
||||||
Result:=ASection.AddUnitToUsesList(AUnitName,NameExpr,InFileExpr,UnitRef,UsesUnit);
|
Result:=ASection.AddUnitToUsesList(AUnitName,NameExpr,InFileExpr,UnitRef,UsesUnit);
|
||||||
|
@ -370,7 +370,7 @@ type
|
|||||||
Procedure TestUnit_DottedUnit;
|
Procedure TestUnit_DottedUnit;
|
||||||
Procedure TestUnit_DottedExpr;
|
Procedure TestUnit_DottedExpr;
|
||||||
Procedure TestUnit_DuplicateDottedUsesFail;
|
Procedure TestUnit_DuplicateDottedUsesFail;
|
||||||
Procedure TestUnit_DuplicateUsesDiffNameFail;
|
Procedure TestUnit_DuplicateUsesDiffName;
|
||||||
Procedure TestUnit_Unit1DotUnit2Fail;
|
Procedure TestUnit_Unit1DotUnit2Fail;
|
||||||
Procedure TestUnit_InFilename;
|
Procedure TestUnit_InFilename;
|
||||||
Procedure TestUnit_InFilenameAliasDelphiFail;
|
Procedure TestUnit_InFilenameAliasDelphiFail;
|
||||||
@ -5924,7 +5924,7 @@ begin
|
|||||||
nParserDuplicateIdentifier);
|
nParserDuplicateIdentifier);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TTestResolver.TestUnit_DuplicateUsesDiffNameFail;
|
procedure TTestResolver.TestUnit_DuplicateUsesDiffName;
|
||||||
begin
|
begin
|
||||||
MainFilename:='unitdots.main1.pas';
|
MainFilename:='unitdots.main1.pas';
|
||||||
AddModuleWithIntfImplSrc('unitdots.unit1.pp',
|
AddModuleWithIntfImplSrc('unitdots.unit1.pp',
|
||||||
@ -5942,8 +5942,7 @@ begin
|
|||||||
' if unit1.j1=0 then ;',
|
' if unit1.j1=0 then ;',
|
||||||
' if unitdots.unit1.j1=0 then ;',
|
' if unitdots.unit1.j1=0 then ;',
|
||||||
'']);
|
'']);
|
||||||
CheckParserException('Duplicate identifier "unit1" at token ";" in file unitdots.main1.pas at line 2 column 27',
|
ParseProgram;
|
||||||
nParserDuplicateIdentifier);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TTestResolver.TestUnit_Unit1DotUnit2Fail;
|
procedure TTestResolver.TestUnit_Unit1DotUnit2Fail;
|
||||||
|
@ -145,10 +145,15 @@ type
|
|||||||
procedure TestUS_Program_FE_o;
|
procedure TestUS_Program_FE_o;
|
||||||
procedure TestUS_IncludeSameDir;
|
procedure TestUS_IncludeSameDir;
|
||||||
|
|
||||||
|
// uses 'in' modifier
|
||||||
procedure TestUS_UsesInFile;
|
procedure TestUS_UsesInFile;
|
||||||
procedure TestUS_UsesInFile_Duplicate;
|
procedure TestUS_UsesInFile_Duplicate;
|
||||||
procedure TestUS_UsesInFile_IndirectDuplicate;
|
procedure TestUS_UsesInFile_IndirectDuplicate;
|
||||||
procedure TestUS_UsesInFile_WorkNotEqProgDir;
|
procedure TestUS_UsesInFile_WorkNotEqProgDir;
|
||||||
|
procedure TestUS_UsesInFileTwice;
|
||||||
|
|
||||||
|
procedure TestUS_UseUnitTwiceFail;
|
||||||
|
procedure TestUS_UseUnitTwiceViaNameSpace;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function LinesToStr(const Lines: array of string): string;
|
function LinesToStr(const Lines: array of string): string;
|
||||||
@ -738,6 +743,7 @@ end;
|
|||||||
|
|
||||||
procedure TTestCLI_UnitSearch.TestUS_UsesInFile_Duplicate;
|
procedure TTestCLI_UnitSearch.TestUS_UsesInFile_Duplicate;
|
||||||
begin
|
begin
|
||||||
|
// check if using two different units with same name
|
||||||
AddUnit('system.pp',[''],['']);
|
AddUnit('system.pp',[''],['']);
|
||||||
AddUnit('unit1.pas',
|
AddUnit('unit1.pas',
|
||||||
['var a: longint;'],
|
['var a: longint;'],
|
||||||
@ -757,6 +763,7 @@ end;
|
|||||||
|
|
||||||
procedure TTestCLI_UnitSearch.TestUS_UsesInFile_IndirectDuplicate;
|
procedure TTestCLI_UnitSearch.TestUS_UsesInFile_IndirectDuplicate;
|
||||||
begin
|
begin
|
||||||
|
// check if using two different units with same name
|
||||||
AddUnit('system.pp',[''],['']);
|
AddUnit('system.pp',[''],['']);
|
||||||
AddUnit('unit1.pas',
|
AddUnit('unit1.pas',
|
||||||
['var a: longint;'],
|
['var a: longint;'],
|
||||||
@ -791,6 +798,51 @@ begin
|
|||||||
Compile(['sub/test1.pas','-Jc']);
|
Compile(['sub/test1.pas','-Jc']);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestCLI_UnitSearch.TestUS_UsesInFileTwice;
|
||||||
|
begin
|
||||||
|
AddUnit('system.pp',[''],['']);
|
||||||
|
AddUnit('unit1.pas',
|
||||||
|
['var a: longint;'],
|
||||||
|
['']);
|
||||||
|
AddFile('test1.pas',[
|
||||||
|
'uses foo in ''unit1.pas'', bar in ''unit1.pas'';',
|
||||||
|
'begin',
|
||||||
|
' bar.a:=foo.a;',
|
||||||
|
' a:=a;',
|
||||||
|
'end.']);
|
||||||
|
Compile(['test1.pas','-Jc']);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestCLI_UnitSearch.TestUS_UseUnitTwiceFail;
|
||||||
|
begin
|
||||||
|
AddUnit('system.pp',[''],['']);
|
||||||
|
AddUnit('sub.unit1.pas',
|
||||||
|
['var a: longint;'],
|
||||||
|
['']);
|
||||||
|
AddFile('test1.pas',[
|
||||||
|
'uses sub.Unit1, sub.unit1;',
|
||||||
|
'begin',
|
||||||
|
' a:=a;',
|
||||||
|
'end.']);
|
||||||
|
Compile(['test1.pas','-FNsub','-Jc'],ExitCodeSyntaxError);
|
||||||
|
AssertEquals('ErrorMsg','Duplicate identifier "sub.unit1"',ErrorMsg);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TTestCLI_UnitSearch.TestUS_UseUnitTwiceViaNameSpace;
|
||||||
|
begin
|
||||||
|
AddUnit('system.pp',[''],['']);
|
||||||
|
AddUnit('sub.unit1.pas',
|
||||||
|
['var a: longint;'],
|
||||||
|
['']);
|
||||||
|
AddFile('test1.pas',[
|
||||||
|
'uses unit1, sub.unit1;',
|
||||||
|
'begin',
|
||||||
|
' unit1.a:=sub.unit1.a;',
|
||||||
|
' a:=a;',
|
||||||
|
'end.']);
|
||||||
|
Compile(['test1.pas','-FNsub','-Jc']);
|
||||||
|
end;
|
||||||
|
|
||||||
Initialization
|
Initialization
|
||||||
RegisterTests([TTestCLI_UnitSearch]);
|
RegisterTests([TTestCLI_UnitSearch]);
|
||||||
end.
|
end.
|
||||||
|
Loading…
Reference in New Issue
Block a user