Skip to content
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

Make macro configs static #1823

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 30 additions & 3 deletions packages/macros/src/babel/evaluate-json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type State from './state';
import dependencySatisfies from './dependency-satisfies';
import moduleExists from './module-exists';
import getConfig from './get-config';
import assertNever from 'assert-never';

type OpValue = string | boolean | number;

Expand Down Expand Up @@ -388,13 +389,39 @@ export class Evaluator {
return { confident: true, value: moduleExists(path, this.state), hasRuntimeImplementation: false };
}
if (callee.referencesImport('@embroider/macros', 'getConfig')) {
return { confident: true, value: getConfig(path, this.state, 'package'), hasRuntimeImplementation: true };
return { confident: true, value: getConfig(path, this.state, 'package'), hasRuntimeImplementation: false };
}
if (callee.referencesImport('@embroider/macros', 'getOwnConfig')) {
return { confident: true, value: getConfig(path, this.state, 'own'), hasRuntimeImplementation: true };
return { confident: true, value: getConfig(path, this.state, 'own'), hasRuntimeImplementation: false };
}
if (callee.referencesImport('@embroider/macros', 'getGlobalConfig')) {
return { confident: true, value: getConfig(path, this.state, 'getGlobalConfig'), hasRuntimeImplementation: true };
// Check for getGlobalConfig().fastboot.isRunning, which is the only pattern in use where config actually needs to have a runtime implementation.
// For compatibility reasons we will continue to support that. All other cases of macro configs are static now.
let maybeFastbootMemberExpression = path.parentPath;
if (
maybeFastbootMemberExpression.isMemberExpression() ||
maybeFastbootMemberExpression.isOptionalMemberExpression()
) {
let maybeFastbootProperty = maybeFastbootMemberExpression.isMemberExpression()
? maybeFastbootMemberExpression.get('property')
: maybeFastbootMemberExpression.isOptionalMemberExpression()
? maybeFastbootMemberExpression.get('property')
: assertNever(maybeFastbootMemberExpression);

if (maybeFastbootProperty.isIdentifier() && maybeFastbootProperty.node.name === 'fastboot') {
return {
confident: true,
value: getConfig(path, this.state, 'getGlobalConfig'),
hasRuntimeImplementation: true,
};
}
}

return {
confident: true,
value: getConfig(path, this.state, 'getGlobalConfig'),
hasRuntimeImplementation: false,
};
}
if (callee.referencesImport('@embroider/macros', 'isDevelopingApp')) {
return {
Expand Down
40 changes: 38 additions & 2 deletions packages/macros/tests/babel/eval.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,21 +164,57 @@ describe('hasRuntimeImplementation', function () {
let code = transform(`
import { getConfig } from '@embroider/macros';
const result = getConfig('foo')`);
expect(code).toMatch(`result = true`);
expect(code).toMatch(`result = false`);
});

test('getConfig property access', () => {
let code = transform(`
import { getConfig } from '@embroider/macros';
const result = getConfig('foo').bar`);
expect(code).toMatch(`result = false`);
});

// this is throwing internally, not sure how to fix
test.skip('getOwnConfig', () => {
let code = transform(`
import { getOwnConfig } from '@embroider/macros';
const result = getOwnConfig()`);
expect(code).toMatch(`result = true`);
expect(code).toMatch(`result = false`);
});

test('getGlobalConfig', () => {
let code = transform(`
import { getGlobalConfig } from '@embroider/macros';
const result = getGlobalConfig()`);
expect(code).toMatch(`result = false`);
});

test('getGlobalConfig property access', () => {
let code = transform(`
import { getGlobalConfig } from '@embroider/macros';
const result = getGlobalConfig().foo`);
expect(code).toMatch(`result = false`);
});

test('getGlobalConfig fastboot access', () => {
let code = transform(`
import { getGlobalConfig } from '@embroider/macros';
const result = getGlobalConfig().fastboot`);
expect(code).toMatch(`result = true`);
});

// fastboot.isRunning relies on dynamic evaluation at runtime. For backwards compatibility we keep it working. See https://github.com/embroider-build/embroider/issues/1804
test('getGlobalConfig fastboot.isRunning access', () => {
let code = transform(`
import { getGlobalConfig } from '@embroider/macros';
const result = getGlobalConfig().fastboot.isRunning`);
expect(code).toMatch(`result = true`);
});

test('getGlobalConfig fastboot?.isRunning access', () => {
let code = transform(`
import { getGlobalConfig } from '@embroider/macros';
const result = getGlobalConfig().fastboot?.isRunning`);
expect(code).toMatch(`result = true`);
});

Expand Down
15 changes: 1 addition & 14 deletions packages/macros/tests/babel/macro-condition.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ describe('macroCondition', function () {
expect(code).not.toMatch(/beta/);
});

buildTimeTest('can see booleans inside getConfig', () => {
test('can see booleans inside getConfig', () => {
let code = transform(`
import { macroCondition, getConfig } from '@embroider/macros';
export default function() {
Expand All @@ -373,19 +373,6 @@ describe('macroCondition', function () {
expect(code).not.toMatch(/alpha/);
});

runTimeTest('can see booleans inside getConfig', () => {
let code = transform(`
import { macroCondition, getConfig } from '@embroider/macros';
export default function() {
// this deliberately chains three kinds of property access syntax: by
// identifier, by numeric index, and by string literal.
return macroCondition(getConfig('qunit').items[0]["other"]) ? 'alpha' : 'beta';
}
`);
expect(run(code, { filename })).toBe('beta');
expect(code).toMatch(/alpha/);
});

if (transform.babelMajorVersion === 7) {
buildTimeTest('can be used as class field initializer', () => {
let code = transform(`
Expand Down
Loading