Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 3.1.2-wip

* Support dot shorthand syntax.
* Enable language version 3.10.

## 3.1.1

* Update to latest analyzer and enable language version 3.9.
Expand Down
2 changes: 1 addition & 1 deletion lib/src/cli/formatter_options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import 'show.dart';
import 'summary.dart';

// Note: The following line of code is modified by tool/grind.dart.
const dartStyleVersion = '3.1.1';
const dartStyleVersion = '3.1.2-wip';

/// Global options parsed from the command line that affect how the formatter
/// produces and uses its outputs.
Expand Down
9 changes: 5 additions & 4 deletions lib/src/dart_formatter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/analysis/utilities.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/diagnostic/diagnostic.dart';
import 'package:analyzer/error/error.dart';
// ignore: implementation_imports
import 'package:analyzer/src/dart/scanner/scanner.dart';
Expand Down Expand Up @@ -34,7 +35,7 @@ final RegExp _widthCommentPattern = RegExp(r'^// dart format width=(\d+)$');
final class DartFormatter {
/// The latest Dart language version that can be parsed and formatted by this
/// version of the formatter.
static final latestLanguageVersion = Version(3, 9, 0);
static final latestLanguageVersion = Version(3, 10, 0);

/// The latest Dart language version that will be formatted using the older
/// "short" style.
Expand Down Expand Up @@ -176,7 +177,7 @@ final class DartFormatter {
// Throw if there are syntactic errors.
var syntacticErrors =
parseResult.errors.where((error) {
return error.errorCode.type == ErrorType.SYNTACTIC_ERROR;
return error.diagnosticCode.type == DiagnosticType.SYNTACTIC_ERROR;
}).toList();
if (syntacticErrors.isNotEmpty) {
throw FormatterException(syntacticErrors);
Expand All @@ -194,11 +195,11 @@ final class DartFormatter {
var token = node.endToken.next!;
if (token.type != TokenType.CLOSE_CURLY_BRACKET) {
var stringSource = StringSource(text, source.uri);
var error = AnalysisError.tmp(
var error = Diagnostic.tmp(
source: stringSource,
offset: token.offset - inputOffset,
length: math.max(token.length, 1),
errorCode: ParserErrorCode.UNEXPECTED_TOKEN,
diagnosticCode: ParserErrorCode.UNEXPECTED_TOKEN,
arguments: [token.lexeme],
);
throw FormatterException([error]);
Expand Down
6 changes: 3 additions & 3 deletions lib/src/exceptions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
// 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 'package:analyzer/error/error.dart';
import 'package:analyzer/diagnostic/diagnostic.dart';
import 'package:source_span/source_span.dart';

/// Thrown when one or more errors occurs while parsing the code to be
/// formatted.
final class FormatterException implements Exception {
/// The [AnalysisError]s that occurred.
final List<AnalysisError> errors;
/// The [Diagnostic]s that occurred.
final List<Diagnostic> errors;

/// Creates a new FormatterException with an optional error [message].
const FormatterException(this.errors);
Expand Down
33 changes: 29 additions & 4 deletions lib/src/front_end/ast_node_visitor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,7 @@ final class AstNodeVisitor extends ThrowingAstVisitor<void> with PieceFactory {

// The name of the type being constructed.
var type = node.type;
pieces.token(type.name2);
pieces.token(type.name);
pieces.visit(type.typeArguments);
pieces.token(type.question);

Expand Down Expand Up @@ -589,6 +589,31 @@ final class AstNodeVisitor extends ThrowingAstVisitor<void> with PieceFactory {
pieces.token(node.semicolon);
}

@override
void visitDotShorthandConstructorInvocation(
DotShorthandConstructorInvocation node,
) {
pieces.modifier(node.constKeyword);
pieces.token(node.period);
pieces.visit(node.constructorName);
pieces.visit(node.typeArguments);
pieces.visit(node.argumentList);
}

@override
void visitDotShorthandInvocation(DotShorthandInvocation node) {
pieces.token(node.period);
pieces.visit(node.memberName);
pieces.visit(node.typeArguments);
pieces.visit(node.argumentList);
}

@override
void visitDotShorthandPropertyAccess(DotShorthandPropertyAccess node) {
pieces.token(node.period);
pieces.visit(node.propertyName);
}

@override
void visitDottedName(DottedName node) {
writeDotted(node.components);
Expand Down Expand Up @@ -1229,7 +1254,7 @@ final class AstNodeVisitor extends ThrowingAstVisitor<void> with PieceFactory {

// The type being constructed.
var type = constructor.type;
pieces.token(type.name2);
pieces.token(type.name);
pieces.visit(type.typeArguments);

// If this is a named constructor call, the name.
Expand Down Expand Up @@ -1334,7 +1359,7 @@ final class AstNodeVisitor extends ThrowingAstVisitor<void> with PieceFactory {
void visitLibraryDirective(LibraryDirective node) {
pieces.withMetadata(node.metadata, () {
pieces.token(node.libraryKeyword);
pieces.visit(node.name2, spaceBefore: true);
pieces.visit(node.name, spaceBefore: true);
pieces.token(node.semicolon);
});
}
Expand Down Expand Up @@ -1536,7 +1561,7 @@ final class AstNodeVisitor extends ThrowingAstVisitor<void> with PieceFactory {
void visitNamedType(NamedType node) {
pieces.token(node.importPrefix?.name);
pieces.token(node.importPrefix?.period);
pieces.token(node.name2);
pieces.token(node.name);
pieces.visit(node.typeArguments);
pieces.token(node.question);
}
Expand Down
8 changes: 3 additions & 5 deletions lib/src/short/source_visitor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1970,9 +1970,7 @@ final class SourceVisitor extends ThrowingAstVisitor {
_visitDirectiveMetadata(node);
_simpleStatement(node, () {
token(node.libraryKeyword);
if (node.name2 != null) {
visit(node.name2, before: space);
}
if (node.name case var name?) visit(name, before: space);
});
}

Expand Down Expand Up @@ -2184,10 +2182,10 @@ final class SourceVisitor extends ThrowingAstVisitor {
token(importPrefix.name);
soloZeroSplit();
token(importPrefix.period);
token(node.name2);
token(node.name);
builder.endSpan();
} else {
token(node.name2);
token(node.name);
}

visit(node.typeArguments);
Expand Down
4 changes: 2 additions & 2 deletions pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: dart_style
# Note: See tool/grind.dart for how to bump the version.
version: 3.1.1
version: 3.1.2-wip
description: >-
Opinionated, automatic Dart source code formatter.
Provides an API and a CLI tool.
Expand All @@ -9,7 +9,7 @@ environment:
sdk: ^3.7.0

dependencies:
analyzer: ^7.5.2
analyzer: ^8.0.0
args: ">=1.0.0 <3.0.0"
collection: "^1.17.0"
package_config: ^2.1.0
Expand Down
77 changes: 77 additions & 0 deletions test/tall/invocation/dot_shorthand.stmt
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
40 columns |
(experiment dot-shorthands)
>>> Getter.
variable = . getter;
<<< 3.9
variable = .getter;
>>> Method call with unsplit arguments.
variable = .method(1,x:2,3,y:4);
<<< 3.9
variable = .method(1, x: 2, 3, y: 4);
>>> Method call with split arguments.
variable = .method(one, x: two, three, y: four);
<<< 3.9
variable = .method(
one,
x: two,
three,
y: four,
);
>>> Generic method call.
variable = . method < int , String > ( ) ;
<<< 3.9
variable = .method<int, String>();
>>> Constructor.
variable = .new(1);
<<< 3.9
variable = .new(1);
>>> Const constructor.
variable = const . new ( );
<<< 3.9
variable = const .new();
>>> Const named constructor.
variable = const . named ( );
<<< 3.9
variable = const .named();
>>> Unsplit selector chain.
v = . property . method() . x . another();
<<< 3.9
v = .property.method().x.another();
>>> Split selector chain on shorthand getter.
variable = .shorthand.method().another().third();
<<< 3.9
variable = .shorthand
.method()
.another()
.third();
>>> Split selector chain on shorthand method.
variable = .shorthand().method().getter.another().third();
<<< 3.9
variable = .shorthand()
.method()
.getter
.another()
.third();
>>> Split in shorthand method call argument list.
context(.shorthand(argument, anotherArgument, thirdArgument)
.chain().another().third().fourthOne());
<<< 3.9
context(
.shorthand(
argument,
anotherArgument,
thirdArgument,
)
.chain()
.another()
.third()
.fourthOne(),
);
>>> Nested call.
.method(.getter,.method(.new(.new())),const.ctor());
<<<
.method(
.getter,
.method(.new(.new())),
const .ctor(),
);
26 changes: 26 additions & 0 deletions test/tall/invocation/dot_shorthand_comment.stmt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
40 columns |
(experiment dot-shorthands)
>>> Line comment after dot.
variable = . // Comment.
whoDoesThis();
<<< 3.9
variable =
. // Comment.
whoDoesThis();
>>> Block comment after dot.
variable = ./* Comment. */whoDoesThis();
<<< 3.9
variable =
. /* Comment. */ whoDoesThis();
>>> Line comment after `const`.
variable = const // Comment.
. whoDoesThis();
<<< 3.9
variable =
const // Comment.
.whoDoesThis();
>>> Block comment after `const`.
variable = const/* Comment. */.whoDoesThis();
<<< 3.9
variable =
const /* Comment. */ .whoDoesThis();