Skip to content
This repository has been archived by the owner on Nov 20, 2024. It is now read-only.

Close instances of dart.core.Sink #241

Merged
merged 1 commit into from
Jun 13, 2016
Merged

Close instances of dart.core.Sink #241

merged 1 commit into from
Jun 13, 2016

Conversation

alexeieleusis
Copy link
Contributor

First attempt, I am facing a problem I don't know how to solve, which is I can't run the test, I get the following:

± |185_close_sinks {2} ✓| → dart test/util/solo_test.dart close_sinks
unittest-suite-wait-for-done
Task failed: GenerateLintsTask for source /home/alexeieleusis/development/dart/linter/test/rules/close_sinks.dart
ERROR: close_sinks
  Test failed: Caught AnalysisException: Cannot compute DART_ERRORS for /home/alexeieleusis/development/dart/linter/test/rules/close_sinks.dart
  Caused by Unexpected exception while performing GenerateLintsTask for source /home/alexeieleusis/development/dart/linter/test/rules/close_sinks.dart
...

If I instead run the linter directly, I get the expected lints

± |185_close_sinks {2} ✓| → dart ~/development/dart/linter/bin/linter.dart --lints=close_sinks test/rules/close_sinks.dart 
/home/alexeieleusis/development/dart/linter/test/rules/close_sinks.dart 10:10 [lint] Close instances of `dart.core.Sink`.
  IOSink _sinkA;
         ^^^^^^
/home/alexeieleusis/development/dart/linter/test/rules/close_sinks.dart 28:10 [lint] Close instances of `dart.core.Sink`.
  IOSink _sinkF; // LINT
         ^^^^^^

1 file analyzed, 2 issues found, in 2626 ms.

dart-lang/sdk#57281

@pq
Copy link
Member

pq commented May 16, 2016

First attempt, I am facing a problem I don't know how to solve, which is I can't run the test,

@alexeieleusis : are you still blocked here?

@alexeieleusis
Copy link
Contributor Author

@pq yes I am,, I think the problem is that the code test has an import and that code is not available/parsed when the test is running, hopefully is just a matter of running the test the right way or changing the test type. I uploaded a new commit rebased on the PR merged this morning.

@alexeieleusis
Copy link
Contributor Author

Thank you!

@alexeieleusis
Copy link
Contributor Author

I should also say, I sent #242 which refactors code in this PR just to provide visibility in the upcoming changes.

@pq
Copy link
Member

pq commented May 16, 2016

Could you paste the rest of the stack trace? I'm curious where the exception is originating. I'll try and repro later but in the meantime maybe something will jump out at a quick glance.

@alexeieleusis
Copy link
Contributor Author

alexeieleusis commented May 16, 2016

