fix location tracking transformer for use in flutter
Closes https://github.com/dart-lang/sdk/pull/63551 GitOrigin-RevId: a14cbbd88c605d193e2a1b744727765c45d38278 Change-Id: Ied6c2fc4ee3b5343c6ab8e38080542d667175f4d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/510160 Reviewed-by: Daco Harkes <dacoharkes@google.com> Commit-Queue: Daco Harkes <dacoharkes@google.com> Reviewed-by: Jens Johansen <jensj@google.com>
This commit is contained in:
committed by
dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent
034b90af5d
commit
dd4f983cee
+117
@@ -0,0 +1,117 @@
|
||||
# Copyright (c) 2026, 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.
|
||||
|
||||
type: newworld
|
||||
target: dartdevc
|
||||
trackCreationLocations: true
|
||||
worlds:
|
||||
- entry: main.dart
|
||||
sources:
|
||||
main.dart: |
|
||||
import 'foo.dart';
|
||||
Foo newFoo = new Foo();
|
||||
var newFooFunction = Foo.new;
|
||||
var newFooFunctionCall = newFooFunction();
|
||||
Foo extensionFoo = null.foo();
|
||||
var extensionFooFunction = null.foo;
|
||||
var extensionFooFunctionCall = extensionFooFunction();
|
||||
Foo extensionBar = null.bar();
|
||||
Foo extensionBaz = null.baz();
|
||||
Foo extensionBoz = null.boz();
|
||||
Foo extensionConstFoo = null.constFoo();
|
||||
Foo extensionGetterFoo = null.getterFoo;
|
||||
var extensionSetterFoo = () => null.setterFoo = null;
|
||||
Foo extensionOperatorFoo = -null;
|
||||
Foo extensionStaticFoo = FooExtension.staticFoo();
|
||||
foo.dart: |
|
||||
import 'package:flutter/src/widgets/framework.dart';
|
||||
|
||||
const alias = widgetFactory;
|
||||
const nullableAlias = false ? widgetFactory : null;
|
||||
const nonNullableAlias = false ? widgetFactory : alias;
|
||||
|
||||
class Foo extends Widget {
|
||||
factory Foo() => const Foo._();
|
||||
|
||||
const Foo._();
|
||||
}
|
||||
|
||||
extension FooExtension on Object? {
|
||||
@widgetFactory
|
||||
Foo foo() => Foo._();
|
||||
|
||||
@alias
|
||||
Foo bar() => Foo._();
|
||||
|
||||
@nullableAlias
|
||||
Foo baz() => Foo._();
|
||||
|
||||
@nonNullableAlias
|
||||
Foo boz() => Foo._();
|
||||
|
||||
@widgetFactory
|
||||
Foo constFoo() => const Foo._();
|
||||
|
||||
@widgetFactory
|
||||
Foo get getterFoo => new Foo._();
|
||||
|
||||
@widgetFactory
|
||||
void set setterFoo(_) => new Foo._();
|
||||
|
||||
@widgetFactory
|
||||
Foo operator -() => new Foo._();
|
||||
|
||||
@widgetFactory
|
||||
static Foo staticFoo() => new Foo._();
|
||||
}
|
||||
flutter/lib/src/widgets/framework.dart: |
|
||||
export 'widget_inspector.dart' show widgetFactory;
|
||||
|
||||
abstract class Bar {
|
||||
const Bar();
|
||||
}
|
||||
|
||||
@pragma('track-creation-locations')
|
||||
abstract class Widget extends Bar {
|
||||
const Widget();
|
||||
}
|
||||
flutter/lib/src/widgets/widget_inspector.dart: |
|
||||
const widgetFactory = pragma('track-creation-locations');
|
||||
.dart_tool/package_config.json: |
|
||||
{
|
||||
"configVersion": 2,
|
||||
"packages": [
|
||||
{
|
||||
"name": "flutter",
|
||||
"rootUri": "../flutter",
|
||||
"packageUri": "lib/"
|
||||
}
|
||||
]
|
||||
}
|
||||
expectedLibraryCount: 4
|
||||
|
||||
- entry: main.dart
|
||||
worldType: updated
|
||||
invalidate:
|
||||
- main.dart
|
||||
expectInitializeFromDill: false
|
||||
sources:
|
||||
main.dart: |
|
||||
import 'foo.dart';
|
||||
Foo extensionConstFoo = null.constFoo();
|
||||
Foo newFoo = new Foo();
|
||||
var newFooFunction = Foo.new;
|
||||
var newFooFunctionCall = newFooFunction();
|
||||
Foo extensionFoo = null.foo();
|
||||
var extensionFooFunction = null.foo;
|
||||
var extensionFooFunctionCall = extensionFooFunction();
|
||||
Foo extensionBar = null.bar();
|
||||
Foo extensionBaz = null.baz();
|
||||
Foo extensionBoz = null.boz();
|
||||
Foo extensionGetterFoo = null.getterFoo;
|
||||
var extensionSetterFoo = () => null.setterFoo = null;
|
||||
Foo extensionOperatorFoo = -null;
|
||||
Foo extensionStaticFoo = FooExtension.staticFoo();
|
||||
expectedLibraryCount: 4
|
||||
advancedInvalidation: bodiesOnly
|
||||
+194
@@ -0,0 +1,194 @@
|
||||
main = <No Member>;
|
||||
library from "package:flutter/src/widgets/framework.dart" as fra {
|
||||
additionalExports = (wid::widgetFactory)
|
||||
|
||||
export "package:flutter/src/widgets/widget_inspector.dart" show widgetFactory;
|
||||
|
||||
abstract class Bar extends dart.core::Object /*hasConstConstructor*/ {
|
||||
const constructor •() → fra::Bar
|
||||
: super dart.core::Object::•()
|
||||
;
|
||||
}
|
||||
@#C3
|
||||
abstract class Widget extends fra::Bar implements dart.developer::_HasCreationLocation /*hasConstConstructor*/ {
|
||||
final field dart.developer::CreationLocation? dart.developer::_location;
|
||||
const constructor •({dart.developer::CreationLocation? $creationLocationd_0dea112b090073317d4 = #C2}) → fra::Widget
|
||||
: super fra::Bar::•(), fra::Widget::_location = $creationLocationd_0dea112b090073317d4
|
||||
;
|
||||
}
|
||||
}
|
||||
library from "package:flutter/src/widgets/widget_inspector.dart" as wid {
|
||||
|
||||
static const field dart.core::pragma widgetFactory = #C3;
|
||||
}
|
||||
library from "org-dartlang-test:///foo.dart" as foo {
|
||||
|
||||
import "package:flutter/src/widgets/framework.dart";
|
||||
|
||||
class Foo extends fra::Widget /*hasConstConstructor*/ {
|
||||
const constructor _({dart.developer::CreationLocation? $creationLocationd_0dea112b090073317d4 = #C2}) → foo::Foo
|
||||
: super fra::Widget::•($creationLocationd_0dea112b090073317d4: $creationLocationd_0dea112b090073317d4)
|
||||
;
|
||||
static factory •({dart.developer::CreationLocation? $creationLocationd_0dea112b090073317d4 = #C2}) → foo::Foo
|
||||
return #C9;
|
||||
static synthetic method _#new#tearOff() → foo::Foo
|
||||
return foo::Foo::•($creationLocationd_0dea112b090073317d4: #C11);
|
||||
static synthetic method _#_#tearOff() → foo::Foo
|
||||
return new foo::Foo::_($creationLocationd_0dea112b090073317d4: #C14);
|
||||
}
|
||||
extension FooExtension on dart.core::Object? {
|
||||
method foo = foo::FooExtension|foo;
|
||||
method tearoff foo = foo::FooExtension|get#foo;
|
||||
method bar = foo::FooExtension|bar;
|
||||
method tearoff bar = foo::FooExtension|get#bar;
|
||||
method baz = foo::FooExtension|baz;
|
||||
method tearoff baz = foo::FooExtension|get#baz;
|
||||
method boz = foo::FooExtension|boz;
|
||||
method tearoff boz = foo::FooExtension|get#boz;
|
||||
method constFoo = foo::FooExtension|constFoo;
|
||||
method tearoff constFoo = foo::FooExtension|get#constFoo;
|
||||
get getterFoo = foo::FooExtension|get#getterFoo;
|
||||
set setterFoo = foo::FooExtension|set#setterFoo;
|
||||
operator unary- = foo::FooExtension|unary-;
|
||||
static method staticFoo = foo::FooExtension|staticFoo;
|
||||
}
|
||||
static const field dart.core::pragma alias = #C3;
|
||||
static const field dart.core::pragma? nullableAlias = #C2;
|
||||
static const field dart.core::pragma nonNullableAlias = #C3;
|
||||
@#C3
|
||||
static extension-member method FooExtension|foo(lowered final dart.core::Object? #this, {dart.developer::CreationLocation? $creationLocationd_0dea112b090073317d4 = #C2}) → foo::Foo
|
||||
return new foo::Foo::_($creationLocationd_0dea112b090073317d4: $creationLocationd_0dea112b090073317d4);
|
||||
static extension-member method FooExtension|get#foo(lowered final dart.core::Object? #this) → () → foo::Foo
|
||||
return () → foo::Foo => foo::FooExtension|foo(#this, $creationLocationd_0dea112b090073317d4: #C18);
|
||||
@#C3
|
||||
static extension-member method FooExtension|bar(lowered final dart.core::Object? #this, {dart.developer::CreationLocation? $creationLocationd_0dea112b090073317d4 = #C2}) → foo::Foo
|
||||
return new foo::Foo::_($creationLocationd_0dea112b090073317d4: $creationLocationd_0dea112b090073317d4);
|
||||
static extension-member method FooExtension|get#bar(lowered final dart.core::Object? #this) → () → foo::Foo
|
||||
return () → foo::Foo => foo::FooExtension|bar(#this, $creationLocationd_0dea112b090073317d4: #C21);
|
||||
@#C2
|
||||
static extension-member method FooExtension|baz(lowered final dart.core::Object? #this) → foo::Foo
|
||||
return new foo::Foo::_($creationLocationd_0dea112b090073317d4: #C24);
|
||||
static extension-member method FooExtension|get#baz(lowered final dart.core::Object? #this) → () → foo::Foo
|
||||
return () → foo::Foo => foo::FooExtension|baz(#this);
|
||||
@#C3
|
||||
static extension-member method FooExtension|boz(lowered final dart.core::Object? #this) → foo::Foo
|
||||
return new foo::Foo::_($creationLocationd_0dea112b090073317d4: #C26);
|
||||
static extension-member method FooExtension|get#boz(lowered final dart.core::Object? #this) → () → foo::Foo
|
||||
return () → foo::Foo => foo::FooExtension|boz(#this);
|
||||
@#C3
|
||||
static extension-member method FooExtension|constFoo(lowered final dart.core::Object? #this, {dart.developer::CreationLocation? $creationLocationd_0dea112b090073317d4 = #C2}) → foo::Foo
|
||||
return #C29;
|
||||
static extension-member method FooExtension|get#constFoo(lowered final dart.core::Object? #this) → () → foo::Foo
|
||||
return () → foo::Foo => foo::FooExtension|constFoo(#this, $creationLocationd_0dea112b090073317d4: #C31);
|
||||
@#C3
|
||||
static extension-member method FooExtension|get#getterFoo(lowered final dart.core::Object? #this, {dart.developer::CreationLocation? $creationLocationd_0dea112b090073317d4 = #C2}) → foo::Foo
|
||||
return new foo::Foo::_($creationLocationd_0dea112b090073317d4: $creationLocationd_0dea112b090073317d4);
|
||||
@#C3
|
||||
static extension-member method FooExtension|set#setterFoo(lowered final dart.core::Object? #this, wildcard dynamic _#wc0#formal, {dart.developer::CreationLocation? $creationLocationd_0dea112b090073317d4 = #C2}) → void
|
||||
return new foo::Foo::_($creationLocationd_0dea112b090073317d4: $creationLocationd_0dea112b090073317d4);
|
||||
@#C3
|
||||
static extension-member method FooExtension|unary-(lowered final dart.core::Object? #this, {dart.developer::CreationLocation? $creationLocationd_0dea112b090073317d4 = #C2}) → foo::Foo
|
||||
return new foo::Foo::_($creationLocationd_0dea112b090073317d4: $creationLocationd_0dea112b090073317d4);
|
||||
@#C3
|
||||
static extension-member method FooExtension|staticFoo() → foo::Foo
|
||||
return new foo::Foo::_($creationLocationd_0dea112b090073317d4: #C34);
|
||||
}
|
||||
library from "org-dartlang-test:///main.dart" as main {
|
||||
|
||||
import "org-dartlang-test:///foo.dart";
|
||||
|
||||
static field foo::Foo newFoo = foo::Foo::•($creationLocationd_0dea112b090073317d4: #C38);
|
||||
static field () → foo::Foo newFooFunction = #C39;
|
||||
static field foo::Foo newFooFunctionCall = main::newFooFunction(){() → foo::Foo};
|
||||
static field foo::Foo extensionFoo = foo::FooExtension|foo(null, $creationLocationd_0dea112b090073317d4: #C42);
|
||||
static field () → foo::Foo extensionFooFunction = foo::FooExtension|get#foo(null);
|
||||
static field foo::Foo extensionFooFunctionCall = main::extensionFooFunction(){() → foo::Foo};
|
||||
static field foo::Foo extensionBar = foo::FooExtension|bar(null, $creationLocationd_0dea112b090073317d4: #C43);
|
||||
static field foo::Foo extensionBaz = foo::FooExtension|baz(null);
|
||||
static field foo::Foo extensionBoz = foo::FooExtension|boz(null);
|
||||
static field foo::Foo extensionConstFoo = foo::FooExtension|constFoo(null, $creationLocationd_0dea112b090073317d4: #C45);
|
||||
static field foo::Foo extensionGetterFoo = foo::FooExtension|get#getterFoo(null, $creationLocationd_0dea112b090073317d4: #C49);
|
||||
static field () → Null extensionSetterFoo = () → Null => let final has-declared-initializer Null #t1 = null in let final void #t2 = foo::FooExtension|set#setterFoo(null, #t1, $creationLocationd_0dea112b090073317d4: #C53) in #t1;
|
||||
static field foo::Foo extensionOperatorFoo = foo::FooExtension|unary-(null, $creationLocationd_0dea112b090073317d4: #C56);
|
||||
static field foo::Foo extensionStaticFoo = foo::FooExtension|staticFoo();
|
||||
}
|
||||
constants {
|
||||
#C1 = "track-creation-locations"
|
||||
#C2 = null
|
||||
#C3 = dart.core::pragma {name:#C1, options:#C2}
|
||||
#C4 = "org-dartlang-test:///foo.dart"
|
||||
#C5 = 8.0
|
||||
#C6 = 26.0
|
||||
#C7 = "Foo"
|
||||
#C8 = dart.developer::CreationLocation {file:#C4, line:#C5, column:#C6, name:#C7}
|
||||
#C9 = foo::Foo {_location:#C8}
|
||||
#C10 = 11.0
|
||||
#C11 = dart.developer::CreationLocation {file:#C4, line:#C5, column:#C10, name:#C7}
|
||||
#C12 = 10.0
|
||||
#C13 = 9.0
|
||||
#C14 = dart.developer::CreationLocation {file:#C4, line:#C12, column:#C13, name:#C7}
|
||||
#C15 = 14.0
|
||||
#C16 = 3.0
|
||||
#C17 = "FooExtension|foo"
|
||||
#C18 = dart.developer::CreationLocation {file:#C4, line:#C15, column:#C16, name:#C17}
|
||||
#C19 = 17.0
|
||||
#C20 = "FooExtension|bar"
|
||||
#C21 = dart.developer::CreationLocation {file:#C4, line:#C19, column:#C16, name:#C20}
|
||||
#C22 = 21.0
|
||||
#C23 = 20.0
|
||||
#C24 = dart.developer::CreationLocation {file:#C4, line:#C22, column:#C23, name:#C7}
|
||||
#C25 = 24.0
|
||||
#C26 = dart.developer::CreationLocation {file:#C4, line:#C25, column:#C23, name:#C7}
|
||||
#C27 = 27.0
|
||||
#C28 = dart.developer::CreationLocation {file:#C4, line:#C27, column:#C27, name:#C7}
|
||||
#C29 = foo::Foo {_location:#C28}
|
||||
#C30 = "FooExtension|constFoo"
|
||||
#C31 = dart.developer::CreationLocation {file:#C4, line:#C6, column:#C16, name:#C30}
|
||||
#C32 = 39.0
|
||||
#C33 = 33.0
|
||||
#C34 = dart.developer::CreationLocation {file:#C4, line:#C32, column:#C33, name:#C7}
|
||||
#C35 = "org-dartlang-test:///main.dart"
|
||||
#C36 = 2.0
|
||||
#C37 = 18.0
|
||||
#C38 = dart.developer::CreationLocation {file:#C35, line:#C36, column:#C37, name:#C7}
|
||||
#C39 = static-tearoff foo::Foo::_#new#tearOff
|
||||
#C40 = 5.0
|
||||
#C41 = 25.0
|
||||
#C42 = dart.developer::CreationLocation {file:#C35, line:#C40, column:#C41, name:#C17}
|
||||
#C43 = dart.developer::CreationLocation {file:#C35, line:#C5, column:#C41, name:#C20}
|
||||
#C44 = 30.0
|
||||
#C45 = dart.developer::CreationLocation {file:#C35, line:#C10, column:#C44, name:#C30}
|
||||
#C46 = 12.0
|
||||
#C47 = 31.0
|
||||
#C48 = "FooExtension|get#getterFoo"
|
||||
#C49 = dart.developer::CreationLocation {file:#C35, line:#C46, column:#C47, name:#C48}
|
||||
#C50 = 13.0
|
||||
#C51 = 37.0
|
||||
#C52 = "FooExtension|set#setterFoo"
|
||||
#C53 = dart.developer::CreationLocation {file:#C35, line:#C50, column:#C51, name:#C52}
|
||||
#C54 = 28.0
|
||||
#C55 = "FooExtension|unary-"
|
||||
#C56 = dart.developer::CreationLocation {file:#C35, line:#C15, column:#C54, name:#C55}
|
||||
}
|
||||
|
||||
|
||||
Constructor coverage from constants:
|
||||
org-dartlang-test:///main.dart:
|
||||
- CreationLocation._ (from org-dartlang-sdk:///lib/developer/creation_tracking.dart)
|
||||
- Object. (from org-dartlang-sdk:///lib/core/object.dart)
|
||||
|
||||
org-dartlang-test:///foo.dart:
|
||||
- CreationLocation._ (from org-dartlang-sdk:///lib/developer/creation_tracking.dart)
|
||||
- Object. (from org-dartlang-sdk:///lib/core/object.dart)
|
||||
- Foo._ (from org-dartlang-test:///foo.dart:10:9)
|
||||
- Widget. (from org-dartlang-test:///flutter/lib/src/widgets/framework.dart:9:9)
|
||||
- Bar. (from org-dartlang-test:///flutter/lib/src/widgets/framework.dart:4:9)
|
||||
|
||||
org-dartlang-test:///flutter/lib/src/widgets/framework.dart:
|
||||
- pragma._ (from org-dartlang-sdk:///lib/core/annotations.dart)
|
||||
- Object. (from org-dartlang-sdk:///lib/core/object.dart)
|
||||
|
||||
org-dartlang-test:///flutter/lib/src/widgets/widget_inspector.dart:
|
||||
- pragma._ (from org-dartlang-sdk:///lib/core/annotations.dart)
|
||||
- Object. (from org-dartlang-sdk:///lib/core/object.dart)
|
||||
|
||||
+194
@@ -0,0 +1,194 @@
|
||||
main = <No Member>;
|
||||
library from "package:flutter/src/widgets/framework.dart" as fra {
|
||||
additionalExports = (wid::widgetFactory)
|
||||
|
||||
export "package:flutter/src/widgets/widget_inspector.dart" show widgetFactory;
|
||||
|
||||
abstract class Bar extends dart.core::Object /*hasConstConstructor*/ {
|
||||
const constructor •() → fra::Bar
|
||||
: super dart.core::Object::•()
|
||||
;
|
||||
}
|
||||
@#C3
|
||||
abstract class Widget extends fra::Bar implements dart.developer::_HasCreationLocation /*hasConstConstructor*/ {
|
||||
final field dart.developer::CreationLocation? dart.developer::_location;
|
||||
const constructor •({dart.developer::CreationLocation? $creationLocationd_0dea112b090073317d4 = #C2}) → fra::Widget
|
||||
: super fra::Bar::•(), fra::Widget::_location = $creationLocationd_0dea112b090073317d4
|
||||
;
|
||||
}
|
||||
}
|
||||
library from "package:flutter/src/widgets/widget_inspector.dart" as wid {
|
||||
|
||||
static const field dart.core::pragma widgetFactory = #C3;
|
||||
}
|
||||
library from "org-dartlang-test:///foo.dart" as foo {
|
||||
|
||||
import "package:flutter/src/widgets/framework.dart";
|
||||
|
||||
class Foo extends fra::Widget /*hasConstConstructor*/ {
|
||||
const constructor _({dart.developer::CreationLocation? $creationLocationd_0dea112b090073317d4 = #C2}) → foo::Foo
|
||||
: super fra::Widget::•($creationLocationd_0dea112b090073317d4: $creationLocationd_0dea112b090073317d4)
|
||||
;
|
||||
static factory •({dart.developer::CreationLocation? $creationLocationd_0dea112b090073317d4 = #C2}) → foo::Foo
|
||||
return #C9;
|
||||
static synthetic method _#new#tearOff() → foo::Foo
|
||||
return foo::Foo::•($creationLocationd_0dea112b090073317d4: #C11);
|
||||
static synthetic method _#_#tearOff() → foo::Foo
|
||||
return new foo::Foo::_($creationLocationd_0dea112b090073317d4: #C14);
|
||||
}
|
||||
extension FooExtension on dart.core::Object? {
|
||||
method foo = foo::FooExtension|foo;
|
||||
method tearoff foo = foo::FooExtension|get#foo;
|
||||
method bar = foo::FooExtension|bar;
|
||||
method tearoff bar = foo::FooExtension|get#bar;
|
||||
method baz = foo::FooExtension|baz;
|
||||
method tearoff baz = foo::FooExtension|get#baz;
|
||||
method boz = foo::FooExtension|boz;
|
||||
method tearoff boz = foo::FooExtension|get#boz;
|
||||
method constFoo = foo::FooExtension|constFoo;
|
||||
method tearoff constFoo = foo::FooExtension|get#constFoo;
|
||||
get getterFoo = foo::FooExtension|get#getterFoo;
|
||||
set setterFoo = foo::FooExtension|set#setterFoo;
|
||||
operator unary- = foo::FooExtension|unary-;
|
||||
static method staticFoo = foo::FooExtension|staticFoo;
|
||||
}
|
||||
static const field dart.core::pragma alias = #C3;
|
||||
static const field dart.core::pragma? nullableAlias = #C2;
|
||||
static const field dart.core::pragma nonNullableAlias = #C3;
|
||||
@#C3
|
||||
static extension-member method FooExtension|foo(lowered final dart.core::Object? #this, {dart.developer::CreationLocation? $creationLocationd_0dea112b090073317d4 = #C2}) → foo::Foo
|
||||
return new foo::Foo::_($creationLocationd_0dea112b090073317d4: $creationLocationd_0dea112b090073317d4);
|
||||
static extension-member method FooExtension|get#foo(lowered final dart.core::Object? #this) → () → foo::Foo
|
||||
return () → foo::Foo => foo::FooExtension|foo(#this, $creationLocationd_0dea112b090073317d4: #C18);
|
||||
@#C3
|
||||
static extension-member method FooExtension|bar(lowered final dart.core::Object? #this, {dart.developer::CreationLocation? $creationLocationd_0dea112b090073317d4 = #C2}) → foo::Foo
|
||||
return new foo::Foo::_($creationLocationd_0dea112b090073317d4: $creationLocationd_0dea112b090073317d4);
|
||||
static extension-member method FooExtension|get#bar(lowered final dart.core::Object? #this) → () → foo::Foo
|
||||
return () → foo::Foo => foo::FooExtension|bar(#this, $creationLocationd_0dea112b090073317d4: #C21);
|
||||
@#C2
|
||||
static extension-member method FooExtension|baz(lowered final dart.core::Object? #this) → foo::Foo
|
||||
return new foo::Foo::_($creationLocationd_0dea112b090073317d4: #C24);
|
||||
static extension-member method FooExtension|get#baz(lowered final dart.core::Object? #this) → () → foo::Foo
|
||||
return () → foo::Foo => foo::FooExtension|baz(#this);
|
||||
@#C3
|
||||
static extension-member method FooExtension|boz(lowered final dart.core::Object? #this) → foo::Foo
|
||||
return new foo::Foo::_($creationLocationd_0dea112b090073317d4: #C26);
|
||||
static extension-member method FooExtension|get#boz(lowered final dart.core::Object? #this) → () → foo::Foo
|
||||
return () → foo::Foo => foo::FooExtension|boz(#this);
|
||||
@#C3
|
||||
static extension-member method FooExtension|constFoo(lowered final dart.core::Object? #this, {dart.developer::CreationLocation? $creationLocationd_0dea112b090073317d4 = #C2}) → foo::Foo
|
||||
return #C29;
|
||||
static extension-member method FooExtension|get#constFoo(lowered final dart.core::Object? #this) → () → foo::Foo
|
||||
return () → foo::Foo => foo::FooExtension|constFoo(#this, $creationLocationd_0dea112b090073317d4: #C31);
|
||||
@#C3
|
||||
static extension-member method FooExtension|get#getterFoo(lowered final dart.core::Object? #this, {dart.developer::CreationLocation? $creationLocationd_0dea112b090073317d4 = #C2}) → foo::Foo
|
||||
return new foo::Foo::_($creationLocationd_0dea112b090073317d4: $creationLocationd_0dea112b090073317d4);
|
||||
@#C3
|
||||
static extension-member method FooExtension|set#setterFoo(lowered final dart.core::Object? #this, wildcard dynamic _#wc0#formal, {dart.developer::CreationLocation? $creationLocationd_0dea112b090073317d4 = #C2}) → void
|
||||
return new foo::Foo::_($creationLocationd_0dea112b090073317d4: $creationLocationd_0dea112b090073317d4);
|
||||
@#C3
|
||||
static extension-member method FooExtension|unary-(lowered final dart.core::Object? #this, {dart.developer::CreationLocation? $creationLocationd_0dea112b090073317d4 = #C2}) → foo::Foo
|
||||
return new foo::Foo::_($creationLocationd_0dea112b090073317d4: $creationLocationd_0dea112b090073317d4);
|
||||
@#C3
|
||||
static extension-member method FooExtension|staticFoo() → foo::Foo
|
||||
return new foo::Foo::_($creationLocationd_0dea112b090073317d4: #C34);
|
||||
}
|
||||
library from "org-dartlang-test:///main.dart" as main {
|
||||
|
||||
import "org-dartlang-test:///foo.dart";
|
||||
|
||||
static field foo::Foo extensionConstFoo = foo::FooExtension|constFoo(null, $creationLocationd_0dea112b090073317d4: #C38);
|
||||
static field foo::Foo newFoo = foo::Foo::•($creationLocationd_0dea112b090073317d4: #C40);
|
||||
static field () → foo::Foo newFooFunction = #C41;
|
||||
static field foo::Foo newFooFunctionCall = main::newFooFunction(){() → foo::Foo};
|
||||
static field foo::Foo extensionFoo = foo::FooExtension|foo(null, $creationLocationd_0dea112b090073317d4: #C44);
|
||||
static field ({$creationLocationd_0dea112b090073317d4: dart.developer::CreationLocation?}) → foo::Foo extensionFooFunction = foo::FooExtension|get#foo(null);
|
||||
static field foo::Foo extensionFooFunctionCall = main::extensionFooFunction(){({$creationLocationd_0dea112b090073317d4: dart.developer::CreationLocation?}) → foo::Foo};
|
||||
static field foo::Foo extensionBar = foo::FooExtension|bar(null, $creationLocationd_0dea112b090073317d4: #C45);
|
||||
static field foo::Foo extensionBaz = foo::FooExtension|baz(null);
|
||||
static field foo::Foo extensionBoz = foo::FooExtension|boz(null);
|
||||
static field foo::Foo extensionGetterFoo = foo::FooExtension|get#getterFoo(null, $creationLocationd_0dea112b090073317d4: #C49);
|
||||
static field () → Null extensionSetterFoo = () → Null => let final has-declared-initializer Null #t1 = null in let final void #t2 = foo::FooExtension|set#setterFoo(null, #t1, $creationLocationd_0dea112b090073317d4: #C53) in #t1;
|
||||
static field foo::Foo extensionOperatorFoo = foo::FooExtension|unary-(null, $creationLocationd_0dea112b090073317d4: #C56);
|
||||
static field foo::Foo extensionStaticFoo = foo::FooExtension|staticFoo();
|
||||
}
|
||||
constants {
|
||||
#C1 = "track-creation-locations"
|
||||
#C2 = null
|
||||
#C3 = dart.core::pragma {name:#C1, options:#C2}
|
||||
#C4 = "org-dartlang-test:///foo.dart"
|
||||
#C5 = 8.0
|
||||
#C6 = 26.0
|
||||
#C7 = "Foo"
|
||||
#C8 = dart.developer::CreationLocation {file:#C4, line:#C5, column:#C6, name:#C7}
|
||||
#C9 = foo::Foo {_location:#C8}
|
||||
#C10 = 11.0
|
||||
#C11 = dart.developer::CreationLocation {file:#C4, line:#C5, column:#C10, name:#C7}
|
||||
#C12 = 10.0
|
||||
#C13 = 9.0
|
||||
#C14 = dart.developer::CreationLocation {file:#C4, line:#C12, column:#C13, name:#C7}
|
||||
#C15 = 14.0
|
||||
#C16 = 3.0
|
||||
#C17 = "FooExtension|foo"
|
||||
#C18 = dart.developer::CreationLocation {file:#C4, line:#C15, column:#C16, name:#C17}
|
||||
#C19 = 17.0
|
||||
#C20 = "FooExtension|bar"
|
||||
#C21 = dart.developer::CreationLocation {file:#C4, line:#C19, column:#C16, name:#C20}
|
||||
#C22 = 21.0
|
||||
#C23 = 20.0
|
||||
#C24 = dart.developer::CreationLocation {file:#C4, line:#C22, column:#C23, name:#C7}
|
||||
#C25 = 24.0
|
||||
#C26 = dart.developer::CreationLocation {file:#C4, line:#C25, column:#C23, name:#C7}
|
||||
#C27 = 27.0
|
||||
#C28 = dart.developer::CreationLocation {file:#C4, line:#C27, column:#C27, name:#C7}
|
||||
#C29 = foo::Foo {_location:#C28}
|
||||
#C30 = "FooExtension|constFoo"
|
||||
#C31 = dart.developer::CreationLocation {file:#C4, line:#C6, column:#C16, name:#C30}
|
||||
#C32 = 39.0
|
||||
#C33 = 33.0
|
||||
#C34 = dart.developer::CreationLocation {file:#C4, line:#C32, column:#C33, name:#C7}
|
||||
#C35 = "org-dartlang-test:///main.dart"
|
||||
#C36 = 2.0
|
||||
#C37 = 30.0
|
||||
#C38 = dart.developer::CreationLocation {file:#C35, line:#C36, column:#C37, name:#C30}
|
||||
#C39 = 18.0
|
||||
#C40 = dart.developer::CreationLocation {file:#C35, line:#C16, column:#C39, name:#C7}
|
||||
#C41 = static-tearoff foo::Foo::_#new#tearOff
|
||||
#C42 = 6.0
|
||||
#C43 = 25.0
|
||||
#C44 = dart.developer::CreationLocation {file:#C35, line:#C42, column:#C43, name:#C17}
|
||||
#C45 = dart.developer::CreationLocation {file:#C35, line:#C13, column:#C43, name:#C20}
|
||||
#C46 = 12.0
|
||||
#C47 = 31.0
|
||||
#C48 = "FooExtension|get#getterFoo"
|
||||
#C49 = dart.developer::CreationLocation {file:#C35, line:#C46, column:#C47, name:#C48}
|
||||
#C50 = 13.0
|
||||
#C51 = 37.0
|
||||
#C52 = "FooExtension|set#setterFoo"
|
||||
#C53 = dart.developer::CreationLocation {file:#C35, line:#C50, column:#C51, name:#C52}
|
||||
#C54 = 28.0
|
||||
#C55 = "FooExtension|unary-"
|
||||
#C56 = dart.developer::CreationLocation {file:#C35, line:#C15, column:#C54, name:#C55}
|
||||
}
|
||||
|
||||
|
||||
Constructor coverage from constants:
|
||||
org-dartlang-test:///foo.dart:
|
||||
- CreationLocation._ (from org-dartlang-sdk:///lib/developer/creation_tracking.dart)
|
||||
- Object. (from org-dartlang-sdk:///lib/core/object.dart)
|
||||
- Foo._ (from org-dartlang-test:///foo.dart:10:9)
|
||||
- Widget. (from org-dartlang-test:///flutter/lib/src/widgets/framework.dart:9:9)
|
||||
- Bar. (from org-dartlang-test:///flutter/lib/src/widgets/framework.dart:4:9)
|
||||
|
||||
org-dartlang-test:///flutter/lib/src/widgets/framework.dart:
|
||||
- pragma._ (from org-dartlang-sdk:///lib/core/annotations.dart)
|
||||
- Object. (from org-dartlang-sdk:///lib/core/object.dart)
|
||||
|
||||
org-dartlang-test:///flutter/lib/src/widgets/widget_inspector.dart:
|
||||
- pragma._ (from org-dartlang-sdk:///lib/core/annotations.dart)
|
||||
- Object. (from org-dartlang-sdk:///lib/core/object.dart)
|
||||
|
||||
org-dartlang-test:///main.dart:
|
||||
- CreationLocation._ (from org-dartlang-sdk:///lib/developer/creation_tracking.dart)
|
||||
- Object. (from org-dartlang-sdk:///lib/core/object.dart)
|
||||
|
||||
@@ -218,13 +218,19 @@ class _WidgetCallSiteTransformer extends Transformer {
|
||||
);
|
||||
return node;
|
||||
}
|
||||
if (_isWidgetFactory(target) && _tracker._locationClass != null) {
|
||||
_addLocationArgument(
|
||||
node,
|
||||
target.function,
|
||||
locationClass: _tracker._locationClass!,
|
||||
if (_isWidgetFactory(target)) {
|
||||
final Variable parameter = target.function.namedParameters.firstWhere(
|
||||
(p) => p.name == _creationLocationParameterName,
|
||||
);
|
||||
return node;
|
||||
final DartType type = parameter.type;
|
||||
if (type is InterfaceType) {
|
||||
_addLocationArgument(
|
||||
node,
|
||||
target.function,
|
||||
locationClass: type.classNode,
|
||||
);
|
||||
return node;
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
@@ -383,7 +389,6 @@ class WidgetCreatorTracker {
|
||||
void _resolveWellKnownClasses(Iterable<Library> libraries) {
|
||||
// If the Widget or Debug location classes have been updated we need to get
|
||||
// the latest version
|
||||
|
||||
for (Library library in libraries) {
|
||||
final Uri importUri = library.importUri;
|
||||
|
||||
@@ -589,14 +594,12 @@ class WidgetCreatorTracker {
|
||||
changedStructureNotifier,
|
||||
);
|
||||
}
|
||||
if (_widgetFactoryClass != null) {
|
||||
for (Extension extension in library.extensions) {
|
||||
_transformWidgetFactories(
|
||||
librariesToTransform,
|
||||
transformedExtensions,
|
||||
extension,
|
||||
);
|
||||
}
|
||||
for (Extension extension in library.extensions) {
|
||||
_transformExtension(
|
||||
librariesToTransform,
|
||||
transformedExtensions,
|
||||
extension,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -612,17 +615,6 @@ class WidgetCreatorTracker {
|
||||
}
|
||||
|
||||
_TrackingClasses? _getTrackingClasses(Class clazz) {
|
||||
// Legacy Case: Check for widget class.
|
||||
if (_isSubclassOfWidget(clazz)) {
|
||||
if (_hasCreationLocationClass != null && _locationClass != null) {
|
||||
return new _TrackingClasses(
|
||||
hasCreationLocationClass: _hasCreationLocationClass!,
|
||||
locationClass: _locationClass!,
|
||||
locationFieldName: _locationFieldName,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// New Case: Check for 'pragma('track-creation-locations')' annotation.
|
||||
if (_hasTrackCreationLocationsPragmaAnnotation(clazz)) {
|
||||
if (_developerHasCreationLocationClass != null &&
|
||||
@@ -635,6 +627,17 @@ class WidgetCreatorTracker {
|
||||
}
|
||||
}
|
||||
|
||||
// Legacy Case: Check for widget class.
|
||||
if (_isSubclassOfWidget(clazz)) {
|
||||
if (_hasCreationLocationClass != null && _locationClass != null) {
|
||||
return new _TrackingClasses(
|
||||
hasCreationLocationClass: _hasCreationLocationClass!,
|
||||
locationClass: _locationClass!,
|
||||
locationFieldName: _locationFieldName,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -645,50 +648,81 @@ class WidgetCreatorTracker {
|
||||
|
||||
bool _hasTrackCreationLocationsPragmaAnnotation(Class clazz) {
|
||||
if (_developerHasCreationLocationClass == null) return false;
|
||||
return _isSubclassWhere(clazz, (Class c) {
|
||||
for (Expression annotation in c.annotations) {
|
||||
// Case before constant evaluation (newly compiled modules).
|
||||
if (annotation is RedirectingFactoryInvocation) {
|
||||
final expression = annotation.expression;
|
||||
return _isSubclassWhere(
|
||||
clazz,
|
||||
(Class c) => _hasPragmaAnnotation(c, 'track-creation-locations'),
|
||||
);
|
||||
}
|
||||
|
||||
if (expression is ConstructorInvocation) {
|
||||
final Class enclosingClass = expression.target.enclosingClass;
|
||||
bool _hasPragmaAnnotation(Annotatable node, String pragmaName) {
|
||||
for (Expression annotation in node.annotations) {
|
||||
if (_getPragmaName(annotation) == pragmaName) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (enclosingClass.name == 'pragma' &&
|
||||
enclosingClass.enclosingLibrary.importUri.toString() ==
|
||||
'dart:core') {
|
||||
if (expression.arguments.positional.isNotEmpty) {
|
||||
final Expression firstArg =
|
||||
expression.arguments.positional.first;
|
||||
if (firstArg is StringLiteral &&
|
||||
firstArg.value == 'track-creation-locations') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
String? _getPragmaName(Expression expression) {
|
||||
// Direct invocation, e.g. `@pragma('...')`.
|
||||
// Applies before constant evaluation (newly compiled modules).
|
||||
if (expression
|
||||
case RedirectingFactoryInvocation(
|
||||
expression: final ConstructorInvocation invocation,
|
||||
) ||
|
||||
final ConstructorInvocation invocation) {
|
||||
final Class enclosingClass = invocation.target.enclosingClass;
|
||||
if (enclosingClass.name == 'pragma' &&
|
||||
enclosingClass.enclosingLibrary.importUri.toString() == 'dart:core') {
|
||||
if (invocation.arguments.positional.isNotEmpty) {
|
||||
final Expression firstArg = invocation.arguments.positional.first;
|
||||
if (firstArg is StringLiteral) {
|
||||
return firstArg.value;
|
||||
}
|
||||
}
|
||||
// Case after constant evaluation (incremental or modular compilation).
|
||||
if (annotation case ConstantExpression(
|
||||
constant: final InstanceConstant constant,
|
||||
)) {
|
||||
final Class enclosingClass = constant.classNode;
|
||||
}
|
||||
}
|
||||
|
||||
if (enclosingClass.name == 'pragma' &&
|
||||
enclosingClass.enclosingLibrary.importUri.toString() ==
|
||||
'dart:core') {
|
||||
for (final Constant value in constant.fieldValues.values) {
|
||||
if (value case StringConstant(
|
||||
value: 'track-creation-locations',
|
||||
)) {
|
||||
return true;
|
||||
}
|
||||
// Aliased constant, e.g. `@widgetFactory`
|
||||
// with `const widgetFactory = pragma('...');`.
|
||||
// Applies before constant evaluation (newly compiled modules).
|
||||
if (expression is StaticGet) {
|
||||
final Member target = expression.target;
|
||||
if (target is Field && target.isConst) {
|
||||
if (target.initializer != null) {
|
||||
return _getPragmaName(target.initializer!);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Evaluated constant pragma.
|
||||
// Applies after constant evaluation (incremental or modular compilation).
|
||||
if (expression is ConstantExpression) {
|
||||
final Constant constant = expression.constant;
|
||||
if (constant is InstanceConstant) {
|
||||
final Class enclosingClass = constant.classNode;
|
||||
if (enclosingClass.name == 'pragma' &&
|
||||
enclosingClass.enclosingLibrary.importUri.toString() ==
|
||||
'dart:core') {
|
||||
for (final Constant value in constant.fieldValues.values) {
|
||||
if (value is StringConstant) {
|
||||
return value.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Class? _getFactoryLocationClass(Procedure method) {
|
||||
if (_hasPragmaAnnotation(method, 'track-creation-locations')) {
|
||||
return _developerCreationLocationClass;
|
||||
}
|
||||
if (_hasWidgetFactoryAnnotation(method)) {
|
||||
return _locationClass;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
bool _isSubclassWhere(Class a, bool Function(Class b) predicate) {
|
||||
@@ -845,14 +879,13 @@ class WidgetCreatorTracker {
|
||||
clazz.constructors.forEach(handleConstructor);
|
||||
}
|
||||
|
||||
void _transformWidgetFactories(
|
||||
void _transformExtension(
|
||||
Set<Library> librariesToBeTransformed,
|
||||
Set<Extension> transformedExtensions,
|
||||
Extension extension,
|
||||
) {
|
||||
// TODO(johnniwinther): We should have a lint for unsupported use of
|
||||
// `@widgetFactory`.
|
||||
assert(_widgetFactoryClass != null);
|
||||
|
||||
if (!librariesToBeTransformed.contains(extension.enclosingLibrary) ||
|
||||
!transformedExtensions.add(extension)) {
|
||||
@@ -866,35 +899,34 @@ class WidgetCreatorTracker {
|
||||
continue;
|
||||
}
|
||||
final Procedure? method = member.memberReference?.asProcedure;
|
||||
if (method != null && _hasWidgetFactoryAnnotation(method)) {
|
||||
_maybeAddNamedParameter(
|
||||
method.function,
|
||||
new Variable(
|
||||
_creationLocationParameterName,
|
||||
type: new InterfaceType(
|
||||
_locationClass!,
|
||||
extension.enclosingLibrary.nullable,
|
||||
),
|
||||
initializer: new NullLiteral(),
|
||||
),
|
||||
);
|
||||
if (method != null) {
|
||||
_transformExtensionProcedure(method, extension);
|
||||
}
|
||||
final Procedure? tearOff = member.tearOffReference?.asProcedure;
|
||||
if (tearOff != null && _hasWidgetFactoryAnnotation(tearOff)) {
|
||||
_maybeAddNamedParameter(
|
||||
tearOff.function,
|
||||
new Variable(
|
||||
_creationLocationParameterName,
|
||||
type: new InterfaceType(
|
||||
_locationClass!,
|
||||
extension.enclosingLibrary.nullable,
|
||||
),
|
||||
initializer: new NullLiteral(),
|
||||
),
|
||||
);
|
||||
if (tearOff != null) {
|
||||
_transformExtensionProcedure(tearOff, extension);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _transformExtensionProcedure(Procedure method, Extension extension) {
|
||||
final Class? locationClass = _getFactoryLocationClass(method);
|
||||
if (locationClass == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
_maybeAddNamedParameter(
|
||||
method.function,
|
||||
new Variable(
|
||||
_creationLocationParameterName,
|
||||
type: new InterfaceType(
|
||||
locationClass,
|
||||
extension.enclosingLibrary.nullable,
|
||||
),
|
||||
initializer: new NullLiteral(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Holds the set of creation location classes, either
|
||||
|
||||
@@ -92,6 +92,74 @@ void main() {
|
||||
);
|
||||
testLib.addProcedure(mainProcedure);
|
||||
|
||||
final Extension extension =
|
||||
new Extension(name: 'MyExtension', fileUri: testUri)
|
||||
..fileOffset = fileOffset
|
||||
..onType = const DynamicType();
|
||||
testLib.addExtension(extension);
|
||||
|
||||
final Procedure factoryMethod =
|
||||
new Procedure(
|
||||
new Name('myFactory'),
|
||||
ProcedureKind.Method,
|
||||
new FunctionNode(
|
||||
new Block([
|
||||
new ReturnStatement(
|
||||
new ConstructorInvocation(
|
||||
myWidgetClass.constructors.first,
|
||||
new Arguments([]),
|
||||
)..fileOffset = fileOffset,
|
||||
),
|
||||
]),
|
||||
returnType: new InterfaceType(
|
||||
myWidgetClass,
|
||||
Nullability.nonNullable,
|
||||
),
|
||||
),
|
||||
isStatic: true,
|
||||
fileUri: testUri,
|
||||
)
|
||||
..fileOffset = fileOffset
|
||||
..isExtensionMember = true;
|
||||
factoryMethod.addAnnotation(
|
||||
new ConstantExpression(
|
||||
new InstanceConstant(
|
||||
pragmaClass.reference,
|
||||
<DartType>[],
|
||||
<Reference, Constant>{
|
||||
pragmaNameField.fieldReference: new StringConstant(
|
||||
'track-creation-locations',
|
||||
),
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
testLib.addProcedure(factoryMethod);
|
||||
|
||||
extension.memberDescriptors.add(
|
||||
new ExtensionMemberDescriptor(
|
||||
name: new Name('myFactory'),
|
||||
kind: ExtensionMemberKind.Method,
|
||||
memberReference: factoryMethod.reference,
|
||||
tearOffReference: null,
|
||||
),
|
||||
);
|
||||
|
||||
final Block newBody = new Block([
|
||||
new ExpressionStatement(
|
||||
new ConstructorInvocation(
|
||||
myWidgetClass.constructors.first,
|
||||
new Arguments([]),
|
||||
)..fileOffset = fileOffset,
|
||||
),
|
||||
new ExpressionStatement(
|
||||
new StaticInvocation(factoryMethod, new Arguments([]))
|
||||
..fileOffset = fileOffset,
|
||||
),
|
||||
]);
|
||||
newBody.parent = mainProcedure.function;
|
||||
mainProcedure.function.body = newBody;
|
||||
|
||||
final WidgetCreatorTracker tracker = new WidgetCreatorTracker();
|
||||
tracker.transform([testLib], [developerLib, testLib], null);
|
||||
|
||||
@@ -124,8 +192,30 @@ void main() {
|
||||
final NamedExpression namedArg = invocation.arguments.named.firstWhere(
|
||||
(n) => n.name.startsWith(creationLocationPrefix),
|
||||
);
|
||||
|
||||
Expect.isTrue(namedArg.value is ConstructorInvocation);
|
||||
final ConstructorInvocation locInvocation =
|
||||
namedArg.value as ConstructorInvocation;
|
||||
Expect.equals(creationLocationClass, locInvocation.target.enclosingClass);
|
||||
|
||||
Expect.isTrue(
|
||||
factoryMethod.function.namedParameters.any(
|
||||
(p) => p.name!.startsWith(creationLocationPrefix),
|
||||
),
|
||||
);
|
||||
|
||||
final ExpressionStatement stmt2 = body.statements[1] as ExpressionStatement;
|
||||
final StaticInvocation staticInv = stmt2.expression as StaticInvocation;
|
||||
Expect.isTrue(
|
||||
staticInv.arguments.named.any(
|
||||
(n) => n.name.startsWith(creationLocationPrefix),
|
||||
),
|
||||
);
|
||||
final NamedExpression namedArg2 = staticInv.arguments.named.firstWhere(
|
||||
(n) => n.name.startsWith(creationLocationPrefix),
|
||||
);
|
||||
Expect.isTrue(namedArg2.value is ConstructorInvocation);
|
||||
final ConstructorInvocation locInvocation2 =
|
||||
namedArg2.value as ConstructorInvocation;
|
||||
Expect.equals(creationLocationClass, locInvocation2.target.enclosingClass);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user