michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: "use strict"; michael@0: michael@0: this.EXPORTED_SYMBOLS = [ "Deprecated" ]; michael@0: michael@0: const Cu = Components.utils; michael@0: const Ci = Components.interfaces; michael@0: const PREF_DEPRECATION_WARNINGS = "devtools.errorconsole.deprecation_warnings"; michael@0: michael@0: Cu.import("resource://gre/modules/Services.jsm"); michael@0: michael@0: // A flag that indicates whether deprecation warnings should be logged. michael@0: let logWarnings = Services.prefs.getBoolPref(PREF_DEPRECATION_WARNINGS); michael@0: michael@0: Services.prefs.addObserver(PREF_DEPRECATION_WARNINGS, michael@0: function (aSubject, aTopic, aData) { michael@0: logWarnings = Services.prefs.getBoolPref(PREF_DEPRECATION_WARNINGS); michael@0: }, false); michael@0: michael@0: /** michael@0: * Build a callstack log message. michael@0: * michael@0: * @param nsIStackFrame aStack michael@0: * A callstack to be converted into a string log message. michael@0: */ michael@0: function stringifyCallstack (aStack) { michael@0: // If aStack is invalid, use Components.stack (ignoring the last frame). michael@0: if (!aStack || !(aStack instanceof Ci.nsIStackFrame)) { michael@0: aStack = Components.stack.caller; michael@0: } michael@0: michael@0: let frame = aStack.caller; michael@0: let msg = ""; michael@0: // Get every frame in the callstack. michael@0: while (frame) { michael@0: msg += frame.filename + " " + frame.lineNumber + michael@0: " " + frame.name + "\n"; michael@0: frame = frame.caller; michael@0: } michael@0: return msg; michael@0: } michael@0: michael@0: const Deprecated = { michael@0: /** michael@0: * Log a deprecation warning. michael@0: * michael@0: * @param string aText michael@0: * Deprecation warning text. michael@0: * @param string aUrl michael@0: * A URL pointing to documentation describing deprecation michael@0: * and the way to address it. michael@0: * @param nsIStackFrame aStack michael@0: * An optional callstack. If it is not provided a michael@0: * snapshot of the current JavaScript callstack will be michael@0: * logged. michael@0: */ michael@0: warning: function (aText, aUrl, aStack) { michael@0: if (!logWarnings) { michael@0: return; michael@0: } michael@0: michael@0: // If URL is not provided, report an error. michael@0: if (!aUrl) { michael@0: Cu.reportError("Error in Deprecated.warning: warnings must " + michael@0: "provide a URL documenting this deprecation."); michael@0: return; michael@0: } michael@0: michael@0: let textMessage = "DEPRECATION WARNING: " + aText + michael@0: "\nYou may find more details about this deprecation at: " + michael@0: aUrl + "\n" + michael@0: // Append a callstack part to the deprecation message. michael@0: stringifyCallstack(aStack); michael@0: michael@0: // Report deprecation warning. michael@0: Cu.reportError(textMessage); michael@0: } michael@0: };