diff --git a/packages/fcl-passrc/src/pasresolver.pp b/packages/fcl-passrc/src/pasresolver.pp index e4dc50147f..cccf903374 100644 --- a/packages/fcl-passrc/src/pasresolver.pp +++ b/packages/fcl-passrc/src/pasresolver.pp @@ -1137,7 +1137,7 @@ type Access: TResolvedRefAccess); virtual; procedure AccessExpr(Expr: TPasExpr; Access: TResolvedRefAccess); procedure FinishModule(CurModule: TPasModule); virtual; - procedure FinishUsesList; virtual; + procedure FinishUsesClause; virtual; procedure FinishTypeSection(El: TPasDeclarations); virtual; procedure FinishTypeDef(El: TPasType); virtual; procedure FinishEnumType(El: TPasEnumType); virtual; @@ -3025,54 +3025,56 @@ begin {$ENDIF} end; -procedure TPasResolver.FinishUsesList; +procedure TPasResolver.FinishUsesClause; var Section: TPasSection; i: Integer; - El, PublicEl: TPasElement; + PublicEl, UseModule: TPasElement; Scope: TPasSectionScope; UsesScope: TPasIdentifierScope; + UseUnit: TPasUsesUnit; begin CheckTopScope(TPasSectionScope); Scope:=TPasSectionScope(TopScope); Section:=TPasSection(Scope.Element); {$IFDEF VerbosePasResolver} - writeln('TPasResolver.FinishUsesList Section=',Section.ClassName,' Section.UsesList.Count=',Section.UsesList.Count); + writeln('TPasResolver.FinishUsesClause Section=',Section.ClassName,' Section.UsesList.Count=',Section.UsesList.Count); {$ENDIF} for i:=0 to Section.UsesList.Count-1 do begin - El:=TPasElement(Section.UsesList[i]); + UseUnit:=Section.UsesClause[i]; {$IFDEF VerbosePasResolver} - writeln('TPasResolver.FinishUsesList ',GetObjName(El)); + writeln('TPasResolver.FinishUsesClause ',GetObjName(UseUnit)); {$ENDIF} - if (El.ClassType=TProgramSection) then - RaiseInternalError(20160922163346,'used unit is a program: '+GetObjName(El)); + UseModule:=UseUnit.Module; + if (UseModule.ClassType=TProgramSection) then + RaiseInternalError(20160922163346,'used unit is a program: '+GetObjName(UseModule)); // add unitname as identifier - AddIdentifier(Scope,El.Name,El,pikSimple); + AddIdentifier(Scope,UseUnit.Name,UseModule,pikSimple); // check used unit PublicEl:=nil; - if (El.ClassType=TLibrarySection) then - PublicEl:=El - else if (El.ClassType=TPasModule) then - PublicEl:=TPasModule(El).InterfaceSection; + if (UseModule.ClassType=TLibrarySection) then + PublicEl:=UseModule + else if (UseModule.ClassType=TPasModule) then + PublicEl:=TPasModule(UseModule).InterfaceSection; if PublicEl=nil then - RaiseInternalError(20160922163352,'uses element has no interface section: '+GetObjName(El)); + RaiseInternalError(20160922163352,'uses element has no interface section: '+GetObjName(UseModule)); if PublicEl.CustomData=nil then RaiseInternalError(20160922163358,'uses element has no resolver data: ' - +El.Name+'->'+GetObjName(PublicEl)); + +UseUnit.Name+'->'+GetObjName(PublicEl)); if not (PublicEl.CustomData is TPasIdentifierScope) then RaiseInternalError(20160922163403,'uses element has invalid resolver data: ' - +El.Name+'->'+GetObjName(PublicEl)+'->'+PublicEl.CustomData.ClassName); + +UseUnit.Name+'->'+GetObjName(PublicEl)+'->'+PublicEl.CustomData.ClassName); UsesScope:=TPasIdentifierScope(PublicEl.CustomData); {$IFDEF VerbosePasResolver} - writeln('TPasResolver.FinishUsesList Add UsesScope=',GetObjName(UsesScope)); + writeln('TPasResolver.FinishUsesClause Add UsesScope=',GetObjName(UsesScope)); {$ENDIF} Scope.UsesList.Add(UsesScope); - EmitElementHints(Section,El); + EmitElementHints(Section,UseUnit); end; end; @@ -8569,7 +8571,7 @@ procedure TPasResolver.FinishScope(ScopeType: TPasScopeType; El: TPasElement); begin case ScopeType of stModule: FinishModule(El as TPasModule); - stUsesList: FinishUsesList; + stUsesClause: FinishUsesClause; stTypeSection: FinishTypeSection(El as TPasDeclarations); stTypeDef: FinishTypeDef(El as TPasType); stConstDef: FinishConstDef(El as TPasConst); @@ -11656,11 +11658,18 @@ begin ResolvedEl.IdentEl:=El; ResolvedEl.Flags:=[rrfReadable,rrfWritable]; end - else if El is TPasModule then + else if ElClass=TPasUsesUnit then + begin + if TPasUsesUnit(El).Module is TPasModule then + SetResolverIdentifier(ResolvedEl,btModule,TPasUsesUnit(El).Module,nil,[]) + else + RaiseNotYetImplemented(20170429112047,TPasUsesUnit(El).Module); + end + else if El.InheritsFrom(TPasModule) then SetResolverIdentifier(ResolvedEl,btModule,El,nil,[]) else if ElClass=TNilExpr then SetResolverValueExpr(ResolvedEl,btNil,FBaseTypes[btNil],TNilExpr(El),[rrfReadable]) - else if El is TPasProcedure then + else if El.InheritsFrom(TPasProcedure) then begin SetResolverIdentifier(ResolvedEl,btProc,El,TPasProcedure(El).ProcType,[rrfCanBeStatement]); if El is TPasFunction then @@ -11668,7 +11677,7 @@ begin // Note: the readability of TPasConstructor depends on the context // Note: implicit calls are handled in TPrimitiveExpr end - else if El is TPasProcedureType then + else if El.InheritsFrom(TPasProcedureType) then begin SetResolverIdentifier(ResolvedEl,btContext,El,TPasProcedureType(El),[rrfCanBeStatement]); // Note: implicit calls are handled in TPrimitiveExpr diff --git a/packages/fcl-passrc/src/passrcutil.pp b/packages/fcl-passrc/src/passrcutil.pp index 4a7babdad3..3599c42204 100644 --- a/packages/fcl-passrc/src/passrcutil.pp +++ b/packages/fcl-passrc/src/passrcutil.pp @@ -195,7 +195,7 @@ begin If not Assigned(ASection) then exit; if ASection.UsesList.Count=length(ASection.UsesClause) then For I:=0 to length(ASection.UsesClause)-1 do - List.Add(ASection.UsesClause[i].Identifier) + List.Add(ASection.UsesClause[i].Name) else For I:=0 to ASection.UsesList.Count-1 do List.Add(TPasElement(ASection.UsesList[i]).Name); diff --git a/packages/fcl-passrc/src/pastree.pp b/packages/fcl-passrc/src/pastree.pp index 286cd338fe..746b44eb48 100644 --- a/packages/fcl-passrc/src/pastree.pp +++ b/packages/fcl-passrc/src/pastree.pp @@ -319,10 +319,9 @@ type procedure ForEachCall(const aMethodCall: TOnForEachPasElement; const Arg: Pointer); override; public - Expr: TPasExpr; - Identifier: string; // e.g. 'name.space.unitname' + Expr: TPasExpr; // name expression InFilename: TPrimitiveExpr; // Kind=pekString, can be nil - Module: TPasElement; // TPasUnresolvedTypeRef or TPasModule + Module: TPasElement; // TPasUnresolvedUnitRef or TPasModule end; TPasUsesClause = array of TPasUsesUnit; @@ -332,12 +331,13 @@ type public constructor Create(const AName: string; AParent: TPasElement); override; destructor Destroy; override; - procedure AddUnitToUsesList(const AUnitName: string); + function AddUnitToUsesList(const AUnitName: string; aName: TPasExpr = nil; + InFilename: TPrimitiveExpr = nil; aModule: TPasElement = nil): TPasUsesUnit; function ElementTypeName: string; override; procedure ForEachCall(const aMethodCall: TOnForEachPasElement; const Arg: Pointer); override; public - UsesList: TFPList; // kept for compatibility, see UsesClause Module + UsesList: TFPList; // kept for compatibility, see TPasUsesUnit.Module UsesClause: TPasUsesClause; end; @@ -4028,14 +4028,26 @@ begin {$IFDEF VerbosePasTreeMem}writeln('TPasSection.Destroy END');{$ENDIF} end; -procedure TPasSection.AddUnitToUsesList(const AUnitName: string); +function TPasSection.AddUnitToUsesList(const AUnitName: string; + aName: TPasExpr; InFilename: TPrimitiveExpr; aModule: TPasElement + ): TPasUsesUnit; var l: Integer; begin - UsesList.Add(TPasUnresolvedTypeRef.Create(AUnitName, Self)); + if (InFilename<>nil) and (InFilename.Kind<>pekString) then + raise Exception.Create(''); + if aModule=nil then + aModule:=TPasUnresolvedUnitRef.Create(AUnitName, Self); l:=length(UsesClause); SetLength(UsesClause,l+1); - UsesClause[l]:=TPasUsesUnit.Create(AUnitName,Self); + Result:=TPasUsesUnit.Create(AUnitName,Self); + UsesClause[l]:=Result; + Result.Expr:=aName; + Result.InFilename:=InFilename; + Result.Module:=aModule; + + UsesList.Add(aModule); + aModule.AddRef; end; function TPasSection.ElementTypeName: string; diff --git a/packages/fcl-passrc/src/pasuseanalyzer.pas b/packages/fcl-passrc/src/pasuseanalyzer.pas index 148150f9d2..aeeda11968 100644 --- a/packages/fcl-passrc/src/pasuseanalyzer.pas +++ b/packages/fcl-passrc/src/pasuseanalyzer.pas @@ -740,11 +740,11 @@ end; procedure TPasAnalyzer.UseSection(Section: TPasSection; Mode: TPAUseMode); // called by UseModule var - UsesList: TFPList; i: Integer; UsedModule: TPasModule; Decl: TPasElement; OnlyExports: Boolean; + UsesClause: TPasUsesClause; begin // Section is TProgramSection, TLibrarySection, TInterfaceSection, TImplementationSection if Mode=paumElement then @@ -760,12 +760,12 @@ begin {$ENDIF} // used units - UsesList:=Section.UsesList; - for i:=0 to UsesList.Count-1 do + UsesClause:=Section.UsesClause; + for i:=0 to length(UsesClause)-1 do begin - if TObject(UsesList[i]) is TPasModule then + if UsesClause[i].Module is TPasModule then begin - UsedModule:=TPasModule(UsesList[i]); + UsedModule:=TPasModule(UsesClause[i].Module); if ScopeModule=nil then // whole program analysis UseModule(UsedModule,paumAllExports) @@ -1563,21 +1563,21 @@ end; procedure TPasAnalyzer.EmitSectionHints(Section: TPasSection); var - UsesList: TFPList; i: Integer; UsedModule, aModule: TPasModule; + UsesClause: TPasUsesClause; begin {$IFDEF VerbosePasAnalyzer} writeln('TPasAnalyzer.EmitSectionHints ',GetElModName(Section)); {$ENDIF} // initialization, program or library sections aModule:=Section.GetModule; - UsesList:=Section.UsesList; - for i:=0 to UsesList.Count-1 do + UsesClause:=Section.UsesClause; + for i:=0 to length(UsesClause)-1 do begin - if TObject(UsesList[i]) is TPasModule then + if UsesClause[i].Module is TPasModule then begin - UsedModule:=TPasModule(UsesList[i]); + UsedModule:=TPasModule(UsesClause[i].Module); if CompareText(UsedModule.Name,'system')=0 then continue; if FindNode(UsedModule)=nil then EmitMessage(20170311191725,mtHint,nPAUnitNotUsed,sPAUnitNotUsed, diff --git a/packages/fcl-passrc/src/pparser.pp b/packages/fcl-passrc/src/pparser.pp index d3cdaff816..9d8b4d26dc 100644 --- a/packages/fcl-passrc/src/pparser.pp +++ b/packages/fcl-passrc/src/pparser.pp @@ -134,7 +134,7 @@ resourcestring type TPasScopeType = ( stModule, // e.g. unit, program, library - stUsesList, + stUsesClause, stTypeSection, stTypeDef, // e.g. a TPasType stConstDef, // e.g. a TPasConst @@ -312,7 +312,8 @@ type function DoParseExpression(AParent: TPaselement;InitExpr: TPasExpr=nil; AllowEqual : Boolean = True): TPasExpr; function DoParseConstValueExpression(AParent: TPasElement): TPasExpr; function CheckPackMode: TPackMode; - function CheckUseUnit(ASection: TPasSection; AUnitName : string): TPasElement; + function AddUseUnit(ASection: TPasSection; AUnitName : string; + NameExpr: TPasExpr; InFileExpr: TPrimitiveExpr): TPasElement; procedure CheckImplicitUsedUnits(ASection: TPasSection); // Overload handling procedure AddProcOrFunction(Decs: TPasDeclarations; AProc: TPasProcedure); @@ -2425,14 +2426,14 @@ begin end; procedure TPasParser.ParseOptionalUsesList(ASection: TPasSection); -// checks if next token is Uses keyword and read uses list +// checks if next token is Uses keyword and reads the uses list begin NextToken; if CurToken=tkuses then ParseUsesList(ASection) else begin CheckImplicitUsedUnits(ASection); - Engine.FinishScope(stUsesList,ASection); + Engine.FinishScope(stUsesClause,ASection); UngetToken; end; end; @@ -2852,38 +2853,64 @@ begin SetBlock(declNone); end; -function TPasParser.CheckUseUnit(ASection: TPasSection; AUnitName: string - ): TPasElement; +function TPasParser.AddUseUnit(ASection: TPasSection; AUnitName: string; + NameExpr: TPasExpr; InFileExpr: TPrimitiveExpr): TPasElement; - procedure CheckDuplicateInUsesList(AUnitName : string; UsesList: TFPList); + procedure CheckDuplicateInUsesList(AUnitName : string; UsesClause: TPasUsesClause); var i: Integer; begin - if UsesList=nil then exit; - for i:=0 to UsesList.Count-1 do - if CompareText(AUnitName,TPasModule(UsesList[i]).Name)=0 then + if UsesClause=nil then exit; + for i:=0 to length(UsesClause)-1 do + if CompareText(AUnitName,UsesClause[i].Name)=0 then ParseExc(nParserDuplicateIdentifier,SParserDuplicateIdentifier,[AUnitName]); end; +var + UnitRef: TPasElement; begin - if CompareText(AUnitName,CurModule.Name)=0 then - begin - // System is implicit, except when parsing system unit. - if CompareText(AUnitName,'System')=0 then - exit; - ParseExc(nParserDuplicateIdentifier,SParserDuplicateIdentifier,[AUnitName]); - end; - CheckDuplicateInUsesList(AUnitName,ASection.UsesList); - if ASection.ClassType=TImplementationSection then - CheckDuplicateInUsesList(AUnitName,CurModule.InterfaceSection.UsesList); + Result:=nil; + try + {$IFDEF VerbosePasParser} + writeln('TPasParser.AddUseUnit AUnitName=',AUnitName,' CurModule.Name=',CurModule.Name); + {$ENDIF} + if CompareText(AUnitName,CurModule.Name)=0 then + begin + if CompareText(AUnitName,'System')=0 then + exit; // for compatibility ignore implicit use of system in system + ParseExc(nParserDuplicateIdentifier,SParserDuplicateIdentifier,[AUnitName]); + end; + CheckDuplicateInUsesList(AUnitName,ASection.UsesClause); + if ASection.ClassType=TImplementationSection then + CheckDuplicateInUsesList(AUnitName,CurModule.InterfaceSection.UsesClause); - result := Engine.FindModule(AUnitName); // should we resolve module here when "IN" filename is not known yet? - if Assigned(result) then - result.AddRef - else - Result := TPasUnresolvedUnitRef(CreateElement(TPasUnresolvedUnitRef, - AUnitName, ASection)); - ASection.UsesList.Add(Result); + UnitRef := Engine.FindModule(AUnitName); // should we resolve module here when "IN" filename is not known yet? + if Assigned(UnitRef) then + UnitRef.AddRef + else + UnitRef := TPasUnresolvedUnitRef(CreateElement(TPasUnresolvedUnitRef, + AUnitName, ASection)); + + Result:=ASection.AddUnitToUsesList(AUnitName,NameExpr,InFileExpr,UnitRef); + if InFileExpr<>nil then + begin + if UnitRef is TPasModule then + begin + if TPasModule(UnitRef).Filename='' then + TPasModule(UnitRef).Filename:=InFileExpr.Value; + end + else if UnitRef is TPasUnresolvedUnitRef then + TPasUnresolvedUnitRef(UnitRef).FileName:=InFileExpr.Value; + end; + finally + if Result=nil then + begin + if NameExpr<>nil then + NameExpr.Release; + if InFileExpr<>nil then + InFileExpr.Release; + end; + end; end; procedure TPasParser.CheckImplicitUsedUnits(ASection: TPasSection); @@ -2894,43 +2921,60 @@ begin begin // load implicit units, like 'System' for i:=0 to ImplicitUses.Count-1 do - CheckUseUnit(ASection,ImplicitUses[i]); + AddUseUnit(ASection,ImplicitUses[i],nil,nil); end; end; // Starts after the "uses" token procedure TPasParser.ParseUsesList(ASection: TPasSection); var - AUnitName: String; - Element: TPasElement; + AUnitName, aName: String; + NameExpr: TPasExpr; + InFileExpr: TPrimitiveExpr; + FreeExpr: Boolean; begin CheckImplicitUsedUnits(ASection); - Repeat - AUnitName := ExpectIdentifier; - NextToken; - while CurToken = tkDot do - begin - ExpectIdentifier; - AUnitName := AUnitName + '.' + CurTokenString; + NameExpr:=nil; + InFileExpr:=nil; + FreeExpr:=true; + try + Repeat + FreeExpr:=true; + AUnitName := ExpectIdentifier; + NameExpr:=CreatePrimitiveExpr(ASection,pekString,AUnitName); NextToken; - end; - Element := CheckUseUnit(ASection,AUnitName); - if (CurToken=tkin) then + while CurToken = tkDot do begin - ExpectToken(tkString); - if (Element is TPasModule) and (TPasmodule(Element).filename='') then - TPasModule(Element).FileName:=curtokenstring - else if (Element is TPasUnresolvedUnitRef) then - TPasUnresolvedUnitRef(Element).FileName:=curtokenstring; - NextToken; + ExpectIdentifier; + aName:=CurTokenString; + AUnitName := AUnitName + '.' + aName; + AddToBinaryExprChain(NameExpr,CreatePrimitiveExpr(ASection,pekString,aName),eopSubIdent); + NextToken; end; + if (CurToken=tkin) then + begin + ExpectToken(tkString); + InFileExpr:=CreatePrimitiveExpr(ASection,pekString,CurTokenString); + NextToken; + end; + FreeExpr:=false; + AddUseUnit(ASection,AUnitName,NameExpr,InFileExpr); + InFileExpr:=nil; + NameExpr:=nil; - if Not (CurToken in [tkComma,tkSemicolon]) then - ParseExc(nParserExpectedCommaSemicolon,SParserExpectedCommaSemicolon); - Until (CurToken=tkSemicolon); + if Not (CurToken in [tkComma,tkSemicolon]) then + ParseExc(nParserExpectedCommaSemicolon,SParserExpectedCommaSemicolon); + Until (CurToken=tkSemicolon); + finally + if FreeExpr then + begin + NameExpr.Release; + InFileExpr.Release; + end; + end; - Engine.FinishScope(stUsesList,ASection); + Engine.FinishScope(stUsesClause,ASection); end; // Starts after the variable name diff --git a/packages/fcl-passrc/tests/tcmoduleparser.pas b/packages/fcl-passrc/tests/tcmoduleparser.pas index a18dbc404d..20f3a37157 100644 --- a/packages/fcl-passrc/tests/tcmoduleparser.pas +++ b/packages/fcl-passrc/tests/tcmoduleparser.pas @@ -15,7 +15,7 @@ Type private function GetIf: TInterfaceSection; function GetIm: TImplementationSection; - function CheckUnit(AIndex: Integer; const AName: String; AList: TFPList): TPasUnresolvedUnitRef; + function CheckUnit(AIndex: Integer; const AName: String; Section: TPasSection): TPasUnresolvedUnitRef; Protected Procedure ParseUnit; Procedure ParseProgram; @@ -98,18 +98,32 @@ begin end; function TTestModuleParser.CheckUnit(AIndex: Integer; const AName: String; - AList: TFPList) : TPasUnresolvedUnitRef; + Section: TPasSection): TPasUnresolvedUnitRef; Var C : string; + AList: TFPList; + Clause: TPasUsesClause; begin + Result:=nil; C:='Unit '+IntTostr(AIndex)+' '; + + AList:=Section.UsesList; + AssertNotNull('Have useslist',AList); if (AIndex>=AList.Count) then Fail(Format('Index %d larger than unit list count %d',[AIndex,AList.Count ])); AssertNotNull('Have pascal element',AList[AIndex]); AssertEquals(C+'Correct class',TPasUnresolvedUnitRef,TObject(AList[AIndex]).CLassType); - Result:=TPasUnresolvedUnitRef(AList[AIndex]); + + Clause:=Section.UsesClause; + if AIndex>=length(Clause) then + Fail(Format('Index %d larger than unit list count %d',[AIndex,length(Clause) ])); + AssertNotNull('Have pascal element',Clause[AIndex]); + AssertEquals(C+'Correct class',TPasUsesUnit,Clause[AIndex].ClassType); + AssertNotNull(C+'Has Module',Clause[AIndex].Module); + AssertEquals(C+'Correct module class',TPasUnresolvedUnitRef,Clause[AIndex].Module.ClassType); + Result:=TPasUnresolvedUnitRef(Clause[AIndex].Module); AssertEquals(C+'Unit name correct',AName,Result.Name); end; @@ -119,8 +133,10 @@ begin StartImplementation; ParseUnit; AssertEquals('Only system in interface units',1,IntfSection.UsesList.Count); - CheckUnit(0,'System',IntfSection.UsesList); + AssertEquals('Only system in interface units',1,length(IntfSection.UsesClause)); + CheckUnit(0,'System',IntfSection); AssertEquals('No implementation units',0,ImplSection.UsesList.Count); + AssertEquals('No implementation units',0,length(ImplSection.UsesClause)); end; procedure TTestModuleParser.TestUnitOneUses; @@ -130,9 +146,11 @@ begin StartImplementation; ParseUnit; AssertEquals('Two interface units',2,IntfSection.UsesList.Count); - CheckUnit(0,'System',IntfSection.UsesList); - CheckUnit(1,'a',IntfSection.UsesList); + AssertEquals('Two interface units',2,length(IntfSection.UsesClause)); + CheckUnit(0,'System',IntfSection); + CheckUnit(1,'a',IntfSection); AssertEquals('No implementation units',0,ImplSection.UsesList.Count); + AssertEquals('No implementation units',0,length(ImplSection.UsesClause)); end; procedure TTestModuleParser.TestUnitTwoUses; @@ -141,11 +159,13 @@ begin UsesClause(['a','b']); StartImplementation; ParseUnit; - AssertEquals('Two interface units',3,IntfSection.UsesList.Count); - CheckUnit(0,'System',IntfSection.UsesList); - CheckUnit(1,'a',IntfSection.UsesList); - CheckUnit(2,'b',IntfSection.UsesList); + AssertEquals('Three interface units',3,IntfSection.UsesList.Count); + AssertEquals('Three interface units',3,length(IntfSection.UsesClause)); + CheckUnit(0,'System',IntfSection); + CheckUnit(1,'a',IntfSection); + CheckUnit(2,'b',IntfSection); AssertEquals('No implementation units',0,ImplSection.UsesList.Count); + AssertEquals('No implementation units',0,length(ImplSection.UsesClause)); end; procedure TTestModuleParser.TestUnitOneImplUses; @@ -155,9 +175,11 @@ begin UsesClause(['a']); ParseUnit; AssertEquals('One implementation units',1,ImplSection.UsesList.Count); - CheckUnit(0,'a',ImplSection.UsesList); + AssertEquals('One implementation units',1,length(ImplSection.UsesClause)); + CheckUnit(0,'a',ImplSection); AssertEquals('Only system in interface units',1,IntfSection.UsesList.Count); - CheckUnit(0,'System',IntfSection.UsesList); + AssertEquals('Only system in interface units',1,length(IntfSection.UsesClause)); + CheckUnit(0,'System',IntfSection); end; procedure TTestModuleParser.TestUnitTwoImplUses; @@ -167,10 +189,12 @@ begin UsesClause(['a','b']); ParseUnit; AssertEquals('One interface unit',1,IntfSection.UsesList.Count); - CheckUnit(0,'System',IntfSection.UsesList); + AssertEquals('One interface unit',1,length(IntfSection.UsesClause)); + CheckUnit(0,'System',IntfSection); AssertEquals('Two implementation units',2,ImplSection.UsesList.Count); - CheckUnit(0,'a',ImplSection.UsesList); - CheckUnit(1,'b',ImplSection.UsesList); + AssertEquals('Two implementation units',2,length(ImplSection.UsesClause)); + CheckUnit(0,'a',ImplSection); + CheckUnit(1,'b',ImplSection); end; procedure TTestModuleParser.TestEmptyUnitInitialization; @@ -260,8 +284,9 @@ begin Add('begin'); ParseProgram; AssertEquals('Two interface units',2, PasProgram.ProgramSection.UsesList.Count); - CheckUnit(0,'System',PasProgram.ProgramSection.UsesList); - CheckUnit(1,'a',PasProgram.ProgramSection.UsesList); + AssertEquals('Two interface units',2, length(PasProgram.ProgramSection.UsesClause)); + CheckUnit(0,'System',PasProgram.ProgramSection); + CheckUnit(1,'a',PasProgram.ProgramSection); end; procedure TTestModuleParser.TestEmptyProgramUsesTwoUnits; @@ -270,9 +295,10 @@ begin Add('begin'); ParseProgram; AssertEquals('Three interface units',3, PasProgram.ProgramSection.UsesList.Count); - CheckUnit(0,'System',PasProgram.ProgramSection.UsesList); - CheckUnit(1,'a',PasProgram.ProgramSection.UsesList); - CheckUnit(2,'b',PasProgram.ProgramSection.UsesList); + AssertEquals('Three interface unit',3, length(PasProgram.ProgramSection.UsesClause)); + CheckUnit(0,'System',PasProgram.ProgramSection); + CheckUnit(1,'a',PasProgram.ProgramSection); + CheckUnit(2,'b',PasProgram.ProgramSection); end; procedure TTestModuleParser.TestEmptyProgramUsesUnitIn; @@ -284,11 +310,12 @@ begin UsesClause(['a in ''../a.pas''','b']); Add('begin'); ParseProgram; - AssertEquals('One interface unit',3, PasProgram.ProgramSection.UsesList.Count); - CheckUnit(0,'System',PasProgram.ProgramSection.UsesList); - U:=CheckUnit(1,'a',PasProgram.ProgramSection.UsesList); + AssertEquals('Three interface unit',3, PasProgram.ProgramSection.UsesList.Count); + AssertEquals('Three interface unit',3, length(PasProgram.ProgramSection.UsesClause)); + CheckUnit(0,'System',PasProgram.ProgramSection); + U:=CheckUnit(1,'a',PasProgram.ProgramSection); AssertEquals('Filename','''../a.pas''',U.FileName); - CheckUnit(2,'b',PasProgram.ProgramSection.UsesList); + CheckUnit(2,'b',PasProgram.ProgramSection); end; procedure TTestModuleParser.TestEmptyLibrary; @@ -305,8 +332,9 @@ begin ParseLibrary; AssertEquals('Correct class',TPasLibrary,Module.ClassType); AssertEquals('Two interface units',2, PasLibrary.LibrarySection.UsesList.Count); - CheckUnit(0,'System',PasLibrary.LibrarySection.UsesList); - CheckUnit(1,'a',PasLibrary.LibrarySection.UsesList); + AssertEquals('Two interface units',2, length(PasLibrary.LibrarySection.UsesClause)); + CheckUnit(0,'System',PasLibrary.LibrarySection); + CheckUnit(1,'a',PasLibrary.LibrarySection); end; procedure TTestModuleParser.TestEmptyLibraryExports; diff --git a/packages/fcl-passrc/tests/tcpassrcutil.pas b/packages/fcl-passrc/tests/tcpassrcutil.pas index 0462db7831..f85e917a47 100644 --- a/packages/fcl-passrc/tests/tcpassrcutil.pas +++ b/packages/fcl-passrc/tests/tcpassrcutil.pas @@ -16,7 +16,7 @@ type FAnalyser : TPasSrcAnalysis; FSrc : TStrings; FList : TStrings; - FStream: TmemoryStream; + FStream: TMemoryStream; protected procedure SetUp; override; procedure TearDown; override;