Просмотр исходного кода

Parse EClass supertypes and indent in the tree view.

Timur Sağlam 4 лет назад
Родитель
Сommit
74b3ed3bc3

+ 68 - 17
jplag.frontend.emf/src/main/java/de/jplag/emf/EcoreParser.java

@@ -11,6 +11,7 @@ import static de.jplag.emf.MetamodelTokenConstants.OPERATION;
 import static de.jplag.emf.MetamodelTokenConstants.PACKAGE;
 import static de.jplag.emf.MetamodelTokenConstants.PARAMETER;
 import static de.jplag.emf.MetamodelTokenConstants.REFERENCE;
+import static de.jplag.emf.MetamodelTokenConstants.SUPER_TYPE;
 
 import java.io.BufferedWriter;
 import java.io.File;
@@ -48,13 +49,14 @@ import de.jplag.TokenList;
  * Parser for EMF metamodels.
  * @author Timur Saglam
  */
-public class EcoreParser extends AbstractParser {
+public class EcoreParser extends AbstractParser { // TODO TS: Currently combines parser with the tree view generation.
     private static final String TREE_VIEW_FILE_SUFFIX = ".tmp";
     private TokenList tokens;
     private String currentFile;
     private StringBuilder treeView;
     private int lineIndex;
     private int columnIndex;
+    private int indentation;
 
     /**
      * Creates the parser.
@@ -62,6 +64,10 @@ public class EcoreParser extends AbstractParser {
      */
     public EcoreParser(ErrorConsumer errorConsumer) {
         super(errorConsumer);
+        EcorePackage.eINSTANCE.eClass();
+        final Resource.Factory.Registry registry = Resource.Factory.Registry.INSTANCE;
+        final Map<String, Object> extensionMap = registry.getExtensionToFactoryMap();
+        extensionMap.put(EcorePackage.eNAME, new XMIResourceFactoryImpl());
     }
 
     /**
@@ -71,6 +77,7 @@ public class EcoreParser extends AbstractParser {
      * @return the list of parsed tokens.
      */
     public TokenList parse(File directory, List<String> fileNames) {
+        // TODO TS: When the submissions are files, the file names are empty and the directory is the file --> error
         tokens = new TokenList();
         errors = 0;
         for (String fileName : fileNames) {
@@ -81,7 +88,7 @@ public class EcoreParser extends AbstractParser {
             columnIndex = 0;
             parseEPackage(root);
 
-            tokens.addToken(new MetamodelToken(TokenConstants.FILE_END, fileName, -1, -1, -1));
+            tokens.addToken(new MetamodelToken(TokenConstants.FILE_END, currentFile, -1, -1, -1));
             createTreeViewFile(directory, fileName);
         }
         return tokens;
@@ -102,10 +109,7 @@ public class EcoreParser extends AbstractParser {
     }
 
     private EPackage loadModel(String directory, String name) {
-        EcorePackage.eINSTANCE.eClass();
-        final Resource.Factory.Registry registry = Resource.Factory.Registry.INSTANCE;
-        final Map<String, Object> extensionMap = registry.getExtensionToFactoryMap();
-        extensionMap.put(EcorePackage.eNAME, new XMIResourceFactoryImpl());
+
         final ResourceSet resourceSet = new ResourceSetImpl();
         Resource resource = resourceSet.getResource(URI.createFileURI(directory + File.separator + name), true);
         EObject content = resource.getContents().get(0);
@@ -117,9 +121,11 @@ public class EcoreParser extends AbstractParser {
 
     private void parseEPackage(EPackage ePackage) {
         addToken(PACKAGE, ePackage, true);
+        indentation++;
         ePackage.getEClassifiers().forEach(it -> parseEClassifier(it));
         ePackage.getEAnnotations().forEach(it -> parseEAnnotation(it));
         ePackage.getESubpackages().forEach(it -> parseEPackage(it));
+        indentation--;
     }
 
     private void parseEAnnotation(EAnnotation annotation) {
@@ -138,23 +144,32 @@ public class EcoreParser extends AbstractParser {
 
     private void parseEClass(EClass eClass) {
         if (eClass.isInterface()) {
-            addToken(INTERFACE, eClass, true);
+            addToken(INTERFACE, eClass, false);
         } else {
-            addToken(CLASS, eClass, true);
+            addToken(CLASS, eClass, false);
         }
+        indentation++;
         // TODO TS: Extract abstract? probably not
-        // TODO TS: Extract super type relation? probably
+        eClass.getESuperTypes().forEach(it -> parseESuperType(it));
+        addNewLine();
         eClass.getEStructuralFeatures().forEach(it -> parseEStructuralFeature(it));
         eClass.getEOperations().forEach(it -> parseEOperation(it));
+        indentation--;
+    }
+
+    private void parseESuperType(EClass superType) {
+        addToken(SUPER_TYPE, superType, false, " -> ");
     }
 
     private void parseEOperation(EOperation operation) {
         addToken(OPERATION, operation, true);
-        operation.getEParameters().forEach(it -> addToken(PARAMETER, it, false));
+        indentation++;
+        operation.getEParameters().forEach(it -> addToken(PARAMETER, it, true));
         // TODO TS: Extract return type?
         // TODO TS: Extract throws declarations?
         // TODO TS: Parse type parameters & generic type?
         operation.getEAnnotations().forEach(it -> parseEAnnotation(it));
+        indentation--;
     }
 
     private void parseEStructuralFeature(EStructuralFeature structuralFeature) {
@@ -164,7 +179,9 @@ public class EcoreParser extends AbstractParser {
             addToken(REFERENCE, reference, true);
             // TODO TS: Extract containment?
         }
+        indentation++;
         structuralFeature.getEAnnotations().forEach(it -> parseEAnnotation(it));
+        indentation--;
     }
 
     private void parseEDataType(EDataType dataType) {
@@ -173,30 +190,64 @@ public class EcoreParser extends AbstractParser {
         } else {
             addToken(DATATYPE, dataType, true);
         }
+        indentation++;
+        dataType.getEAnnotations().forEach(it -> parseEAnnotation(it));
+        indentation--;
     }
 
     private void parseEEnum(EEnum enumeration) {
         addToken(ENUM, enumeration, true);
+        indentation++;
         enumeration.getELiterals().forEach(it -> parseEEnumLiteral(it));
+        indentation--;
     }
 
     private void parseEEnumLiteral(EEnumLiteral enumeral) {
-        addToken(ENUM_LITERAL, enumeral, false);
+        addToken(ENUM_LITERAL, enumeral, true);
         enumeral.getEAnnotations().forEach(it -> parseEAnnotation(it));
     }
 
     private void addToken(int type, EObject source, boolean newLine) {
+        addToken(type, source, newLine, "");
+    }
+
+    private void addToken(int type, EObject source, boolean newLine, String prefix) {
+        int tokenLength = addTokenText(source, prefix);
+        tokens.addToken(new MetamodelToken(type, currentFile, lineIndex + 1, columnIndex + 1, tokenLength));
+        updateIndices(newLine, tokenLength);
+    }
+
+    private void updateIndices(boolean newLine, int tokenLength) {
         if (newLine) {
-            lineIndex++;
-            treeView.append(System.lineSeparator());
+            addNewLine();
+        } else {
+            columnIndex += tokenLength;
         }
-        String tokenText = source.getClass().getSimpleName().toString() + " ";
+    }
+
+    private void addNewLine() {
+        lineIndex++;
+        columnIndex = 0;
+        treeView.append(System.lineSeparator());
+    }
+
+    private int addTokenText(EObject source, String prefix) {
+        String tokenText = "(" + source.getClass().getInterfaces()[0].getSimpleName().toString() + ")";
         if (source instanceof ENamedElement element) {
-            tokenText += " " + element.getName();
+            tokenText = element.getName() + " " + tokenText;
         }
         int tokenLength = tokenText.length();
+        if (prefix.isEmpty()) {
+            for (int i = 0; i < indentation; i++) {
+                String indentationText = "  ";
+                tokenText = indentationText + tokenText;
+                columnIndex += indentationText.length();
+            }
+        } else {
+            tokenText = prefix + tokenText;
+            columnIndex += prefix.length();
+        }
         treeView.append(tokenText);
-        tokens.addToken(new MetamodelToken(type, currentFile, lineIndex, columnIndex, tokenLength));
-        columnIndex += tokenLength;
+        return tokenLength;
     }
 }

+ 1 - 0
jplag.frontend.emf/src/main/java/de/jplag/emf/MetamodelToken.java

@@ -35,6 +35,7 @@ public class MetamodelToken extends Token implements MetamodelTokenConstants {
             case ATTRIBUTE -> "EAttribute";
             case PARAMETER -> "EParameter";
             case INTERFACE -> "EInterface";
+            case SUPER_TYPE -> "ESuperType";
             case FILE_END -> "(EOF)";
             default -> "<UNKNOWN" + type + ">";
         };

+ 2 - 1
jplag.frontend.emf/src/main/java/de/jplag/emf/MetamodelTokenConstants.java

@@ -18,9 +18,10 @@ public interface MetamodelTokenConstants extends TokenConstants {
     int ATTRIBUTE = 10;
     int PARAMETER = 11;
     int INTERFACE = 12;
+    int SUPER_TYPE = 13;
 
     /*
      * Number of token constants:
      */
-    int NUM_DIFF_TOKENS = 13;
+    int NUM_DIFF_TOKENS = 14;
 }