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

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.

#185

@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)
  #1      AnalysisTask.perform (package:analyzer/task/model.dart:229:7)
  #2      AnalysisDriver.performWorkItem (package:analyzer/src/task/driver.dart:276:10)
  #3      AnalysisDriver.computeResult (package:analyzer/src/task/driver.dart:109:18)
  #4      AnalysisContextImpl.computeResult (package:analyzer/src/context/context.dart:667:14)
  #5      AnalysisContextImpl.computeErrors (package:analyzer/src/context/context.dart:615:12)
  #6      AnalysisDriver.analyze (package:linter/src/analysis.dart:147:15)
  #7      DartLinter.lintFiles (package:linter/src/linter.dart:68:34)
  #8      testRule.<anonymous closure> (file:///usr/local/.../home/.../development/dart/linter/test/rule_test.dart:390:48)
  #9      InternalTestCase.run.<anonymous closure> (package:unittest/src/internal_test_case.dart:120:37)
  #10     _rootRunUnary (dart:async/zone.dart:958)
  #11     _CustomZone.runUnary (dart:async/zone.dart:837)
  #12     _FutureListener.handleValue (dart:async/future_impl.dart:131)
  #13     _Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:628)
  #14     _Future._propagateToListeners (dart:async/future_impl.dart:658)
  #15     _Future._completeWithValue (dart:async/future_impl.dart:468)
  #16     _Future._asyncComplete.<anonymous closure> (dart:async/future_impl.dart:519)
  #17     _rootRun (dart:async/zone.dart:950)
  #18     _CustomZone.run (dart:async/zone.dart:826)
  #19     _CustomZone.runGuarded (dart:async/zone.dart:724)
  #20     _CustomZone.bindCallback.<anonymous closure> (dart:async/zone.dart:751)
  #21     _microtaskLoop (dart:async/schedule_microtask.dart:41)
  #22     _startMicrotaskLoop (dart:async/schedule_microtask.dart:50)
  #23     _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:96)
  #24     _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)
  #1      Object.noSuchMethod (dart:core-patch/object_patch.dart:45)
  #2      findImplementedInterfaces (package:linter/src/util/dart_type_utilities.dart:33:16)
  #3      _implementsDartCoreSink (package:linter/src/rules/close_sinks.dart:90:5)
  #4      _buildVisitVariableCallback.<anonymous closure> (package:linter/src/util/leak_detector_visitor.dart:44:21)
  #5      Object&ListMixin.forEach (dart:collection/list.dart:63)
  #6      LeakDetectorVisitor.visitFieldDeclaration (package:linter/src/util/leak_detector_visitor.dart:36:27)
  #7      DelegatingAstVisitor.visitFieldDeclaration.<anonymous closure> (package:analyzer/dart/ast/visitor.dart:396:47)
  #8      List.forEach (dart:core-patch/growable_array.dart:254)
  #9      DelegatingAstVisitor.visitFieldDeclaration (package:analyzer/dart/ast/visitor.dart:396:16)
  #10     FieldDeclarationImpl.accept (package:analyzer/src/dart/ast/ast.dart:4274:15)
  #11     NodeListImpl.accept (package:analyzer/src/dart/ast/ast.dart:7681:20)
  #12     ClassDeclarationImpl.visitChildren (package:analyzer/src/dart/ast/ast.dart:1908:13)
  #13     DelegatingAstVisitor.visitClassDeclaration (package:analyzer/dart/ast/visitor.dart:224:10)
  #14     ClassDeclarationImpl.accept (package:analyzer/src/dart/ast/ast.dart:1840:15)
  #15     NodeListImpl.accept (package:analyzer/src/dart/ast/ast.dart:7681:20)
  #16     CompilationUnitImpl.visitChildren (package:analyzer/src/dart/ast/ast.dart:2439:21)
  #17     DelegatingAstVisitor.visitCompilationUnit (package:analyzer/dart/ast/visitor.dart:252:10)
  #18     CompilationUnitImpl.accept (package:analyzer/src/dart/ast/ast.dart:2432:15)
  #19     GenerateLintsTask.internalPerform (package:analyzer/src/task/dart.dart:2990:10)
  #20     AnalysisTask._safelyPerform (package:analyzer/task/model.dart:329:9)
  #21     AnalysisTask.perform (package:analyzer/task/model.dart:229:7)
  #22     AnalysisDriver.performWorkItem (package:analyzer/src/task/driver.dart:276:10)
  #23     AnalysisDriver.computeResult (package:analyzer/src/task/driver.dart:109:18)
  #24     AnalysisContextImpl.computeResult (package:analyzer/src/context/context.dart:667:14)
  #25     AnalysisContextImpl.computeErrors (package:analyzer/src/context/context.dart:615:12)
  #26     AnalysisDriver.analyze (package:linter/src/analysis.dart:147:15)
  #27     DartLinter.lintFiles (package:linter/src/linter.dart:68:34)
  #28     testRule.<anonymous closure> (file:///usr/local/.../home/.../development/dart/linter/test/rule_test.dart:390:48)
  #29     InternalTestCase.run.<anonymous closure> (package:unittest/src/internal_test_case.dart:120:37)
  #30     _rootRunUnary (dart:async/zone.dart:958)
  #31     _CustomZone.runUnary (dart:async/zone.dart:837)
  #32     _FutureListener.handleValue (dart:async/future_impl.dart:131)
  #33     _Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:628)
  #34     _Future._propagateToListeners (dart:async/future_impl.dart:658)
  #35     _Future._completeWithValue (dart:async/future_impl.dart:468)
  #36     _Future._asyncComplete.<anonymous closure> (dart:async/future_impl.dart:519)
  #37     _rootRun (dart:async/zone.dart:950)
  #38     _CustomZone.run (dart:async/zone.dart:826)
  #39     _CustomZone.runGuarded (dart:async/zone.dart:724)
  #40     _CustomZone.bindCallback.<anonymous closure> (dart:async/zone.dart:751)
  #41     _microtaskLoop (dart:async/schedule_microtask.dart:41)
  #42     _startMicrotaskLoop (dart:async/schedule_microtask.dart:50)
  #43     _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:96)
  #44     _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)
#1      _completeTests (package:unittest/unittest.dart:370:10)
#2      _runTest (package:unittest/unittest.dart:310:5)
#3      _nextTestCase (package:unittest/unittest.dart:256:3)
#4      Timer._createTimer.<anonymous closure> (dart:async-patch/timer_patch.dart:16)
#5      _Timer._runTimers (dart:isolate-patch/timer_impl.dart:385)
#6      _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:414)
#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 join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants