From 28afb395502276a71172e8e1a2e387d626374465 Mon Sep 17 00:00:00 2001 From: Alexander Rose <alexander.rose@weirdbyte.de> Date: Sat, 5 Mar 2022 10:18:40 -0800 Subject: [PATCH] make use of assertUnreachable --- src/mol-canvas3d/camera.ts | 3 ++- src/mol-geo/geometry/text/text-builder.ts | 3 ++- src/mol-gl/shader-code.ts | 3 ++- src/mol-gl/webgl/buffer.ts | 5 ++--- src/mol-io/common/binary-cif/classifier.ts | 15 +++++++------ src/mol-io/common/binary-cif/decoder.ts | 7 ++++--- src/mol-io/writer/cif/encoder.ts | 3 ++- src/mol-model/sequence/sequence.ts | 3 ++- src/mol-plugin-state/actions/structure.ts | 2 +- src/mol-plugin-state/actions/volume.ts | 5 +++-- .../helpers/structure-component.ts | 3 ++- src/mol-plugin-state/transforms/data.ts | 3 ++- src/mol-plugin-state/transforms/model.ts | 3 ++- src/mol-script/language/parser.ts | 21 +++++++++++-------- src/mol-util/zip/deflate.ts | 4 ++-- 15 files changed, 47 insertions(+), 36 deletions(-) diff --git a/src/mol-canvas3d/camera.ts b/src/mol-canvas3d/camera.ts index 2cd6d5348..2b82c50df 100644 --- a/src/mol-canvas3d/camera.ts +++ b/src/mol-canvas3d/camera.ts @@ -10,6 +10,7 @@ import { Viewport, cameraProject, cameraUnproject } from './camera/util'; import { CameraTransitionManager } from './camera/transition'; import { BehaviorSubject } from 'rxjs'; import { Scene } from '../mol-gl/scene'; +import { assertUnreachable } from '../mol-util/type-helpers'; export { ICamera, Camera }; @@ -84,7 +85,7 @@ class Camera implements ICamera { switch (this.state.mode) { case 'orthographic': updateOrtho(this); break; case 'perspective': updatePers(this); break; - default: throw new Error('unknown camera mode'); + default: assertUnreachable(this.state.mode); } const changed = !Mat4.areEqual(this.projection, this.prevProjection, EPSILON) || !Mat4.areEqual(this.view, this.prevView, EPSILON); diff --git a/src/mol-geo/geometry/text/text-builder.ts b/src/mol-geo/geometry/text/text-builder.ts index 83e0ba647..b5d98a2ef 100644 --- a/src/mol-geo/geometry/text/text-builder.ts +++ b/src/mol-geo/geometry/text/text-builder.ts @@ -8,6 +8,7 @@ import { ParamDefinition as PD } from '../../../mol-util/param-definition'; import { ChunkedArray } from '../../../mol-data/util'; import { Text } from './text'; import { getFontAtlas } from './font-atlas'; +import { assertUnreachable } from '../../../mol-util/type-helpers'; const quadIndices = new Uint16Array([ 0, 1, 2, @@ -237,7 +238,7 @@ export namespace TextBuilder { yBaseCenter = yTop; break; default: - throw new Error('unsupported attachment'); + assertUnreachable(attachment); } caAdd2(mappings, xTip, yTip); // tip caAdd2(mappings, xBaseA, yBaseA); // base A diff --git a/src/mol-gl/shader-code.ts b/src/mol-gl/shader-code.ts index be5974773..1fd36f8c0 100644 --- a/src/mol-gl/shader-code.ts +++ b/src/mol-gl/shader-code.ts @@ -202,6 +202,7 @@ export const DirectVolumeShaderCode = ShaderCode('direct-volume', directVolume_v import { image_vert } from './shader/image.vert'; import { image_frag } from './shader/image.frag'; +import { assertUnreachable } from '../mol-util/type-helpers'; export const ImageShaderCode = ShaderCode('image', image_vert, image_frag, { drawBuffers: 'optional' }, {}, ignoreDefineUnlit); // @@ -228,7 +229,7 @@ function getDefinesCode(defines: ShaderDefines, ignore?: IgnoreDefine) { } else if (typeof v === 'boolean') { if (v) lines.push(`#define ${name}`); } else { - throw new Error('unknown define type'); + assertUnreachable(v); } } } diff --git a/src/mol-gl/webgl/buffer.ts b/src/mol-gl/webgl/buffer.ts index eedcc6346..cd5790982 100644 --- a/src/mol-gl/webgl/buffer.ts +++ b/src/mol-gl/webgl/buffer.ts @@ -8,7 +8,7 @@ import { WebGLContext } from './context'; import { ValueCell } from '../../mol-util'; import { RenderableSchema } from '../renderable/schema'; import { idFactory } from '../../mol-util/id-factory'; -import { ValueOf } from '../../mol-util/type-helpers'; +import { assertUnreachable, ValueOf } from '../../mol-util/type-helpers'; import { GLRenderingContext } from './compat'; import { WebGLExtensions } from './extensions'; import { WebGLState } from './state'; @@ -66,9 +66,8 @@ function dataTypeFromArray(gl: GLRenderingContext, array: ArrayType) { return gl.INT; } else if (array instanceof Float32Array) { return gl.FLOAT; - } else { - throw new Error('Should never happen'); } + assertUnreachable(array); } export function getBufferType(gl: GLRenderingContext, bufferType: BufferType) { diff --git a/src/mol-io/common/binary-cif/classifier.ts b/src/mol-io/common/binary-cif/classifier.ts index 2c94fbc89..9ad8aaaa7 100644 --- a/src/mol-io/common/binary-cif/classifier.ts +++ b/src/mol-io/common/binary-cif/classifier.ts @@ -7,6 +7,7 @@ import { ArrayEncoder, ArrayEncoding as E } from './array-encoder'; import { getArrayDigitCount } from '../../../mol-util/number'; +import { assertUnreachable } from '../../../mol-util/type-helpers'; export function classifyIntArray(xs: ArrayLike<number>) { return IntClassifier.classify(xs as number[]); @@ -62,7 +63,7 @@ namespace IntClassifier { for (let i = 0, n = data.length; i < n; i++) { incSize(info, size, data[i]); } - return { ...byteSize(size), kind: 'pack' }; + return { ...byteSize(size), kind: 'pack' as const }; } function deltaSize(data: number[], info: IntColumnInfo) { @@ -72,7 +73,7 @@ namespace IntClassifier { incSizeSigned(size, data[i] - prev); prev = data[i]; } - return { ...byteSize(size), kind: 'delta' }; + return { ...byteSize(size), kind: 'delta' as const }; } function rleSize(data: number[], info: IntColumnInfo) { @@ -90,7 +91,7 @@ namespace IntClassifier { incSize(info, size, data[data.length - 1]); incSize(info, size, run); - return { ...byteSize(size), kind: 'rle' }; + return { ...byteSize(size), kind: 'rle' as const }; } function deltaRleSize(data: number[], info: IntColumnInfo) { @@ -111,7 +112,7 @@ namespace IntClassifier { incSizeSigned(size, prevValue); incSizeSigned(size, run); - return { ...byteSize(size), kind: 'delta-rle' }; + return { ...byteSize(size), kind: 'delta-rle' as const }; } export function getSize(data: number[]) { @@ -132,9 +133,8 @@ namespace IntClassifier { case 'rle': return E.by(E.runLength).and(E.integerPacking); case 'delta': return E.by(E.delta).and(E.integerPacking); case 'delta-rle': return E.by(E.delta).and(E.runLength).and(E.integerPacking); + default: assertUnreachable(size); } - - throw new Error('should not happen :)'); } } @@ -169,9 +169,8 @@ namespace FloatClassifier { case 'rle': return fp.and(E.runLength).and(E.integerPacking); case 'delta': return fp.and(E.delta).and(E.integerPacking); case 'delta-rle': return fp.and(E.delta).and(E.runLength).and(E.integerPacking); + default: assertUnreachable(size); } - - throw new Error('should not happen :)'); } function getMultiplier(mantissaDigits: number) { diff --git a/src/mol-io/common/binary-cif/decoder.ts b/src/mol-io/common/binary-cif/decoder.ts index fe6ca9ebf..10cdc28d7 100644 --- a/src/mol-io/common/binary-cif/decoder.ts +++ b/src/mol-io/common/binary-cif/decoder.ts @@ -7,6 +7,7 @@ import { Encoding, EncodedData } from './encoding'; import { IsNativeEndianLittle, flipByteOrder } from '../binary'; +import { assertUnreachable } from '../../../mol-util/type-helpers'; /** * Fixed point, delta, RLE, integer packing adopted from https://github.com/rcsb/mmtf-javascript/ @@ -33,7 +34,7 @@ function decodeStep(data: any, encoding: Encoding): any { case Encoding.IntDataType.Uint32: return uint32(data); case Encoding.FloatDataType.Float32: return float32(data); case Encoding.FloatDataType.Float64: return float64(data); - default: throw new Error('Unsupported ByteArray type.'); + default: assertUnreachable(encoding.type); } } case 'FixedPoint': return fixedPoint(data, encoding); @@ -53,7 +54,7 @@ function getIntArray(type: Encoding.IntDataType, size: number) { case Encoding.IntDataType.Uint8: return new Uint8Array(size); case Encoding.IntDataType.Uint16: return new Uint16Array(size); case Encoding.IntDataType.Uint32: return new Uint32Array(size); - default: throw new Error('Unsupported integer data type.'); + default: assertUnreachable(type); } } @@ -61,7 +62,7 @@ function getFloatArray(type: Encoding.FloatDataType, size: number) { switch (type) { case Encoding.FloatDataType.Float32: return new Float32Array(size); case Encoding.FloatDataType.Float64: return new Float64Array(size); - default: throw new Error('Unsupported floating data type.'); + default: assertUnreachable(type); } } diff --git a/src/mol-io/writer/cif/encoder.ts b/src/mol-io/writer/cif/encoder.ts index 819ad351b..71fa7ae0e 100644 --- a/src/mol-io/writer/cif/encoder.ts +++ b/src/mol-io/writer/cif/encoder.ts @@ -11,6 +11,7 @@ import { Tensor } from '../../../mol-math/linear-algebra'; import { Encoder as EncoderBase } from '../encoder'; import { ArrayEncoder, ArrayEncoding } from '../../common/binary-cif'; import { BinaryEncodingProvider } from './encoder/binary'; +import { assertUnreachable } from '../../../mol-util/type-helpers'; // TODO: support for "coordinate fields", make "coordinate precision" a parameter of the encoder // TODO: automatically detect "precision" of floating point arrays. @@ -324,7 +325,7 @@ function cifFieldsFromTableSchema(schema: Table.Schema) { } else if (t.valueType === 'tensor') { fields.push(...getTensorDefinitions(k, t.space)); } else { - throw new Error(`Unknown valueType ${t.valueType}`); + assertUnreachable(t.valueType); } } return fields; diff --git a/src/mol-model/sequence/sequence.ts b/src/mol-model/sequence/sequence.ts index 5ac73f82f..e68daae6b 100644 --- a/src/mol-model/sequence/sequence.ts +++ b/src/mol-model/sequence/sequence.ts @@ -7,6 +7,7 @@ import { AminoAlphabet, NuclecicAlphabet, getProteinOneLetterCode, getRnaOneLetterCode, getDnaOneLetterCode } from './constants'; import { Column } from '../../mol-data/db'; +import { assertUnreachable } from '../../mol-util/type-helpers'; // TODO add mapping support to other sequence spaces, e.g. uniprot @@ -66,7 +67,7 @@ namespace Sequence { case Kind.DNA: code = getDnaOneLetterCode; break; case Kind.RNA: code = getRnaOneLetterCode; break; case Kind.Generic: code = () => 'X'; break; - default: throw new Error(`unknown kind '${kind}'`); + default: assertUnreachable(kind); } if (map && map.size > 0) { return (name: string) => { diff --git a/src/mol-plugin-state/actions/structure.ts b/src/mol-plugin-state/actions/structure.ts index ea267499b..6bdd89273 100644 --- a/src/mol-plugin-state/actions/structure.ts +++ b/src/mol-plugin-state/actions/structure.ts @@ -155,7 +155,7 @@ const DownloadStructure = StateAction.build({ asTrajectory = !!src.params.options.asTrajectory; format = 'mol'; break; - default: throw new Error(`${(src as any).name} not supported.`); + default: assertUnreachable(src); } const representationPreset: any = params.source.params.options.representation || plugin.config.get(PluginConfig.Structure.DefaultRepresentationPreset) || PresetStructureRepresentations.auto.id; diff --git a/src/mol-plugin-state/actions/volume.ts b/src/mol-plugin-state/actions/volume.ts index f117a0a13..fad2beeca 100644 --- a/src/mol-plugin-state/actions/volume.ts +++ b/src/mol-plugin-state/actions/volume.ts @@ -15,6 +15,7 @@ import { Download } from '../transforms/data'; import { DataFormatProvider } from '../formats/provider'; import { Asset } from '../../mol-util/assets'; import { StateTransforms } from '../transforms'; +import { assertUnreachable } from '../../mol-util/type-helpers'; export type EmdbDownloadProvider = 'pdbe' | 'rcsb' @@ -109,7 +110,7 @@ const DownloadDensity = StateAction.build({ label: `RCSB PDB X-ray Density Server: ${src.params.provider.id}` }; break; - default: throw new Error(`${(src as any).name} not supported.`); + default: assertUnreachable(src); } const data = await plugin.builders.data.download(downloadParams); @@ -131,7 +132,7 @@ const DownloadDensity = StateAction.build({ entryId = src.params.provider.id; provider = plugin.dataFormats.get('dscif'); break; - default: throw new Error(`${(src as any).name} not supported.`); + default: assertUnreachable(src); } if (!provider) { diff --git a/src/mol-plugin-state/helpers/structure-component.ts b/src/mol-plugin-state/helpers/structure-component.ts index 06226bafa..6ddaac6b1 100644 --- a/src/mol-plugin-state/helpers/structure-component.ts +++ b/src/mol-plugin-state/helpers/structure-component.ts @@ -13,6 +13,7 @@ import { PluginStateObject as SO } from '../objects'; import { StructureSelectionQueries } from './structure-selection-query'; import { StateTransformer, StateObject } from '../../mol-state'; import { Script } from '../../mol-script/script'; +import { assertUnreachable } from '../../mol-util/type-helpers'; export const StaticStructureComponentTypes = [ 'all', @@ -72,7 +73,7 @@ export function createStructureComponent(a: Structure, params: StructureComponen case 'coarse': query = StructureSelectionQueries.coarse.query; label = 'Coarse'; break; - default: throw new Error(`${params.type} is a not valid complex element.`); + default: assertUnreachable(params.type); } const result = query(new QueryContext(a)); component = Sel.unionStructure(result); diff --git a/src/mol-plugin-state/transforms/data.ts b/src/mol-plugin-state/transforms/data.ts index 4e486e226..0543b8f19 100644 --- a/src/mol-plugin-state/transforms/data.ts +++ b/src/mol-plugin-state/transforms/data.ts @@ -20,6 +20,7 @@ import { Asset } from '../../mol-util/assets'; import { parseCube } from '../../mol-io/reader/cube/parser'; import { parseDx } from '../../mol-io/reader/dx/parser'; import { ColorNames } from '../../mol-util/color/names'; +import { assertUnreachable } from '../../mol-util/type-helpers'; export { Download }; export { DownloadBlob }; @@ -151,7 +152,7 @@ const RawData = PluginStateTransform.BuiltIn({ } else if (p.data instanceof Uint8Array) { return new SO.Data.Binary(p.data, { label: p.label ? p.label : 'Binary' }); } else { - throw new Error('Supplied binary data must be a plain array, ArrayBuffer, or Uint8Array.'); + assertUnreachable(p.data); } }); }, diff --git a/src/mol-plugin-state/transforms/model.ts b/src/mol-plugin-state/transforms/model.ts index 715201540..9cd34a05b 100644 --- a/src/mol-plugin-state/transforms/model.ts +++ b/src/mol-plugin-state/transforms/model.ts @@ -41,6 +41,7 @@ import { parseXyz } from '../../mol-io/reader/xyz/parser'; import { trajectoryFromXyz } from '../../mol-model-formats/structure/xyz'; import { parseSdf } from '../../mol-io/reader/sdf/parser'; import { trajectoryFromSdf } from '../../mol-model-formats/structure/sdf'; +import { assertUnreachable } from '../../mol-util/type-helpers'; export { CoordinatesFromDcd }; export { CoordinatesFromXtc }; @@ -846,7 +847,7 @@ const StructureComplexElement = PluginStateTransform.BuiltIn({ case 'atomic-het': query = Queries.internal.atomicHet(); label = 'HET Groups/Ligands'; break; case 'spheres': query = Queries.internal.spheres(); label = 'Coarse Spheres'; break; - default: throw new Error(`${params.type} is a not valid complex element.`); + default: assertUnreachable(params.type); } const result = query(new QueryContext(a.data)); diff --git a/src/mol-script/language/parser.ts b/src/mol-script/language/parser.ts index 79db907d5..f34ca2a31 100644 --- a/src/mol-script/language/parser.ts +++ b/src/mol-script/language/parser.ts @@ -7,6 +7,7 @@ import { MonadicParser as P } from '../../mol-util/monadic-parser'; import { Expression } from './expression'; import { MolScriptBuilder as B } from './builder'; +import { assertUnreachable } from '../../mol-util/type-helpers'; export function parseMolScript(input: string) { return Language.parse(input); @@ -17,6 +18,7 @@ namespace Language { namespace ASTNode { export type Expression = Str | Symb | List | Comment + export type ExpressionWithoutComment = Str | Symb | List export interface Str { kind: 'string', @@ -60,7 +62,7 @@ namespace Language { function getAST(input: string) { return Expressions.tryParse(input); } - function visitExpr(expr: ASTNode.Expression): Expression { + function visitExpr(expr: ASTNode.ExpressionWithoutComment): Expression { switch (expr.kind) { case 'string': return expr.value; case 'symbol': { @@ -82,15 +84,14 @@ namespace Language { case '[': return B.core.type.list(withoutComments(expr.nodes).map(visitExpr)); case '{': return B.core.type.set(withoutComments(expr.nodes).map(visitExpr)); case '(': { + if (expr.nodes[0].kind === 'comment') throw new Error('Invalid expression'); const head = visitExpr(expr.nodes[0]); return Expression.Apply(head, getArgs(expr.nodes)); } + default: assertUnreachable(expr.bracket); } - return 0 as any; - } - default: { - throw new Error('should not happen'); } + default: assertUnreachable(expr); } } @@ -109,14 +110,16 @@ namespace Language { let allNumeric = true; let pos = 0; for (let i = 1, _i = nodes.length; i < _i; i++) { - const n = nodes[i]; + let n = nodes[i]; if (n.kind === 'comment') continue; if (n.kind === 'symbol' && n.value.length > 1 && n.value.charAt(0) === ':') { const name = n.value.substr(1); ++i; while (i < _i && nodes[i].kind === 'comment') { i++; } if (i >= _i) throw new Error(`There must be a value foolowed a named arg ':${name}'.`); - args[name] = visitExpr(nodes[i]); + n = nodes[i]; + if (n.kind === 'comment') throw new Error('Invalid expression'); + args[name] = visitExpr(n); if (isNaN(+name)) allNumeric = false; } else { args[pos++] = visitExpr(n); @@ -158,8 +161,8 @@ namespace Language { break; } } - if (!hasComment) return nodes; - return nodes.filter(n => n.kind !== 'comment'); + if (!hasComment) return nodes as ASTNode.ExpressionWithoutComment[]; + return nodes.filter(n => n.kind !== 'comment') as ASTNode.ExpressionWithoutComment[]; } function isNumber(value: string) { diff --git a/src/mol-util/zip/deflate.ts b/src/mol-util/zip/deflate.ts index 217f92993..71627f51b 100644 --- a/src/mol-util/zip/deflate.ts +++ b/src/mol-util/zip/deflate.ts @@ -8,7 +8,7 @@ */ import { RuntimeContext } from '../../mol-task'; -import { NumberArray } from '../type-helpers'; +import { assertUnreachable, NumberArray } from '../type-helpers'; import { _hufTree } from './huffman'; import { U, revCodes, makeCodes } from './util'; @@ -250,7 +250,7 @@ function _writeBlock(BFINAL: number, lits: Uint32Array, li: number, ebits: numbe pos = _codeTiny(lset, U.itree, out, pos); pos = _codeTiny(dset, U.itree, out, pos); } else { - throw new Error(`unknown BTYPE ${BTYPE}`); + assertUnreachable(BTYPE); } let off = o0; -- GitLab