Skip to content

Remove "cyclic" references #2969

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

Merged
merged 3 commits into from
Apr 23, 2020
Merged

Remove "cyclic" references #2969

merged 3 commits into from
Apr 23, 2020

Conversation

schmidt-sebastian
Copy link
Contributor

Static members of classes introduce something akin to cyclic references, which prevents the Rollup build from detecting that code is unused. A simple example is:

class Precondition {
   static NONE = new Precondition();
}

This translates to the following JavaScript code:

class Precondition {
}
Precondition.NONE = new Precondition(); 

In this example, Rollup doesn't know whether NONE = new Precondition() is side-effect free, and hence keeps the member and the class. This PR removes all static member variables and replaces them either with const enums (which are inlined) or member functions.

@google-oss-bot
Copy link
Contributor

google-oss-bot commented Apr 22, 2020

Binary Size Report

Affected SDKs

  • @firebase/firestore

    Type Base (a98a766) Head (5a50fa5) Diff
    browser 248 kB 247 kB -1.50 kB (-0.6%)
    esm2017 194 kB 193 kB -1.33 kB (-0.7%)
    main 489 kB 486 kB -2.42 kB (-0.5%)
    module 246 kB 245 kB -1.50 kB (-0.6%)
  • @firebase/firestore/memory

    Type Base (a98a766) Head (5a50fa5) Diff
    browser 189 kB 188 kB -1.51 kB (-0.8%)
    esm2017 149 kB 148 kB -1.34 kB (-0.9%)
    main 366 kB 363 kB -2.41 kB (-0.7%)
    module 188 kB 186 kB -1.51 kB (-0.8%)
  • firebase

    Type Base (a98a766) Head (5a50fa5) Diff
    firebase-firestore.js 290 kB 289 kB -1.45 kB (-0.5%)
    firebase-firestore.memory.js 232 kB 231 kB -1.46 kB (-0.6%)
    firebase.js 824 kB 822 kB -1.45 kB (-0.2%)

Test Logs

Copy link
Contributor

@dconeybe dconeybe left a comment

Choose a reason for hiding this comment

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

Is there a way to add a lint check to prevent this "static instance" anti-pattern from being used in the future?

isEqual(other: Operator): boolean {
return this.name === other.name;
}
export const enum Operator {
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider adding a function to convert from string to Operator in lieu of using the as operator at call sites. This function should invoke fail() if conversion fails. This would restore parity with the old code since the following logic from the deleted fromString() method has been lost:

default:
  return fail('Unknown FieldFilter operator: ' + op);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since we are using "const enums" the value of the operator is actually a string in the code. Hence, there is no conversion. We already validate that the input is one of the specific strings before we convert to the Operator type (via validateStringEnum). I changed validateStringEnum to do the casting on behalf of the caller, which means that the validation and the conversion now happens in the same place.

Copy link
Contributor

Choose a reason for hiding this comment

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

Looks great!

Copy link
Contributor Author

@schmidt-sebastian schmidt-sebastian left a comment

Choose a reason for hiding this comment

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

I will take a look to see if we can enable a lint setting to catch these cyclic references. It would need to specifically target static instance creations. If I find something, I will send that PR your way.

I am, however, planning to add unit tests that would catch these references. See https://github.com/firebase/firebase-js-sdk/pull/2972/files#diff-9d841c6ff52ac4a265de0910aa64844dR62. These tests would fail if we accidentally introduced a cyclic reference. A lint check is still preferable though.

@schmidt-sebastian
Copy link
Contributor Author

Update: I don't think there is a lint check that we can use here.

@schmidt-sebastian schmidt-sebastian merged commit 4ad5733 into master Apr 23, 2020
@schmidt-sebastian schmidt-sebastian deleted the mrschmidt/cherrypicks branch April 23, 2020 17:28
@firebase firebase locked and limited conversation to collaborators May 24, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants