animate/webGl/my-threejs-test/node_modules/glslify-bundle/index.js

233 lines
5.4 KiB
JavaScript
Raw Normal View History

2024-06-24 09:24:00 +00:00
/* eslint-disable no-redeclare */
var hash = require('murmurhash-js/murmurhash3_gc')
var trim = require('glsl-token-whitespace-trim')
var tokenize = require('glsl-tokenizer/string')
var inject = require('glsl-inject-defines')
var defines = require('glsl-token-defines')
var descope = require('glsl-token-descope')
var clean = require('./lib/clean-suffixes')
var string = require('glsl-token-string')
var scope = require('glsl-token-scope')
var depth = require('glsl-token-depth')
var topoSort = require('./lib/topo-sort')
var copy = require('shallow-copy')
module.exports = function (deps) {
return inject(Bundle(deps).src, {
GLSLIFY: 1
})
}
function Bundle (deps) {
if (!(this instanceof Bundle)) return new Bundle(deps)
// Reorder dependencies topologically
deps = topoSort(deps)
this.depList = deps
this.depIndex = indexBy(deps, 'id')
this.exported = {}
this.cache = {}
this.varCounter = 0
this.src = []
for (var i = 0; i < deps.length; i++) {
this.preprocess(deps[i])
}
for (var i = 0; i < deps.length; i++) {
if (deps[i].entry) {
this.src = this.src.concat(this.bundle(deps[i]))
}
}
this.src = string(this.src)
this.src = string(clean(trim(tokenize(this.src))))
}
var proto = Bundle.prototype
proto.preprocess = function (dep) {
var tokens = tokenize(dep.source)
var imports = []
var exports = null
depth(tokens)
scope(tokens)
for (var i = 0; i < tokens.length; i++) {
var token = tokens[i]
if (token.type !== 'preprocessor') continue
if (!glslifyPreprocessor(token.data)) continue
var exported = glslifyExport(token.data)
var imported = glslifyImport(token.data)
if (exported) {
exports = exported[1]
tokens.splice(i--, 1)
} else if (imported) {
var name = imported[1]
var maps = imported[2].split(/\s?,\s?/g)
var path = maps.shift()
.trim()
.replace(/^'|'$/g, '')
.replace(/^"|"$/g, '')
var target = this.depIndex[dep.deps[path]]
imports.push({
name: name,
path: path,
target: target,
maps: toMapping(maps),
index: i
})
tokens.splice(i--, 1)
}
}
var eof = tokens[tokens.length - 1]
if (eof && eof.type === 'eof') {
tokens.pop()
}
if (dep.entry) {
exports = exports || 'main'
}
if (!exports) {
throw new Error(dep.file + ' does not export any symbols')
}
dep.parsed = {
tokens: tokens,
imports: imports,
exports: exports
}
}
proto.bundle = function (entry) {
var resolved = {}
var result = resolve(entry, [])[1]
return result
function resolve (dep, bindings) {
// Compute suffix for module
bindings.sort()
var ident = bindings.join(':') + ':' + dep.id
var suffix = '_' + hash(ident)
if (dep.entry) {
suffix = ''
}
// Test if export is already resolved
var exportName = dep.parsed.exports + suffix
if (resolved[exportName]) {
return [exportName, []]
}
// Initialize map for variable renamings based on bindings
var rename = {}
for (var i = 0; i < bindings.length; ++i) {
var binding = bindings[i]
rename[binding[0]] = binding[1]
}
// Resolve all dependencies
var imports = dep.parsed.imports
var edits = []
for (var i = 0; i < imports.length; ++i) {
var data = imports[i]
var importMaps = data.maps
var importName = data.name
var importTarget = data.target
var importBindings = Object.keys(importMaps).map(function (id) {
var value = importMaps[id]
// floats/ints should not be renamed
if (value.match(/^\d+(?:\.\d+?)?$/g)) {
return [id, value]
}
// properties (uVec.x, ray.origin, ray.origin.xy etc.) should
// have their host identifiers renamed
var parent = value.match(/^([^.]+)\.(.+)$/)
if (parent) {
return [id, (rename[parent[1]] || (parent[1] + suffix)) + '.' + parent[2]]
}
return [id, rename[value] || (value + suffix)]
})
var importTokens = resolve(importTarget, importBindings)
rename[importName] = importTokens[0]
edits.push([data.index, importTokens[1]])
}
// Rename tokens
var parsedTokens = dep.parsed.tokens.map(copy)
var parsedDefs = defines(parsedTokens)
var tokens = descope(parsedTokens, function (local, token) {
if (parsedDefs[local]) return local
if (rename[local]) return rename[local]
return local + suffix
})
// Insert edits
edits.sort(function (a, b) {
return b[0] - a[0]
})
for (var i = 0; i < edits.length; ++i) {
var edit = edits[i]
tokens = tokens.slice(0, edit[0])
.concat(edit[1])
.concat(tokens.slice(edit[0]))
}
resolved[exportName] = true
return [exportName, tokens]
}
}
function glslifyPreprocessor (data) {
return /#pragma glslify:/.test(data)
}
function glslifyExport (data) {
return /#pragma glslify:\s*export\(([^)]+)\)/.exec(data)
}
function glslifyImport (data) {
return /#pragma glslify:\s*([^=\s]+)\s*=\s*require\(([^)]+)\)/.exec(data)
}
function indexBy (deps, key) {
return deps.reduce(function (deps, entry) {
deps[entry[key]] = entry
return deps
}, {})
}
function toMapping (maps) {
if (!maps) return false
return maps.reduce(function (mapping, defn) {
defn = defn.split(/\s?=\s?/g)
var expr = defn.pop()
defn.forEach(function (key) {
mapping[key] = expr
})
return mapping
}, {})
}