Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ElementImpl equality operator false negatives #59947

Open
holzgeist opened this issue Jan 21, 2025 · 4 comments
Open

ElementImpl equality operator false negatives #59947

holzgeist opened this issue Jan 21, 2025 · 4 comments
Labels
area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. P2 A bug or feature request we're likely to work on

Comments

@holzgeist
Copy link

Hi there,

This is a followup to Milad-Akarie/injectable#491, which I traced down to the dart analyzer, specifically commit 6494efb

The injectable library referenced above uses the analyzer to perform dependency injection at build time.
However, since the update to analyzer 7.2.0, generation randomly fails due to incorrect in-equality.
Unfortunately I couldn't generate a minimal reproducible example yet, but it looks like that elements are cached somewhere, sometimes discarded and re-instantiated.

Printing a StackTrace from ElementImpl constructor showed that elements created in stack trace [1] only are working, even if there are multiple invocations of the constructor.
As soon as one invocations is using stack trace [2], generation fails.
Line numbers are from commit 5daaead

[1]

#0      new ElementImpl (package:analyzer/src/dart/element/element.dart:2602:24)
#1      new InterfaceElementImpl (package:analyzer/src/dart/element/element.dart)
#2      new ClassElementImpl (package:analyzer/src/dart/element/element.dart)
#3      ElementBuilder.visitClassDeclaration (package:analyzer/src/summary2/element_builder.dart:103:20)
#4      ClassDeclarationImpl.accept (package:analyzer/src/dart/ast/ast.dart:2891:50)
#5      ElementBuilder._visitPropertyFirst (package:analyzer/src/summary2/element_builder.dart:1856:14)
#6      ElementBuilder.buildDeclarationElements (package:analyzer/src/summary2/element_builder.dart:50:5)
#7      LibraryBuilder.buildElements (package:analyzer/src/summary2/library_builder.dart:210:22)
#8      Linker._computeLibraryScopes (package:analyzer/src/summary2/link.dart:321:15)
#9      Linker._buildOutlines.<anonymous closure> (package:analyzer/src/summary2/link.dart:243:15)
#10     OperationPerformanceImpl.runAsync (package:analyzer/src/util/performance/operation_performance.dart:174:29)
#11     Linker._buildOutlines (package:analyzer/src/summary2/link.dart:240:23)
#12     Linker.link.<anonymous closure> (package:analyzer/src/summary2/link.dart:125:13)
#13     OperationPerformanceImpl.runAsync (package:analyzer/src/util/performance/operation_performance.dart:174:29)
#14     Linker.link (package:analyzer/src/summary2/link.dart:124:23)
#15     link (package:analyzer/src/summary2/link.dart:43:16)
#16     LibraryContext.load.loadBundle.<anonymous closure> (package:analyzer/src/dart/analysis/library_context.dart:201:28)
#17     OperationPerformanceImpl.runAsync (package:analyzer/src/util/performance/operation_performance.dart:174:29)
#18     LibraryContext.load.loadBundle (package:analyzer/src/dart/analysis/library_context.dart:198:42)
<asynchronous suspension>
#19     LibraryContext.load.<anonymous closure> (package:analyzer/src/dart/analysis/library_context.dart:286:7)
<asynchronous suspension>
#20     PerformanceLog.runAsync (package:analyzer/src/dart/analysis/performance_logger.dart:50:14)
<asynchronous suspension>
#21     LibraryContext.load (package:analyzer/src/dart/analysis/library_context.dart:277:5)
<asynchronous suspension>
#22     AnalysisDriver._getUnitElement.<anonymous closure>.<anonymous closure> (package:analyzer/src/dart/analysis/driver.dart:1834:13)
<asynchronous suspension>
#23     OperationPerformanceImpl.runAsync (package:analyzer/src/util/performance/operation_performance.dart:174:14)
<asynchronous suspension>
#24     AnalysisDriver._getUnitElement.<anonymous closure> (package:analyzer/src/dart/analysis/driver.dart:1831:9)
<asynchronous suspension>
#25     OperationPerformanceImpl.runAsync (package:analyzer/src/util/performance/operation_performance.dart:174:14)
<asynchronous suspension>
#26     AnalysisDriver._getUnitElement (package:analyzer/src/dart/analysis/driver.dart:1822:5)
<asynchronous suspension>
#27     AnalysisDriver.performWork (package:analyzer/src/dart/analysis/driver.dart:1239:7)
<asynchronous suspension>
#28     AnalysisDriverScheduler._run (package:analyzer/src/dart/analysis/driver.dart:2438:7)
<asynchronous suspension>

[2]

