SlideShare a Scribd company logo
1 of 45
Download to read offline
Писать код быстрее,
ошибаться реже
Чашников Николай
JetBrains
Nikolay.Chashnikov@jetbrains.com
Пример 1. Найди меня
public static URL getClassUrl(Class<?> aClass) {
String path = aClass.getName().replaceAll(".", "/")
+ ".class";
return aClass.getClassLoader().getResource(path);
}
Пример 2. Аннотации правят миром
@interface Anno { String value(); }
@Anno("Hello, World!")
public class HelloAnno {
public static void main(String[] args) {
System.out.println(
HelloAnno.class.getAnnotation(Anno.class).value());
}
}
Пример 3. Все писали это
public static String toString(List<String> list) {
StringBuilder buf = new StringBuilder('(');
for (int i = 0; i < list.size(); i++) {
if (i > 0) buf.append(", ");
buf.append(list.get(i));
}
return buf.append(')').toString();
}
Пример 4. Хитрый прогресс
public void showCurrentProgress(JLabel label) {
int percents = (int) Math.random()*100;
label.setText(String.format("%d%% completed...",
percents));
}
Пример 5. Геометрическая задача
public static void printInfo(Point point, Point c1, Point c2) {
int maxX = Math.max(c1.x, c2.x); int minX = Math.min(c1.x, c2.x);
int maxY = Math.max(c1.y, c2.y); int minY = Math.min(c1.y, c2.y);
int maxZ = Math.max(c1.z, c2.z); int minZ = Math.min(c1.z, c2.z);
if (minX <= point.x && point.x <= maxX
&& minY <= point.y && point.y <= maxZ &&
minZ <= point.z && point.z <= maxZ) {
System.out.println("Inside");
} else {
System.out.println("Outside");
}
}
FindBugs
● анализирует байт-код
● встраивается в процесс компиляции
● плагины для Maven, IntelliJ IDEA, Eclipse
● 400+ типов ошибок
PMD
● анализирует java код
● 270 проверок
● плагины для Maven, Eclipse
● расширяется при помощи шаблонов
PMD
Есть интересные проверки:
AvoidUsingVolatile
Use of the keyword 'volatile' is generally used to fine tune a
Java application, and therefore, requires a good expertise
of the Java Memory Model. Moreover, its range of action is
somewhat misknown. Therefore, the volatile keyword
should not be used for maintenance purpose and
portability.
Error-prone compiler
● разрабатывается в Google
● подменяет javac
● анализирует AST дерево
● находит 24 типа ошибок (и 40
экспериментальных)
● легко расширять
public class NonRuntimeAnnotation extends BugChecker {
public Description matchMethodInvocation(MethodInvocationTree tree,
VisitorState state) {
if (!methodSelect(
instanceMethod(Matchers.<ExpressionTree>isSubtypeOf(
"java.lang.Class"), "getAnnotation"))
.matches(tree, state)) {
return Description.NO_MATCH;
}
MemberSelectTree memTree = (MemberSelectTree) tree.getArguments().get(0);
TypeSymbol annotation = ASTHelpers.getSymbol(memTree.getExpression()).type.tsym;
Retention retention = ASTHelpers.getAnnotation(annotation, Retention.class);
if (retention != null && retention.value().equals(RUNTIME)) {
return Description.NO_MATCH;
}
return describeMatch(tree, SuggestedFix.replace(tree, "null"));
}
}
Error-prone compiler
Из требований к новым проверкам:
The bug pattern should have no false positives.
In essentially no cases should the detected code actually
be working as intended.
Ошибки компиляции
Исключения
Как проявляются ошибки
Неправильное поведение
Что, если хочется не только находить
ошибки по шаблонам, но и полностью
исключить возможность появления
некоторых классов ошибок?
I call it my billion-dollar mistake. It was the invention of the
null reference in 1965. ... This has led to innumerable errors,
vulnerabilities, and system crashes, which have probably
caused a billion dollars of pain and damage in the last forty
years.
Sir Charles Antony Richard Hoare
NullPointerException
Можно ли при помощи статического анализа
доказать, что в программе нет NPE?
Это непростая задача
class Address {
String city;
boolean isValid() {
return city != null;
}
void print() {
if (isValid()) {
System.out.println(city.toUpperCase());
}
}
}
http://ceylon-lang.org
В Ceylon нет NPE
void run() {
String s = null;
}
Этот код не скомпилируется: 'null' is not assignable to 'String'
Зато есть Nullable types
void run(String? s) {
if (exists s) {
//здесь s типа String
}
}
Union types
Nullable типы — частный случай union types
String? — просто сокращение для String|Null
Можно использовать List<String|Integer>
В Kotlin тоже есть Nullable types
val s: String = null //error
val p: String? = null //ok
print(p.length) //error
if (p != null) {
print(p.length) //ok
}
Object?
Object String?
String
В Java 8 появился класс Optional:
public final class Optional<T> {
public static <T> Optional<T> empty() {...}
public static <T> Optional<T> of(T value) {...}
}
Nullable types в Java
● но придётся писать Optional<? extends T>
● и делать явное преобразование T в Optional<T>
Аннотации
● появились в Java 5
○ но только на декларациях
● в Java 8 могут быть везде, где
встречаются типы:
○ List<@Nullable String>
○ @Nullable String @NonNull[]
Checker Framework
● встраивается в javac в виде annotation
processor
● обрабатывает исходный код
● поддерживает несколько проверок
● можно расширять
Nullness checker
● по умолчанию всё @NonNull, кроме
локальных переменных
○ для локальных переменных аннотации
выводятся
● для классов JDK есть готовые наборы
аннотаций
● гарантирует* отсутствие NPE, если не
выдал предупреждений
Nullness checker: инициализация
class Person {
final String name;
public Person(String name) {
PersonRegistry.register(this);
this.name = name;
}
}
Контракты для методов
public void m(@Nullable String p) {
if (p == null || p.isEmpty()) return;
System.out.println(p.endsWith("!"));
}
Контракты для методов
public void m(@Nullable String p) {
if (isEmpty(p)) return;
System.out.println(p.endsWith("!"));
}
private boolean isEmpty(@Nullable String p) {
return p == null || p.isEmpty();
}
@EnsuresNonNullIf(expression = {"#1"}, result = false)
@Nullable в IntelliJ IDEA
public void m(String unknown, @Nullable String nullable) {
String s = null;//ok
@NonNull String q = unknown;//ok
q = nullable;//warning
}
Контракты выводятся
public void m(@Nullable String p) {
if (isEmpty(p)) return;
System.out.println(p.endsWith("!"));
}
//@Contract("null->true")
private boolean isEmpty(@Nullable String p) {
return p == null || p.isEmpty();
}
Не слишком ли много аннотаций?
IntelliJ IDEA sources:
● @NotNull – 65 000
● @Nullable – 200 000
● в сумме занимают 2Mb
Аннотации помогают
● можно генерировать assertions
○ вместо Objects.requireNonNull
● ошибки проявляются раньше
● помогают читать код
Статистика по исключениям
2011 год 2012 год 2013 год 2014 год
NPE 18% 17% 15% 14%
NotNull assertion 5% 5% 6% 5%
По продуктам на базе платформы IntelliJ IDEA, показана доля среди всех
исключений.
@Tainted/@Untainted
private List<?> getPeopleByName(String name) {
return executeQuery("from people where name="
+ name);
}
private List<?> executeQuery(@Untainted String s) {
//...
}
@Tainted/@Untainted
private List<?> getPeopleByName(String name) {
return executeQuery("from people where name="
+ name);
}
private @Untainted String validate(String s) {
//@SuppressWarnings
//...
}
LockChecker
public class Node {
@GuardedBy("myLock")
List<Node> children = new ArrayList<>();
final Object myLock = new Object();
public Node add() {
Node node = new Node();
synchronized (myLock) {
children.add(node);
}
return node;
}
}
LockChecker
public class Node {
@GuardedBy("myLock")
List<Node> children = new ArrayList<>();
final Object myLock = new Object();
//...
@Holding("myLock")
private void sort() {
Collections.sort(children, ourComparator);
}
}
Что дальше?
● другие проверки в Checker Framework:
○ @SideEffectFree, @Pure
○ @Immutable, @ReadOnly
● собственные проверки
Ссылки
http://types.cs.washington.edu/checker-framework/
http://pmd.sourceforge.net/
http://findbugs.sourceforge.net/
http://code.google.com/p/error-prone/
http://ceylon-lang.org/
http://kotlinlang.org/
http://eclipse.org/
http://jetbrains.org/
Всё бесплатно и open source

More Related Content

What's hot

Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++Sergey Platonov
 
Вещи в Java, о которых вы (возможно) не знали
Вещи в Java, о которых вы (возможно) не зналиВещи в Java, о которых вы (возможно) не знали
Вещи в Java, о которых вы (возможно) не зналиZheka Kozlov
 
Unit тестирование
Unit тестированиеUnit тестирование
Unit тестированиеMaxim Volchenko
 
C++ refelection and cats
C++ refelection and catsC++ refelection and cats
C++ refelection and catscorehard_by
 
RDSDataSource: Чистые тесты на Swift
RDSDataSource: Чистые тесты на SwiftRDSDataSource: Чистые тесты на Swift
RDSDataSource: Чистые тесты на SwiftRAMBLER&Co
 
Многопоточность, работа с сетью (Lecture 12 – multithreading, network)
Многопоточность, работа с сетью (Lecture 12 – multithreading, network)Многопоточность, работа с сетью (Lecture 12 – multithreading, network)
Многопоточность, работа с сетью (Lecture 12 – multithreading, network)Noveo
 
"Внутренности" CPython, часть II
"Внутренности" CPython, часть II"Внутренности" CPython, часть II
"Внутренности" CPython, часть IIPython Meetup
 
JPoint 2015 - Javassist на службе Java-разработчика
JPoint 2015 - Javassist на службе Java-разработчикаJPoint 2015 - Javassist на службе Java-разработчика
JPoint 2015 - Javassist на службе Java-разработчикаAnton Arhipov
 
