Browse Source

* Patch from Mattias Gaertner to check uses clause

git-svn-id: trunk@34205 -
michael 9 years ago
parent
commit
798b6d753a
1 changed files with 20 additions and 1 deletions
  1. 20 1
      packages/fcl-passrc/src/pparser.pp

+ 20 - 1
packages/fcl-passrc/src/pparser.pp

@@ -70,6 +70,7 @@ const
   nParserUnknownProcedureType = 2043;
   nParserUnknownProcedureType = 2043;
   nParserGenericArray1Element = 2044;
   nParserGenericArray1Element = 2044;
   nParserGenericClassOrArray = 2045;
   nParserGenericClassOrArray = 2045;
+  nParserDuplicateIdentifier = 2046;
 
 
 
 
 // resourcestring patterns of messages
 // resourcestring patterns of messages
@@ -119,6 +120,7 @@ resourcestring
   SParserUnknownProcedureType = 'Unknown procedure type "%d"';
   SParserUnknownProcedureType = 'Unknown procedure type "%d"';
   SParserGenericArray1Element = 'Generic arrays can have only 1 template element';
   SParserGenericArray1Element = 'Generic arrays can have only 1 template element';
   SParserGenericClassOrArray = 'Generic can only be used with classes or arrays';
   SParserGenericClassOrArray = 'Generic can only be used with classes or arrays';
+  SParserDuplicateIdentifier = 'Duplicate identifier "%s"';
 
 
 type
 type
   TPasParserLogHandler = Procedure (Sender : TObject; Const Msg : String) of object;
   TPasParserLogHandler = Procedure (Sender : TObject; Const Msg : String) of object;
@@ -600,6 +602,7 @@ end;
 
 
 function TPasTreeContainer.FindModule(const AName: String): TPasModule;
 function TPasTreeContainer.FindModule(const AName: String): TPasModule;
 begin
 begin
+  if AName='' then ;
   Result := nil;
   Result := nil;
 end;
 end;
 
 
@@ -2347,8 +2350,24 @@ end;
 // Starts after the "uses" token
 // Starts after the "uses" token
 procedure TPasParser.ParseUsesList(ASection: TPasSection);
 procedure TPasParser.ParseUsesList(ASection: TPasSection);
 
 
+  procedure CheckDuplicateInUsesList(AUnitName : string; UsesList: TFPList);
+  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
+        ParseExc(nParserDuplicateIdentifier,SParserDuplicateIdentifier,[AUnitName]);
+  end;
+
   function CheckUnit(AUnitName : string):TPasElement;
   function CheckUnit(AUnitName : string):TPasElement;
   begin
   begin
+    if CompareText(AUnitName,CurModule.Name)=0 then
+      ParseExc(nParserDuplicateIdentifier,SParserDuplicateIdentifier,[AUnitName]);
+    CheckDuplicateInUsesList(AUnitName,ASection.UsesList);
+    if ASection.ClassType=TImplementationSection then
+      CheckDuplicateInUsesList(AUnitName,CurModule.InterfaceSection.UsesList);
+
     result := Engine.FindModule(AUnitName);  // should we resolve module here when "IN" filename is not known yet?
     result := Engine.FindModule(AUnitName);  // should we resolve module here when "IN" filename is not known yet?
     if Assigned(result) then
     if Assigned(result) then
       result.AddRef
       result.AddRef
@@ -2371,7 +2390,7 @@ begin
     end;
     end;
 
 
   Repeat
   Repeat
-    AUnitName := ExpectIdentifier; 
+    AUnitName := ExpectIdentifier;
     NextToken;
     NextToken;
     while CurToken = tkDot do
     while CurToken = tkDot do
     begin
     begin