Repository: angular
Issue: Shadowing built-ins confuses compiler
Labels: area: i18n,area: compiler

### Which @angular/* package(s) are the source of the bug?

compiler-cli

### Is this a regression?

No

### Description

If you attempt to extract messages from a component with the following import:

```typescript
import { $localize } from '@angular/localize/init';
```

### Please provide a link to a minimal reproduction of the bug

https://github.com/fischeversenker/ng-decorator-tree-shaking

### Please provide the exception or error you saw

```true
Messages from the component are not extracted.

This appears to be because the `$localize` import will be included in the generated JavaScript and so any user-authored or generated references to `$localize` actually refer to this _imported_ `$localize`, not the _global_ `$localize`. This appears to confuse the compiler and prevents it from extracting the messages.
```


### Please provide the environment you discovered this bug in (run `ng version`)

_No response_

### Anything else?

Spin off from https://github.com/angular/angular-cli/issues/24145#issuecomment-1358687296.

Fortunately this can be worked around by just `import '@angular/localize';` and using the global `$localize`. However I think this is indicative of a bigger problem in the compiler that it allows you to shadow built-in symbols. `$localize` is the most obvious one, but I think the same thing can happen to `i0`? The following snippet compiles without error:

```typescript
import { Component } from '@angular/core';
import { $localize } from '@angular/localize/init';

(() => {
  const i0 = null;

  @Component({
    selector: 'lib-library-with-localize',
    template: `<div i18n>unused library template with localize</div>`,
    standalone: true,
  })
  class LibraryWithLocalizeComponent {
    name = $localize`my name`;
  }
})();
```

I'm pretty sure that will fail at runtime given that the generated `i0.*` instructions will resolve to the `null` constant. `i0` is harder to misuse given that the compiler actually generates `import * as i0 from '...';`, so you get a name conflict if you define a top-level constant for it (which is also unintuitive, but better than compiling successfully and failing later). Also given that the symbol is only ever used in the code generated by `@Component()` (I think?) there aren't many situations outside of my contrived example where someone could reasonably shadow `i0` in a breaking manner.

We should consider banning any compiler built-in from being shadowed in user-code. Users just shouldn't be able to declare variables named `$localize` because they will have different semantics from the built-in symbol. For `i0`, I think the ideal fix would just be for the compiler to pick a different name (`i1`) if `i0` is already taken. Not sure how hard that is given that we'd probably want to verify _all_ symbols in the file, not just top-level declarations. Are there other "built-in symbols" we'd want to ban from user code?

Just to be a pedant, I'll point that out that _technically_ `with` becomes a problem here, since users could write something like:

```typescript
import '@angular/localize';

const imARealJerk = {
  $localize: () => { /* ... */ },
};

with (imARealJerk) {
  console.log($localize`Oh so you think you're such a wiz at CS205-Compilers?`);
}
```

Technically we could inspect the type of the object to look for `$localize` key, but that's probably not worth the effort and we could just ignore `with` cases. Just wanted to call that out.