Unverified Commit 83db268c authored by Stefan Brunecker's avatar Stefan Brunecker Committed by GitHub
Browse files

Merge pull request #14 from EmbeddedMontiArc/release-0.1.1

Release 0.1.1
parents 2c89bef7 af1883ef
......@@ -30,7 +30,8 @@ jobs:
- stage: acceptance-test
script:
- mvn verify -Pacceptance-test jacoco:report --settings "settings.xml"
after_success:
- if [ "${TRAVIS_BRANCH}" == "master" ]; then mvn -B deploy --settings "./settings.xml"; fi
after_success:
- bash <(curl -s https://codecov.io/bash) || echo "Codecov did not collect coverage reports"
#- mvn deploy --settings "./settings.xml"
......@@ -6,7 +6,7 @@
<groupId>de.monticore.lang.montiarc</groupId>
<artifactId>emam2wasm</artifactId>
<version>0.1.0</version>
<version>0.1.1</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
......@@ -348,16 +348,16 @@
</profile>
</profiles>
<!--<distributionManagement>
<distributionManagement>
<repository>
<id>internal.repo</id>
<name>Temporary Staging Repository</name>
<url>file://${project.build.directory}/external-dependencies</url>
<name>Temporary Staging Repository</name>
<url>file://${project.build.directory}/external-dependencies</url>
</repository>
<snapshotRepository>
<id>internal.repo</id>
<url>file://${project.build.directory}/external-dependencies</url>
<id>internal.repo</id>
<url>file://${project.build.directory}/external-dependencies</url>
</snapshotRepository>
</distributionManagement>-->
</distributionManagement>
</project>
\ No newline at end of file
......@@ -73,11 +73,14 @@
src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/4.0.1/math.min.js"></script>
<script type="text/javascript" src="array_wrapper.js"></script>
<script type="text/javascript" src="array.js"></script>
<title>Model</title>
<title>Array</title>
</head>
<body>
<div class="container">
<div class="model">
<div class="header">
<h2>Array</h2>
</div>
<div class="ports">
<div class="inports">
<div class="header">
......
......@@ -73,11 +73,14 @@
src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/4.0.1/math.min.js"></script>
<script type="text/javascript" src="matrix_wrapper.js"></script>
<script type="text/javascript" src="matrix.js"></script>
<title>Model</title>
<title>Matrix</title>
</head>
<body>
<div class="container">
<div class="model">
<div class="header">
<h2>Matrix</h2>
</div>
<div class="ports">
<div class="inports">
<div class="header">
......
......@@ -73,11 +73,14 @@
src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/4.0.1/math.min.js"></script>
<script type="text/javascript" src="multiplePorts_wrapper.js"></script>
<script type="text/javascript" src="multiplePorts.js"></script>
<title>Model</title>
<title>MultiplePorts</title>
</head>
<body>
<div class="container">
<div class="model">
<div class="header">
<h2>MultiplePorts</h2>
</div>
<div class="ports">
<div class="inports">
<div class="header">
......
......@@ -73,11 +73,14 @@
src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/4.0.1/math.min.js"></script>
<script type="text/javascript" src="noPorts_wrapper.js"></script>
<script type="text/javascript" src="noPorts.js"></script>
<title>Model</title>
<title>NoPorts</title>
</head>
<body>
<div class="container">
<div class="model">
<div class="header">
<h2>NoPorts</h2>
</div>
<div class="ports">
<div class="inports">
<div class="header">
......
......@@ -73,11 +73,14 @@
src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/4.0.1/math.min.js"></script>
<script type="text/javascript" src="scalar_wrapper.js"></script>
<script type="text/javascript" src="scalar.js"></script>
<title>Model</title>
<title>Scalar</title>
</head>
<body>
<div class="container">
<div class="model">
<div class="header">
<h2>Scalar</h2>
</div>
<div class="ports">
<div class="inports">
<div class="header">
......
......@@ -65,11 +65,14 @@
src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/4.0.1/math.min.js"></script>
<script type="text/javascript" src="multiplePorts_wrapper.js"></script>
<script type="text/javascript" src="multiplePorts.js"></script>
<title>Model</title>
<title>MultiplePorts</title>
</head>
<body>
<div class="container">
<div class="model">
<div class="header">
<h2>MultiplePorts</h2>
</div>
<div class="ports">
<div class="inports">
<div class="header">
......
package de.monticore.lang.monticar.emam2wasm.cpp;
import static de.monticore.lang.monticar.contract.Precondition.requiresNotNull;
import de.monticore.symboltable.Symbol;
import org.springframework.stereotype.Component;
......@@ -10,7 +12,7 @@ public class CppMainNameProvider implements CppNameProvider {
@Override
public String getName(Symbol model) {
return model.getName();
return requiresNotNull(model).getName();
}
@Override
......
package de.monticore.lang.monticar.emam2wasm.wasm;
import static de.monticore.lang.monticar.contract.Precondition.requiresNotNull;
import java.nio.file.Path;
import org.apache.commons.io.FilenameUtils;
import org.springframework.stereotype.Component;
......@@ -11,7 +13,7 @@ public class WasmJsNameProvider implements WasmNameProvider {
@Override
public String getName(Path cppFile) {
return FilenameUtils.getBaseName(cppFile.toString());
return FilenameUtils.getBaseName(requiresNotNull(cppFile).toString());
}
@Override
......
......@@ -3,25 +3,49 @@ package de.monticore.lang.monticar.generator;
import static de.monticore.lang.monticar.contract.Precondition.requiresNotNull;
import static de.monticore.lang.monticar.contract.StringPrecondition.requiresNotBlank;
import com.google.common.annotations.VisibleForTesting;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.PortSymbol;
import de.monticore.lang.monticar.common2._ast.ASTCommonDimensionElement;
import de.monticore.lang.monticar.common2._ast.ASTCommonMatrixType;
import de.monticore.lang.monticar.ts.MCTypeSymbol;
import de.monticore.lang.monticar.ts.references.MCASTTypeSymbolReference;
import de.monticore.lang.monticar.ts.references.MCTypeReference;
import de.monticore.lang.monticar.types2._ast.ASTElementType;
import de.monticore.lang.monticar.types2._ast.ASTType;
import de.monticore.symboltable.Symbol;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import org.springframework.util.StringUtils;
/**
* Class for methods commonly used by generator classes.
*/
public class GeneratorUtil {
private static final String GETTER_PREFIX = "get";
private static final String SETTER_PREFIX = "set";
private static final String BOOLEAN_TYPE = "B";
private static final String NATURAL_NUMBER_TYPE = "N";
private static final String INTEGER_NUMBER_TYPE = "Z";
private static final String RATIONAL_NUMBER_TYPE = "Q";
private static final String COMPLEX_NUMBER_TYPE = "C";
/**
* Takes a collection of {@link PortSymbol}s and filters out ports that
* belong to an array except for one. The order of the ports in the supplied
* collection remains otherwise unchanged.<p>
* It is guaranteed that the first port of an array as returned by the
* collections iterator is put into the returned collection. All subsequent
* ports belonging to this array will be discarded.<p>
* Two ports are determined to belong to the same port array if their names
* match disregarding the trailing square brackets.
*
* @param ports a collection of ports
* @return collection that contains only one port for each port array and is
* otherwise unchanged from the supplied collection
*/
public static Collection<PortSymbol> filterMultipleArrayPorts(Collection<PortSymbol> ports) {
List<PortSymbol> filteredPorts = new ArrayList<>();
List<String> processedArrays = new ArrayList<>();
......@@ -38,23 +62,123 @@ public class GeneratorUtil {
return filteredPorts;
}
/**
* Returns the method name to be used when generating a setter method for the
* supplied port.
*
* @param port {@code PortSymbol}
* @return method name for the supplied port
*/
public static String getSetterMethodName(PortSymbol port) {
return getSetterMethodName(requiresNotNull(port).getNameWithoutArrayBracketPart());
}
/**
* Returns the method name to be used when generating a setter method for a
* {@link PortSymbol} with the supplied name.
*
* @param portName the name of a {@code PortSymbol}
* @return method name for the supplied port name
*/
public static String getSetterMethodName(String portName) {
return SETTER_PREFIX + StringUtils.capitalize(requiresNotBlank(portName));
}
/**
* Returns the method name to be used when generating a getter method for the
* supplied port.
*
* @param port {@code PortSymbol}
* @return method name for the supplied port
*/
public static String getGetterMethodName(PortSymbol port) {
return getGetterMethodName(requiresNotNull(port).getNameWithoutArrayBracketPart());
}
/**
* Returns the method name to be used when generating a getter method for a
* {@link PortSymbol} with the supplied name.
*
* @param portName the name of a {@code PortSymbol}
* @return method name for the supplied port name
*/
public static String getGetterMethodName(String portName) {
return GETTER_PREFIX + StringUtils.capitalize(requiresNotBlank(portName));
}
@VisibleForTesting
/**
* Returns the component name for the supplied {@code Symbol}. This name
* always starts with an capital letter.
*
* @param model {@code Symbol}
* @return component name for the supplied symbol
*/
public static String getComponentName(Symbol model) {
return StringUtils.capitalize(requiresNotNull(model).getName());
}
/**
* Tries to determine the supplied {@code PortSymbol}'s type. The type
* includes the number set, any defined range and corresponding units.
*
* @param port {@code PortSymbol}
* @return the port's type
* @throws RuntimeException if it failed to determine the port's type
*/
public static String getType(PortSymbol port) {
MCASTTypeSymbolReference typeReference = (MCASTTypeSymbolReference) port.getTypeReference();
ASTType astType = typeReference.getAstType();
if (astType instanceof ASTCommonMatrixType) {
return matrixType((ASTCommonMatrixType) astType);
} else if (astType instanceof ASTElementType) {
ASTElementType type = (ASTElementType) astType;
Optional<String> elementType = type.getTElementType();
return elementType.orElse(typeReference.getName());
} else {
throw new RuntimeException("Unexpected ASTType: " + astType);
}
}
private static String matrixType(ASTCommonMatrixType type) {
ASTElementType elementType = type.getElementType();
Optional<String> tElementTypeOpt = elementType.getTElementType();
if (tElementTypeOpt.isPresent()) {
return tElementTypeOpt.get();
} else {
if (elementType.isIsBoolean()) {
return BOOLEAN_TYPE;
} else if (elementType.isIsNatural()) {
return NATURAL_NUMBER_TYPE;
} else if (elementType.isIsWholeNumberNumber()) {
return INTEGER_NUMBER_TYPE;
} else if (elementType.isIsRational()) {
return RATIONAL_NUMBER_TYPE;
} else if (elementType.isIsComplex()) {
return COMPLEX_NUMBER_TYPE;
} else {
throw new RuntimeException("Unable to determine type from " + type);
}
}
}
/**
* Returns a string array representing the dimension of the supplied port.
* The entries in this array are strings of integer numbers. The dimension
* is a combination of the port's potential matrix dimension and array size.
* In case the supplied port is defined as an array of matrices, a string
* array with the array and matrix dimension is returned. The size of the
* port array will be in position 0 of the returned array.
* In case the supplied port is either defined as a matrix or belongs to an
* array, the respective dimension is returned.
* Otherwise, a string array of size 0 is returned.<p>
* A collection of all ports of the component that the supplied port belongs
* to is needed to determine a potential array size.
*
* @param ports all ports directly belonging to the component of the
* supplied port
* @param port PortSymbol to determine the dimension for
* @return dimension of the port or an empty array
*/
public static String[] getDimension(Collection<PortSymbol> ports, PortSymbol port) {
int arrayDimension = port.isPartOfPortArray() ?
getArrayDimension(ports, port.getNameWithoutArrayBracketPart()) : 0;
......
package de.monticore.lang.monticar.generator.html;
import static de.monticore.lang.monticar.generator.GeneratorUtil.filterMultipleArrayPorts;
import static de.monticore.lang.monticar.generator.GeneratorUtil.getComponentName;
import static de.monticore.lang.monticar.generator.GeneratorUtil.getDimension;
import static de.monticore.lang.monticar.generator.GeneratorUtil.getType;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.ExpandedComponentInstanceSymbol;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.PortSymbol;
import de.monticore.lang.monticar.common2._ast.ASTCommonMatrixType;
import de.monticore.lang.monticar.freemarker.TemplateProcessor;
import de.monticore.lang.monticar.generator.GeneratorUtil;
import de.monticore.lang.monticar.ts.references.MCASTTypeSymbolReference;
import de.monticore.lang.monticar.types2._ast.ASTElementType;
import de.monticore.lang.monticar.types2._ast.ASTType;
import freemarker.template.TemplateException;
import java.io.IOException;
import java.util.Arrays;
......@@ -18,7 +16,6 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
......@@ -62,6 +59,7 @@ public class HtmlGenerator {
List<Port> outports = produceOutports(model.getOutgoingPorts());
Map<String, Object> dataModel = new HashMap<>();
dataModel.put("model_name", getComponentName(model));
dataModel.put("model", wasmNamingFunction.apply(model));
dataModel.put("model_wrapper", wrapperNamingFunction.apply(model));
dataModel.put("inports", inports);
......@@ -82,23 +80,11 @@ public class HtmlGenerator {
Function<PortSymbol, String> methodNameFunction) {
return filterMultipleArrayPorts(ports).stream().map(
p -> port(p.getNameWithoutArrayBracketPart(), methodNameFunction.apply(p),
getType(ports, p))).collect(Collectors.toList());
getPortDefinition(ports, p))).collect(Collectors.toList());
}
private String getType(Collection<PortSymbol> ports, PortSymbol port) {
MCASTTypeSymbolReference typeReference = (MCASTTypeSymbolReference) port.getTypeReference();
ASTType astType = typeReference.getAstType();
Optional<String> elementType;
if (astType instanceof ASTCommonMatrixType) {
ASTCommonMatrixType type = (ASTCommonMatrixType) astType;
elementType = type.getElementType().getTElementType();
} else if (astType instanceof ASTElementType) {
ASTElementType type = (ASTElementType) astType;
elementType = type.getTElementType();
} else {
throw new RuntimeException("Unexpected ASTType: " + astType);
}
String type = elementType.orElse(typeReference.getName());
private String getPortDefinition(Collection<PortSymbol> ports, PortSymbol port) {
String type = getType(port);
String[] dimension = getDimension(ports, port);
String dim = dimension.length > 0 ?
......
......@@ -66,11 +66,14 @@
src="https://cdnjs.cloudflare.com/ajax/libs/mathjs/4.0.1/math.min.js"></script>
<script type="text/javascript" src="${model_wrapper}.js"></script>
<script type="text/javascript" src="${model}.js"></script>
<title>Model</title>
<title>${model_name}</title>
</head>
<body>
<div class="container">
<div class="model">
<div class="header">
<h2>${model_name}</h2>
</div>
<div class="ports">
<div class="inports">
<div class="header">
......
package de.monticore.lang.monticar.emam2wasm.cpp;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import de.monticore.lang.monticar.contract.Precondition.PreconditionViolationException;
import de.monticore.symboltable.Symbol;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
class CppMainNameProviderTest {
private static final Symbol NULL_SYMBOL = null;
private static final String SOME_SYMBOL_NAME = "someSymbolName";
private static final String EXPECTED_SYMBOL_NAME = SOME_SYMBOL_NAME;
private static final Path EXPECTED_FILE_PATH = Paths.get("someSymbolName.cpp");
private CppMainNameProvider nameProvider;
private Symbol symbol;
@BeforeEach
void setUp() {
nameProvider = new CppMainNameProvider();
symbol = mock(Symbol.class);
when(symbol.getName()).thenReturn(SOME_SYMBOL_NAME);
}
@Nested
class GetName {
@Nested
class ShouldThrowPreconditionViolationException {
@Test
void whenSymbolIsNull() {
assertThatExceptionOfType(PreconditionViolationException.class)
.isThrownBy(() -> nameProvider.getName(NULL_SYMBOL));
}
}
@Nested
class ShouldReturnSymbolName {
@Test
void whenSymbolIsNotNull() {
assertThat(nameProvider.getName(symbol)).isEqualTo(EXPECTED_SYMBOL_NAME);
}
}
}
@Nested
class GetFilePath {
@Nested
class ShouldThrowPreconditionViolationException {
@Test
void whenSymbolIsNull() {
assertThatExceptionOfType(PreconditionViolationException.class)
.isThrownBy(() -> nameProvider.getName(NULL_SYMBOL));
}
}
@Nested
class ShouldReturnFilePath {
@Test
void whenOnlyFileName() {
assertThat(nameProvider.getFilePath(symbol)).isEqualTo(
CppMainNameProviderTest.EXPECTED_FILE_PATH);
}
}
}
}
\ No newline at end of file
package de.monticore.lang.monticar.emam2wasm;
package de.monticore.lang.monticar.emam2wasm.cpp;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.ArgumentMatchers.any;
......@@ -7,9 +7,6 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import de.monticore.lang.monticar.contract.Precondition.PreconditionViolationException;
import de.monticore.lang.monticar.emam2wasm.cpp.CppCompiler;
import de.monticore.lang.monticar.emam2wasm.cpp.CppNameProvider;
import de.monticore.lang.monticar.emam2wasm.cpp.CppStep;
import de.monticore.symboltable.Symbol;
import java.nio.file.Path;
import java.nio.file.Paths;
......
package de.monticore.lang.monticar.emam2wasm;
package de.monticore.lang.monticar.emam2wasm.model;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
......@@ -7,7 +7,6 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarcmath._parser.EmbeddedMontiArcMathParser;
import de.monticore.lang.monticar.emam2wasm.model.EmamModelNameProvider;
import de.monticore.lang.monticar.util.TextFile;
import java.io.IOException;
import java.io.Reader;
......
package de.monticore.lang.monticar.emam2wasm;
package de.monticore.lang.monticar.emam2wasm.model;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
......@@ -7,8 +7,6 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import de.monticore.lang.monticar.contract.Precondition.PreconditionViolationException;
import de.monticore.lang.monticar.emam2wasm.model.ModelNameProvider;
import de.monticore.lang.monticar.emam2wasm.model.ModelStep;
import de.monticore.lang.monticar.junit.TemporaryDirectoryExtension;
import java.nio.file.Path;
import java.nio.file.Paths;
......
package de.monticore.lang.monticar.emam2wasm.wasm;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import de.monticore.lang.monticar.contract.Precondition.PreconditionViolationException;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
class WasmJsNameProviderTest {
private static final Path NULL_PATH = null;