Você está na página 1de 37

Universidade Federal de Pernambuco

Centro de Informática

Graduação em Ciência da Computação

Compreendendo a Adoção da Linguagem Kotlin em Repositórios Android

Trabalho de Graduação

Aluno:​ Albertinin Mourato Santos


Orientador:​ Prof. Dr. Leopoldo Motta Teixeira

Recife
Junho, 2019
UNIVERSIDADE FEDERAL DE PERNAMBUCO
CENTRO DE INFORMÁTICA

ALBERTININ MOURATO SANTOS

COMPREENDENDO A ADOÇÃO DA LINGUAGEM KOTLIN EM REPOSITÓRIOS


ANDROID

Trabalho apresentado ao Programa de


Graduação em Ciência da Computação do
Departamento de Informática da
Universidade Federal de Pernambuco como
requisito parcial para obtenção do grau de
Bacharel em Ciência da Computação.

Orientador: Prof. Dr. Leopoldo Motta Teixeira

Recife
Junho, 2019
AGRADECIMENTOS

Agradeço, em primeiro lugar, a Deus, o criador do tempo, aquEle que


transcende qualquer entendimento humano. Aos meus pais, Gilberto e Francisca,
por nunca terem me deixado passar necessidade e sempre estarem comigo em
todos os momentos da minha vida. Nada disso seria possível sem que vocês
estivessem comigo. A minha namorada, Laís, por me mostrar que eu sou capaz, por
sonhar junto comigo e estar me mostrar que, juntos, realizaremos todos o nossos
sonhos. Agradeço, também, ao meu orientador e amigo, Dr. Leopoldo, pelos
ensinamentos e assistência dentro e fora de sala de aula. Por último e não menos
importante, agradeço a Ian, pelo apoio durante o início do curso onde enfrentei
dificuldades com lógica de programação, e aos meus amigos Eduardo, Giovanni,
Pedro, Guilherme e Nicola, que sempre estiveram presente nas aulas e fora delas
compartilhando suas vidas e momentos memoráveis.
Para os crentes, Deus está no princípio das coisas. 
Para os cientistas, no final de toda reflexão. 
- Max Planck 
RESUMO

A migração de código entre linguagens de programação tem sido um desafio à


medida que novas linguagens foram surgindo e possibilitando, aos
desenvolvedores, escrever código mais conciso, robusto e de melhor desempenho
com linguagens otimizadas. A conversão de código de uma linguagem para outra
não é só uma mudança de sintaxe, mas também na forma de se pensar com o
objetivo de utilizar as ferramentas que a linguagem alvo oferece para o
desenvolvedor. A primeira linguagem oficial para desenvolvimento de aplicações
móveis na plataforma Android foi Java. Esta continua a ser a principal linguagem
seguida da linguagem Kotlin, que foi recentemente anunciada como a linguagem
secundária. Kotlin é uma linguagem menos verbosa com uma menor quantidade de
palavras reservadas, além de ser ​null-safe e permitir interoperabilidade com Java.
Este trabalho visa entender e quantificar a adoção da linguagem Kotlin, através do
uso de seus operadores, em repositórios Android que utilizam Java como principal
linguagem. Foi feita uma análise em 3342 repositórios Git públicos hospedados na
plataforma de hospedagem e versionamento de controle, Github cujo tópico é
Android. Dentre os resultados, foi possível contabilizar o uso de alguns operadores
da linguagem Kotlin no código que foi migrado a partir de Java, bem como a
quantidade de novos repositórios que possuem somente Kotlin, Kotlin e Java e
Kotlin seguido de Java na sua lista de linguagens.

Palavras-chave​: Kotlin, java, construção, linguagem, interoperabilidade, adoção.


ABSTRACT

The code migration between programming languages has been a challenge as the
new languages have been introduced and allowing developers to write more concise
code, more robust and with a better performance with optimized languages. The
code conversion from one language to another is not only a syntax change but also
the logic way of thinking with the aim of using the tools provided by the language for
the developer. The first official language, for the development of mobile applications
on the Android platform, was Java, which continues to be the main language
followed by the Kotlin language, which was recently announced as the secondary
official language. Kotlin is a less verbose language with a smaller set of reserved
words, it is also a null-safe language that allows interoperability with Java. This work
aims to understand and quantify the adoption of the Kotlin language through its
operators usage in Android repositories that use Java as the main language and are
with public access on the hosting platform for Git repositories, Github. It was
analyzed 3342 public repositories hosted on the platform for hosting and versioning
control, Github whose topic is Android. Among the results, it was able to quantify the
usage of some language operators in the code that was migrated from Java as well
as the number of new repositories that contains only Kotlin, Kotlin and Java and
Java followed by Kotlin in their list of languages.

Keywords:​ Migration, challenge, kotlin, java, interoperability, adoption.


LISTA DE ABREVIATURAS E SIGLAS

API Application Programming Interfaces


CSV Comma-Separated Values
OS Operational System
JVM Java Virtual Machine
Q&A Question and Answer
SDK Software Development Kit
SO Stack Overflow
URL Uniform Resource Location
VSC Version System Control
XML Extensible Markup Language
PAM Possui Arquivos Migrados
NPAM Não Possui Arquivos Migrados
POK Possui Operadores Kotlin
NPOK Não​ ​Possui Arquivos Migrados
1. INTRODUÇÃO

Com a diminuição nos custos de produção de circuitos integrados, e o

crescente aumento na capacidade computacional destes, o uso de dispositivos


móveis tem se tornado cada vez mais frequente em diferentes ecossistemas. Isso
se deve ao fato de que cada vez mais, os dispositivos estão ficando menores e com
mais funcionalidades [1]. Em 2014, existiam, aproximadamente, 7,2 bilhões de
dispositivos móveis de acordo com a ​US Census Bureau [2]. Com a evolução
desses dispositivos, bem como suas aplicações, a utilização deles se tornou
bastante popular nos dias atuais. Dentre estes dispositivos, estão os ​smartphones,​
que são dispositivos móveis de telefonia, geralmente providos de diferentes
sensores que permitem a comunicação entre eles através da internet, ​bluetooth​,
NFC, entre outros.
Os dois sistemas operacionais mais utilizados em smartphones são Android e
iOS. Neste trabalho focaremos apenas na plataforma Android. Este sistema
operacional foi introduzido pela Google, em 23 de Setembro de 2008. A primeira
linguagem utilizada para desenvolvimento Android foi Java [3], ainda utilizada
atualmente. Java é uma linguagem orientada a objetos (OO), lançada em 1996, e se
tornou popular por ser uma linguagem onde o programador pode escrever um só
programa e executá-lo em diferentes tipos de dispositivos, daí veio o termo '​write
once, run anywhere'​ [4].
Dessa forma, a popularização de Java cresceu juntamente com a
popularização de smartphones, uma vez que os programadores poderiam criar
aplicações uma só vez, e rodar em diversos dispositivos que utilizassem Android
como OS. Em 2017, a Google oficializou Kotlin [5] como a segunda linguagem de
programação para desenvolvimento Android. Kotlin surgiu em 2011 mas só foi
oficializada pela Google 6 anos após seu surgimento. É uma linguagem
multi-paradigma possuindo, além do paradigma orientado à objetos, o funcional.

