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

Update keyword list #5681

Merged
merged 1 commit into from
Apr 5, 2024
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
207 changes: 207 additions & 0 deletions src/_data/keywords.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
- term: 'abstract'
link: /language/class-modifiers#abstract
type: bit
- term: 'as'
link: /language/operators#type-test-operators
type: bit
- term: 'assert'
link: /language/error-handling#assert
type: reserved
- term: 'async'
link: /language/async
type: context
Copy link
Member

Choose a reason for hiding this comment

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

async is one of those identifiers that occur verbatim in a grammar rule, but there are no restrictions on the use of this identifier (it can be the name of a variable, a type, an import prefix, anything).

We need a separate category for these identifiers. I'll use nothing as a strawman here, because there's nothing special about these words. They will be recognized as being a structural part of certain syntactic forms, not just as the name of a declared entity (like other identifiers).

Suggested change
type: context
type: nothing

I'm using the same type in several cases below, for the same reason.

- term: 'await'
link: /language/async
type: context
- term: 'base'
link: /language/class-modifiers#base
type: bit
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
type: bit
type: nothing

- term: 'break'
link: /language/loops#break-and-continue
type: reserved
- term: 'case'
link: /language/branches#switch
type: reserved
- term: 'catch'
link: /language/error-handling#catch
type: reserved
- term: 'class'
link: /language/classes#instance-variables
type: reserved
- term: 'const'
link: /language/variables#final-and-const
type: reserved
- term: 'continue'
link: /language/loops#break-and-continue
type: reserved
- term: 'covariant'
link: /guides/language/sound-problems#the-covariant-keyword
type: context
Copy link
Member

Choose a reason for hiding this comment

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

covariant is a built-in identifier

Suggested change
type: context
type: bit

- term: 'default'
link: /language/branches#switch
type: reserved
- term: 'deferred'
link: /language/libraries#lazily-loading-a-library
type: bit
- term: 'do'
link: /language/loops#while-and-do-while
type: reserved
- term: 'dynamic'
link: /language#important-concepts
type: reserved
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
type: reserved
type: bit

- term: 'else'
link: /language/branches#if
type: reserved
- term: 'enum'
link: /language/enums
type: reserved
- term: 'export'
link: /guides/libraries/create-packages
type: bit
- term: 'extends'
link: /language/extend
type: reserved
- term: 'extension'
link: /language/extension-methods
type: bit
- term: 'external'
link: /language/functions#external
type: bit
- term: 'factory'
link: /language/constructors#factory-constructors
type: bit
- term: 'false'
link: /language/built-in-types#booleans
type: reserved
- term: 'final (var)'
link: /language/variables#final-and-const
type: reserved
- term: 'final (class)'
link: /language/class-modifiers#final
type: bit
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
type: bit
type: reserved

- term: 'finally'
link: /language/error-handling#finally
type: reserved
- term: 'for'
link: /language/loops#for-loops
type: reserved
- term: 'Function'
link: /language/functions
type: bit
- term: 'get'
link: /language/methods#getters-and-setters
type: bit
- term: 'hide'
link: /language/libraries#importing-only-part-of-a-library
type: reserved
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
type: reserved
type: nothing

- term: 'if'
link: /language/branches#if
type: reserved
- term: 'implements'
link: /language/classes#implicit-interfaces
type: bit
- term: 'import'
link: /language/libraries#using-libraries
type: bit
- term: 'in'
link: /language/loops#for-loops
type: reserved
- term: 'interface'
link: /language/class-modifiers#interface
type: bit
- term: 'is'
link: /language/operators#type-test-operators
type: reserved
- term: 'late'
link: /language/variables#late-variables
type: bit
- term: 'library'
link: /language/libraries
type: bit
- term: 'mixin'
link: /language/mixins
type: bit
- term: 'new'
link: /language/classes#using-constructors
type: reserved
- term: 'null'
link: /language/variables#default-value
type: reserved
- term: 'of'
link: /guides/libraries/create-packages#organizing-a-package
type: context
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
type: context
type: nothing

- term: 'on'
link: /language/error-handling#catch
type: context
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
type: context
type: nothing

- term: 'operator'
link: /language/methods#operators
type: bit
- term: 'part'
link: /guides/libraries/create-packages#organizing-a-package
type: bit
- term: 'required'
link: /language/functions#named-parameters
type: bit
- term: 'rethrow'
link: /language/error-handling#catch
type: reserved
- term: 'return'
link: /language/functions#return-values
type: reserved
- term: 'sealed'
link: /language/class-modifiers#sealed
type: bit
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
type: bit
type: nothing

- term: 'set'
link: /language/methods#getters-and-setters
type: bit
- term: 'show'
link: /language/libraries#importing-only-part-of-a-library
type: context
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
type: context
type: nothing

- term: 'static'
link: /language/classes#class-variables-and-methods
type: bit
- term: 'super'
link: /language/extend
type: reserved
- term: 'switch'
link: /language/branches#switch
type: reserved
- term: 'sync'
link: /language/functions#generators
type: context
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
type: context
type: nothing

- term: 'this'
link: /language/constructors
type: reserved
- term: 'throw'
link: /language/error-handling#throw
type: reserved
- term: 'true'
link: /language/built-in-types#booleans
type: reserved
- term: 'try'
link: /language/error-handling#catch
type: reserved
- term: 'type'
link: /language/extension-types
type: reserved
Copy link
Member

Choose a reason for hiding this comment

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

This one is really tricky. I couldn't convince the language team to make it a built-in identifier, so it isn't. But it is just like a built-in identifier in that it cannot be the name of "some" kinds of declarations, except that it is only forbidden for an extension declaration to have the name type. That's again because it is confusing if extension type ... can be an extension whose name is 'type' rather than an extension type. So let's call it a built-in identifier. It's almost true.

Suggested change
type: reserved
type: bit

- term: 'typedef'
link: /language/typedefs
type: bit
- term: 'var'
link: /language/variables
type: reserved
- term: 'void'
link: /language/built-in-types
type: reserved
- term: 'when'
link: /language/branches#when
type: reserved
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
type: reserved
type: nothing

- term: 'with'
link: /language/mixins
type: reserved
- term: 'while'
link: /language/loops#while-and-do-while
type: reserved
- term: 'yield'
link: /language/functions#generators
type: context
4 changes: 2 additions & 2 deletions src/_sass/_site.scss
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ main .content {
}

// Columns
.col2 {
.cols2 {
list-style: none;
column-count: 2;
column-gap: 0;
Expand All @@ -343,7 +343,7 @@ main .content {
}
}

.col3 {
.cols3 {
list-style: none;
column-count: 3;
column-gap: 0;
Expand Down
145 changes: 25 additions & 120 deletions src/content/language/keywords.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,123 +10,28 @@ nextpage:
title: Built-in types
---

The following table lists the words that the Dart language treats specially.

{% assign ckw = '&nbsp;<sup title="contextual keyword" alt="contextual keyword">1</sup>' %}
{% assign bii = '&nbsp;<sup title="built-in-identifier" alt="built-in-identifier">2</sup>' %}
{% assign lrw = '&nbsp;<sup title="limited reserved word" alt="limited reserved word">3</sup>' %}

<div class="table-wrapper">

|||||
|-|-|-|-|
| [abstract][]{{bii}} | [else][] | [import][]{{bii}} | [show][]{{ckw}} |
| [as][]{{bii}} | [enum][] | [in][] | [static][]{{bii}} |
| [assert][] | [export][]{{bii}} | [interface][]{{bii}} | [super][] |
| [async][]{{ckw}} | [extends][] | [is][] | [switch][] |
| [await][]{{lrw}} | [extension][]{{bii}} | [late][]{{bii}} | [sync][]{{ckw}} |
| [base][]{{bii}} | [external][]{{bii}} | [library][]{{bii}} | [this][] |
| [break][] | [factory][]{{bii}} | [mixin][]{{bii}} | [throw][] |
| [case][] | [false][] | [new][] | [true][] |
| [catch][] | [final (variable)][] | [null][] | [try][] |
| [class][] | [final (class)][]{{bii}} | [on][]{{ckw}} | [type][]{{lrw}} |
| [const][] | [finally][] | [operator][]{{bii}} | [typedef][]{{bii}} |
| [continue][] | [for][] | [part][]{{bii}} | [var][] |
| [covariant][]{{bii}} | [Function][]{{bii}} | [required][]{{bii}} | [void][] |
| [default][] | [get][]{{bii}} | [rethrow][] | [when][] |
| [deferred][]{{bii}} | [hide][]{{ckw}} | [return][] | [while][] |
| [do][] | [if][] | [sealed][]{{bii}} | [with][] |
| [dynamic][]{{bii}} | [implements][]{{bii}} | [set][]{{bii}} | [yield][]{{lrw}} |

{:.table .table-striped .nowrap}
</div>

[abstract]: /language/class-modifiers#abstract
[as]: /language/operators#type-test-operators
[assert]: /language/error-handling#assert
[async]: /language/async
[await]: /language/async
[base]: /language/class-modifiers#base
[break]: /language/loops#break-and-continue
[case]: /language/branches#switch
[catch]: /language/error-handling#catch
[class]: /language/classes#instance-variables
[const]: /language/variables#final-and-const
[continue]: /language/loops#break-and-continue
[covariant]: /guides/language/sound-problems#the-covariant-keyword
[default]: /language/branches#switch
[deferred]: /language/libraries#lazily-loading-a-library
[do]: /language/loops#while-and-do-while
[dynamic]: /language#important-concepts
[else]: /language/branches#if
[enum]: /language/enums
[export]: /guides/libraries/create-packages
[extends]: /language/extend
[extension]: /language/extension-methods
[external]: /language/functions#external
[factory]: /language/constructors#factory-constructors
[false]: /language/built-in-types#booleans
[final (variable)]: /language/variables#final-and-const
[final (class)]: /language/class-modifiers#final
[finally]: /language/error-handling#finally
[for]: /language/loops#for-loops
[Function]: /language/functions
[get]: /language/methods#getters-and-setters
[hide]: /language/libraries#importing-only-part-of-a-library
[if]: /language/branches#if
[implements]: /language/classes#implicit-interfaces
[import]: /language/libraries#using-libraries
[in]: /language/loops#for-loops
[interface]: /language/class-modifiers#interface
[is]: /language/operators#type-test-operators
[late]: /language/variables#late-variables
[library]: /language/libraries
[mixin]: /language/mixins
[new]: /language/classes#using-constructors
[null]: /language/variables#default-value
[on]: /language/error-handling#catch
[operator]: /language/methods#operators
[part]: /guides/libraries/create-packages#organizing-a-package
[required]: /language/functions#named-parameters
[rethrow]: /language/error-handling#catch
[return]: /language/functions#return-values
[sealed]: /language/class-modifiers#sealed
[set]: /language/methods#getters-and-setters
[show]: /language/libraries#importing-only-part-of-a-library
[static]: /language/classes#class-variables-and-methods
[super]: /language/extend
[switch]: /language/branches#switch
[sync]: /language/functions#generators
[this]: /language/constructors
[throw]: /language/error-handling#throw
[true]: /language/built-in-types#booleans
[try]: /language/error-handling#catch
[type]: /language/extension-types
[typedef]: /language/typedefs
[var]: /language/variables
[void]: /language/built-in-types
[when]: /language/branches#when
[with]: /language/mixins
[while]: /language/loops#while-and-do-while
[yield]: /language/functions#generators

Avoid using these words as identifiers.
However, if necessary, the keywords marked with superscripts can be identifiers:

* Words with the superscript **1** are **contextual keywords**,
which have meaning only in specific places.
They're valid identifiers everywhere.

* Words with the superscript **2** are **built-in identifiers**.
These keywords are valid identifiers in most places,
but they can't be used as class or type names, or as import prefixes.

* Words with the superscript **3** are limited reserved words related to
[asynchrony support][].
You can't use `await` or `yield` as an identifier
in any function body marked with `async`, `async*`, or `sync*`.

All other words in the table are **reserved words**,
which can't be identifiers.

[asynchrony support]: /language/async
{% assign ckw = '&nbsp;<sup>1</sup>' %}
{% assign bii = '&nbsp;<sup>2</sup>' %}

The following table lists the words
that the Dart language reserves for its own use.
Don't use these terms as identifiers unless the term notes an exception.
Copy link
Member

Choose a reason for hiding this comment

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

I think some form of the original guidance is appropriate here. It's almost never good style to use any of these as identifiers. So maybe say something like "These words cannot be used as identifiers unless otherwise noted. Even when allowed, using keywords as identifiers is confusing and should be avoided."?

Copy link
Member

Choose a reason for hiding this comment

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

I don't see a reason to discourage the user of, fx, show and hide as variable or method names. Sometimes they are precisely what you want to use, and they work.

The thing users need to know are the actual restrictions: reserved words that cannot be used as a name, ever, and built-in identifiers that cannot be used as a type or prefix name.

The rest are not really important.
Or that many: hide, show, async, sync and on. Now possibly also type.
These are identifiers that can be used as names, even for types or prefixes (but as lower case, they shouldn't be names of types or extensions), but which also occur in a few specific places not as a name to be resolved, but as a keyword of a syntactic construct.

If this is a list of every word that occurs as a "keyword" (managing: not as a resolvable name) anywhere in the grammar, then those words should be included, and linked to the descriptions of the constructs where the word can occur.
That's a fine index, if someone sees a word they don't understand, they can look it up, and see what it means in the context where they found it.

That index can also double as the list of restrictions, saying which words are restricted words and built-in identifiers, wish it's useful information. It can even mention that type cannot be the name of an extension, as a unique restriction.
I don't think being on the list as a contextual keyword should imply that the word should not be used as a name.
(And await and yield should be listed as restricted words, with a comment that they're not reserved everywhere, because users should refrain from using them as names everywhere. Unlike show or sync, which are perfectly fine names.)

To learn more about identifier usage, click on the term.

<table class="table table-striped">

{% tablerow keyword in keywords cols: 4 %}
<a href="{{keyword.link}}">{{keyword.term}}</a>
{%- case keyword.type %}
{% when 'bit' %}{{bii}}
{% when 'context' %}{{ckw}}
{% endcase %}
{% endtablerow %}
</table>

{{ckw}} These keywords can be used as an identifier
depending on **context**.
Comment on lines +32 to +33
Copy link
Member

Choose a reason for hiding this comment

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

Using a singlar form for consistency with lines 35-37:

Suggested change
{{ckw}} These keywords can be used as an identifier
depending on **context**.
{{ckw}} This keyword can be used as an identifier
depending on **context**.

Also, 'these keywords' can be used as 'an identifier' isn't quite congruent.


{{bii}} These keywords can't be used as class names, type names,
or import prefixes. They can be used as identifiers in all other
circumstances.
Comment on lines +35 to +37
Copy link
Member

Choose a reason for hiding this comment

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

'Class names' is a subset of 'type names', and we may also want to mention a few other kinds of type names. Perhaps:

Suggested change
{{bii}} These keywords can't be used as class names, type names,
or import prefixes. They can be used as identifiers in all other
circumstances.
{{bii}} This keyword can't be used as the name of a type (a class, a
mixin, an enum, an extension type, or a type alias), or the name of
an extension, or as an import prefix. It can be used as an identifier
in all other circumstances.

extension declarations are singled out because that kind of declaration doesn't introduce a type. You could also include that into '(a class, a mixin, an enum, an extension, an extension type, or a type alias)' if it's considered overly pedantic to mention it separately. ;-)

I'm using a singular form because it makes everything in this paragraph a bit more straightforward and unambiguous, and also because a reader would often arrive at this paragraph because they want to know more about one specific identifier that they were looking at.

4 changes: 2 additions & 2 deletions src/content/tools/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ except for VM libraries such as `dart:io`.

Dart plugins exist for these commonly used IDEs.

<ul class="col2">
<ul class="cols2">
<li>
<img src="/assets/img/tools/android_studio.svg" width="48" alt="Android Studio logo">
<a href="/tools/jetbrains-plugin"><b>Android Studio</b></a>
Expand All @@ -68,7 +68,7 @@ Dart plugins exist for these commonly used IDEs.
The following Dart plugins are also available,
thanks to the Dart community.

<ul class="col2">
<ul class="cols2">
<li>
<img src="/assets/img/tools/emacs.png" alt="Emacs logo">
<a href="https://github.com/nex3/dart-mode"><b>Emacs</b></a>
Expand Down
Loading