Skip to content

Commit

Permalink
Closes #903, thanks @davidhesselbom for the find
Browse files Browse the repository at this point in the history
  • Loading branch information
fasterthanlime committed Jul 10, 2015
1 parent 3bd3dbc commit 60d42ed
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 12 deletions.
39 changes: 28 additions & 11 deletions source/rock/middle/Scope.ooc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import structs/[ArrayList]
import VariableAccess, VariableDecl, Statement, Node, Visitor,
FunctionCall, Type, FuncType, Version, BaseType
FunctionCall, Type, FuncType, Version, BaseType, Tuple
import tinker/[Trail, Resolver, Response]
import ../frontend/[BuildParams, Token]

Expand Down Expand Up @@ -66,6 +66,19 @@ Scope: class extends Node {
candidate := list get(i)

match candidate {
// a VariableDeclTuple is like a chrysalis from which a
// beautiful pupa VariableDecl eventually emerges. While
// it's still in chrysalis form, though, we gently let
// the VariableAccess know it's not ready yet. cf. #903
case vDeclTuple: VariableDeclTuple =>
for (el in vDeclTuple tuple elements) {
match (el) {
case va: VariableAccess =>
if (va getName() == name) {
return -1
}
}
}
case vDecl: VariableDecl =>
if (vDecl name == name) {
if(cb(vDecl)) {
Expand All @@ -91,17 +104,21 @@ Scope: class extends Node {
}

resolveCall: func (call: FunctionCall, res: Resolver, trail: Trail) -> Int {
// FIXME: this is as wrong as resolveAccess, see the comments up there.

for(stat in this) {
if(stat instanceOf?(VariableDecl)) {
vDecl := stat as VariableDecl
// experimental
if((vDecl getType() instanceOf?(FuncType) || (vDecl getType() != null && vDecl type getName() == "Closure")) &&
vDecl name == call name &&
call suggest(vDecl getFunctionDecl(), res, trail)) {
break
}
match stat {
case vDecl: VariableDecl =>
// can call funcTypes (C functions) or closures (anonymous ooc functions w/context)
declType := vDecl getType()
if (declType == null) continue

funcType := declType instanceOf?(FuncType)
closureType := declType getName() == "Closure"

if((funcType || closureType) && vDecl name == call name) {
if (call suggest(vDecl getFunctionDecl(), res, trail)) {
break
}
}
}
}

Expand Down
7 changes: 6 additions & 1 deletion source/rock/middle/VariableAccess.ooc
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,12 @@ VariableAccess: class extends Expression {
suggest(isThisRef ? tDecl thisRefDecl : tDecl thisDecl)
}
}
node resolveAccess(this, res, trail)
status := node resolveAccess(this, res, trail)
if (status == -1) {
token printMessage("asked to wait while resolving access #{this}, ref = #{ref ? ref toString() : "<none>"}")
res wholeAgain(this, "asked to wait while resolving access")
return Response OK
}

if(ref) {
if(expr) {
Expand Down
23 changes: 23 additions & 0 deletions test/compiler/tuples/tuple-multidecl-precedence.ooc
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

// Test for https://github.com/fasterthanlime/rock/issues/903

use sam-assert

describe("tuple variable decls should have precedence over members", ||
bar := Foo new(1337)
expect(1337, bar xolophan)
expect(1337, bar yardenis)
)

// support code

Foo: class {
xolophan := 1
yardenis := 2
init: func (=xolophan, =yardenis)
init: func ~fromInt (input: Int) {
(xolophan, yardenis) := This makeXY(input)
init(xolophan, yardenis)
}
makeXY: static func (input: Int) -> (Int, Int) { (input, input) }
}

0 comments on commit 60d42ed

Please sign in to comment.