1.1 MOTIVAÇÃO

Linguagens de programação estão continuamente mudando para se adaptar


à novas tecnologias, para ter melhora de desempenho e, consequentemente,
permitir que dispositivos pequenos possam, cada vez mais, executarem tarefas
computacionais de alta complexibilidade, além da necessidade, dos programadores,
de possuir código de fácil entendimento e menos verboso [6]. Kotlin surgiu como
uma solução para esses requisitos no desenvolvimento Android.
No entanto, migração de código entre linguagens tem sido um desafio por
quase uma década [6], pois não é simplesmente uma mudança de sintaxe. A
migração requer, ao máximo, o mantenimento da estrutura da aplicação. Por estes e
outros motivos, a conversão de linguagem foi formulado como um dos dez
problemas mais desafiadores do próximo século [7]. Kotlin, por sua vez, é 100%
interoperável com Java, ou seja, é possível utilizar ambas as linguagens ao mesmo
tempo, em um mesmo projeto. Essa possibilidade permite que o desenvolvedor
possa migrar o seu código aos poucos, de forma concisa e sem comprometer
funcionalidades da aplicação. Além disso, Kotlin visa evitar erros do tipo
NullPointerException por meio da funcionalidade de ​Null Safety.​ Dessa forma,
a linguagem força ao programador trabalhar de forma segura com variáveis cujo
valor não pode ser nulo. Se, por acaso, um erro desse tipo ocorrer, a aplicação é
finalizada. Esta funcionalidade força o programador a estar ciente de onde valores
podem ou não serem retornados, e, por isso, usa-se o operador ​dot safe (​?.)​
quando se está trabalhando com variáveis que podem ser ​nullable.​
No contexto de Android, a migração de Java para Kotlin se tornou atrativa
devido à quantidade de funcionalidades que Kotlin introduziu, facilitando, assim, a
vida dos desenvolvedores e incrementando a performance das aplicações.
Esta pesquisa tem como motivação entender quais recursos da linguagem
Kotlin estão sendo utilizados na prática, quantificar como está sendo adotada essa
migração em repositórios de código aberto, além de entender quais impactos essa
migração tem no tamanho do código Kotlin que foi gerado imediatamente após a
mudança.

1.2 OBJETIVO

Este trabalho tem como objetivo fazer uma análise em repositórios de código
aberto que possuem arquivos que migraram de Java para Kotlin com o intuito de
entender quais estruturas da linguagem Kotlin estão sendo utilizadas nessa
migração. Além disso, será feito uma relação entre a quantidade de repositórios que
migraram arquivos de Java para Kotlin e a relação entre as perguntas relacionadas
a Kotlin na maior plataforma de Q&A para desenvolvedores de software, o Stack
Overflow [8].

Os principais pontos a serem analisados são:

● Identificar e quantificar utilização de operadores de Kotlin. São estes: ​lambda


operator (​ ​→​), ​null dereference (​ ​!!​), ​dot safe operator (​?.​), ​elvis operator (​?:​) e
range operator​ (​..​);
● Identificar e quantificar a utilização de ​companion object;​
● Identificar e quantificar a utilização das funções de escopo: ​also,​ ​apply,​ ​let,​
run​ e ​with;​
● Relacionar a quantidade de perguntas referentes à Kotlin no Stack Overflow e
a quantidade de repositórios que, entre 2014 e Março de 2019, migraram
algum arquivo de Java para Kotlin;
● Relacionar a quantidade de linhas de código que aumentou ou diminuiu com
a migração, de Java para Kotlin, dos respectivos arquivos com o tipo de
alteração que foi feita.
1.3 ORGANIZAÇÃO

Este trabalho está dividido em 5 capítulos. O capítulo 1 apresenta a


motivação e introduz o trabalho. No capítulo 2, é apresentada uma fundamentação
teórica, onde conceitos sobre as ferramentas utilizadas no desenvolvimento do
projeto são vistos. No capítulo 3, é apresentada a metodologia utilizada para
alcançar os resultados da pesquisa. No capítulo 4, são mostrado os resultados
obtidos pela análise. O capítulo 5 apresenta as conclusões que podemos retirar
baseados nos resultados que obtivemos no capítulo anterior.

2. FUNDAMENTAÇÃO TEÓRICA

O objetivo deste capítulo é fornecer uma fundamentação das ferramentas e


plataforma utilizada para a realização dessa pesquisa. A Seção 2.1 apresenta a
plataforma Android, bem como os seus componentes. A Seção 2.2 apresenta a VSC
Git. Na Seção 2.3 é apresentada a ferramenta PyDriller1 e, por fim, a Seção 2.4
apresenta a ferramenta Kastree2.

2.1 ANDROID

Android3 é um OS, desenvolvido pela Google, para dispositivos móveis. Pode


ser definido como uma pilha de ​software de código aberto para uma grande
variedade de dispositivos com diferentes formatos. Um dos seus principais
propósitos é criar uma plataforma de ​software aberto para programadores
transformarem suas ideias inovadoras em aplicações reais e introduzi-las no mundo
com o intuito de melhorar a experiência móvel de usuários.

1
"GitHub - ishepard/pydriller: Python Framework to analyse Git ...."
https://github.com/ishepard/pydriller​. Acessado em 20 mai. 2019.
2
"GitHub - cretz/kastree: Simple Kotlin Source AST and Syntax Parsing ...."
https://github.com/cretz/kastree​. Acessado em 20 mai. 2019.
3
"Set up for Android Development | Android Open Source Project." ​https://source.android.com/setup​.
Acessado em 29 mai. 2019.
4

Figura 2.1 - Pilha de componentes que formam o Android OS.


Disponível em:
https://www.embedded.com/design/prototyping-and-development/4442810/1/Porting-Android-to-the-PowerPC-ar
chitecture

Analisando a Figura 2.1 de baixo para cima, cada camada da pilha fornece
serviço para a camada seguinte, como abstração de hardware, serviço do sistema,
bibliotecas, banco de dados ​embeeded​, ​frameworks e etc. Este trabalho foca na
camada de Aplicação, a qual é utilizada pelos desenvolvedores para
desenvolvimento de aplicações.
Na camada de aplicação, existem os 4 componentes fundamentais, que são
utilizados pelos programadores, de uma aplicação Android: Activities, Broadcast
Receivers, Content Providers e Services. Será descrito, brevemente, o que cada um
desses componentes é responsável por realizar.

4
"Porting Android to the PowerPC architecture | Embedded." 4 out. 2016,
https://www.embedded.com/design/prototyping-and-development/4442810/Porting-Android-to-the-Po
werPC-architecture​. Acessado em 17 jun. 2019.
Activities representam telas de uma aplicação Android. Ela é a classe que
renderiza o código XML e controla eventos de interação com o usuário. Cada tela é
representada por uma, e somente uma, Activity.
Broadcast Receivers são responsáveis por fazer o tratamento de eventos
emitidos pelo próprio sistema ou por outras aplicações. Se assemelha ao padrão
publish ​and subscribe​, onde uma parte da aplicação se inscreve para determinado
tipo de evento, e outra parte fica responsável por lançar notificações que são
interceptadas pelos ​subscribers​.
Content Providers funcionam como uma interface entre o sistema e uma
fonte de dados. Permite que diferentes aplicações utilizem a mesma interface para
obter dados, criando, assim, uma abstração entre a camada de dados da aplicação
e o consumidor de dados.
Services são classes que possuem o papel de rodar tarefas em segundo
plano, enquanto a aplicação principal está sendo executada. São controlados pelo
SO e, eventualmente, podem ser interrompidos devido a alguma necessidade de
recursos por parte do SO.

2.2 GIT

Git é um VSC distribuído, lançado em 2005, cujo objetivo é permitir


rastreamento de mudanças no código durante o desenvolvimento de um software.
Dentre diferentes funcionalidades existem os ​commits​, que são mudanças em um
ou mais arquivos.
Github é uma plataforma ​web para hospedagem de repositórios Git. O Github
fornece uma interface visual amigável, com diversas funcionalidades para os
usuários terem fácil controle sobre seus repositórios. Foi criado com o objetivo de
facilitar o desenvolvimento de aplicações de forma colaborativa, ou seja, vários
desenvolvedores trabalhando, ao mesmo tempo, no mesmo projeto. Para este
trabalho, foi feito uma coleta de repositórios que estão hospedados no Github.
Para os fins deste trabalho, a única funcionalidade que é necessária de ser
entendida é a de ​commit5. Como mencionado no início desta seção, um ​commit a
modificação de um ou mais arquivos em um repositório. Em outras palavras, toda
vez que um usuários faz modificações em um ou mais arquivos, ele pode criar um
commit,​ através do comando ​git commit para efetivar estas alterações na aplicação
em um dado momento. Dessa forma, usuários podem voltar para um determinado
ponto na história do repositório e reverter mudanças indesejadas utilizando o ​hash
gerado por cada execução do comando..

Figura 2.2 - Grafo que representa o histórico de ​commits


Disponível em:
https://trailhead.salesforce.com/en/content/learn/modules/git-and-git-hub-basics/work-with-your-history-in-git

Na Figura 2.2, cada nó do grafo representa o estado do código do repositório


em um determinado momento, ou seja, em cada nó é a representação de um
comando ​git commit que foi executado quando o desenvolvedor desejou salvar o
estado do repositório em um dado momento. Para cada ​commit​, é gerado um ​hash
que é usado para o desenvolvedor voltar para aquele determinado ponto. Para
voltar para um determinado ponto na história de desenvolvimento, basta executar o
comando ​git reset <commit-hash> e o código será revertido. Neste estudo,
analisaremos ​commits​, em repositórios Android, para entender se houve migração
entre as linguagens alvo deste estudo.

2.3 PYDRILLER

5
"Git - git-commit Documentation - Git SCM." ​https://git-scm.com/docs/git-commit​. Acessado em 19
mai. 2019.
PyDriller é um ​framework escrito em Python, uma linguagem de alto nível que
se tornou bastante popular e de fácil entendimento, de acordo com [9]. Python tem
sido utilizada para criação de programas de alto nível, desde pequenos sistemas à
grandes plataformas. É comumente utilizada como a primeira linguagem de
programação no ensino de lógica de programação [10] devido a sua sintaxe
amigável e ser uma linguagem pouco verbosa. Este é um dos pontos fortes da
ferramenta PyDriller.
De acordo com [9], PyDriller é um ​wrapper em cima do GitPython6 uma
biblioteca para Python onde o usuário é capaz de coletar quase todas as
informações que se é possível coletar utilizando o próprio Git. A maior e principal
diferença entre PyDriller e GitPython, é que PyDriller não possui uma menor
quantidade de funcionalidade existentes no GitPython, no entanto, PyDriller fornece
somente funcionalidades que são necessárias para ​Mining software repositories
(MSR). Assim, a ferramenta esconde a complexibilidade desnecessária para o
usuário final.
Dentre os objetos fornecidos pelo ​framework​, serão mencionados somente
os que foram utilizados para o desenvolvimento dessa pesquisa. Em sua
arquitetura, PyDriller possui uma classe chamada ​RepositoryMining que recebe
como parâmetro uma lista de caminhos para o repositório Git que será utilizado.
Pode ser passado tanto o caminho de um repositório que exista numa máquina
local, quanto uma URL do Github onde o repositório encontra-se hospedado. Para
essa classe, é possível passar, como parâmetro, também, o ​hash de um ​commit
específico, no caso da análise de um só commit. Também é possível passar os
parâmetros ​since ​e ​to​, significando, respectivamente, a data inicial e a data final de
onde a análise deve ser feita. Quando é chamado o método ​traverse_commit()
da classe, é retornada a lista de ​commits que foi filtrada de acordo com os
parâmetros passados na criação da classe.
Em cada ​commit retornado pelo objeto ​RepositoryMining, todas as
informações sobre aquele ​commit está disponível para ser utilizado pelo usuário.
Estes são: autor, data, ​hash​, lista de ​parent commits​, mensagem, lista de
modificações e etc. A lista de modificações é composta de objetos que possuem os
atributos: ​Old path, New path, Change Type, Diff, Source code, Added, Removed e
Filename.​

2.4 KASTREE

Kastree é uma ferramenta escrita em Kotlin para geração de ​Abstract Syntax


Trees (AST) de código Kotlin. Árvores sintáticas abstratas são estrutura de dados
simples capazes de representar o código fonte de uma aplicação [11][12]. Em uma
AST, cada nó da árvore representa a ocorrência de uma construção da linguagem.

