Skip to content

ensure CheckLibraryIsLoaded guards the left-most immediate expression #35320

Open
@sigmundch

Description

@sigmundch

To simplify how we implement #35005, we need the AST to always include the CheckLibraryIsLoaded on the left-most immediate expression. For example:

a.dart

import 'b.dart' deferred as d;

main() {
  d.loadLibrary().then((_) {
    new d.A().property1;
    d.field.property1;
    d.field.property1.property2;
    d.method().property1;
    d.field.method();
    d.field.method().property1;
    d.A.static1.property1;
    d.A.method2().property1;
  });
}

b.dart

class A {
  A() { print ('hi'); }

  A method() => null;
  A property1;
  A property2;

  static A static1;
  static A method2() => null;
}

A field = new A();
A method() => new A();

Generates:

library;
import self as self;
import "dart:core" as core;
import "./b.dart" as b;

static method main() → dynamic {
  (LoadLibrary(d)).{dart.async::Future::then}<dynamic>((dynamic _) → core::Null {
    (let final dynamic #t1 = CheckLibraryIsLoaded(d) in new b::A::•()).{b::A::property1};
    let final dynamic #t2 = CheckLibraryIsLoaded(d) in b::field.{b::A::property1};
    let final dynamic #t3 = CheckLibraryIsLoaded(d) in b::field.{b::A::property1}.{b::A::property2};
    (let final dynamic #t4 = CheckLibraryIsLoaded(d) in b::method()).{b::A::property1};
    let final dynamic #t5 = CheckLibraryIsLoaded(d) in b::field.{b::A::method}();
    (let final dynamic #t6 = CheckLibraryIsLoaded(d) in b::field.{b::A::method}()).{b::A::property1};
    let final dynamic #t7 = CheckLibraryIsLoaded(d) in b::A::static1.{b::A::property1};
    (let final dynamic #t8 = CheckLibraryIsLoaded(d) in b::A::method2()).{b::A::property1};
  });
}

But should instead generate:

library;
import self as self;
import "dart:core" as core;
import "./b.dart" as b;

static method main() → dynamic {
  (LoadLibrary(d)).{dart.async::Future::then}<dynamic>((dynamic _) → core::Null {
    (let final dynamic #t1 = CheckLibraryIsLoaded(d) in new b::A::•()).{b::A::property1};
    (let final dynamic #t2 = CheckLibraryIsLoaded(d) in b::field).{b::A::property1};
    (let final dynamic #t3 = CheckLibraryIsLoaded(d) in b::field).{b::A::property1}.{b::A::property2};
    (let final dynamic #t4 = CheckLibraryIsLoaded(d) in b::method()).{b::A::property1};
    (let final dynamic #t5 = CheckLibraryIsLoaded(d) in b::field).{b::A::method}();
    (let final dynamic #t6 = CheckLibraryIsLoaded(d) in b::field).{b::A::method}().{b::A::property1};
    (let final dynamic #t7 = CheckLibraryIsLoaded(d) in b::A::static1).{b::A::property1};
    (let final dynamic #t8 = CheckLibraryIsLoaded(d) in b::A::method2()).{b::A::property1};
  });
}

It appears that we are already doing the correct thing for method calls, we just need to fix how field accesses are generated.

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions