Skip to content

Commit cca3291

Browse files
committed
Conditionally mark config expressions as feature constant
This exposes a `featureConstant` property on `Config` instances to determine at parse time whether the current value (or the default) of the config option evaluates to a feature-constant expression, and uses that property in `isFeatureConstant`.
1 parent e91b3e1 commit cca3291

File tree

2 files changed

+26
-5
lines changed

2 files changed

+26
-5
lines changed

src/style-spec/expression/definitions/config.ts

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
1-
import {ValueType} from '../types';
1+
import {typeEquals, ValueType} from '../types';
22
import {Color, typeOf, toString as valueToString} from '../values';
33
import Formatted from '../types/formatted';
44
import ResolvedImage from '../types/resolved_image';
5+
import * as isConstant from '../is_constant';
56
import Literal from './literal';
67

78
import type {Type} from '../types';
89
import type {Expression, SerializedExpression} from '../expression';
910
import type ParsingContext from '../parsing_context';
1011
import type EvaluationContext from '../evaluation_context';
1112

13+
const FQIDSeparator = '\u001F';
14+
1215
function coerceValue(type: string, value: any): any {
1316
switch (type) {
1417
case 'string': return valueToString(value);
@@ -42,11 +45,13 @@ class Config implements Expression {
4245
type: Type;
4346
key: string;
4447
scope: string | null | undefined;
48+
featureConstant: boolean;
4549

46-
constructor(type: Type, key: string, scope?: string) {
50+
constructor(type: Type, key: string, scope?: string, featureConstant: boolean = false) {
4751
this.type = type;
4852
this.key = key;
4953
this.scope = scope;
54+
this.featureConstant = featureConstant;
5055
}
5156

5257
static parse(args: ReadonlyArray<unknown>, context: ParsingContext): Config | null | void {
@@ -63,19 +68,31 @@ class Config implements Expression {
6368
return context.error(`Key name of 'config' expression must be a string literal.`);
6469
}
6570

71+
let featureConstant = true;
72+
let configScopeValue: string | undefined;
73+
const configKeyValue = valueToString(configKey.value);
74+
6675
if (args.length >= 3) {
6776
const configScope = context.parse(args[2], 2);
6877
if (!(configScope instanceof Literal)) {
6978
return context.error(`Scope of 'config' expression must be a string literal.`);
7079
}
71-
return new Config(type, valueToString(configKey.value), valueToString(configScope.value));
80+
81+
configScopeValue = valueToString(configScope.value);
82+
}
83+
84+
if (context.options) {
85+
const key = [configKeyValue, configScopeValue, context._scope].filter(Boolean).join(FQIDSeparator);
86+
const config = context.options.get(key);
87+
if (config) {
88+
featureConstant = isConstant.isFeatureConstant(config.value || config.default);
89+
}
7290
}
7391

74-
return new Config(type, valueToString(configKey.value));
92+
return new Config(type, configKeyValue, configScopeValue, featureConstant);
7593
}
7694

7795
evaluate(ctx: EvaluationContext): any {
78-
const FQIDSeparator = '\u001F';
7996
const configKey = [this.key, this.scope, ctx.scope].filter(Boolean).join(FQIDSeparator);
8097

8198
const config = ctx.getConfig(configKey);

src/style-spec/expression/is_constant.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ function isFeatureConstant(e: Expression): boolean {
3232
return false;
3333
}
3434

35+
if (e instanceof Config) {
36+
return e.featureConstant;
37+
}
38+
3539
let result = true;
3640
e.eachChild(arg => {
3741
if (result && !isFeatureConstant(arg)) { result = false; }

0 commit comments

Comments
 (0)