Skip to content

Commit

Permalink
take argument labels into account when declaring members for nested d…
Browse files Browse the repository at this point in the history
…eclarations
  • Loading branch information
turbolent committed Jun 12, 2022
1 parent f4bc9b2 commit abcb205
Show file tree
Hide file tree
Showing 2 changed files with 262 additions and 0 deletions.
1 change: 1 addition & 0 deletions runtime/sema/check_composite_declaration.go
Expand Up @@ -562,6 +562,7 @@ func (checker *Checker) declareCompositeMembersAndValue(
TypeAnnotation: NewTypeAnnotation(nestedCompositeDeclarationVariable.Type),
DeclarationKind: nestedCompositeDeclarationVariable.DeclarationKind,
VariableKind: ast.VariableKindConstant,
ArgumentLabels: nestedCompositeDeclarationVariable.ArgumentLabels,
IgnoreInSerialization: true,
DocString: nestedCompositeDeclaration.DocString,
})
Expand Down
261 changes: 261 additions & 0 deletions runtime/tests/checker/invocation_test.go
Expand Up @@ -24,8 +24,11 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/onflow/cadence/runtime/ast"
"github.com/onflow/cadence/runtime/common"
"github.com/onflow/cadence/runtime/sema"
"github.com/onflow/cadence/runtime/stdlib"
"github.com/onflow/cadence/runtime/tests/utils"
)

func TestCheckInvalidFunctionCallWithTooFewArguments(t *testing.T) {
Expand Down Expand Up @@ -343,3 +346,261 @@ func TestCheckInvocationWithOnlyVarargs(t *testing.T) {

require.NoError(t, err)
}

func TestCheckArgumentLabels(t *testing.T) {

t.Parallel()

t.Run("function", func(t *testing.T) {

t.Run("", func(t *testing.T) {

t.Parallel()

_, err := ParseAndCheck(t, `
fun test(foo bar: Int, baz: String) {}
let t = test(x: 1, "2")
`)

errs := ExpectCheckerErrors(t, err, 2)

assert.IsType(t, &sema.IncorrectArgumentLabelError{}, errs[0])
assert.IsType(t, &sema.MissingArgumentLabelError{}, errs[1])
})

t.Run("imported", func(t *testing.T) {

t.Parallel()

importedChecker, err := ParseAndCheckWithOptions(t,
`
fun test(foo bar: Int, baz: String) {}
`,
ParseAndCheckOptions{
Location: utils.ImportedLocation,
},
)

require.NoError(t, err)

_, err = ParseAndCheckWithOptions(t,
`
import "imported"
let t = test(x: 1, "2")
`,
ParseAndCheckOptions{
Options: []sema.Option{
sema.WithImportHandler(
func(_ *sema.Checker, _ common.Location, _ ast.Range) (sema.Import, error) {
return sema.ElaborationImport{
Elaboration: importedChecker.Elaboration,
}, nil
},
),
},
},
)

errs := ExpectCheckerErrors(t, err, 2)

assert.IsType(t, &sema.IncorrectArgumentLabelError{}, errs[0])
assert.IsType(t, &sema.MissingArgumentLabelError{}, errs[1])
})
})

t.Run("composite function", func(t *testing.T) {

t.Run("", func(t *testing.T) {

t.Parallel()

_, err := ParseAndCheck(t, `
struct Test {
fun test(foo bar: Int, baz: String) {}
}
let t = Test().test(x: 1, "2")
`)

errs := ExpectCheckerErrors(t, err, 2)

assert.IsType(t, &sema.IncorrectArgumentLabelError{}, errs[0])
assert.IsType(t, &sema.MissingArgumentLabelError{}, errs[1])
})

t.Run("imported", func(t *testing.T) {

t.Parallel()

importedChecker, err := ParseAndCheckWithOptions(t,
`
struct Test {
fun test(foo bar: Int, baz: String) {}
}
`,
ParseAndCheckOptions{
Location: utils.ImportedLocation,
},
)

require.NoError(t, err)

_, err = ParseAndCheckWithOptions(t,
`
import "imported"
let t = Test().test(x: 1, "2")
`,
ParseAndCheckOptions{
Options: []sema.Option{
sema.WithImportHandler(
func(_ *sema.Checker, _ common.Location, _ ast.Range) (sema.Import, error) {
return sema.ElaborationImport{
Elaboration: importedChecker.Elaboration,
}, nil
},
),
},
},
)

errs := ExpectCheckerErrors(t, err, 2)

assert.IsType(t, &sema.IncorrectArgumentLabelError{}, errs[0])
assert.IsType(t, &sema.MissingArgumentLabelError{}, errs[1])
})
})

t.Run("constructor", func(t *testing.T) {

t.Run("", func(t *testing.T) {

t.Parallel()

_, err := ParseAndCheck(t, `
struct Test {
init(foo bar: Int, baz: String) {}
}
let t = Test(x: 1, "2")
`)

errs := ExpectCheckerErrors(t, err, 2)

assert.IsType(t, &sema.IncorrectArgumentLabelError{}, errs[0])
assert.IsType(t, &sema.MissingArgumentLabelError{}, errs[1])
})

t.Run("imported", func(t *testing.T) {

t.Parallel()

importedChecker, err := ParseAndCheckWithOptions(t,
`
struct Test {
init(foo bar: Int, baz: String) {}
}
`,
ParseAndCheckOptions{
Location: utils.ImportedLocation,
},
)

require.NoError(t, err)

_, err = ParseAndCheckWithOptions(t,
`
import "imported"
let t = Test(x: 1, "2")
`,
ParseAndCheckOptions{
Options: []sema.Option{
sema.WithImportHandler(
func(_ *sema.Checker, _ common.Location, _ ast.Range) (sema.Import, error) {
return sema.ElaborationImport{
Elaboration: importedChecker.Elaboration,
}, nil
},
),
},
},
)

errs := ExpectCheckerErrors(t, err, 2)

assert.IsType(t, &sema.IncorrectArgumentLabelError{}, errs[0])
assert.IsType(t, &sema.MissingArgumentLabelError{}, errs[1])
})
})

t.Run("nested constructor", func(t *testing.T) {

t.Run("", func(t *testing.T) {

t.Parallel()

_, err := ParseAndCheck(t, `
contract C {
struct S {
init(foo bar: Int, baz: String) {}
}
}
let t = C.S(x: 1, "2")
`)

errs := ExpectCheckerErrors(t, err, 2)

assert.IsType(t, &sema.IncorrectArgumentLabelError{}, errs[0])
assert.IsType(t, &sema.MissingArgumentLabelError{}, errs[1])
})

t.Run("imported", func(t *testing.T) {

t.Parallel()

importedChecker, err := ParseAndCheckWithOptions(t,
`
contract C {
struct S {
init(foo bar: Int, baz: String) {}
}
}
`,
ParseAndCheckOptions{
Location: utils.ImportedLocation,
},
)

require.NoError(t, err)

_, err = ParseAndCheckWithOptions(t,
`
import "imported"
let t = C.S(x: 1, "2")
`,
ParseAndCheckOptions{
Options: []sema.Option{
sema.WithImportHandler(
func(_ *sema.Checker, _ common.Location, _ ast.Range) (sema.Import, error) {
return sema.ElaborationImport{
Elaboration: importedChecker.Elaboration,
}, nil
},
),
},
},
)

errs := ExpectCheckerErrors(t, err, 2)

assert.IsType(t, &sema.IncorrectArgumentLabelError{}, errs[0])
assert.IsType(t, &sema.MissingArgumentLabelError{}, errs[1])
})

})
}

0 comments on commit abcb205

Please sign in to comment.