Поговорим о JavaScript, основы и современные тенденции развития языка
Поговорим о JavaScript, основы и современные тенденции развития языкаПоговорим о JavaScript, основы и современные тенденции развития языка
Поговорим о JavaScript, основы и современные тенденции развития языкаAlexander Kucherenko
 
JPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profilerJPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profilerAnton Arhipov
 
Магия в Python: Дескрипторы. Что это?
Магия в Python: Дескрипторы. Что это?Магия в Python: Дескрипторы. Что это?
Магия в Python: Дескрипторы. Что это?PyNSK
 
Easy selenium test automation on python
Easy selenium test automation on pythonEasy selenium test automation on python
Easy selenium test automation on pythonMykhailo Poliarush
 
RxJava+RxAndroid (Lecture 20 – rx java)
RxJava+RxAndroid (Lecture 20 – rx java)RxJava+RxAndroid (Lecture 20 – rx java)
RxJava+RxAndroid (Lecture 20 – rx java)Noveo
 
Oop java.generics
Oop java.genericsOop java.generics
Oop java.genericsmuqaddas_m
 
Современный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыСовременный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыcorehard_by
 
Шишки, набитые за 15 лет использования акторов в C++
Шишки, набитые за 15 лет использования акторов в C++Шишки, набитые за 15 лет использования акторов в C++
Шишки, набитые за 15 лет использования акторов в C++Yauheni Akhotnikau
 
Применение behave+webdriver для тестирования Web-проектов
Применение behave+webdriver для тестирования Web-проектовПрименение behave+webdriver для тестирования Web-проектов
Применение behave+webdriver для тестирования Web-проектовPyNSK
 
Автоматизация для ленивых тестировщиков. Selenium + Python + Behave (BDD)
Автоматизация для ленивых тестировщиков. Selenium + Python + Behave (BDD)Автоматизация для ленивых тестировщиков. Selenium + Python + Behave (BDD)
Автоматизация для ленивых тестировщиков. Selenium + Python + Behave (BDD)SQALab
 
Очередной скучный доклад про логгирование
Очередной скучный доклад про логгированиеОчередной скучный доклад про логгирование
Очередной скучный доклад про логгированиеPython Meetup
 
Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Sergey Platonov
 

What's hot (20)

Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++
 
Вещи в Java, о которых вы (возможно) не знали
Вещи в Java, о которых вы (возможно) не зналиВещи в Java, о которых вы (возможно) не знали
Вещи в Java, о которых вы (возможно) не знали
 
Unit тестирование
Unit тестированиеUnit тестирование
Unit тестирование
 
C++ refelection and cats
C++ refelection and catsC++ refelection and cats
C++ refelection and cats
 
RDSDataSource: Чистые тесты на Swift
RDSDataSource: Чистые тесты на SwiftRDSDataSource: Чистые тесты на Swift
RDSDataSource: Чистые тесты на Swift
 
