This commit is contained in:
130
node_modules/@mapbox/mapbox-gl-style-spec/expression/definitions/assertion.js
generated
vendored
Normal file
130
node_modules/@mapbox/mapbox-gl-style-spec/expression/definitions/assertion.js
generated
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
// @flow
|
||||
|
||||
import assert from 'assert';
|
||||
|
||||
import {
|
||||
ObjectType,
|
||||
ValueType,
|
||||
StringType,
|
||||
NumberType,
|
||||
BooleanType,
|
||||
checkSubtype,
|
||||
toString,
|
||||
array
|
||||
} from '../types.js';
|
||||
import RuntimeError from '../runtime_error.js';
|
||||
import {typeOf} from '../values.js';
|
||||
|
||||
import type {Expression, SerializedExpression} from '../expression.js';
|
||||
import type ParsingContext from '../parsing_context.js';
|
||||
import type EvaluationContext from '../evaluation_context.js';
|
||||
import type {Type} from '../types.js';
|
||||
|
||||
const types = {
|
||||
string: StringType,
|
||||
number: NumberType,
|
||||
boolean: BooleanType,
|
||||
object: ObjectType
|
||||
};
|
||||
|
||||
class Assertion implements Expression {
|
||||
type: Type;
|
||||
args: Array<Expression>;
|
||||
|
||||
constructor(type: Type, args: Array<Expression>) {
|
||||
this.type = type;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
static parse(args: $ReadOnlyArray<mixed>, context: ParsingContext): ?Expression {
|
||||
if (args.length < 2)
|
||||
return context.error(`Expected at least one argument.`);
|
||||
|
||||
let i = 1;
|
||||
let type;
|
||||
|
||||
const name: string = (args[0]: any);
|
||||
if (name === 'array') {
|
||||
let itemType;
|
||||
if (args.length > 2) {
|
||||
const type = args[1];
|
||||
if (typeof type !== 'string' || !(type in types) || type === 'object')
|
||||
return context.error('The item type argument of "array" must be one of string, number, boolean', 1);
|
||||
itemType = types[type];
|
||||
i++;
|
||||
} else {
|
||||
itemType = ValueType;
|
||||
}
|
||||
|
||||
let N;
|
||||
if (args.length > 3) {
|
||||
if (args[2] !== null &&
|
||||
(typeof args[2] !== 'number' ||
|
||||
args[2] < 0 ||
|
||||
args[2] !== Math.floor(args[2]))
|
||||
) {
|
||||
return context.error('The length argument to "array" must be a positive integer literal', 2);
|
||||
}
|
||||
N = args[2];
|
||||
i++;
|
||||
}
|
||||
|
||||
type = array(itemType, N);
|
||||
} else {
|
||||
assert(types[name], name);
|
||||
type = types[name];
|
||||
}
|
||||
|
||||
const parsed = [];
|
||||
for (; i < args.length; i++) {
|
||||
const input = context.parse(args[i], i, ValueType);
|
||||
if (!input) return null;
|
||||
parsed.push(input);
|
||||
}
|
||||
|
||||
return new Assertion(type, parsed);
|
||||
}
|
||||
|
||||
evaluate(ctx: EvaluationContext): any | null {
|
||||
for (let i = 0; i < this.args.length; i++) {
|
||||
const value = this.args[i].evaluate(ctx);
|
||||
const error = checkSubtype(this.type, typeOf(value));
|
||||
if (!error) {
|
||||
return value;
|
||||
} else if (i === this.args.length - 1) {
|
||||
throw new RuntimeError(`Expected value to be of type ${toString(this.type)}, but found ${toString(typeOf(value))} instead.`);
|
||||
}
|
||||
}
|
||||
|
||||
assert(false);
|
||||
return null;
|
||||
}
|
||||
|
||||
eachChild(fn: (_: Expression) => void) {
|
||||
this.args.forEach(fn);
|
||||
}
|
||||
|
||||
outputDefined(): boolean {
|
||||
return this.args.every(arg => arg.outputDefined());
|
||||
}
|
||||
|
||||
serialize(): SerializedExpression {
|
||||
const type = this.type;
|
||||
const serialized = [type.kind];
|
||||
if (type.kind === 'array') {
|
||||
const itemType = type.itemType;
|
||||
if (itemType.kind === 'string' ||
|
||||
itemType.kind === 'number' ||
|
||||
itemType.kind === 'boolean') {
|
||||
serialized.push(itemType.kind);
|
||||
const N = type.N;
|
||||
if (typeof N === 'number' || this.args.length > 1) {
|
||||
serialized.push(N);
|
||||
}
|
||||
}
|
||||
}
|
||||
return serialized.concat(this.args.map(arg => arg.serialize()));
|
||||
}
|
||||
}
|
||||
|
||||
export default Assertion;
|
||||
Reference in New Issue
Block a user