Package org.sugarj.driver.transformations.primitive

Source Code of org.sugarj.driver.transformations.primitive.CompileTransformed

package org.sugarj.driver.transformations.primitive;

import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.TreeSet;

import org.spoofax.interpreter.core.IContext;
import org.spoofax.interpreter.core.InterpreterException;
import org.spoofax.interpreter.library.AbstractPrimitive;
import org.spoofax.interpreter.stratego.Strategy;
import org.spoofax.interpreter.terms.IStrategoTerm;
import org.spoofax.jsglr.shared.BadTokenException;
import org.sugarj.common.ATermCommands;
import org.sugarj.common.Environment;
import org.sugarj.common.FileCommands;
import org.sugarj.common.Log;
import org.sugarj.common.path.AbsolutePath;
import org.sugarj.common.path.Path;
import org.sugarj.common.path.RelativePath;
import org.sugarj.driver.Driver;
import org.sugarj.driver.ImportCommands;
import org.sugarj.driver.ModuleSystemCommands;
import org.sugarj.driver.Result;
import org.sugarj.util.Renaming;

/**
* Primitive for looking up and loading a model according to the current environment.
* If successful, this primitive returns the loaded model as a term.
*
* @author seba
*/
class CompileTransformed extends AbstractPrimitive {

  private Driver driver;
  private Environment environment;
 
  public CompileTransformed(Driver driver, Environment environment) {
    super("SUGARJ_compile", 0, 2);
    this.driver = driver;
    this.environment = environment;
  }

  @Override
  public boolean call(IContext context, Strategy[] svars, IStrategoTerm[] tvars) throws InterpreterException {
    try {
      IStrategoTerm generatedModel = context.current();
     
      if (!ATermCommands.isString(tvars[0]) || !ATermCommands.isString(tvars[1]))
        return false;
     
      String modelPath = ATermCommands.getString(tvars[0]);
      RelativePath modelRelativePath = new RelativePath(modelPath);
     
      IStrategoTerm transformationsTerm = tvars[1];
      RelativePath transformationPath = new RelativePath(ATermCommands.getString(transformationsTerm));
     
      RelativePath source = ImportCommands.getTransformedModelSourceFilePath(modelRelativePath, transformationPath, environment);
     
      try {
        Renaming ren = new Renaming(modelPath, source.getRelativePath());
        environment.getRenamings().add(0, ren);
//        generatedModel = driver.currentRename(generatedModel);
       
        driver.getCurrentResult().generateFile(source, ATermCommands.atermToString(generatedModel));
      } catch (IOException e) {
        driver.setErrorMessage(e.getLocalizedMessage());
      }
     
      Result res;
      try {
        res = driver.subcompile(driver.getTreeForErrorMarking(), source);
       
        if (res != null) {
          context.setCurrent(ATermCommands.atermFromFile(source.getAbsolutePath()));
         
          Result modelResult = ModuleSystemCommands.locateResult(FileCommands.dropExtension(modelPath), environment);
          if (modelResult != null)
            res.addDependency(modelResult);
          Result transformationResult = ModuleSystemCommands.locateResult(FileCommands.dropExtension(transformationPath.getRelativePath()), environment);
          if (transformationResult != null)
            res.addDependency(transformationResult);
        }
      } catch (Exception e) {
        e.printStackTrace();
        driver.setErrorMessage(e.getMessage());
        return false;
      } finally {
        environment.getRenamings().remove(0);
      }
     
      if (res == null)
        return false;
     
      try {
        if (res.hasFailed()) {
          for (BadTokenException e : res.getParseErrors())
            driver.setErrorMessage("line " + e.getLineNumber() + ": " + e.getLocalizedMessage());
          for (String err : res.getCollectedErrors())
            driver.setErrorMessage(err);
          return false;
        }
     
        checkCommunicationIntegrity(modelPath, transformationPath, source, res);
      } catch (IOException e) {
        e.printStackTrace();
        driver.setErrorMessage(e.getMessage());
      } catch (ClassNotFoundException e) {
        e.printStackTrace();
        driver.setErrorMessage(e.getMessage());
      } catch (Exception e) {
        e.printStackTrace();
        driver.setErrorMessage(e.getMessage());
      }
    } catch (Exception e) {
      e.printStackTrace();
      driver.setErrorMessage(e.getMessage());
    }
   
    return true;
  }
 
  private void checkCommunicationIntegrity(String modelPath, RelativePath transformationPath, RelativePath source, Result res) throws IOException, ClassNotFoundException {
    String error = null;
   
    Log.log.beginTask("Check communication integrity", Log.CORE);
    try {
      Collection<Path> modelDeps = new HashSet<Path>();
      Result modelResult = ModuleSystemCommands.locateResult(FileCommands.dropExtension(modelPath), environment);
      if (modelResult != null) {
        modelDeps.addAll(modelResult.getCircularFileDependencies(environment));
        modelDeps.addAll(modelResult.getDirectlyGeneratedFiles());
      }
 
      Collection<Path> transDeps = new HashSet<Path>();
      Result transResult = ModuleSystemCommands.locateResult(FileCommands.dropExtension(transformationPath.getRelativePath()), environment);
      if (transResult != null) {
        transDeps.addAll(transResult.getCircularFileDependencies(environment));
        transDeps.addAll(transResult.getDirectlyGeneratedFiles());
      }
 
      if (res.getPersistentPath() == null)
        res.writeDependencyFile(FileCommands.newTempFile("dep"));
      Collection<Path> transformedModelDeps = res.getCircularFileDependencies(environment);
      TreeSet<String> failed = new TreeSet<String>();
     
      for (Path p : transformedModelDeps) {
        boolean ok = false ||
            source.equals(p) ||
            res.getDirectlyGeneratedFiles().contains(p) ||
            modelDeps.contains(p) ||
            transDeps.contains(p);
        Result pRes = null;
        if (!ok) {
          // transformations may generate other artifacts, given that their dependencies in turn are marked in the current result
          Path dep = new AbsolutePath(FileCommands.dropExtension(p.getAbsolutePath()) + ".dep");
          if (FileCommands.exists(dep)) {
            pRes = Result.readDependencyFile(dep);
            if (pRes != null && pRes.isGenerated()) {
              boolean isContained = transformedModelDeps.containsAll(pRes.getCircularFileDependencies(environment));
              ok = isContained;
            }
          }
        }
        if (!ok)
          failed.add(FileCommands.dropExtension(p.getAbsolutePath()));
      }
 
      if (!failed.isEmpty()) {
        StringBuilder b = new StringBuilder("Violation of communication integrity in " + source.getRelativePath() + ": Generated model refers to the following artifacts, which neither the model nor the transformation refers to.\n");
        for (String p : failed)
          b.append("  ").append(p).append('\n');
        error = b.toString();
        driver.setErrorMessage(error);
      }
    } finally {
      if (error == null)
        Log.log.endTask(true);
      else
        Log.log.endTask(error);
    }
  }
}
TOP

Related Classes of org.sugarj.driver.transformations.primitive.CompileTransformed

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.