Skip to content

Commit

Permalink
Fix lots of type errors and introduces assertElement. (#4885)
Browse files Browse the repository at this point in the history
* Fix lots of type errors and introduces assertElement.

- Gets rid of many specific `Element` types. In practice these aren't helpful, but introduce a lot of casting.
- Might have fixed on actualy bug in url-replacements.js

142 error(s), 6 warning(s), 93.81603250831178% typed
  • Loading branch information
cramforce authored Sep 9, 2016
1 parent 92f2e6a commit d7d493a
Show file tree
Hide file tree
Showing 17 changed files with 128 additions and 70 deletions.
5 changes: 5 additions & 0 deletions build-system/amp.extern.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,8 @@ twttr.widgets.createTweet;

var FB;
FB.init;

// Validator
var amp;
amp.validator;
amp.validator.validateUrlAndLog = function(string, doc, filter) {}
Binary file modified build-system/runner/dist/runner.jar
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package org.ampproject;

import com.google.common.collect.ImmutableList;
import com.google.javascript.jscomp.ClosureCodingConvention.AssertFunctionByTypeName;
import com.google.javascript.jscomp.CodingConvention;
import com.google.javascript.jscomp.CodingConvention.AssertionFunctionSpec;
import com.google.javascript.jscomp.CodingConventions;
Expand Down Expand Up @@ -45,9 +46,8 @@ public AmpCodingConvention(CodingConvention convention) {
return ImmutableList.of(
new AssertionFunctionSpec("user.assert", JSType.TRUTHY),
new AssertionFunctionSpec("dev.assert", JSType.TRUTHY),
new AssertionFunctionSpec("module$src$log.user.assert", JSType.TRUTHY),
new AssertionFunctionSpec("module$src$log.dev.assert", JSType.TRUTHY),
new AssertionFunctionSpec("Log$$module$src$log.prototype.assert", JSType.TRUTHY)
new AssertionFunctionSpec("Log$$module$src$log.prototype.assert", JSType.TRUTHY),
new AssertFunctionByTypeName("Log$$module$src$log.prototype.assertElement", "Element")
);
}

Expand Down
5 changes: 3 additions & 2 deletions src/event-helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,10 @@ export function isLoaded(element) {
* Returns a promise that will resolve or fail based on the element's 'load'
* and 'error' events. Optionally this method takes a timeout, which will reject
* the promise if the resource has not loaded by then.
* @param {!Element} element
* @param {T} element
* @param {number=} opt_timeout
* @return {!Promise<!Element>}
* @return {!Promise<T>}
* @template T
*/
export function loadPromise(element, opt_timeout) {
let unlistenLoad;
Expand Down
2 changes: 1 addition & 1 deletion src/json.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export function getValueForExpr(obj, expr) {
* Parses the given `json` string without throwing an exception if not valid.
* Returns `undefined` if parsing fails.
* Returns the `Object` corresponding to the JSON string when parsing succeeds.
* @param {string} json JSON string to parse
* @param {*} json JSON string to parse
* @param {function(!Error)=} opt_onFailed Optional function that will be called with
* the error if parsing fails.
* @return {?JSONValueDef|undefined}
Expand Down
18 changes: 18 additions & 0 deletions src/log.js
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,24 @@ export class Log {
}
return shouldBeTrueish;
}

/**
* Throws an error if the first argument isn't an Element
*
* Otherwise see `assert` for usage
*
* @param {*} shouldBeElement
* @param {string=} opt_message The assertion message
* @return {!Element} The value of shouldBeTrueish.
* @template T
*/
/*eslint "google-camelcase/google-camelcase": 2*/
assertElement(shouldBeElement, opt_message) {
const shouldBeTrueish = shouldBeElement && shouldBeElement.nodeType == 1;
this.assert(shouldBeTrueish, (opt_message || 'Element expected') + ': %s',
shouldBeElement);
return /** @type {!Element} */ (shouldBeElement);
}

/**
* Asserts and returns the enum value. If the enum doesn't contain such a value,
Expand All @@ -261,6 +278,7 @@ export class Log {
* @return T
* @template T
*/
/*eslint "google-camelcase/google-camelcase": 2*/
assertEnumValue(enumObj, s, opt_enumName) {
for (const k in enumObj) {
if (enumObj[k] == s) {
Expand Down
5 changes: 3 additions & 2 deletions src/performance.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ import {getExistingServiceForWindow} from './service';

/**
* @param {!Window} window
* @return {!Performance}
* @return {!./service/performance-impl.Performance}
*/
export function performanceFor(window) {
return getExistingServiceForWindow(window, 'performance');
return /** @type {!./service/performance-impl.Performance}*/ (
getExistingServiceForWindow(window, 'performance'));
};
19 changes: 10 additions & 9 deletions src/service/url-replacements-impl.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export class UrlReplacements {
/** @private {!RegExp|undefined} */
this.replacementExpr_ = undefined;

/** @private @const {!Object<string, function(*):*>} */
/** @private @const {!Object<string, function(*, *):*>} */
this.replacements_ = this.win_.Object.create(null);

/** @private @const {function():!Promise<?AccessService>} */
Expand Down Expand Up @@ -426,7 +426,7 @@ export class UrlReplacements {
* @template T
*/
getAccessValue_(getter, expr) {
return this.getAccessService_(this.win_).then(accessService => {
return this.getAccessService_().then(accessService => {
if (!accessService) {
// Access service is not installed.
user().error(TAG, 'Access service is not installed to access: ', expr);
Expand All @@ -441,8 +441,8 @@ export class UrlReplacements {
* The data for the timing events is retrieved from performance.timing API.
* If start and end events are both given, the result is the difference between the two.
* If only start event is given, the result is the timing value at start event.
* @param {string} startEvent
* @param {string=} endEvent
* @param {*} startEvent
* @param {*=} endEvent
* @return {!Promise<string|undefined>}
* @private
*/
Expand Down Expand Up @@ -472,14 +472,15 @@ export class UrlReplacements {
: String(metric);
});
} else {
return Promise.resolve(String(metric));
return /** @type {!Promise<(string|undefined)>} */ (
Promise.resolve(String(metric)));
}
}

/**
* Returns navigation information from the current browsing context.
* @param {string} attribute
* @return {!Promise<string|undefined>}
* @return {!Promise<undefined>|string}
* @private
*/
getNavigationData_(attribute) {
Expand All @@ -497,7 +498,7 @@ export class UrlReplacements {
* Sets the value resolver for the variable with the specified name. The
* value resolver may optionally take an extra parameter.
* @param {string} varName
* @param {function(*):*} resolver
* @param {function(*, *):*} resolver
* @return {!UrlReplacements}
* @private
*/
Expand Down Expand Up @@ -604,7 +605,7 @@ export class UrlReplacements {
/**
* Method exists to assist stubbing in tests.
* @param {string} name
* @return {function(*):*}
* @return {function(*, *):*}
*/
getReplacement_(name) {
return this.replacements_[name];
Expand All @@ -620,7 +621,7 @@ export class UrlReplacements {
if (additionalKeys && additionalKeys.length > 0) {
const allKeys = Object.keys(this.replacements_);
additionalKeys.forEach(key => {
if (allKeys[key] === undefined) {
if (this.replacements_[key] === undefined) {
allKeys.push(key);
}
});
Expand Down
47 changes: 25 additions & 22 deletions src/service/viewer-impl.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export class Viewer {
/** @private {boolean} */
this.overtakeHistory_ = false;

/** @private {string} */
/** @private {!VisibilityState} */
this.visibilityState_ = VisibilityState.VISIBLE;

/** @private {string} */
Expand Down Expand Up @@ -164,6 +164,15 @@ export class Viewer {
/** @private {?time} */
this.firstVisibleTime_ = null;

/** @private {?Function} */
this.messagingReadyResolver_ = null;

/** @private {?Function} */
this.viewerOriginResolver_ = null;

/** @private {?Function} */
this.trustedViewerResolver_ = null;

/**
* This promise might be resolved right away if the current
* document is already visible. See end of this constructor where we call
Expand All @@ -188,8 +197,8 @@ export class Viewer {
this.isRuntimeOn_ = !parseInt(this.params_['off'], 10);
dev().fine(TAG_, '- runtimeOn:', this.isRuntimeOn_);

this.overtakeHistory_ = !!(parseInt(this.params_['history'], 10)) ||
this.overtakeHistory_;
this.overtakeHistory_ = !!(parseInt(this.params_['history'], 10) ||
this.overtakeHistory_);
dev().fine(TAG_, '- history:', this.overtakeHistory_);

this.setVisibilityState_(this.params_['visibilityState']);
Expand Down Expand Up @@ -237,9 +246,6 @@ export class Viewer {
// Wait for document to become visible.
this.docState_.onVisibilityChanged(this.recheckVisibilityState_.bind(this));

/** @private {function()|undefined} */
this.messagingReadyResolver_ = undefined;

/**
* This promise will resolve when communications channel has been
* established or timeout in 20 seconds. The timeout is needed to avoid
Expand Down Expand Up @@ -287,9 +293,6 @@ export class Viewer {
this.isTrustedViewerOrigin_(this.win.location.ancestorOrigins[0]));
trustedViewerPromise = Promise.resolve(trustedViewerResolved);
} else {

/** @private {!function(boolean)|undefined} */
this.trustedViewerResolver_ = undefined;
// Wait for comms channel to confirm the origin.
trustedViewerResolved = undefined;
trustedViewerPromise = new Promise(resolve => {
Expand All @@ -300,9 +303,6 @@ export class Viewer {
/** @const @private {!Promise<boolean>} */
this.isTrustedViewer_ = trustedViewerPromise;

/** @private {!function(string)|undefined} */
this.viewerOriginResolver_ = undefined;

/** @const @private {!Promise<string>} */
this.viewerOrigin_ = new Promise(resolve => {
if (!this.isEmbedded()) {
Expand Down Expand Up @@ -775,7 +775,8 @@ export class Viewer {
* @return {!Promise}
*/
requestFullOverlay() {
return this.sendMessageUnreliable_('requestFullOverlay', {}, true);
return /** @type {!Promise} */ (
this.sendMessageUnreliable_('requestFullOverlay', {}, true));
}

/**
Expand All @@ -784,7 +785,8 @@ export class Viewer {
* @return {!Promise}
*/
cancelFullOverlay() {
return this.sendMessageUnreliable_('cancelFullOverlay', {}, true);
return /** @type {!Promise} */ (
this.sendMessageUnreliable_('cancelFullOverlay', {}, true));
}

/**
Expand All @@ -793,8 +795,8 @@ export class Viewer {
* @return {!Promise}
*/
postPushHistory(stackIndex) {
return this.sendMessageUnreliable_(
'pushHistory', {stackIndex}, true);
return /** @type {!Promise} */ (this.sendMessageUnreliable_(
'pushHistory', {stackIndex}, true));
}

/**
Expand All @@ -803,8 +805,8 @@ export class Viewer {
* @return {!Promise}
*/
postPopHistory(stackIndex) {
return this.sendMessageUnreliable_(
'popHistory', {stackIndex}, true);
return /** @type {!Promise} */ (this.sendMessageUnreliable_(
'popHistory', {stackIndex}, true));
}

/**
Expand Down Expand Up @@ -833,7 +835,7 @@ export class Viewer {
// it should resolve in milli seconds.
return timerFor(this.win).timeoutPromise(10000, cidPromise, 'base cid')
.catch(error => {
dev().error(error);
dev().error(TAG_, error);
return undefined;
});
});
Expand Down Expand Up @@ -925,7 +927,8 @@ export class Viewer {
return Promise.resolve();
}
if (eventType == 'broadcast') {
this.broadcastObservable_.fire(data);
this.broadcastObservable_.fire(
/** @type {!JSONType|undefined} */ (data));
return Promise.resolve();
}
dev().fine(TAG_, 'unknown message:', eventType);
Expand Down Expand Up @@ -1018,7 +1021,7 @@ export class Viewer {
* @param {string} eventType
* @param {*} data
* @param {boolean} awaitResponse
* @return {!Promise<*>|undefined}
* @return {?Promise<*>|undefined}
* @private
*/
sendMessageUnreliable_(eventType, data, awaitResponse) {
Expand Down Expand Up @@ -1094,7 +1097,7 @@ function parseParams_(str, allParams) {

/**
* Creates an error for the case where a channel cannot be established.
* @param {!Error|string=} opt_reason
* @param {*=} opt_reason
* @return {!Error}
*/
function getChannelError(opt_reason) {
Expand Down
20 changes: 11 additions & 9 deletions src/service/viewport-impl.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ export class Viewport {
/** @private @const {!Observable} */
this.scrollObservable_ = new Observable();

/** @private {?HTMLMetaElement|undefined} */
/** @private {?Element|undefined} */
this.viewportMeta_ = undefined;

/** @private {string|undefined} */
Expand Down Expand Up @@ -483,7 +483,7 @@ export class Viewport {
}

/**
* @return {?HTMLMetaElement}
* @return {?Element}
* @private
*/
getViewportMeta_() {
Expand Down Expand Up @@ -646,9 +646,7 @@ export class ViewportBindingDef {
* independent fixed layer.
* @return {boolean}
*/
requiresFixedLayerTransfer() {
return false;
}
requiresFixedLayerTransfer() {}

/**
* Register a callback for scroll events.
Expand Down Expand Up @@ -934,6 +932,9 @@ export class ViewportBindingNaturalIosEmbed_ {
/** @private {?Element} */
this.scrollMoveEl_ = null;

/** @private {?Element} */
this.endPosEl_ = null;

/** @private {!{x: number, y: number}} */
this.pos_ = {x: 0, y: 0};

Expand Down Expand Up @@ -962,7 +963,8 @@ export class ViewportBindingNaturalIosEmbed_ {
/** @private */
setup_() {
const documentElement = this.win.document.documentElement;
const documentBody = this.win.document.body;
const documentBody = /** @type {!Element} */ (
this.win.document.body);

// Embedded scrolling on iOS is rather complicated. IFrames cannot be sized
// and be scrollable. Sizing iframe by scrolling height has a big negative
Expand Down Expand Up @@ -1221,7 +1223,7 @@ export class ViewportBindingNaturalIosEmbed_ {
* width=device-width,initial-scale=1,minimum-scale=1
* ```
* @param {string} content
* @return {!Object<string, string>}
* @return {!Object<string, (string|undefined)>}
* @private Visible for testing only.
*/
export function parseViewportMeta(content) {
Expand Down Expand Up @@ -1324,7 +1326,7 @@ function createViewport_(window) {
* @return {!Viewport}
*/
export function installViewportService(window) {
return getService(window, 'viewport', () => {
return /** @type !Viewport} */ (getService(window, 'viewport', () => {
return createViewport_(window);
});
}));
};
Loading

0 comments on commit d7d493a

Please sign in to comment.