@@ -16,7 +16,7 @@ type templDocLazyLoader struct {
1616 templDocHooks templDocHooks
1717 packageLoader packageLoader
1818 fileReader fileReader
19- docsOpenCount map [string ]int
19+ pkgsRefCount map [string ]int
2020}
2121
2222type templDocHooks struct {
@@ -53,16 +53,18 @@ func newTemplDocLazyLoader(templDocHooks templDocHooks) templDocLazyLoader {
5353 return templDocLazyLoader {
5454 templDocHooks : templDocHooks ,
5555 packageLoader : goPackageLoader {},
56- docsOpenCount : make (map [string ]int ),
5756 fileReader : templFileReader {},
57+ pkgsRefCount : make (map [string ]int ),
5858 }
5959}
6060
6161// load loads all templ documents in the dependency graph topologically (dependencies are loaded before dependents).
6262func (l * templDocLazyLoader ) load (ctx context.Context , params * lsp.DidOpenTextDocumentParams ) error {
63- pkgs , err := l .packageLoader .load (params .TextDocument .URI .Filename ())
63+ filename := params .TextDocument .URI .Filename ()
64+
65+ pkgs , err := l .packageLoader .load (filename )
6466 if err != nil {
65- return fmt .Errorf ("load packages for file %q: %w" , params . TextDocument . URI . Filename () , err )
67+ return fmt .Errorf ("load packages for file %q: %w" , filename , err )
6668 }
6769
6870 for _ , pkg := range pkgs {
@@ -81,6 +83,11 @@ func (l *templDocLazyLoader) openTopologically(ctx context.Context, pkg *package
8183 }
8284 visited [pkg .PkgPath ] = true
8385
86+ if l .pkgsRefCount [pkg .PkgPath ] > 0 {
87+ l .pkgsRefCount [pkg .PkgPath ]++
88+ return nil
89+ }
90+
8491 for _ , imp := range pkg .Imports {
8592 if err := l .openTopologically (ctx , imp , visited ); err != nil {
8693 return fmt .Errorf ("open topologically %q: %w" , imp .PkgPath , err )
@@ -92,35 +99,34 @@ func (l *templDocLazyLoader) openTopologically(ctx context.Context, pkg *package
9299 continue
93100 }
94101
95- if l .docsOpenCount [otherFile ] == 0 {
96- text , err := l .fileReader .read (otherFile )
97- if err != nil {
98- return fmt .Errorf ("read file %q: %w" , otherFile , err )
99- }
100-
101- if err := l .templDocHooks .didOpen (ctx , & lsp.DidOpenTextDocumentParams {
102- TextDocument : lsp.TextDocumentItem {
103- URI : uri .File (otherFile ),
104- Text : string (text ),
105- Version : 1 ,
106- LanguageID : "go" ,
107- },
108- }); err != nil {
109- return fmt .Errorf ("did open file %q: %w" , otherFile , err )
110- }
102+ text , err := l .fileReader .read (otherFile )
103+ if err != nil {
104+ return fmt .Errorf ("read file %q: %w" , otherFile , err )
111105 }
112106
113- l .docsOpenCount [otherFile ]++
107+ if err := l .templDocHooks .didOpen (ctx , & lsp.DidOpenTextDocumentParams {
108+ TextDocument : lsp.TextDocumentItem {
109+ URI : uri .File (otherFile ),
110+ Text : string (text ),
111+ Version : 1 ,
112+ LanguageID : "go" ,
113+ },
114+ }); err != nil {
115+ return fmt .Errorf ("did open file %q: %w" , otherFile , err )
116+ }
114117 }
118+ l .pkgsRefCount [pkg .PkgPath ]++
115119
116120 return nil
117121}
118122
119123// unload unloads all templ documents in the dependency graph topologically (dependents are unloaded before dependencies).
120124func (l * templDocLazyLoader ) unload (ctx context.Context , params * lsp.DidCloseTextDocumentParams ) error {
121- pkgs , err := l .packageLoader .load (params .TextDocument .URI .Filename ())
125+ filename := params .TextDocument .URI .Filename ()
126+
127+ pkgs , err := l .packageLoader .load (filename )
122128 if err != nil {
123- return fmt .Errorf ("load packages for file %q: %w" , params . TextDocument . URI . Filename () , err )
129+ return fmt .Errorf ("load packages for file %q: %w" , filename , err )
124130 }
125131
126132 for _ , pkg := range pkgs {
@@ -139,25 +145,25 @@ func (l *templDocLazyLoader) closeTopologically(ctx context.Context, pkg *packag
139145 }
140146 visited [pkg .PkgPath ] = true
141147
148+ if l .pkgsRefCount [pkg .PkgPath ] > 1 {
149+ l .pkgsRefCount [pkg .PkgPath ]--
150+ return nil
151+ }
152+
142153 for _ , otherFile := range pkg .OtherFiles {
143154 if filepath .Ext (otherFile ) != ".templ" {
144155 continue
145156 }
146157
147- if l .docsOpenCount [otherFile ] > 1 {
148- l .docsOpenCount [otherFile ]--
149- continue
150- }
151-
152158 if err := l .templDocHooks .didClose (ctx , & lsp.DidCloseTextDocumentParams {
153159 TextDocument : lsp.TextDocumentIdentifier {
154160 URI : uri .File (otherFile ),
155161 },
156162 }); err != nil {
157163 return fmt .Errorf ("did close file %q: %w" , otherFile , err )
158164 }
159- delete (l .docsOpenCount , otherFile )
160165 }
166+ delete (l .pkgsRefCount , pkg .PkgPath )
161167
162168 for _ , imp := range pkg .Imports {
163169 if err := l .closeTopologically (ctx , imp , visited ); err != nil {
0 commit comments