1
0
Fork 0
mirror of https://github.com/jashkenas/coffeescript.git synced 2022-11-09 12:23:24 -05:00

Merge branch 'master' of github.com:jashkenas/coffeescript into 1.12.4

# Conflicts:
#	Cakefile
This commit is contained in:
Geoffrey Booth 2017-02-18 02:48:57 -05:00
commit ee8f022317
14 changed files with 144 additions and 28 deletions

View file

@ -100,10 +100,7 @@ watchAndBuildAndTest = (harmony = no) ->
if eventType is 'change'
log "src/#{filename} changed, rebuilding..."
buildAndTest (filename is 'grammar.coffee'), harmony
fs.watch 'test/',
interval: 200
recursive: yes
, (eventType, filename) ->
fs.watch 'test/', {interval: 200, recursive: yes}, (eventType, filename) ->
if eventType is 'change'
log "test/#{filename} changed, rebuilding..."
buildAndTest no, harmony

View file

@ -385,7 +385,8 @@
} else if (sources[filename] != null) {
answer = compile(sources[filename], {
filename: filename,
sourceMap: true
sourceMap: true,
literate: helpers.isLiterate(filename)
});
return answer.sourceMap;
} else {

View file

@ -409,11 +409,11 @@
double: true
}, this.formatHeregex);
if (flags) {
this.token(',', ',', index, 0);
this.token('STRING', '"' + flags + '"', index, flags.length);
this.token(',', ',', index - 1, 0);
this.token('STRING', '"' + flags + '"', index - 1, flags.length);
}
this.token(')', ')', end, 0);
this.token('REGEX_END', ')', end, 0);
this.token(')', ')', end - 1, 0);
this.token('REGEX_END', ')', end - 1, 0);
}
return end;
};

View file

