浏览代码

* Move finding unit to compiler instead of Compilerfile

git-svn-id: trunk@40446 -
michael 6 年之前
父节点
当前提交
99c5c79327
共有 1 个文件被更改,包括 189 次插入162 次删除
  1. 189 162
      packages/pastojs/src/pas2jscompiler.pp

+ 189 - 162
packages/pastojs/src/pas2jscompiler.pp

@@ -281,6 +281,13 @@ type
   end;
 
 
+  TFindUnitInfo = Record
+    FileName : String;
+    UnitName : String;
+    isPCU : Boolean;
+    isForeign : Boolean;
+  end;
+
   { TPas2jsCompilerFile }
 
   TPas2jsCompilerFile = class
@@ -551,6 +558,7 @@ type
     function IsDefined(const aName: String): boolean;
     procedure SetOption(Flag: TP2jsCompilerOption; Enable: boolean);
 
+    function GetUnitInfo(const UseUnitName, InFileName: String; PCUSupport: TPCUSupport): TFindUnitInfo;
     function FindUnitWithFile(PasFilename: string): TPas2jsCompilerFile;
     procedure LoadPasFile(UnitFilename, UseUnitName: string; out aFile: TPas2jsCompilerFile; isPCU : Boolean);
     Function FindUnitJSFileName(aFileName : String) : String;
@@ -1335,7 +1343,7 @@ begin
     Compiler.AddReadingModule(Self);
     PascalResolver.InterfaceOnly:=IsForeign;
 
-    if Assigned(PCUSupport) then
+    if IsUnitReadFromPCU then
       PCUSupport.ReadUnit
     else
     begin
@@ -1566,179 +1574,30 @@ end;
 
 function TPas2jsCompilerFile.OnResolverFindModule(const UseUnitName,
   InFilename: String; NameExpr, InFileExpr: TPasExpr): TPasModule;
-var
-  FoundPasFilename, FoundPasUnitName: string;
-  FoundPasIsForeign: Boolean;
-  FoundPCUFilename, FoundPCUUnitName: string;
-
-  procedure TryUnitName(const TestUnitName: string);
-  var
-    aFile: TPas2jsCompilerFile;
-  begin
-    if FoundPasFilename='' then
-    begin
-      // search loaded units
-      aFile:=Compiler.FindLoadedUnit(TestUnitName);
-      if aFile<>nil then
-      begin
-        FoundPasFilename:=aFile.PasFilename;
-        FoundPasUnitName:=TestUnitName;
-      end else begin
-        // search pas in unit path
-        FoundPasFilename:=Compiler.FileCache.FindUnitFileName(TestUnitName,'',FoundPasIsForeign);
-        if FoundPasFilename<>'' then
-          FoundPasUnitName:=TestUnitName;
-      end;
-    end;
-    if Assigned(PCUSupport) and (FoundPCUFilename='')  then
-    begin
-      FoundPCUFilename:=PCUSupport.FindPCU(TestUnitName);
-      if FoundPCUFilename<>'' then
-        FoundPCUUnitName:=TestUnitName;
-    end;
-  end;
 
 var
-  aNameSpace, DefNameSpace: String;
-  i: Integer;
   aFile: TPas2jsCompilerFile;
+  UnitInfo : TFindUnitInfo;
+
 begin
   Result:=nil;
+  aFile:=Nil;
+  // duplicate identifier or unit cycle
   if CompareText(ExtractFilenameOnly(PasFilename),UseUnitname)=0 then
-  begin
-    // duplicate identifier or unit cycle
     Parser.RaiseParserError(nUnitCycle,[UseUnitname]);
-  end;
-
-  FoundPasFilename:='';
-  FoundPasIsForeign:=false;
-  FoundPasUnitName:='';
-  FoundPCUFilename:='';
-  FoundPCUUnitName:='';
-  if (InFilename='') and (Pos('.',UseUnitname)<1) then
-  begin
-    // generic unit -> search with namespaces
-    // first the default program namespace
-    DefNameSpace:=Compiler.GetDefaultNamespace;
-    if DefNameSpace<>'' then
-      TryUnitName(DefNameSpace+'.'+UseUnitname);
-
-    if (FoundPasFilename='') or (FoundPCUFilename='') then
+  UnitInfo:=Compiler.GetUnitInfo(UseUnitName,InFileName,PCUSupport);
+  if UnitInfo.FileName<>'' then
     begin
-      // then the cmdline namespaces
-      for i:=0 to Compiler.FileCache.Namespaces.Count-1 do begin
-        aNameSpace:=Compiler.FileCache.Namespaces[i];
-        if aNameSpace='' then continue;
-        if SameText(aNameSpace,DefNameSpace) then continue;
-        TryUnitName(aNameSpace+'.'+UseUnitname);
-      end;
-    end;
-  end;
-
-  if FoundPasFilename='' then
-  begin
-    if InFilename='' then
-    begin
-      // search unitname in loaded units
-      aFile:=Compiler.FindLoadedUnit(UseUnitname);
-      if aFile<>nil then
-      begin
-        FoundPasFilename:=aFile.PasFilename;
-        FoundPasUnitName:=UseUnitName;
-      end;
-    end;
-    if FoundPasFilename='' then
-    begin
-      // search Pascal file
-      FoundPasFilename:=Compiler.FileCache.FindUnitFileName(UseUnitname,InFilename,FoundPasIsForeign);
-      if FoundPasFilename<>'' then
-        begin
-        if InFilename<>'' then
-          FoundPasUnitName:=ExtractFilenameOnly(InFilename)
-        else
-          FoundPasUnitName:=UseUnitName;
-        end
-      else if InFilename<>'' then
-        exit; // an in-filename unit source is missing -> stop
+    if UnitInfo.isPCU then
+      aFile:=LoadUsedUnit(UnitInfo.FileName,UnitInfo.UnitName,'',NameExpr,nil,false,True)
+    else
+      aFile:=LoadUsedUnit(UnitInfo.FileName,UnitInfo.UnitName,InFilename,NameExpr,InFileExpr,UnitInfo.IsForeign,False);
     end;
-  end;
-
-  if Assigned(PCUSupport) and (FoundPCUFilename='')  then
-  begin
-    FoundPCUFilename:=PCUSupport.FindPCU(UseUnitName);
-    FoundPCUUnitName:=UseUnitName;
-  end;
-
-  if (FoundPasFilename='') and (FoundPCUFilename<>'') then
-  begin
-    aFile:=LoadUsedUnit(FoundPCUFilename,FoundPCUUnitName,'',NameExpr,nil,false,True);
-    if aFile<>nil then
-      Result:=aFile.PasModule;
-    exit;
-  end;
-
-  if FoundPasFilename<>'' then
-  begin
-    // load unit
-    aFile:=LoadUsedUnit(FoundPasFilename,FoundPasUnitName,InFilename,
-                         NameExpr,InFileExpr,FoundPasIsForeign,False);
-    if aFile<>nil then
-      Result:=aFile.PasModule;
-  end;
+  if aFile<>nil then
+    Result:=aFile.PasModule;
   // if Result=nil resolver will give a nice error position
 end;
 
