From 37d366165e740805dcb2687d9f6fd1fe2ba5c59d Mon Sep 17 00:00:00 2001 From: Paul Lindner Date: Fri, 12 Apr 2019 11:42:55 -0700 Subject: [PATCH] Activate strictBindCallApply and strictFunctionTypes compiler rules (#2880) * Fix firebase strictFunctionTypes violation * Activate strictBindCallApply and strictFunctionTypes compiler rules - Improves types in api-channel and slot-consumer - Introduce option types for startRender and stopRender - Fix mismatched Map/object types in providedSlots - Use specific types in Literalizer --- config/tsconfig.base.json | 2 ++ src/runtime/api-channel.ts | 26 +++++++++++++------ src/runtime/arc-exceptions.ts | 2 +- src/runtime/particle-execution-host.ts | 16 ++++++++++-- src/runtime/particle-spec.ts | 2 +- src/runtime/slot-consumer.ts | 10 ++++--- .../storage/firebase/firebase-storage.ts | 4 +-- 7 files changed, 45 insertions(+), 17 deletions(-) diff --git a/config/tsconfig.base.json b/config/tsconfig.base.json index 8131c941766..0a76f8bf05c 100644 --- a/config/tsconfig.base.json +++ b/config/tsconfig.base.json @@ -11,6 +11,8 @@ "noImplicitThis": true, "module": "es2015", "moduleResolution": "Node", + "strictBindCallApply": true, + "strictFunctionTypes": true, "allowJs": false, "sourceMap": true, diff --git a/src/runtime/api-channel.ts b/src/runtime/api-channel.ts index 4fbb7f49549..b57dfa17110 100644 --- a/src/runtime/api-channel.ts +++ b/src/runtime/api-channel.ts @@ -14,15 +14,15 @@ import {Arc} from './arc.js'; import {DevtoolsConnection} from './debug/devtools-connection.js'; import {OuterPortAttachment} from './debug/outer-port-attachment.js'; import {Handle} from './handle.js'; -import {ParticleSpec} from './particle-spec.js'; +import {ParticleSpec, SerializedParticleSpec} from './particle-spec.js'; import {Particle} from './particle.js'; import * as recipeHandle from './recipe/handle.js'; import * as recipeParticle from './recipe/particle.js'; import {StorageProxy} from './storage-proxy.js'; import {SerializedModelEntry} from './storage/crdt-collection-model.js'; import {StorageProviderBase} from './storage/storage-provider-base.js'; -import {Type} from './type.js'; -import {PropagatedException} from './arc-exceptions.js'; +import {Type, TypeLiteral} from './type.js'; +import {PropagatedException, SerializedPropagatedException} from './arc-exceptions.js'; enum MappingType {Mapped, LocalMapped, RemoteMapped, Direct, ObjectMap, List, ByLiteral} @@ -32,15 +32,25 @@ interface MappingInfo { redundant?: boolean; value?: MappingInfo; key?: MappingInfo; - converter?: Literalizer; + converter?: Literalizer | LiteralizerParticleSpec | LiteralizerPropagatedException; identifier?: boolean; ignore?: boolean; } // TODO(shans): are there better types that I can use for this? interface Literalizer { - prototype: {toLiteral: () => {}}; - fromLiteral: ({}) => {}; + prototype: {toLiteral: () => TypeLiteral}; + fromLiteral: (typeliteral: TypeLiteral) => Type; +} + +interface LiteralizerParticleSpec { + prototype: {toLiteral: () => SerializedParticleSpec}; + fromLiteral: (spec: SerializedParticleSpec) => ParticleSpec; +} + +interface LiteralizerPropagatedException { + prototype: {toLiteral: () => SerializedPropagatedException}; + fromLiteral: (exception: SerializedPropagatedException) => PropagatedException; } const targets = new Map<{}, Map>(); @@ -67,7 +77,7 @@ function Mapped(target: {}, propertyKey: string, parameterIndex: number) { set(target.constructor, propertyKey, parameterIndex, {type: MappingType.Mapped}); } -function ByLiteral(constructor: Literalizer) { +function ByLiteral(constructor: Literalizer | LiteralizerParticleSpec | LiteralizerPropagatedException) { return (target: {}, propertyKey: string, parameterIndex: number) => { const info: MappingInfo = {type: MappingType.ByLiteral, converter: constructor}; set(target.constructor, propertyKey, parameterIndex, info); @@ -415,7 +425,7 @@ export abstract class PECOuterPort extends APIPort { UIEvent(@Mapped particle: recipeParticle.Particle, @Direct slotName: string, @Direct event: {}) {} SimpleCallback(@RemoteMapped callback: number, @Direct data: {}) {} AwaitIdle(@Direct version: number) {} - StartRender(@Mapped particle: recipeParticle.Particle, @Direct slotName: string, @ObjectMap(MappingType.Direct, MappingType.Direct) providedSlots: {[index: string]: string}, @List(MappingType.Direct) contentTypes: string[]) {} + StartRender(@Mapped particle: recipeParticle.Particle, @Direct slotName: string, @ObjectMap(MappingType.Direct, MappingType.Direct) providedSlots: Map, @List(MappingType.Direct) contentTypes: string[]) {} StopRender(@Mapped particle: recipeParticle.Particle, @Direct slotName: string) {} abstract onRender(particle: recipeParticle.Particle, slotName: string, content: string); diff --git a/src/runtime/arc-exceptions.ts b/src/runtime/arc-exceptions.ts index 65fdecbdabd..dcae3cb7201 100644 --- a/src/runtime/arc-exceptions.ts +++ b/src/runtime/arc-exceptions.ts @@ -10,7 +10,7 @@ import {Particle} from './particle'; * http://polymer.github.io/PATENTS.txt */ -type SerializedPropagatedException = { +export type SerializedPropagatedException = { exceptionType: string, cause: {name: string, message: string, stack: string}, // Serialized Error. method: string, diff --git a/src/runtime/particle-execution-host.ts b/src/runtime/particle-execution-host.ts index 5faf9527c9d..507f77017a5 100644 --- a/src/runtime/particle-execution-host.ts +++ b/src/runtime/particle-execution-host.ts @@ -21,6 +21,18 @@ import {SlotComposer} from './slot-composer.js'; import {StorageProviderBase} from './storage/storage-provider-base.js'; import {Type} from './type.js'; +export type StartRenderOptions = { + particle: Particle; + slotName: string; + providedSlots: Map; + contentTypes: string[]; +}; + +export type StopRenderOptions = { + particle: Particle; + slotName: string; +}; + export class ParticleExecutionHost { private _apiPort : PECOuterPort; close : () => void; @@ -281,11 +293,11 @@ export class ParticleExecutionHost { this._apiPort.InstantiateParticle(particle, particle.id.toString(), particle.spec, stores); } - startRender({particle, slotName, providedSlots, contentTypes}: {particle: Particle, slotName: string, providedSlots: {[index: string]: string}, contentTypes: string[]}) { + startRender({particle, slotName, providedSlots, contentTypes}: StartRenderOptions): void { this._apiPort.StartRender(particle, slotName, providedSlots, contentTypes); } - stopRender({particle, slotName}: {particle: Particle, slotName: string}) { + stopRender({particle, slotName}: StopRenderOptions): void { this._apiPort.StopRender(particle, slotName); } diff --git a/src/runtime/particle-spec.ts b/src/runtime/particle-spec.ts index 4e4236c3dd0..8851d26c522 100644 --- a/src/runtime/particle-spec.ts +++ b/src/runtime/particle-spec.ts @@ -144,7 +144,7 @@ export class ProvideSlotConnectionSpec { } } -type SerializedParticleSpec = { +export type SerializedParticleSpec = { name: string, id?: string, verbs: string[], diff --git a/src/runtime/slot-consumer.ts b/src/runtime/slot-consumer.ts index d7faa7a1278..a23b69e8513 100644 --- a/src/runtime/slot-consumer.ts +++ b/src/runtime/slot-consumer.ts @@ -12,8 +12,10 @@ import {assert} from '../platform/assert-web.js'; import {Arc} from './arc.js'; import {Description} from './description.js'; +import {Particle} from './recipe/particle.js'; import {SlotConnection} from './recipe/slot-connection.js'; import {HostedSlotContext, ProvidedSlotContext, SlotContext} from './slot-context.js'; +import {StartRenderOptions, StopRenderOptions} from './particle-execution-host.js'; export interface Content { templateName?: string | Map; @@ -41,8 +43,8 @@ export class SlotConsumer { slotContext: SlotContext; readonly directlyProvidedSlotContexts: ProvidedSlotContext[] = []; readonly hostedSlotContexts: HostedSlotContext[] = []; - startRenderCallback: ({}) => void; - stopRenderCallback: ({}) => void; + startRenderCallback: (options: StartRenderOptions) => void; + stopRenderCallback: (options: StopRenderOptions) => void; eventHandler: ({}) => void; readonly containerKind?: string; // Contains `container` and other modality specific rendering information @@ -149,10 +151,12 @@ export class SlotConsumer { startRender() { if (this.consumeConn && this.startRenderCallback) { + const providedSlots = new Map(this.allProvidedSlotContexts.map(context => ([context.name, context.id] as [string, string]))); + this.startRenderCallback({ particle: this.consumeConn.particle, slotName: this.consumeConn.name, - providedSlots: new Map(this.allProvidedSlotContexts.map(context => ([context.name, context.id] as [string, string]))), + providedSlots, contentTypes: this.constructRenderRequest() }); } diff --git a/src/runtime/storage/firebase/firebase-storage.ts b/src/runtime/storage/firebase/firebase-storage.ts index 108cb1e24e2..1d1721bceec 100644 --- a/src/runtime/storage/firebase/firebase-storage.ts +++ b/src/runtime/storage/firebase/firebase-storage.ts @@ -374,7 +374,7 @@ class FirebaseVariable extends FirebaseStorageProvider implements VariableStorag private pendingWrites: {storageKey: string, value: {}}[] = []; wasConnect: boolean; // for debugging private resolveInitialized: () => void; - private readonly valueChangeCallback: ({}) => void; + private readonly valueChangeCallback: (dataSnapshot: firebase.database.DataSnapshot, s?: string) => void; constructor(type, storageEngine, id, reference, firebaseKey, shouldExist) { super(type, storageEngine, id, reference, firebaseKey); @@ -651,7 +651,7 @@ class FirebaseCollection extends FirebaseStorageProvider implements CollectionSt private pendingWrites: {value: {}, storageKey: string}[] = []; private resolveInitialized: () => void; private localKeyId = Date.now(); - private readonly valueChangeCallback: ({}) => void; + private readonly valueChangeCallback: (dataSnapshot: firebase.database.DataSnapshot, s?: string) => void; constructor(type, storageEngine, id, reference, firebaseKey) { super(type, storageEngine, id, reference, firebaseKey);