@ -1024,6 +1024,22 @@
Call.prototype.children = ['variable', 'args'];
Call.prototype.updateLocationDataIfMissing = function(locationData) {
var base, ref3;
if (this.locationData && this.needsUpdatedStartLocation) {
this.locationData.first_line = locationData.first_line;
this.locationData.first_column = locationData.first_column;
base = ((ref3 = this.variable) != null ? ref3.base : void 0) || this.variable;
if (base.needsUpdatedStartLocation) {
this.variable.locationData.first_line = locationData.first_line;
this.variable.locationData.first_column = locationData.first_column;
base.updateLocationDataIfMissing(locationData);
}
delete this.needsUpdatedStartLocation;
}
return Call.__super__.updateLocationDataIfMissing.apply(this, arguments);
};
Call.prototype.newInstance = function() {
var base, ref3;
base = ((ref3 = this.variable) != null ? ref3.base : void 0) || this.variable;
@ -1032,6 +1048,7 @@
} else {
this.isNew = true;
}
this.needsUpdatedStartLocation = true;
return this;
};
@ -2059,7 +2076,7 @@
ModuleSpecifier.prototype.compileNode = function(o) {
var code;
o.scope.add(this.identifier, this.moduleDeclarationType);
o.scope.find(this.identifier, this.moduleDeclarationType);
code = [];
code.push(this.makeCode(this.original.value));
if (this.alias != null) {

View file

@ -45,11 +45,14 @@
return this.parent.namedMethod();
};
Scope.prototype.find = function(name) {
Scope.prototype.find = function(name, type) {
if (type == null) {
type = 'var';
}
if (this.check(name)) {
return true;
}
this.add(name, 'var');
this.add(name, type);
return false;
};

View file

@ -366,6 +366,7 @@ getSourceMap = (filename) ->
answer = compile sources[filename],
filename: filename
sourceMap: yes
literate: helpers.isLiterate filename
answer.sourceMap
else
null

View file

@ -343,10 +343,10 @@ exports.Lexer = class Lexer
@token 'CALL_START', '(', 0, 0
@mergeInterpolationTokens tokens, {delimiter: '"', double: yes}, @formatHeregex
if flags
@token ',', ',', index, 0
@token 'STRING', '"' + flags + '"', index, flags.length
@token ')', ')', end, 0
@token 'REGEX_END', ')', end, 0
@token ',', ',', index - 1, 0
@token 'STRING', '"' + flags + '"', index - 1, flags.length
@token ')', ')', end - 1, 0
@token 'REGEX_END', ')', end - 1, 0
end

View file

@ -633,6 +633,21 @@ exports.Call = class Call extends Base
children: ['variable', 'args']
# When setting the location, we sometimes need to update the start location to
# account for a newly-discovered `new` operator to the left of us. This
# expands the range on the left, but not the right.
updateLocationDataIfMissing: (locationData) ->
if @locationData and @needsUpdatedStartLocation
@locationData.first_line = locationData.first_line
@locationData.first_column = locationData.first_column
base = @variable?.base or @variable
if base.needsUpdatedStartLocation
@variable.locationData.first_line = locationData.first_line
@variable.locationData.first_column = locationData.first_column
base.updateLocationDataIfMissing locationData
delete @needsUpdatedStartLocation
super
# Tag this invocation as creating a new instance.
newInstance: ->
base = @variable?.base or @variable
@ -640,6 +655,7 @@ exports.Call = class Call extends Base
base.newInstance()
else
@isNew = true
@needsUpdatedStartLocation = true
this
# Soaked chained invocations unfold into if/else ternary structures.
@ -1352,7 +1368,7 @@ exports.ModuleSpecifier = class ModuleSpecifier extends Base
children: ['original', 'alias']
compileNode: (o) ->
o.scope.add @identifier, @moduleDeclarationType
o.scope.find @identifier, @moduleDeclarationType
code = []
code.push @makeCode @original.value
code.push @makeCode " as #{@alias.value}" if @alias?

View file

@ -44,9 +44,9 @@ function object that has a name filled in, or bottoms out.
Look up a variable name in lexical scope, and declare it if it does not
already exist.
find: (name) ->
find: (name, type = 'var') ->
return yes if @check name
@add name, 'var'
@add name, type
no
Reserve a variable name as originating from a function parameter for this
@ -116,4 +116,3 @@ of this scope.
assignedVariables: ->
"#{v.name} = #{v.type.value}" for v in @variables when v.type.assigned

View file

@ -71,20 +71,21 @@ if require?
test "#2849: compilation error in a require()d file", ->
# Create a temporary file to require().
ok not fs.existsSync 'test/syntax-error.coffee'
fs.writeFileSync 'test/syntax-error.coffee', 'foo in bar or in baz'
tempFile = path.join os.tmpdir(), 'syntax-error.coffee'
ok not fs.existsSync tempFile
fs.writeFileSync tempFile, 'foo in bar or in baz'
try
assertErrorFormat '''
require './test/syntax-error'
''',
assertErrorFormat """
require '#{tempFile}'
""",
"""
#{path.join __dirname, 'syntax-error.coffee'}:1:15: error: unexpected in
#{fs.realpathSync tempFile}:1:15: error: unexpected in
foo in bar or in baz
^^
"""
finally
fs.unlinkSync 'test/syntax-error.coffee'
fs.unlinkSync tempFile
test "#3890 Error.prepareStackTrace doesn't throw an error if a compiled file is deleted", ->
# Adapted from https://github.com/atom/coffee-cash/blob/master/spec/coffee-cash-spec.coffee

View file

@ -585,6 +585,29 @@ test "Verify indented heredocs have the right position", ->
eq stringToken[2].last_line, 3
eq stringToken[2].last_column, 4
test "Verify heregexes with interpolations have the right ending position", ->
source = '''
[a ///#{b}///g]
'''
[..., stringEnd, comma, flagsString, regexCallEnd, regexEnd, fnCallEnd,
arrayEnd, terminator] = CoffeeScript.tokens source
eq comma[0], ','
eq arrayEnd[0], ']'
assertColumn = (token, column) ->
eq token[2].first_line, 0
eq token[2].first_column, column
eq token[2].last_line, 0
eq token[2].last_column, column
arrayEndColumn = arrayEnd[2].first_column
for token in [comma, flagsString]
assertColumn token, arrayEndColumn - 2
for token in [regexCallEnd, regexEnd, fnCallEnd]
assertColumn token, arrayEndColumn - 1
assertColumn arrayEnd, arrayEndColumn
test "Verify all tokens get a location", ->
doesNotThrow ->
tokens = CoffeeScript.tokens testScript

View file

@ -733,3 +733,19 @@ test "export an imported aliased member named default", ->
default as def
} from 'lib';"""
eq toJS(input), output
test "#4394: export shouldn't prevent variable declarations", ->
input = """
x = 1
export { x }
"""
output = """
var x;
x = 1;
export {
x
};
"""
eq toJS(input), output

View file

@ -38,3 +38,43 @@ test "operator precedence for binary ? operator", ->
eq expression.second.first.base.value, 'b'
eq expression.second.operator, '&&'
eq expression.second.second.base.value, 'c'
test "new calls have a range including the new", ->
source = '''
a = new B().c(d)
'''
block = CoffeeScript.nodes source
assertColumnRange = (node, firstColumn, lastColumn) ->
eq node.locationData.first_line, 0
eq node.locationData.first_column, firstColumn
eq node.locationData.last_line, 0
eq node.locationData.last_column, lastColumn
[assign] = block.expressions
outerCall = assign.value
innerValue = outerCall.variable
innerCall = innerValue.base
assertColumnRange assign, 0, 15
assertColumnRange outerCall, 4, 15
assertColumnRange innerValue, 4, 12
assertColumnRange innerCall, 4, 10
test "location data is properly set for nested `new`", ->
source = '''
new new A()()
'''
block = CoffeeScript.nodes source
assertColumnRange = (node, firstColumn, lastColumn) ->
eq node.locationData.first_line, 0
eq node.locationData.first_column, firstColumn
eq node.locationData.last_line, 0
eq node.locationData.last_column, lastColumn
[outerCall] = block.expressions
innerCall = outerCall.variable
assertColumnRange outerCall, 0, 12
assertColumnRange innerCall, 4, 10

View file

@ -109,4 +109,6 @@ testRepl "keeps running after runtime error", (input, output) ->
eq 'undefined', output.lastWrite()
process.on 'exit', ->
fs.unlinkSync historyFile
try
fs.unlinkSync historyFile
catch exception # Already deleted, nothing else to do.