Статический анализатор кода для intersystems caché object script
DESCRIPTION
Статический анализатор кода для InterSystems Caché Object Script.TRANSCRIPT
coslint статическая проверка кода на COS
Caché Object Script
● Слабая динамическая типизация USER>write “22 яблока” + “3 груши” 25
● Минусы: o runtime-ошибки, которые очевидны при просмотре программы
● Плюсы: o гибкость o скорость компиляции
=====Test.test:Hello===== 3: }elseif name = "Вася" || name = "Петя" { Might be missed parentheses in name = "Вася" || name = "Петя". 6: q Quit without arguments. Method should return %Library.String. =====Test.test:test===== 3: s p.Surname = "Doe" Property Test.test:Surname is not found. 4: w p.Hello() Omitted 1 argument in call of Test.test:Hello. Expected: %Library.String.
========================================
Что можно проверить без типов
● Возможно забытые скобки: o if a = 1 || a = 2
● Выход без аргумента, хотя метод должен что-то вернуть: Method Sqr(a As %Integer) As %Integer { set res = a ** 2 quit }
Что можно проверить без типов
● Отсутствие quit (или return) вообще, если метод должен что-то вернуть
● Обращение к несуществующему классу ● Переменная не была определена перед обращением
Что можно проверить с типами
● Все-ли параметры передали в метод и не передали-ли лишних
● Передали параметр нужного типа ● Обращение к свойству/методу, которого у данного класса нет
● Вызвали метод, который возвращает %Status, но не проверили его значение
Что ещё можно проверять?
● Неиспользуемые o параметры o переменные o переменные цикла
● Переменная цикла for меняется в теле цикла.
Как узнать тип переменной? (1/3)
● переменная — аргумент метода ● set a = <expression> ● #dim a As Sample.Person ● set a = ##class(...).%New() ● set a = ##class(...).%OpenId(...) ● переменная была передана в вызов метода по ссылке
Как узнать тип переменной? (2/3)
● set $Extract(a, …) = <expr> ● set $Piece(a, …) = <expr> ● set $ListBuild(a, ...) = <list-expr> ● set $List(a, … ) = <expr> ● $Data(… , a), $Order(... , a), $Query(..., a) ● $ListNext(..., a)
Пример с $Data
If $Data(^someglobal(1), val)#10=1 { write val,! }
Как узнать тип переменной? (3/3)
● &sql (select … into :a ...) ● &sql (fetch … into :a) ● try { … } catch a { ... } ● read a ● merge a = <some-var>
%IsA
set a = somecollection.GetAt(1) if ( a.%IsA("Sample.Employee") && somecondition && (somecondition2 || somothercondition)) { //здесь a имеет тип Sample.Employee } //здесь тип a опять как у всех элементов коллекции
Опять же, не всё так просто
Method some(a As Sample.Person) { if a.%IsA(“Sample.Employee”) { set a = ##class(Sample.Company).%New() } // что мы теперь можем сказать об a? }
Наконец есть
● %objlasterror ● SQLCODE ● %request ● %response ● %session ● %page ● %application ● …
Спасибо Что ещё можно проверять?