UNPKG

7.4 kBtext/coffeescriptView Raw
1return if global.window
2
3_ = require 'underscore' # imported for debounce/throttle methods
4utility = require './utility'
5fs = require 'fs'
6np = require 'path'
7ion = require '../'
8
9# this doesn't seem to work with Object.observe callbacks
10process.on 'uncaughtException', (e) ->
11 console.error e.stack ? e
12
13module.exports = exports =
14 removeExtension: removeExtension = utility.removeExtension
15 changeExtension: changeExtension = utility.changeExtension
16 normalizePath: normalizePath = utility.normalizePath
17 isPrivate: isPrivate = (path) ->
18 return false unless path?
19 path = normalizePath path
20 result = path[0] is '_' or path.indexOf('/_') >= 0
21 return result
22 link: (object) ->
23 # EXISTING_FILE : SYMBOLIC_LINK
24 for key, value of object
25 if not fs.existsSync key
26 console.error "link source not found: #{key}"
27 continue
28 isDirectory = utility.isDirectory key
29 # existing file path needs to be relative to the link path
30 existingPath = np.relative value, key
31 console.log "link EXISTING: #{existing} LINK: #{value}"
32 runIonFile: (file) ->
33 src = fs.readFileSync(file, 'utf8')
34 js = require('../compiler').compile(src)
35 eval(js)
36 runTests: do ->
37 fn = (manifestFile) ->
38 # convert the files to a name, moduleId map
39 require('../browser/tester').spawnTests manifestFile
40 return _.debounce(_.throttle(fn, 100), 2000)
41
42 buildScriptIncludeFile: (files, base = '') ->
43 files.map((x) -> "document.writeln(\"<script type='text/javascript' src='#{base}#{normalizePath x}'></script>\");").join('\n')
44
45 getModuleId: getModuleId = (source, packageObject) ->
46 # new getModuleId behavior
47 if typeof source is 'string'
48 root = source
49 path = packageObject
50 return normalizePath removeExtension np.join root, path
51 # old getModuleId behavior
52 if packageObject?
53 return normalizePath removeExtension np.join packageObject.name, np.relative packageObject.directories.src, source.path
54 else
55 return null
56
57 showPrettyError: showPrettyError = (e, filename, input) ->
58 message = e.message = syntaxErrorToString e, filename, input
59 beep = '\x07'
60 console.error message + beep
61
62 syntaxErrorToString: syntaxErrorToString = (e, filename, code) ->
63 return e.toString() unless e.location?
64 # lifted from https://github.com/jashkenas/coffee-script/blob/master/src/helpers.coffee
65 repeat = (str, n) ->
66 # Use clever algorithm to have O(log(n)) string concatenation operations.
67 res = ''
68 while n > 0
69 res += str if n & 1
70 n >>>= 1
71 str += str
72 res
73 {first_line, first_column, last_line, last_column} = e.location
74 last_line ?= first_line
75 last_column ?= first_column
76
77 codeLine = code.split('\n')[first_line]
78
79 start = first_column
80 end = if first_line is last_line then last_column + 1 else codeLine.length
81 marker = repeat(' ', start) + repeat('^', end - start)
82
83 colorize = (str) -> "\x1B[1;31m#{str}\x1B[0m"
84 codeLine = codeLine[...start] + colorize(codeLine[start...end]) + codeLine[end..]
85 marker = colorize marker
86
87 """
88 #{filename}:#{first_line + 1}:#{first_column + 1}: error: #{e.originalMessage ? e.message}
89
90 #{codeLine}
91 #{marker}
92 """
93
94 # this compiles coffeescript if needed, but does not actually write the result.
95 compileCoffeeScript: compileCoffeeScript = (source, packageObject) ->
96 return if source.modified is 0
97 moduleId = if typeof packageObject is 'string' then packageObject else getModuleId source, packageObject
98
99 input = source.read()
100 filename = source.path
101
102 cs = require 'coffee-script'
103 try
104 console.log "Compile: #{filename}"
105 compiled = cs.compile input, options = {bare: true}
106 # console.log 'sourceMap: ' + typeof options.sourceMap
107 compiled = addBrowserShim compiled, moduleId
108 return compiled
109 catch e
110 showPrettyError e, filename, input
111 return
112
113 # this compiles a pegjs parser and returns the result. Does not write to the target file.
114 compilePegjs: compilePegjs = (source, packageObject) ->
115 return if source.modified is 0
116 moduleId = if typeof packageObject is 'string' then packageObject else getModuleId source, packageObject
117 filename = source.path
118 try
119 peg = require 'pegjs'
120 console.log "Building: #{filename}"
121 input = source.read()
122 parser = peg.buildParser input, {cache:true,output:"source"}
123 source = "module.exports = " + parser
124 source = addBrowserShim source, moduleId
125 return source
126 catch e
127 console.error e
128
129 compileIon: compileIon = (source, packageObject) -> compileIonWithSourceMap(source, packageObject)?[0]
130
131 # this compiles ion and returns the result. Does not write to the target file.
132 compileIonWithSourceMap: compileIonWithSourceMap = (source, packageObject) ->
133 if source.modified is 0
134 return
135 moduleId = if typeof packageObject is 'string' then packageObject else getModuleId source, packageObject
136 filename = source.path
137 try
138 console.log "Compile: #{filename}"
139 ionCompiler = require '../compiler'
140 input = source.read()
141 [source,map] = ionCompiler.compileWithSourceMap(input, {source:moduleId + ".ion" ,sourceMap:filename.split(/[\/\\]/).pop()})
142 source = addBrowserShim source, moduleId
143 return [source,map]
144 catch e
145 console.error(String(e))
146
147 shimJavascript: shimJavascript = (source, packageObject) ->
148 return if source.modified is 0
149 moduleId = if typeof packageObject is 'string' then packageObject else getModuleId source, packageObject
150 return addBrowserShim source.read(), moduleId
151
152 addBrowserShim: addBrowserShim = (sourceText, moduleId) ->
153 # don't shim if the source starts with a shebang
154 if sourceText.substring(0, 2) is "#!"
155 return sourceText
156 # make sure the javascript isn't already shimmed, so we don't shim it twice.
157 if moduleId?
158 safeId = "_" + moduleId.replace(/[^a-zA-Z0-9]/g, '_') + "_"
159 sourceText =
160 """
161 void (function(){var #{safeId} = function(module,exports,require){#{sourceText}
162 }
163 if (typeof require === 'function') {
164 if (require.register)
165 require.register('#{moduleId}',#{safeId});
166 else
167 #{safeId}.call(this, module, exports, require);
168 }
169 else {
170 #{safeId}.call(this);
171 }
172 }).call(this)
173 """
174 return sourceText
175
176for name in ["ModuleBuilder", "WebsiteBuilder", "File", "Directory", "utility"]
177 do (name) ->
178 Object.defineProperty(exports, name, {enumerable: true, get: -> require("./" + name)})
179