Переглянути джерело

pas2js: search no namespace, cmd line namespaces, default prg namespace, issue #37206

git-svn-id: trunk@45650 -
Mattias Gaertner 5 роки тому
батько
коміт
8b84d925fb

+ 26 - 20
packages/pastojs/src/pas2jscompiler.pp

@@ -5185,10 +5185,11 @@ var
   FoundPasIsForeign: Boolean;
   FoundPCUFilename, FoundPCUUnitName: string;
 
-  procedure TryUnitName(const TestUnitName: string);
+  function TryUnitName(const TestUnitName: string): boolean;
   var
     aFile: TPas2jsCompilerFile;
   begin
+    writeln('AAA1 TryUnitName ',TestUnitName);
     if FoundPasFilename='' then
     begin
       // search loaded units
@@ -5220,6 +5221,9 @@ var
       if FoundPCUFilename<>'' then
         FoundPCUUnitName:=TestUnitName;
     end;
+
+    Result:=(FoundPasFilename<>'')
+        and (not Assigned(PCUSupport) or (FoundPCUFilename<>''));
   end;
 
 var
@@ -5227,7 +5231,7 @@ var
   i: Integer;
 
 begin
-  //writeln('TPas2jsCompiler.GetUnitInfo ',UseUnitName,' in=',InFileName,' ',GetObjName(PCUSupport));
+  writeln('TPas2jsCompiler.GetUnitInfo ',UseUnitName,' in=',InFileName,' ',GetObjName(PCUSupport));
   Result:=Default(TFindUnitInfo);
   FoundPasFilename:='';
   FoundPasIsForeign:=false;
@@ -5239,32 +5243,34 @@ begin
   begin
     CheckUnitAlias(UseUnitName);
 
-    if Pos('.',UseUnitname)<1 then
+    // first search with name as written in module
+    if not TryUnitName(UseUnitname) then
     begin
-      // generic unit name -> search with namespaces
-      // first the default program namespace
-      DefNameSpace:=GetDefaultNamespace;
-      if DefNameSpace<>'' then
-        TryUnitName(DefNameSpace+'.'+UseUnitname);
-
-      if (FoundPasFilename='') or (FoundPCUFilename='') then
+      if Pos('.',UseUnitname)<1 then
       begin
-        // then the cmdline namespaces
+        // generic unit name -> search with namespaces
+        // first the cmdline namespaces
         for i:=0 to Namespaces.Count-1 do
         begin
           aNameSpace:=Namespaces[i];
           if aNameSpace='' then continue;
-          if SameText(aNameSpace,DefNameSpace) then continue;
-          TryUnitName(aNameSpace+'.'+UseUnitname);
+          if TryUnitName(aNameSpace+'.'+UseUnitname) then break;
         end;
-      end;
-    end;
 
-    if (FoundPasFilename='') or (FoundPCUFilename='') then
-    begin
-      // search unitname
-      TryUnitName(UseUnitname);
-    end;
+        if (FoundPasFilename='') or (FoundPCUFilename='') then
+        begin
+          // then the default program namespace
+          DefNameSpace:=GetDefaultNamespace;
+          if DefNameSpace<>'' then
+          begin
+            i:=Namespaces.Count-1;
+            while (i>=0) and not SameText(Namespaces[i],DefNameSpace) do dec(i);
+            if i<0 then
+              TryUnitName(DefNameSpace+'.'+UseUnitname);
+          end;
+        end;
+      end;
+    end
   end else begin
     // search Pascal file with InFilename
     FoundPasFilename:=FS.FindUnitFileName(UseUnitname,InFilename,ModuleDir,FoundPasIsForeign);

+ 88 - 0
packages/pastojs/tests/tcunitsearch.pas

@@ -154,6 +154,12 @@ type
 
     procedure TestUS_UseUnitTwiceFail;
     procedure TestUS_UseUnitTwiceViaNameSpace;
+
+    // namespace
+    Procedure TestDefaultNameSpaceLast;
+    Procedure TestDefaultNameSpaceAfterNameSpace;
+    Procedure TestNoNameSpaceBeforeDefaultNameSpace;
+    Procedure TestNoNameSpaceAndDefaultNameSpace;
   end;
 
 function LinesToStr(const Lines: array of string): string;
@@ -843,6 +849,88 @@ begin
   Compile(['test1.pas','-FNsub','-Jc']);
 end;
 
+procedure TTestCLI_UnitSearch.TestDefaultNameSpaceLast;
+begin
+  AddUnit('system.pp',[''],['']);
+  AddUnit('Unit2.pas',
+    ['var i: longint;'],
+    ['']);
+  AddUnit('NS1.Unit2.pas',
+    ['var j: longint;'],
+    ['']);
+  AddFile('test1.pas',[
+    'uses unIt2;',
+    'var',
+    '  k: longint;',
+    'begin',
+    '  k:=i;',
+    'end.']);
+  Compile(['test1.pas','','-Jc']);
+end;
+
+procedure TTestCLI_UnitSearch.TestDefaultNameSpaceAfterNameSpace;
+begin
+  AddUnit('system.pp',[''],['']);
+  AddUnit('prg.Unit2.pas',
+    ['var j: longint;'],
+    ['']);
+  AddUnit('sub.Unit2.pas',
+    ['var i: longint;'],
+    ['']);
+  AddFile('prg.test1.pas',[
+    'uses unIt2;',
+    'var',
+    '  k: longint;',
+    'begin',
+    '  k:=i;',
+    'end.']);
+  Compile(['prg.test1.pas','-FNsub','-Jc']);
+end;
+
+procedure TTestCLI_UnitSearch.TestNoNameSpaceBeforeDefaultNameSpace;
+begin
+  AddUnit('system.pp',[''],['']);
+  AddUnit('prg.Unit2.pas',
+    ['var j: longint;'],
+    ['']);
+  AddUnit('Unit2.pas',
+    ['var i: longint;'],
+    ['']);
+  AddFile('prg.test1.pas',[
+    'uses unIt2;',
+    'var',
+    '  k: longint;',
+    'begin',
+    '  k:=i;',
+    'end.']);
+  Compile(['prg.test1.pas','','-Jc']);
+end;
+
+procedure TTestCLI_UnitSearch.TestNoNameSpaceAndDefaultNameSpace;
+begin
+  AddUnit('system.pp',[''],['']);
+  AddUnit('UnitA.pas',
+    ['type TBool = boolean;'],
+    ['']);
+  AddUnit('ThirdParty.UnitB.pas',
+    ['uses UnitA;',
+     'type TAlias = TBool;'],
+    ['']);
+  AddUnit('MyProject.UnitA.pas',
+    [
+    'uses ThirdParty.UnitB;',
+    'var a: TAlias;'],
+    ['']);
+  AddFile('MyProject.Main.pas',[
+    'uses MyProject.UnitA;',
+    'var',
+    '  b: boolean;',
+    'begin',
+    '  b:=a;',
+    'end.']);
+  Compile(['MyProject.Main.pas','','-Jc']);
+end;
+
 Initialization
   RegisterTests([TTestCLI_UnitSearch]);
 end.