Ver Fonte

Merge pull request #392 from molstar/assert-unreachable

make use of assertUnreachable
Alexander Rose há 3 anos atrás
pai
commit
3ff2c0840e

+ 2 - 1
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);

+ 2 - 1
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

+ 2 - 1
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);
             }
         }
     }

+ 2 - 3
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) {

+ 7 - 8
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) {

+ 4 - 3
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);
     }
 }
 

+ 2 - 1
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;

+ 2 - 1
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) => {

+ 1 - 1
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;

+ 3 - 2
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) {

+ 2 - 1
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);

+ 2 - 1
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);
             }
         });
     },

+ 2 - 1
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));

+ 9 - 7
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);
         }
     }
 
@@ -116,6 +117,7 @@ namespace Language {
                 ++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}'.`);
+                if (nodes[i].kind === 'comment') throw new Error('Invalid expression');
                 args[name] = visitExpr(nodes[i]);
                 if (isNaN(+name)) allNumeric = false;
             } else {
@@ -158,8 +160,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) {

+ 2 - 2
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;