6
"gitpython-developers/GitPython: GitPython is a python library ... - GitHub."
https://github.com/gitpython-developers/GitPython​. Acessado em 21 mai. 2019.
Por ser uma representação de fácil entendimento, a AST procura demonstrar
apenas os detalhes estruturais de um programa, deixando de lado alguns detalhes
de sintaxe como, por exemplo, utilização de chaves para representar escopos.
A biblioteca Kastree utiliza o compilador de Kotlin para gerar a AST de um
dado código fonte. Além disso, utiliza o padrão Visitor [13], que é uma maneira de
separar um algoritmo de uma estrutura de objeto na qual ele opera [14]. Dessa
forma, cada nó da árvore é visitado é representado pela classe ​Node​. Dentre outros
tipos, esta classe pode ser do tipo ​Expr​, que significa uma expressão ou ​Decl​, que
significa uma declaração. Em ambos os casos, o nó possui um operador, chamado
oper​. No caso de uma operação binária o lado esquerdo da operação é chamado
lhs​ e o lado direito, chamado ​rhs​. Cada ambos os lados podem ser do tipo ​Node​.
Um operador representa um operador da linguagem que está sendo utilizado
no nó corrente. Nesta pesquisa, os operadores analisados foram do tipo:
Structured​, ​UnaryOperator​, ​BinaryOperator​, ​Call​, ​Token​ e ​TrailLambda​.

3. METODOLOGIA

A metodologia seguida para a realização deste trabalho pode ser dividida em


4 etapas, que são apresentadas no decorrer deste capítulo. A análise foi realizada
em repositórios Android, hospedados no Github, que estão públicos. A Seção 3.1
apresenta como a coleta de repositórios foi feita. Em seguida, mostramos na Seção
3.2 como a filtragem por linguagem foi possível. O pré-processamento dos dados é
discutido na seção 3.3. Por último, apresentamos como foram coletadas as
informaçòes de um arquivo Kotlin.

Figura 3.1 - Fluxograma do processo de desenvolvimento da pesquisa

3.1 COLETA DE REPOSITÓRIOS

Para o processo de coleta de repositórios do Github, foi utilizada a biblioteca


oficial da plataforma, a Octokit7. Um script criado na linguagem Typescript8 foi

7
"octokit/rest.js: GitHub REST API client for JavaScript - GitHub." ​https://github.com/octokit/rest.js/​.
Acessado em 1 jun. 2019.
utilizado juntamente com a API v3 do Github para realizar a consulta de repositórios,
baseado na ​string de busca e em intervalos de tempo que deveria ser feito o
matching.​
Devido à limitação da quantidade de requisições à API do Github, foi
necessária a criação de intervalos de consulta para que todos os resultados da
consulta fossem coletados. Para este trabalho, a data inicial da pesquisa foi
01/01/2014. Os intervalos de consulta foram de uma semana. Para cada consulta
semanal, foi usado 100 como o parâmetro de paginação. Entre as consultas de
paginação, foi necessário adicionar um ​sleep de três segundos também devido à
limitações da API. Quando todos os intervalos foram analisados, todos os resultados
foram concatenados e escritos em um arquivo que foi utilizado na próximas etapas.
O Octokit recebe um objeto contendo os parâmetros ​q​, ​per_page e ​page
que significam, respectivamente: ​query​, ​itens por paginação e ​índice ou ​offset de
paginação. ​A string de consulta foi ​topic:android e os intervalos de tempo
foram semanais, iniciando no dia 01/01/2014 até o dia 28/04/2019, data em que o
script foi executado. O método ​.search.repos​, do objeto Octokit, recebe a lista de
parâmetros aqui descritos e retorna a lista de repositórios que foi utilizada neste
trabalho. Os gráficos mostram dados até 31/12/2018, já que o ano de 2019 só
possui dados até o mês em que o script foi executado.
No total, 56239 repositórios foram coletados. Após a eliminação de
duplicatas, restaram 47825. As duplicatas acontecem quando os dados coletados
em um dia é contabilizado duas vezes, por exemplo, do dia um ao dia sete, e do dia
sete ao dia quatorze significa que o dia sete foi contado duas vezes criando, assim,
uma duplicatas.

3.2 FILTRO POR LINGUAGEM

Após a coleta dos 47825 repositórios Android, foi necessária a identificação


de quais eram as linguagens de cada repositório. Isso se dá ao fato de que este
estudo está interessado em repositórios cujas linguagem principal é Java, seguido
de Kotlin. Para isso, um filtro foi aplicado utilizando, novamente, o Octokit. Desta
vez, o método ​.repos.listLanguages foi utilizado. Este método retorna,
ordenadas pela quantidade de código existente, as linguagens utilizadas em um
dado repositório.
Novamente, limitações da API do Github fizeram com que as consultas
desses repositórios fossem feitas com um intervalo de tempo entre elas. Desta vez,
foram utilizadas cinco diferentes contas de acesso, cada uma com o seu ​token de
acesso. Assim, a lista de repositórios foi dividida em cinco novas listas, as quais
executaram o código de filtragem paralelamente, reduzindo, assim, em cinco vezes
a quantidade de tempo estimada caso fosse utilizada apenas uma conta de acesso.

8
"microsoft/TypeScript: TypeScript is a superset of JavaScript ... - GitHub."
https://github.com/microsoft/TypeScript​. Acessado em 1 jun. 2019.
O script para fazer as consultas das linguagens foi executado em VMs no Google
Cloud.9 O filtro de linguagem utilizado foi: possuem Java e Kotlin na lista de
linguagens e possuem majoritariamente Java seguido de Kotlin na lista de
linguagens.
Depois desta última etapa 3342 repositórios passaram pelo primeiro filtro,
significando que eles possuem Java e Kotlin na sua lista de linguagens. Já no
segundo filtro, 1070 repositórios passaram, ou seja, possuíam Java como a
linguagem com maior quantidade de código, seguido, imediatamente por Kotlin. Foi
feita uma filtragem por ano para que uma análise temporal fosse realizada ao final
da pesquisa. Desta forma, foram gerados 6 arquivos, cada um representando os
anos de 2014 até 2019. Esse subconjunto de repositórios foi utilizado para a
identificação de arquivos que mudaram de Java para Kotlin através da ferramenta
PyDriller.

3.3 MINERAÇÃO DE DADOS DOS REPOSITÓRIOS

Possuindo a URL de cada um dos 3342 repositórios, a próxima etapa da


pesquisa foi realizada utilizando um ​script escrito na linguagem Python para o
framework PyDriller. Nesse ​script​, cada repositório é clonado pelo PyDriller e, então,
é feita a análise. Em seguida, o repositório é deletado do disco rígido da máquina
onde o script foi executado.
Para identificar se um arquivo migrou de Java para Kotlin, a análise foi feita
como mostra o fluxograma da Figura 3.2 abaixo.

