Affichage des articles dont le libellé est java. Afficher tous les articles
Affichage des articles dont le libellé est java. Afficher tous les articles
4 commentaires vendredi 1 janvier 2010

Avant de commencer, bonne année 2010 à tous!

La plupart des IDEs pour Java sur le marché (dont les deux plus populaires, Eclipse et NetBeans) sont eux-mêmes écrits en Java. Cela n'est pas vraiment un problème en soit: j'utilise Eclipse pour le développement Java, et NetBeans est de facto l'IDE officiel pour le langage. De plus, écrire dans un langage avec un outil écrit dans le même langage est plutôt commun: Visual Studio est écrit en C++, et ça reste quand même un des meilleurs IDEs C++ existant.

Cherchant toujours n'importe quel prétexte pour me mettre à coder, je me suis dis qu'il serait intéressant de coder un IDE pour Java, avec la particularité qu'il serait écrit en C++. L'objectif étant d'en faire un assez rapide et prenant relativement peu de mémoire (n'importe qui utilisant Eclipse et NetBeans sait à quel point il sont lents au démarrage et qu'ils bouffent les ressources de façon assez impressionnante). Surtout que je n'ai jamais vraiment fait d'interface graphique en C++.

Les fonctionnalités prévues seraient plutôt standard: coloration syntaxique, auto-complétion, refactoring, etc. Je préfère ne pas être trop ambitieux et ne pas parler tout de suite de débogueur.

Je sais, je sais, rien de tout cela n'est facile. Mais en fait, tout ceci n'est qu'un gros prétexte pour ce qui me fascine le plus: l'auto-complétion. Cela impliquerait de construire en mémoire une représentation des classes (avec leurs méthodes et attributs) présentes dans le classpath. Lorsque l'utilisateur entrera du code et aura besoin d'aide de la part de l'IDE, on pourrait ensuite faire une recherche selon divers critères dans cette représentation et présenter les résultats au programmeur, qui n'aurait qu'à choisir l'élément le plus approprié.

Le plus difficile reste donc de construire la représentation en question. Et c'est là que ça se corse. Un compilateur Java insère des métadonnées dans le bytecode généré pour permettre certaines choses comme la réflexion. Il serait donc techniquement possible d'extraire les métadonnées du code pour construire la représentation. Sauf que ce n'est pas simple à faire. Je pourrais bien sûr exécuter javap avec les bons paramètres et ensuite analyser la sortie, mais ça me semble un peu paresseux.

En tout cas, je vais faire des recherches sur le sujet, et je vous reviens avec ce que j'ai trouvé.

1 commentaires samedi 10 octobre 2009

Dans le .NET Framework, on retrouve l'interface IEnumerable (ainsi que sa version générique, IEnumerable<T> depuis la version 2.0). Toute classe implémentant cette interface pourra être parcourue avec un foreach.

Java possède, depuis sa version 1.5, un équivalent, l'interface Iterable. Une classe implémentant Iterable pourra être parcourue avec un for.

En C#, j'ai tendance à utiliser le plus possible IEnumerable: c'est le dénominateur commun. Alors quand je me suis mis à faire du Java, j'ai décidé d'employer Iterable pour les mêmes raisons. Sauf que j'ai découvert quelque chose d'étrange.

Avec .NET, les tableaux implémentent IEnumerable. On peut donc passer un tableau à une méthode qui attend un IEnumerable en paramètre. Or, en Java, les tableaux n'implémentent pas Iterable. On peut les parcourir comme un Iterable, mais c'est probablement du à une "patch" du compilateur. Je n'ai aucune idée de pourquoi est-ce que c'est le cas, mais toujours est-il qu'on ne peut donc pas faire la même chose qu'avec .NET.

Mais ce n'est pas vraiment un problème. Il suffit de coder un adaptateur! Et c'est ce que j'ai fait:


import java.util.Iterator;
import java.util.NoSuchElementException;

/**
* Un adaptateur permettant d'utiliser un tableau là où un Iterable<T> est requis
* @author Etienne de Martel
* @param <T> Le type d'un élément du tableau
*/
public class IterableArray<T> implements Iterable<T>
{
// Un itérateur sur un tableau
private class ArrayIterator implements Iterator<T>
{
T[] _array;
int _index;

public ArrayIterator(T[] array)
{
_array = array;
_index = 0;
}

@Override
public boolean hasNext()
{
return _index < _array.length;
}

@Override
public T next()
{
if(!hasNext())
throw new NoSuchElementException();
return _array[_index++];
}

// Cet itérateur est en lecture seule
@Override
public void remove()
{
throw new UnsupportedOperationException();
}

}

private T[] _array;

/**
* Construit un nouvel adaptateur
* @param array Le tableau autour duquel l'adaptateur sera construit
* @throws NullPointerException Le tableau passé en paramêtre est null
*/
public IterableArray(T[] array) throws NullPointerException
{
if(array == null)
throw new NullPointerException("array cannot be null");
_array = array;
}

@Override
public Iterator<T> iterator()
{
return new ArrayIterator(_array);
}

}


Voilà. Have fun.