± |cancel_subscriptions → github_alexeieleusis ✓| → dart test/util/solo_test.dart close_sinks
unittest-suite-wait-for-done
Task failed: GenerateLintsTask for source /usr/local/.../home/.../development/dart/linter/test/rules/close_sinks.dart
ERROR: close_sinks
  Test failed: Caught AnalysisException: Cannot compute DART_ERRORS for /usr/local/.../home/.../development/dart/linter/test/rules/close_sinks.dart
  Caused by Unexpected exception while performing GenerateLintsTask for source /usr/local/.../home/.../development/dart/linter/test/rules/close_sinks.dart
  #0      AnalysisTask._safelyPerform (package:analyzer/task/model.dart:339:7)
  dart-lang/sdk#57147      AnalysisTask.perform (package:analyzer/task/model.dart:229:7)
  dart-lang/sdk#57148      AnalysisDriver.performWorkItem (package:analyzer/src/task/driver.dart:276:10)
  dart-lang/sdk#57149      AnalysisDriver.computeResult (package:analyzer/src/task/driver.dart:109:18)
  dart-lang/sdk#57150      AnalysisContextImpl.computeResult (package:analyzer/src/context/context.dart:667:14)
  dart-lang/linter#5      AnalysisContextImpl.computeErrors (package:analyzer/src/context/context.dart:615:12)
  dart-lang/sdk#57152      AnalysisDriver.analyze (package:linter/src/analysis.dart:147:15)
  dart-lang/linter#7      DartLinter.lintFiles (package:linter/src/linter.dart:68:34)
  dart-lang/sdk#57154      testRule.<anonymous closure> (file:///usr/local/.../home/.../development/dart/linter/test/rule_test.dart:390:48)
  dart-lang/sdk#57155      InternalTestCase.run.<anonymous closure> (package:unittest/src/internal_test_case.dart:120:37)
  dart-lang/sdk#57156     _rootRunUnary (dart:async/zone.dart:958)
  dart-lang/sdk#57157     _CustomZone.runUnary (dart:async/zone.dart:837)
  dart-lang/sdk#57158     _FutureListener.handleValue (dart:async/future_impl.dart:131)
  dart-lang/sdk#57159     _Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:628)
  dart-lang/sdk#57160     _Future._propagateToListeners (dart:async/future_impl.dart:658)
  dart-lang/sdk#57161     _Future._completeWithValue (dart:async/future_impl.dart:468)
  dart-lang/sdk#57162     _Future._asyncComplete.<anonymous closure> (dart:async/future_impl.dart:519)
  dart-lang/sdk#57163     _rootRun (dart:async/zone.dart:950)
  dart-lang/sdk#57164     _CustomZone.run (dart:async/zone.dart:826)
  dart-lang/sdk#57165     _CustomZone.runGuarded (dart:async/zone.dart:724)
  dart-lang/sdk#57166     _CustomZone.bindCallback.<anonymous closure> (dart:async/zone.dart:751)
  dart-lang/sdk#57167     _microtaskLoop (dart:async/schedule_microtask.dart:41)
  dart-lang/sdk#57168     _startMicrotaskLoop (dart:async/schedule_microtask.dart:50)
  dart-lang/sdk#57169     _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:96)
  dart-lang/sdk#57170     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:149)

  Caused by Class 'UndefinedTypeImpl' has no instance getter 'interfaces'.

  NoSuchMethodError: method not found: 'interfaces'
  Receiver: Instance of 'UndefinedTypeImpl'
  Arguments: []
  #0      Object._noSuchMethod (dart:core-patch/object_patch.dart:42)
  dart-lang/sdk#57147      Object.noSuchMethod (dart:core-patch/object_patch.dart:45)
  dart-lang/sdk#57148      findImplementedInterfaces (package:linter/src/util/dart_type_utilities.dart:33:16)
  dart-lang/sdk#57149      _implementsDartCoreSink (package:linter/src/rules/close_sinks.dart:90:5)
  dart-lang/sdk#57150      _buildVisitVariableCallback.<anonymous closure> (package:linter/src/util/leak_detector_visitor.dart:44:21)
  dart-lang/linter#5      Object&ListMixin.forEach (dart:collection/list.dart:63)
  dart-lang/sdk#57152      LeakDetectorVisitor.visitFieldDeclaration (package:linter/src/util/leak_detector_visitor.dart:36:27)
  dart-lang/linter#7      DelegatingAstVisitor.visitFieldDeclaration.<anonymous closure> (package:analyzer/dart/ast/visitor.dart:396:47)
  dart-lang/sdk#57154      List.forEach (dart:core-patch/growable_array.dart:254)
  dart-lang/sdk#57155      DelegatingAstVisitor.visitFieldDeclaration (package:analyzer/dart/ast/visitor.dart:396:16)
  dart-lang/sdk#57156     FieldDeclarationImpl.accept (package:analyzer/src/dart/ast/ast.dart:4274:15)
  dart-lang/sdk#57157     NodeListImpl.accept (package:analyzer/src/dart/ast/ast.dart:7681:20)
  dart-lang/sdk#57158     ClassDeclarationImpl.visitChildren (package:analyzer/src/dart/ast/ast.dart:1908:13)
  dart-lang/sdk#57159     DelegatingAstVisitor.visitClassDeclaration (package:analyzer/dart/ast/visitor.dart:224:10)
  dart-lang/sdk#57160     ClassDeclarationImpl.accept (package:analyzer/src/dart/ast/ast.dart:1840:15)
  dart-lang/sdk#57161     NodeListImpl.accept (package:analyzer/src/dart/ast/ast.dart:7681:20)
  dart-lang/sdk#57162     CompilationUnitImpl.visitChildren (package:analyzer/src/dart/ast/ast.dart:2439:21)
  dart-lang/sdk#57163     DelegatingAstVisitor.visitCompilationUnit (package:analyzer/dart/ast/visitor.dart:252:10)
  dart-lang/sdk#57164     CompilationUnitImpl.accept (package:analyzer/src/dart/ast/ast.dart:2432:15)
  dart-lang/sdk#57165     GenerateLintsTask.internalPerform (package:analyzer/src/task/dart.dart:2990:10)
  dart-lang/sdk#57166     AnalysisTask._safelyPerform (package:analyzer/task/model.dart:329:9)
  dart-lang/sdk#57167     AnalysisTask.perform (package:analyzer/task/model.dart:229:7)
  dart-lang/sdk#57168     AnalysisDriver.performWorkItem (package:analyzer/src/task/driver.dart:276:10)
  dart-lang/sdk#57169     AnalysisDriver.computeResult (package:analyzer/src/task/driver.dart:109:18)
  dart-lang/sdk#57170     AnalysisContextImpl.computeResult (package:analyzer/src/context/context.dart:667:14)
  dart-lang/sdk#57171     AnalysisContextImpl.computeErrors (package:analyzer/src/context/context.dart:615:12)
  dart-lang/sdk#57172     AnalysisDriver.analyze (package:linter/src/analysis.dart:147:15)
  dart-lang/linter#27     DartLinter.lintFiles (package:linter/src/linter.dart:68:34)
  dart-lang/sdk#57174     testRule.<anonymous closure> (file:///usr/local/.../home/.../development/dart/linter/test/rule_test.dart:390:48)
  dart-lang/sdk#57175     InternalTestCase.run.<anonymous closure> (package:unittest/src/internal_test_case.dart:120:37)
  dart-lang/sdk#57176     _rootRunUnary (dart:async/zone.dart:958)
  dart-lang/sdk#57177     _CustomZone.runUnary (dart:async/zone.dart:837)
  dart-lang/sdk#57178     _FutureListener.handleValue (dart:async/future_impl.dart:131)
  dart-lang/sdk#57179     _Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:628)
  dart-lang/sdk#57182     _Future._propagateToListeners (dart:async/future_impl.dart:658)
  dart-lang/sdk#57183     _Future._completeWithValue (dart:async/future_impl.dart:468)
  dart-lang/sdk#57184     _Future._asyncComplete.<anonymous closure> (dart:async/future_impl.dart:519)
  dart-lang/sdk#57185     _rootRun (dart:async/zone.dart:950)
  dart-lang/sdk#57186     _CustomZone.run (dart:async/zone.dart:826)
  dart-lang/sdk#57187     _CustomZone.runGuarded (dart:async/zone.dart:724)
  dart-lang/sdk#57188     _CustomZone.bindCallback.<anonymous closure> (dart:async/zone.dart:751)
  dart-lang/sdk#57189     _microtaskLoop (dart:async/schedule_microtask.dart:41)
  dart-lang/sdk#57190     _startMicrotaskLoop (dart:async/schedule_microtask.dart:50)
  dart-lang/linter#43     _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:96)
  dart-lang/sdk#57193     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:149)


  package:analyzer/src/context/context.dart 671:7      AnalysisContextImpl.computeResult
  package:analyzer/src/context/context.dart 615:12     AnalysisContextImpl.computeErrors
  package:linter/src/analysis.dart 147:15              AnalysisDriver.analyze
  package:linter/src/linter.dart 68:34                 DartLinter.lintFiles
  test/rule_test.dart 390:48                           testRule.<fn>
  package:unittest/src/internal_test_case.dart 120:37  InternalTestCase.run.<fn>
  dart:async/zone.dart 958                             _rootRunUnary
  dart:async/zone.dart 837                             _CustomZone.runUnary
  dart:async/future_impl.dart 131                      _FutureListener.handleValue
  dart:async/future_impl.dart 628                      _Future._propagateToListeners.handleValueCallback
  dart:async/future_impl.dart 658                      _Future._propagateToListeners
  dart:async/future_impl.dart 468                      _Future._completeWithValue
  dart:async/future_impl.dart 519                      _Future._asyncComplete.<fn>
  dart:async/zone.dart 950                             _rootRun
  dart:async/zone.dart 826                             _CustomZone.run
  dart:async/zone.dart 724                             _CustomZone.runGuarded
  dart:async/zone.dart 751                             _CustomZone.bindCallback.<fn>
  dart:async/schedule_microtask.dart 41                _microtaskLoop
  dart:async/schedule_microtask.dart 50                _startMicrotaskLoop
  dart:isolate-patch/isolate_patch.dart 96             _runPendingImmediateCallback
  dart:isolate-patch/isolate_patch.dart 149            _RawReceivePortImpl._handleMessage

