-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
21 changed files
with
592 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
// @flow | ||
|
||
import {BooleanType, StringType, ValueType, NullType, toString, NumberType, isValidType, isValidNativeType} from '../types'; | ||
import RuntimeError from '../runtime_error'; | ||
import {typeOf} from '../values'; | ||
|
||
import type {Expression} from '../expression'; | ||
import type ParsingContext from '../parsing_context'; | ||
import type EvaluationContext from '../evaluation_context'; | ||
import type {Type} from '../types'; | ||
|
||
class IndexOf implements Expression { | ||
type: Type; | ||
needle: Expression; | ||
haystack: Expression; | ||
fromIndex: ?Expression; | ||
|
||
constructor(needle: Expression, haystack: Expression, fromIndex?: Expression) { | ||
this.type = NumberType; | ||
this.needle = needle; | ||
this.haystack = haystack; | ||
this.fromIndex = fromIndex; | ||
} | ||
|
||
static parse(args: $ReadOnlyArray<mixed>, context: ParsingContext) { | ||
if (args.length <= 2 || args.length >= 5) { | ||
return context.error(`Expected 3 or 4 arguments, but found ${args.length - 1} instead.`); | ||
} | ||
|
||
const needle = context.parse(args[1], 1, ValueType); | ||
|
||
const haystack = context.parse(args[2], 2, ValueType); | ||
|
||
if (!needle || !haystack) return null; | ||
if (!isValidType(needle.type, [BooleanType, StringType, NumberType, NullType, ValueType])) { | ||
return context.error(`Expected first argument to be of type boolean, string, number or null, but found ${toString(needle.type)} instead`); | ||
} | ||
|
||
if (args.length === 4) { | ||
const fromIndex = context.parse(args[3], 3, NumberType); | ||
if (!fromIndex) return null; | ||
return new IndexOf(needle, haystack, fromIndex); | ||
} else { | ||
return new IndexOf(needle, haystack); | ||
} | ||
} | ||
|
||
evaluate(ctx: EvaluationContext) { | ||
const needle = (this.needle.evaluate(ctx): any); | ||
const haystack = (this.haystack.evaluate(ctx): any); | ||
|
||
if (!isValidNativeType(needle, ['boolean', 'string', 'number', 'null'])) { | ||
throw new RuntimeError(`Expected first argument to be of type boolean, string, number or null, but found ${toString(typeOf(needle))} instead.`); | ||
} | ||
|
||
if (!isValidNativeType(haystack, ['string', 'array'])) { | ||
throw new RuntimeError(`Expected second argument to be of type array or string, but found ${toString(typeOf(haystack))} instead.`); | ||
} | ||
|
||
if (this.fromIndex) { | ||
const fromIndex = (this.fromIndex.evaluate(ctx): number); | ||
return haystack.indexOf(needle, fromIndex); | ||
} | ||
|
||
return haystack.indexOf(needle); | ||
} | ||
|
||
eachChild(fn: (_: Expression) => void) { | ||
fn(this.needle); | ||
fn(this.haystack); | ||
if (this.fromIndex) { | ||
fn(this.fromIndex); | ||
} | ||
} | ||
|
||
outputDefined() { | ||
return false; | ||
} | ||
|
||
serialize() { | ||
if (this.fromIndex != null && this.fromIndex !== undefined) { | ||
const fromIndex = this.fromIndex.serialize(); | ||
return ["index-of", this.needle.serialize(), this.haystack.serialize(), fromIndex]; | ||
} | ||
return ["index-of", this.needle.serialize(), this.haystack.serialize()]; | ||
} | ||
} | ||
|
||
export default IndexOf; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
// @flow | ||
|
||
import {ValueType, NumberType, StringType, array, toString, isValidType, isValidNativeType} from '../types'; | ||
import RuntimeError from '../runtime_error'; | ||
import {typeOf} from '../values'; | ||
|
||
import type {Expression} from '../expression'; | ||
import type ParsingContext from '../parsing_context'; | ||
import type EvaluationContext from '../evaluation_context'; | ||
import type {Type} from '../types'; | ||
|
||
class Slice implements Expression { | ||
type: Type; | ||
input: Expression; | ||
beginIndex: Expression; | ||
endIndex: ?Expression; | ||
|
||
constructor(type: Type, input: Expression, beginIndex: Expression, endIndex?: Expression) { | ||
this.type = type; | ||
this.input = input; | ||
this.beginIndex = beginIndex; | ||
this.endIndex = endIndex; | ||
|
||
} | ||
|
||
static parse(args: $ReadOnlyArray<mixed>, context: ParsingContext) { | ||
if (args.length <= 2 || args.length >= 5) { | ||
return context.error(`Expected 3 or 4 arguments, but found ${args.length - 1} instead.`); | ||
} | ||
|
||
const input = context.parse(args[1], 1, ValueType); | ||
const beginIndex = context.parse(args[2], 2, NumberType); | ||
|
||
if (!input || !beginIndex) return null; | ||
|
||
if (!isValidType(input.type, [array(ValueType), StringType, ValueType])) { | ||
return context.error(`Expected first argument to be of type array or string, but found ${toString(input.type)} instead`); | ||
} | ||
|
||
if (args.length === 4) { | ||
const endIndex = context.parse(args[3], 3, NumberType); | ||
if (!endIndex) return null; | ||
return new Slice(input.type, input, beginIndex, endIndex); | ||
} else { | ||
return new Slice(input.type, input, beginIndex); | ||
} | ||
} | ||
|
||
evaluate(ctx: EvaluationContext) { | ||
const input = (this.input.evaluate(ctx): any); | ||
const beginIndex = (this.beginIndex.evaluate(ctx): number); | ||
|
||
if (!isValidNativeType(input, ['string', 'array'])) { | ||
throw new RuntimeError(`Expected first argument to be of type array or string, but found ${toString(typeOf(input))} instead.`); | ||
} | ||
|
||
if (this.endIndex) { | ||
const endIndex = (this.endIndex.evaluate(ctx): number); | ||
return input.slice(beginIndex, endIndex); | ||
} | ||
|
||
return input.slice(beginIndex); | ||
} | ||
|
||
eachChild(fn: (_: Expression) => void) { | ||
fn(this.input); | ||
fn(this.beginIndex); | ||
if (this.endIndex) { | ||
fn(this.endIndex); | ||
} | ||
} | ||
|
||
outputDefined() { | ||
return false; | ||
} | ||
|
||
serialize() { | ||
if (this.endIndex != null && this.endIndex !== undefined) { | ||
const endIndex = this.endIndex.serialize(); | ||
return ["slice", this.input.serialize(), this.beginIndex.serialize(), endIndex]; | ||
} | ||
return ["slice", this.input.serialize(), this.beginIndex.serialize()]; | ||
} | ||
} | ||
|
||
export default Slice; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
test/integration/expression-tests/index-of/assert-array/test.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
{ | ||
"expression": ["index-of", ["get", "i"], ["array", ["get", "arr"]]], | ||
"inputs": [ | ||
[{}, { "properties": { "i": null, "arr": [9, 8, 7] } }], | ||
[{}, { "properties": { "i": null, "arr": [9, 8, 7, null] } }], | ||
[{}, { "properties": { "i": 1, "arr": [9, 8, 7] } }], | ||
[{}, { "properties": { "i": 9, "arr": [9, 8, 7, 9] } }], | ||
[{}, { "properties": { "i": 1, "arr": null } }] | ||
], | ||
"expected": { | ||
"compiled": { | ||
"result": "success", | ||
"isFeatureConstant": false, | ||
"isZoomConstant": true, | ||
"type": "number" | ||
}, | ||
"outputs": [ | ||
-1, | ||
3, | ||
-1, | ||
0, | ||
{ "error": "Expected value to be of type array, but found null instead." } | ||
], | ||
"serialized": ["index-of", ["get", "i"], ["array", ["get", "arr"]]] | ||
} | ||
} |
Oops, something went wrong.