From b2db082f00baba22aa90a1e2fabe786dfce0240f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Galland?= Date: Sat, 14 Oct 2017 19:54:29 +0200 Subject: [PATCH] [docs] Add the missed documentation on the numbers' extension methods. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Galland --- .../DocumentationContribution.md | 9 + .../documentation/reference/bic/Schedules.md | 40 +++ .../reference/general/Extension.md | 144 +++++----- .../IActionPrototypeProvider.java | 2 +- .../io/sarl/maven/docs/parser/Messages.java | 1 + .../docs/parser/SarlDocumentationParser.java | 240 +++++++--------- .../maven/docs/parser/messages.properties | 1 + ...cumentationImplicitlyImportedFeatures.java | 1 + .../maven/docs/testing/FactExtensions.java | 2 +- .../docs/testing/MarkdownExtensions.java | 2 +- .../maven/docs/testing/ReflectExtensions.java | 264 ++++++++++++++++++ .../docs/testing/SarlScriptExecutor.java | 89 +++--- .../maven/docs/testing/ScriptExecutor.java | 49 +++- .../maven/docs/testing/ShouldExtensions.java | 2 +- 14 files changed, 584 insertions(+), 262 deletions(-) create mode 100644 main/externalmaven/io.sarl.maven.docs.testing/src/main/java/io/sarl/maven/docs/testing/ReflectExtensions.java diff --git a/docs/io.sarl.docs.markdown/src/main/documentation/DocumentationContribution.md b/docs/io.sarl.docs.markdown/src/main/documentation/DocumentationContribution.md index ac3f2b135d..99321f3614 100644 --- a/docs/io.sarl.docs.markdown/src/main/documentation/DocumentationContribution.md +++ b/docs/io.sarl.docs.markdown/src/main/documentation/DocumentationContribution.md @@ -131,6 +131,15 @@ The `Dynamic` macro is supposed to replies a value that could be interpreted as The given string of characters will replace the `Dynamic` macro into the generated Markdown text. +The replied value by `Dynamic` is assumed to be a valid Markdown text. If this value should +be automatically formatted within a block of code, you should use the following macro: + +[:ParserOff] +```text +[:DynamicCode:](expression) +``` +[:ParserOn] + ### Generate code from Java type You could generate a piece of code from a Java type with the following macro: diff --git a/docs/io.sarl.docs.markdown/src/main/documentation/reference/bic/Schedules.md b/docs/io.sarl.docs.markdown/src/main/documentation/reference/bic/Schedules.md index 448647afe3..6186c00515 100644 --- a/docs/io.sarl.docs.markdown/src/main/documentation/reference/bic/Schedules.md +++ b/docs/io.sarl.docs.markdown/src/main/documentation/reference/bic/Schedules.md @@ -8,6 +8,7 @@ The built-in capacity `[:schedules](Schedules)` enables the agent to schedule ta documented --> [:Fact:]{typeof(io.sarl.core.[:schedules!]).shouldHaveMethods( "[:task](task)(java.lang.String) : io.sarl.core.[:agenttask](AgentTask)", + "[:setname](setName)(io.sarl.core.AgentTask, java.lang.String)", "[:execute](execute)(org.eclipse.xtext.xbase.lib.Procedures$Procedure1) : io.sarl.core.AgentTask", "execute(io.sarl.core.AgentTask, org.eclipse.xtext.xbase.lib.Procedures$Procedure1) : io.sarl.core.AgentTask", "[:in](in)(io.sarl.core.AgentTask, long, org.eclipse.xtext.xbase.lib.Procedures$Procedure1) : io.sarl.core.AgentTask", @@ -58,6 +59,45 @@ Example: [:End:] +## Changing the name of a task + +A task has a name that serves as its identifier. You could change the task name by calling the following function: + + [:Success:] + package io.sarl.docs.reference.bic + import io.sarl.core.AgentTask + interface Tmp { + [:On] + def [:setname!](task : AgentTask, name : String) + [:Off] + } + [:End:] + +Example: + + [:Success:] + package io.sarl.docs.reference.bic + import io.sarl.core.Initialize + import io.sarl.core.Schedules + import io.sarl.core.AgentTask + [:On] + agent A { + uses Schedules + + var t : AgentTask + + on Initialize { + t = task("abc") + } + + def action { + this.task.setName("newName") + } + + } + [:Off] + [:End:] + ## Launching a Task for a single run For running a task once time, the following function is provided: diff --git a/docs/io.sarl.docs.markdown/src/main/documentation/reference/general/Extension.md b/docs/io.sarl.docs.markdown/src/main/documentation/reference/general/Extension.md index a60d1831ae..42a5ff7483 100644 --- a/docs/io.sarl.docs.markdown/src/main/documentation/reference/general/Extension.md +++ b/docs/io.sarl.docs.markdown/src/main/documentation/reference/general/Extension.md @@ -166,110 +166,96 @@ The extensions are described into categories. ### Collection Category -The [:arrayext:] class extends the class `Array` with the following functions: +The following functions are provided for extended the standard collection API: - [:ShowType:](org.eclipse.xtext.xbase.lib.[:arrayext]$ArrayExtensions$) - -The [:colext:] class extends the class `Collection` with the following functions: - - [:ShowType:](org.eclipse.xtext.xbase.lib.[:colext]$CollectionExtensions$) - -The [:iterext:] class extends the class `Iterable` with the following functions: - - [:ShowType:](org.eclipse.xtext.xbase.lib.[:iterext]$IterableExtensions$) - -The [:iterext2:] class extends the class `Iterator` with the following functions: - - [:ShowType:](org.eclipse.xtext.xbase.lib.[:iterext2]$IteratorExtensions$) - -The [:listext:] class extends the class `List` with the following functions: - - [:ShowType:](org.eclipse.xtext.xbase.lib.[:listext]$ListExtensions$) - -The [:mapext:] and [:sarlmapext:] classes extend the class `Map` with the following functions: - - [:ShowType:](org.eclipse.xtext.xbase.lib.[:mapext]$MapExtensions$) - - [:ShowType:](io.sarl.lang.scoping.batch.[:sarlmapext]$SARLMapExtensions$) +[:DynamicCode:]{io.sarl.maven.docs.testing.ReflectExtensions.getPublicMethods( + org.eclipse.xtext.xbase.lib.ArrayExtensions, + org.eclipse.xtext.xbase.lib.CollectionExtensions, + org.eclipse.xtext.xbase.lib.IterableExtensions, + org.eclipse.xtext.xbase.lib.IteratorExtensions, + org.eclipse.xtext.xbase.lib.ListExtensions, + org.eclipse.xtext.xbase.lib.MapExtensions, + io.sarl.lang.scoping.batch.SARLMapExtensions)} ### Number Category -The [:bdecext:] class extends the class `BigDecimal` with the following functions: - - [:ShowType:](org.eclipse.xtext.xbase.lib.[:bdecext]$BigDecimalExtensions$) - -The [:bintext:] class extends the class `BigInteger` with the following functions: - - [:ShowType:](org.eclipse.xtext.xbase.lib.[:bintext]$BigIntegerExtensions$) - -The [:byteext:] class extends the class `Byte` with the following functions: - - [:ShowType:](org.eclipse.xtext.xbase.lib.[:byteext]$ByteExtensions$) - -The [:dblext:] class extends the class `Double` with the following functions: - - [:ShowType:](org.eclipse.xtext.xbase.lib.[:dblext]$DoubleExtensions$) - -The [:fltext:] class extends the class `Float` with the following functions: - - [:ShowType:](org.eclipse.xtext.xbase.lib.[:fltext]$FloatExtensions$) - -The [:intext:] class extends the class `Integer` with the following functions: - - [:ShowType:](org.eclipse.xtext.xbase.lib.[:intext]$IntegerExtensions$) - -The [:longext:] class extends the class `Long` with the following functions: - - [:ShowType:](org.eclipse.xtext.xbase.lib.[:longext]$LongExtensions$) - -The [:shortext:] class extends the class `Short` with the following functions: - - [:ShowType:](org.eclipse.xtext.xbase.lib.[:shortext]$ShortExtensions$) +The following functions are provided for extended the standard number API: + +[:DynamicCode:]{io.sarl.maven.docs.testing.ReflectExtensions.getPublicMethods( + org.eclipse.xtext.xbase.lib.BigDecimalExtensions, + org.eclipse.xtext.xbase.lib.BigIntegerExtensions, + org.eclipse.xtext.xbase.lib.ByteExtensions, + org.eclipse.xtext.xbase.lib.DoubleExtensions, + org.eclipse.xtext.xbase.lib.FloatExtensions, + org.eclipse.xtext.xbase.lib.IntegerExtensions, + org.eclipse.xtext.xbase.lib.LongExtensions, + org.eclipse.xtext.xbase.lib.ShortExtensions, + io.sarl.lang.scoping.numbers.PrimitiveByteOperatorExtensions, + io.sarl.lang.scoping.numbers.PrimitiveIntOperatorExtensions, + io.sarl.lang.scoping.numbers.PrimitiveShortOperatorExtensions, + io.sarl.lang.scoping.numbers.PrimitiveDoubleOperatorExtensions, + io.sarl.lang.scoping.numbers.PrimitiveFloatOperatorExtensions, + io.sarl.lang.scoping.numbers.PrimitiveLongOperatorExtensions, + io.sarl.lang.scoping.numbers.IntegerOperatorExtensions, + io.sarl.lang.scoping.numbers.ShortOperatorExtensions, + io.sarl.lang.scoping.numbers.DoubleOperatorExtensions, + io.sarl.lang.scoping.numbers.FloatOperatorExtensions, + io.sarl.lang.scoping.numbers.ByteOperatorExtensions, + io.sarl.lang.scoping.numbers.LongOperatorExtensions, + io.sarl.lang.scoping.numbers.AtomicLongOperatorExtensions, + io.sarl.lang.scoping.numbers.AtomicIntegerOperatorExtensions, + io.sarl.lang.scoping.numbers.NumberOperatorExtensions, + io.sarl.lang.scoping.numbers.IntegerCastExtensions, + io.sarl.lang.scoping.numbers.PrimitiveShortCastExtensions, + io.sarl.lang.scoping.numbers.AtomicLongCastExtensions, + io.sarl.lang.scoping.numbers.LongCastExtensions, + io.sarl.lang.scoping.numbers.AtomicIntegerCastExtensions, + io.sarl.lang.scoping.numbers.PrimitiveByteCastExtensions, + io.sarl.lang.scoping.numbers.PrimitiveDoubleCastExtensions, + io.sarl.lang.scoping.numbers.ShortCastExtensions, + io.sarl.lang.scoping.numbers.ByteCastExtensions, + io.sarl.lang.scoping.numbers.PrimitiveFloatCastExtensions, + io.sarl.lang.scoping.numbers.FloatCastExtensions, + io.sarl.lang.scoping.numbers.DoubleCastExtensions, + io.sarl.lang.scoping.numbers.PrimitiveLongCastExtensions, + io.sarl.lang.scoping.numbers.PrimitiveIntCastExtensions)} ### Primitive Type Category -The [:boolext:] class extends the class `Boolean` with the following functions: +The following functions are provided for extended the standard primitive type API: - [:ShowType:](org.eclipse.xtext.xbase.lib.[:boolext]$BooleanExtensions$) - -The [:charext:] class extends the class `Character` with the following functions: - - [:ShowType:](org.eclipse.xtext.xbase.lib.[:charext]$CharacterExtensions$) +[:DynamicCode:]{io.sarl.maven.docs.testing.ReflectExtensions.getPublicMethods( + org.eclipse.xtext.xbase.lib.BooleanExtensions, + org.eclipse.xtext.xbase.lib.CharacterExtensions)} ### Object Type Category -The [:compext:] class extends the class `Comparable` with the following functions: - - [:ShowType:](org.eclipse.xtext.xbase.lib.[:compext]$ComparableExtensions$) - -The [:objext:] class extends the class `Object` with the following functions: +The following functions are provided for extended the Object types: - [:ShowType:](org.eclipse.xtext.xbase.lib.[:objext]$ObjectExtensions$) - -The [:strext:] class extends the class `String` with the following functions: - - [:ShowType:](org.eclipse.xtext.xbase.lib.[:strext]$StringExtensions$) +[:DynamicCode:]{io.sarl.maven.docs.testing.ReflectExtensions.getPublicMethods( + org.eclipse.xtext.xbase.lib.ComparableExtensions, + org.eclipse.xtext.xbase.lib.ObjectExtensions, + org.eclipse.xtext.xbase.lib.StringExtensions)} ### Functions and Procedure Category -The [:funcext:] class extends the function type with the following functions: - - [:ShowType:](org.eclipse.xtext.xbase.lib.[:funcext]$FunctionExtensions$) - -The [:procext:] class extends the procedure type with the following functions: +The following functions are provided for extended the standard Lambda expression API: - [:ShowType:](org.eclipse.xtext.xbase.lib.[:procext]$ProcedureExtensions$) +[:DynamicCode:]{io.sarl.maven.docs.testing.ReflectExtensions.getPublicMethods( + org.eclipse.xtext.xbase.lib.FunctionExtensions, + org.eclipse.xtext.xbase.lib.ProcedureExtensions)} ### Time Category -The [:timeext:] class extends the number classes with the following time-based functions: +The following functions are provided for extended the standard time API: - [:ShowType:](io.sarl.lang.scoping.batch.[:timeext]$SARLTimeExtensions$) +[:DynamicCode:]{io.sarl.maven.docs.testing.ReflectExtensions.getPublicMethods( + io.sarl.lang.scoping.batch.SARLTimeExtensions)} diff --git a/main/coreplugins/io.sarl.lang/src/io/sarl/lang/sarl/actionprototype/IActionPrototypeProvider.java b/main/coreplugins/io.sarl.lang/src/io/sarl/lang/sarl/actionprototype/IActionPrototypeProvider.java index 5d4fb31a29..454cd3d7de 100644 --- a/main/coreplugins/io.sarl.lang/src/io/sarl/lang/sarl/actionprototype/IActionPrototypeProvider.java +++ b/main/coreplugins/io.sarl.lang/src/io/sarl/lang/sarl/actionprototype/IActionPrototypeProvider.java @@ -175,7 +175,7 @@ InferredPrototype createPrototypeFromSarlModel(QualifiedActionName id, boolean i */ String toJavaArgument(String callerQualifiedName, String argumentSpecification); - /** Replies the default value of the formal parameter at the given position. + /** Replies the default value of the given formal parameter. * *

This function replies the string representation of the default value. * diff --git a/main/externalmaven/io.sarl.maven.docs.generator/src/main/java/io/sarl/maven/docs/parser/Messages.java b/main/externalmaven/io.sarl.maven.docs.generator/src/main/java/io/sarl/maven/docs/parser/Messages.java index d11a98883d..e6bb5f8d80 100644 --- a/main/externalmaven/io.sarl.maven.docs.generator/src/main/java/io/sarl/maven/docs/parser/Messages.java +++ b/main/externalmaven/io.sarl.maven.docs.generator/src/main/java/io/sarl/maven/docs/parser/Messages.java @@ -40,6 +40,7 @@ public class Messages extends NLS { public static String SarlDocumentationParser_3; public static String SarlDocumentationParser_4; public static String SarlDocumentationParser_5; + public static String SarlDocumentationParser_6; public static String DynamicValidationContext_0; public static String DynamicValidationContext_1; public static String InvalidAnchorLabelException_0; diff --git a/main/externalmaven/io.sarl.maven.docs.generator/src/main/java/io/sarl/maven/docs/parser/SarlDocumentationParser.java b/main/externalmaven/io.sarl.maven.docs.generator/src/main/java/io/sarl/maven/docs/parser/SarlDocumentationParser.java index 46f423aefc..c59cf42c96 100644 --- a/main/externalmaven/io.sarl.maven.docs.generator/src/main/java/io/sarl/maven/docs/parser/SarlDocumentationParser.java +++ b/main/externalmaven/io.sarl.maven.docs.generator/src/main/java/io/sarl/maven/docs/parser/SarlDocumentationParser.java @@ -27,12 +27,6 @@ import java.io.IOException; import java.io.Reader; import java.lang.ref.WeakReference; -import java.lang.reflect.GenericArrayType; -import java.lang.reflect.Method; -import java.lang.reflect.Parameter; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.lang.reflect.WildcardType; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collection; @@ -57,18 +51,13 @@ import org.apache.commons.lang3.tuple.MutableTriple; import org.arakhne.afc.vmutil.FileSystem; import org.arakhne.afc.vmutil.ReflectionUtil; -import org.eclipse.jdt.core.Flags; import org.eclipse.xtext.Constants; -import org.eclipse.xtext.xbase.lib.Functions; import org.eclipse.xtext.xbase.lib.Functions.Function2; -import org.eclipse.xtext.xbase.lib.Procedures; import org.eclipse.xtext.xbase.lib.Procedures.Procedure1; -import io.sarl.lang.annotation.DefaultValue; -import io.sarl.lang.annotation.SyntheticMember; import io.sarl.lang.sarl.actionprototype.IActionPrototypeProvider; import io.sarl.lang.util.OutParameter; -import io.sarl.lang.util.Utils; +import io.sarl.maven.docs.testing.ReflectExtensions; import io.sarl.maven.docs.testing.ScriptExecutor; /** Generator of the marker language files for the modified marker language for SARL. @@ -930,7 +919,12 @@ protected boolean parse(ParsingContext context) { blockContent = null; } specialTagFound = true; - context.getParserInterceptor().tag(context, tag, tagDynamicName, parameterValue, blockContent); + try { + context.getParserInterceptor().tag(context, tag, tagDynamicName, parameterValue, blockContent); + } catch (Throwable exception) { + reportError(context, Messages.SarlDocumentationParser_6, tagName, exception); + return false; + } } else { // Ignore the tag for this stage. } @@ -960,15 +954,23 @@ protected boolean parse(ParsingContext context) { * the filename. The second argument is the line number. The third argument is the position in the file. * @param parameter additional parameter, starting at {4}. */ - protected static void reportError(ParsingContext context, String message, Object parameter) { + protected static void reportError(ParsingContext context, String message, Object... parameter) { final File file = context.getCurrentFile(); final int offset = context.getMatcher().start() + context.getStartIndex(); final int lineno = context.getLineNo(); Throwable cause = null; - if (parameter instanceof Throwable) { - cause = (Throwable) parameter; - } - final String msg = MessageFormat.format(message, file, lineno, offset, parameter); + for (final Object param : parameter) { + if (param instanceof Throwable) { + cause = (Throwable) param; + break; + } + } + final Object[] args = new Object[parameter.length + 3]; + args[0] = file; + args[1] = lineno; + args[2] = offset; + System.arraycopy(parameter, 0, args, 3, parameter.length); + final String msg = MessageFormat.format(message, args); if (cause != null) { throw new ParsingException(msg, file, lineno, cause); } @@ -2131,6 +2133,74 @@ public boolean isInternalTextAsBlockContent() { } }, + /** {@code [:DynamicCode:](code)} returns the text to put in the documentation text within a code block. + * + * @since 0.7 + */ + DYNAMIC_CODE { + @Override + public String getDefaultPattern() { + return DEFAULT_DYNAMIC_CODE_PATTERN; + } + + @Override + public boolean hasDynamicName() { + return false; + } + + @Override + public boolean hasParameter() { + return true; + } + + @Override + public boolean isOpeningTag() { + return false; + } + + @Override + public String passThrough(ParsingContext context, String dynamicTag, String parameter, String blockValue) { + if (context.isInBlock()) { + reportError(context, Messages.SarlDocumentationParser_5, name()); + return null; + } + String code = blockValue; + if (Strings.isNullOrEmpty(code)) { + code = parameter; + } + if (!Strings.isNullOrEmpty(code)) { + final ScriptExecutor executor = context.getScriptExecutor(); + if (executor != null) { + try { + final Object result = executor.execute(context.getLineNo(), code); + if (result != null) { + final String stringResult = Strings.nullToEmpty(Objects.toString(result)); + return formatBlockText(stringResult, context.getOutputLanguage(), context.getBlockCodeFormat()); + } + } catch (Exception exception) { + Throwables.propagate(exception); + } + } + } + return ""; //$NON-NLS-1$ + } + + @Override + public boolean isActive(ParsingContext context) { + return context.isParsing() && context.getStage() == Stage.FIRST; + } + + @Override + public boolean isEnclosingSpaceCouldRemovable() { + return false; + } + + @Override + public boolean isInternalTextAsBlockContent() { + return true; + } + }, + /** {@code [:On]} switches on the output of the code. */ ON { @@ -2402,25 +2472,25 @@ public String passThrough(ParsingContext context, String dynamicTag, String para } final String block; if (javaType.isInterface()) { - block = extractInterface(context, javaType); + block = extractInterface(javaType); } else if (javaType.isEnum()) { block = extractEnumeration(javaType); } else if (javaType.isAnnotation()) { - block = extractAnnotation(context, javaType); + block = extractAnnotation(javaType); } else { - block = extractClass(context, javaType); + block = extractClass(javaType); } return formatBlockText(block, context.getOutputLanguage(), context.getBlockCodeFormat()); } - private String extractInterface(ParsingContext context, Class type) { + private String extractInterface(Class type) { final StringBuilder it = new StringBuilder(); it.append("interface ").append(type.getSimpleName()); //$NON-NLS-1$ if (type.getSuperclass() != null && !Object.class.equals(type.getSuperclass())) { it.append(" extends ").append(type.getSuperclass().getSimpleName()); //$NON-NLS-1$ } it.append(" {\n"); //$NON-NLS-1$ - extractPublicMethods(context, it, type); + ReflectExtensions.appendPublicMethods(it, true, type); it.append("}"); //$NON-NLS-1$ return it.toString(); } @@ -2436,16 +2506,16 @@ private String extractEnumeration(Class type) { return it.toString(); } - private String extractAnnotation(ParsingContext context, Class type) { + private String extractAnnotation(Class type) { final StringBuilder it = new StringBuilder(); it.append("interface ").append(type.getSimpleName()); //$NON-NLS-1$ it.append(" {\n"); //$NON-NLS-1$ - extractPublicMethods(context, it, type); + ReflectExtensions.appendPublicMethods(it, true, type); it.append("}"); //$NON-NLS-1$ return it.toString(); } - private String extractClass(ParsingContext context, Class type) { + private String extractClass(Class type) { final StringBuilder it = new StringBuilder(); it.append("interface ").append(type.getSimpleName()); //$NON-NLS-1$ if (type.getSuperclass() != null && !Object.class.equals(type.getSuperclass())) { @@ -2469,121 +2539,11 @@ private String extractClass(ParsingContext context, Class type) { } } it.append(" {\n"); //$NON-NLS-1$ - extractPublicMethods(context, it, type); + ReflectExtensions.appendPublicMethods(it, true, type); it.append("}"); //$NON-NLS-1$ return it.toString(); } - private boolean isDeprecated(Method method) { - return Flags.isDeprecated(method.getModifiers()) || method.getAnnotation(Deprecated.class) != null; - } - - private void extractPublicMethods(ParsingContext context, StringBuilder it, Class type) { - for (final Method method : type.getDeclaredMethods()) { - if (Flags.isPublic(method.getModifiers()) && !Utils.isHiddenMember(method.getName()) - && !isDeprecated(method) && !method.isSynthetic() - && method.getAnnotation(SyntheticMember.class) == null) { - it.append("\tdef ").append(method.getName()); //$NON-NLS-1$ - if (method.getParameterCount() > 0) { - it.append("("); //$NON-NLS-1$ - boolean first = true; - int i = 1; - for (final Parameter param : method.getParameters()) { - if (first) { - first = false; - } else { - it.append(", "); //$NON-NLS-1$ - } - //it.append(param.getName()); - //it.append(" : "); //$NON-NLS-1$ - toType(it, param.getParameterizedType(), method.isVarArgs() && i == method.getParameterCount()); - final DefaultValue defaultValue = param.getAnnotation(DefaultValue.class); - if (defaultValue != null) { - final String fieldName = context.getParser().getActionPrototypeProvider().toJavaArgument( - "", defaultValue.value()); //$NON-NLS-1$ - it.append(" = "); //$NON-NLS-1$ - it.append(fieldName); - } - } - it.append(")"); //$NON-NLS-1$ - ++i; - } - if (method.getGenericReturnType() != null && !Objects.equals(method.getGenericReturnType(), Void.class) - && !Objects.equals(method.getGenericReturnType(), void.class)) { - it.append(" : "); //$NON-NLS-1$ - toType(it, method.getGenericReturnType(), false); - } - it.append("\n"); //$NON-NLS-1$ - } - } - } - - @SuppressWarnings({"checkstyle:cyclomaticcomplexity", "checkstyle:npathcomplexity"}) - private void toType(StringBuilder it, Type otype, boolean isVarArg) { - final Type type; - if (otype instanceof Class) { - type = isVarArg ? ((Class) otype).getComponentType() : otype; - } else { - type = otype; - } - if (type instanceof Class) { - it.append(((Class) type).getSimpleName()); - } else if (type instanceof ParameterizedType) { - final ParameterizedType paramType = (ParameterizedType) type; - final Type ownerType = paramType.getOwnerType(); - final boolean isForFunction = ownerType != null && Functions.class.getName().equals(ownerType.getTypeName()); - final boolean isForProcedure = ownerType != null && Procedures.class.getName().equals(ownerType.getTypeName()); - if (!isForFunction && !isForProcedure) { - it.append(((Class) paramType.getRawType()).getSimpleName()); - if (paramType.getActualTypeArguments().length > 0) { - it.append("<"); //$NON-NLS-1$ - boolean first = true; - for (final Type subtype : paramType.getActualTypeArguments()) { - if (first) { - first = false; - } else { - it.append(", "); //$NON-NLS-1$ - } - final StringBuilder it2 = new StringBuilder(); - toType(it2, subtype, false); - it.append(it2); - } - it.append(">"); //$NON-NLS-1$ - } - } else { - int nb = paramType.getActualTypeArguments().length; - if (isForFunction) { - --nb; - } - it.append("("); //$NON-NLS-1$ - for (int i = 0; i < nb; ++i) { - final Type subtype = paramType.getActualTypeArguments()[i]; - if (i > 0) { - it.append(", "); //$NON-NLS-1$ - } - toType(it, subtype, false); - } - it.append(") => "); //$NON-NLS-1$ - if (isForFunction) { - toType(it, paramType.getActualTypeArguments()[nb], false); - } else { - it.append("void"); //$NON-NLS-1$ - } - } - } else if (type instanceof WildcardType) { - final Type[] types = ((WildcardType) type).getUpperBounds(); - toType(it, types[0], false); - } else if (type instanceof GenericArrayType) { - toType(it, ((GenericArrayType) type).getGenericComponentType(), false); - it.append("[]"); //$NON-NLS-1$ - } else { - it.append(Object.class.getSimpleName()); - } - if (isVarArg) { - it.append("*"); //$NON-NLS-1$ - } - } - @Override public boolean isActive(ParsingContext context) { return context.isParsing() && context.getStage() == Stage.FIRST; @@ -2756,6 +2716,12 @@ public boolean isInternalTextAsBlockContent() { */ static final String DEFAULT_DYNAMIC_PATTERN = "\\[:Dynamic:\\]"; //$NON-NLS-1$ + /** Default pattern. + * + * @since 0.7 + */ + static final String DEFAULT_DYNAMIC_CODE_PATTERN = "\\[:DynamicCode:\\]"; //$NON-NLS-1$ + /** Default pattern. */ static final String DEFAULT_ON_PATTERN = "\\[:On\\]"; //$NON-NLS-1$ diff --git a/main/externalmaven/io.sarl.maven.docs.generator/src/main/resources/io/sarl/maven/docs/parser/messages.properties b/main/externalmaven/io.sarl.maven.docs.generator/src/main/resources/io/sarl/maven/docs/parser/messages.properties index 2cbf0d9441..8eb891b0d4 100644 --- a/main/externalmaven/io.sarl.maven.docs.generator/src/main/resources/io/sarl/maven/docs/parser/messages.properties +++ b/main/externalmaven/io.sarl.maven.docs.generator/src/main/resources/io/sarl/maven/docs/parser/messages.properties @@ -4,6 +4,7 @@ SarlDocumentationParser_2=Invalid parameter value for tag {3} SarlDocumentationParser_3={3} SarlDocumentationParser_4=Unknown replacement identifier: {3} SarlDocumentationParser_5=Nested tag not allowed for {3} +SarlDocumentationParser_6=Error when expanding the {0} tag: {1}. DynamicValidationContext_0=Invalid anchor reference ''{0}'' into {1}. DynamicValidationContext_1=Invalid target file {1} for anchor ''{0}''. Possible alternatives are:\n InvalidAnchorLabelException_0=Invalid anchor "{0}". Expecting one of: {1}. \ No newline at end of file diff --git a/main/externalmaven/io.sarl.maven.docs.testing/src/main/java/io/sarl/maven/docs/testing/DocumentationImplicitlyImportedFeatures.java b/main/externalmaven/io.sarl.maven.docs.testing/src/main/java/io/sarl/maven/docs/testing/DocumentationImplicitlyImportedFeatures.java index 1f13a5d83a..e28f6ef6a4 100644 --- a/main/externalmaven/io.sarl.maven.docs.testing/src/main/java/io/sarl/maven/docs/testing/DocumentationImplicitlyImportedFeatures.java +++ b/main/externalmaven/io.sarl.maven.docs.testing/src/main/java/io/sarl/maven/docs/testing/DocumentationImplicitlyImportedFeatures.java @@ -46,6 +46,7 @@ public DocumentationImplicitlyImportedFeatures() { protected List> getExtensionClasses() { final List> xtextList = super.getExtensionClasses(); // Insert at the beginning for ensuring the SARL extension is selected before any Xtext extension. + xtextList.add(0, ReflectExtensions.class); xtextList.add(0, MarkdownExtensions.class); xtextList.add(0, FactExtensions.class); xtextList.add(0, ShouldExtensions.class); diff --git a/main/externalmaven/io.sarl.maven.docs.testing/src/main/java/io/sarl/maven/docs/testing/FactExtensions.java b/main/externalmaven/io.sarl.maven.docs.testing/src/main/java/io/sarl/maven/docs/testing/FactExtensions.java index 9c94f96541..538d224879 100644 --- a/main/externalmaven/io.sarl.maven.docs.testing/src/main/java/io/sarl/maven/docs/testing/FactExtensions.java +++ b/main/externalmaven/io.sarl.maven.docs.testing/src/main/java/io/sarl/maven/docs/testing/FactExtensions.java @@ -33,7 +33,7 @@ import org.arakhne.afc.vmutil.FileSystem; import org.eclipse.xtext.xbase.lib.Functions.Function3; -/** Shoulds functions. +/** Extended Functions for writting facts within the documentation. * * @author $Author: sgalland$ * @version $FullVersion$ diff --git a/main/externalmaven/io.sarl.maven.docs.testing/src/main/java/io/sarl/maven/docs/testing/MarkdownExtensions.java b/main/externalmaven/io.sarl.maven.docs.testing/src/main/java/io/sarl/maven/docs/testing/MarkdownExtensions.java index d08861cdc1..edb5e86487 100644 --- a/main/externalmaven/io.sarl.maven.docs.testing/src/main/java/io/sarl/maven/docs/testing/MarkdownExtensions.java +++ b/main/externalmaven/io.sarl.maven.docs.testing/src/main/java/io/sarl/maven/docs/testing/MarkdownExtensions.java @@ -29,7 +29,7 @@ import org.apache.commons.cli.Option; import org.apache.commons.cli.Options; -/** Tools for generating markdown. +/** Tools for generating markdown from different sources. * * @author $Author: sgalland$ * @version $FullVersion$ diff --git a/main/externalmaven/io.sarl.maven.docs.testing/src/main/java/io/sarl/maven/docs/testing/ReflectExtensions.java b/main/externalmaven/io.sarl.maven.docs.testing/src/main/java/io/sarl/maven/docs/testing/ReflectExtensions.java new file mode 100644 index 0000000000..a7146e1353 --- /dev/null +++ b/main/externalmaven/io.sarl.maven.docs.testing/src/main/java/io/sarl/maven/docs/testing/ReflectExtensions.java @@ -0,0 +1,264 @@ +/* + * $Id$ + * + * SARL is an general-purpose agent programming language. + * More details on http://www.sarl.io + * + * Copyright (C) 2014-2017 the original authors or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.sarl.maven.docs.testing; + +import java.lang.reflect.Field; +import java.lang.reflect.GenericArrayType; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.lang.reflect.WildcardType; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Objects; + +import com.google.common.collect.Iterables; +import org.eclipse.jdt.core.Flags; +import org.eclipse.xtext.util.Strings; +import org.eclipse.xtext.xbase.lib.Functions; +import org.eclipse.xtext.xbase.lib.IterableExtensions; +import org.eclipse.xtext.xbase.lib.Procedures; +import org.eclipse.xtext.xbase.lib.Pure; + +import io.sarl.lang.annotation.DefaultValue; +import io.sarl.lang.annotation.SarlSourceCode; +import io.sarl.lang.annotation.SyntheticMember; +import io.sarl.lang.util.Utils; + +/** Functions that are based on Java reflection, for building the documentation. + * + * @author $Author: sgalland$ + * @version $FullVersion$ + * @mavengroupid $GroupId$ + * @mavenartifactid $ArtifactId$ + * @since 0.7 + */ +public final class ReflectExtensions { + + private ReflectExtensions() { + // + } + + private static boolean isDeprecated(Method method) { + return Flags.isDeprecated(method.getModifiers()) || method.getAnnotation(Deprecated.class) != null; + } + + /** Extract the public methods from the given types. + * + * @param type the first type to parse. + * @param otherTypes the other types to parse. + * @return the code. + */ + @Pure + public static String getPublicMethods(Class type, Class... otherTypes) { + final StringBuilder it = new StringBuilder(); + appendPublicMethods(it, false, IterableExtensions.flatten( + Arrays.asList( + Collections.singletonList(type), + Arrays.asList(otherTypes)))); + return it.toString(); + } + + /** Extract the public methods from the given types. + * + * @param it the output. + * @param indent indicates if the code should be indented. + * @param types the types to parse. + */ + public static void appendPublicMethods(StringBuilder it, boolean indent, Class... types) { + appendPublicMethods(it, indent, Arrays.asList(types)); + } + + /** Extract the public methods from the given types. + * + * @param it the output. + * @param indent indicates if the code should be indented. + * @param types the types to parse. + */ + public static void appendPublicMethods(StringBuilder it, boolean indent, Iterable> types) { + final List lines = new LinkedList<>(); + for (final Class type : types) { + for (final Method method : type.getDeclaredMethods()) { + if (Flags.isPublic(method.getModifiers()) && !Utils.isHiddenMember(method.getName()) + && !isDeprecated(method) && !method.isSynthetic() + && method.getAnnotation(SyntheticMember.class) == null) { + final StringBuilder line = new StringBuilder(); + if (indent) { + line.append("\t"); //$NON-NLS-1$ + } + line.append("def ").append(method.getName()); //$NON-NLS-1$ + if (method.getParameterCount() > 0) { + line.append("("); //$NON-NLS-1$ + boolean first = true; + int i = 1; + for (final Parameter param : method.getParameters()) { + if (first) { + first = false; + } else { + line.append(", "); //$NON-NLS-1$ + } + //it.append(param.getName()); + //it.append(" : "); //$NON-NLS-1$ + toType(line, param.getParameterizedType(), method.isVarArgs() && i == method.getParameterCount()); + final String defaultValue = extractDefaultValueString(param); + if (!Strings.isEmpty(defaultValue)) { + line.append(" = "); //$NON-NLS-1$ + line.append(defaultValue); + } + } + line.append(")"); //$NON-NLS-1$ + ++i; + } + if (method.getGenericReturnType() != null && !Objects.equals(method.getGenericReturnType(), Void.class) + && !Objects.equals(method.getGenericReturnType(), void.class)) { + line.append(" : "); //$NON-NLS-1$ + toType(line, method.getGenericReturnType(), false); + } + line.append("\n"); //$NON-NLS-1$ + lines.add(line.toString()); + } + } + } + lines.sort(null); + for (final String line : lines) { + it.append(line); + } + } + + private static String extractDefaultValueString(Parameter parameter) { + final DefaultValue defaultValueAnnotation = parameter.getAnnotation(DefaultValue.class); + if (defaultValueAnnotation == null) { + return null; + } + final String fieldId = defaultValueAnnotation.value(); + if (!Strings.isEmpty(fieldId)) { + final Class container = parameter.getDeclaringExecutable().getDeclaringClass(); + if (container != null) { + final int index = fieldId.indexOf('#'); + Class target; + final String fieldName; + if (index > 0) { + try { + final Class type = Class.forName(fieldId.substring(0, index), true, container.getClassLoader()); + target = type; + } catch (Throwable exception) { + target = container; + } + fieldName = Utils.createNameForHiddenDefaultValueAttribute(fieldId.substring(index + 1)); + } else { + target = container; + fieldName = Utils.createNameForHiddenDefaultValueAttribute(fieldId); + } + + final Field field = Iterables.find(Arrays.asList(target.getDeclaredFields()), + (it) -> Strings.equal(it.getName(), fieldName), + null); + if (field != null) { + final SarlSourceCode sourceCodeAnnotation = parameter.getAnnotation(SarlSourceCode.class); + if (sourceCodeAnnotation != null) { + final String value = sourceCodeAnnotation.value(); + if (!Strings.isEmpty(fieldId)) { + return value; + } + } + } + } + } + return null; + } + + /** Extract the type name. + * + * @param it the output. + * @param otype the type to parse. + * @param isVarArg indicates if the type is used within a variadic parameter. + */ + @SuppressWarnings({"checkstyle:cyclomaticcomplexity", "checkstyle:npathcomplexity"}) + public static void toType(StringBuilder it, Type otype, boolean isVarArg) { + final Type type; + if (otype instanceof Class) { + type = isVarArg ? ((Class) otype).getComponentType() : otype; + } else { + type = otype; + } + if (type instanceof Class) { + it.append(((Class) type).getSimpleName()); + } else if (type instanceof ParameterizedType) { + final ParameterizedType paramType = (ParameterizedType) type; + final Type ownerType = paramType.getOwnerType(); + final boolean isForFunction = ownerType != null && Functions.class.getName().equals(ownerType.getTypeName()); + final boolean isForProcedure = ownerType != null && Procedures.class.getName().equals(ownerType.getTypeName()); + if (!isForFunction && !isForProcedure) { + it.append(((Class) paramType.getRawType()).getSimpleName()); + if (paramType.getActualTypeArguments().length > 0) { + it.append("<"); //$NON-NLS-1$ + boolean first = true; + for (final Type subtype : paramType.getActualTypeArguments()) { + if (first) { + first = false; + } else { + it.append(", "); //$NON-NLS-1$ + } + final StringBuilder it2 = new StringBuilder(); + toType(it2, subtype, false); + it.append(it2); + } + it.append(">"); //$NON-NLS-1$ + } + } else { + int nb = paramType.getActualTypeArguments().length; + if (isForFunction) { + --nb; + } + it.append("("); //$NON-NLS-1$ + for (int i = 0; i < nb; ++i) { + final Type subtype = paramType.getActualTypeArguments()[i]; + if (i > 0) { + it.append(", "); //$NON-NLS-1$ + } + toType(it, subtype, false); + } + it.append(") => "); //$NON-NLS-1$ + if (isForFunction) { + toType(it, paramType.getActualTypeArguments()[nb], false); + } else { + it.append("void"); //$NON-NLS-1$ + } + } + } else if (type instanceof WildcardType) { + final Type[] types = ((WildcardType) type).getUpperBounds(); + toType(it, types[0], false); + } else if (type instanceof GenericArrayType) { + toType(it, ((GenericArrayType) type).getGenericComponentType(), false); + it.append("[]"); //$NON-NLS-1$ + } else { + it.append(Object.class.getSimpleName()); + } + if (isVarArg) { + it.append("*"); //$NON-NLS-1$ + } + } + +} diff --git a/main/externalmaven/io.sarl.maven.docs.testing/src/main/java/io/sarl/maven/docs/testing/SarlScriptExecutor.java b/main/externalmaven/io.sarl.maven.docs.testing/src/main/java/io/sarl/maven/docs/testing/SarlScriptExecutor.java index 7976ad991a..2264754d29 100644 --- a/main/externalmaven/io.sarl.maven.docs.testing/src/main/java/io/sarl/maven/docs/testing/SarlScriptExecutor.java +++ b/main/externalmaven/io.sarl.maven.docs.testing/src/main/java/io/sarl/maven/docs/testing/SarlScriptExecutor.java @@ -32,6 +32,7 @@ import com.google.common.io.Files; import com.google.inject.Injector; +import com.google.inject.Provider; import org.apache.log4j.Level; import org.arakhne.afc.vmutil.FileSystem; import org.eclipse.emf.ecore.resource.Resource; @@ -67,9 +68,9 @@ public class SarlScriptExecutor implements ScriptExecutor { private String sourceVersion = Strings.emptyIfNull(null); - private SarlBatchCompiler compiler; + private Provider compilerProvider; - private IExpressionInterpreter interpreter; + private Provider interpreterProvider; /** Change the injector. * @@ -77,10 +78,8 @@ public class SarlScriptExecutor implements ScriptExecutor { */ @Inject public void setInjector(Injector injector) { - if (injector != null) { - this.compiler = injector.getInstance(SarlBatchCompiler.class); - this.interpreter = injector.getInstance(IExpressionInterpreter.class); - } + this.compilerProvider = injector.getProvider(SarlBatchCompiler.class); + this.interpreterProvider = injector.getProvider(IExpressionInterpreter.class); } @Override @@ -127,62 +126,72 @@ private static File createFile(File sourceFolder, String content) throws IOExcep } @Override - public File compile(int lineno, String code, List issues, ICompilatedResourceReceiver receiver) throws Exception { + public CompiledFile compile(int lineno, String code, List issues, ICompilatedResourceReceiver receiver) throws Exception { File rootFolder = createRootFolder(); File sourceFolder = createSourceFolder(rootFolder); File genFolder = createGenFolder(rootFolder); File binFolder = createBinFolder(rootFolder); - this.compiler.setBasePath(rootFolder.getAbsolutePath()); - this.compiler.addSourcePath(sourceFolder); - this.compiler.setClassOutputPath(binFolder); - this.compiler.setOutputPath(genFolder); - this.compiler.setGenerateGeneratedAnnotation(false); - this.compiler.setGenerateInlineAnnotation(false); - this.compiler.setGenerateSyntheticSuppressWarnings(true); - this.compiler.setDeleteTempDirectory(false); - this.compiler.setClassPath(this.classpath); - this.compiler.setBootClassPath(this.bootClasspath); - this.compiler.setJavaSourceVersion(this.sourceVersion); - this.compiler.setAllWarningSeverities(Severity.IGNORE); - this.compiler.setWarningSeverity(IssueCodes.DEPRECATED_MEMBER_REFERENCE, Severity.ERROR); - this.compiler.setJavaCompilerVerbose(false); - this.compiler.getLogger().setLevel(Level.OFF); - this.compiler.addIssueMessageListener((issue, uri, message) -> { - if (issue.isSyntaxError() || issue.getSeverity().compareTo(Severity.ERROR) >= 0) { + final SarlBatchCompiler compiler = this.compilerProvider.get(); + compiler.setBasePath(rootFolder.getAbsolutePath()); + compiler.addSourcePath(sourceFolder); + compiler.setClassOutputPath(binFolder); + compiler.setOutputPath(genFolder); + compiler.setGenerateGeneratedAnnotation(false); + compiler.setGenerateInlineAnnotation(false); + compiler.setGenerateSyntheticSuppressWarnings(true); + compiler.setDeleteTempDirectory(false); + compiler.setClassPath(this.classpath); + compiler.setBootClassPath(this.bootClasspath); + compiler.setJavaSourceVersion(this.sourceVersion); + compiler.setAllWarningSeverities(Severity.IGNORE); + compiler.setWarningSeverity(IssueCodes.DEPRECATED_MEMBER_REFERENCE, Severity.ERROR); + compiler.setJavaCompilerVerbose(false); + compiler.getLogger().setLevel(Level.OFF); + compiler.addIssueMessageListener((issue, uri, message) -> { + if (issue.isSyntaxError() || issue.getSeverity() == Severity.ERROR) { final Integer line = issue.getLineNumber(); final int issueLine = (line == null ? 0 : line.intValue()) + lineno; issues.add(message + "(line " + issueLine + ")"); //$NON-NLS-1$ //$NON-NLS-2$ } }); if (receiver != null) { - this.compiler.addCompiledResourceReceiver(receiver); + compiler.addCompiledResourceReceiver(receiver); } File file = createFile(sourceFolder, code); - if (this.compiler.compile()) { - issues.clear(); - } - return file; + compiler.compile(); + return new CompiledFile(rootFolder, file); } @Override public Object execute(int lineno, String code) throws Exception { final List issues = new ArrayList<>(); final Collection resources = new ArrayList<>(); - compile(lineno, "package x.x.x; class ____Fake_Class____ { var __fake_attr__ : Object = { " + code + " }; }", //$NON-NLS-1$ //$NON-NLS-2$ + final CompiledFile outFile = compile(lineno, + "package x.x.x; class ____Fake_Class____ { var __fake_attr__ : Object = { " + code + " }; }", //$NON-NLS-1$ //$NON-NLS-2$ issues, (it) -> { resources.add(it); }); - assertNoIssue(lineno, issues); - for (Resource resource : resources) { - SarlScript script = (SarlScript) resource.getContents().get(0); - SarlClass clazz = (SarlClass) script.getXtendTypes().get(0); - SarlField field = (SarlField) clazz.getMembers().get(0); - XExpression xexpression = field.getInitialValue(); - IEvaluationResult result = this.interpreter.evaluate(xexpression); - if (result.getException() == null) { - return result.getResult(); + try { + if (resources.isEmpty()) { + throw new IllegalStateException("No Xtext resource created [line:" + lineno + "]"); //$NON-NLS-1$ //$NON-NLS-2$ + } + assertNoIssue(lineno, issues); + for (Resource resource : resources) { + SarlScript script = (SarlScript) resource.getContents().get(0); + SarlClass clazz = (SarlClass) script.getXtendTypes().get(0); + SarlField field = (SarlField) clazz.getMembers().get(0); + XExpression xexpression = field.getInitialValue(); + final IExpressionInterpreter interpreter = this.interpreterProvider.get(); + IEvaluationResult result = interpreter.evaluate(xexpression); + if (result.getException() == null) { + return result.getResult(); + } + throw new RuntimeException(result.getException()); + } + } finally { + if (outFile != null && outFile.getRootFolder() != null) { + FileSystem.delete(outFile.getRootFolder()); } - return result.getException(); } return null; } diff --git a/main/externalmaven/io.sarl.maven.docs.testing/src/main/java/io/sarl/maven/docs/testing/ScriptExecutor.java b/main/externalmaven/io.sarl.maven.docs.testing/src/main/java/io/sarl/maven/docs/testing/ScriptExecutor.java index 59cc4347ea..bbe0eb9028 100644 --- a/main/externalmaven/io.sarl.maven.docs.testing/src/main/java/io/sarl/maven/docs/testing/ScriptExecutor.java +++ b/main/externalmaven/io.sarl.maven.docs.testing/src/main/java/io/sarl/maven/docs/testing/ScriptExecutor.java @@ -26,6 +26,7 @@ import java.util.List; import com.google.inject.ImplementedBy; +import org.arakhne.afc.vmutil.FileSystem; import io.sarl.lang.compiler.batch.ICompilatedResourceReceiver; @@ -73,7 +74,10 @@ public interface ScriptExecutor { */ default List compile(int lineno, String code) throws Exception { List issues = new ArrayList<>(); - compile(lineno, code, issues, null); + final CompiledFile file = compile(lineno, code, issues, null); + if (file != null && file.getRootFolder() != null) { + FileSystem.delete(file.getRootFolder()); + } return issues; } @@ -86,7 +90,7 @@ default List compile(int lineno, String code) throws Exception { * @return the file which contains the compiled code. * @throws Exception if compilation failed. */ - File compile(int lineno, String code, List issues, ICompilatedResourceReceiver receiver) throws Exception; + CompiledFile compile(int lineno, String code, List issues, ICompilatedResourceReceiver receiver) throws Exception; /** Execute the given code for obtaining a string. * @@ -97,4 +101,45 @@ default List compile(int lineno, String code) throws Exception { */ Object execute(int lineno, String code) throws Exception; + /** Represents a compiled file. + * + * @author $Author: sgalland$ + * @version $FullVersion$ + * @mavengroupid $GroupId$ + * @mavenartifactid $ArtifactId$ + * @since 0.7 + */ + public final class CompiledFile { + + private final File rootFolder; + + private final File file; + + /** Constructor. + * + * @param root the root folder. + * @param file the compiled file. + */ + public CompiledFile(File root, File file) { + this.rootFolder = root; + this.file = file; + } + + /** Replies the root folder. + * + * @return the root folder. + */ + public File getRootFolder() { + return this.rootFolder; + } + + /** Replies the compiled file. + * + * @return the compiled file. + */ + public File getCompiledFile() { + return this.file; + } + + } } diff --git a/main/externalmaven/io.sarl.maven.docs.testing/src/main/java/io/sarl/maven/docs/testing/ShouldExtensions.java b/main/externalmaven/io.sarl.maven.docs.testing/src/main/java/io/sarl/maven/docs/testing/ShouldExtensions.java index 02a13ec1ac..1760d8a52c 100644 --- a/main/externalmaven/io.sarl.maven.docs.testing/src/main/java/io/sarl/maven/docs/testing/ShouldExtensions.java +++ b/main/externalmaven/io.sarl.maven.docs.testing/src/main/java/io/sarl/maven/docs/testing/ShouldExtensions.java @@ -65,7 +65,7 @@ import org.eclipse.xtext.xbase.lib.Pair; import org.osgi.framework.Version; -/** Shoulds functions. +/** Should functions for the documentation facts. * * @author $Author: sgalland$ * @version $FullVersion$