0 PASSED, 0 FAILED, 1 ERRORS
Unhandled exception:
Exception: Some tests failed.
#0      SimpleConfiguration.onDone (package:unittest/src/simple_configuration.dart:197:9)
dart-lang/sdk#57147      _completeTests (package:unittest/unittest.dart:370:10)
dart-lang/sdk#57148      _runTest (package:unittest/unittest.dart:310:5)
dart-lang/sdk#57149      _nextTestCase (package:unittest/unittest.dart:256:3)
dart-lang/sdk#57150      Timer._createTimer.<anonymous closure> (dart:async-patch/timer_patch.dart:16)
dart-lang/linter#5      _Timer._runTimers (dart:isolate-patch/timer_impl.dart:385)
dart-lang/sdk#57152      _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:414)
dart-lang/linter#7      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:148)

@pq
Copy link
Member

pq commented May 16, 2016

Thanks!

This is interesting:

Caused by Class 'UndefinedTypeImpl' has no instance getter 'interfaces'.

On a quick glance, I see interfaces defined on InterfaceType but not on UndefinedTypeImpl... Maybe it was moved?

@alexeieleusis
Copy link
Contributor Author

Curious on why it does not happen when running the linter itself? I thought it was because dart.io is available there. Do you think this is something the rule should guard against?