9
"Google Cloud Platform." ​https://cloud.google.com/?hl=pt-br​. Acessado em 29 mai. 2019.
Figura 3.2 - Fluxograma do processo de identificação de arquivos que migraram de
Java para Kotlin.

Foi utilizado o método ​traverse_commits() da classe


RepositoryMining para fazer a análise em cada um dos commits do repositório.
Para cada um desses commits, foi analisado o tipo da modificação através do
atributo ​modifications​. Neste caso, os arquivos de modificações do tipo ​ADD e
DELETE foram coletados e armazenados em diferentes listas de acordo com seu
tipo.
Na lista de arquivos deletados, foi feito um filtro que pega todos os nomes
dos arquivos ​.java através do atributo ​file_name ​do objeto modificação. De
forma semelhante, na lista de arquivos adicionados, foram pegos os nomes dos
arquivos ​.kt​. Tendo estas duas listas, para cada elemento da lista de arquivos ​.kt
adicionados, foi verificado se na lista de arquivos .java deletados, existia algum
arquivo com o mesmo nome do arquivo corrente que estava sendo analisado.
Essa comparação foi feita através do método ​.ratio()​, que utiliza o
algoritmo ​Ratcliff-Obershelp de similaridade entre strings ​[15], ​da biblioteca
SequenceMatcher.​ 10 A utilização desse algoritmo teve como justificativa o fato de
que os desenvolvedores podem renomear o nome dos arquivos e classes durante a
migração. A função ​.ratio() retorna um ​score entre 0 e 1, que representa a
similaridade entre duas strings, nesse caso, o nome do arquivo Java que foi

10
"7.4. difflib — Helpers for computing deltas — Python 2.7.16 ...."
https://docs.python.org/2/library/difflib.html​. Acessado em 1 jun. 2019.
deletado e Kotlin que foi criado. Para este estudo, consideramos que os arquivos
eram os mesmos caso a similaridade entre eles fosse de 90% ou mais.
Os arquivos Kotlin que foram analisados possuíam exatamente o mesmo
nome de um arquivo Java que foi deletado no mesmo ​commit em que ele foi criado.
Para cada repositório, foi gerada uma lista contendo o nome de todos os arquivos
que estavam presentes na lista de arquivos Kotlin que foram criados e Java que
foram deletados. O método ​.intersection foi utilizado para a pegar estes
nomes.
Durante esse processo, toda vez que um arquivo foi identificado como
arquivo que migrou de Java para Kotlin, o código adicionado naquela modificação
foi salvo e, posteriormente, escrito em um arquivo ​.kt​, pois representa o código
exato que foi criado a partir do código Java.

3.4 ANÁLISE DA AST

Uma vez que o código Kotlin estava salvo, a última etapa da análise foi
realizada com o auxílio da ferramenta Kastree. Como descrito no capítulo de
metodologia, Kastree é uma ferramenta escrita em Kotlin para a geração da AST de
um dado código Kotlin. Com a AST, é possível fazer a contagem do número de
operadores de Kotlin que estão sendo utilizados no código, após a migração. Dessa
forma, foi realizada a identificação se os desenvolvedores estão, de fato, fazendo o
uso das funcionalidades de Kotlin, ou estão apenas fazendo conversão de sintaxe.
Além de operadores da linguagem, foi possível identificar construções da linguagem
como funções de escopo e utilização da declaração estrutural ​companion object​.
Para cada arquivo, o script Kotlin foi executado e, ao final do processamento
de todos os arquivos, um arquivo CSV foi gerado contendo o número de aparições
de cada elemento da construção da linguagem, que foi utilizado logo após a
migração de código. Na última linha do CSV, a soma acumulada dos repositórios
também foi realizada. Devido à constante mudança no código dos repositórios, o
motivo de salvar o código Kotlin exatamente no momento em que houve a troca de
arquivo, se deu pelo fato de que o desenvolvedor pode continuar trabalhando na
classe, após a migração, e acompanhar esta mudança não é o objetivo desta
pesquisa. Mesmo com este cuidado, houveram casos em que o código Kotlin tinha
conteúdo além do que existia na classe Java.
A Tabela 3.1 mostra a lista de operadores utilizados para a análise deste
estudo.

Operadores

companion
!! ?. ?: .. also apply let run with
object
Tabela 3.1 - Operadores Kotlin

4. RESULTADOS

A seguir, detalhamos os resultados obtidos através da metodologia


apresentada no capítulo anterior. Na Seção 4.1, mostramos os dados comparativos,
gerais e anuais, entre repositórios Android que possuem Java e Kotlin nas suas
listas de linguagens. A Seção 4.2 apresenta os resultados relacionados ao código
Kotlin que foi desenvolvido com base em código Java que já existia.

4.1 REPOSITÓRIOS

Todos os valores mencionados tratam-se de repositórios coletados no Github


a partir de 2014 até 2018. O gráfico da Figura 4.1.1 mostra a distribuição de
repositórios que possuem como tópico Android, baseado nos filtros total (Total),
somente Java (Java), somente Kotlin (Kotlin), contém Java e Kotlin (Java e Kotlin),
contém Java ou Kotlin (Java ou Kotlin) e, por último, majoritariamente Java seguido
de Kotlin (Java > Kotlin).

Figura 4.1.1 - Distribuição de repositórios Android baseados nos filtros definidos para
a pesquisa.

Apesar de Kotlin ter se tornado uma linguagem bastante popular, os dados


mostram que apenas uma pequena parte dos repositórios Android, coletados entre
2014 e 2018, utilizam a linguagem como principal, cerca de 8,49%. Quando se trata
de repositórios Java > Kotlin, essa quantidade é ainda menor, representando
apenas 2,25% de todos os repositórios Android.
Para um melhor entendimento sobre o crescimento da linguagem Kotlin, o
gráfico da Figura 4.1.2 mostra esses valores distribuídos por anos no intervalo de
2014 a 2018. Cada ano representa a quantidade de repositórios criados cujo tema é
Android e a linguagem é Kotlin e não possui Java.

Figura 4.1.2 - Número de repositórios Android cuja linguagem é Kotlin e não possui Java.

Claramente é notado que, após o anúncio de Kotlin como linguagem oficial


para desenvolvimento Android, em 2017, o número de repositórios criados cresce
com uma diferença cada vez maior em relação ao ano anterior.
Estes dados podem ser confirmado com o gráfico da Figura 4.1.3 que mostra
como a quantidade de perguntas relacionadas a Kotlin no Stack Overflow tem
acompanhado o número de repositórios criados entre 2014 e 2018 no Github. Os
dados são cumulativos por período.
Figura 4.1.3

A seguir, as Figuras 4.1.4 e 4.1.5, mostram, respectivamente, a distribuição


de repositórios que possuem Java e Kotlin na lista de linguagens e majoritariamente
Java seguido de Kotlin. Os valores não são cumulativos.

Figura 4.1.4 - Número de repositórios Android cuja lista de linguagens possui Kotlin e Java.
Figura 4.1.5 - Número de repositórios Android cuja lista de linguagens possui
majoritariamente Java seguido de Kotlin (Java > Kotlin).

Dos 3345 repositórios cujo filtro aplicado foi Java e Kotlin, três deles não
estavam mais públicos para que a análise do código migrado fosse realizada. Desta
forma, a mineração nos ​commits do repositório foi realizada em cima de 3342
repositórios. Dos 3342, 980 repositórios possuem, pelo menos, 1 arquivo migrado
de Java para Kotlin. 26734 foi a quantidade de arquivos migrados.

A Figura ​4.1.6 mostra um comparativo entre os filtros Java > Kotlin e Java e
Kotlin que foram aplicados nos repositórios cuja lista de linguagens inclui Java e
Kotlin. Na primeira coluna, estão representados os repositórios que possuem o filtro
Java > Kotlin. Com um total de 1077 repositórios, 321 deles possuem arquivos
migrados de Java para Kotlin (PAM), representando 29,9% do total. Já dos
repositórios cujo filtro é Java e Kotlin, eliminando os itens já contabilizados na
primeira coluna, resulta em total de 2265 repositórios dos quais 658 possuem
arquivos migrados, representando 29% do total para esse filtro.
Figura 4.1.6 - Comparação entre filtros e a relação de repositórios que possuem arquivos
migrados (PAM) e que não possuem arquivos migrados (NPAM).
* Foram eliminados os repositórios contabilizados na primeira coluna, dessa forma, os
valores da segunda coluna não incluem o filtro Java > Kotlin.

Os dados da Figura 4.1.6 mostram que, de 2014 à 2018, aproximadamente


29% dos repositórios que possuem Java e Kotlin entre sua lista de linguagens,
possuem pelo menos um arquivo migrado de Java para Kotlin. Comparando as duas
primeiras colunas, onde o filtro foi Java > Kotlin, houve um leve aumento percentual
no número de repositórios que migraram de linguagem. Desta forma, a inferência de
que 29% dos repositórios que possuem Java e Kotlin na sua lista de linguagens têm
pelo menos um arquivo migrado é válida.
Também foi feita uma comparação entre repositórios que possuem Java e
Kotlin na sua lista de linguagens, e a quantidade que possui algum arquivo migrado,
por ano.
Figura 4.1.7 - Comparação entre número de repositórios criados que possuem o filtro Java e
Kotlin vs PAM em intervalos anuais.

No gráfico da Figura 4.1.7, é possível notar que, entre os anos de 2017 e


2018, o número de repositórios criados que possuem Java e Kotlin continua a
crescer, enquanto o número de repositórios criados entre esses anos começa a
diminuir. Um dos possíveis fatores que explica esse comportamento é o fato de que,
em 2017, a Google anunciou Kotlin como linguagem oficial para desenvolvimento
Android, dessa forma, novos repositórios passaram a utilizar diretamente Kotlin.
Figura 4.1.8 - Quantidade de repositórios criados por ano baseado na linguagem.

A Figura 4.1.8 mostra a quantidade de repositórios cujas linguagens eram


majoritariamente Java seguido, imediatamente, por Kotlin. O total destes
repositórios, entre 2014 e 2018, foi de 1077, dos quais 322 possuíam pelo menos
um arquivo ​.java que foi deletado no mesmo commit em que um arquivo ​.kt foi
criado com o mesmo nome. O total foi de 6863 arquivos migrados.
Nos gráficos das Figuras 4.1.7 e 4.1.8 pode-se notar um decréscimo na
quantidade de repositórios que possuem arquivos migrados no ano de 2018. O
gráfico sugere que isso seja pelo fato de que a quantidade de repositórios criados já
com Kotlin como linguagem principal, sem possuir Java, tenha sido altamente
elevada, uma vez que o crescimento foi maior que 100% entre os dois últimos anos,
como demonstrado na figura 4.1.2. É possível que nos próximos anos, a quantidade
de repositórios Android criados possuindo Java e Kotlin venha a diminuir, ao passo
que a adoção de Kotlin seja feita na criação do repositório.
Além disso, é possível que o fato de um repositório possuir Java e Kotlin
entre sua lista de linguagens, não necessariamente significa que está havendo uma
migração do código existente para Kotlin. Ao invés disso, outras novas partes do
sistema podem estar sendo desenvolvidas sem que haja necessidade de migração.
4.2 RESULTADOS DO CÓDIGO KOTLIN

A seguir, a Figura 4.2.1 mostra a quantidade de arquivos migrados para os


filtros Java e Kotlin e Java > Kotlin. No total, 24099 arquivos foram migrado de Java
para Kotlin.

Figura 4.2.1 - Número de arquivos migrados para os filtros Java > Kotlin & Java e Kotlin.
* Foram eliminados os repositórios contabilizados na primeira coluna da Figura 4.1.6, dessa
forma, os valores do filtro Java e Kotlin não incluem o filtro Java > Kotlin.

Dos 6863 migrados, cujo filtro foi Java > Kotlin, 4592 possuem a utilização
de, pelo menos, um operador dos que foram escolhidos para análise neste estudo,
173 não compilaram e 2098 não possuem nenhum dos operadores da Tabela 3.1.

Os dados sobre o número de repositórios são ilustrados na Figura 4.2.1.


Figura 4.2.2 - Utilização de operadores Kotlin em repositórios cujo filtro é Java>Kotlin

Dos 17236 arquivos migrados, cujos repositórios possuem Java e Kotlin em


qualquer ordem, com a remoção dos itens do filtro Java > Kotlin, 8897 arquivos
utilizam, pelo menos, um operador que está presente na Tabela 3.1, 560 não
compilaram e 7779 não fazem uso de qualquer operador listado na Tabela. A Figura
4.2.2 ilustra os dados.
Figura 4.2.2 - Utilização de operadores Kotlin em repositórios cujo filtro é Java e
Kotlin

A soma dos valores obtidos para cada filtro filtros mostra que 24099 arquivos
foram migrados dos quais, 13489 possuem algum operador listado na Tabela 3.1,
733 não compilaram e 9877 não utilizam quaisquer dos operadores listados na
Tabela 3.1. A Figura 4.2.3 ilustra o resultado total dos arquivos analisados.

Figura 4.2.3 - Utilização de operadores Kotlin em repositórios cujo valor é união de Java e
Kotlin com Java > Kotlin.

Foi feita uma análise em 20 arquivos selecionados aleatoriamente para


entender o motivo de não terem sido compilados. Em alguns deles, erros de sintaxe
foram encontrados, o que não permitiu ao Kastree construir corretamente a árvore
sintática para análise.
A seguir, é mostrado, no Código 4.1, um exemplo de código que o Kastree
não foi capaz de analisar. A versão corrigida do código encontra-se em:
https://github.com/HabitRPG/habitica-android/blob/develop/Habitica/src/main/java/com/habitr
pg/android/habitica/receivers/TaskReceiver.kt#L73​.

val​ notificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE) ​as
NotificationManager?
Código 4.1 - Exemplo de código cuja ferramenta Kastree não foi capaz de analisar.
Uma limitação da ferramenta de análise foi identificada ao analisar o trecho
de código descrito no Código 4.2. Devido à interoperabilidade entre Java e Kotlin,
algumas anotações de métodos devem ser feitas para que o Java entenda que, por
exemplo, um método escrito em Kotlin pode lançar uma exceção. O Kastree não é
capaz de identificar.

throws(javaClass<JSONException>())
private​ ​fun​ ​parseTags​(tags: JSONArray)​: List<String> {
​val​ results = ArrayList<String>()
​for​ (i ​in​ ​0.​.tags.length() - ​1​) {
results.add(tags.getString(i))
}
​return​ results
}

Código 4.2 - Exemplo de código cuja ferramenta Kastree não foi capaz de analisar.

Apesar de não ter sido possível analisar todos os arquivos, devido à limitação
da ferramenta Kastree, apenas três por cento dos arquivos migrados não foram
analisados.
A seguir, a Tabela 5.1 mostra a quantidade de operadores utilizados em cada
um dos filtros para 23366 arquivos, migrados de Java para Kotlin, que a ferramenta
Kastree foi capaz de realizar a análise.

Java > Kotlin Java e Kotlin* Total

!! 5537 29164 34701

→ 8827 20773 29600

?. 4065 10550 14615

companion 1510 4991 6501


object

?: 886 2959 3845

.. 200 593 793

with 463 1001 1464

apply 708 2404 3112

run 245 715 960


let 859 1690 2549

also 104 142 246

Tabela 4.2.1 - Número de operadores Kotlin nos arquivos migrados.

A seguir, alguns exemplos de código migrado sem o uso de quaisquer


operadores da Tabela 3.1 são apresentados.

package com.elmz.shelfthing.util
import​ okhttp3.MultipartBody
import​ retrofit2.Call
import​ retrofit2.http.Multipart
import​ retrofit2.http.POST
import​ retrofit2.http.Part
interface Api {
@Multipart
@POST("/status")
fun upload(@Part bytes: List<MultipartBody.Part>): Call<String>
}

Código 4.3 - Exemplo de código migrado sem que haja utilização de operadores
selecionados na Tabela 3.1.
Fonte: ​https://github.com/elmzteam/shelf-thing.git

package com.adiaz.deportesmadrid.utils
import​ java.util.Comparator
class​ ​ListItem(var name: String, var count: String)​ {
​class​ ​ListItemCompartor​ : Comparator<ListItem> {
override fun compare(item01: ListItem?, item02: ListItem?): Int {
​return​ ​if​ (item01 == null || item02 == null) {
​0
} ​else​ item01.name.compareTo(item02.name)
}
}
}

Código 4.4 - Exemplo de código migrado sem que haja utilização de operadores
selecionados na Tabela 3.1.
Fonte: ​https://github.com/AntonioDiaz/LigasMadrid_android.git

4.3 USO DO OPERADOR ​NOT EQUAL​ (​!=​)

O uso de operadores restritos de Kotlin mostra que construções da


linguagem estão sendo utilizadas na migração entre as linguagens. Porém, ainda
existem oportunidades de melhorias. A seguir, mostramos um exemplo em que
Kotlin poderia auxiliar na diminuição de código através de um de seus operadores, o
dot safe (​?.​) juntamente com o operador de ​scoping function.​
No gráfico da Figura 4.3.1, mostramos a utilização do trecho de código onde
o operador not equal (​!=​) ​do Java, ainda está sendo utilizado no código Kotlin. O
operador dot safe possui a seguinte funcionalidade: se a variável for diferente de
null, execute o que quer que que seja passado após o ponto. Em outras palavras ​if
(a != null) é o mesmo que ​a?.run​. Se for desejado executar uma operação na
própria variável, é possível chamar qualquer outra função, ao invés do ​run​.

Figura 4.3.1 - Comparação entre uso do operador ​dot safe​ e ​not equal​.

Esses valores podem revelar que o fato de Kotlin ser interoperável com Java,
permite que a forma de programar em Java continue a ser feita quando
programando em Kotlin.

4.4 QUANTIDADE DE LINHAS DE CÓDIGO

A seguir, mostramos a distribuição entre quantidade de código aumentada e


diminuída nos repositórios que possuem arquivos migrados.
Figura 4.4.1 - Número de linhas de código diminuídas versus aumentadas por repositório.

O histograma da Figura 4.4.1 mostra a quantidade de linhas de código


aumentadas ou diminuídas para repositórios cuja quantidade de arquivos
modificadas foi maior do que 0. No total, 979 repositórios possuem pelo menos um
arquivo migrado. A parte superior do gráfico representa os repositórios que tiveram
diminuição na quantidade de linhas de código, enquanto a parte inferior representa
a quantidade os repositórios que tiveram linhas de código aumentadas após a
migração. É notório que a maior parte dos repositórios tiveram diminuição em suas
linhas de código. Isso se deve ao fato de Kotlin ser uma linguagem menos verbosa
[16] e à refatoração enquanto é feito a migração.
Por outro lado, a refatoração pode ser motivo de incremento de código. No
canto direito do gráfico, é visto alguns repositórios que possuíram aumento em suas
linhas de código após a migração. Foi feito uma análise aleatória em 20 arquivos e o
resultado é que em sua maior parte, quando houve aumento de linhas de código, no
momento da migração, foi porque o código Kotlin adicionado possui mais conteúdo
do que o código Java que foi removido, isto é, o código adicionado tinha mais
funcionalidades do que o código removido. Foi identificado, também, que a maioria
dos arquivos onde este comportamento foi visto, tratava-se de classes de teste,
mostrando que foram adicionados mais testes.
5. CONCLUSÃO

Android é um SO que se popularizou e se tornou o maior sistema operacional


no mercado mobile. O fato de ser escrito em Java, permite que o SO seja rodado
em diferentes dispositivos de diferentes fabricantes devido à JVM. Java facilitou a
vida de programadores que desejavam criar aplicações para o SO Android, devido à
portabilidade e o fato de não depender do dispositivo que estava sendo executado.
Kotlin surgiu como uma linguagem moderna que fornece várias melhoria além de
suportar o paradigma funcional. Além disso, Kotlin é uma linguagem 100%
interoperável com Java, ou seja, o código de uma pode ser traduzido facilmente em
código da outra e ambas rodam na JVM.
Este estudo, que foi feito em cima de mais de 3300 repositórios que possuem
Java e Kotlin na suas listas de linguagens, mostrou que, apesar de vários
repositórios estarem utilizando Kotlin, seja através de migração ou utilização da
linguagem para desenvolvimento de outros componentes da aplicação, existem
resquícios que o código Java foi convertido para Kotlin, mas com a mentalidade da
programação em Java, deixando de ganhar em código simples e menos verboso.
Foi visto que, com o passar dos anos, a popularidade de Kotlin cresceu e isso foi
deduzido através da quantidade de repositórios criados em cada ano bem como a
quantidade de repositório que possui Java, que é mais antiga, e Kotlin.
Foi identificado, também, que quando os arquivos migrados de Java para
Kotlin possuem maior quantidade de linhas de código, significa que a migração
acrescentou mais funcionalidades ao código que já existia, pois, o fato de Kotlin ser
menos verboso, sugere que os arquivos migrados possuam uma menor quantidade
de linhas de código. Dentre os repositórios que tiveram mais linhas de código
adicionadas do que deletadas, foram encontradas várias classes de teste, o que
sugere que, durante a migração, os desenvolvedores aproveitam para adicionar
mais casos de testes aos seus sistemas.
Como trabalhos futuros, três sugestões foram coletadas durante o
desenvolvimento desta pesquisa. A primeira refere-se ao acompanhamento da
evolução do código depois da migração com o intuito de entender se a forma de
utilização da linguagem Kotlin muda com o passar do tempo. Isso pode ser feito
analisando, com detalhes, a utilização de operadores da linguagem com o objetivo
de evitar o uso de expressões como foi mencionado no caso da Figura 4.3.1. A
segunda sugestão é fazer análise da AST do código Java original, no momento em
que foi deletado e, em paralelo, da AST do código Kotlin que foi criado, não
necessariamente no mesmo ​commit​, mas que possuam os mesmos métodos.
Dessa forma, poderá ser analisado com mais profundidade partes exatas de código
que foram convertidas e, assim, fazer uma associação de quais trechos de código
combinam com quais operadores de Kotlin. Isso também permite entender os
motivos de ter, ou não, incremento de código após a migração. Por último, a
terceira sugestão é a construção de uma ferramenta de análise de AST que esteja
livre das limitações mencionadas no capítulo anterior.

6. REFERÊNCIAS BIBLIOGRÁFICAS

[1] H., Z., A., H., & M., M. (2015). Internet of Things (IoT): Definitions,
Challenges and Recent Research Directions. ​International Journal of
Computer Applications​, ​128(​ 1), 37–47.
https://doi.org/10.5120/ijca2015906430

[2] Leonid, M. (2014). The Impact Of Smartphones And Mobile Devices On


Human Health And Life. ​The Impact Of Smartphones And Mobile Devices
On Human Health And Life​, 28. Retrieved from
https://www.nyu.edu/classes/keefer/waoe/miakotkol.pdf

[3] Gosling, J., & McGilton, H. (1995). The Java language environment: a white
paper. ​Language,​ (October), 86. Retrieved from
http://www.hs-augsburg.de/informatik/projekte/mebib/emiel/entw_inf/lernpro
gramme/java/Tools/Java/Doc/Papers/langenviron.pdf

[4] Blom, S., Book, M., Gruhn, V., Hrushchak, R., & Köhler, A. (2008). Write
once, run anywhere - A survey of mobile runtime environments.
Proceedings - 3rd International Conference on Grid and Pervasive
Computing Symposia/Workshops, GPC 2008,​ (June), 132–137.
https://doi.org/10.1109/GPC.WORKSHOPS.2008.19

[5] Arockiajeyanthi, J., & Kamaleswari, T. (2017). ​KOTLIN - A New Programming


Language for the Modern Needs​. ​2(​ 12), 271–275.

[6] George, D., Girase, P., Gupta, M., Gupta, P., & Sharma, A. (2010).
Programming Language Inter-conversion. ​International Journal of Computer
Applications​, ​1​(20), 68–74. ​https://doi.org/10.5120/419-619

[7] Verhoef, C., & Terekhov, A. A. (2000). The realities of language conversions.
IEEE Software,​ ​17(​ 6), 111–124. ​https://doi.org/10.1109/52.895180

[8] Movshovitz-Attias, D., Movshovitz-Attias, Y., Steenkiste, P., & Faloutsos, C.


(2014). ​Analysis of the reputation system and user contributions on a
question answering website.​ 886–893.
https://doi.org/10.1145/2492517.2500242
[9] Spadini, D., Aniche, M., & Bacchelli, A. (2018). ​PyDriller: Python framework
for mining software repositories.​ 908–911.
https://doi.org/10.1145/3236024.3264598

[10] Dierbach, C. (2014). Python As a First Programming Language. ​Journal of


Computing Sciences in Colleges,​ ​29(​ 6), 153–154.

[11] Kim, Jaehyun & Lee, Yangsun. (2018). A Study on Abstract Syntax Tree for
Development of a JavaScript Compiler. International Journal of Grid and
Distributed Computing. 11. 37-48. 10.14257/ijgdc.2018.11.6.04.

[12] Spadini, D., Aniche, M., & Bacchelli, A. (2018). ​PyDriller: Python framework
for mining software repositories.​ 908–911.
https://doi.org/10.1145/3236024.3264598

[13] Palsberg, J., & Jay, C. B. (1998). The essence of the Visitor pattern.
Proceedings - International Computer Software and Applications
Conference,​ 9–15. ​https://doi.org/10.1109/CMPSAC.1998.716629

​ ikipedia contributors. (2019, May 12). Visitor pattern. In ​Wikipedia, The


[14] W
Free Encyclopedia​. Retrieved 03:37, June 1, 2019, from
https://en.wikipedia.org/w/index.php?title=Visitor_pattern&oldid=896701134

[15] Science, C. (2014). ​IB Extended Essay Computer Science Comparison of


Jaro-Winkler and Ratcliff / Obershelp algorithms in spell check.​ (May),
1–35.

[16] Flauzino, M., Veríssimo, J., Terra, R., Cirilo, E., Durelli, V. H. S., & Durelli,
R. S. (2018). Are you still smelling it? A comparative study between Java
and Kotlin language. ​ACM International Conference Proceeding Series​.
https://doi.org/10.1145/3267183.326718

Você também pode gostar