Многопоточность, работа с сетью (Lecture 12 – multithreading, network)
Многопоточность, работа с сетью (Lecture 12 – multithreading, network)Многопоточность, работа с сетью (Lecture 12 – multithreading, network)
Многопоточность, работа с сетью (Lecture 12 – multithreading, network)
 
"Внутренности" CPython, часть II
"Внутренности" CPython, часть II"Внутренности" CPython, часть II
"Внутренности" CPython, часть II
 
JPoint 2015 - Javassist на службе Java-разработчика
JPoint 2015 - Javassist на службе Java-разработчикаJPoint 2015 - Javassist на службе Java-разработчика
JPoint 2015 - Javassist на службе Java-разработчика
 
Поговорим о JavaScript, основы и современные тенденции развития языка
Поговорим о JavaScript, основы и современные тенденции развития языкаПоговорим о JavaScript, основы и современные тенденции развития языка
Поговорим о JavaScript, основы и современные тенденции развития языка
 
JPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profilerJPoint 2016 - Etudes of DIY Java profiler
JPoint 2016 - Etudes of DIY Java profiler
 
Магия в Python: Дескрипторы. Что это?
Магия в Python: Дескрипторы. Что это?Магия в Python: Дескрипторы. Что это?
Магия в Python: Дескрипторы. Что это?
 
Easy selenium test automation on python
Easy selenium test automation on pythonEasy selenium test automation on python
Easy selenium test automation on python
 
RxJava+RxAndroid (Lecture 20 – rx java)
RxJava+RxAndroid (Lecture 20 – rx java)RxJava+RxAndroid (Lecture 20 – rx java)
RxJava+RxAndroid (Lecture 20 – rx java)
 
Oop java.generics
Oop java.genericsOop java.generics
Oop java.generics
 
Современный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтерыСовременный статический анализ кода: что умеет он, чего не умели линтеры
Современный статический анализ кода: что умеет он, чего не умели линтеры
 
Шишки, набитые за 15 лет использования акторов в C++
Шишки, набитые за 15 лет использования акторов в C++Шишки, набитые за 15 лет использования акторов в C++
Шишки, набитые за 15 лет использования акторов в C++
 
Применение behave+webdriver для тестирования Web-проектов
Применение behave+webdriver для тестирования Web-проектовПрименение behave+webdriver для тестирования Web-проектов
Применение behave+webdriver для тестирования Web-проектов
 
Автоматизация для ленивых тестировщиков. Selenium + Python + Behave (BDD)
Автоматизация для ленивых тестировщиков. Selenium + Python + Behave (BDD)Автоматизация для ленивых тестировщиков. Selenium + Python + Behave (BDD)
Автоматизация для ленивых тестировщиков. Selenium + Python + Behave (BDD)
 
Очередной скучный доклад про логгирование
Очередной скучный доклад про логгированиеОчередной скучный доклад про логгирование
Очередной скучный доклад про логгирование
 
Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++Александр Фокин, Рефлексия в C++
Александр Фокин, Рефлексия в C++
 

Viewers also liked

Generics Past, Present and Future
Generics Past, Present and FutureGenerics Past, Present and Future
Generics Past, Present and FutureRichardWarburton
 
JEE Conf 2015: Less JS!
JEE Conf 2015: Less JS!JEE Conf 2015: Less JS!
JEE Conf 2015: Less JS!_Dewy_
 
BIG DATA: From mammoth to elephant
BIG DATA: From mammoth to elephantBIG DATA: From mammoth to elephant
BIG DATA: From mammoth to elephantRoman Nikitchenko
 
Web application I have always dreamt of
Web application I have always dreamt ofWeb application I have always dreamt of
Web application I have always dreamt ofVictor_Cr
 
API design in java project
API design in java projectAPI design in java project
API design in java projectchashnikov
 
Plugin development for intelli j platform
Plugin development for intelli j platformPlugin development for intelli j platform
Plugin development for intelli j platformchashnikov
 
JDK: CPU, PSU, LU, FR — WTF?!
JDK: CPU, PSU, LU, FR — WTF?!JDK: CPU, PSU, LU, FR — WTF?!
JDK: CPU, PSU, LU, FR — WTF?!Alexey Fyodorov
 
Lambdas in java 8
Lambdas in java 8Lambdas in java 8
Lambdas in java 8chashnikov
 
Pragmatic functional refactoring with java 8 (1)
Pragmatic functional refactoring with java 8 (1)Pragmatic functional refactoring with java 8 (1)
Pragmatic functional refactoring with java 8 (1)RichardWarburton
 