@pq
Copy link
Member

pq commented May 17, 2016

OK, so that is odd. Really not sure what's happening... I'll try and look later.

@alexeieleusis
Copy link
Contributor Author

Pushed a new commit with a similar approach to the one in 8fa9ddd. I think this is now in a state where we can start discussing the rule and tests.


const _details = r'''

**DO** Invoke `close` on instances of `dart.core.Sink` to avoid memory leaks and
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Invoke => invoke.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@bwilkerson
Copy link
Member

I have concerns about false positives from this lint. If a class has a Sink and uses a local variable (of type Sink) in a method that creates the sink, then the local variable will be flagged, even though the sink might well be closed in some other method. If a class takes a Sink in the constructor because the Sink is owned by some other object and only used by that class, then the field will be flagged even though the class shouldn't close the sink.

You can reduce the number of false positives with some heuristics. For example, if a Sink is created in and returned from a method then it clearly shouldn't be closed in that method. Of if a field is initialized to an instance that might have come from outside the class then it probably shouldn't be closed in that class.

Of course, the only way to be really accurate with a rule like this is to do some data flow analysis, but that's more work that I would recommend at this point. As a fun challenge, try thinking of some valid code patterns that this rule would currently flag and see whether you can think of heuristics that would avoid the false positives.

@alexeieleusis
Copy link
Contributor Author

I think most of the false positives are discarded now, still need to address some of the previous comments, but I think this is looking better now.

@alexeieleusis
Copy link
Contributor Author

I think all comments are addressed now :)

@bwilkerson
Copy link
Member

lgtm

@pq pq merged commit e9d3470 into dart-lang:master Jun 13, 2016
@alexeieleusis alexeieleusis deleted the 185_close_sinks branch June 13, 2016 21:52
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants