UNPKG

@shaderfrog/glsl-parser

Version:

A GLSL ES 1.0 and 3.0 parser and preprocessor that can preserve whitespace and comments

131 lines (130 loc) 4.93 kB
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; import { xor } from './utils.js'; export var UNKNOWN_TYPE = 'UNKNOWN TYPE'; export var makeScopeIndex = function (firstReference, declaration) { return ({ declaration: declaration, references: [firstReference], }); }; export var findTypeScope = function (scope, typeName) { if (!scope) { return null; } if (typeName in scope.types) { return scope; } return findTypeScope(scope.parent, typeName); }; export var isDeclaredType = function (scope, typeName) { return findTypeScope(scope, typeName) !== null; }; export var findBindingScope = function (scope, name) { if (!scope) { return null; } if (name in scope.bindings) { return scope; } return findBindingScope(scope.parent, name); }; export var extractConstant = function (expression) { var result = UNKNOWN_TYPE; // Keyword case, like float if ('token' in expression) { result = expression.token; // User defined type } else if ('identifier' in expression && typeof expression.identifier === 'string') { result = expression.identifier; } else { console.warn(result, expression); } return result; }; export var quantifiersSignature = function (quantifier) { return quantifier.map(function (q) { return "[".concat(extractConstant(q.expression), "]"); }).join(''); }; export var functionDeclarationSignature = function (node) { var _a; var proto = node.type === 'function' ? node.prototype : node; var specifier = proto.header.returnType.specifier; var quantifiers = specifier.quantifier || []; var parameterTypes = ((_a = proto === null || proto === void 0 ? void 0 : proto.parameters) === null || _a === void 0 ? void 0 : _a.map(function (_a) { var specifier = _a.specifier, quantifier = _a.quantifier; var quantifiers = // vec4[1][2] param specifier.quantifier || // vec4 param[1][3] quantifier || []; return "".concat(extractConstant(specifier.specifier)).concat(quantifiersSignature(quantifiers)); })) || ['void']; var returnType = "".concat(specifier.specifier.token).concat(quantifiersSignature(quantifiers)); return [ returnType, parameterTypes, "".concat(returnType, ": ").concat(parameterTypes.join(', ')), ]; }; export var doSignaturesMatch = function (definitionSignature, definition, callSignature) { if (definitionSignature === callSignature[0]) { return true; } var left = __spreadArray([definition.returnType], definition.parameterTypes, true); var right = __spreadArray([callSignature[0]], callSignature[1], true); // Special case. When comparing "a()" to "a(1)", a() has paramater VOID, and // a(1) has type UNKNOWN. This will pass as true in the final check of this // function, even though it's not. if (left.length === 2 && xor(left[1] === 'void', right[1] === 'void')) { return false; } return (left.length === right.length && left.every(function (type, index) { return type === right[index] || type === UNKNOWN_TYPE || right[index] === UNKNOWN_TYPE; })); }; export var findOverloadDefinition = function (signature, index) { return Object.entries(index).reduce(function (found, _a) { var overloadSignature = _a[0], overloadDefinition = _a[1]; return (found || (doSignaturesMatch(overloadSignature, overloadDefinition, signature) ? overloadDefinition : undefined)); }, undefined); }; export var functionUseSignature = function (node) { var parameterTypes = node.args.length === 0 ? ['void'] : node.args .filter(function (arg) { return arg.literal !== ','; }) .map(function () { return UNKNOWN_TYPE; }); var returnType = UNKNOWN_TYPE; return [ returnType, parameterTypes, "".concat(returnType, ": ").concat(parameterTypes.join(', ')), ]; }; export var newOverloadIndex = function (returnType, parameterTypes, firstReference, declaration) { return ({ returnType: returnType, parameterTypes: parameterTypes, declaration: declaration, references: [firstReference], }); }; export var findGlobalScope = function (scope) { return scope.parent ? findGlobalScope(scope.parent) : scope; }; export var isDeclaredFunction = function (scope, fnName) { return fnName in findGlobalScope(scope).functions; };