Spring Boot. Boot up your development. JEEConf 2015
Spring Boot. Boot up your development. JEEConf 2015Spring Boot. Boot up your development. JEEConf 2015
Spring Boot. Boot up your development. JEEConf 2015Strannik_2013
 
Effective coding in IntelliJ IDEA
Effective coding in IntelliJ IDEAEffective coding in IntelliJ IDEA
Effective coding in IntelliJ IDEAchashnikov
 
Java compilers and IDEs
Java compilers and IDEsJava compilers and IDEs
Java compilers and IDEschashnikov
 
JEEConf 2015 Big Data Analysis in Java World
JEEConf 2015 Big Data Analysis in Java WorldJEEConf 2015 Big Data Analysis in Java World
JEEConf 2015 Big Data Analysis in Java WorldSerg Masyutin
 
Spring cloud for microservices architecture
Spring cloud for microservices architectureSpring cloud for microservices architecture
Spring cloud for microservices architectureIgor Khotin
 
JEEConf 2015 - Introduction to real-time big data with Apache Spark
JEEConf 2015 - Introduction to real-time big data with Apache SparkJEEConf 2015 - Introduction to real-time big data with Apache Spark
JEEConf 2015 - Introduction to real-time big data with Apache SparkTaras Matyashovsky
 

Viewers also liked (18)

Generics Past, Present and Future
Generics Past, Present and FutureGenerics Past, Present and Future
Generics Past, Present and Future
 
JEE Conf 2015: Less JS!
JEE Conf 2015: Less JS!JEE Conf 2015: Less JS!
JEE Conf 2015: Less JS!
 
BIG DATA: From mammoth to elephant
BIG DATA: From mammoth to elephantBIG DATA: From mammoth to elephant
BIG DATA: From mammoth to elephant
 
X text
X textX text
X text
 
Web application I have always dreamt of
Web application I have always dreamt ofWeb application I have always dreamt of
Web application I have always dreamt of
 
Jee conf
Jee confJee conf
Jee conf
 
API design in java project
API design in java projectAPI design in java project
API design in java project
 
Plugin development for intelli j platform
Plugin development for intelli j platformPlugin development for intelli j platform
Plugin development for intelli j platform
 
JDK: CPU, PSU, LU, FR — WTF?!
JDK: CPU, PSU, LU, FR — WTF?!JDK: CPU, PSU, LU, FR — WTF?!
JDK: CPU, PSU, LU, FR — WTF?!
 
Lambdas in java 8
Lambdas in java 8Lambdas in java 8
Lambdas in java 8
 
Pragmatic functional refactoring with java 8 (1)
Pragmatic functional refactoring with java 8 (1)Pragmatic functional refactoring with java 8 (1)
Pragmatic functional refactoring with java 8 (1)
 
Spring Boot. Boot up your development. JEEConf 2015
Spring Boot. Boot up your development. JEEConf 2015Spring Boot. Boot up your development. JEEConf 2015
Spring Boot. Boot up your development. JEEConf 2015
 
Effective coding in IntelliJ IDEA
Effective coding in IntelliJ IDEAEffective coding in IntelliJ IDEA
Effective coding in IntelliJ IDEA
 
Java compilers and IDEs
Java compilers and IDEsJava compilers and IDEs
Java compilers and IDEs
 
JEEConf 2015 Big Data Analysis in Java World
JEEConf 2015 Big Data Analysis in Java WorldJEEConf 2015 Big Data Analysis in Java World
JEEConf 2015 Big Data Analysis in Java World
 
Scala Rock-Painting
Scala Rock-PaintingScala Rock-Painting
Scala Rock-Painting
 
Spring cloud for microservices architecture
Spring cloud for microservices architectureSpring cloud for microservices architecture
Spring cloud for microservices architecture
 
JEEConf 2015 - Introduction to real-time big data with Apache Spark
JEEConf 2015 - Introduction to real-time big data with Apache SparkJEEConf 2015 - Introduction to real-time big data with Apache Spark
JEEConf 2015 - Introduction to real-time big data with Apache Spark
 

Similar to Statis code analysis

Очень вкусный фрукт Guava
Очень вкусный фрукт GuavaОчень вкусный фрукт Guava
Очень вкусный фрукт GuavaEgor Chernyshev
 
Deep Dive C# by Sergey Teplyakov
Deep Dive  C# by Sergey TeplyakovDeep Dive  C# by Sergey Teplyakov
Deep Dive C# by Sergey TeplyakovAlex Tumanoff
 
