Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ assertj_version = 3.21.0
junit_version = 5.8.2

# Version of published artifacts
version = 7.8.23
version = 7.8.24
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ component grammar SysMLImportsAndPackages extends SysMLBasis {
* Metadata is additional data that can be used to annotate
* the elements of a model.
*/
SysMLMetaDataDefinition implements SysMLElement =
symbol scope SysMLMetaDataDefinition implements SysMLType, SysMLElement =
Modifier UserDefinedKeyword* "metadata" "def"
SysMLIdentifier? Name SysMLCardinality? Specialization*
("{"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ component grammar SysMLParts extends SysMLBasis {
* Defaults to "delayed".
*/
SysMLCausality implements SysMLElement =
"timing" (["instant"] | ["delayed"]) ";" ;
"timing" timing:Name ";" ;

/*
* ##################################################################
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import de.monticore.lang.sysmlv2.cocos.SubcomponentOutputConnectionDirectionCoCo;
import de.monticore.lang.sysmlv2.cocos.TypeCheck3TransitionGuards;
import de.monticore.lang.sysmlv2.cocos.UniqueSubPartNamesInParentCoCo;
import de.monticore.lang.sysmlv2.cocos.ValidCausalityTimingCoCo;
import de.monticore.lang.sysmlv2.cocos.WarnNonExhibited;
import de.monticore.lang.sysmlv2.symboltable.completers.CausalityCompleter;
import de.monticore.lang.sysmlv2.symboltable.completers.DirectRefinementCompleter;
Expand Down Expand Up @@ -123,6 +124,7 @@ public void runDefaultCoCos(ASTSysMLModel ast) {
checker.addCoCo(new QualifiedPortNameExistsCoCo());
// Check ambiguous names
checker.addCoCo(new UniqueSubPartNamesInParentCoCo());
checker.addCoCo(new ValidCausalityTimingCoCo());

checker.checkAll(ast);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import de.monticore.lang.sysmlconstraints._ast.ASTRequirementUsage;
import de.monticore.lang.sysmlconstraints._symboltable.RequirementSubjectSymbol;
import de.monticore.lang.sysmlconstraints.symboltable.adapters.RequirementSubject2VariableSymbolAdapter;
import de.monticore.lang.sysmlimportsandpackages._symboltable.SysMLMetaDataDefinitionSymbol;
import de.monticore.lang.sysmloccurrences.symboltable.adapters.ItemDef2TypeSymbolAdapter;
import de.monticore.lang.sysmlparts._symboltable.AttributeUsageSymbol;
import de.monticore.lang.sysmlparts._symboltable.PartUsageSymbol;
Expand All @@ -28,6 +29,7 @@
import de.monticore.lang.sysmlstates.symboltable.adapters.StateDef2TypeSymbolAdapter;
import de.monticore.lang.sysmlv2.symboltable.adapters.AttributeUsage2PortSymbolAdapter;
import de.monticore.lang.sysmlv2.symboltable.adapters.Constraint2SpecificationAdapter;
import de.monticore.lang.sysmlv2.symboltable.adapters.MetadataDef2TypeSymbolAdapter;
import de.monticore.lang.sysmlv2.symboltable.adapters.PartDef2ComponentAdapter;
import de.monticore.lang.sysmlv2.symboltable.adapters.Requirement2RequirementCCAdapter;
import de.monticore.lang.sysmlv2.symboltable.adapters.Requirement2SpecificationAdapter;
Expand Down Expand Up @@ -251,6 +253,12 @@ default List<TypeSymbol> resolveAdaptedTypeLocallyMany(
adapted.add(new ItemDef2TypeSymbolAdapter(itemDef.get()));
}

// MetadataDef zu Types
var metadataDef = resolveSysMLMetaDataDefinitionLocally(name);
if (metadataDef.isPresent()) {
adapted.add(new MetadataDef2TypeSymbolAdapter(metadataDef.get()));
}

return adapted;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/* (c) https://github.com/MontiCore/monticore */
package de.monticore.lang.sysmlv2.cocos;

import de.monticore.lang.sysmlparts._ast.ASTSysMLCausality;
import de.monticore.lang.sysmlparts._cocos.SysMLPartsASTSysMLCausalityCoCo;
import de.se_rwth.commons.logging.Log;

import java.util.Set;

public class ValidCausalityTimingCoCo implements SysMLPartsASTSysMLCausalityCoCo {
protected static final Set<String> VALID_TIMINGS = Set.of("instant", "delayed");

@Override
public void check(ASTSysMLCausality node) {
if (!VALID_TIMINGS.contains(node.getTiming())) {
Log.error(
"0x10AA8 Illegal timing value '" + node.getTiming()
+ "'. Only 'instant' and 'delayed' are allowed.",
node.get_SourcePositionStart(),
node.get_SourcePositionEnd()
);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/* (c) https://github.com/MontiCore/monticore */
package de.monticore.lang.sysmlv2.symboltable.adapters;

import com.google.common.base.Preconditions;
import de.monticore.lang.sysmlimportsandpackages._symboltable.SysMLMetaDataDefinitionSymbol;
import de.monticore.symbols.basicsymbols._symboltable.IBasicSymbolsScope;
import de.monticore.symbols.basicsymbols._symboltable.TypeSymbol;
import de.se_rwth.commons.SourcePosition;

public class MetadataDef2TypeSymbolAdapter extends TypeSymbol {
protected SysMLMetaDataDefinitionSymbol adaptee;

public MetadataDef2TypeSymbolAdapter(SysMLMetaDataDefinitionSymbol adaptee) {
super(Preconditions.checkNotNull(adaptee.getName()));
this.adaptee = adaptee;
}

protected SysMLMetaDataDefinitionSymbol getAdaptee() {
return adaptee;
}

@Override
public void setName(String name) {
Preconditions.checkNotNull(name);
Preconditions.checkArgument(!name.isBlank());
getAdaptee().setName(name);
}

@Override
public String getName() {
return getAdaptee().getName();
}

@Override
public String getFullName() {
return getAdaptee().getFullName();
}

@Override
public IBasicSymbolsScope getSpannedScope() {
return getAdaptee().getSpannedScope();
}

@Override
public IBasicSymbolsScope getEnclosingScope() {
return getAdaptee().getEnclosingScope();
}

@Override
public SourcePosition getSourcePosition() {
return getAdaptee().getSourcePosition();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,18 @@
* anhand der besitzenden (umliegenden) PartDefinition.
*/
public class CausalityCompleter implements SysMLPartsVisitor2 {
protected static final String INSTANT = "instant";

@Override
public void visit(ASTPortUsage node) {
if (node.getEnclosingScope().isPresentSpanningSymbol()) {
var enclosingSymbol = node.getEnclosingScope().getSpanningSymbol();
if(enclosingSymbol instanceof PartDefSymbol && enclosingSymbol.isPresentAstNode()) {
var ast = (ASTPartDef) enclosingSymbol.getAstNode();
node.getSymbol().setStrong(
ast.getSysMLElements(ASTSysMLCausality.class).stream().noneMatch(ASTSysMLCausality::isInstant)
ast.getSysMLElements(ASTSysMLCausality.class).stream()
.map(ASTSysMLCausality::getTiming)
.noneMatch(INSTANT::equals)
);
}
}
Expand Down
60 changes: 60 additions & 0 deletions language/src/test/java/cocos/ValidCausalityTimingCoCoTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/* (c) https://github.com/MontiCore/monticore */
package cocos;

import de.monticore.lang.sysmlv2.SysMLv2Mill;
import de.monticore.lang.sysmlv2._cocos.SysMLv2CoCoChecker;
import de.monticore.lang.sysmlv2._parser.SysMLv2Parser;
import de.monticore.lang.sysmlv2.cocos.ValidCausalityTimingCoCo;
import de.se_rwth.commons.logging.Log;
import de.se_rwth.commons.logging.LogStub;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.io.IOException;

import static org.assertj.core.api.Assertions.assertThat;

public class ValidCausalityTimingCoCoTest {
private final SysMLv2Parser parser = new SysMLv2Parser();

@BeforeAll
public static void init() {
LogStub.init();
SysMLv2Mill.init();
}

@BeforeEach
public void reset() {
Log.getFindings().clear();
}

@Test
void testDelayedTimingAndMetadataNameCanCoexist() throws IOException {
var ast = parser.parse_String("package Demo { metadata def delayed; part def P { timing delayed; } }");

assertThat(ast).isPresent();
assertThat(parser.hasErrors()).isFalse();

var checker = new SysMLv2CoCoChecker();
checker.addCoCo(new ValidCausalityTimingCoCo());
checker.checkAll(ast.get());

assertThat(Log.getFindings()).isEmpty();
}

@Test
void testInvalidTimingValueProducesFinding() throws IOException {
var ast = parser.parse_String("part def P { timing asap; }");

assertThat(ast).isPresent();
assertThat(parser.hasErrors()).isFalse();

var checker = new SysMLv2CoCoChecker();
checker.addCoCo(new ValidCausalityTimingCoCo());
checker.checkAll(ast.get());

assertThat(Log.getFindings()).isNotEmpty();
assertThat(Log.getFindings().get(0).getMsg()).contains("0x10AA8");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/* (c) https://github.com/MontiCore/monticore */
package symboltable;

import de.monticore.lang.sysmlimportsandpackages._ast.ASTSysMLMetaDataDefinition;
import de.monticore.lang.sysmlimportsandpackages._ast.ASTSysMLPackage;
import de.monticore.lang.sysmlv2.SysMLv2Mill;
import de.monticore.lang.sysmlv2.SysMLv2Tool;
import de.se_rwth.commons.logging.Log;
import de.se_rwth.commons.logging.LogStub;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

public class MetadataDefinitionSymbolTest {

private static final String LOG_NAME = MetadataDefinitionSymbolTest.class.getName();

@Test
public void testMetadataDefinitionCreatesTypeSymbol() throws Exception {
LogStub.init();
Log.getFindings().clear();

var tool = new SysMLv2Tool();
tool.init();

String model = "package Demo {\n"
+ " metadata def delayed;\n"
+ " part def P {\n"
+ " timing delayed;\n"
+ " }\n"
+ "}\n";

var ast = SysMLv2Mill.parser().parse_String(model);
assertThat(ast).isPresent();

var artifactScope = tool.createSymbolTable(ast.get());

var pkg = (ASTSysMLPackage) ast.get().getSysMLElement(0);

var metadataDef = (ASTSysMLMetaDataDefinition) pkg.getSysMLElement(0);
assertThat(metadataDef.getName()).isEqualTo("delayed");

assertThat(artifactScope.getSubScopes()).hasSize(1);
assertThat(artifactScope.getSubScopes().get(0).resolveSysMLMetaDataDefinition("delayed")).isPresent();
assertThat(artifactScope.getSubScopes().get(0).resolveType("delayed")).isPresent();
}
}
Loading