From 4dc3e72cde6d16cd1b510978ce3d8710389ff375 Mon Sep 17 00:00:00 2001 From: Martin Monperrus Date: Sun, 24 Sep 2017 21:52:45 +0200 Subject: [PATCH 1/3] feat: add a static method to getting started with one single line of code --- README.md | 5 +++++ doc/launcher.md | 8 +++++++- src/main/java/spoon/Launcher.java | 10 ++++++++++ src/test/java/spoon/test/api/APITest.java | 10 ++++++++++ 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 97d89346eba..7104a4501c4 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,11 @@ # Spoon Spoon is an open-source library to analyze, rewrite, transform, transpile Java source code. It parses source files to build a well-designed AST with powerful analysis and transformation API. It fully supports Java 8. + +```java +CtClass l = Launcher.parseClass("class A { void m() { System.out.println(\"yeah\");} }"); +``` + External contributions as pull requests are welcome. The official website is available at . Spoon is an official Inria open-source project, and member of the [OW2](https://www.ow2.org/) open-source consortium. diff --git a/doc/launcher.md b/doc/launcher.md index 2acd0a23efa..a2f1dd2c054 100644 --- a/doc/launcher.md +++ b/doc/launcher.md @@ -6,7 +6,13 @@ keywords: usage, java ## Basic Launcher -The Spoon `Launcher` ([JavaDoc](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/Launcher.html)) is used to create the AST model of a project. +The Spoon `Launcher` ([JavaDoc](http://spoon.gforge.inria.fr/mvnsites/spoon-core/apidocs/spoon/Launcher.html)) is used to create the AST model of a project. It can be as short as: + +```java +CtClass l = Launcher.parseClass("class A { void m() { System.out.println(\"yeah\");} }"); +``` + +The Launcher is highly configurable: ```java Launcher launcher = new Launcher(); diff --git a/src/main/java/spoon/Launcher.java b/src/main/java/spoon/Launcher.java index 79fdb45abfb..9c04491ebe8 100644 --- a/src/main/java/spoon/Launcher.java +++ b/src/main/java/spoon/Launcher.java @@ -34,6 +34,7 @@ import spoon.compiler.SpoonResourceHelper; import spoon.processing.Processor; import spoon.reflect.CtModel; +import spoon.reflect.declaration.CtClass; import spoon.reflect.declaration.CtElement; import spoon.reflect.declaration.CtType; import spoon.reflect.factory.Factory; @@ -47,6 +48,7 @@ import spoon.support.StandardEnvironment; import spoon.support.compiler.FileSystemFile; import spoon.support.compiler.FileSystemFolder; +import spoon.support.compiler.VirtualFile; import spoon.support.compiler.jdt.JDTBasedSpoonCompiler; import spoon.support.gui.SpoonModelTree; @@ -798,4 +800,12 @@ public CtModel getModel() { return factory.getModel(); } + /** returns the AST of an inline class */ + public static CtClass parseClass(String code) { + Launcher launcher = new Launcher(); + launcher.addInputResource(new VirtualFile(code)); + launcher.getEnvironment().setNoClasspath(true); + launcher.getEnvironment().setAutoImports(true); + return (CtClass) launcher.buildModel().getAllTypes().stream().findFirst().get(); + } } diff --git a/src/test/java/spoon/test/api/APITest.java b/src/test/java/spoon/test/api/APITest.java index 5c835d1e7af..a350b33bec0 100644 --- a/src/test/java/spoon/test/api/APITest.java +++ b/src/test/java/spoon/test/api/APITest.java @@ -406,4 +406,14 @@ public void accept(CtVisitor visitor) { assertEquals("Check the number of if in method " + statement.getParent(CtMethod.class).getSignature() + " in the declaring class " + statement.getParent(CtType.class).getQualifiedName(),1, matcher.find(ifCondition).size()); } } + + @Test + public void testOneLinerIntro() { + // contract: spoon can be used with a single line of code with Launcher.parseClass + CtClass l = Launcher.parseClass("class A { void m() { System.out.println(\"yeah\");} }"); + assertEquals("A", l.getSimpleName()); + assertEquals(1, l.getMethods().size()); + assertEquals("m", l.getMethodsByName("m").get(0).getSimpleName()); + assertEquals("System.out.println(\"yeah\")", l.getMethodsByName("m").get(0).getBody().getStatement(0).toString()); + } } From cb56d88fc6c4a8ed8c44e0065ecd02fce23d1602 Mon Sep 17 00:00:00 2001 From: Martin Monperrus Date: Fri, 29 Sep 2017 17:32:50 +0200 Subject: [PATCH 2/3] up --- src/main/java/spoon/Launcher.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/spoon/Launcher.java b/src/main/java/spoon/Launcher.java index 9c04491ebe8..9a7f85154cd 100644 --- a/src/main/java/spoon/Launcher.java +++ b/src/main/java/spoon/Launcher.java @@ -806,6 +806,14 @@ public static CtClass parseClass(String code) { launcher.addInputResource(new VirtualFile(code)); launcher.getEnvironment().setNoClasspath(true); launcher.getEnvironment().setAutoImports(true); - return (CtClass) launcher.buildModel().getAllTypes().stream().findFirst().get(); + Collection> allTypes = launcher.buildModel().getAllTypes(); + if (allTypes.size() != 1) { + throw new SpoonException("parseClass only consider one class. Please consider using a Launcher object for more advanced usage."); + } + try { + return (CtClass) allTypes.stream().findFirst().get(); + } catch (ClassCastException e) { + throw new SpoonException("parseClass only considers classes (and not interfaces, enums). Please consider using a Launcher object for more advanced usage."); + } } } From d07387eebdfe6c9c36a76dbb69cda5be7d28c18e Mon Sep 17 00:00:00 2001 From: Martin Monperrus Date: Fri, 29 Sep 2017 17:33:05 +0200 Subject: [PATCH 3/3] up --- src/main/java/spoon/Launcher.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/spoon/Launcher.java b/src/main/java/spoon/Launcher.java index 9a7f85154cd..aa5f8f9d828 100644 --- a/src/main/java/spoon/Launcher.java +++ b/src/main/java/spoon/Launcher.java @@ -808,12 +808,12 @@ public static CtClass parseClass(String code) { launcher.getEnvironment().setAutoImports(true); Collection> allTypes = launcher.buildModel().getAllTypes(); if (allTypes.size() != 1) { - throw new SpoonException("parseClass only consider one class. Please consider using a Launcher object for more advanced usage."); + throw new SpoonException("parseClass only considers one class. Please consider using a Launcher object for more advanced usage."); } try { return (CtClass) allTypes.stream().findFirst().get(); } catch (ClassCastException e) { - throw new SpoonException("parseClass only considers classes (and not interfaces, enums). Please consider using a Launcher object for more advanced usage."); + throw new SpoonException("parseClass only considers classes (and not interfaces and enums). Please consider using a Launcher object for more advanced usage."); } } }