основы Java переменные, циклы
основы Java   переменные, циклыосновы Java   переменные, циклы
основы Java переменные, циклыSergey Nemchinsky
 
Discovering Lambdas in Java 8
Discovering Lambdas in Java 8Discovering Lambdas in Java 8
Discovering Lambdas in Java 8Stfalcon Meetups
 
Статический анализ: вокруг Java за 60 минут
Статический анализ: вокруг Java за 60 минутСтатический анализ: вокруг Java за 60 минут
Статический анализ: вокруг Java за 60 минутAndrey Karpov
 
Зачем нужна Scala?
Зачем нужна Scala?Зачем нужна Scala?
Зачем нужна Scala?Vasil Remeniuk
 
Объектно-Ориентированное Программирование на C++, Лекции 3 и 4
Объектно-Ориентированное Программирование на C++, Лекции  3 и 4 Объектно-Ориентированное Программирование на C++, Лекции  3 и 4
Объектно-Ориентированное Программирование на C++, Лекции 3 и 4 Dima Dzuba
 
Как программировать на JavaScript и не выстрелить себе в ногу
Как программировать на JavaScript и не выстрелить себе в ногуКак программировать на JavaScript и не выстрелить себе в ногу
Как программировать на JavaScript и не выстрелить себе в ногуAndreyGeonya
 
Programming Java - Lecture 02 - Objects - Lavrentyev Fedor
Programming Java - Lecture 02 - Objects - Lavrentyev FedorProgramming Java - Lecture 02 - Objects - Lavrentyev Fedor
Programming Java - Lecture 02 - Objects - Lavrentyev FedorFedor Lavrentyev
 
Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?Andrey Karpov
 
Всё о статическом анализе кода для Java программиста
Всё о статическом анализе кода для Java программистаВсё о статическом анализе кода для Java программиста
Всё о статическом анализе кода для Java программистаAndrey Karpov
 
9. java lecture library
9. java lecture library9. java lecture library
9. java lecture libraryMERA_school
 

Similar to Statis code analysis (20)

Очень вкусный фрукт Guava
Очень вкусный фрукт GuavaОчень вкусный фрукт Guava
Очень вкусный фрукт Guava
 
Deep Dive C# by Sergey Teplyakov
Deep Dive  C# by Sergey TeplyakovDeep Dive  C# by Sergey Teplyakov
Deep Dive C# by Sergey Teplyakov
 
C sharp deep dive
C sharp deep diveC sharp deep dive
C sharp deep dive
 
C# Deep Dive
C# Deep DiveC# Deep Dive
C# Deep Dive
 
основы Java переменные, циклы
основы Java   переменные, циклыосновы Java   переменные, циклы
основы Java переменные, циклы
 
Discovering Lambdas in Java 8
Discovering Lambdas in Java 8Discovering Lambdas in Java 8
Discovering Lambdas in Java 8
 
Discovering Lambdas (Speech)
Discovering Lambdas (Speech)Discovering Lambdas (Speech)
Discovering Lambdas (Speech)
 
Статический анализ: вокруг Java за 60 минут
Статический анализ: вокруг Java за 60 минутСтатический анализ: вокруг Java за 60 минут
Статический анализ: вокруг Java за 60 минут
 
PHP7 - что ожидать?
PHP7 - что ожидать?PHP7 - что ожидать?
PHP7 - что ожидать?
 
Рекурсия. Поиск
Рекурсия. ПоискРекурсия. Поиск
Рекурсия. Поиск
 
Зачем нужна Scala?
Зачем нужна Scala?Зачем нужна Scala?
Зачем нужна Scala?
 
Объектно-Ориентированное Программирование на C++, Лекции 3 и 4
Объектно-Ориентированное Программирование на C++, Лекции  3 и 4 Объектно-Ориентированное Программирование на C++, Лекции  3 и 4
Объектно-Ориентированное Программирование на C++, Лекции 3 и 4
 
course js day 2
course js day 2course js day 2
course js day 2
 
Как программировать на JavaScript и не выстрелить себе в ногу
Как программировать на JavaScript и не выстрелить себе в ногуКак программировать на JavaScript и не выстрелить себе в ногу
Как программировать на JavaScript и не выстрелить себе в ногу
 
Fiche Révision POO
Fiche Révision POOFiche Révision POO
Fiche Révision POO
 
Programming Java - Lecture 02 - Objects - Lavrentyev Fedor
Programming Java - Lecture 02 - Objects - Lavrentyev FedorProgramming Java - Lecture 02 - Objects - Lavrentyev Fedor
Programming Java - Lecture 02 - Objects - Lavrentyev Fedor
 
Bytecode
BytecodeBytecode
Bytecode
 
Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?
 
Всё о статическом анализе кода для Java программиста
Всё о статическом анализе кода для Java программистаВсё о статическом анализе кода для Java программиста
Всё о статическом анализе кода для Java программиста
 
9. java lecture library
9. java lecture library9. java lecture library
9. java lecture library
 

Statis code analysis

  • 1. Писать код быстрее, ошибаться реже Чашников Николай JetBrains Nikolay.Chashnikov@jetbrains.com
  • 2.
  • 3. Пример 1. Найди меня public static URL getClassUrl(Class<?> aClass) { String path = aClass.getName().replaceAll(".", "/") + ".class"; return aClass.getClassLoader().getResource(path); }
  • 4. Пример 2. Аннотации правят миром @interface Anno { String value(); } @Anno("Hello, World!") public class HelloAnno { public static void main(String[] args) { System.out.println( HelloAnno.class.getAnnotation(Anno.class).value()); } }
  • 5. Пример 3. Все писали это public static String toString(List<String> list) { StringBuilder buf = new StringBuilder('('); for (int i = 0; i < list.size(); i++) { if (i > 0) buf.append(", "); buf.append(list.get(i)); } return buf.append(')').toString(); }
  • 6. Пример 4. Хитрый прогресс public void showCurrentProgress(JLabel label) { int percents = (int) Math.random()*100; label.setText(String.format("%d%% completed...", percents)); }
  • 7. Пример 5. Геометрическая задача public static void printInfo(Point point, Point c1, Point c2) { int maxX = Math.max(c1.x, c2.x); int minX = Math.min(c1.x, c2.x); int maxY = Math.max(c1.y, c2.y); int minY = Math.min(c1.y, c2.y); int maxZ = Math.max(c1.z, c2.z); int minZ = Math.min(c1.z, c2.z); if (minX <= point.x && point.x <= maxX && minY <= point.y && point.y <= maxZ && minZ <= point.z && point.z <= maxZ) { System.out.println("Inside"); } else { System.out.println("Outside"); } }
  • 8. FindBugs ● анализирует байт-код ● встраивается в процесс компиляции ● плагины для Maven, IntelliJ IDEA, Eclipse ● 400+ типов ошибок
  • 9. PMD ● анализирует java код ● 270 проверок ● плагины для Maven, Eclipse ● расширяется при помощи шаблонов
  • 10. PMD Есть интересные проверки: AvoidUsingVolatile Use of the keyword 'volatile' is generally used to fine tune a Java application, and therefore, requires a good expertise of the Java Memory Model. Moreover, its range of action is somewhat misknown. Therefore, the volatile keyword should not be used for maintenance purpose and portability.
  • 11. Error-prone compiler ● разрабатывается в Google ● подменяет javac ● анализирует AST дерево ● находит 24 типа ошибок (и 40 экспериментальных) ● легко расширять
  • 12. public class NonRuntimeAnnotation extends BugChecker { public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) { if (!methodSelect( instanceMethod(Matchers.<ExpressionTree>isSubtypeOf( "java.lang.Class"), "getAnnotation")) .matches(tree, state)) { return Description.NO_MATCH; } MemberSelectTree memTree = (MemberSelectTree) tree.getArguments().get(0); TypeSymbol annotation = ASTHelpers.getSymbol(memTree.getExpression()).type.tsym; Retention retention = ASTHelpers.getAnnotation(annotation, Retention.class); if (retention != null && retention.value().equals(RUNTIME)) { return Description.NO_MATCH; } return describeMatch(tree, SuggestedFix.replace(tree, "null")); } }
  • 13. Error-prone compiler Из требований к новым проверкам: The bug pattern should have no false positives. In essentially no cases should the detected code actually be working as intended.
  • 14. Ошибки компиляции Исключения Как проявляются ошибки Неправильное поведение
  • 15. Что, если хочется не только находить ошибки по шаблонам, но и полностью исключить возможность появления некоторых классов ошибок?
  • 16.
  • 17.
  • 18.
  • 19. I call it my billion-dollar mistake. It was the invention of the null reference in 1965. ... This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years. Sir Charles Antony Richard Hoare
  • 20. NullPointerException Можно ли при помощи статического анализа доказать, что в программе нет NPE?
  • 21. Это непростая задача class Address { String city; boolean isValid() { return city != null; } void print() { if (isValid()) { System.out.println(city.toUpperCase()); } } }
  • 23. В Ceylon нет NPE void run() { String s = null; } Этот код не скомпилируется: 'null' is not assignable to 'String'
  • 24. Зато есть Nullable types void run(String? s) { if (exists s) { //здесь s типа String } }
  • 25. Union types Nullable типы — частный случай union types String? — просто сокращение для String|Null Можно использовать List<String|Integer>
  • 26. В Kotlin тоже есть Nullable types val s: String = null //error val p: String? = null //ok print(p.length) //error if (p != null) { print(p.length) //ok }
  • 28. В Java 8 появился класс Optional: public final class Optional<T> { public static <T> Optional<T> empty() {...} public static <T> Optional<T> of(T value) {...} } Nullable types в Java ● но придётся писать Optional<? extends T> ● и делать явное преобразование T в Optional<T>
  • 29. Аннотации ● появились в Java 5 ○ но только на декларациях ● в Java 8 могут быть везде, где встречаются типы: ○ List<@Nullable String> ○ @Nullable String @NonNull[]
  • 30. Checker Framework ● встраивается в javac в виде annotation processor ● обрабатывает исходный код ● поддерживает несколько проверок ● можно расширять
  • 31. Nullness checker ● по умолчанию всё @NonNull, кроме локальных переменных ○ для локальных переменных аннотации выводятся ● для классов JDK есть готовые наборы аннотаций ● гарантирует* отсутствие NPE, если не выдал предупреждений
  • 32. Nullness checker: инициализация class Person { final String name; public Person(String name) { PersonRegistry.register(this); this.name = name; } }
  • 33. Контракты для методов public void m(@Nullable String p) { if (p == null || p.isEmpty()) return; System.out.println(p.endsWith("!")); }
  • 34. Контракты для методов public void m(@Nullable String p) { if (isEmpty(p)) return; System.out.println(p.endsWith("!")); } private boolean isEmpty(@Nullable String p) { return p == null || p.isEmpty(); } @EnsuresNonNullIf(expression = {"#1"}, result = false)
  • 35. @Nullable в IntelliJ IDEA public void m(String unknown, @Nullable String nullable) { String s = null;//ok @NonNull String q = unknown;//ok q = nullable;//warning }
  • 36. Контракты выводятся public void m(@Nullable String p) { if (isEmpty(p)) return; System.out.println(p.endsWith("!")); } //@Contract("null->true") private boolean isEmpty(@Nullable String p) { return p == null || p.isEmpty(); }
  • 37. Не слишком ли много аннотаций? IntelliJ IDEA sources: ● @NotNull – 65 000 ● @Nullable – 200 000 ● в сумме занимают 2Mb
  • 38. Аннотации помогают ● можно генерировать assertions ○ вместо Objects.requireNonNull ● ошибки проявляются раньше ● помогают читать код
  • 39. Статистика по исключениям 2011 год 2012 год 2013 год 2014 год NPE 18% 17% 15% 14% NotNull assertion 5% 5% 6% 5% По продуктам на базе платформы IntelliJ IDEA, показана доля среди всех исключений.
  • 40. @Tainted/@Untainted private List<?> getPeopleByName(String name) { return executeQuery("from people where name=" + name); } private List<?> executeQuery(@Untainted String s) { //... }
  • 41. @Tainted/@Untainted private List<?> getPeopleByName(String name) { return executeQuery("from people where name=" + name); } private @Untainted String validate(String s) { //@SuppressWarnings //... }
  • 42. LockChecker public class Node { @GuardedBy("myLock") List<Node> children = new ArrayList<>(); final Object myLock = new Object(); public Node add() { Node node = new Node(); synchronized (myLock) { children.add(node); } return node; } }
  • 43. LockChecker public class Node { @GuardedBy("myLock") List<Node> children = new ArrayList<>(); final Object myLock = new Object(); //... @Holding("myLock") private void sort() { Collections.sort(children, ourComparator); } }
  • 44. Что дальше? ● другие проверки в Checker Framework: ○ @SideEffectFree, @Pure ○ @Immutable, @ReadOnly ● собственные проверки