/* ----------------------------------------------------------------------------- Copyright 2023 Kevin P. Barry Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ----------------------------------------------------------------------------- */ // Author: Kevin P. Barry [ta0kira@gmail.com] testcase "visibility bad types" { error require "visibility" require "#x" require "Foo" } concrete Test { visibility Append<#x>, Foo } define Test { } testcase "visibility filters not checked" { compiles } concrete Test<#x> { #x requires Order<#x> visibility Test } define Test { } testcase "visibility disallows contravariant" { error require "visibility" require "#x" require "covariant" } concrete Test<#x|> { visibility #x } define Test { } testcase "visibility allows covariant" { compiles } concrete Test<|#x> { visibility #x } define Test { } testcase "visibility allowed types" { compiles } concrete Test<#x> { visibility [Int | Char], #self visibility _ visibility #x, Test<#x> } define Test { } testcase "restricted visibility not allowed for @category" { error require "visibility" require "foo" } concrete Test { visibility all @category foo () -> () } define Test { foo () { } } testcase "restricted visibility not allowed for merge" { error require "visibility" require "default" } concrete Test { defines Default visibility all @type default () -> (Test) } define Test { default () { return #self{ } } } testcase "restricted visibility not broken by internal merge" { compiles } concrete Test { visibility all @type default () -> (Test) } define Test { @type default () -> (Test) default () { return #self{ } } } testcase "restricted visibility ignored in own category" { compiles } concrete Test { visibility all @type default () -> (Test) } define Test { default () { return #self{ } } @type foo () -> () foo () { \ default() } @category bar () -> () bar () { \ Test.default() } } testcase "restricted visibility ignored in unittest" { success } unittest test { \ Test.default() } concrete Test { visibility all @type default () -> (Test) } define Test { default () { return #self{ } } } testcase "visibilty checks correct conversion direction" { compiles } @value interface Base<|#x> { } concrete Test { visibility Base @type call () -> () } define Test { call () { } } concrete Value { refines Base @type test () -> () } define Value { test () { \ Test.call() } } testcase "visibilty checked in @category function" { error require "visibility" require "call" } concrete Test { visibility Value @type call () -> () } define Test { call () { } } concrete Value { @category test () -> () } define Value { test () { \ Test.call() } } testcase "visibilty checked in @category member" { error require "visibility" require "call" } concrete Test { visibility Value @type call () -> (Int) } define Test { call () { return 1 } } concrete Value { } define Value { @category Int value <- Test.call() } testcase "visibilty checked in @category function with reset" { compiles } concrete Test { visibility Value visibility _ @type call () -> () } define Test { call () { } } concrete Value { @category test () -> () } define Value { test () { \ Test.call() } } testcase "visibility handles #self" { error require "visibility" require "Order" } concrete Test { visibility Order<#self> @type call () -> () } define Test { call () { } } concrete Value { refines Order } define Value { next () { \ Test.call() return empty } get () { return 1 } } testcase "visibility handles params" { error require "visibility" require "Append" } concrete Test<#x> { visibility Append<#x> @type call () -> () } define Test { call () { } } concrete Value { refines Append } define Value { append (_) { \ Test.call() return self } } testcase "visibilty allows any" { compiles } @value interface Base { } concrete Test { visibility String, Int, Base, Bool @type call () -> () } define Test { call () { } } concrete Value { refines Base @type test () -> () } define Value { test () { \ Test.call() } } testcase "conversion can change visibility" { success } unittest test { \ Test.test() } @value interface Base<|#x> { } concrete Value<|#x> { @type new () -> (#self) visibility Base<#x> @value call () -> () } define Value { new () { return #self{ } } call () { } } concrete Test { refines Base @type test () -> () } define Test { test () { Value value <- Value.new() \ value?Value.call() } }