-function TPas2jsCompiler.ResolvedMainJSFile: string;
-
-Var
-  OP,UP : String;
-
-begin
-  OP:=FileCache.MainOutputPath;
-  UP:=FileCache.UnitOutputPath;
-  if MainJSFile='.' then
-    Result:=''
-  else begin
-    Result:=MainJSFile;
-    if Result<>'' then
-    begin
-      // has option -o
-      if ExtractFilePath(Result)='' then
-      begin
-        // -o<FileWithoutPath>
-        if OP<>'' then
-          Result:=OP+Result
-        else if UP<>'' then
-          Result:=UP+Result;
-      end;
-    end else begin
-      // no option -o
-      Result:=ChangeFileExt(MainSrcFile,'.js');
-      if OP<>'' then
-      begin
-        // option -FE and no -o => put into MainOutputPath
-        Result:=OP+ExtractFilename(Result)
-      end else if UP<>'' then
-      begin
-        // option -FU and no -o => put into UnitOutputPath
-        Result:=UP+ExtractFilename(Result)
-      end else begin
-        // no -FU and no -o => put into source directory
-      end;
-    end;
-  end;
-end;
-
-function TPas2jsCompiler.GetResolvedMainJSFile: string;
-
-begin
-  if not FIsMainJSFileResolved then
-    begin
-    FMainJSFileResolved:=ResolvedMainJSFile;
-    FIsMainJSFileResolved:=True;
-  end;
-  Result:=FMainJSFileResolved;
-end;
 
 
 function TPas2jsCompilerFile.LoadUsedUnit(const UseFilename, UseUnitname,
@@ -4886,5 +4745,173 @@ begin
     InsertFilenames.Delete(i);
 end;
 
+
+function TPas2jsCompiler.GetUnitInfo(const UseUnitName,InFileName : String; PCUSupport : TPCUSupport) : TFindUnitInfo;
+
+var
+  FoundPasFilename, FoundPasUnitName: string;
+  FoundPasIsForeign: Boolean;
+  FoundPCUFilename, FoundPCUUnitName: string;
+
+  procedure TryUnitName(const TestUnitName: string);
+  var
+    aFile: TPas2jsCompilerFile;
+  begin
+    if FoundPasFilename='' then
+    begin
+      // search loaded units
+      aFile:=FindLoadedUnit(TestUnitName);
+      if aFile<>nil then
+      begin
+        FoundPasFilename:=aFile.PasFilename;
+        FoundPasUnitName:=TestUnitName;
+      end else begin
+        // search pas in unit path
+        FoundPasFilename:=FileCache.FindUnitFileName(TestUnitName,'',FoundPasIsForeign);
+        if FoundPasFilename<>'' then
+          FoundPasUnitName:=TestUnitName;
+      end;
+    end;
+    if Assigned(PCUSupport) and (FoundPCUFilename='')  then
+    begin
+      FoundPCUFilename:=PCUSupport.FindPCU(TestUnitName);
+      if FoundPCUFilename<>'' then
+        FoundPCUUnitName:=TestUnitName;
+    end;
+  end;
+
+var
+  aFile : TPas2jsCompilerFile;
+  aNameSpace, DefNameSpace: String;
+  i: Integer;
+
+begin
+  Result:=Default(TFindUnitInfo);
+  FoundPasFilename:='';
+  FoundPasIsForeign:=false;
+  FoundPasUnitName:='';
+  FoundPCUFilename:='';
+  FoundPCUUnitName:='';
+  if (InFilename='') and (Pos('.',UseUnitname)<1) then
+  begin
+    // generic unit -> search with namespaces
+    // first the default program namespace
+    DefNameSpace:=GetDefaultNamespace;
+    if DefNameSpace<>'' then
+      TryUnitName(DefNameSpace+'.'+UseUnitname);
+
+    if (FoundPasFilename='') or (FoundPCUFilename='') then
+    begin
+      // then the cmdline namespaces
+      for i:=0 to FileCache.Namespaces.Count-1 do begin
+        aNameSpace:=FileCache.Namespaces[i];
+        if aNameSpace='' then continue;
+        if SameText(aNameSpace,DefNameSpace) then continue;
+        TryUnitName(aNameSpace+'.'+UseUnitname);
+      end;
+    end;
+  end;
+
+  if FoundPasFilename='' then
+  begin
+    if InFilename='' then
+    begin
+      // search unitname in loaded units
+      aFile:=FindLoadedUnit(UseUnitname);
+      if aFile<>nil then
+      begin
+        FoundPasFilename:=aFile.PasFilename;
+        FoundPasUnitName:=UseUnitName;
+      end;
+    end;
+    if FoundPasFilename='' then
+    begin
+      // search Pascal file
+      FoundPasFilename:=FileCache.FindUnitFileName(UseUnitname,InFilename,FoundPasIsForeign);
+      if FoundPasFilename<>'' then
+        begin
+        if InFilename<>'' then
+          FoundPasUnitName:=ExtractFilenameOnly(InFilename)
+        else
+          FoundPasUnitName:=UseUnitName;
+        end
+      else if InFilename<>'' then
+        exit; // an in-filename unit source is missing -> stop
+    end;
+  end;
+
+  if Assigned(PCUSupport) and (FoundPCUFilename='')  then
+  begin
+    FoundPCUFilename:=PCUSupport.FindPCU(UseUnitName);
+    FoundPCUUnitName:=UseUnitName;
+  end;
+  if (FoundPasFilename='') and (FoundPCUFilename<>'') then
+    begin
+    Result.FileName:=FoundPCUFilename;
+    Result.UnitName:=FoundPCUUnitName;
+    Result.isPCU:=True;
+    Result.isForeign:=False;
+    end;
+  if (FoundPasFileName<>'') then
+    begin
+    Result.FileName:=FoundPasFilename;
+    Result.UnitName:=FoundPasUnitName;
+    Result.isPCU:=False;
+    Result.isForeign:=FoundPasIsForeign;
+    end;
+end;
+
+function TPas2jsCompiler.ResolvedMainJSFile: string;
+
+Var
+  OP,UP : String;
+
+begin
+  OP:=FileCache.MainOutputPath;
+  UP:=FileCache.UnitOutputPath;
+  if MainJSFile='.' then
+    Result:=''
+  else begin
+    Result:=MainJSFile;
+    if Result<>'' then
+    begin
+      // has option -o
+      if ExtractFilePath(Result)='' then
+      begin
+        // -o<FileWithoutPath>
+        if OP<>'' then
+          Result:=OP+Result
+        else if UP<>'' then
+          Result:=UP+Result;
+      end;
+    end else begin
+      // no option -o
+      Result:=ChangeFileExt(MainSrcFile,'.js');
+      if OP<>'' then
+      begin
+        // option -FE and no -o => put into MainOutputPath
+        Result:=OP+ExtractFilename(Result)
+      end else if UP<>'' then
+      begin
+        // option -FU and no -o => put into UnitOutputPath
+        Result:=UP+ExtractFilename(Result)
+      end else begin
+        // no -FU and no -o => put into source directory
+      end;
+    end;
+  end;
+end;
+
+function TPas2jsCompiler.GetResolvedMainJSFile: string;
+
+begin
+  if not FIsMainJSFileResolved then
+    begin
+    FMainJSFileResolved:=ResolvedMainJSFile;
+    FIsMainJSFileResolved:=True;
+  end;
+  Result:=FMainJSFileResolved;
+end;
+
 end.