From c573f5cf48bd38751ba4a6b4da4a9324116b3a42 Mon Sep 17 00:00:00 2001 From: Stepan Kuzmin Date: Wed, 10 May 2023 14:47:53 +0300 Subject: [PATCH] Annotate function arguments (#12641) * Add local inference annotations --------- Co-authored-by: Volodymyr Agafonkin --- .flowconfig | 3 +- bench/benchmarks/expressions.js | 2 +- bench/benchmarks/worker_transfer.js | 3 +- build/generate-struct-arrays.js | 8 +-- flow-typed/geojson.js | 3 +- package.json | 2 +- src/data/bucket/circle_bucket.js | 2 +- src/data/bucket/fill_extrusion_bucket.js | 20 +++---- src/data/bucket/symbol_bucket.js | 6 +- src/data/dem_data.js | 2 +- src/data/dem_tree.js | 8 +-- src/data/feature_index.js | 7 ++- src/data/feature_position_map.js | 4 +- src/data/load_geometry.js | 2 +- src/data/program_configuration.js | 12 ++-- src/geo/projection/adjustments.js | 4 +- src/geo/projection/globe_util.js | 2 +- src/geo/projection/lambert.js | 2 +- src/geo/projection/resample.js | 6 +- src/geo/projection/tile_transform.js | 4 +- src/geo/transform.js | 33 +++++++---- src/render/draw_debug.js | 2 +- src/render/draw_fill.js | 3 +- src/render/draw_fill_extrusion.js | 29 +++++---- src/render/draw_heatmap.js | 8 ++- src/render/draw_hillshade.js | 5 +- src/render/draw_line.js | 2 +- src/render/draw_symbol.js | 16 ++--- src/render/program/line_program.js | 4 +- src/render/program/raster_program.js | 6 +- src/render/skybox_geometry.js | 2 +- src/source/canvas_source.js | 2 + src/source/custom_source.js | 3 +- src/source/geojson_worker_source.js | 3 +- src/source/geojson_wrapper.js | 5 +- src/source/image_source.js | 4 +- src/source/query_features.js | 7 ++- src/source/raster_dem_tile_source.js | 11 +++- src/source/source.js | 3 +- src/source/source_cache.js | 4 +- src/source/tile_id.js | 2 +- src/source/tile_mesh.js | 6 +- src/source/vector_tile_source.js | 5 +- src/source/vector_tile_worker_source.js | 6 +- src/source/worker.js | 2 +- src/source/worker_tile.js | 8 +-- src/style-spec/deref.js | 2 +- src/style-spec/diff.js | 28 +++++---- .../expression/definitions/format.js | 4 +- .../expression/definitions/index.js | 11 ++-- .../expression/definitions/interpolate.js | 2 +- .../expression/definitions/match.js | 2 +- .../expression/definitions/within.js | 43 +++++++------- src/style-spec/expression/parsing_context.js | 2 +- src/style-spec/feature_filter/convert.js | 2 +- src/style-spec/feature_filter/index.js | 4 +- src/style-spec/function/convert.js | 35 +++++++---- src/style-spec/group_by_layout.js | 4 +- src/style-spec/migrate/expressions.js | 3 + src/style-spec/validate/validate_filter.js | 8 +-- src/style-spec/validate/validate_function.js | 2 +- src/style-spec/validate/validate_source.js | 5 +- src/style-spec/validate_style.min.js | 2 +- src/style-spec/visit.js | 4 +- src/style/fog.js | 1 + src/style/properties.js | 2 +- src/style/style.js | 9 +-- .../style_layer/fill_extrusion_style_layer.js | 4 +- src/style/style_layer/line_style_layer.js | 11 ++-- src/style/style_layer/symbol_style_layer.js | 5 +- src/symbol/get_anchors.js | 2 +- src/symbol/mergelines.js | 9 +-- src/symbol/placement.js | 18 +++--- src/symbol/projection.js | 6 +- src/symbol/quads.js | 16 ++--- src/symbol/shaping.js | 8 +-- src/symbol/symbol_layout.js | 6 +- src/terrain/draw_terrain_raster.js | 10 ++-- src/terrain/terrain.js | 12 ++-- src/ui/camera.js | 12 ++-- src/ui/control/geolocate_control.js | 2 +- src/ui/control/scale_control.js | 59 +++++++------------ src/ui/handler/touch_zoom_rotate.js | 4 +- src/ui/handler_inertia.js | 4 +- src/ui/handler_manager.js | 8 +-- src/ui/map.js | 14 ++--- src/util/actor.js | 2 +- src/util/ajax.js | 10 ++-- src/util/classify_rings.js | 2 +- src/util/color_ramp.js | 2 +- src/util/dom.js | 2 +- src/util/find_pole_of_inaccessibility.js | 8 +-- src/util/live_performance.js | 8 +-- src/util/polygon_clipping.js | 6 +- src/util/struct_array.js | 2 +- src/util/tile_request_cache.js | 4 +- src/util/util.js | 4 +- src/util/window.js | 3 + test/unit/util/util.test.js | 6 +- test/unit/util/web_worker_transfer.test.js | 6 +- test/util/test.js | 2 + yarn.lock | 8 +-- 102 files changed, 409 insertions(+), 334 deletions(-) diff --git a/.flowconfig b/.flowconfig index 582663c86cc..db1d6c7fb95 100644 --- a/.flowconfig +++ b/.flowconfig @@ -30,9 +30,10 @@ .*/test/build/downstream-flow-fixture/.* [version] -0.188.0 +0.191.0 [options] +exact_empty_objects=false [strict] nonstrict-import diff --git a/bench/benchmarks/expressions.js b/bench/benchmarks/expressions.js index 29e75cd17c7..96a7e97dab1 100644 --- a/bench/benchmarks/expressions.js +++ b/bench/benchmarks/expressions.js @@ -39,7 +39,7 @@ class ExpressionBenchmark extends Benchmark { continue; } - const expressionData = function(rawValue, propertySpec: StylePropertySpecification) { + const expressionData = function(rawValue: any, propertySpec: StylePropertySpecification) { const rawExpression = convertFunction(rawValue, propertySpec); const compiledFunction = createFunction(rawValue, propertySpec); const compiledExpression = createPropertyExpression(rawExpression, propertySpec); diff --git a/bench/benchmarks/worker_transfer.js b/bench/benchmarks/worker_transfer.js index ec8d6d9f8bc..fd9db65c7d0 100644 --- a/bench/benchmarks/worker_transfer.js +++ b/bench/benchmarks/worker_transfer.js @@ -7,6 +7,7 @@ import TileParser from '../lib/tile_parser.js'; import {OverscaledTileID} from '../../src/source/tile_id.js'; import {serialize, deserialize} from '../../src/util/web_worker_transfer.js'; import {values} from '../../src/util/util.js'; +import type {Serialized} from '../../src/util/web_worker_transfer.js'; export default class WorkerTransfer extends Benchmark { parser: TileParser; @@ -81,7 +82,7 @@ export default class WorkerTransfer extends Benchmark { } } -function barePayload(obj) { +function barePayload(obj: Serialized) { // strip all transferables from a worker payload, because we can't transfer them repeatedly in the bench: // as soon as it's transfered once, it's no longer available on the main thread return JSON.parse(JSON.stringify(obj, (key, value) => ArrayBuffer.isView(value) ? {} : value) || '{}'); diff --git a/build/generate-struct-arrays.js b/build/generate-struct-arrays.js index 8dbd35df2be..7e0ce9d5e1d 100644 --- a/build/generate-struct-arrays.js +++ b/build/generate-struct-arrays.js @@ -14,7 +14,7 @@ import fs from 'fs'; import ejs from 'ejs'; import {extend} from '../src/util/util.js'; import {createLayout, viewTypes} from '../src/util/struct_array.js'; -import type {ViewType, StructArrayLayout} from '../src/util/struct_array.js'; +import type {ViewType, StructArrayLayout, StructArrayMember} from '../src/util/struct_array.js'; const structArrayLayoutJs = ejs.compile(fs.readFileSync('src/util/struct_array_layout.js.ejs', 'utf8'), {strict: true}); const structArrayJs = ejs.compile(fs.readFileSync('src/util/struct_array.js.ejs', 'utf8'), {strict: true}); @@ -33,7 +33,7 @@ const arraysWithStructAccessors = []; const arrayTypeEntries = new Set(); const layoutCache = {}; -function normalizeMembers(members, usedTypes) { +function normalizeMembers(members: Array, usedTypes: Set) { return members.map((member) => { if (usedTypes && !usedTypes.has(member.type)) { usedTypes.add(member.type); @@ -70,7 +70,7 @@ function createStructArrayType(name: string, layout: StructArrayLayout, includeS } } -function createStructArrayLayoutType({members, size, alignment}) { +function createStructArrayLayoutType({members, size, alignment}: StructArrayLayout) { const usedTypes = new Set(['Uint8']); members = normalizeMembers(members, usedTypes); @@ -106,7 +106,7 @@ function sizeOf(type: ViewType): number { return viewTypes[type].BYTES_PER_ELEMENT; } -function camelize (str) { +function camelize (str: string) { return str.replace(/(?:^|[-_])(.)/g, (_, x) => { return /^[0-9]$/.test(x) ? _ : x.toUpperCase(); }); diff --git a/flow-typed/geojson.js b/flow-typed/geojson.js index eda0f1a4fc5..7b25ae618ba 100644 --- a/flow-typed/geojson.js +++ b/flow-typed/geojson.js @@ -1,9 +1,10 @@ // @flow strict -type GeoJSONPosition = [number, number] | [number, number, number]; type Geometry = { type: T, coordinates: C } declare module "@mapbox/geojson-types" { + declare export type GeoJSONPosition = [number, number] | [number, number, number]; + declare export type GeoJSONPoint = Geometry<'Point', GeoJSONPosition>; declare export type GeoJSONMultiPoint = Geometry<'MultiPoint', Array>; diff --git a/package.json b/package.json index 72767691a05..c23b4c305ec 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "eslint-plugin-html": "^7.1.0", "eslint-plugin-import": "^2.26.0", "eslint-plugin-jsdoc": "^39.6.4", - "flow-bin": "0.188.0", + "flow-bin": "0.191.0", "gl": "6.0.2", "glob": "^10.0.0", "is-builtin-module": "^3.2.0", diff --git a/src/data/bucket/circle_bucket.js b/src/data/bucket/circle_bucket.js index 16a25a23f4b..1ecdeaba146 100644 --- a/src/data/bucket/circle_bucket.js +++ b/src/data/bucket/circle_bucket.js @@ -34,7 +34,7 @@ import type Projection from '../../geo/projection/projection.js'; import type {Vec3} from 'gl-matrix'; import type {IVectorTileLayer} from '@mapbox/vector-tile'; -function addCircleVertex(layoutVertexArray, x, y, extrudeX, extrudeY) { +function addCircleVertex(layoutVertexArray: CircleLayoutArray, x: number, y: number, extrudeX: number, extrudeY: number) { layoutVertexArray.emplaceBack( (x * 2) + ((extrudeX + 1) / 2), (y * 2) + ((extrudeY + 1) / 2)); diff --git a/src/data/bucket/fill_extrusion_bucket.js b/src/data/bucket/fill_extrusion_bucket.js index 28bf7b4ec62..1c1c56ab0b5 100644 --- a/src/data/bucket/fill_extrusion_bucket.js +++ b/src/data/bucket/fill_extrusion_bucket.js @@ -53,7 +53,7 @@ const FACTOR = Math.pow(2, 13); export const ELEVATION_SCALE = 7.0; export const ELEVATION_OFFSET = 450; -function addVertex(vertexArray, x, y, nxRatio, nySign, normalUp, top, e) { +function addVertex(vertexArray: FillExtrusionLayoutArray, x: number, y: number, nxRatio: number, nySign: number, normalUp: number, top: number, e: number) { vertexArray.emplaceBack( // a_pos_normal_ed: // Encode top and side/up normal using the least significant bits @@ -73,7 +73,7 @@ function addGlobeExtVertex(vertexArray: FillExtrusionExtArray, pos: {x: number, normal[0] * encode, normal[1] * encode, normal[2] * encode); } -class PartMetadata { +export class PartMetadata { acc: Point; min: Point; max: Point; @@ -661,20 +661,20 @@ class FillExtrusionBucket implements Bucket { } } -function getCosHalfAngle(na, nb) { +function getCosHalfAngle(na: Point, nb: Point) { const nm = na.add(nb)._unit(); const cosHalfAngle = na.x * nm.x + na.y * nm.y; return cosHalfAngle; } -function getRoundedEdgeOffset(p0, p1, p2, edgeRadius) { +function getRoundedEdgeOffset(p0: Point, p1: Point, p2: Point, edgeRadius: number) { const na = p1.sub(p0)._perp()._unit(); const nb = p2.sub(p1)._perp()._unit(); const cosHalfAngle = getCosHalfAngle(na, nb); return _getRoundedEdgeOffset(p0, p1, p2, cosHalfAngle, edgeRadius); } -function _getRoundedEdgeOffset(p0, p1, p2, cosHalfAngle, edgeRadius) { +function _getRoundedEdgeOffset(p0: Point, p1: Point, p2: Point, cosHalfAngle: number, edgeRadius: number) { const sinHalfAngle = Math.sqrt(1 - cosHalfAngle * cosHalfAngle); return Math.min(p0.dist(p1) / 3, p1.dist(p2) / 3, edgeRadius * sinHalfAngle / cosHalfAngle); } @@ -688,14 +688,14 @@ export default FillExtrusionBucket; // Rendering them twice often results with Z-fighting. // In case of globe and axis aligned bounds, it is also useful to // discard edges that have the both endpoints outside the same bound. -function isEdgeOutsideBounds(p1, p2, bounds) { +function isEdgeOutsideBounds(p1: Point, p2: Point, bounds: [Point, Point]) { return (p1.x < bounds[0].x && p2.x < bounds[0].x) || (p1.x > bounds[1].x && p2.x > bounds[1].x) || (p1.y < bounds[0].y && p2.y < bounds[0].y) || (p1.y > bounds[1].y && p2.y > bounds[1].y); } -function isEntirelyOutside(ring) { +function isEntirelyOutside(ring: Array) { // Discard rings with corners on border if all other vertices are outside: they get defined // also in the tile across the border. Eventual zero area rings at border are discarded by classifyRings // and there is no need to handle that case here. @@ -713,7 +713,7 @@ function tileToMeter(canonical: CanonicalTileID) { return circumferenceAtEquator * 2 * exp / (exp * exp + 1) / EXTENT / (1 << canonical.z); } -function isAOConcaveAngle(p2, p1, p3) { +function isAOConcaveAngle(p2: Point, p1: Point, p3: Point) { if (p2.x < 0 || p2.x >= EXTENT || p1.x < 0 || p1.x >= EXTENT || p3.x < 0 || p3.x >= EXTENT) { return false; // angles are not processed for edges that extend over tile borders } @@ -728,7 +728,7 @@ function isAOConcaveAngle(p2, p1, p3) { return cosAB > -0.866 && dotProductWithNormal < 0; } -function encodeAOToEdgeDistance(edgeDistance, isConcaveCorner, edgeStart) { +function encodeAOToEdgeDistance(edgeDistance: number, isConcaveCorner: boolean, edgeStart: boolean) { // Encode concavity and edge start/end using the least significant bits. // Second least significant bit 1 encodes concavity. // The least significant bit 1 marks the edge start, 0 for edge end. @@ -758,7 +758,7 @@ export function resampleFillExtrusionPolygonsForGlobe(polygons: Point[][][], til const cellCountOnXAxis = Math.ceil((rightLng - leftLng) / cellCount); const cellCountOnYAxis = Math.ceil((topLat - bottomLat) / cellCount); - const splitFn = (axis, min, max) => { + const splitFn = (axis: number, min: number, max: number) => { if (axis === 0) { return 0.5 * (min + max); } else { diff --git a/src/data/bucket/symbol_bucket.js b/src/data/bucket/symbol_bucket.js index 334d8f10e6c..17548e87287 100644 --- a/src/data/bucket/symbol_bucket.js +++ b/src/data/bucket/symbol_bucket.js @@ -132,7 +132,7 @@ const shaderOpacityAttributes = [ {name: 'a_fade_opacity', components: 1, type: 'Uint8', offset: 0} ]; -function addVertex(array, tileAnchorX, tileAnchorY, ox, oy, tx, ty, sizeVertex, isSDF: boolean, pixelOffsetX, pixelOffsetY, minFontScaleX, minFontScaleY) { +function addVertex(array: SymbolLayoutArray, tileAnchorX: number, tileAnchorY: number, ox: number, oy: number, tx: number, ty: number, sizeVertex: any, isSDF: boolean, pixelOffsetX: number, pixelOffsetY: number, minFontScaleX: number, minFontScaleY: number) { const aSizeX = sizeVertex ? Math.min(MAX_PACKED_SIZE, Math.round(sizeVertex[0])) : 0; const aSizeY = sizeVertex ? Math.min(MAX_PACKED_SIZE, Math.round(sizeVertex[1])) : 0; @@ -155,7 +155,7 @@ function addVertex(array, tileAnchorX, tileAnchorY, ox, oy, tx, ty, sizeVertex, ); } -function addGlobeVertex(array, projAnchorX, projAnchorY, projAnchorZ, normX, normY, normZ) { +function addGlobeVertex(array: SymbolGlobeExtArray, projAnchorX: number, projAnchorY: number, projAnchorZ: number, normX: number, normY: number, normZ: number) { array.emplaceBack( // a_globe_anchor projAnchorX, @@ -521,7 +521,7 @@ class SymbolBucket implements Bucket { // cos(11.25 degrees) = 0.98078528056 const cosAngleThreshold = 0.98078528056; - const predicate = (a, b) => { + const predicate = (a: Point, b: Point) => { const v0 = tileCoordToECEF(a.x, a.y, canonical, 1); const v1 = tileCoordToECEF(b.x, b.y, canonical, 1); return vec3.dot(v0, v1) < cosAngleThreshold; diff --git a/src/data/dem_data.js b/src/data/dem_data.js index 66d549076f8..3d9f1538f0f 100644 --- a/src/data/dem_data.js +++ b/src/data/dem_data.js @@ -131,7 +131,7 @@ export default class DEMData { return new RGBAImage({width: this.stride, height: this.stride}, this.pixels); } - backfillBorder(borderTile: DEMData, dx: number, dy: number) { + backfillBorder(borderTile: DEMData, dx: number, dy: number): void { if (this.dim !== borderTile.dim) throw new Error('dem dimension mismatch'); let xMin = dx * this.dim, diff --git a/src/data/dem_tree.js b/src/data/dem_tree.js index 71327e4833a..15fc6226016 100644 --- a/src/data/dem_tree.js +++ b/src/data/dem_tree.js @@ -69,7 +69,7 @@ function aabbRayIntersect(min: Vec3, max: Vec3, pos: Vec3, dir: Vec3): ?number { return tMin; } -function triangleRayIntersect(ax, ay, az, bx, by, bz, cx, cy, cz, pos: Vec3, dir: Vec3): ?number { +function triangleRayIntersect(ax: number, ay: number, az: number, bx: number, by: number, bz: number, cx: number, cy: number, cz: number, pos: Vec3, dir: Vec3): ?number { // Compute barycentric coordinates u and v to find the intersection const abX = bx - ax; const abY = by - ay; @@ -109,11 +109,11 @@ function triangleRayIntersect(ax, ay, az, bx, by, bz, cx, cy, cz, pos: Vec3, dir return (acX * qvecX + acY * qvecY + acZ * qvecZ) * invDet; } -function frac(v, lo, hi) { +function frac(v: number, lo: number, hi: number) { return (v - lo) / (hi - lo); } -function decodeBounds(x, y, depth, boundsMinx, boundsMiny, boundsMaxx, boundsMaxy, outMin, outMax) { +function decodeBounds(x: number, y: number, depth: number, boundsMinx: number, boundsMiny: number, boundsMaxx: number, boundsMaxy: number, outMin: Array, outMax: Array) { const scale = 1 << depth; const rangex = boundsMaxx - boundsMinx; const rangey = boundsMaxy - boundsMiny; @@ -394,7 +394,7 @@ export function buildDemMipmap(dem: DEMData): Array { let blockCount = Math.ceil(Math.pow(2, levelCount)); const blockSize = 1 / blockCount; - const blockSamples = (x, y, size, exclusive, outBounds) => { + const blockSamples = (x: number, y: number, size: number, exclusive: boolean, outBounds: Array) => { const padding = exclusive ? 1 : 0; const minx = x * size; const maxx = (x + 1) * size - padding; diff --git a/src/data/feature_index.js b/src/data/feature_index.js index 95c09def69d..1f8a4f34c18 100644 --- a/src/data/feature_index.js +++ b/src/data/feature_index.js @@ -23,6 +23,7 @@ import {DEMSampler} from '../terrain/elevation.js'; import type StyleLayer from '../style/style_layer.js'; import type {QueryFeature} from '../util/vectortile_to_geojson.js'; +import type {FeatureStates} from "../source/source_state"; import type {FeatureFilter} from '../style-spec/feature_filter/index.js'; import type Transform from '../geo/transform.js'; import type {FilterSpecification, PromoteIdSpecification} from '../style-spec/types.js'; @@ -126,7 +127,7 @@ class FeatureIndex { const transform = args.transform; const bounds = tilespaceGeometry.bufferedTilespaceBounds; - const queryPredicate = (bx1, by1, bx2, by2) => { + const queryPredicate = (bx1: number, by1: number, bx2: number, by2: number) => { return polygonIntersectsBox(tilespaceGeometry.bufferedTilespaceGeometry, bx1, by1, bx2, by2); }; const matching = this.grid.query(bounds.min.x, bounds.min.y, bounds.max.x, bounds.max.y, queryPredicate); @@ -319,13 +320,13 @@ register(FeatureIndex, 'FeatureIndex', {omit: ['rawTileData', 'sourceLayerCoder' export default FeatureIndex; -function evaluateProperties(serializedProperties, styleLayerProperties, feature, featureState, availableImages) { +function evaluateProperties(serializedProperties: mixed, styleLayerProperties: mixed, feature: IVectorTileFeature, featureState: FeatureStates, availableImages: Array) { return mapObject(serializedProperties, (property, key) => { const prop = styleLayerProperties instanceof PossiblyEvaluated ? styleLayerProperties.get(key) : null; return prop && prop.evaluate ? prop.evaluate(feature, featureState, availableImages) : prop; }); } -function topDownFeatureComparator(a, b) { +function topDownFeatureComparator(a: number, b: number) { return b - a; } diff --git a/src/data/feature_position_map.js b/src/data/feature_position_map.js index c78a6ae53bd..5447dbc612e 100644 --- a/src/data/feature_position_map.js +++ b/src/data/feature_position_map.js @@ -94,7 +94,7 @@ function getNumericId(value: mixed) { // custom quicksort that sorts ids, indices and offsets together (by ids) // uses Hoare partitioning & manual tail call optimization to avoid worst case scenarios -function sort(ids, positions, left, right) { +function sort(ids: Float64Array, positions: Uint32Array, left: number, right: number) { while (left < right) { const pivot = ids[(left + right) >> 1]; let i = left - 1; @@ -120,7 +120,7 @@ function sort(ids, positions, left, right) { } } -function swap(arr, i, j) { +function swap(arr: Uint32Array | Float64Array, i: number, j: number) { const tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; diff --git a/src/data/load_geometry.js b/src/data/load_geometry.js index 5261569417a..0be274a5c5a 100644 --- a/src/data/load_geometry.js +++ b/src/data/load_geometry.js @@ -53,7 +53,7 @@ export default function loadGeometry(feature: FeatureWithGeometry, canonical?: C const z2 = 1 << canonical.z; const {scale, x, y, projection} = tileTransform; - const reproject = (p) => { + const reproject = (p: Point) => { const lng = lngFromMercatorX((canonical.x + p.x / extent) / z2); const lat = latFromMercatorY((canonical.y + p.y / extent) / z2); const p2 = projection.project(lng, lat); diff --git a/src/data/program_configuration.js b/src/data/program_configuration.js index b8c6d7be30c..00989fb990d 100644 --- a/src/data/program_configuration.js +++ b/src/data/program_configuration.js @@ -183,7 +183,7 @@ class SourceExpressionBinder implements AttributeBinder { this._setPaintValue(start, end, value); } - _setPaintValue(start, end, value) { + _setPaintValue(start: number, end: number, value: any) { if (this.type === 'color') { const color = packColor(value); for (let i = start; i < end; i++) { @@ -258,7 +258,7 @@ class CompositeExpressionBinder implements AttributeBinder, UniformBinder { this._setPaintValue(start, end, min, max); } - _setPaintValue(start, end, min, max) { + _setPaintValue(start: number, end: number, min: any, max: any) { if (this.type === 'color') { const minColor = packColor(min); const maxColor = packColor(max); @@ -331,7 +331,7 @@ class PatternCompositeBinder implements AttributeBinder { this._setPaintValues(start, end, feature.patterns && feature.patterns[this.layerId], imagePositions); } - _setPaintValues(start, end, patterns, positions) { + _setPaintValues(start: number, end: number, patterns: ?string, positions: SpritePositions) { if (!positions || !patterns) return; const pos = positions[patterns]; @@ -639,7 +639,7 @@ const attributeNameExceptions = { 'line-dasharray': ['dash'] }; -function paintAttributeNames(property, type) { +function paintAttributeNames(property: string, type: string) { return attributeNameExceptions[property] || [property.replace(`${type}-`, '').replace(/-/g, '_')]; } @@ -673,7 +673,9 @@ const defaultLayouts = { } }; -function layoutType(property, type, binderType) { +type LayoutType = 'array' | 'boolean' | 'color' | 'enum' | 'number' | 'resolvedImage' | 'string'; + +function layoutType(property: string, type: LayoutType, binderType: string) { const layoutException = propertyExceptions[property]; // $FlowFixMe[prop-missing] - we don't cover all types in defaultLayouts for some reason return (layoutException && layoutException[binderType]) || defaultLayouts[type][binderType]; diff --git a/src/geo/projection/adjustments.js b/src/geo/projection/adjustments.js index 7870bae73ee..4e0af0d1cb2 100644 --- a/src/geo/projection/adjustments.js +++ b/src/geo/projection/adjustments.js @@ -78,7 +78,7 @@ function getZoomAdjustment(projection: Projection, loc: LngLat) { return Math.log(scale) / Math.LN2; } -function getShearAdjustment(projection, zoom, loc, interpT, withoutRotation?: boolean) { +function getShearAdjustment(projection: Projection, zoom: number, loc: LngLat, interpT: number, withoutRotation?: boolean) { // create two locations a tiny amount (~1km) east and west of the given location const locw = new LngLat(loc.lng - 180 * offset, loc.lat); @@ -141,7 +141,7 @@ function getShearAdjustment(projection, zoom, loc, interpT, withoutRotation?: bo return shear; } -function rotate(x, y, angle) { +function rotate(x: number, y: number, angle: number) { const cos = Math.cos(angle); const sin = Math.sin(angle); return { diff --git a/src/geo/projection/globe_util.js b/src/geo/projection/globe_util.js index 8bccd25d49d..5c375098a04 100644 --- a/src/geo/projection/globe_util.js +++ b/src/geo/projection/globe_util.js @@ -496,7 +496,7 @@ export function globePixelsToTileUnits(zoom: number, id: CanonicalTileID): numbe return ecefPerPixel * normCoeff; } -function calculateGlobePosMatrix(x, y, worldSize, lng, lat): Float64Array { +function calculateGlobePosMatrix(x: number, y: number, worldSize: number, lng: number, lat: number): Float64Array { // transform the globe from reference coordinate space to world space const scale = globeECEFUnitsToPixelScale(worldSize); const offset = [x, y, -worldSize / (2.0 * Math.PI)]; diff --git a/src/geo/projection/lambert.js b/src/geo/projection/lambert.js index a90f1ebc6b8..8d92a683ac7 100644 --- a/src/geo/projection/lambert.js +++ b/src/geo/projection/lambert.js @@ -9,7 +9,7 @@ import type {ProjectedPoint} from './projection.js'; const halfPi = Math.PI / 2; -function tany(y) { +function tany(y: number) { return Math.tan((halfPi + y) / 2); } diff --git a/src/geo/projection/resample.js b/src/geo/projection/resample.js index 3eb2a31bb90..09dad566158 100644 --- a/src/geo/projection/resample.js +++ b/src/geo/projection/resample.js @@ -2,13 +2,13 @@ import Point from '@mapbox/point-geometry'; -function pointToLineDist(px, py, ax, ay, bx, by) { +function pointToLineDist(px: number, py: number, ax: number, ay: number, bx: number, by: number) { const dx = ax - bx; const dy = ay - by; return Math.abs((ay - py) * dx - (ax - px) * dy) / Math.hypot(dx, dy); } -function addResampled(resampled, mx0, my0, mx2, my2, start, end, reproject, tolerance) { +function addResampled(resampled: Array, mx0: number, my0: number, mx2: number, my2: number, start: Point, end: Point, reproject: ((Point) => void), tolerance: number) { const mx1 = (mx0 + mx2) / 2; const my1 = (my0 + my2) / 2; const mid = new Point(mx1, my1); @@ -49,7 +49,7 @@ export default function resample(line: Array, reproject: (Point) => void, return resampled; } -function addResampledPred(resampled: Point[], a: Point, b: Point, pred) { +function addResampledPred(resampled: Point[], a: Point, b: Point, pred: ((Point, Point) => boolean)) { const split = pred(a, b); // if the predicate condition is met, recurse into two halves diff --git a/src/geo/projection/tile_transform.js b/src/geo/projection/tile_transform.js index bf832c97b43..23b6949682f 100644 --- a/src/geo/projection/tile_transform.js +++ b/src/geo/projection/tile_transform.js @@ -9,7 +9,7 @@ import assert from 'assert'; import {CanonicalTileID} from '../../source/tile_id.js'; import type {Vec3} from 'gl-matrix'; -import type Projection from './projection.js'; +import type Projection, {ProjectedPoint} from './projection.js'; import type Transform from '../transform.js'; export type TileTransform = { @@ -51,7 +51,7 @@ export default function tileTransform(id: Object, projection: Projection): TileT // we pick an error threshold for calculating the bbox that balances between performance and precision const maxErr = s / 16; - function processSegment(pa, pb, ax, ay, bx, by) { + function processSegment(pa: ProjectedPoint, pb: ProjectedPoint, ax: number, ay: number, bx: number, by: number) { const mx = (ax + bx) / 2; const my = (ay + by) / 2; diff --git a/src/geo/transform.js b/src/geo/transform.js index 8b570debc24..1685be490a9 100644 --- a/src/geo/transform.js +++ b/src/geo/transform.js @@ -33,12 +33,25 @@ import type Tile from '../source/tile.js'; import type {ProjectionSpecification} from '../style-spec/types.js'; import type {FeatureDistanceData} from '../style-spec/feature_filter/index.js'; import type {Mat4, Vec3, Vec4, Quat} from 'gl-matrix'; +import type {Aabb} from '../util/primitives'; const NUM_WORLD_COPIES = 3; const DEFAULT_MIN_ZOOM = 0; type RayIntersectionResult = { p0: Vec4, p1: Vec4, t: number}; type ElevationReference = "sea" | "ground"; +type RootTile = { + aabb: Aabb, + fullyVisible: boolean, + maxZ: number, + minZ: number, + shouldSplit?: boolean, + tileID?: OverscaledTileID, + wrap: number, + x: number, + y: number, + zoom: number, +}; /** * A single transform, generally used for a single tile to be @@ -795,7 +808,7 @@ class Transform { const scaleAdjustment = this.projection.isReprojectedInTileSpace ? getScaleAdjustment(this) : 1.0; - const relativeScaleAtMercatorCoord = mc => { + const relativeScaleAtMercatorCoord = (mc: MercatorCoordinate) => { // Calculate how scale compares between projected coordinates and mercator coordinates. // Returns a length. The units don't matter since the result is only // used in a ratio with other values returned by this function. @@ -822,7 +835,7 @@ class Transform { return Math.sqrt(dx * dy) * scaleAdjustment / offset; }; - const newRootTile = (wrap: number): any => { + const newRootTile = (wrap: number): RootTile => { const max = maxRange; const min = minRange; return { @@ -844,10 +857,10 @@ class Transform { let result = []; const maxZoom = z; const overscaledZ = options.reparseOverscaled ? actualZ : z; - const square = a => a * a; + const square = (a: number) => a * a; const cameraHeightSqr = square((cameraAltitude - this._centerAltitude) * meterToTile); // in tile coordinates. - const getAABBFromElevation = (it) => { + const getAABBFromElevation = (it: RootTile) => { assert(this._elevation); if (!this._elevation || !it.tileID || !isMercator) return; // To silence flow. const minmax = this._elevation.getMinMaxForTile(it.tileID); @@ -870,7 +883,7 @@ class Transform { // Scale distance to split for acute angles. // dzSqr: z component of camera to tile distance, square. // dSqr: 3D distance of camera to tile, square. - const distToSplitScale = (dzSqr, dSqr) => { + const distToSplitScale = (dzSqr: number, dSqr: number) => { // When the angle between camera to tile ray and tile plane is smaller // than acuteAngleThreshold, scale the distance to split. Scaling is adaptive: smaller // the angle, the scale gets lower value. Although it seems early to start at 45, @@ -892,7 +905,7 @@ class Transform { return r / (1 / acuteAngleThresholdSin + (Math.pow(stretchTile, k + 1) - 1) / (stretchTile - 1) - 1); }; - const shouldSplit = (it) => { + const shouldSplit = (it: RootTile) => { if (it.zoom < minZoom) { return true; } else if (it.zoom === maxZoom) { @@ -1012,7 +1025,7 @@ class Transform { const childY = (y << 1) + (i >> 1); const aabb = isMercator ? it.aabb.quadrant(i) : tileAABB(this, numTiles, it.zoom + 1, childX, childY, it.wrap, it.minZ, it.maxZ, this.projection); - const child = {aabb, zoom: it.zoom + 1, x: childX, y: childY, wrap: it.wrap, fullyVisible, tileID: undefined, shouldSplit: undefined, minZ: it.minZ, maxZ: it.maxZ}; + const child: RootTile = {aabb, zoom: it.zoom + 1, x: childX, y: childY, wrap: it.wrap, fullyVisible, tileID: undefined, shouldSplit: undefined, minZ: it.minZ, maxZ: it.maxZ}; if (useElevationData && !isGlobe) { child.tileID = new OverscaledTileID(it.zoom + 1 === maxZoom ? overscaledZ : it.zoom + 1, it.wrap, it.zoom + 1, childX, childY); getAABBFromElevation(child); @@ -1415,7 +1428,7 @@ class Transform { // and mising area near the horizon is highly compressed so not noticeable const minRecursions = this.projection.name === "globe" ? 1 : 4; - const processSegment = (ax, ay, bx, by, depth) => { + const processSegment = (ax: number, ay: number, bx: number, by: number, depth: number) => { const mx = (ax + bx) / 2; const my = (ay + by) / 2; @@ -1478,7 +1491,7 @@ class Transform { // If map pitch places top corners off map edge (latitude > 90 or < -90), // place them at the intersection between the left/right screen edge and map edge. - const slope = (p1, p2) => (p2.y - p1.y) / (p2.x - p1.x); + const slope = (p1: MercatorCoordinate, p2: MercatorCoordinate) => (p2.y - p1.y) / (p2.x - p1.x); if (tl.y > 1 && tr.y >= 0) tl = new MercatorCoordinate((1 - bl.y) / slope(bl, tl) + bl.x, 1); else if (tl.y < 0 && tr.y <= 1) tl = new MercatorCoordinate(-bl.y / slope(bl, tl) + bl.x, 0); @@ -1847,7 +1860,7 @@ class Transform { return this._mercatorZfromZoom(this._minZoomForBounds()); } - _calcMatrices() { + _calcMatrices(): void { if (!this.height) return; const offset = this.centerOffset; diff --git a/src/render/draw_debug.js b/src/render/draw_debug.js index b1c51651fb0..de02759247a 100644 --- a/src/render/draw_debug.js +++ b/src/render/draw_debug.js @@ -145,7 +145,7 @@ function drawDebugSSRect(painter: Painter, x: number, y: number, width: number, gl.disable(gl.SCISSOR_TEST); } -function drawTileQueryGeometry(painter, sourceCache, coord: OverscaledTileID) { +function drawTileQueryGeometry(painter: Painter, sourceCache: SourceCache, coord: OverscaledTileID) { const context = painter.context; const gl = context.gl; diff --git a/src/render/draw_fill.js b/src/render/draw_fill.js index 25c55787bb4..82fcdc26e48 100644 --- a/src/render/draw_fill.js +++ b/src/render/draw_fill.js @@ -14,6 +14,7 @@ import type Painter from './painter.js'; import type SourceCache from '../source/source_cache.js'; import type FillStyleLayer from '../style/style_layer/fill_style_layer.js'; import type FillBucket from '../data/bucket/fill_bucket.js'; +import type ColorMode from '../gl/color_mode.js'; import type {OverscaledTileID} from '../source/tile_id.js'; export default drawFill; @@ -58,7 +59,7 @@ function drawFill(painter: Painter, sourceCache: SourceCache, layer: FillStyleLa } } -function drawFillTiles(painter, sourceCache, layer, coords, depthMode, colorMode, isOutline) { +function drawFillTiles(painter: Painter, sourceCache: SourceCache, layer: FillStyleLayer, coords: Array, depthMode: DepthMode, colorMode: ColorMode, isOutline: boolean) { const gl = painter.context.gl; const patternProperty = layer.paint.get('fill-pattern'); diff --git a/src/render/draw_fill_extrusion.js b/src/render/draw_fill_extrusion.js index 3992a395620..e00c2ff31dc 100644 --- a/src/render/draw_fill_extrusion.js +++ b/src/render/draw_fill_extrusion.js @@ -15,9 +15,12 @@ import {OverscaledTileID} from '../source/tile_id.js'; import assert from 'assert'; import {mercatorXfromLng, mercatorYfromLat} from '../geo/mercator_coordinate.js'; import {globeToMercatorTransition} from '../geo/projection/globe_util.js'; +import Context from '../gl/context.js'; +import {Terrain} from '../terrain/terrain.js'; import type Painter from './painter.js'; import type SourceCache from '../source/source_cache.js'; +import type {PartMetadata} from '../data/bucket/fill_extrusion_bucket.js'; import type FillExtrusionStyleLayer from '../style/style_layer/fill_extrusion_style_layer.js'; export default draw; @@ -54,7 +57,7 @@ function draw(painter: Painter, source: SourceCache, layer: FillExtrusionStyleLa } } -function drawExtrusionTiles(painter, source, layer, coords, depthMode, stencilMode, colorMode) { +function drawExtrusionTiles(painter: Painter, source: SourceCache, layer: FillExtrusionStyleLayer, coords: Array, depthMode: DepthMode, stencilMode: StencilMode, colorMode: ColorMode) { const context = painter.context; const gl = context.gl; const tr = painter.transform; @@ -147,7 +150,7 @@ function drawExtrusionTiles(painter, source, layer, coords, depthMode, stencilMo // Flat roofs array is prepared in the bucket, except for buildings that are on tile borders. // For them, join pieces, calculate joined size here, and then upload data. -function flatRoofsUpdate(context, source, coord, bucket, layer, terrain) { +function flatRoofsUpdate(context: Context, source: SourceCache, coord: OverscaledTileID, bucket: FillExtrusionBucket, layer: FillExtrusionStyleLayer, terrain: Terrain) { // For all four borders: 0 - left, 1, right, 2 - top, 3 - bottom const neighborCoord = [ (coord: OverscaledTileID) => { @@ -168,15 +171,15 @@ function flatRoofsUpdate(context, source, coord, bucket, layer, terrain) { } return new OverscaledTileID(coord.overscaledZ, w, coord.canonical.z, x, coord.canonical.y); }, - coord => new OverscaledTileID(coord.overscaledZ, coord.wrap, coord.canonical.z, coord.canonical.x, + (coord: OverscaledTileID) => new OverscaledTileID(coord.overscaledZ, coord.wrap, coord.canonical.z, coord.canonical.x, (coord.canonical.y === 0 ? 1 << coord.canonical.z : coord.canonical.y) - 1), - coord => new OverscaledTileID(coord.overscaledZ, coord.wrap, coord.canonical.z, coord.canonical.x, + (coord: OverscaledTileID) => new OverscaledTileID(coord.overscaledZ, coord.wrap, coord.canonical.z, coord.canonical.x, coord.canonical.y === (1 << coord.canonical.z) - 1 ? 0 : coord.canonical.y + 1) ]; - const getLoadedBucket = (nid) => { + const getLoadedBucket = (nid: OverscaledTileID) => { const minzoom = source.getSource().minzoom; - const getBucket = (key) => { + const getBucket = (key: number) => { const n = source.getTileByID(key); if (n && n.hasData()) { return n.getBucket(layer); @@ -198,23 +201,23 @@ function flatRoofsUpdate(context, source, coord, bucket, layer, terrain) { }; const projectedToBorder = [0, 0, 0]; // [min, max, maxOffsetFromBorder] - const xjoin = (a, b) => { + const xjoin = (a: PartMetadata, b: PartMetadata) => { projectedToBorder[0] = Math.min(a.min.y, b.min.y); projectedToBorder[1] = Math.max(a.max.y, b.max.y); projectedToBorder[2] = EXTENT - b.min.x > a.max.x ? b.min.x - EXTENT : a.max.x; return projectedToBorder; }; - const yjoin = (a, b) => { + const yjoin = (a: PartMetadata, b: PartMetadata) => { projectedToBorder[0] = Math.min(a.min.x, b.min.x); projectedToBorder[1] = Math.max(a.max.x, b.max.x); projectedToBorder[2] = EXTENT - b.min.y > a.max.y ? b.min.y - EXTENT : a.max.y; return projectedToBorder; }; const projectCombinedSpanToBorder = [ - (a, b) => xjoin(a, b), - (a, b) => xjoin(b, a), - (a, b) => yjoin(a, b), - (a, b) => yjoin(b, a) + (a: PartMetadata, b: PartMetadata) => xjoin(a, b), + (a: PartMetadata, b: PartMetadata) => xjoin(b, a), + (a: PartMetadata, b: PartMetadata) => yjoin(a, b), + (a: PartMetadata, b: PartMetadata) => yjoin(b, a) ]; const centroid = new Point(0, 0); @@ -222,7 +225,7 @@ function flatRoofsUpdate(context, source, coord, bucket, layer, terrain) { let demTile, neighborDEMTile, neighborTileID; - const flatBase = (min, max, edge, verticalEdge, maxOffsetFromBorder) => { + const flatBase = (min: number, max: number, edge: number, verticalEdge: boolean, maxOffsetFromBorder: number) => { const points = [[verticalEdge ? edge : min, verticalEdge ? min : edge, 0], [verticalEdge ? edge : max, verticalEdge ? max : edge, 0]]; const coord3 = maxOffsetFromBorder < 0 ? EXTENT + maxOffsetFromBorder : maxOffsetFromBorder; diff --git a/src/render/draw_heatmap.js b/src/render/draw_heatmap.js index 3de919a4f6c..fc5178599f4 100644 --- a/src/render/draw_heatmap.js +++ b/src/render/draw_heatmap.js @@ -13,6 +13,8 @@ import { import {mercatorXfromLng, mercatorYfromLat} from '../geo/mercator_coordinate.js'; import type Painter from './painter.js'; +import type Context from '../gl/context.js'; +import type Framebuffer from '../gl/framebuffer.js'; import type SourceCache from '../source/source_cache.js'; import type HeatmapStyleLayer from '../style/style_layer/heatmap_style_layer.js'; import type HeatmapBucket from '../data/bucket/heatmap_bucket.js'; @@ -86,7 +88,7 @@ function drawHeatmap(painter: Painter, sourceCache: SourceCache, layer: HeatmapS } } -function bindFramebuffer(context, painter, layer, scaling) { +function bindFramebuffer(context: Context, painter: Painter, layer: HeatmapStyleLayer, scaling: number) { const gl = context.gl; const width = painter.width * scaling; const height = painter.height * scaling; @@ -116,7 +118,7 @@ function bindFramebuffer(context, painter, layer, scaling) { } } -function bindTextureToFramebuffer(context, painter, texture, fbo, width, height) { +function bindTextureToFramebuffer(context: Context, painter: Painter, texture: ?WebGLTexture, fbo: Framebuffer, width: number, height: number) { const gl = context.gl; // Use the higher precision half-float texture where available (producing much smoother looking heatmaps); // Otherwise, fall back to a low precision texture @@ -127,7 +129,7 @@ function bindTextureToFramebuffer(context, painter, texture, fbo, width, height) fbo.colorAttachment.set(texture); } -function renderTextureToMap(painter, layer) { +function renderTextureToMap(painter: Painter, layer: HeatmapStyleLayer) { const context = painter.context; const gl = context.gl; diff --git a/src/render/draw_hillshade.js b/src/render/draw_hillshade.js index 6c75bc2b414..f8d0c48d49e 100644 --- a/src/render/draw_hillshade.js +++ b/src/render/draw_hillshade.js @@ -13,6 +13,7 @@ import type Painter from './painter.js'; import type SourceCache from '../source/source_cache.js'; import type Tile from '../source/tile.js'; import type HillshadeStyleLayer from '../style/style_layer/hillshade_style_layer.js'; +import type ColorMode from '../gl/color_mode.js'; import type {OverscaledTileID} from '../source/tile_id.js'; import assert from 'assert'; import DEMData from '../data/dem_data.js'; @@ -49,7 +50,7 @@ function drawHillshade(painter: Painter, sourceCache: SourceCache, layer: Hillsh painter.resetStencilClippingMasks(); } -function renderHillshade(painter, coord, tile, layer, depthMode, stencilMode, colorMode) { +function renderHillshade(painter: Painter, coord: OverscaledTileID, tile: Tile, layer: HillshadeStyleLayer, depthMode: DepthMode, stencilMode: StencilMode, colorMode: ColorMode) { const context = painter.context; const gl = context.gl; const fbo = tile.fbo; @@ -92,7 +93,7 @@ export function prepareDEMTexture(painter: Painter, tile: Tile, dem: DEMData) { // hillshade rendering is done in two steps. the prepare step first calculates the slope of the terrain in the x and y // directions for each pixel, and saves those values to a framebuffer texture in the r and g channels. -function prepareHillshade(painter, tile, layer, depthMode, stencilMode, colorMode) { +function prepareHillshade(painter: Painter, tile: Tile, layer: HillshadeStyleLayer, depthMode: DepthMode, stencilMode: StencilMode, colorMode: ColorMode) { const context = painter.context; const gl = context.gl; if (!tile.dem) return; diff --git a/src/render/draw_line.js b/src/render/draw_line.js index bb3bdc724ae..360cc48b393 100644 --- a/src/render/draw_line.js +++ b/src/render/draw_line.js @@ -147,7 +147,7 @@ export default function drawLine(painter: Painter, sourceCache: SourceCache, lay painter.prepareDrawProgram(context, program, coord.toUnwrapped()); - const renderLine = (stencilMode) => { + const renderLine = (stencilMode: StencilMode) => { program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled, uniformValues, layer.id, bucket.layoutVertexBuffer, bucket.indexBuffer, bucket.segments, diff --git a/src/render/draw_symbol.js b/src/render/draw_symbol.js index 52ee6942f92..b0978e1f0ef 100644 --- a/src/render/draw_symbol.js +++ b/src/render/draw_symbol.js @@ -34,10 +34,12 @@ import type SourceCache from '../source/source_cache.js'; import type SymbolStyleLayer from '../style/style_layer/symbol_style_layer.js'; import type SymbolBucket, {SymbolBuffers} from '../data/bucket/symbol_bucket.js'; import type Texture from '../render/texture.js'; +import type ColorMode from '../gl/color_mode.js'; import {OverscaledTileID} from '../source/tile_id.js'; import type {UniformValues} from './uniform_binding.js'; import type {SymbolSDFUniformsType} from '../render/program/symbol_program.js'; import type {CrossTileID, VariableOffset} from '../symbol/placement.js'; +import type {InterpolatedSize} from '../symbol/symbol_size'; export default drawSymbols; @@ -59,6 +61,8 @@ type SymbolTileRenderState = { } }; +type Alignment = 'auto' | 'map' | 'viewport'; + function drawSymbols(painter: Painter, sourceCache: SourceCache, layer: SymbolStyleLayer, coords: Array, variableOffsets: {[_: CrossTileID]: VariableOffset}) { if (painter.renderPass !== 'translucent') return; @@ -123,7 +127,7 @@ function computeGlobeCameraUp(transform: Transform): [number, number, number] { return cameraUpVector; } -function calculateVariableRenderShift({width, height, anchor, textOffset, textScale}, renderTextSize): Point { +function calculateVariableRenderShift({width, height, anchor, textOffset, textScale}: VariableOffset, renderTextSize: number): Point { const {horizontalAlign, verticalAlign} = getAnchorAlignment(anchor); const shiftX = -(horizontalAlign - 0.5) * width; const shiftY = -(verticalAlign - 0.5) * height; @@ -134,7 +138,7 @@ function calculateVariableRenderShift({width, height, anchor, textOffset, textSc ); } -function updateVariableAnchors(coords, painter, layer, sourceCache, rotationAlignment, pitchAlignment, variableOffsets) { +function updateVariableAnchors(coords: Array, painter: Painter, layer: SymbolStyleLayer, sourceCache: SourceCache, rotationAlignment: Alignment, pitchAlignment: Alignment, variableOffsets: { [_: CrossTileID]: VariableOffset }) { const tr = painter.transform; const rotateWithMap = rotationAlignment === 'map'; const pitchWithMap = pitchAlignment === 'map'; @@ -162,8 +166,7 @@ function updateVariableAnchors(coords, painter, layer, sourceCache, rotationAlig } } -function updateVariableAnchorsForBucket(bucket, rotateWithMap, pitchWithMap, variableOffsets, symbolSize, - transform, labelPlaneMatrix, coord, tileScale, size, updateTextFitIcon) { +function updateVariableAnchorsForBucket(bucket: SymbolBucket, rotateWithMap: boolean, pitchWithMap: boolean, variableOffsets: { [_: CrossTileID]: VariableOffset }, symbolSize: typeof symbolSize, transform: Transform, labelPlaneMatrix: Float32Array, coord: OverscaledTileID, tileScale: number, size: InterpolatedSize, updateTextFitIcon: boolean) { const placedSymbols = bucket.text.placedSymbolArray; const dynamicTextLayoutVertexArray = bucket.text.dynamicLayoutVertexArray; const dynamicIconLayoutVertexArray = bucket.icon.dynamicLayoutVertexArray; @@ -266,8 +269,7 @@ function getSymbolProgramName(isSDF: boolean, isText: boolean, bucket: SymbolBuc } } -function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate, translateAnchor, - rotationAlignment, pitchAlignment, keepUpright, stencilMode, colorMode) { +function drawLayerSymbols(painter: Painter, sourceCache: SourceCache, layer: SymbolStyleLayer, coords: Array, isText: boolean, translate: [number, number], translateAnchor: 'map' | 'viewport', rotationAlignment: Alignment, pitchAlignment: Alignment, keepUpright: boolean, stencilMode: StencilMode, colorMode: ColorMode) { const context = painter.context; const gl = context.gl; const tr = painter.transform; @@ -475,7 +477,7 @@ function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate } } -function drawSymbolElements(buffers, segments, layer, painter, program, depthMode, stencilMode, colorMode, uniformValues) { +function drawSymbolElements(buffers: SymbolBuffers, segments: SegmentVector, layer: SymbolStyleLayer, painter: Painter, program: any, depthMode: DepthMode, stencilMode: StencilMode, colorMode: ColorMode, uniformValues: UniformValues) { const context = painter.context; const gl = context.gl; const dynamicBuffers = [buffers.dynamicLayoutVertexBuffer, buffers.opacityVertexBuffer, buffers.globeExtVertexBuffer]; diff --git a/src/render/program/line_program.js b/src/render/program/line_program.js index c653dad03ac..b952c930d85 100644 --- a/src/render/program/line_program.js +++ b/src/render/program/line_program.js @@ -125,7 +125,7 @@ function calculateTileRatio(tile: Tile, transform: Transform) { return 1 / pixelsToTileUnits(tile, 1, transform.tileZoom); } -function calculateMatrix(painter, tile, layer, matrix) { +function calculateMatrix(painter: Painter, tile: Tile, layer: LineStyleLayer, matrix: ?Float32Array) { return painter.translatePosMatrix( matrix ? matrix : tile.tileID.projMatrix, tile, @@ -152,7 +152,7 @@ const lineDefinesValues = (layer: LineStyleLayer): LineDefinesType[] => { return values; }; -function hasDash(layer) { +function hasDash(layer: LineStyleLayer) { const dashPropertyValue = layer.paint.get('line-dasharray').value; return dashPropertyValue.value || dashPropertyValue.kind !== "constant"; } diff --git a/src/render/program/raster_program.js b/src/render/program/raster_program.js index ae6c046fad6..da0c70eaad5 100644 --- a/src/render/program/raster_program.js +++ b/src/render/program/raster_program.js @@ -67,7 +67,7 @@ const rasterUniformValues = ( 'u_perspective_transform': perspectiveTransform }); -function spinWeights(angle) { +function spinWeights(angle: number) { angle *= Math.PI / 180; const s = Math.sin(angle); const c = Math.cos(angle); @@ -78,13 +78,13 @@ function spinWeights(angle) { ]; } -function contrastFactor(contrast) { +function contrastFactor(contrast: number) { return contrast > 0 ? 1 / (1 - contrast) : 1 + contrast; } -function saturationFactor(saturation) { +function saturationFactor(saturation: number) { return saturation > 0 ? 1 - 1 / (1.001 - saturation) : -saturation; diff --git a/src/render/skybox_geometry.js b/src/render/skybox_geometry.js index 251f6934275..7dac3a962e7 100644 --- a/src/render/skybox_geometry.js +++ b/src/render/skybox_geometry.js @@ -7,7 +7,7 @@ import type IndexBuffer from '../gl/index_buffer.js'; import type VertexBuffer from '../gl/vertex_buffer.js'; import type Context from '../gl/context.js'; -function addVertex(vertexArray, x, y, z) { +function addVertex(vertexArray: SkyboxVertexArray, x: number, y: number, z: number) { vertexArray.emplaceBack( // a_pos x, diff --git a/src/source/canvas_source.js b/src/source/canvas_source.js index 1617a63cf3b..c355de29c87 100644 --- a/src/source/canvas_source.js +++ b/src/source/canvas_source.js @@ -124,11 +124,13 @@ class CanvasSource extends ImageSource { return; } + // $FlowFixMe[missing-this-annot] this.play = function() { this._playing = true; this.map.triggerRepaint(); }; + // $FlowFixMe[missing-this-annot] this.pause = function() { if (this._playing) { this.prepare(); diff --git a/src/source/custom_source.js b/src/source/custom_source.js index 7803e75bf77..4869eb9a41c 100644 --- a/src/source/custom_source.js +++ b/src/source/custom_source.js @@ -271,7 +271,8 @@ class CustomSource extends Evented implements Source { // $FlowFixMe[prop-missing] tile.request.cancel = () => controller.abort(); - function tileLoaded(data) { + // $FlowFixMe[missing-this-annot] + function tileLoaded(data: ?T) { delete tile.request; if (tile.aborted) { diff --git a/src/source/geojson_worker_source.js b/src/source/geojson_worker_source.js index 89552634762..256841ca2a0 100644 --- a/src/source/geojson_worker_source.js +++ b/src/source/geojson_worker_source.js @@ -51,6 +51,7 @@ export interface GeoJSONIndex { getLeaves(clusterId: number, limit: number, offset: number): Array; } +// $FlowFixMe[missing-this-annot] function loadGeoJSONTile(params: RequestedTileParameters, callback: LoadVectorDataCallback) { const canonical = params.tileID.canonical; @@ -247,7 +248,7 @@ class GeoJSONWorkerSource extends VectorTileWorkerSource { } } -function getSuperclusterOptions({superclusterOptions, clusterProperties}) { +function getSuperclusterOptions({superclusterOptions, clusterProperties}: LoadGeoJSONParameters) { if (!clusterProperties || !superclusterOptions) return superclusterOptions; const mapExpressions = {}; diff --git a/src/source/geojson_wrapper.js b/src/source/geojson_wrapper.js index f20c6f951fa..7588aa552ed 100644 --- a/src/source/geojson_wrapper.js +++ b/src/source/geojson_wrapper.js @@ -7,6 +7,7 @@ import {VectorTileFeature} from '@mapbox/vector-tile'; const toGeoJSON = VectorTileFeature.prototype.toGeoJSON; import EXTENT from '../data/extent.js'; +import type {GeoJSONFeature} from '@mapbox/geojson-types'; import type {IVectorTile, IVectorTileLayer, IVectorTileFeature} from '@mapbox/vector-tile'; // The feature type used by geojson-vt and supercluster. Should be extracted to @@ -49,7 +50,7 @@ class FeatureWrapper implements IVectorTileFeature { } } - loadGeometry() { + loadGeometry(): Array> { if (this._feature.type === 1) { const geometry = []; for (const point of this._feature.geometry) { @@ -69,7 +70,7 @@ class FeatureWrapper implements IVectorTileFeature { } } - toGeoJSON(x: number, y: number, z: number) { + toGeoJSON(x: number, y: number, z: number): GeoJSONFeature { return toGeoJSON.call(this, x, y, z); } } diff --git a/src/source/image_source.js b/src/source/image_source.js index a6b68daa00c..83b84240d3e 100644 --- a/src/source/image_source.js +++ b/src/source/image_source.js @@ -33,7 +33,7 @@ type Coordinates = [[number, number], [number, number], [number, number], [numbe // perspective correction for texture mapping, see https://github.com/mapbox/mapbox-gl-js/issues/9158 // adapted from https://math.stackexchange.com/a/339033/48653 -function basisToPoints(x1, y1, x2, y2, x3, y3, x4, y4) { +function basisToPoints(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, x4: number, y4: number) { const m = [x1, x2, x3, y1, y2, y3, 1, 1, 1]; const s = [x4, y4, 1]; const ma = mat3.adjoint([], m); @@ -41,7 +41,7 @@ function basisToPoints(x1, y1, x2, y2, x3, y3, x4, y4) { return mat3.multiply(m, [sx, 0, 0, 0, sy, 0, 0, 0, sz], m); } -function getPerspectiveTransform(w, h, x1, y1, x2, y2, x3, y3, x4, y4) { +function getPerspectiveTransform(w: number, h: number, x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, x4: number, y4: number) { const s = basisToPoints(0, 0, w, 0, 0, h, w, h); const m = basisToPoints(x1, y1, x2, y2, x3, y3, x4, y4); mat3.multiply(m, mat3.adjoint(s, s), m); diff --git a/src/source/query_features.js b/src/source/query_features.js index ede68d8b225..701988e23c6 100644 --- a/src/source/query_features.js +++ b/src/source/query_features.js @@ -1,12 +1,13 @@ // @flow +import type {OverscaledTileID} from './tile_id.js'; import type SourceCache from './source_cache.js'; import type StyleLayer from '../style/style_layer.js'; import type CollisionIndex from '../symbol/collision_index.js'; import type Transform from '../geo/transform.js'; import type {RetainedQueryData} from '../symbol/placement.js'; import type {FilterSpecification} from '../style-spec/types.js'; -import type {QueryGeometry} from '../style/query_geometry.js'; +import type {QueryGeometry, TilespaceQueryGeometry} from '../style/query_geometry.js'; import assert from 'assert'; import {mat4} from 'gl-matrix'; @@ -22,7 +23,7 @@ export type RenderedFeatureLayers = Array<{ /* * Returns a matrix that can be used to convert from tile coordinates to viewport pixel coordinates. */ -function getPixelPosMatrix(transform, tileID) { +function getPixelPosMatrix(transform: Transform, tileID: OverscaledTileID) { const t = mat4.identity([]); mat4.scale(t, t, [transform.width * 0.5, -transform.height * 0.5, 1]); mat4.translate(t, t, [1, -1, 0]); @@ -170,7 +171,7 @@ export function querySourceFeatures(sourceCache: SourceCache, params: any): Arra return result; } -function sortTilesIn(a, b) { +function sortTilesIn(a: TilespaceQueryGeometry | RetainedQueryData, b: TilespaceQueryGeometry | RetainedQueryData) { const idA = a.tileID; const idB = b.tileID; return (idA.overscaledZ - idB.overscaledZ) || (idA.canonical.y - idB.canonical.y) || (idA.wrap - idB.wrap) || (idA.canonical.x - idB.canonical.x); diff --git a/src/source/raster_dem_tile_source.js b/src/source/raster_dem_tile_source.js index f56b7d4fd2a..e4ed66b1732 100644 --- a/src/source/raster_dem_tile_source.js +++ b/src/source/raster_dem_tile_source.js @@ -9,12 +9,13 @@ import offscreenCanvasSupported from '../util/offscreen_canvas_supported.js'; import {OverscaledTileID} from './tile_id.js'; import RasterTileSource from './raster_tile_source.js'; // ensure DEMData is registered for worker transfer on main thread: -import '../data/dem_data.js'; +import DEMData from '../data/dem_data.js'; import type {Source} from './source.js'; import type Dispatcher from '../util/dispatcher.js'; import type Tile from './tile.js'; import type {Callback} from '../types/callback.js'; +import type {TextureImage} from '../render/texture.js'; import type {RasterDEMSourceSpecification} from '../style-spec/types.js'; // $FlowFixMe[method-unbinding] @@ -33,7 +34,8 @@ class RasterDEMTileSource extends RasterTileSource implements Source { const url = this.map._requestManager.normalizeTileURL(tile.tileID.canonical.url(this.tiles, this.scheme), false, this.tileSize); tile.request = getImage(this.map._requestManager.transformRequest(url, ResourceType.Tile), imageLoaded.bind(this)); - function imageLoaded(err, img, cacheControl, expires) { + // $FlowFixMe[missing-this-annot] + function imageLoaded(err: ?Error, img: ?TextureImage, cacheControl: ?string, expires: ?string) { delete tile.request; if (tile.aborted) { tile.state = 'unloaded'; @@ -53,6 +55,8 @@ class RasterDEMTileSource extends RasterTileSource implements Source { if (!borderReady && !tile.neighboringTiles) { tile.neighboringTiles = this._getNeighboringTiles(tile.tileID); } + + // $FlowFixMe[incompatible-call] const rawImageData = transfer ? img : browser.getImageData(img, padding); const params = { uid: tile.uid, @@ -70,7 +74,8 @@ class RasterDEMTileSource extends RasterTileSource implements Source { } } - function done(err, dem) { + // $FlowFixMe[missing-this-annot] + function done(err: ?Error, dem: ?DEMData) { if (err) { tile.state = 'errored'; callback(err); diff --git a/src/source/source.js b/src/source/source.js index a3a1e92a424..dafa442174d 100644 --- a/src/source/source.js +++ b/src/source/source.js @@ -106,7 +106,7 @@ import custom from '../source/custom_source.js'; import type {SourceSpecification} from '../style-spec/types.js'; -const sourceTypes = { +const sourceTypes: {[string]: Class} = { vector, raster, 'raster-dem': rasterDem, @@ -128,6 +128,7 @@ const sourceTypes = { * @returns {Source} */ export const create = function(id: string, specification: SourceSpecification, dispatcher: Dispatcher, eventedParent: Evented): Source { + // $FlowFixMe[prop-missing] const source = new sourceTypes[specification.type](id, (specification: any), dispatcher, eventedParent); if (source.id !== id) { diff --git a/src/source/source_cache.js b/src/source/source_cache.js index a1afffb650c..5b33cb3c5ad 100644 --- a/src/source/source_cache.js +++ b/src/source/source_cache.js @@ -292,7 +292,7 @@ class SourceCache extends Evented { } } - function fillBorder(tile, borderTile) { + function fillBorder(tile: Tile, borderTile: Tile) { if (!tile.dem || tile.dem.borderReady) return; tile.needsHillshadePrepare = true; tile.needsDEMTextureUpload = true; @@ -1043,7 +1043,7 @@ function compareTileId(a: OverscaledTileID, b: OverscaledTileID): number { return a.overscaledZ - b.overscaledZ || bWrap - aWrap || b.canonical.y - a.canonical.y || b.canonical.x - a.canonical.x; } -function isRasterType(type): boolean { +function isRasterType(type: string): boolean { return type === 'raster' || type === 'image' || type === 'video' || type === 'custom'; } diff --git a/src/source/tile_id.js b/src/source/tile_id.js index 016dfb624f9..54cdbe517a3 100644 --- a/src/source/tile_id.js +++ b/src/source/tile_id.js @@ -182,7 +182,7 @@ function calculateKey(wrap: number, overscaledZ: number, z: number, x: number, y return key; } -function getQuadkey(z, x, y) { +function getQuadkey(z: number, x: number, y: number) { let quadkey = '', mask; for (let i = z; i > 0; i--) { mask = 1 << (i - 1); diff --git a/src/source/tile_mesh.js b/src/source/tile_mesh.js index 5246d04fd09..2faf13cbcfd 100644 --- a/src/source/tile_mesh.js +++ b/src/source/tile_mesh.js @@ -67,7 +67,7 @@ type TileMesh = { // most of these issues. const commonRasterTileSize = 256; const paddingSize = meshSize / commonRasterTileSize / 4; -function seamPadding(n) { +function seamPadding(n: number) { if (n === 0) return -paddingSize; else if (n === gridSize - 1) return paddingSize; else return 0; @@ -132,7 +132,7 @@ export default function getTileMesh(canonical: CanonicalTileID, projection: Proj let numVertices = 0; - function addVertex(x, y) { + function addVertex(x: number, y: number) { const k = y * gridSize + x; if (indexMap[k] === 0) { @@ -149,7 +149,7 @@ export default function getTileMesh(canonical: CanonicalTileID, projection: Proj return indexMap[k] - 1; } - function addTriangles(ax, ay, bx, by, cx, cy) { + function addTriangles(ax: number, ay: number, bx: number, by: number, cx: number, cy: number) { const mx = (ax + bx) >> 1; const my = (ay + by) >> 1; diff --git a/src/source/vector_tile_source.js b/src/source/vector_tile_source.js index 70c23497a20..c3ca74a9ae3 100644 --- a/src/source/vector_tile_source.js +++ b/src/source/vector_tile_source.js @@ -21,6 +21,7 @@ import type {Cancelable} from '../types/cancelable.js'; import type {VectorSourceSpecification, PromoteIdSpecification} from '../style-spec/types.js'; import type Actor from '../util/actor.js'; import type {LoadVectorTileResult} from './vector_tile_worker_source.js'; +import type {WorkerTileResult} from './worker_source.js'; /** * A source containing vector tiles in [Mapbox Vector Tile format](https://docs.mapbox.com/vector-tiles/reference/). @@ -265,12 +266,14 @@ class VectorTileSource extends Evented implements Source { tile.request = tile.actor.send('reloadTile', params, done.bind(this)); } - function done(err, data) { + // $FlowFixMe[missing-this-annot] + function done(err: ?Error, data: ?WorkerTileResult) { delete tile.request; if (tile.aborted) return callback(null); + // $FlowFixMe[prop-missing] - generic Error type doesn't have status if (err && err.status !== 404) { return callback(err); } diff --git a/src/source/vector_tile_worker_source.js b/src/source/vector_tile_worker_source.js index 4257bc67064..bc89780fd45 100644 --- a/src/source/vector_tile_worker_source.js +++ b/src/source/vector_tile_worker_source.js @@ -12,6 +12,7 @@ import tileTransform from '../geo/projection/tile_transform.js'; import type { WorkerSource, + WorkerTileResult, WorkerTileParameters, RequestedTileParameters, WorkerTileCallback, @@ -98,10 +99,11 @@ export class DedupedRequest { /** * @private */ +// $FlowFixMe[missing-this-annot] export function loadVectorTile(params: RequestedTileParameters, callback: LoadVectorDataCallback, skipParse?: boolean): (() => void) { const key = JSON.stringify(params.request); - const makeRequest = (callback) => { + const makeRequest = (callback: LoadVectorDataCallback) => { const request = getArrayBuffer(params.request, (err: ?Error, data: ?ArrayBuffer, cacheControl: ?string, expires: ?string) => { if (err) { callback(err); @@ -253,7 +255,7 @@ class VectorTileWorkerSource extends Evented implements WorkerSource { workerTile.projection = params.projection; workerTile.tileTransform = tileTransform(params.tileID.canonical, params.projection); - const done = (err, data) => { + const done = (err: ?Error, data: ?WorkerTileResult) => { const reloadCallback = workerTile.reloadCallback; if (reloadCallback) { delete workerTile.reloadCallback; diff --git a/src/source/worker.js b/src/source/worker.js index 4f9994457c3..26b2ac86df3 100644 --- a/src/source/worker.js +++ b/src/source/worker.js @@ -259,7 +259,7 @@ export default class Worker { // use a wrapped actor so that we can attach a target mapId param // to any messages invoked by the WorkerSource const actor = { - send: (type, data, callback, _, mustQueue, metadata) => { + send: (type: string, data: mixed, callback: any, _: any, mustQueue: boolean, metadata: any) => { this.actor.send(type, data, callback, mapId, mustQueue, metadata); }, scheduler: this.actor.scheduler diff --git a/src/source/worker_tile.js b/src/source/worker_tile.js index eb8b25ce467..4894964cf10 100644 --- a/src/source/worker_tile.js +++ b/src/source/worker_tile.js @@ -224,9 +224,7 @@ class WorkerTile { PerformanceUtils.endMeasure(m); - maybePrepare.call(this); - - function maybePrepare() { + const maybePrepare = () => { if (error) { return callback(error); } else if (glyphMap && iconMap && patternMap) { @@ -274,7 +272,9 @@ class WorkerTile { }); PerformanceUtils.endMeasure(m); } - } + }; + + maybePrepare.call(this); } } diff --git a/src/style-spec/deref.js b/src/style-spec/deref.js index b5947adbe40..99ff5d23037 100644 --- a/src/style-spec/deref.js +++ b/src/style-spec/deref.js @@ -38,7 +38,7 @@ function deref(layer: LayerSpecification, parent: LayerSpecification): LayerSpec export default function derefLayers(layers: Array): Array { layers = layers.slice(); - const map = Object.create(null); + const map: Object = Object.create(null); for (let i = 0; i < layers.length; i++) { map[layers[i].id] = layers[i]; } diff --git a/src/style-spec/diff.js b/src/style-spec/diff.js index f25d31c3b8f..ac38be9c849 100644 --- a/src/style-spec/diff.js +++ b/src/style-spec/diff.js @@ -2,7 +2,9 @@ import isEqual from './util/deep_equal.js'; -import type {StyleSpecification} from './types.js'; +import type {StyleSpecification, SourceSpecification, LayerSpecification} from './types.js'; + +type Sources = { [string]: SourceSpecification }; type Command = { command: string; @@ -122,21 +124,21 @@ export const operations: {[_: string]: string} = { setProjection: 'setProjection' }; -function addSource(sourceId, after, commands) { +function addSource(sourceId: string, after: Sources, commands: Array) { commands.push({command: operations.addSource, args: [sourceId, after[sourceId]]}); } -function removeSource(sourceId, commands, sourcesRemoved) { +function removeSource(sourceId: string, commands: Array, sourcesRemoved: {[string]: true}) { commands.push({command: operations.removeSource, args: [sourceId]}); sourcesRemoved[sourceId] = true; } -function updateSource(sourceId, after, commands, sourcesRemoved) { +function updateSource(sourceId: string, after: Sources, commands: Array, sourcesRemoved: {[string]: true}) { removeSource(sourceId, commands, sourcesRemoved); addSource(sourceId, after, commands); } -function canUpdateGeoJSON(before, after, sourceId) { +function canUpdateGeoJSON(before: Sources, after: Sources, sourceId: string) { let prop; for (prop in before[sourceId]) { if (!before[sourceId].hasOwnProperty(prop)) continue; @@ -153,7 +155,7 @@ function canUpdateGeoJSON(before, after, sourceId) { return true; } -function diffSources(before, after, commands, sourcesRemoved) { +function diffSources(before: Sources, after: Sources, commands: Array, sourcesRemoved: {[string]: true}) { before = before || {}; after = after || {}; @@ -184,7 +186,7 @@ function diffSources(before, after, commands, sourcesRemoved) { } } -function diffLayerPropertyChanges(before, after, commands, layerId, klass, command) { +function diffLayerPropertyChanges(before: any, after: any, commands: Array, layerId: string, klass: ?string, command: string) { before = before || {}; after = after || {}; @@ -204,15 +206,16 @@ function diffLayerPropertyChanges(before, after, commands, layerId, klass, comma } } -function pluckId(layer) { +function pluckId(layer: LayerSpecification) { return layer.id; } -function indexById(group, layer) { + +function indexById(group: {[string]: LayerSpecification}, layer: LayerSpecification) { group[layer.id] = layer; return group; } -function diffLayers(before, after, commands) { +function diffLayers(before: Array, after: Array, commands: Array) { before = before || []; after = after || []; @@ -228,9 +231,9 @@ function diffLayers(before, after, commands) { const tracker = beforeOrder.slice(); // layers that have been added do not need to be diffed - const clean = Object.create(null); + const clean: Object = Object.create(null); - let i, d, layerId, beforeLayer, afterLayer, insertBeforeLayerId, prop; + let i, d, layerId, beforeLayer: LayerSpecification, afterLayer: LayerSpecification, insertBeforeLayerId, prop; // remove layers for (i = 0, d = 0; i < beforeOrder.length; i++) { @@ -278,6 +281,7 @@ function diffLayers(before, after, commands) { // If source, source-layer, or type have changes, then remove the layer // and add it back 'from scratch'. + // $FlowFixMe[prop-missing] - there is no `source-layer` in background and sky layers if (!isEqual(beforeLayer.source, afterLayer.source) || !isEqual(beforeLayer['source-layer'], afterLayer['source-layer']) || !isEqual(beforeLayer.type, afterLayer.type)) { commands.push({command: operations.removeLayer, args: [layerId]}); // we add the layer back at the same position it was already in, so diff --git a/src/style-spec/expression/definitions/format.js b/src/style-spec/expression/definitions/format.js index 6445edd63ff..84fcc210451 100644 --- a/src/style-spec/expression/definitions/format.js +++ b/src/style-spec/expression/definitions/format.js @@ -9,7 +9,7 @@ import type EvaluationContext from '../evaluation_context.js'; import type ParsingContext from '../parsing_context.js'; import type {Type} from '../types.js'; -type FormattedSectionExpression = { +export type FormattedSectionExpression = { // Content of a section may be Image expression or other // type of expression that is coercable to 'string'. content: Expression, @@ -84,7 +84,7 @@ export default class FormatExpression implements Expression { } evaluate(ctx: EvaluationContext): Formatted { - const evaluateSection = section => { + const evaluateSection = (section: FormattedSectionExpression) => { const evaluatedContent = section.content.evaluate(ctx); if (typeOf(evaluatedContent) === ResolvedImageType) { return new FormattedSection('', evaluatedContent, null, null, null); diff --git a/src/style-spec/expression/definitions/index.js b/src/style-spec/expression/definitions/index.js index 43284dcc0bb..5f8c6b4c6d0 100644 --- a/src/style-spec/expression/definitions/index.js +++ b/src/style-spec/expression/definitions/index.js @@ -46,8 +46,9 @@ import ImageExpression from './image.js'; import Length from './length.js'; import Within from './within.js'; +import type EvaluationContext from '../evaluation_context.js'; import type {Varargs} from '../compound_expression.js'; -import type {ExpressionRegistry} from '../expression.js'; +import type {Expression, ExpressionRegistry} from '../expression.js'; const expressions: ExpressionRegistry = { // special forms @@ -108,7 +109,7 @@ const expressions: ExpressionRegistry = { 'within': Within }; -function rgba(ctx, [r, g, b, a]) { +function rgba(ctx: EvaluationContext, [r, g, b, a]: Array) { r = r.evaluate(ctx); g = g.evaluate(ctx); b = b.evaluate(ctx); @@ -118,16 +119,16 @@ function rgba(ctx, [r, g, b, a]) { return new Color(r / 255 * alpha, g / 255 * alpha, b / 255 * alpha, alpha); } -function has(key, obj) { +function has(key: string, obj: {[string]: any}): boolean { return key in obj; } -function get(key, obj) { +function get(key: string, obj: {[string]: any}) { const v = obj[key]; return typeof v === 'undefined' ? null : v; } -function binarySearch(v, a, i, j) { +function binarySearch(v: any, a: {[number]: any}, i: number, j: number) { while (i <= j) { const m = (i + j) >> 1; if (a[m] === v) diff --git a/src/style-spec/expression/definitions/interpolate.js b/src/style-spec/expression/definitions/interpolate.js index 30e60d39084..f3b0729c52b 100644 --- a/src/style-spec/expression/definitions/interpolate.js +++ b/src/style-spec/expression/definitions/interpolate.js @@ -252,7 +252,7 @@ class Interpolate implements Expression { * * @private */ -function exponentialInterpolation(input, base, lowerValue, upperValue) { +function exponentialInterpolation(input: number, base: number, lowerValue: number, upperValue: number) { const difference = upperValue - lowerValue; const progress = input - lowerValue; diff --git a/src/style-spec/expression/definitions/match.js b/src/style-spec/expression/definitions/match.js index c4403102c96..5210125fe84 100644 --- a/src/style-spec/expression/definitions/match.js +++ b/src/style-spec/expression/definitions/match.js @@ -138,7 +138,7 @@ class Match implements Expression { } } - const coerceLabel = (label) => this.inputType.kind === 'number' ? Number(label) : label; + const coerceLabel = (label: number | string) => this.inputType.kind === 'number' ? Number(label) : label; for (const [outputIndex, labels] of groupedByOutput) { if (labels.length === 1) { diff --git a/src/style-spec/expression/definitions/within.js b/src/style-spec/expression/definitions/within.js index 6e5c98d6f4a..b828296fe90 100644 --- a/src/style-spec/expression/definitions/within.js +++ b/src/style-spec/expression/definitions/within.js @@ -6,7 +6,8 @@ import {BooleanType} from '../types.js'; import type {Expression, SerializedExpression} from '../expression.js'; import type ParsingContext from '../parsing_context.js'; import type EvaluationContext from '../evaluation_context.js'; -import type {GeoJSON, GeoJSONPolygon, GeoJSONMultiPolygon} from '@mapbox/geojson-types'; +import type Point from '@mapbox/point-geometry'; +import type {GeoJSON, GeoJSONPosition, GeoJSONPolygon, GeoJSONMultiPolygon} from '@mapbox/geojson-types'; import type {CanonicalTileID} from '../../../source/tile_id.js'; type GeoJSONPolygons =| GeoJSONPolygon | GeoJSONMultiPolygon; @@ -15,7 +16,7 @@ type GeoJSONPolygons =| GeoJSONPolygon | GeoJSONMultiPolygon; type BBox = [number, number, number, number]; const EXTENT = 8192; -function updateBBox(bbox: BBox, coord: [number, number]) { +function updateBBox(bbox: BBox, coord: GeoJSONPosition) { bbox[0] = Math.min(bbox[0], coord[0]); bbox[1] = Math.min(bbox[1], coord[1]); bbox[2] = Math.max(bbox[2], coord[0]); @@ -38,14 +39,14 @@ function boxWithinBox(bbox1: BBox, bbox2: BBox) { return true; } -function getTileCoordinates(p, canonical: CanonicalTileID) { +function getTileCoordinates(p: GeoJSONPosition, canonical: CanonicalTileID) { const x = mercatorXfromLng(p[0]); const y = mercatorYfromLat(p[1]); const tilesAtZoom = Math.pow(2, canonical.z); return [Math.round(x * tilesAtZoom * EXTENT), Math.round(y * tilesAtZoom * EXTENT)]; } -function onBoundary(p, p1, p2) { +function onBoundary(p: GeoJSONPosition, p1: GeoJSONPosition, p2: GeoJSONPosition) { const x1 = p[0] - p1[0]; const y1 = p[1] - p1[1]; const x2 = p[0] - p2[0]; @@ -53,12 +54,12 @@ function onBoundary(p, p1, p2) { return (x1 * y2 - x2 * y1 === 0) && (x1 * x2 <= 0) && (y1 * y2 <= 0); } -function rayIntersect(p, p1, p2) { +function rayIntersect(p: GeoJSONPosition, p1: GeoJSONPosition, p2: GeoJSONPosition) { return ((p1[1] > p[1]) !== (p2[1] > p[1])) && (p[0] < (p2[0] - p1[0]) * (p[1] - p1[1]) / (p2[1] - p1[1]) + p1[0]); } // ray casting algorithm for detecting if point is in polygon -function pointWithinPolygon(point, rings) { +function pointWithinPolygon(point: GeoJSONPosition, rings: Array>) { let inside = false; for (let i = 0, len = rings.length; i < len; i++) { const ring = rings[i]; @@ -70,19 +71,19 @@ function pointWithinPolygon(point, rings) { return inside; } -function pointWithinPolygons(point, polygons) { +function pointWithinPolygons(point: GeoJSONPosition, polygons: Array>>) { for (let i = 0; i < polygons.length; i++) { if (pointWithinPolygon(point, polygons[i])) return true; } return false; } -function perp(v1, v2) { +function perp(v1: GeoJSONPosition, v2: GeoJSONPosition) { return (v1[0] * v2[1] - v1[1] * v2[0]); } // check if p1 and p2 are in different sides of line segment q1->q2 -function twoSided(p1, p2, q1, q2) { +function twoSided(p1: GeoJSONPosition, p2: GeoJSONPosition, q1: GeoJSONPosition, q2: GeoJSONPosition) { // q1->p1 (x1, y1), q1->p2 (x2, y2), q1->q2 (x3, y3) const x1 = p1[0] - q1[0]; const y1 = p1[1] - q1[1]; @@ -96,7 +97,7 @@ function twoSided(p1, p2, q1, q2) { return false; } // a, b are end points for line segment1, c and d are end points for line segment2 -function lineIntersectLine(a, b, c, d) { +function lineIntersectLine(a: GeoJSONPosition, b: GeoJSONPosition, c: GeoJSONPosition, d: GeoJSONPosition) { // check if two segments are parallel or not // precondition is end point a, b is inside polygon, if line a->b is // parallel to polygon edge c->d, then a->b won't intersect with c->d @@ -111,7 +112,7 @@ function lineIntersectLine(a, b, c, d) { return false; } -function lineIntersectPolygon(p1, p2, polygon) { +function lineIntersectPolygon(p1: GeoJSONPosition, p2: GeoJSONPosition, polygon: Array>) { for (const ring of polygon) { // loop through every edge of the ring for (let j = 0; j < ring.length - 1; ++j) { @@ -123,7 +124,7 @@ function lineIntersectPolygon(p1, p2, polygon) { return false; } -function lineStringWithinPolygon(line, polygon) { +function lineStringWithinPolygon(line: Array, polygon: Array>) { // First, check if geometry points of line segments are all inside polygon for (let i = 0; i < line.length; ++i) { if (!pointWithinPolygon(line[i], polygon)) { @@ -140,14 +141,14 @@ function lineStringWithinPolygon(line, polygon) { return true; } -function lineStringWithinPolygons(line, polygons) { +function lineStringWithinPolygons(line: Array, polygons: Array>>) { for (let i = 0; i < polygons.length; i++) { if (lineStringWithinPolygon(line, polygons[i])) return true; } return false; } -function getTilePolygon(coordinates, bbox: BBox, canonical: CanonicalTileID) { +function getTilePolygon(coordinates: Array>, bbox: BBox, canonical: CanonicalTileID) { const polygon = []; for (let i = 0; i < coordinates.length; i++) { const ring = []; @@ -161,7 +162,7 @@ function getTilePolygon(coordinates, bbox: BBox, canonical: CanonicalTileID) { return polygon; } -function getTilePolygons(coordinates, bbox, canonical: CanonicalTileID) { +function getTilePolygons(coordinates: Array>>, bbox: BBox, canonical: CanonicalTileID) { const polygons = []; for (let i = 0; i < coordinates.length; i++) { const polygon = getTilePolygon(coordinates[i], bbox, canonical); @@ -170,7 +171,7 @@ function getTilePolygons(coordinates, bbox, canonical: CanonicalTileID) { return polygons; } -function updatePoint(p, bbox, polyBBox, worldSize) { +function updatePoint(p: GeoJSONPosition, bbox: BBox, polyBBox: Array, worldSize: number) { if (p[0] < polyBBox[0] || p[0] > polyBBox[2]) { const halfWorldSize = worldSize * 0.5; let shift = (p[0] - polyBBox[0] > halfWorldSize) ? -worldSize : (polyBBox[0] - p[0] > halfWorldSize) ? worldSize : 0; @@ -182,12 +183,12 @@ function updatePoint(p, bbox, polyBBox, worldSize) { updateBBox(bbox, p); } -function resetBBox(bbox) { +function resetBBox(bbox: BBox) { bbox[0] = bbox[1] = Infinity; bbox[2] = bbox[3] = -Infinity; } -function getTilePoints(geometry, pointBBox, polyBBox, canonical: CanonicalTileID) { +function getTilePoints(geometry: ?Array>, pointBBox: BBox, polyBBox: Array, canonical: CanonicalTileID) { const worldSize = Math.pow(2, canonical.z) * EXTENT; const shifts = [canonical.x * EXTENT, canonical.y * EXTENT]; const tilePoints = []; @@ -202,15 +203,15 @@ function getTilePoints(geometry, pointBBox, polyBBox, canonical: CanonicalTileID return tilePoints; } -function getTileLines(geometry, lineBBox, polyBBox, canonical: CanonicalTileID) { +function getTileLines(geometry: ?Array>, lineBBox: BBox, polyBBox: Array, canonical: CanonicalTileID) { const worldSize = Math.pow(2, canonical.z) * EXTENT; const shifts = [canonical.x * EXTENT, canonical.y * EXTENT]; - const tileLines = []; + const tileLines: Array> = []; if (!geometry) return tileLines; for (const line of geometry) { const tileLine = []; for (const point of line) { - const p = [point.x + shifts[0], point.y + shifts[1]]; + const p: GeoJSONPosition = [point.x + shifts[0], point.y + shifts[1]]; updateBBox(lineBBox, p); tileLine.push(p); } diff --git a/src/style-spec/expression/parsing_context.js b/src/style-spec/expression/parsing_context.js index 39c4e71a598..936eb96ffc3 100644 --- a/src/style-spec/expression/parsing_context.js +++ b/src/style-spec/expression/parsing_context.js @@ -73,7 +73,7 @@ class ParsingContext { expr = ['literal', expr]; } - function annotate(parsed, type, typeAnnotation: 'assert' | 'coerce' | 'omit') { + function annotate(parsed: Expression, type: Type, typeAnnotation: 'assert' | 'coerce' | 'omit') { if (typeAnnotation === 'assert') { return new Assertion(type, [parsed]); } else if (typeAnnotation === 'coerce') { diff --git a/src/style-spec/feature_filter/convert.js b/src/style-spec/feature_filter/convert.js index e3394f699d4..c363f33f5b3 100644 --- a/src/style-spec/feature_filter/convert.js +++ b/src/style-spec/feature_filter/convert.js @@ -161,7 +161,7 @@ function convertComparisonOp(property: string, value: any, op: string, expectedT return [op, get, value]; } -function convertInOp(property: string, values: Array, negate = false) { +function convertInOp(property: string, values: Array, negate: boolean = false) { if (values.length === 0) return negate; let get; diff --git a/src/style-spec/feature_filter/index.js b/src/style-spec/feature_filter/index.js index 294ab2114f1..6d67995d289 100644 --- a/src/style-spec/feature_filter/index.js +++ b/src/style-spec/feature_filter/index.js @@ -254,11 +254,11 @@ function collapsedExpression(expression: any): any { } // Comparison function to sort numbers and strings -function compare(a, b) { +function compare(a: number, b: number) { return a < b ? -1 : a > b ? 1 : 0; } -function geometryNeeded(filter) { +function geometryNeeded(filter: Array | boolean) { if (!Array.isArray(filter)) return false; if (filter[0] === 'within') return true; for (let index = 1; index < filter.length; index++) { diff --git a/src/style-spec/function/convert.js b/src/style-spec/function/convert.js index 5b520065c87..ce3cb750bcd 100644 --- a/src/style-spec/function/convert.js +++ b/src/style-spec/function/convert.js @@ -5,11 +5,22 @@ import assert from 'assert'; import type {StylePropertySpecification} from '../style-spec.js'; import type {ExpressionSpecification} from '../types.js'; -function convertLiteral(value) { +type Stop = [{zoom: number, value: string | number | boolean}, mixed]; + +type FunctionParameters = { + stops: Array; + base: number; + property: string; + type: 'identity' | 'exponential' | 'interval' | 'categorical'; + colorSpace: 'rgb' | 'lab' | 'hcl'; + default: mixed; +}; + +function convertLiteral(value: mixed) { return typeof value === 'object' ? ['literal', value] : value; } -export default function convertFunction(parameters: any, propertySpec: StylePropertySpecification): ExpressionSpecification { +export default function convertFunction(parameters: FunctionParameters, propertySpec: StylePropertySpecification): ExpressionSpecification { let stops = parameters.stops; if (!stops) { // identity function @@ -36,7 +47,7 @@ export default function convertFunction(parameters: any, propertySpec: StyleProp } } -function convertIdentityFunction(parameters, propertySpec): Array { +function convertIdentityFunction(parameters: FunctionParameters, propertySpec: StylePropertySpecification): Array { const get = ['get', parameters.property]; if (parameters.default === undefined) { @@ -60,7 +71,7 @@ function convertIdentityFunction(parameters, propertySpec): Array { } } -function getInterpolateOperator(parameters) { +function getInterpolateOperator(parameters: FunctionParameters) { switch (parameters.colorSpace) { case 'hcl': return 'interpolate-hcl'; case 'lab': return 'interpolate-lab'; @@ -68,7 +79,7 @@ function getInterpolateOperator(parameters) { } } -function convertZoomAndPropertyFunction(parameters, propertySpec, stops) { +function convertZoomAndPropertyFunction(parameters: FunctionParameters, propertySpec: StylePropertySpecification, stops: Array) { const featureFunctionParameters = {}; const featureFunctionStops = {}; const zoomStops = []; @@ -116,12 +127,12 @@ function convertZoomAndPropertyFunction(parameters, propertySpec, stops) { } } -function coalesce(a, b) { +function coalesce(a: mixed, b: mixed) { if (a !== undefined) return a; if (b !== undefined) return b; } -function getFallback(parameters, propertySpec) { +function getFallback(parameters: FunctionParameters, propertySpec: StylePropertySpecification) { const defaultValue = convertLiteral(coalesce(parameters.default, propertySpec.default)); /* @@ -136,7 +147,7 @@ function getFallback(parameters, propertySpec) { return defaultValue; } -function convertPropertyFunction(parameters, propertySpec, stops) { +function convertPropertyFunction(parameters: FunctionParameters, propertySpec: StylePropertySpecification, stops: Array) { const type = getFunctionType(parameters, propertySpec); const get = ['get', parameters.property]; if (type === 'categorical' && typeof stops[0][0] === 'boolean') { @@ -189,7 +200,7 @@ function convertPropertyFunction(parameters, propertySpec, stops) { } } -function convertZoomFunction(parameters, propertySpec, stops, input = ['zoom']) { +function convertZoomFunction(parameters: FunctionParameters, propertySpec: StylePropertySpecification, stops: Array, input: Array = ['zoom']) { const type = getFunctionType(parameters, propertySpec); let expression; let isStep = false; @@ -213,7 +224,7 @@ function convertZoomFunction(parameters, propertySpec, stops, input = ['zoom']) return expression; } -function fixupDegenerateStepCurve(expression) { +function fixupDegenerateStepCurve(expression: ExpressionSpecification) { // degenerate step curve (i.e. a constant function): add a noop stop if (expression[0] === 'step' && expression.length === 3) { expression.push(0); @@ -221,7 +232,7 @@ function fixupDegenerateStepCurve(expression) { } } -function appendStopPair(curve, input, output, isStep) { +function appendStopPair(curve: ExpressionSpecification, input: mixed, output: mixed, isStep: boolean) { // Skip duplicate stop values. They were not validated for functions, but they are for expressions. // https://github.com/mapbox/mapbox-gl-js/issues/4107 if (curve.length > 3 && input === curve[curve.length - 2]) { @@ -234,7 +245,7 @@ function appendStopPair(curve, input, output, isStep) { curve.push(output); } -function getFunctionType(parameters, propertySpec) { +function getFunctionType(parameters: FunctionParameters, propertySpec: StylePropertySpecification): string { if (parameters.type) { return parameters.type; } else { diff --git a/src/style-spec/group_by_layout.js b/src/style-spec/group_by_layout.js index 20045cddf48..8335c23225f 100644 --- a/src/style-spec/group_by_layout.js +++ b/src/style-spec/group_by_layout.js @@ -4,7 +4,7 @@ import type {LayerSpecification} from './types.js'; import refProperties from './util/ref_properties.js'; -function stringify(obj) { +function stringify(obj: any) { if (typeof obj === 'number' || typeof obj === 'boolean' || typeof obj === 'string' || obj === undefined || obj === null) return JSON.stringify(obj); @@ -23,7 +23,7 @@ function stringify(obj) { return `${str}}`; } -function getKey(layer) { +function getKey(layer: LayerSpecification) { let key = ''; for (const k of refProperties) { key += `/${stringify((layer: any)[k])}`; diff --git a/src/style-spec/migrate/expressions.js b/src/style-spec/migrate/expressions.js index 65fef2582b6..38f30145dcb 100644 --- a/src/style-spec/migrate/expressions.js +++ b/src/style-spec/migrate/expressions.js @@ -27,6 +27,9 @@ export default function(style: StyleSpecification): StyleSpecification { eachProperty(style, {paint: true, layout: true}, ({path, value, reference, set}) => { if (isExpression(value)) return; if (typeof value === 'object' && !Array.isArray(value)) { + // $FlowFixMe[prop-missing] + // $FlowFixMe[incompatible-call] + // $FlowFixMe[incompatible-variance] set(convertFunction(value, reference)); converted.push(path.join('.')); } else if (reference.tokens && typeof value === 'string') { diff --git a/src/style-spec/validate/validate_filter.js b/src/style-spec/validate/validate_filter.js index 489ef934453..7368b0f0d0f 100644 --- a/src/style-spec/validate/validate_filter.js +++ b/src/style-spec/validate/validate_filter.js @@ -11,7 +11,7 @@ import {isExpressionFilter} from '../feature_filter/index.js'; import type {ValidationOptions} from './validate.js'; type Options = ValidationOptions & { - layerType: string; + layerType?: string; } export default function validateFilter(options: Options): Array { @@ -28,7 +28,7 @@ export default function validateFilter(options: Options): Array } } -function validateNonExpressionFilter(options) { +function validateNonExpressionFilter(options: Options) { const value = options.value; const key = options.key; @@ -96,12 +96,12 @@ function validateNonExpressionFilter(options) { case 'all': case 'none': for (let i = 1; i < value.length; i++) { - errors = errors.concat(validateNonExpressionFilter({ + errors = errors.concat(validateNonExpressionFilter(({ key: `${key}[${i}]`, value: value[i], style: options.style, styleSpec: options.styleSpec - })); + }: any))); } break; diff --git a/src/style-spec/validate/validate_function.js b/src/style-spec/validate/validate_function.js index e86e3af4e54..67ff23aea72 100644 --- a/src/style-spec/validate/validate_function.js +++ b/src/style-spec/validate/validate_function.js @@ -161,7 +161,7 @@ export default function validateFunction(options: ValidationOptions): any { })); } - function validateStopDomainValue(options: ValidationOptions, stop) { + function validateStopDomainValue(options: ValidationOptions, stop: any) { const type = getType(options.value); const value = unbundle(options.value); diff --git a/src/style-spec/validate/validate_source.js b/src/style-spec/validate/validate_source.js index 61cafc19fa1..789b4628ab6 100644 --- a/src/style-spec/validate/validate_source.js +++ b/src/style-spec/validate/validate_source.js @@ -8,6 +8,7 @@ import validateExpression from './validate_expression.js'; import validateString from './validate_string.js'; import getType from '../util/get_type.js'; +import type {StyleReference} from '../reference/latest.js'; import type {ValidationOptions} from './validate.js'; const objectElementValidators = { @@ -101,7 +102,7 @@ export default function validateSource(options: ValidationOptions): Array { const sourceType = styleSpec[source]; if (sourceType.type.type === 'enum') { @@ -111,7 +112,7 @@ function getSourceTypeValues(styleSpec) { }, []); } -function validatePromoteId({key, value}) { +function validatePromoteId({key, value}: $Shape) { if (getType(value) === 'string') { return validateString({key, value}); } else { diff --git a/src/style-spec/validate_style.min.js b/src/style-spec/validate_style.min.js index a1ab583635d..c2b8e3738d2 100644 --- a/src/style-spec/validate_style.min.js +++ b/src/style-spec/validate_style.min.js @@ -62,6 +62,6 @@ export const validateFilter: Validator = opts => sortErrors(_validateFilter(opts export const validatePaintProperty: Validator = opts => sortErrors(_validatePaintProperty(opts)); export const validateLayoutProperty: Validator = opts => sortErrors(_validateLayoutProperty(opts)); -function sortErrors(errors) { +function sortErrors(errors: ValidationErrors) { return errors.slice().sort((a, b) => a.line && b.line ? a.line - b.line : 0); } diff --git a/src/style-spec/visit.js b/src/style-spec/visit.js index e26d0ebd8c7..b4ca254b7d6 100644 --- a/src/style-spec/visit.js +++ b/src/style-spec/visit.js @@ -10,7 +10,7 @@ import type { DataDrivenPropertyValueSpecification } from './types.js'; -function getPropertyReference(propertyName): StylePropertySpecification { +function getPropertyReference(propertyName: string): StylePropertySpecification { for (let i = 0; i < Reference.layout.length; i++) { for (const key in Reference[Reference.layout[i]]) { if (key === propertyName) return (Reference[Reference.layout[i]][key]: any); @@ -50,7 +50,7 @@ export function eachProperty( options: {paint?: boolean, layout?: boolean}, callback: PropertyCallback ) { - function inner(layer, propertyType: 'paint' | 'layout') { + function inner(layer: LayerSpecification, propertyType: 'paint' | 'layout') { const properties = (layer[propertyType]: any); if (!properties) return; Object.keys(properties).forEach((key) => { diff --git a/src/style/fog.js b/src/style/fog.js index 56097879994..04b7ca05d8d 100644 --- a/src/style/fog.js +++ b/src/style/fog.js @@ -82,6 +82,7 @@ class Fog extends Evented { for (const name of Object.keys(styleSpec.fog)) { // Fallback to use default style specification when the properties wasn't set if (fog && fog[name] === undefined) { + // $FlowFixMe[prop-missing] fog[name] = styleSpec.fog[name].default; } } diff --git a/src/style/properties.js b/src/style/properties.js index a19fb7b5c6e..220bb981124 100644 --- a/src/style/properties.js +++ b/src/style/properties.js @@ -423,7 +423,7 @@ export class Layout { * * @private */ -type PossiblyEvaluatedValue = +export type PossiblyEvaluatedValue = | {kind: 'constant', value: T} | SourceExpression | CompositeExpression; diff --git a/src/style/style.js b/src/style/style.js index 056f9239e74..5493def69de 100644 --- a/src/style/style.js +++ b/src/style/style.js @@ -492,7 +492,7 @@ class Style extends Evented { return drapedLayers[layer.type]; } - _checkLoaded() { + _checkLoaded(): void { if (!this._loaded) { throw new Error('Style is not done loading'); } @@ -711,7 +711,7 @@ class Style extends Evented { return this._availableImages.slice(); } - addSource(id: string, source: SourceSpecification, options: StyleSetterOptions = {}) { + addSource(id: string, source: SourceSpecification, options: StyleSetterOptions = {}): void { this._checkLoaded(); if (this.getSource(id) !== undefined) { @@ -736,7 +736,7 @@ class Style extends Evented { sourceId: id })); - const addSourceCache = (onlySymbols) => { + const addSourceCache = (onlySymbols: boolean) => { const sourceCacheId = (onlySymbols ? 'symbol:' : 'other:') + id; const sourceCache = this._sourceCaches[sourceCacheId] = new SourceCache(sourceCacheId, sourceInstance, onlySymbols); (onlySymbols ? this._symbolSourceCaches : this._otherSourceCaches)[id] = sourceCache; @@ -1285,7 +1285,7 @@ class Style extends Evented { // This means that that the line_layer feature is above the extrusion_layer_b feature despite // it being in an earlier layer. - const isLayer3D = layerId => this._layers[layerId].type === 'fill-extrusion'; + const isLayer3D = (layerId: string) => this._layers[layerId].type === 'fill-extrusion'; const layerIndex = {}; const features3D = []; @@ -1507,6 +1507,7 @@ class Style extends Evented { for (const name of Object.keys(styleSpec.terrain)) { // Fallback to use default style specification when the properties wasn't set if (!options.hasOwnProperty(name) && !!styleSpec.terrain[name].default) { + // $FlowFixMe[prop-missing] options[name] = styleSpec.terrain[name].default; } } diff --git a/src/style/style_layer/fill_extrusion_style_layer.js b/src/style/style_layer/fill_extrusion_style_layer.js index a874e8d3163..3680c2e2988 100644 --- a/src/style/style_layer/fill_extrusion_style_layer.js +++ b/src/style/style_layer/fill_extrusion_style_layer.js @@ -118,7 +118,7 @@ class FillExtrusionStyleLayer extends StyleLayer { } } -function dot(a, b) { +function dot(a: Point, b: Point) { return a.x * b.x + a.y * b.y; } @@ -229,7 +229,7 @@ function projectExtrusionGlobe(tr: Transform, geometry: Array>, zBa const basePoint = [0, 0, 0, 1]; const topPoint = [0, 0, 0, 1]; - const setPoint = (point, x, y, z) => { + const setPoint = (point: Array, x: number, y: number, z: number) => { point[0] = x; point[1] = y; point[2] = z; diff --git a/src/style/style_layer/line_style_layer.js b/src/style/style_layer/line_style_layer.js index 08a66d2c97a..eb295ef73c4 100644 --- a/src/style/style_layer/line_style_layer.js +++ b/src/style/style_layer/line_style_layer.js @@ -13,7 +13,8 @@ import {Transitionable, Transitioning, Layout, PossiblyEvaluated, DataDrivenProp import ProgramConfiguration from '../../data/program_configuration.js'; import Step from '../../style-spec/expression/definitions/step.js'; -import type {FeatureState, ZoomConstantExpression, StylePropertyExpression} from '../../style-spec/expression/index.js'; +import type {PossiblyEvaluatedValue, PropertyValue, PossiblyEvaluatedPropertyValue} from '../properties.js'; +import type {Feature, FeatureState, ZoomConstantExpression, StylePropertyExpression} from '../../style-spec/expression/index.js'; import type {Bucket, BucketParameters} from '../../data/bucket.js'; import type {LayoutProps, PaintProps} from './line_style_layer_properties.js'; import type Transform from '../../geo/transform.js'; @@ -24,7 +25,7 @@ import type {IVectorTileFeature} from '@mapbox/vector-tile'; class LineFloorwidthProperty extends DataDrivenProperty { useIntegerZoom: ?boolean; - possiblyEvaluate(value, parameters) { + possiblyEvaluate(value: PropertyValue>, parameters: EvaluationParameters): PossiblyEvaluatedPropertyValue { parameters = new EvaluationParameters(Math.floor(parameters.zoom), { now: parameters.now, fadeDuration: parameters.fadeDuration, @@ -33,7 +34,7 @@ class LineFloorwidthProperty extends DataDrivenProperty { return super.possiblyEvaluate(value, parameters); } - evaluate(value, globals, feature, featureState) { + evaluate(value: PossiblyEvaluatedValue, globals: EvaluationParameters, feature: Feature, featureState: FeatureState): number { globals = extend({}, globals, {zoom: Math.floor(globals.zoom)}); return super.evaluate(value, globals, feature, featureState); } @@ -137,7 +138,7 @@ class LineStyleLayer extends StyleLayer { export default LineStyleLayer; -function getLineWidth(lineWidth, lineGapWidth) { +function getLineWidth(lineWidth: number, lineGapWidth: number) { if (lineGapWidth > 0) { return lineGapWidth + 2 * lineWidth; } else { @@ -145,7 +146,7 @@ function getLineWidth(lineWidth, lineGapWidth) { } } -function offsetLine(rings, offset) { +function offsetLine(rings: Array>, offset: number) { const newRings = []; const zero = new Point(0, 0); for (let k = 0; k < rings.length; k++) { diff --git a/src/style/style_layer/symbol_style_layer.js b/src/style/style_layer/symbol_style_layer.js index 8eac1810527..8562105cf1b 100644 --- a/src/style/style_layer/symbol_style_layer.js +++ b/src/style/style_layer/symbol_style_layer.js @@ -6,6 +6,8 @@ import assert from 'assert'; import SymbolBucket from '../../data/bucket/symbol_bucket.js'; import resolveTokens from '../../util/resolve_tokens.js'; import properties from './symbol_style_layer_properties.js'; +import type {FormattedSection} from '../../style-spec/expression/types/formatted.js'; +import type {FormattedSectionExpression} from '../../style-spec/expression/definitions/format.js'; import { Transitionable, @@ -140,6 +142,7 @@ class SymbolStyleLayer extends StyleLayer { overriden.value.zoomStops, overriden.value._interpolationType): CompositeExpression); } + // $FlowFixMe[prop-missing] this.paint._values[overridable] = new PossiblyEvaluatedPropertyValue(overriden.property, expression, overriden.parameters); @@ -158,7 +161,7 @@ class SymbolStyleLayer extends StyleLayer { const property = properties.paint.properties[propertyName]; let hasOverrides = false; - const checkSections = (sections) => { + const checkSections = (sections: Array | Array) => { for (const section of sections) { if (property.overrides && property.overrides.hasOverride(section)) { hasOverrides = true; diff --git a/src/symbol/get_anchors.js b/src/symbol/get_anchors.js index 5c5a5262353..0cfd80067f6 100644 --- a/src/symbol/get_anchors.js +++ b/src/symbol/get_anchors.js @@ -110,7 +110,7 @@ function getAnchors(line: Array, return resample(line, offset, spacing, angleWindowSize, maxAngle, labelLength, isLineContinued, false, tileExtent); } -function resample(line, offset, spacing, angleWindowSize, maxAngle, labelLength, isLineContinued, placeAtMiddle, tileExtent) { +function resample(line: Array, offset: number, spacing: number, angleWindowSize: number, maxAngle: number, labelLength: number, isLineContinued: boolean, placeAtMiddle: boolean, tileExtent: number) { const halfLabelLength = labelLength / 2; const lineLength = getLineLength(line); diff --git a/src/symbol/mergelines.js b/src/symbol/mergelines.js index 852efb62d1f..f14ac4e23bd 100644 --- a/src/symbol/mergelines.js +++ b/src/symbol/mergelines.js @@ -1,5 +1,6 @@ // @flow +import type Point from '@mapbox/point-geometry'; import type {SymbolFeature} from '../data/bucket/symbol_bucket.js'; export default function (features: Array): Array { @@ -8,12 +9,12 @@ export default function (features: Array): Array { const mergedFeatures = []; let mergedIndex = 0; - function add(k) { + function add(k: number) { mergedFeatures.push(features[k]); mergedIndex++; } - function mergeFromRight(leftKey: string, rightKey: string, geom) { + function mergeFromRight(leftKey: string, rightKey: string, geom: Array>) { const i = rightIndex[leftKey]; delete rightIndex[leftKey]; rightIndex[rightKey] = i; @@ -23,7 +24,7 @@ export default function (features: Array): Array { return i; } - function mergeFromLeft(leftKey: string, rightKey: string, geom) { + function mergeFromLeft(leftKey: string, rightKey: string, geom: Array>) { const i = leftIndex[rightKey]; delete leftIndex[rightKey]; leftIndex[leftKey] = i; @@ -33,7 +34,7 @@ export default function (features: Array): Array { return i; } - function getKey(text, geom, onRight) { + function getKey(text: string, geom: Array>, onRight: ?boolean) { const point = onRight ? geom[0][geom[0].length - 1] : geom[0][0]; return `${text}:${point.x}:${point.y}`; } diff --git a/src/symbol/placement.js b/src/symbol/placement.js index 61a45c59142..12c5105cdc4 100644 --- a/src/symbol/placement.js +++ b/src/symbol/placement.js @@ -13,7 +13,7 @@ import Point from '@mapbox/point-geometry'; import type Transform from '../geo/transform.js'; import type StyleLayer from '../style/style_layer.js'; import type Tile from '../source/tile.js'; -import type SymbolBucket, {CollisionArrays, SingleCollisionBox} from '../data/bucket/symbol_bucket.js'; +import type SymbolBucket, {SymbolBuffers, CollisionArrays, SingleCollisionBox} from '../data/bucket/symbol_bucket.js'; import type {CollisionBoxArray, CollisionVertexArray, SymbolInstance} from '../data/array_types.js'; import type FeatureIndex from '../data/feature_index.js'; import {getSymbolPlacementTileProjectionMatrix} from '../geo/projection/projection_util.js'; @@ -518,7 +518,7 @@ export class Placement { const textBox = collisionArrays.textBox; if (textBox) { updateBoxData(textBox); - const updatePreviousOrientationIfNotPlaced = (isPlaced) => { + const updatePreviousOrientationIfNotPlaced = (isPlaced: boolean) => { let previousOrientation = WritingMode.horizontal; if (bucket.allowVerticalPlacement && !isPlaced && this.prevPlacement) { const prevPlacedOrientation = this.prevPlacement.placedOrientations[crossTileID]; @@ -548,7 +548,7 @@ export class Placement { }; if (!layout.get('text-variable-anchor')) { - const placeBox = (collisionTextBox, orientation) => { + const placeBox = (collisionTextBox: SingleCollisionBox, orientation: number) => { const textScale = bucket.getSymbolInstanceTextSize(partiallyEvaluatedTextSize, symbolInstance, this.transform.zoom, boxIndex); const placedFeature = this.collisionIndex.placeCollisionBox(bucket, textScale, collisionTextBox, new Point(0, 0), textAllowOverlap, textPixelRatio, posMatrix, collisionGroup.predicate); @@ -577,7 +577,8 @@ export class Placement { ((placeVertical: any): () => PartialPlacedCollisionBox), ); - updatePreviousOrientationIfNotPlaced(placed && placed.box && placed.box.length); + const isPlaced = placed && placed.box && placed.box.length; + updatePreviousOrientationIfNotPlaced(!!isPlaced); } else { let anchors = layout.get('text-variable-anchor'); @@ -593,7 +594,7 @@ export class Placement { } } - const placeBoxForVariableAnchors = (collisionTextBox, collisionIconBox, orientation) => { + const placeBoxForVariableAnchors = (collisionTextBox: SingleCollisionBox, collisionIconBox: ?SingleCollisionBox, orientation: number) => { const textScale = bucket.getSymbolInstanceTextSize(partiallyEvaluatedTextSize, symbolInstance, this.transform.zoom, boxIndex); const width = (collisionTextBox.x2 - collisionTextBox.x1) * textScale + 2.0 * collisionTextBox.padding; const height = (collisionTextBox.y2 - collisionTextBox.y1) * textScale + 2.0 * collisionTextBox.padding; @@ -647,7 +648,8 @@ export class Placement { textOccluded = placed.occluded; } - const prevOrientation = updatePreviousOrientationIfNotPlaced(placed && placed.box); + const isPlaced = placed && placed.box; + const prevOrientation = updatePreviousOrientationIfNotPlaced(!!isPlaced); // If we didn't get placed, we still need to copy our position from the last placement for // fade animations @@ -710,7 +712,7 @@ export class Placement { if (collisionArrays.iconBox) { - const placeIconFeature = iconBox => { + const placeIconFeature = (iconBox: SingleCollisionBox) => { updateBoxData(iconBox); const shiftPoint: Point = hasIconTextFit && shift ? offsetShift(shift.x, shift.y, rotateWithMap, pitchWithMap, this.transform.angle) : @@ -954,7 +956,7 @@ export class Placement { bucket.deserializeCollisionBoxes(collisionBoxArray); } - const addOpacities = (iconOrText, numVertices: number, opacity: number) => { + const addOpacities = (iconOrText: SymbolBuffers, numVertices: number, opacity: number) => { for (let i = 0; i < numVertices / 4; i++) { iconOrText.opacityVertexArray.emplaceBack(opacity); } diff --git a/src/symbol/projection.js b/src/symbol/projection.js index 72f9d3f7801..d585678a206 100644 --- a/src/symbol/projection.js +++ b/src/symbol/projection.js @@ -395,11 +395,11 @@ function placeFirstAndLastGlyph( // Check in the glCoordinate space, the rough estimation of angle between the text line and the Y axis. // If the angle if less or equal to 5 degree, then keep the text glyphs unflipped even if it is required. -function isInFlipRetainRange(dx, dy) { +function isInFlipRetainRange(dx: number, dy: number) { return dx === 0 || Math.abs(dy / dx) > maxTangent; } -function requiresOrientationChange(writingMode, flipState, dx, dy) { +function requiresOrientationChange(writingMode: number, flipState: number, dx: number, dy: number) { if (writingMode === WritingMode.horizontal && Math.abs(dy) > Math.abs(dx)) { // On top of choosing whether to flip, choose whether to render this version of the glyphs or the alternate // vertical glyphs. We can't just filter out vertical glyphs in the horizontal range because the horizontal @@ -422,7 +422,7 @@ function requiresOrientationChange(writingMode, flipState, dx, dy) { return dx < 0 ? {needsFlipping: true} : null; } -function placeGlyphsAlongLine(symbol, fontSize, flip, keepUpright, posMatrix, labelPlaneMatrix, glCoordMatrix, glyphOffsetArray, lineVertexArray, dynamicLayoutVertexArray, globeExtVertexArray, anchorPoint, tileAnchorPoint, projectionCache, aspectRatio, getElevation, projection, tileID, pitchWithMap): PlacementStatus { +function placeGlyphsAlongLine(symbol: PlacedSymbol, fontSize: number, flip: boolean, keepUpright: boolean, posMatrix: Float32Array, labelPlaneMatrix: Float32Array, glCoordMatrix: Float32Array, glyphOffsetArray: GlyphOffsetArray, lineVertexArray: SymbolLineVertexArray, dynamicLayoutVertexArray: SymbolDynamicLayoutArray, globeExtVertexArray: ?SymbolGlobeExtArray, anchorPoint: VecType, tileAnchorPoint: Point, projectionCache: ProjectionCache, aspectRatio: number, getElevation: ?((p: Point) => Array), projection: Projection, tileID: OverscaledTileID, pitchWithMap: boolean): PlacementStatus { const fontScale = fontSize / 24; const lineOffsetX = symbol.lineOffsetX * fontScale; const lineOffsetY = symbol.lineOffsetY * fontScale; diff --git a/src/symbol/quads.js b/src/symbol/quads.js index 8a36f522d24..5752af9079e 100644 --- a/src/symbol/quads.js +++ b/src/symbol/quads.js @@ -15,6 +15,8 @@ import {isVerticalClosePunctuation, isVerticalOpenPunctuation} from '../util/ver import ONE_EM from './one_em.js'; import {warnOnce} from '../util/util.js'; +type Size = {| fixed: number, stretch: number |}; + /** * A textured quad for rendering a single icon or glyph. * @@ -76,7 +78,7 @@ export function getIconQuads( const stretchX = image.stretchX || [[0, imageWidth]]; const stretchY = image.stretchY || [[0, imageHeight]]; - const reduceRanges = (sum, range) => sum + range[1] - range[0]; + const reduceRanges = (sum: number, range: [number, number]) => sum + range[1] - range[0]; const stretchWidth = stretchX.reduce(reduceRanges, 0); const stretchHeight = stretchY.reduce(reduceRanges, 0); const fixedWidth = imageWidth - stretchWidth; @@ -103,7 +105,7 @@ export function getIconQuads( fixedContentHeight = content[3] - content[1] - stretchContentHeight; } - const makeBox = (left, top, right, bottom) => { + const makeBox = (left: Size, top: Size, right: Size, bottom: Size) => { const leftEm = getEmOffset(left.stretch - stretchOffsetX, stretchContentWidth, iconWidth, shapedIcon.left); const leftPx = getPxOffset(left.fixed - fixedOffsetX, fixedContentWidth, left.stretch, stretchWidth); @@ -180,7 +182,7 @@ export function getIconQuads( return quads; } -function sumWithinRange(ranges, min, max) { +function sumWithinRange(ranges: Array<[number, number]>, min: number, max: number) { let sum = 0; for (const range of ranges) { sum += Math.max(min, Math.min(max, range[1])) - Math.max(min, Math.min(max, range[0])); @@ -188,7 +190,7 @@ function sumWithinRange(ranges, min, max) { return sum; } -function stretchZonesToCuts(stretchZones, fixedSize, stretchSize) { +function stretchZonesToCuts(stretchZones: Array<[number, number]>, fixedSize: number, stretchSize: number) { const cuts = [{fixed: -border, stretch: 0}]; for (const [c1, c2] of stretchZones) { @@ -209,11 +211,11 @@ function stretchZonesToCuts(stretchZones, fixedSize, stretchSize) { return cuts; } -function getEmOffset(stretchOffset, stretchSize, iconSize, iconOffset) { +function getEmOffset(stretchOffset: number, stretchSize: number, iconSize: number, iconOffset: number) { return stretchOffset / stretchSize * iconSize + iconOffset; } -function getPxOffset(fixedOffset, fixedSize, stretchOffset, stretchSize) { +function getPxOffset(fixedOffset: number, fixedSize: number, stretchOffset: number, stretchSize: number) { return fixedOffset - fixedSize * stretchOffset / stretchSize; } @@ -231,7 +233,7 @@ function getRotateOffset(textOffset: [number, number]) { } } -function getMidlineOffset(shaping, lineHeight, previousOffset, lineIndex) { +function getMidlineOffset(shaping: Shaping, lineHeight: number, previousOffset: number, lineIndex: number) { const currentLineHeight = (lineHeight + shaping.positionedLines[lineIndex].lineOffset); if (lineIndex === 0) { return previousOffset + currentLineHeight / 2.0; diff --git a/src/symbol/shaping.js b/src/symbol/shaping.js index ae473198ad8..2ca5b793f87 100644 --- a/src/symbol/shaping.js +++ b/src/symbol/shaping.js @@ -96,14 +96,14 @@ class SectionOptions { this.imageName = null; } - static forText(scale: number | null, fontStack: string) { + static forText(scale: ?number, fontStack: string): SectionOptions { const textOptions = new SectionOptions(); textOptions.scale = scale || 1; textOptions.fontStack = fontStack; return textOptions; } - static forImage(imageName: string) { + static forImage(imageName: string): SectionOptions { const imageOptions = new SectionOptions(); imageOptions.imageName = imageName; return imageOptions; @@ -124,7 +124,7 @@ class TaggedString { this.imageSectionID = null; } - static fromFeature(text: Formatted, defaultFontStack: string) { + static fromFeature(text: Formatted, defaultFontStack: string): TaggedString { const result = new TaggedString(); for (let i = 0; i < text.sections.length; i++) { const section = text.sections[i]; @@ -190,7 +190,7 @@ class TaggedString { return this.text; } - getMaxScale() { + getMaxScale(): number { return this.sectionIndex.reduce((max, index) => Math.max(max, this.sections[index].scale), 0); } diff --git a/src/symbol/symbol_layout.js b/src/symbol/symbol_layout.js index e2ce64de989..c6d3cffbe9f 100644 --- a/src/symbol/symbol_layout.js +++ b/src/symbol/symbol_layout.js @@ -231,7 +231,7 @@ export function performSymbolLayout(bucket: SymbolBucket, layout.get('text-max-width').evaluate(feature, {}, canonical) * ONE_EM : Infinity; - const addVerticalShapingIfNeeded = (textJustify) => { + const addVerticalShapingIfNeeded = (textJustify: TextJustify) => { if (bucket.allowVerticalPlacement && allowsVerticalWritingMode(unformattedText)) { // Vertical POI label placement is meant to be used for scripts that support vertical // writing mode, thus, default left justification is used. If Latin @@ -342,7 +342,7 @@ export function getAnchorJustification(anchor: TextAnchor): TextJustify { * in order to thin out labels density and save memory and CPU . * @private */ -function tilePixelRatioForSymbolSpacing(overscaleFactor, overscaledZ) { +function tilePixelRatioForSymbolSpacing(overscaleFactor: number, overscaledZ: number) { if (overscaledZ > 18 && overscaleFactor > 2) { overscaleFactor >>= 1; } @@ -411,7 +411,7 @@ function addFeature(bucket: SymbolBucket, } } - const addSymbolAtAnchor = (line, anchor, canonicalId) => { + const addSymbolAtAnchor = (line: Array, anchor: Anchor, canonicalId: CanonicalTileID) => { if (anchor.x < 0 || anchor.x >= EXTENT || anchor.y < 0 || anchor.y >= EXTENT) { // Symbol layers are drawn across tile boundaries, We filter out symbols // outside our tile boundaries (which may be included in vector tile buffers) diff --git a/src/terrain/draw_terrain_raster.js b/src/terrain/draw_terrain_raster.js index a783476d5be..882aa725480 100644 --- a/src/terrain/draw_terrain_raster.js +++ b/src/terrain/draw_terrain_raster.js @@ -28,6 +28,8 @@ import { getLatitudinalLod } from '../geo/projection/globe_util.js'; import extend from '../style-spec/util/extend.js'; +import type Program from '../render/program.js'; +import type VertexBuffer from "../gl/vertex_buffer.js"; export { drawTerrainRaster, @@ -148,7 +150,7 @@ function drawTerrainForGlobe(painter: Painter, terrain: Terrain, sourceCache: So const tr = painter.transform; const useCustomAntialiasing = globeUseCustomAntiAliasing(painter, context, tr); - const setShaderMode = (mode, isWireframe) => { + const setShaderMode = (mode: number, isWireframe: boolean) => { if (programMode === mode) return; const defines = [shaderDefines[mode], 'PROJECTION_GLOBE_VIEW']; @@ -253,7 +255,7 @@ function drawTerrainForGlobe(painter: Painter, terrain: Terrain, sourceCache: So let poleMatrix = globePoleMatrixForTile(z, x, tr); const normalizeMatrix = globeNormalizeECEF(globeTileBounds(coord.canonical)); - const drawPole = (program, vertexBuffer) => program.draw( + const drawPole = (program: Program, vertexBuffer: VertexBuffer) => program.draw( context, gl.TRIANGLES, depthMode, StencilMode.disabled, colorMode, CullFaceMode.disabled, globeRasterUniformValues(tr.projMatrix, poleMatrix, poleMatrix, normalizeMatrix, 0.0, mercatorCenter, tr.frustumCorners.TL, tr.frustumCorners.TR, tr.frustumCorners.BR, tr.frustumCorners.BL, @@ -286,7 +288,7 @@ function drawTerrainRaster(painter: Painter, terrain: Terrain, sourceCache: Sour let program, programMode; const showWireframe = painter.options.showTerrainWireframe ? SHADER_TERRAIN_WIREFRAME : SHADER_DEFAULT; - const setShaderMode = (mode, isWireframe) => { + const setShaderMode = (mode: number, isWireframe: boolean) => { if (programMode === mode) return; const modes = [shaderDefines[mode]]; @@ -373,7 +375,7 @@ function drawTerrainDepth(painter: Painter, terrain: Terrain, sourceCache: Sourc } } -function skirtHeight(zoom) { +function skirtHeight(zoom: number) { // Skirt height calculation is heuristic: provided value hides // seams between tiles and it is not too large: 9 at zoom 22, ~20000m at zoom 0. return 6 * Math.pow(1.5, 22 - zoom); diff --git a/src/terrain/terrain.js b/src/terrain/terrain.js index 4fcac4753bd..9781cc75f80 100644 --- a/src/terrain/terrain.js +++ b/src/terrain/terrain.js @@ -540,7 +540,9 @@ export class Terrain extends Elevation { const demId = demTile.tileID.canonical; const demScaleBy = Math.pow(2, demId.z - proxyId.z); const suffix = uniformSuffix || ""; + // $FlowFixMe[prop-missing] uniforms[`u_dem_tl${suffix}`] = [proxyId.x * demScaleBy % 1, proxyId.y * demScaleBy % 1]; + // $FlowFixMe[prop-missing] uniforms[`u_dem_scale${suffix}`] = demScaleBy; return true; } @@ -939,7 +941,7 @@ export class Terrain extends Elevation { } } - const isTransitioning = id => { + const isTransitioning = (id: string) => { const layer = this._style._layers[id]; const isHidden = layer.isHidden(this.painter.transform.zoom); if (layer.type === 'custom') { @@ -1353,7 +1355,7 @@ export class Terrain extends Elevation { }, {min: new Point(Number.MAX_VALUE, Number.MAX_VALUE), max: new Point(-Number.MAX_VALUE, -Number.MAX_VALUE)}); // Fast conservative check using aabb: content outside proxy tile gets clipped out by on render, anyway. - const tileOutsideImage = (tileID, imageTileID) => { + const tileOutsideImage = (tileID: OverscaledTileID, imageTileID: OverscaledTileID) => { const x = tileID.wrap + tileID.canonical.x / (1 << tileID.canonical.z); const y = tileID.canonical.y / (1 << tileID.canonical.z); const d = EXTENT / (1 << tileID.canonical.z); @@ -1451,7 +1453,7 @@ export class Terrain extends Elevation { } } - const pathToLookup = (key) => { + const pathToLookup = (key: ?number) => { path.forEach(id => { lookup[id] = key; }); path.length = 0; }; @@ -1510,7 +1512,7 @@ export class Terrain extends Elevation { } -function sortByDistanceToCamera(tileIDs, painter) { +function sortByDistanceToCamera(tileIDs: Array, painter: Painter) { const cameraCoordinate = painter.transform.pointCoordinate(painter.transform.getCameraPoint()); const cameraPoint = new Point(cameraCoordinate.x, cameraCoordinate.y); tileIDs.sort((a, b) => { @@ -1567,7 +1569,7 @@ function createGrid(count: number): [PosArray, TriangleIndexArray, number] { // For cases when there's no need to render "skirt", the "inner" grid indices // are followed by skirt indices. const skirtIndicesOffset = (size - 3) * (size - 3) * 2; - const quad = (i, j) => { + const quad = (i: number, j: number) => { const index = j * size + i; indexArray.emplaceBack(index + 1, index, index + size); indexArray.emplaceBack(index + size, index + size + 1, index + 1); diff --git a/src/ui/camera.js b/src/ui/camera.js index 2f403a1674a..a244c0aa900 100644 --- a/src/ui/camera.js +++ b/src/ui/camera.js @@ -1313,7 +1313,7 @@ class Camera extends Evented { const pitchChanged = this._pitching || (pitch !== startPitch); const paddingChanged = !tr.isPaddingEqual(padding); - const frame = (tr) => (k) => { + const frame = (tr: Transform) => (k: number) => { if (zoomChanged) { tr.zoom = interpolate(startZoom, zoom, k); } @@ -1570,14 +1570,14 @@ class Camera extends Evented { * @param i 0 for the ascent or 1 for the descent. * @private */ - function r(i) { + function r(i: number) { const b = (w1 * w1 - w0 * w0 + (i ? -1 : 1) * rho2 * rho2 * u1 * u1) / (2 * (i ? w1 : w0) * rho2 * u1); return Math.log(Math.sqrt(b * b + 1) - b); } - function sinh(n) { return (Math.exp(n) - Math.exp(-n)) / 2; } - function cosh(n) { return (Math.exp(n) + Math.exp(-n)) / 2; } - function tanh(n) { return sinh(n) / cosh(n); } + function sinh(n: number) { return (Math.exp(n) - Math.exp(-n)) / 2; } + function cosh(n: number) { return (Math.exp(n) + Math.exp(-n)) / 2; } + function tanh(n: number) { return sinh(n) / cosh(n); } // r₀: Zoom-out factor during ascent. const r0 = r(0); @@ -1625,7 +1625,7 @@ class Camera extends Evented { const pitchChanged = (pitch !== startPitch); const paddingChanged = !tr.isPaddingEqual(padding); - const frame = (tr) => (k) => { + const frame = (tr: Transform) => (k: number) => { // s: The distance traveled along the flight path, measured in ρ-screenfuls. const s = k * S; const scale = 1 / w(s); diff --git a/src/ui/control/geolocate_control.js b/src/ui/control/geolocate_control.js index 623f6c72c27..a409ff5b5b5 100644 --- a/src/ui/control/geolocate_control.js +++ b/src/ui/control/geolocate_control.js @@ -163,7 +163,7 @@ class GeolocateControl extends Evented { } _checkGeolocationSupport(callback: boolean => void) { - const updateSupport = (supported = !!this.options.geolocation) => { + const updateSupport = (supported: boolean = !!this.options.geolocation) => { this._supportsGeolocation = supported; callback(supported); }; diff --git a/src/ui/control/scale_control.js b/src/ui/control/scale_control.js index 58a6c4c9ee2..6b6d71ed6af 100644 --- a/src/ui/control/scale_control.js +++ b/src/ui/control/scale_control.js @@ -17,6 +17,14 @@ const defaultOptions: Options = { unit: 'metric' }; +const unitAbbr = { + kilometer: 'km', + meter: 'm', + mile: 'mi', + foot: 'ft', + 'nautical-mile': 'nm', +}; + /** * A `ScaleControl` control displays the ratio of a distance on the map to the corresponding distance on the ground. * Add this control to a map using {@link Map#addControl}. @@ -38,17 +46,15 @@ class ScaleControl { _map: Map; _container: HTMLElement; _language: ?string | ?string[]; + _isNumberFormatSupported: boolean; options: Options; constructor(options: Options) { this.options = extend({}, defaultOptions, options); - // Some old browsers (e.g., Safari < 14.1) don't support the "unit" style. + // Some old browsers (e.g., Safari < 14.1) don't support the "unit" style in NumberFormat. // This is a workaround to display the scale without proper internationalization support. - if (!isNumberFormatSupported()) { - // $FlowIgnore[cannot-write] - this._setScale = legacySetScale.bind(this); - } + this._isNumberFormatSupported = isNumberFormatSupported(); bindAll([ '_update', @@ -96,21 +102,18 @@ class ScaleControl { } _setScale(maxWidth: number, maxDistance: number, unit: string) { - const distance = getRoundNum(maxDistance); - const ratio = distance / maxDistance; - this._map._requestDomTask(() => { - this._container.style.width = `${maxWidth * ratio}px`; + const distance = getRoundNum(maxDistance); + const ratio = distance / maxDistance; - // Intl.NumberFormat doesn't support nautical-mile as a unit, - // so we are hardcoding `nm` as a unit symbol for all locales - if (unit === 'nautical-mile') { - this._container.innerHTML = `${distance} nm`; - return; + if (this._isNumberFormatSupported && unit !== 'nautical-mile') { + // $FlowFixMe[incompatible-call] — flow v0.190.1 doesn't support optional `locales` argument and `unit` style option + this._container.innerHTML = new Intl.NumberFormat(this._language, {style: 'unit', unitDisplay: 'short', unit}).format(distance); + } else { + this._container.innerHTML = `${distance} ${unitAbbr[unit]}`; } - // $FlowFixMe — flow v0.142.0 doesn't support optional `locales` argument and `unit` style option - this._container.innerHTML = new Intl.NumberFormat(this._language, {style: 'unit', unitDisplay: 'short', unit}).format(distance); + this._container.style.width = `${maxWidth * ratio}px`; }); } @@ -155,37 +158,19 @@ export default ScaleControl; function isNumberFormatSupported() { try { // $FlowIgnore - new Intl.NumberFormat('en', {style: 'unit', unitDisplay: 'narrow', unit: 'meter'}); + new Intl.NumberFormat('en', {style: 'unit', unitDisplay: 'short', unit: 'meter'}); return true; } catch (_) { return false; } } -function legacySetScale(maxWidth: number, maxDistance: number, unit: string) { - const distance = getRoundNum(maxDistance); - const ratio = distance / maxDistance; - - const unitAbbr = { - kilometer: 'km', - meter: 'm', - mile: 'mi', - foot: 'ft', - 'nautical-mile': 'nm', - }[unit]; - - this._map._requestDomTask(() => { - this._container.style.width = `${maxWidth * ratio}px`; - this._container.innerHTML = `${distance} ${unitAbbr}`; - }); -} - -function getDecimalRoundNum(d) { +function getDecimalRoundNum(d: number) { const multiplier = Math.pow(10, Math.ceil(-Math.log(d) / Math.LN10)); return Math.round(d * multiplier) / multiplier; } -function getRoundNum(num) { +function getRoundNum(num: number) { const pow10 = Math.pow(10, (`${Math.floor(num)}`).length - 1); let d = num / pow10; diff --git a/src/ui/handler/touch_zoom_rotate.js b/src/ui/handler/touch_zoom_rotate.js index d59cf6411c8..224c5383d37 100644 --- a/src/ui/handler/touch_zoom_rotate.js +++ b/src/ui/handler/touch_zoom_rotate.js @@ -104,7 +104,7 @@ function getTouchById(mapTouches: Array, points: Array, identifier const ZOOM_THRESHOLD = 0.1; -function getZoomDelta(distance, lastDistance) { +function getZoomDelta(distance: number, lastDistance: number) { return Math.log(distance / lastDistance) / Math.LN2; } @@ -197,7 +197,7 @@ export class TouchRotateHandler extends TwoTouchHandler { /* PITCH */ -function isVertical(vector) { +function isVertical(vector: Point) { return Math.abs(vector.y) > Math.abs(vector.x); } diff --git a/src/ui/handler_inertia.js b/src/ui/handler_inertia.js index 3881ada6d52..0369562a022 100644 --- a/src/ui/handler_inertia.js +++ b/src/ui/handler_inertia.js @@ -140,14 +140,14 @@ export default class HandlerInertia { // Unfortunately zoom, bearing, etc can't have different durations and easings so // we need to choose one. We use the longest duration and it's corresponding easing. -function extendDuration(easeOptions, result) { +function extendDuration(easeOptions: EasingOptions, result: {| amount: number, duration: number, easing: (t: number) => number |}) { if (!easeOptions.duration || easeOptions.duration < result.duration) { easeOptions.duration = result.duration; easeOptions.easing = result.easing; } } -function calculateEasing(amount, inertiaDuration: number, inertiaOptions) { +function calculateEasing(amount: number, inertiaDuration: number, inertiaOptions: InertiaOptions) { const {maxSpeed, linearity, deceleration} = inertiaOptions; const speed = clamp( amount * linearity / (inertiaDuration / 1000), diff --git a/src/ui/handler_manager.js b/src/ui/handler_manager.js index c9a1f1a83a9..1b09ae61223 100644 --- a/src/ui/handler_manager.js +++ b/src/ui/handler_manager.js @@ -29,7 +29,7 @@ import type {Vec3} from 'gl-matrix'; export type InputEvent = MouseEvent | TouchEvent | KeyboardEvent | WheelEvent; -const isMoving = p => p.zoom || p.drag || p.pitch || p.rotate; +const isMoving = (p: { [string]: any }) => p.zoom || p.drag || p.pitch || p.rotate; class RenderFrameEvent extends Event { type: 'renderFrame'; @@ -491,12 +491,12 @@ class HandlerManager { const map = this._map; const tr = map.transform; - const eventStarted = (type) => { + const eventStarted = (type: string) => { const newEvent = combinedEventsInProgress[type]; return newEvent && !this._eventsInProgress[type]; }; - const eventEnded = (type) => { + const eventEnded = (type: string) => { const event = this._eventsInProgress[type]; return event && !this._handlersById[event.handlerName].isActive(); }; @@ -669,7 +669,7 @@ class HandlerManager { this._updatingCamera = true; const inertialEase = this._inertia._onMoveEnd(this._map.dragPan._inertiaOptions); - const shouldSnapToNorth = bearing => bearing !== 0 && -this._bearingSnap < bearing && bearing < this._bearingSnap; + const shouldSnapToNorth = (bearing: number) => bearing !== 0 && -this._bearingSnap < bearing && bearing < this._bearingSnap; if (inertialEase) { if (shouldSnapToNorth(inertialEase.bearing || this._map.getBearing())) { diff --git a/src/ui/map.js b/src/ui/map.js index 9e10e5706ea..339de38e2a5 100755 --- a/src/ui/map.js +++ b/src/ui/map.js @@ -1368,7 +1368,7 @@ class Map extends Camera { _createDelegatedListener(type: MapEvent, layers: Array, listener: any): any { if (type === 'mouseenter' || type === 'mouseover') { let mousein = false; - const mousemove = (e) => { + const mousemove = (e: MapMouseEvent) => { const filteredLayers = layers.filter(layerId => this.getLayer(layerId)); const features = filteredLayers.length ? this.queryRenderedFeatures(e.point, {layers: filteredLayers}) : []; if (!features.length) { @@ -1385,7 +1385,7 @@ class Map extends Camera { return {layers: new Set(layers), listener, delegates: {mousemove, mouseout}}; } else if (type === 'mouseleave' || type === 'mouseout') { let mousein = false; - const mousemove = (e) => { + const mousemove = (e: MapMouseEvent) => { const filteredLayers = layers.filter(layerId => this.getLayer(layerId)); const features = filteredLayers.length ? this.queryRenderedFeatures(e.point, {layers: filteredLayers}) : []; if (features.length) { @@ -1395,7 +1395,7 @@ class Map extends Camera { listener.call(this, new MapMouseEvent(type, this, e.originalEvent)); } }; - const mouseout = (e) => { + const mouseout = (e: MapMouseEvent) => { if (mousein) { mousein = false; listener.call(this, new MapMouseEvent(type, this, e.originalEvent)); @@ -1404,7 +1404,7 @@ class Map extends Camera { return {layers: new Set(layers), listener, delegates: {mousemove, mouseout}}; } else { - const delegate = (e) => { + const delegate = (e: MapMouseEvent) => { const filteredLayers = layers.filter(layerId => this.getLayer(layerId)); const features = filteredLayers.length ? this.queryRenderedFeatures(e.point, {layers: filteredLayers}) : []; if (features.length) { @@ -1643,7 +1643,7 @@ class Map extends Camera { } layerIds = new Set(Array.isArray(layerIds) ? layerIds : [layerIds]); - const areLayerArraysEqual = (hash1, hash2) => { + const areLayerArraysEqual = (hash1: Set, hash2: Set) => { if (hash1.size !== hash2.size) { return false; // at-least 1 arr has duplicate value(s) } @@ -3363,7 +3363,7 @@ class Map extends Camera { * @private */ _updateAverageElevation(timeStamp: number, ignoreTimeout: boolean = false): boolean { - const applyUpdate = value => { + const applyUpdate = (value: number) => { this.transform.averageElevation = value; this._update(false); return true; @@ -3468,7 +3468,7 @@ class Map extends Camera { const framebuffer = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); - function read(texture) { + function read(texture: ?WebGLTexture) { gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); const pixels = new Uint8Array(gl.drawingBufferWidth * gl.drawingBufferHeight * 4); gl.readPixels(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight, gl.RGBA, gl.UNSIGNED_BYTE, pixels); diff --git a/src/util/actor.js b/src/util/actor.js index 7c709c06959..59db67bcc1c 100644 --- a/src/util/actor.js +++ b/src/util/actor.js @@ -141,7 +141,7 @@ class Actor { } } else { const buffers: ?Array = isSafari(this.globalScope) ? undefined : []; - const done = task.hasCallback ? (err, data) => { + const done = task.hasCallback ? (err: ?Error, data: mixed) => { delete this.cancelCallbacks[id]; this.target.postMessage({ id, diff --git a/src/util/ajax.js b/src/util/ajax.js index 8824c78c33b..6685790b0ca 100644 --- a/src/util/ajax.js +++ b/src/util/ajax.js @@ -103,7 +103,7 @@ export const getReferrer: (() => string) = isWorker() ? // Determines whether a URL is a file:// URL. This is obviously the case if it begins // with file://. Relative URLs are also file:// URLs iff the original document was loaded // via a file:// URL. -const isFileURL = url => /^file:/.test(url) || (/^file:/.test(getReferrer()) && !/^\w+:/.test(url)); +const isFileURL = (url: string) => /^file:/.test(url) || (/^file:/.test(getReferrer()) && !/^\w+:/.test(url)); function makeFetchRequest(requestParameters: RequestParameters, callback: ResponseCallback): Cancelable { const controller = new window.AbortController(); @@ -125,14 +125,14 @@ function makeFetchRequest(requestParameters: RequestParameters, callback: Respon request.headers.set('Accept', 'application/json'); } - const validateOrFetch = (err, cachedResponse, responseIsFresh) => { + const validateOrFetch = (err: ?Error, cachedResponse: ?Response, responseIsFresh: ?boolean) => { if (aborted) return; if (err) { // Do fetch in case of cache error. // HTTP pages in Edge trigger a security error that can be ignored. if (err.message !== 'SecurityError') { - warnOnce(err); + warnOnce(err.toString()); } } @@ -163,7 +163,7 @@ function makeFetchRequest(requestParameters: RequestParameters, callback: Respon }); }; - const finishRequest = (response, cacheableResponse, requestTime) => { + const finishRequest = (response: Response, cacheableResponse: ?Response, requestTime: ?number) => { ( requestParameters.type === 'arrayBuffer' ? response.arrayBuffer() : requestParameters.type === 'json' ? response.json() : @@ -270,7 +270,7 @@ export const getData = function(requestParameters: RequestParameters, callback: return makeRequest(extend(requestParameters, {method: 'GET'}), callback); }; -function sameOrigin(url) { +function sameOrigin(url: string) { const a: HTMLAnchorElement = window.document.createElement('a'); a.href = url; return a.protocol === window.document.location.protocol && a.host === window.document.location.host; diff --git a/src/util/classify_rings.js b/src/util/classify_rings.js index 396e6401233..a2f93ef6215 100644 --- a/src/util/classify_rings.js +++ b/src/util/classify_rings.js @@ -47,6 +47,6 @@ export default function classifyRings(rings: Array>, maxRings: numb return polygons; } -function compareAreas(a, b) { +function compareAreas(a: {area: number}, b: {area: number}) { return b.area - a.area; } diff --git a/src/util/color_ramp.js b/src/util/color_ramp.js index 3456773f721..ecbfad22826 100644 --- a/src/util/color_ramp.js +++ b/src/util/color_ramp.js @@ -28,7 +28,7 @@ export function renderColorRamp(params: ColorRampParams): RGBAImage { assert(isPowerOfTwo(width)); - const renderPixel = (stride, index, progress) => { + const renderPixel = (stride: number, index: number, progress: number) => { evaluationGlobals[params.evaluationKey] = progress; const pxColor = params.expression.evaluate((evaluationGlobals: any)); // the colors are being unpremultiplied because Color uses diff --git a/src/util/dom.js b/src/util/dom.js index 24ac033e269..ac5086413bf 100644 --- a/src/util/dom.js +++ b/src/util/dom.js @@ -41,7 +41,7 @@ export function enableDrag() { } // Suppress the next click, but only if it's immediate. -function suppressClickListener(e) { +function suppressClickListener(e: Event) { e.preventDefault(); e.stopPropagation(); window.removeEventListener('click', suppressClickListener, true); diff --git a/src/util/find_pole_of_inaccessibility.js b/src/util/find_pole_of_inaccessibility.js index 4587dfe0028..04e418172c5 100644 --- a/src/util/find_pole_of_inaccessibility.js +++ b/src/util/find_pole_of_inaccessibility.js @@ -78,7 +78,7 @@ export default function (polygonRings: Array>, precision?: number = return bestCell.p; } -function compareMax(a, b) { +function compareMax(a: Cell, b: Cell) { return b.max - a.max; } @@ -88,7 +88,7 @@ class Cell { d: number; max: number; - constructor(x, y, h, polygon) { + constructor(x: number, y: number, h: number, polygon: Array>) { this.p = new Point(x, y); this.h = h; // half the cell size this.d = pointToPolygonDist(this.p, polygon); // distance from cell center to polygon @@ -97,7 +97,7 @@ class Cell { } // signed distance from point to polygon outline (negative if point is outside) -function pointToPolygonDist(p, polygon) { +function pointToPolygonDist(p: Point, polygon: Array>) { let inside = false; let minDistSq = Infinity; @@ -119,7 +119,7 @@ function pointToPolygonDist(p, polygon) { } // get polygon centroid -function getCentroidCell(polygon) { +function getCentroidCell(polygon: Array>) { let area = 0; let x = 0; let y = 0; diff --git a/src/util/live_performance.js b/src/util/live_performance.js index d0a0d849f86..bd958e78356 100644 --- a/src/util/live_performance.js +++ b/src/util/live_performance.js @@ -44,7 +44,7 @@ export const LivePerformanceUtils = { } }; -function categorize(arr, fn) { +function categorize(arr: Array, fn: (entry: PerformanceResourceTiming) => string): {[string]: Array} { const obj = {}; if (arr) { for (const item of arr) { @@ -58,7 +58,7 @@ function categorize(arr, fn) { return obj; } -function getCountersPerResourceType(resourceTimers) { +function getCountersPerResourceType(resourceTimers: { [string]: Array }) { const obj = {}; if (resourceTimers) { for (const category in resourceTimers) { @@ -74,7 +74,7 @@ function getCountersPerResourceType(resourceTimers) { obj[min] = Math.min(obj[min] || +Infinity, timer.startTime); obj[max] = Math.max(obj[max] || -Infinity, timer.responseEnd); - const increment = (key) => { + const increment = (key: string) => { if (obj[key] === undefined) { obj[key] = 0; } @@ -134,7 +134,7 @@ export function getLivePerformanceMetrics(data: LivePerformanceData): LivePerfor // Please read carefully before adding or modifying the following metrics: // https://github.com/mapbox/gl-js-team/blob/main/docs/live_performance_metrics.md - const addMetric = (arr, name, value) => { + const addMetric = (arr: Array<{| name: string, value: string |}>, name: string, value: ?(number | string)) => { if (value !== undefined && value !== null) { arr.push({name, value: value.toString()}); } diff --git a/src/util/polygon_clipping.js b/src/util/polygon_clipping.js index 9d8700d292b..bfb72d25e00 100644 --- a/src/util/polygon_clipping.js +++ b/src/util/polygon_clipping.js @@ -11,10 +11,10 @@ export type ClippedPolygon = { type PolygonArray = Array>>; function clipPolygon(polygons: PolygonArray, clipAxis1: number, clipAxis2: number, axis: number): PolygonArray { - const intersectX = (ring, ax, ay, bx, by, x) => { + const intersectX = (ring: Array, ax: number, ay: number, bx: number, by: number, x: number) => { ring.push(new Point(x, ay + (by - ay) * ((x - ax) / (bx - ax)))); }; - const intersectY = (ring, ax, ay, bx, by, y) => { + const intersectY = (ring: Array, ax: number, ay: number, bx: number, by: number, y: number) => { ring.push(new Point(ax + (bx - ax) * ((y - ay) / (by - ay)), y)); }; @@ -82,7 +82,7 @@ export function subdividePolygons(polygons: PolygonArray, bounds: [Point, Point] return outPolygons; } - const addResult = (clipped, bounds) => { + const addResult = (clipped: PolygonArray, bounds: [Point, Point]) => { for (const polygon of clipped) { outPolygons.push({polygon, bounds}); } diff --git a/src/util/struct_array.js b/src/util/struct_array.js index ccdd0b70f17..75f81e68c28 100644 --- a/src/util/struct_array.js +++ b/src/util/struct_array.js @@ -192,7 +192,7 @@ class StructArray { /** * Create TypedArray views for the current ArrayBuffer. */ - _refreshViews() { + _refreshViews(): void { throw new Error('_refreshViews() must be implemented by each concrete StructArray layout'); } diff --git a/src/util/tile_request_cache.js b/src/util/tile_request_cache.js index 7bcaed87180..20e0865bed8 100644 --- a/src/util/tile_request_cache.js +++ b/src/util/tile_request_cache.js @@ -46,7 +46,7 @@ export function cacheClose() { } let responseConstructorSupportsReadableStream; -function prepareBody(response: Response, callback) { +function prepareBody(response: Response, callback: ((body: ?(Blob | ReadableStream)) => void)) { if (responseConstructorSupportsReadableStream === undefined) { try { new Response(new ReadableStream()); // eslint-disable-line no-undef @@ -151,7 +151,7 @@ export function cacheGet(request: Request, callback: (error: ?any, response: ?Re } -function isFresh(response) { +function isFresh(response: Response) { if (!response) return false; const expires = new Date(response.headers.get('Expires') || 0); const cacheControl = parseCacheControl(response.headers.get('Cache-Control') || ''); diff --git a/src/util/util.js b/src/util/util.js index c0a210aab5e..4be7529dad1 100644 --- a/src/util/util.js +++ b/src/util/util.js @@ -375,7 +375,7 @@ export function uniqueId(): number { * @private */ export function uuid(): string { - function b(a) { + function b(a: void) { return a ? (a ^ Math.random() * (16 >> a / 4)).toString(16) : //$FlowFixMe: Flow doesn't like the implied array literal conversion here ([1e7] + -[1e3] + -4e3 + -8e3 + -1e11).replace(/[018]/g, b); @@ -462,6 +462,7 @@ export function endsWith(string: string, suffix: string): boolean { * * @private */ +// $FlowFixMe[missing-this-annot] export function mapObject(input: Object, iterator: Function, context?: Object): Object { const output = {}; for (const key in input) { @@ -475,6 +476,7 @@ export function mapObject(input: Object, iterator: Function, context?: Object): * * @private */ +// $FlowFixMe[missing-this-annot] export function filterObject(input: Object, iterator: Function, context?: Object): Object { const output = {}; for (const key in input) { diff --git a/src/util/window.js b/src/util/window.js index 006e445f945..10fedf3523c 100644 --- a/src/util/window.js +++ b/src/util/window.js @@ -55,6 +55,7 @@ function restore(): Window { // Add webgl context with the supplied GL const originalGetContext = window.HTMLCanvasElement.prototype.getContext; + // $FlowFixMe[missing-this-annot] window.HTMLCanvasElement.prototype.getContext = function (type, attributes) { if (type === 'webgl') { if (!this._webGLContext) { @@ -66,10 +67,12 @@ function restore(): Window { return originalGetContext.call(this, type, attributes); }; + // $FlowFixMe[missing-this-annot] window.useFakeHTMLCanvasGetContext = function() { this.HTMLCanvasElement.prototype.getContext = function() { return '2d'; }; }; + // $FlowFixMe[missing-this-annot] window.useFakeXMLHttpRequest = function() { sinon.xhr.supportsCORS = true; this.server = sinon.fakeServer.create(); diff --git a/test/unit/util/util.test.js b/test/unit/util/util.test.js index a790c2f0377..c99578c43f3 100644 --- a/test/unit/util/util.test.js +++ b/test/unit/util/util.test.js @@ -8,7 +8,7 @@ import Point from '@mapbox/point-geometry'; const EPSILON = 1e-8; -function pointsetEqual(t, actual, expected) { +function pointsetEqual(t: any, actual: Array, expected: Array) { t.equal(actual.length, expected.length); for (let i = 0; i < actual.length; i++) { const p1 = actual[i]; @@ -231,6 +231,7 @@ test('util', (t) => { t.plan(6); t.deepEqual(mapObject({}, () => { t.ok(false); }), {}); const that = {}; + // $FlowFixMe[missing-this-annot] t.deepEqual(mapObject({map: 'box'}, function(value, key, object) { t.equal(value, 'box'); t.equal(key, 'map'); @@ -244,6 +245,7 @@ test('util', (t) => { t.plan(6); t.deepEqual(filterObject({}, () => { t.ok(false); }), {}); const that = {}; + // $FlowFixMe[missing-this-annot] filterObject({map: 'box'}, function(value, key, object) { t.equal(value, 'box'); t.equal(key, 'map'); @@ -427,7 +429,7 @@ test('util', (t) => { t.test('isSafariWithAntialiasingBug', (t) => { - const isSafariWithAntialiasingBugReset = (scope) => { + const isSafariWithAntialiasingBugReset = (scope: {| navigator: {| userAgent: string |} |}) => { _resetSafariCheckForTest(); const result = isSafariWithAntialiasingBug(scope); _resetSafariCheckForTest(); diff --git a/test/unit/util/web_worker_transfer.test.js b/test/unit/util/web_worker_transfer.test.js index ab2d037a362..6f7f32e2e93 100644 --- a/test/unit/util/web_worker_transfer.test.js +++ b/test/unit/util/web_worker_transfer.test.js @@ -11,13 +11,13 @@ test('round trip', (t) => { buffer: ArrayBuffer; _cached: ?number; - constructor(n) { + constructor(n: number) { this.n = n; this.buffer = new ArrayBuffer(100); this.squared(); } - squared() { + squared(): number { if (this._cached) { return this._cached; } @@ -48,7 +48,7 @@ test('custom serialization', (t) => { class Bar { id: string; _deserialized: boolean; - constructor(id) { + constructor(id: string) { this.id = id; this._deserialized = false; } diff --git a/test/util/test.js b/test/util/test.js index 9c2425b380e..fb384e65c2a 100644 --- a/test/util/test.js +++ b/test/util/test.js @@ -32,6 +32,7 @@ export const only = (tap.only: CreateTest); const consoleError = console.error; const consoleWarn = console.warn; +// $FlowFixMe[missing-this-annot] tap.beforeEach(function () { this.sandbox = sinon.createSandbox({ injectInto: this, @@ -44,6 +45,7 @@ tap.beforeEach(function () { console.warn = () => this.fail(`console.warn called -- please adjust your test (maybe stub console.warn?)`); }); +// $FlowFixMe[missing-this-annot] tap.afterEach(function () { // $FlowFixMe the assignment is intentional console.error = consoleError; diff --git a/yarn.lock b/yarn.lock index 53f4de12758..b2dc2e34c12 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3469,10 +3469,10 @@ flatted@^3.1.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== -flow-bin@0.188.0: - version "0.188.0" - resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.188.0.tgz#5d6e2c918fdf1d1d1d083f739ad8812ecd6f0b46" - integrity sha512-VGCvufWjCQgbM+S2inUeq4mpU/cSAVKUrJFn0iQ+68dHnQdXUdDKd0Mtt18mToPgu3Dsxgi20529V5vlyzYKEQ== +flow-bin@0.191.0: + version "0.191.0" + resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.191.0.tgz#9324c9498584b60575fd8d77a2897ee4f384443b" + integrity sha512-IhaDGoOtRDdGUJLjm7KQlHK8BAzOVJmpx+CIR6bCju4pF7zon2v7WNrds5706WZqDE3rD2c8cM4GdhDnIFYXtg== follow-redirects@^1.0.0: version "1.15.1"