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

support empty line comments #439

Closed
wants to merge 3 commits into from
Closed

Conversation

devoncarew
Copy link
Contributor

  • support empty line comments

This is to allow us to do things like:

// Copyright foo
// bar
// baz.

// Here's an additional file comment, but separated from the copyright header.

  • I’ve reviewed the contributor guide and applied the relevant portions to this PR.
Contribution guidelines:

Note that many Dart repos have a weekly cadence for reviewing PRs - please allow for some latency before initial review feedback.

Copy link

github-actions bot commented Nov 29, 2023

Package publishing

Package Version Status Publish tag (post-merge)
package:code_builder 4.8.1 ready to publish v4.8.1

Documentation at https://github.com/dart-lang/ecosystem/wiki/Publishing-automation.

@@ -45,7 +45,7 @@ void main() {
),
equalsDart(r'''
// Generated by foo!
//
Copy link
Collaborator

Choose a reason for hiding this comment

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

It seems like there should still be a way to get this output. Not sure how though... comments could be a list of nullable strings, and then null means something different from a blank string. Or a string that is only whitespace vs blank? I can't think of anything great...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't know that it's an important use case to support // lines? But the easiest and most clear way would likely be by supporting null strings.

An alternative approach would be to support line wrapping. So, multiple lines would mean multiple groups of comments, with each line automatically wrapped at ~80 cols.

I may implement the 1st solution as that seems like the smallest API diff.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Well, I don't have any examples, but I can imagine that it's more common to write a multi-paragraph comment (with blank // lines) than adjacent comments. Like if you have two paragraphs, or an example, like a code block separated from test.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This functionality is just affecting leading library line comments; mostly this is used for the ~3 line copyright headers for files.

The use case I have here is that I also want a // Generated by ... message at the top of the file. Currently this is emitted as part of the file copyright header, which is really not intended or desired. So, I want to go from:

// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
//
// Generated from Web IDL definitions.

to:

// Copyright (c) 2023, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Generated from Web IDL definitions.

(see https://github.com/dart-lang/web/blob/main/lib/src/dom/accelerometer.dart)

@devoncarew devoncarew requested a review from srawlins November 29, 2023 21:04
@devoncarew
Copy link
Contributor Author

ptal - updated to support both empty line comments as well as having groups of line comments

@srawlins
Copy link
Collaborator

I'm not a huge fan of the nullable String API, where null is sort of a "magic value." But I do think it is extremely pragmatic, functional, easy to understand...

I think I'd like another opinion like @natebosch before landing. If we go a nullable String API then it would be a pain to bring it back to a non-nullable String API. I'd almost prefer an API where "a comment" is a List<String> and a declaration, like a class, can have "plural comments", so a List<Comment>. But that might not be pragmatic, making everyone write so many nested structures just to add a little one-line comment somewhere...

@devoncarew
Copy link
Contributor Author

I'm not a huge fan of the nullable String API, where null is sort of a "magic value." But I do think it is extremely pragmatic, functional, easy to understand...

Agree w/ the nullability aspect; I think it doesn't improve the API. I've reverted back to a simplier form of this PR; happy to wait for an opinion from Nate.

For context, this PR is to improve the output of the files we generate for package:web.

@natebosch
Copy link
Contributor

I'd almost prefer an API where "a comment" is a List<String> and a declaration, like a class, can have "plural comments", so a List<Comment>. But that might not be pragmatic, making everyone write so many nested structures just to add a little one-line comment somewhere...

It's currently a bug to have a newline in a comment. We could allow this flexibility by splitting each String by newlines.

diff --git a/lib/src/emitter.dart b/lib/src/emitter.dart
index 591b992..fe4a898 100644
--- a/lib/src/emitter.dart
+++ b/lib/src/emitter.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:convert';
+
 import 'allocator.dart';
 import 'base.dart';
 import 'specs/class.dart';
@@ -479,8 +481,16 @@ class DartEmitter extends Object
     output ??= StringBuffer();
 
     if (spec.comments.isNotEmpty) {
-      spec.comments.map((line) => '// $line').forEach(output.writeln);
-      output.writeln();
+      for (final comment in spec.comments) {
+        for (final line in const LineSplitter().convert(comment)) {
+          if (line.isEmpty) {
+            output.writeln('//');
+          } else {
+            output.writeln('// $line');
+          }
+        }
+        output.writeln();
+      }
     }
 
     if (spec.ignoreForFile.isNotEmpty) {
diff --git a/test/specs/library_test.dart b/test/specs/library_test.dart
index 3c5502e..a525ae2 100644
--- a/test/specs/library_test.dart
+++ b/test/specs/library_test.dart
@@ -35,9 +35,7 @@ void main() {
         Library(
           (b) => b
             ..comments.addAll([
-              'Generated by foo!',
-              '',
-              'Avoid editing by hand.',
+              'Generated by foo!\n\nAvoid editing by hand.',
             ])
             ..body.add(
               Class((b) => b..name = 'Foo'),

I think this change, either my diff or as is in the PR, breaks the meaning of some usage in the same way. The line splitting gives users an escape hatch to get back to the old output if that is what they prefer.

@devoncarew
Copy link
Contributor Author

Thinking about the comments above:

  • I don't love changing the meaning of the current comments field (what this PR proposes and in Nate's idea above)
  • I think a green field solution would use something like the List<Comment> idea from above, but I don't think the new api / deprecated api dance for a new comments field is worth it for this feature
  • the use case I have is wanting both a file copyright section and a 'generated by' line for a generated file (and for that 2nd comment to be separate from the copyright one)

I have a separate PR now - #441 - which adds a new field for that specific use case - a generatedByComment field. This is not dissimilar to the existing Library.ignoreForFile field.

@devoncarew devoncarew closed this Dec 12, 2023
@devoncarew devoncarew deleted the support_empty_line_comments branch May 8, 2024 18:24
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants