It is a compile-time error for `super` to be used in any way when in the
body of a parameterless anonymous method. This CL adds these error
messages to the analyzer.
It introduces a new `SuperContext` in order to maintain proper knowledge
about the situation when it is detected, but it uses a rather generic
error message (just saying that the context is wrong) following the
rationale that this is sufficient for occurrences of `super` in static
members, constructors, top-level declarations, and more.
Change-Id: I4552be0983e4d64a6e59fd03521cbe4f5c784f15
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/498040
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Erik Ernst <eernst@google.com>
I changed the parsing of const dot shorthands to parse the entire selector chain in `parsePrecedenceExpression` rather than parsing them in `parseConstExpression`. We were originally parsing the initial expression before the `.` and only flagging that as a dot shorthand which prevented any chaining on const constructors. Const expressions with chained methods/property accesses were not being flagged as a dot shorthand so we weren’t saving the context type properly which led to producing the “unknown context type” error.
Before:
```
class C {
const new someConstCtor();
C method() => this;
}
C c = const .someConstCtor.method();
// (const .someConstCtor) is parsed and handled as a const constructor
// (const .someConstCtor) is handled as a dot shorthand, context is
// saved on only this AST and not the outer chain.
// Then we parse the rest of the selector chain (.method())
//
// Error: No context type for (const .someConstCtor.method())
```
After:
```
class C {
const new someConstCtor();
C method() => this;
}
C c = const .someConstCtor.method();
// (const .someConstCtor) is parsed and handled as a const constructor.
// Then we parse the rest of the selector chain (.method())
// (const .someConstCtor.method()) is handled as a dot shorthand, context is saved for this outer node.
//
// OK. No error because we are able to retrieve the type for the
// entire dot shorthand chain.
```
Fixes: https://github.com/dart-lang/sdk/issues/63119
Change-Id: I3308d8eb7ce101466be257aba6b5448921bff136
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/495560
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Kallen Tu <kallentu@google.com>
Replace manual type construction utilities in type system tests with a
unified string-based type parser. This simplifies test code, improves
readability, and enables more expressive type scenarios.
Key changes:
- Introduce TypeSpecParser and TypeParsingScope to parse types,
function types, records, and type parameters from strings.
- Add parseType() and related helpers to AbstractTypeSystemTest,
replacing ElementsTypesMixin usage.
- Remove ElementsTypesMixin and migrate all tests to use parsed
types instead of manually constructed TypeImpl instances.
- Extend _SpecParser to support:
- Promoted type parameter bounds (`T & int`)
- Parenthesized vs record types disambiguation
- Additional built-in types (InvalidType, UnknownInferredType)
- Variance in generic function types
- Covariant parameters
- Refactor scope construction to use _Scope.forLibraries, reducing
duplicated interface/type alias collection logic.
- Add standalone materialization flow for type parameters to support
parsing in isolation.
Impact:
- Tests become more declarative and closer to Dart syntax.
- Eliminates boilerplate and reduces risk of inconsistencies in
manual type construction.
- Enables testing of newer type system features (promotion,
variance, complex function types) via concise string specs.
Change-Id: I85dd0aa88a37142356f14419d0d35350e38b9c8b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/497680
Reviewed-by: Johnni Winther <johnniwinther@google.com>
`ConstantVisitor.visitAdjacentStrings` previously delegated to
`_concatenateNodes`, which folds the list pairwise and materializes
a new `DartObjectImpl` / `StringState` at every step. For an
`AdjacentStrings` with `n` string pieces of total length `L`, this
is roughly O(L^2) work and garbage.
This is pathological on generated code: parser generators and other
codegen tools commonly emit a single large string constant as a long
sequence of adjacent string literals (e.g. encoded transition tables
for a table-driven parser). In those files, constant evaluation of
a single top-level `const` dominates analyzer runtime.
Fast-path `visitAdjacentStrings`: when every element evaluates to a
plain `StringState`, append into one `StringBuffer` and return a
single final `DartObjectImpl`. Fall back to the existing
`_concatenateNodes` path only when an element is not a plain string
(diagnostic, unknown, etc.).
Wall-clock time to resolve a library containing one `const table =`
of N adjacent 16-char string pieces, on an Apple M-series laptop
with a recent main-channel SDK:
pieces total_chars baseline_ms patched_ms speedup
1024 16384 218 222 ~1x
4096 65536 180 189 ~1x
16384 262144 245 166 ~1.5x
65536 1048576 9229 246 ~37x
At larger sizes the baseline grows quadratically while the patched
path stays linear; n=262144 took multiple minutes on the baseline
and roughly half a second after the patch.
TEST=pkg/analyzer/test/src/dart/constant/evaluation_test.dart:test_visitAdjacentInterpolation_simple
Bug: https://github.com/dart-lang/sdk/issues/63222
Change-Id: Ibffe4124d025fceb5991ea88b4af9a03f36525b4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/497001
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Move buildLibrariesFromSpec to a parsed header model instead of
assembling mock declarations from many separate fields.
This rewrites the test library builder around declaration objects that
first create fragments and elements and then resolve their types in a
second pass. Specs now describe classes, constructors, methods, mixins,
extension types, typedefs, and top-level functions using compact
Dart-like headers, and the builder parses those headers in one place.
This makes mock libraries easier to read and update, keeps test data
closer to real source syntax, and removes a lot of repetitive client
code. It also simplifies the surrounding helpers by using named
arguments, adding missing library support for type aliases, and
providing small convenience APIs for looking up declarations in tests.
Change-Id: I6a3b174b3899b4350b571906dc9784a59affe216
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/497181
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Create `TypeParameterElementImpl` instances when their owning elements
are constructed, instead of materializing them later in builders,
fragment linkers, and bundle reading. This makes ownership explicit in
the element model.
Update synthetic executable construction in inheritance handling to
build fresh type parameter and formal parameter elements. Top-merge and
covariance inheritance were previously able to reuse fragments from
other executables, which could attach fragments to the wrong element and
produce invalid synthetic members for generic signatures.
For type aliases, serialize the first fragment directly instead of a
fragment list. This matches how type alias elements are constructed and
avoids a separate read-time step that recreated type parameter elements.
Bump the data version for the format change.
Change-Id: If4f203f65fb11bcd0ffd1dcc0e47956b9fb2597b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/496780
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Expand the test library builder so more unit-style type system tests can
construct declarations through LibrarySpec instead of assembling
elements and fragments by hand.
Add support for imports and external libraries, enums, mixins, extension
types, type aliases, class mixins, type parameter bounds and variances,
and additional parsed type forms needed by these tests. Also add shared
helpers in type_system_base to build test libraries with the mock SDK
libraries and wire in the type provider and type system.
Migrate the affected tests to describe their libraries declaratively and
look up the resulting elements from the built library. This removes a
large amount of bespoke test-only element construction, drops helper
APIs that were only needed for hand-built declarations, and makes these
tests exercise element shapes that are closer to normal analyzer code.
Change-Id: Ic4180a64a5309b87b942f95ff45f682fbb8399df
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/496664
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
This CL adds an implementation of anonymous `=>` methods in the CFE
which is sufficiently complete to handle the existing test cases in
language/anonymous_methods/expression.
Coverage is handled by adding magic comments to ignore the fact that new
code is not covered by existing testcases. This will be settled in a
separate CL.
To keep the failures visible, the failures in configurations
dart2js-hostasserts-linux-d8-try, dart2js-linux-chrome-try,
dart2js-minified-linux-d8-try, and ddc-linux-chrome-try have not been
approved. It seems likely to me that those are bugs in dart2js and in
DDC.
Change-Id: Ia70fedd4de6166d6a3bf8a108f49728b6e16c9f6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/494440
Commit-Queue: Erik Ernst <eernst@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Keep track of the most recent same-named fragment even when it has a
different declaration kind. This lets augmentation validation
distinguish between a missing target and a target whose kind does not
match the augmentation.
Store this information on elements, serialize it through summaries, and
use it during error verification. When an augmentation finds a previous
declaration with the same name but a different kind, report
`augmentationOfDifferentDeclarationKind` and attach a context message
that points to the original declaration instead of falling back to
`augmentationWithoutDeclaration`.
This improves diagnostics for both top-level and member declarations,
including combinations such as constructors vs fields, methods vs
accessors, and functions vs variables.
Change-Id: Ic794c437fa160bb29d25f90559b544a7282ca697
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/494301
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Create `TypeParameterElementImpl` instances when fragments are built or
read, instead of synthesizing them lazily from
`TypeParameterFragmentImpl.element`.
This makes fragment-to-element wiring explicit and predictable across
the element model. To support this, accesses to `typeParameters` now
ensure that resolution has been read before returning element-backed
data.
The bundle format is adjusted so that type parameter metadata remains on
fragments, while variance, bounds, and default types are serialized with
the corresponding elements. This keeps the eager element creation model
consistent when reading summaries.
As part of this cleanup, generic function types and formal parameters
now create their nested type parameter elements up front, and
declarations that cannot have type parameters stop serializing empty
type parameter lists.
Change-Id: Ifcdc05bcccd2de6ae88d8102b10efe9a144e2545
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/496520
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Rename the bundle read/write helpers so their names reflect whether they
operate on elements, fragments, or whole library fragments. This makes
the serialization flow easier to follow and keeps the reader and writer
structured around the same concepts.
Also extract small helpers for imports, exports, parts, type parameters,
and formal parameters, so the bundle layout is spelled out more directly
instead of being spread across larger methods.
While doing this, move import prefix `enclosingFragment` wiring into the
`libraryImports` setter on `LibraryFragmentImpl`. This keeps prefix
fragments attached consistently whether they come from the library
builder or from summary deserialization.
Change-Id: I78f66f3e8a33d6c0dbf32bf9976ed666ceb6422c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/496500
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
The old flag described a resolver behavior and defaulted to true, which
made persisted element data less explicit and caused many declarations
to carry the flag even when their type did not actually come from an
initializer. The new flag records the underlying fact we care about:
whether top-level inference produced the element's type from its
initializer.
Make top-level inference return both the inferred type and whether it
was derived from the initializer, and store that result on the element
when the type is computed. Use this recorded fact when choosing the
context type for initializer resolution, so only declarations whose type
was taken from the initializer fall back to `UnknownInferredType`.
Update the stored flags, manifest matching, result printers, and
serialized expectations to reflect the renamed and narrower semantics,
and bump the analysis driver data version for the format change.
Change-Id: I120f3cc289454c8ffc0963dcb028e2d5250f16da
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/496220
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Propagate flags to top-level variable accessors
Record `isAbstract` on top-level variable fragments and copy it to the
synthetic getter and setter fragments built from those variables. Also
mark those accessors as complete declarations when the originating
variable is external or not abstract. o later linking and element model
expectations stay consistent.
Change-Id: I36edfab18feaa2e2d9f8dca20dad837bd82f0836
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/495943
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Replace the hand-written header flag formatting for elements and
fragments with writeHeaderFlags(...flagsForTesting). This makes the
printed output come from the same generated flag definitions as the
element model instead of maintaining separate lists of writeIf calls.
Mark computed element flags such as hasDefaultValue, hasInitializer, and
hasNonFinalField in the generated metadata, and add the missing
generated overrides needed to expose them through flagsForTesting. This
also lets the shared path report flags such as isSimplyBounded and
hasEnclosingTypeParameterReference consistently.
Because hasNonFinalField now needs to round-trip through bundles for
enums, update the bundle reader and writer and bump the data version.
Change-Id: I7c126fe4bc69fd6b191f339ddc420b05cd8b5ee7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/495860
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Fixes https://github.com/dart-lang/sdk/issues/63173
hasJS now checks both dart:_js_annotations and dart:js_interop so check
only for dart:_js_annotations to restore the original intent of the
check.
Linter tests did not fail before because the mock SDK did not have the
equivalent @JS renames as the real js_interop.dart, so the hasJS check
reported the same answer as before and after its semantic change. With
the change in the mock SDK, multiple tests would now correctly fail
without the change in the lint rule to not use hasJS.
Change-Id: I79c5fbb35f0d868f932aa5ed42e484ea725debbe
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/495787
Reviewed-by: Nate Biggs <natebiggs@google.com>
Auto-Submit: Srujan Gaddam <srujzs@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Nate Biggs <natebiggs@google.com>
Remove FragmentImpl.isSynthetic and record synthesized fragment origins
using more specific isOrigin... flags instead.
This adds dedicated origin markers for formal parameters and type
parameters synthesized to keep augmentation fragments aligned, and for
formal parameters synthesized for mixin application constructors. It
also stops marking other generated fragments as synthetic when their
origin is already represented by a more specific flag such as
isOriginVariable, isOriginGetterSetter, isOriginLoadLibrary, or
isOriginNotExistingFile.
Update summary serialization to preserve the new fragment flags and bump
the data version. This makes generated fragment provenance more precise
and avoids collapsing different synthesized cases into one generic
synthetic marker.
Change-Id: I99788b3372d05fd882f6e15e05af39e048f94122
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/495786
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Add a lazily initialized substitution to `InterfaceTypeImpl` and reuse
it when instantiating members for the target type.
Previously getters, setters, and methods went through specialized
`forTargetType()` helpers that rebuilt the same substitution from the
interface type before delegating to `substitute()`. This duplicated
logic and spread the target-type instantiation path across several
member classes.
Keep the substitution on `InterfaceTypeImpl` instead, and use
`element.substitute(_substitution)` at the call sites. This makes the
instantiation flow more direct, removes redundant helpers, and keeps
member substitution logic centered on the interface type that owns it.
Change-Id: I985c8da13ae8a8c9e36b85ad3be2af2743c386b1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/495640
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Add `InternalFieldElement.substitute()` and route field substitution
through the element itself instead of the static
`SubstitutedFieldElementImpl.from()` helper.
This makes fields follow the same substitution pattern as other internal
elements, so callers no longer need to special-case field members or
depend directly on the substituted implementation class. It also lets an
already substituted field compose another substitution, instead of
rebuilding the wrapper from scratch.
The new implementation avoids creating a substituted field when the
substitution is empty or the field does not reference enclosing type
parameters. This keeps the fast path cheap while preserving the same
behavior for fields that actually need instantiation.
Update the bundle reader and substituted field-formal parameters to call
`field.substitute(...)`, and remove the now-unused direct import of
`member.dart`.
Change-Id: I146b44bb81a6033bb19b2be6fe498046544cd235
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/495621
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Add `substitute()` to `InternalFormalParameterElement` and move formal
parameter substitution logic behind that interface.
This replaces `SubstitutedFormalParameterElementImpl.from()` helper and
the subtype switch in substituted executables with polymorphic dispatch
from each parameter element.
The change makes substitution follow the same pattern already used by
other internal element APIs, so callers no longer need to know which
formal parameter subtype they are handling. It also keeps composition of
existing substitutions local to substituted parameter implementations.
As part of this cleanup, field formal parameters now use a dedicated
internal mixin, and function type instantiation and super-formal lookup
reuse the new element-level substitution entry point.
Change-Id: I3efaa4ae3e08652328058338ad37715fe838e435
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/495220
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Permit `abstract` on top-level variable declarations when the
augmentations feature is enabled. Previously the parser always reported
`abstract` as extraneous at the top level, which rejected valid syntax
and dropped the modifier before later stages could see it.
Thread the abstract token through top-level field parsing, record it on
`TopLevelVariableDeclaration`, and pass it through the front-end
builders. Reorder the field callback arguments so `augment` precedes
`abstract`, matching the augmentation grammar for incomplete top-level
variables and keeping the parser, listener, and outline plumbing
consistent.
Change-Id: I680414a746b707d483e485702685c95f28a9c9ac
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/494564
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Add `InterfaceType.interfaceMembers` and
`InterfaceType.inheritedConcreteMembers`, and implement them by applying
the type's substitution to the underlying element members.
This moves member instantiation to the `InterfaceType` API instead of
requiring callers to read raw element maps and wrap the results
manually. With this change, code that works with an instantiated type
can ask the type itself for the corresponding instantiated members.
Update completion, inheritance, extension resolution, and summary
reading code to use the new API and `ExecutableElement.substitute()`
instead of `SubstitutedExecutableElementImpl.from()`. This removes the
old helper, simplifies callers, and makes substitution behavior more
uniform across the analyzer.
Change-Id: I2349546d65e9745c2cdeda19ca6ff9283a5fd001
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/495100
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
This adds validation that plugin diagnostics are configured with one
of the valid values (taken from one of the test cases):
```
plugins:
one:
diagnostics:
code1: ignore
code2: warning
code3: error
code4: info
```
Change-Id: I2a77988c2efe1d9e0fdcd33558ed970fbe4c47c0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/494781
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Samuel Rawlins <srawlins@google.com>
Replace the generic executable substitution helper with
`forSubstitution()` methods on internal executable and member elements.
This moves the logic for creating substituted constructors, methods,
getters, and setters onto the corresponding element implementations.
Each element kind can now decide whether a substituted wrapper is
needed, reject invalid cases such as non-member accessors, and combine
nested substitutions in a single place.
Also add `MapSubstitution.andThen()` so substituted elements can compose
an existing substitution with a new one directly, instead of rebuilding
maps ad hoc. This makes repeated substitution clearer and preserves the
intended order of application.
Overall, the change makes member substitution more explicit, removes
type casts and kind switches from the shared helper path, and keeps
substitution-specific behavior closer to the element types that own it.
Change-Id: I54a3bfea48ddf87b4db5c53094090f24d66a9a23
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/494780
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Use merged type parameters in BundleWriter
Use `withTypeParameters()` when writing type-parameterized fragments
instead of rebuilding a local scope from `fragment.typeParameters`.
The serialized data still comes from the fragment list, but the
resolution context now uses `fragment.element.typeParameters`. This
makes BundleWriter use the canonical merged type parameter elements when
writing bounds, default types, and other references that can point back
to those parameters.
Using the merged elements keeps the writer aligned with how later
resolution data refers to type parameters, especially when multiple
fragments are linked into a single element.
Also rename `_writeTypeParameterElement` to
`_writeTypeParameterFragment` to match what the method actually writes:
fragment declaration data, with element-backed resolution properties.
Change-Id: Iddcd7a4b15ad0717bd137da97813f761e0fba5eb
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/494569
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>