Chromium Code Reviews| Index: chrome/renderer/resources/extensions/schema_generated_bindings.js |
| diff --git a/chrome/renderer/resources/extensions/schema_generated_bindings.js b/chrome/renderer/resources/extensions/schema_generated_bindings.js |
| index 29700bb5be8ed89282a9db4c0649934faef987e6..124e28f9cddb65c9a35045f7130301d9beb51975 100644 |
| --- a/chrome/renderer/resources/extensions/schema_generated_bindings.js |
| +++ b/chrome/renderer/resources/extensions/schema_generated_bindings.js |
| @@ -16,7 +16,7 @@ |
| var utils = require('utils'); |
| var isDevChannel = requireNative('channel').IsDevChannel; |
| var chromeHidden = requireNative('chrome_hidden').GetChromeHidden(); |
| - |
| + var validateUtils = require('validateUtils'); |
|
not at google - send to devlin
2012/06/07 00:17:11
nit: maintain blank line after this.
benwells
2012/06/07 01:45:40
Done.
|
| // The object to generate the bindings for "internal" APIs in, so that |
| // extensions can't directly call them (without access to chromeHidden), |
| // but are still needed for internal mechanisms of extensions (e.g. events). |
| @@ -26,156 +26,6 @@ |
| var internalAPIs = {}; |
| chromeHidden.internalAPIs = internalAPIs; |
| - // Validate arguments. |
| - var schemaValidator = new chromeHidden.JSONSchemaValidator(); |
| - chromeHidden.validate = function(args, parameterSchemas) { |
| - if (args.length > parameterSchemas.length) |
| - throw new Error("Too many arguments."); |
| - |
| - for (var i = 0; i < parameterSchemas.length; i++) { |
| - if (i in args && args[i] !== null && args[i] !== undefined) { |
| - schemaValidator.resetErrors(); |
| - schemaValidator.validate(args[i], parameterSchemas[i]); |
| - if (schemaValidator.errors.length == 0) |
| - continue; |
| - |
| - var message = "Invalid value for argument " + (i + 1) + ". "; |
| - for (var i = 0, err; err = schemaValidator.errors[i]; i++) { |
| - if (err.path) { |
| - message += "Property '" + err.path + "': "; |
| - } |
| - message += err.message; |
| - message = message.substring(0, message.length - 1); |
| - message += ", "; |
| - } |
| - message = message.substring(0, message.length - 2); |
| - message += "."; |
| - |
| - throw new Error(message); |
| - } else if (!parameterSchemas[i].optional) { |
| - throw new Error("Parameter " + (i + 1) + " is required."); |
| - } |
| - } |
| - }; |
| - |
| - // Generate all possible signatures for a given API function. |
| - function getSignatures(parameterSchemas) { |
| - if (parameterSchemas.length === 0) |
| - return [[]]; |
| - |
| - var signatures = []; |
| - var remaining = getSignatures(parameterSchemas.slice(1)); |
| - for (var i = 0; i < remaining.length; i++) |
| - signatures.push([parameterSchemas[0]].concat(remaining[i])) |
| - |
| - if (parameterSchemas[0].optional) |
| - return signatures.concat(remaining); |
| - return signatures; |
| - }; |
| - |
| - // Return true if arguments match a given signature's schema. |
| - function argumentsMatchSignature(args, candidateSignature) { |
| - if (args.length != candidateSignature.length) |
| - return false; |
| - |
| - for (var i = 0; i < candidateSignature.length; i++) { |
| - var argType = chromeHidden.JSONSchemaValidator.getType(args[i]); |
| - if (!schemaValidator.isValidSchemaType(argType, candidateSignature[i])) |
| - return false; |
| - } |
| - return true; |
| - }; |
| - |
| - // Finds the function signature for the given arguments. |
| - function resolveSignature(args, definedSignature) { |
| - var candidateSignatures = getSignatures(definedSignature); |
| - for (var i = 0; i < candidateSignatures.length; i++) { |
| - if (argumentsMatchSignature(args, candidateSignatures[i])) |
| - return candidateSignatures[i]; |
| - } |
| - return null; |
| - }; |
| - |
| - // Returns a string representing the defined signature of the API function. |
| - // Example return value for chrome.windows.getCurrent: |
| - // "windows.getCurrent(optional object populate, function callback)" |
| - function getParameterSignatureString(name, definedSignature) { |
| - var getSchemaTypeString = function(schema) { |
| - var schemaTypes = schemaValidator.getAllTypesForSchema(schema); |
| - var typeName = schemaTypes.join(" or ") + " " + schema.name; |
| - if (schema.optional) |
| - return "optional " + typeName; |
| - return typeName; |
| - }; |
| - |
| - var typeNames = definedSignature.map(getSchemaTypeString); |
| - return name + "(" + typeNames.join(", ") + ")"; |
| - }; |
| - |
| - // Returns a string representing a call to an API function. |
| - // Example return value for call: chrome.windows.get(1, callback) is: |
| - // "windows.get(int, function)" |
| - function getArgumentSignatureString(name, args) { |
| - var typeNames = args.map(chromeHidden.JSONSchemaValidator.getType); |
| - return name + "(" + typeNames.join(", ") + ")"; |
| - }; |
| - |
| - // Finds the correct signature for the given arguments, then validates the |
| - // arguments against that signature. Returns a 'normalized' arguments list |
| - // where nulls are inserted where optional parameters were omitted. |
| - function normalizeArgumentsAndValidate(args, funDef) { |
| - if (funDef.allowAmbiguousOptionalArguments) { |
| - chromeHidden.validate(args, funDef.definition.parameters); |
| - return args; |
| - } |
| - |
| - var definedSignature = funDef.definition.parameters; |
| - var resolvedSignature = resolveSignature(args, definedSignature); |
| - if (!resolvedSignature) |
| - throw new Error("Invocation of form " + |
| - getArgumentSignatureString(funDef.name, args) + |
| - " doesn't match definition " + |
| - getParameterSignatureString(funDef.name, definedSignature)); |
| - |
| - chromeHidden.validate(args, resolvedSignature); |
| - |
| - var normalizedArgs = []; |
| - var ai = 0; |
| - for (var si = 0; si < definedSignature.length; si++) { |
| - if (definedSignature[si] === resolvedSignature[ai]) |
| - normalizedArgs.push(args[ai++]); |
| - else |
| - normalizedArgs.push(null); |
| - } |
| - return normalizedArgs; |
| - }; |
| - |
| - // Validates that a given schema for an API function is not ambiguous. |
| - function isFunctionSignatureAmbiguous(functionDef) { |
| - if (functionDef.allowAmbiguousOptionalArguments) |
| - return false; |
| - |
| - var signaturesAmbiguous = function(signature1, signature2) { |
| - if (signature1.length != signature2.length) |
| - return false; |
| - |
| - for (var i = 0; i < signature1.length; i++) { |
| - if (!schemaValidator.checkSchemaOverlap(signature1[i], signature2[i])) |
| - return false; |
| - } |
| - return true; |
| - }; |
| - |
| - var candidateSignatures = getSignatures(functionDef.parameters); |
| - for (var i = 0; i < candidateSignatures.length; i++) { |
| - for (var j = i + 1; j < candidateSignatures.length; j++) { |
| - if (signaturesAmbiguous(candidateSignatures[i], candidateSignatures[j])) |
| - return true; |
| - } |
| - } |
| - return false; |
| - }; |
| - |
| // Stores the name and definition of each API function, with methods to |
| // modify their behaviour (such as a custom way to handle requests to the |
| // API, a custom callback, etc). |
| @@ -296,11 +146,26 @@ |
| // dictionary for easier access. |
| var self = this; |
| self.parameters = {}; |
| + self.funDefs = {}; |
|
not at google - send to devlin
2012/06/07 00:17:11
Sadly I think that funDefs is a silly name. functi
benwells
2012/06/07 01:45:40
Ok mr grown up. How about funSchemas?
... oh all
|
| schema.functions.forEach(function(f) { |
| self.parameters[f.name] = f.parameters; |
| + var apiFunction = {}; |
| + apiFunction.definition = f; |
| + apiFunction.name = f.name; |
| + self.funDefs[f.name] = apiFunction; |
|
not at google - send to devlin
2012/06/07 00:17:11
nit: inline apiFunction like
self.functionSchemas
benwells
2012/06/07 01:45:40
Done.
|
| }); |
| }; |
| + CustomBindingsObject.prototype.setApiDef = function(apiDef) { |
|
not at google - send to devlin
2012/06/07 00:17:11
is this used? Grep cannot find.
assuming this is
benwells
2012/06/07 01:45:40
Yeah sorry this is an experiment which lived past
|
| + var self = this; |
| + self.funDefs = {}; |
| + if (apiDef.functions) { |
| + apiDef.functions.forEach(function(f) { |
| + self.funDefs[f.name] = f.definition; |
| + }); |
| + } |
| + } |
| + |
| // Registers a custom type referenced via "$ref" fields in the API schema |
| // JSON. |
| var customTypes = {}; |
| @@ -390,7 +255,7 @@ |
| if (!isSchemaNodeSupported(t, platform, manifestVersion)) |
| return; |
| - schemaValidator.addTypes(t); |
| + validateUtils.schemaValidator.addTypes(t); |
| if (t.type == 'object' && customTypes[t.id]) { |
| customTypes[t.id].prototype.setSchema(t); |
| } |
| @@ -444,7 +309,8 @@ |
| // to do that we would need to better factor this code so that it |
| // doesn't depend on so much v8::Extension machinery. |
| if (chromeHidden.validateAPI && |
| - isFunctionSignatureAmbiguous(apiFunction.definition)) { |
| + validateUtils.isFunctionSignatureAmbiguous( |
| + apiFunction.definition)) { |
| throw new Error( |
| apiFunction.name + ' has ambiguous optional arguments. ' + |
| 'To implement custom disambiguation logic, add ' + |
| @@ -458,7 +324,7 @@ |
| if (this.updateArgumentsPreValidate) |
| args = this.updateArgumentsPreValidate.apply(this, args); |
| - args = normalizeArgumentsAndValidate(args, this); |
| + args = validateUtils.normalizeArgumentsAndValidate(args, this); |
| if (this.updateArgumentsPostValidate) |
| args = this.updateArgumentsPostValidate.apply(this, args); |
| @@ -473,9 +339,8 @@ |
| // Validate return value if defined - only in debug. |
| if (chromeHidden.validateCallbacks && |
| - chromeHidden.validate && |
| this.definition.returns) { |
| - chromeHidden.validate([retval], [this.definition.returns]); |
| + validateUtils.validate([retval], [this.definition.returns]); |
| } |
| return retval; |
| }).bind(apiFunction); |