Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prototype for EMF model instance language module #856

Merged
merged 46 commits into from
May 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
19dd588
Add updated prototype for a dynamic EMF model instance language.
tsaglam Oct 26, 2022
7e8ccee
Add updated model instance test case.
tsaglam Oct 26, 2022
335bbea
Merge branch 'develop' into emf-model-new
tsaglam Oct 26, 2022
2581b16
Merge branch 'develop' into emf-model-new
tsaglam Dec 20, 2022
49a4e38
Add view file suffixes to gitattributes file.
tsaglam Dec 20, 2022
60f349b
Include emf model module into build.
tsaglam Dec 20, 2022
f34a646
Add record for token tracing information.
tsaglam Jan 10, 2023
1ce6343
Overhaul metamodel tree view and adapt view/parser interaction.
tsaglam Jan 10, 2023
4d39a26
Fix view file suffix for model instances.
tsaglam Jan 10, 2023
b10531c
Use display names for dynamic (meta)model test cases.
tsaglam Jan 10, 2023
10943be
Fix JavaDoc.
tsaglam Jan 10, 2023
5cf97d3
Resolve sonar issues.
tsaglam Jan 10, 2023
8b4ae27
Add test cases for the modified model tree view generation.
tsaglam Jan 11, 2023
6e88db1
Minor changes to the (meta)model test cases.
tsaglam Jan 12, 2023
1c0b7d4
Coverage
dfuchss Jan 26, 2023
ae137ca
Add model instance module to readme.
tsaglam Jan 16, 2023
f539354
Add emf model module to CLI.
tsaglam Feb 7, 2023
585ff51
Prevent file encoding issue in the emf tests.
tsaglam Feb 14, 2023
a1fd275
Move emfatic dependency version to the parent pom.
tsaglam Feb 14, 2023
82805b7
Include the emf model language as service, exclude the dynamic metamo…
tsaglam Feb 14, 2023
98d208c
Fix custom submission order for EMF instance module.
tsaglam Mar 17, 2023
3c7a4d1
Merge branch 'develop' into emf-model-new
tsaglam Mar 17, 2023
57d90a8
Fix language test to the current number of languages.
tsaglam Mar 17, 2023
372db87
Fix view file suffix for EMF model instance view files.
tsaglam Mar 17, 2023
12634e1
Improve logging of the new EMF model language module.
tsaglam Mar 17, 2023
503a4ab
Fix clean-up of the minimal model instance test case.
tsaglam Mar 17, 2023
58c7234
Fix view file warning.
tsaglam Mar 17, 2023
cd7c828
Merge branch 'develop' into emf-model-new
tsaglam Mar 28, 2023
ea8f1c3
Implement prototypical containment tree order normalization.
tsaglam Apr 6, 2023
dfee2e2
Normalize subtree histogram vector.
tsaglam Apr 9, 2023
56aa349
Avoid extracting super type and operation end tokens.
tsaglam Apr 10, 2023
423d8ac
Format code.
tsaglam Apr 10, 2023
4b67f5f
Provide more detail for references in the tokens sequence.
tsaglam Apr 12, 2023
8bff2ce
Chose better assertion for emf view file tests.
tsaglam Apr 27, 2023
370c8ad
Overhauled and cleaned-up normalization approach.
tsaglam Apr 27, 2023
37d1f6c
Adapt test case to changed token extraction rules.
tsaglam Apr 27, 2023
bf1b046
Remove outdated TODO comment.
tsaglam Apr 27, 2023
f380df1
Fix minor code style issues.
tsaglam Apr 27, 2023
0770c4d
Overhaul normalization and extraction rules to support normalization …
tsaglam May 2, 2023
2d8b383
Update gitignore.
tsaglam May 16, 2023
8867197
Fix bug that led to all tokens being normalized by the nearest neighb…
tsaglam May 16, 2023
f857f18
Clean-up metamodel token generator.
tsaglam May 16, 2023
a8859e9
Merge pull request #1053 from jplag/model-norm
tsaglam May 16, 2023
8e34214
Merge branch 'develop' into emf-model-new
tsaglam May 16, 2023
dc0012a
Adapt language test case.
tsaglam May 16, 2023
cf4b1a3
Merge branch 'develop' into emf-model-new
tsaglam May 19, 2023
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
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto

*.emfatic text
*.treeview text
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,6 @@ hs_err_pid*
# default result file name, should never be commited
result/
result.zip

# macOS
*.DS_Store
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ In the following, a list of all supported languages with their supported languag
| [Scala](https://www.scala-lang.org) | 2.13.8 | scala | beta | Scalameta |
| [Scheme](http://www.scheme-reports.org) | ? | scheme | unknown | JavaCC |
| [Swift](https://www.swift.org) | 5.4 | swift | beta | ANTLR 4 |
| [EMF Metamodel](https://www.eclipse.org/modeling/emf/) | 2.25.0 | emf | alpha | EMF |
| [EMF Metamodel](https://www.eclipse.org/modeling/emf/) | 2.25.0 | emf | beta | EMF |
| [EMF Model](https://www.eclipse.org/modeling/emf/) | 2.25.0 | emf-model | alpha | EMF |
| Text (naive) | - | text | legacy | CoreNLP |

## Download and Installation
Expand Down
5 changes: 5 additions & 0 deletions cli/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@
<artifactId>emf-metamodel</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>de.jplag</groupId>
<artifactId>emf-model</artifactId>
<version>${revision}</version>
</dependency>
<!-- CLI -->
<dependency>
<groupId>org.kohsuke.metainf-services</groupId>
Expand Down
2 changes: 1 addition & 1 deletion cli/src/test/java/de/jplag/cli/LanguageTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ void testInvalidLanguage() throws Exception {
@Test
void testLoading() {
var languages = LanguageLoader.getAllAvailableLanguages();
assertEquals(15, languages.size(), "Loaded Languages: " + languages.keySet());
assertEquals(16, languages.size(), "Loaded Languages: " + languages.keySet());
}

@Test
Expand Down
7 changes: 7 additions & 0 deletions core/src/main/java/de/jplag/SubmissionSetBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,13 @@ public SubmissionSet buildSubmissionSet() throws ExitException {

// Merge everything in a submission set.
List<Submission> submissions = new ArrayList<>(foundSubmissions.values());

// Some languages expect a certain order, which is ensured here:
if (options.language().expectsSubmissionOrder()) {
List<File> rootFiles = foundSubmissions.values().stream().map(it -> it.getRoot()).toList();
rootFiles = options.language().customizeSubmissionOrder(rootFiles);
submissions = new ArrayList<>(rootFiles.stream().map(foundSubmissions::get).toList());
}
return new SubmissionSet(submissions, baseCodeSubmission.orElse(null), options);
}

Expand Down
10 changes: 10 additions & 0 deletions coverage-report/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,16 @@
<artifactId>emf-metamodel</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>de.jplag</groupId>
<artifactId>emf-metamodel-dynamic</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>de.jplag</groupId>
<artifactId>emf-model</artifactId>
<version>${revision}</version>
</dependency>
</dependencies>
<build>
<plugins>
Expand Down
17 changes: 17 additions & 0 deletions language-api/src/main/java/de/jplag/Language.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,21 @@ default boolean useViewFiles() {
default String viewFileSuffix() {
return "";
}

/**
* Specifies if the submission order is relevant for this language.
* @return defaults to false.
*/
default boolean expectsSubmissionOrder() {
return false;
}

/**
* Re-orders the provided submission according the requirements of the language.
* @param submissions is the list of submissions.
* @return the re-ordered list.
*/
default List<File> customizeSubmissionOrder(List<File> submissions) {
return submissions;
}
tsaglam marked this conversation as resolved.
Show resolved Hide resolved
}
10 changes: 10 additions & 0 deletions language-api/src/main/java/de/jplag/Token.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@ public Token(TokenType type, File file, int line, int column, int length) {
this.length = length;
}

/**
* Creates a token with column and length information.
* @param type is the token type.
* @param file is the name of the source code file.
* @param trace is the tracing information of the token, meaning line, column, and length.
*/
public Token(TokenType type, File file, TokenTrace trace) {
this(type, file, trace.line(), trace.column(), trace.length());
}

/**
* Creates a token with column, length and semantic information.
* @param type is the token type.
Expand Down
17 changes: 17 additions & 0 deletions language-api/src/main/java/de/jplag/TokenTrace.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package de.jplag;

/**
* Tracing information to locate the corresponding code section of a token.
* @param line is the line index in the source code where the token resides. Index is 1-based.
* @param column is the column index, meaning where the token starts in the line. Index is 1-based.
* @param length is the length of the token in the source code.
*/
public record TokenTrace(int line, int column, int length) {

/**
* Creates a empty trace with line, column, and length set to {@link Token#NO_VALUE NO_VALUE}.
*/
public TokenTrace() {
this(Token.NO_VALUE, Token.NO_VALUE, Token.NO_VALUE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import org.eclipse.emf.ecore.EObject;

import de.jplag.TokenTrace;
import de.jplag.TokenType;
import de.jplag.emf.MetamodelToken;

Expand All @@ -15,7 +16,7 @@
public class DynamicMetamodelToken extends MetamodelToken {

public DynamicMetamodelToken(TokenType type, File file, EObject eObject) {
super(type, file, NO_VALUE, NO_VALUE, NO_VALUE, Optional.of(eObject));
super(type, file, new TokenTrace(), Optional.of(eObject));
}

public DynamicMetamodelToken(TokenType type, File file) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ public DynamicMetamodelTokenType(EObject eObject) {
this(eObject.eClass());
}

@Override
public String getDescription() {
return eClass.getName();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,33 @@
package de.jplag.emf.dynamic;

import org.kohsuke.MetaInfServices;

import de.jplag.emf.dynamic.parser.DynamicEcoreParser;
import de.jplag.emf.parser.EcoreParser;

/**
* Language for EMF metamodels from the Eclipse Modeling Framework (EMF). This language is based on a dynamically
* created token set instead of a hand-picked one.
* @author Timur Saglam
*/
@MetaInfServices(de.jplag.Language.class)
public class Language extends de.jplag.emf.Language {
public class Language extends de.jplag.emf.Language { // currently not included in the CLI
private static final String NAME = "EMF metamodels (dynamically created token set)";
private static final String IDENTIFIER = "emf-dynamic";

private static final int DEFAULT_MIN_TOKEN_MATCH = 10;

/**
* Creates an EMF language instance with a dynamic token parser.
*/
public Language() {
super(new DynamicEcoreParser());
}

/**
* Creates an EMF language instance with a custom token parser.
*/
public Language(EcoreParser parser) {
super(parser);
}

@Override
public String getName() {
return NAME;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package de.jplag.emf.dynamic.parser;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;

import de.jplag.TokenType;
import de.jplag.emf.MetamodelToken;
import de.jplag.emf.dynamic.DynamicMetamodelToken;
import de.jplag.emf.dynamic.DynamicMetamodelTokenType;
import de.jplag.emf.normalization.ModelSorter;
import de.jplag.emf.parser.EcoreParser;
import de.jplag.emf.util.AbstractMetamodelVisitor;

Expand All @@ -14,12 +16,24 @@
*/
public class DynamicEcoreParser extends EcoreParser {

private final DynamicElementTokenizer tokenizer;

public DynamicEcoreParser() {
tokenizer = new DynamicElementTokenizer();
}

@Override
protected AbstractMetamodelVisitor createMetamodelVisitor() {
return new DynamicMetamodelTokenGenerator(this);
return new DynamicMetamodelTokenGenerator(this, tokenizer);
}

public void addToken(DynamicMetamodelTokenType type, EObject source) {
@Override
protected void normalizeOrder(Resource modelResource) {
ModelSorter.sort(modelResource, tokenizer);
}

@Override
public void addToken(TokenType type, EObject source) {
MetamodelToken token = new DynamicMetamodelToken(type, currentFile, source);
MetamodelToken metadataEnrichedToken = treeView.convertToMetadataEnrichedToken(token);
tokens.add(metadataEnrichedToken);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package de.jplag.emf.dynamic.parser;

import java.util.HashSet;
import java.util.Set;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;

import de.jplag.TokenType;
import de.jplag.emf.dynamic.DynamicMetamodelTokenType;
import de.jplag.emf.parser.ModelingElementTokenizer;

/**
* Tokenizes any {@link EObject} via its {@link EClass}. Tracks all known tokens.
*/
public class DynamicElementTokenizer implements ModelingElementTokenizer {

private final Set<TokenType> knownTokenTypes;

/**
* Creates the tokenizer, initially with an empty token set.
*/
public DynamicElementTokenizer() {
knownTokenTypes = new HashSet<>();
}

@Override
public TokenType element2Token(EObject modelElement) {
DynamicMetamodelTokenType token = new DynamicMetamodelTokenType(modelElement);
knownTokenTypes.add(token);
return token;
}

@Override
public Set<TokenType> allTokenTypes() {
return Set.copyOf(knownTokenTypes);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import org.eclipse.emf.ecore.EObject;

import de.jplag.emf.dynamic.DynamicMetamodelTokenType;
import de.jplag.emf.util.AbstractMetamodelVisitor;

/**
Expand All @@ -11,19 +10,19 @@
*/
public class DynamicMetamodelTokenGenerator extends AbstractMetamodelVisitor {
private final DynamicEcoreParser parser;
private final DynamicElementTokenizer tokenizer;

/**
* Creates the visitor.
* @param parser is the parser which receives the generated tokens.
*/
public DynamicMetamodelTokenGenerator(DynamicEcoreParser parser) {
super(false);
public DynamicMetamodelTokenGenerator(DynamicEcoreParser parser, DynamicElementTokenizer tokenizer) {
this.parser = parser;
this.tokenizer = tokenizer;
}

@Override
protected void visitEObject(EObject eObject) {
var tokenType = new DynamicMetamodelTokenType(eObject);
parser.addToken(tokenType, eObject);
parser.addToken(tokenizer.element2Token(eObject), eObject);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -42,6 +43,7 @@ public void setUp() {
}

@Test
@DisplayName("Test tokens generated from example metamodels")
void testBookstoreMetamodels() throws ParsingException {
List<File> testFiles = Arrays.stream(TEST_SUBJECTS).map(path -> new File(BASE_PATH.toFile(), path)).toList();
List<Token> result = language.parse(new HashSet<>(testFiles));
Expand Down
2 changes: 1 addition & 1 deletion languages/emf-metamodel/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<dependency>
<groupId>org.eclipse.emfatic</groupId>
<artifactId>org.eclipse.emfatic.core</artifactId>
<version>1.0.0</version>
<version>${emfatic.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.emf</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.eclipse.emf.ecore.EObject;

import de.jplag.Token;
import de.jplag.TokenTrace;
import de.jplag.TokenType;

/**
Expand All @@ -22,8 +23,8 @@ public class MetamodelToken extends Token {
* @param file is the source model file.
* @param eObject is the corresponding eObject in the model from which this token was extracted.
*/
public MetamodelToken(MetamodelTokenType type, File file, EObject eObject) {
this(type, file, NO_VALUE, NO_VALUE, NO_VALUE, Optional.of(eObject));
public MetamodelToken(TokenType type, File file, EObject eObject) {
this(type, file, new TokenTrace(), Optional.of(eObject));
}

/**
Expand All @@ -32,20 +33,18 @@ public MetamodelToken(MetamodelTokenType type, File file, EObject eObject) {
* @param file is the source model file.
*/
public MetamodelToken(TokenType type, File file) {
this(type, file, NO_VALUE, NO_VALUE, NO_VALUE, Optional.empty());
this(type, file, new TokenTrace(), Optional.empty());
}

/**
* Creates a token with column and length information.
* @param type is the token type.
* @param file is the source code file.
* @param line is the line index in the source code where the token resides. Cannot be smaller than 1.
* @param column is the column index, meaning where the token starts in the line.
* @param length is the length of the token in the source code.
* @param trace is the tracing information of the token, meaning line, column, and length.
* @param eObject is the corresponding eObject in the model from which this token was extracted
*/
public MetamodelToken(TokenType type, File file, int line, int column, int length, Optional<EObject> eObject) {
super(type, file, line, column, length);
public MetamodelToken(TokenType type, File file, TokenTrace trace, Optional<EObject> eObject) {
super(type, file, trace);
this.eObject = eObject;
}

Expand Down
Loading