Skip to content

Commit

Permalink
[FIX!] update scope to use positions and call .type() recursively!
Browse files Browse the repository at this point in the history
this fixes the following code:
```coffee
import x from "./lib/coffeescript/index.js"
do ->
  x = 3
  x
```
  • Loading branch information
cosmicexplorer committed Nov 16, 2024
1 parent 21b1ea8 commit 81c5989
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 31 deletions.
15 changes: 8 additions & 7 deletions lib/coffeescript/nodes.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 27 additions & 12 deletions lib/coffeescript/scope.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 3 additions & 5 deletions src/nodes.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -4103,11 +4103,9 @@ exports.Code = class Code extends Base
# Compile this parameter, but if any generated variables get created
# (e.g. `ref`), shift those into the parent scope since we can’t put a
# `var` line inside a function parameter list.
scopeVariablesCount = o.scope.variables.length
signature.push param.compileToFragments(o, LEVEL_PAREN)...
if scopeVariablesCount isnt o.scope.variables.length
generatedVariables = o.scope.variables.splice scopeVariablesCount
o.scope.parent.variables.push generatedVariables...
proxyScope = Object.assign Object.create(o.scope), {delegateToParent: yes}
proxyNode = Object.assign Object.create(o), {scope: proxyScope}
signature.push param.compileToFragments(proxyNode, LEVEL_PAREN)...
signature.push @makeCode ')'
# Block comments between `)` and `->`/`=>` get output between `)` and `{`.
if @funcGlyph?.comments?
Expand Down
27 changes: 20 additions & 7 deletions src/scope.litcoffee
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,27 @@ The `@root` is the top-level **Scope** object for a given file.

@root = @parent?.root ? this
Return whether a variable was declared by the given name in exactly this scope,
without checking any parents.

hasName: (name) -> Object::hasOwnProperty.call @positions, name
Internal method to add a new variable to the scope. When `@delegateToParent`
is set, new variables are generated in the parent scope instead.

internNew: (name, type) ->
return @parent.internNew name, type if @delegateToParent
throw new Error "interned existing name '#{name}'" if @hasName name
@positions[name] = @variables.push({name, type}) - 1
Adds a new variable or overrides an existing one.

add: (name, type, immediate) ->
return @parent.add name, type, immediate if @shared and not immediate
if Object::hasOwnProperty.call @positions, name
if @hasName name
@variables[@positions[name]].type = type
else
@positions[name] = @variables.push({name, type}) - 1
@internNew name, type
When `super` is called, we need to find the name of the current method we're
in, so that we know how to invoke the same method of the parent class. This
Expand All @@ -55,14 +68,13 @@ Reserve a variable name as originating from a function parameter for this
scope. No `var` required for internal references.

parameter: (name) ->
return if @shared and @parent.check name, yes
return if @shared and @parent.check name
@add name, 'param'
Just check to see if a variable has already been declared, without reserving,
walks up to the root scope.

check: (name) ->
!!(@type(name) or @parent?.check(name))
check: (name) -> @hasName(name) or @parent?.check(name)
Generate a temporary variable name at the given index.

Expand All @@ -81,8 +93,9 @@ Generate a temporary variable name at the given index.
Gets the type of a variable.

type: (name) ->
return v.type for v in @variables when v.name is name
null
if @hasName name
@variables[@positions[name]].type
else @parent?.type name
If we need to store an intermediate result, find an available name for a
compiler-generated variable. `_var`, `_var2`, and so on...
Expand Down

0 comments on commit 81c5989

Please sign in to comment.