#0      new ElementImpl (package:analyzer/src/dart/element/element.dart:2602:24)
#1      new InterfaceElementImpl (package:analyzer/src/dart/element/element.dart)
#2      LibraryReader._readClassElement (package:analyzer/src/summary2/bundle_reader.dart)
#3      LibraryReader._readClasses.<anonymous closure> (package:analyzer/src/summary2/bundle_reader.dart:820:14)
#4      SummaryDataReader.readTypedList.<anonymous closure> (package:analyzer/src/summary2/data_reader.dart:144:18)
#5      new _List.generate (dart:core-patch/array.dart:113:28)
#6      SummaryDataReader.readTypedList (package:analyzer/src/summary2/data_reader.dart:143:12)
#7      LibraryReader._readClasses (package:analyzer/src/summary2/bundle_reader.dart:819:35)
#8      LibraryReader._readUnitElement (package:analyzer/src/summary2/bundle_reader.dart:1879:5)
#9      LibraryReader.readElement (package:analyzer/src/summary2/bundle_reader.dart:702:47)
#10     LinkedElementFactory.createLibraryElementForReading (package:analyzer/src/summary2/linked_element_factory.dart:164:33)
#11     LinkedElementFactory.elementOfReference (package:analyzer/src/summary2/linked_element_factory.dart:214:14)
#12     LinkedElementFactory.elementOfReference (package:analyzer/src/summary2/linked_element_factory.dart:218:25)
#13     LibraryContext.computeUnitElement (package:analyzer/src/dart/analysis/library_context.dart:107:34)
#14     AnalysisDriver._getUnitElement.<anonymous closure> (package:analyzer/src/dart/analysis/driver.dart:1841:38)
<asynchronous suspension>
#15     OperationPerformanceImpl.runAsync (package:analyzer/src/util/performance/operation_performance.dart:174:14)
<asynchronous suspension>
#16     AnalysisDriver._getUnitElement (package:analyzer/src/dart/analysis/driver.dart:1822:5)
<asynchronous suspension>
#17     AnalysisDriver.performWork (package:analyzer/src/dart/analysis/driver.dart:1239:7)
<asynchronous suspension>
#18     AnalysisDriverScheduler._run (package:analyzer/src/dart/analysis/driver.dart:2438:7)
<asynchronous suspension>

If you have any pointers, I'm happy to provide more infos

@holzgeist holzgeist added the area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. label Jan 21, 2025
@bwilkerson bwilkerson added the P2 A bug or feature request we're likely to work on label Jan 21, 2025
@bwilkerson
Copy link
Member

@scheglov

@scheglov
Copy link
Contributor

Two elements are equal only if they are identical, i.e. are from the same AnalysisSession.

If there was a change to the file system, the analysis session is discarded, and elements are recreated.
After this they stop being identical to the elements from the previous session.

Try avoiding making changes to the file system while working on analysis of a codebase.

@holzgeist
Copy link
Author

@scheglov thanks for your answer.
Does any change in the file tree cause the session to be discarded? Or does it need to be in the file that contains an element?

I'm using freezed to generate some in-tree files which are included with part '... .freezed.dart';.
I'll check tomorrow if those run in parallel with the injectable library

@holzgeist
Copy link
Author

Hi @scheglov ,

I did some more digging on file changes. I mixed up repos, freezed isn't running on this code. According to inotifywait, there is no other file modified under lib except the dependency file which is written at the very end of the process.

Printing out the stack trace form the changeFile function in the AnalysisDriver shows random files getting changed during the process (random as in dart files from dependencies like /flutter_webrtc/lib/flutter_webrtc.dart):

#0      AnalysisDriver.changeFile (package:analyzer/src/dart/analysis/driver.dart:646:24)
#1      AnalysisDriverForPackageBuild.changeFile (package:analyzer/src/clients/build_resolvers/build_resolvers.dart:116:13)
#2      BuildAssetUriResolver.performResolve.<anonymous closure> (package:build_resolvers/src/build_asset_uri_resolver.dart:109:18)
#3      PerActionResolver._resolveIfNecessary.<anonymous closure>.<anonymous closure>.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:build_resolvers/src/resolver.dart:158:57)
#4      Pool.withResource (package:pool/pool.dart:127:28)
<asynchronous suspension>
#5      Pool.withResource (package:pool/pool.dart:127:14)
<asynchronous suspension>
#6      BuildAssetUriResolver.performResolve (package:build_resolvers/src/build_asset_uri_resolver.dart:106:5)
<asynchronous suspension>
#7      PerActionResolver._resolveIfNecessary.<anonymous closure> (package:build_resolvers/src/resolver.dart:143:11)
<asynchronous suspension>
#8      Pool.withResource (package:pool/pool.dart:127:14)
<asynchronous suspension>
#9      PerActionResolver.libraryFor.<anonymous closure> (package:build_resolvers/src/resolver.dart:126:9)
<asynchronous suspension>
#10     _Builder.build (package:source_gen/src/builder.dart:105:17)
<asynchronous suspension>
#11     runBuilder.buildForInput (package:build/src/generate/run_builder.dart:83:7)
<asynchronous suspension>
#12     Future.wait.<anonymous closure> (dart:async/future.dart:520:21)
<asynchronous suspension>
#13     scopeLogAsync.<anonymous closure> (package:build/src/builder/logging.dart:32:40)
<asynchronous suspension>

Does this sound like a problem in analyzer, build_runner or injectable?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. P2 A bug or feature request we're likely to work on
Projects
None yet
Development

No branches or pull requests

3 participants