Search in sources :

Example 1 with TransformException

use of org.metaborg.core.transform.TransformException in project spoofax by metaborg.

the class StrategoTransformer method transformAllAnalyzed.

@Override
public Collection<ISpoofaxTransformUnit<ISpoofaxAnalyzeUnit>> transformAllAnalyzed(Iterable<ISpoofaxAnalyzeUnit> inputs, IContext context, TransformActionContrib action, ITransformConfig config) throws TransformException {
    final int size = Iterables.size(inputs);
    final Collection<ISpoofaxTransformUnit<ISpoofaxAnalyzeUnit>> transformUnits = Lists.newArrayListWithCapacity(size);
    for (ISpoofaxAnalyzeUnit input : inputs) {
        if (!input.valid()) {
            throw new TransformException("Cannot transform analyze unit " + input + ", it is not valid");
        }
        if (!input.hasAst()) {
            throw new TransformException("Cannot transform analyze unit " + input + ", it has no AST");
        }
        transformUnits.add(transform(input, context, action, input.source(), input.ast(), config));
    }
    return transformUnits;
}
Also used : ISpoofaxTransformUnit(org.metaborg.spoofax.core.unit.ISpoofaxTransformUnit) TransformException(org.metaborg.core.transform.TransformException) ISpoofaxAnalyzeUnit(org.metaborg.spoofax.core.unit.ISpoofaxAnalyzeUnit)

Example 2 with TransformException

use of org.metaborg.core.transform.TransformException in project spoofax by metaborg.

the class Builder method transform.

private Collection<T> transform(BuildInput input, ILanguageImpl langImpl, FileObject location, Multimap<IContext, A> allAnalysisUnits, Set<FileName> includeFiles, boolean pardoned, Set<FileName> removedResources, Collection<IMessage> extraMessages, RefBool success, IProgress progress, ICancel cancel) throws InterruptedException {
    final int size = allAnalysisUnits.size();
    progress.setWorkRemaining(size);
    final Collection<T> allTransformUnits = Lists.newArrayListWithCapacity(size);
    if (size == 0) {
        return allTransformUnits;
    }
    progress.setDescription("Compiling " + size + " file(s) of " + langImpl.belongsTo().name());
    logger.debug("Compiling {} analysis results", size);
    for (Entry<IContext, Collection<A>> entry : allAnalysisUnits.asMap().entrySet()) {
        cancel.throwIfCancelled();
        final IContext context = entry.getKey();
        final Iterable<A> analysisResults = entry.getValue();
        try (IClosableLock lock = context.read()) {
            for (A analysisResult : analysisResults) {
                cancel.throwIfCancelled();
                final FileObject source = analysisResult.source();
                final FileName name = source.getName();
                if (removedResources.contains(name) || includeFiles.contains(name)) {
                    // Don't compile removed resources, which the analysis results contain for legacy reasons.
                    // Don't transform included resources, they should just be parsed and analyzed.
                    progress.work(1);
                    continue;
                }
                if (!analysisResult.valid()) {
                    logger.warn("Input result for {} is invalid, cannot transform it", source != null ? source.getName().getPath() : "detached source");
                    progress.work(1);
                    continue;
                }
                for (ITransformGoal goal : input.transformGoals) {
                    cancel.throwIfCancelled();
                    if (!transformService.available(context, goal)) {
                        logger.trace("No {} transformation required for {}", goal, context.language());
                        progress.work(1);
                        continue;
                    }
                    try {
                        final Collection<TA> results = transformService.transform(analysisResult, context, goal);
                        for (TA result : results) {
                            final boolean noErrors = printMessages(result.messages(), goal + " transformation", input, pardoned);
                            success.and(noErrors);
                            @SuppressWarnings("unchecked") final T genericResult = (T) result;
                            allTransformUnits.add(genericResult);
                        }
                        progress.work(1);
                    } catch (TransformException e) {
                        final String message = String.format("Transformation failed unexpectedly for %s", name);
                        logger.error(message, e);
                        final boolean noErrors = printMessage(source, message, e, input, pardoned);
                        success.and(noErrors);
                        extraMessages.add(MessageFactory.newBuilderErrorAtTop(location, "Transformation failed unexpectedly", e));
                    }
                }
            }
        // GTODO: also compile any affected sources
        }
    }
    return allTransformUnits;
}
Also used : IContext(org.metaborg.core.context.IContext) FileName(org.apache.commons.vfs2.FileName) TransformException(org.metaborg.core.transform.TransformException) ITransformGoal(org.metaborg.core.action.ITransformGoal) Collection(java.util.Collection) IClosableLock(org.metaborg.util.concurrent.IClosableLock) FileObject(org.apache.commons.vfs2.FileObject)

Example 3 with TransformException

use of org.metaborg.core.transform.TransformException in project spoofax by metaborg.

the class StrategoTransformer method transform.

private <I extends IUnit> ISpoofaxTransformUnit<I> transform(I input, IContext context, TransformActionContrib actionContribution, FileObject source, IStrategoTerm term, ITransformConfig config) throws TransformException {
    final FileObject location = context.location();
    final ILanguageComponent component = actionContribution.contributor;
    final TransformAction action = action(actionContribution.action);
    // Get input term
    final IStrategoTerm inputTerm = common.builderInputTerm(term, source, location);
    // Get Stratego runtime
    final HybridInterpreter runtime;
    try {
        runtime = strategoRuntimeService.runtime(component, context, true);
    } catch (MetaborgException e) {
        throw new TransformException("Transformation failed unexpectedly; cannot get Stratego interpreter", e);
    }
    // Transform
    logger.debug("Transforming {} with '{}'", source, action.name);
    final Timer timer = new Timer(true);
    final IStrategoTerm outputTerm;
    try {
        outputTerm = common.invoke(runtime, inputTerm, action.strategy);
    } catch (MetaborgException e) {
        throw new TransformException(e.getMessage(), e.getCause());
    }
    final long duration = timer.stop();
    if (outputTerm == null) {
        final String message = logger.format("Invoking Stratego strategy {} failed", action.strategy);
        throw new TransformException(message);
    }
    // Get the result and, if allowed and required, write to file
    List<TransformOutput> outputs;
    IStrategoTerm resultTerm;
    if (outputTerm.getSubtermCount() == 2 && (outputTerm instanceof IStrategoTuple)) {
        final IStrategoTerm resourceTerm = outputTerm.getSubterm(0);
        final IStrategoTerm contentTerm = outputTerm.getSubterm(1);
        try {
            if (resourceTerm instanceof IStrategoString) {
                resultTerm = contentTerm;
                outputs = Lists.newArrayList(output(resourceTerm, contentTerm, location, config));
            } else if (resourceTerm instanceof IStrategoList) {
                if (!(contentTerm instanceof IStrategoList) || resourceTerm.getSubtermCount() != contentTerm.getSubtermCount()) {
                    logger.error("List of terms does not match list of file names, cannot write to file.");
                    resultTerm = null;
                    outputs = Collections.emptyList();
                } else {
                    outputs = Lists.newArrayListWithExpectedSize(resourceTerm.getSubtermCount());
                    for (int i = 0; i < resourceTerm.getSubtermCount(); i++) {
                        outputs.add(output(resourceTerm.getSubterm(i), contentTerm.getSubterm(i), location, config));
                    }
                    resultTerm = resourceTerm.getSubtermCount() == 1 ? resourceTerm.getSubterm(0) : null;
                }
            } else {
                logger.error("First term of result tuple {} is neither a string, nor a list, cannot write output file", resourceTerm);
                resultTerm = null;
                outputs = Collections.emptyList();
            }
        } catch (MetaborgException ex) {
            resultTerm = null;
            outputs = Collections.emptyList();
        }
    } else {
        resultTerm = outputTerm;
        outputs = Collections.emptyList();
    }
    // Open editor
    if (action.flags.openEditor) {
        List<FileObject> resources = Lists.newArrayListWithExpectedSize(outputs.size());
        for (TransformOutput output : outputs) {
            if (output.resource != null) {
                resources.add(output.resource);
            }
        }
        editorRegistry.open(resources, context.project());
    }
    // Return result
    final TransformContrib contrib = new TransformContrib(resultTerm != null || !Iterables.isEmpty(outputs), true, resultTerm, outputs, Iterables2.<IMessage>empty(), duration);
    return unitService.transformUnit(input, contrib, context, actionContribution);
}
Also used : IStrategoTerm(org.spoofax.interpreter.terms.IStrategoTerm) TransformOutput(org.metaborg.spoofax.core.unit.TransformOutput) MetaborgException(org.metaborg.core.MetaborgException) TransformAction(org.metaborg.spoofax.core.action.TransformAction) ITransformAction(org.metaborg.core.action.ITransformAction) HybridInterpreter(org.strategoxt.HybridInterpreter) TransformException(org.metaborg.core.transform.TransformException) IStrategoTuple(org.spoofax.interpreter.terms.IStrategoTuple) IStrategoString(org.spoofax.interpreter.terms.IStrategoString) IStrategoList(org.spoofax.interpreter.terms.IStrategoList) IStrategoString(org.spoofax.interpreter.terms.IStrategoString) Timer(org.metaborg.util.time.Timer) FileObject(org.apache.commons.vfs2.FileObject) TransformContrib(org.metaborg.spoofax.core.unit.TransformContrib) ILanguageComponent(org.metaborg.core.language.ILanguageComponent)

Aggregations

TransformException (org.metaborg.core.transform.TransformException)3 FileObject (org.apache.commons.vfs2.FileObject)2 Collection (java.util.Collection)1 FileName (org.apache.commons.vfs2.FileName)1 MetaborgException (org.metaborg.core.MetaborgException)1 ITransformAction (org.metaborg.core.action.ITransformAction)1 ITransformGoal (org.metaborg.core.action.ITransformGoal)1 IContext (org.metaborg.core.context.IContext)1 ILanguageComponent (org.metaborg.core.language.ILanguageComponent)1 TransformAction (org.metaborg.spoofax.core.action.TransformAction)1 ISpoofaxAnalyzeUnit (org.metaborg.spoofax.core.unit.ISpoofaxAnalyzeUnit)1 ISpoofaxTransformUnit (org.metaborg.spoofax.core.unit.ISpoofaxTransformUnit)1 TransformContrib (org.metaborg.spoofax.core.unit.TransformContrib)1 TransformOutput (org.metaborg.spoofax.core.unit.TransformOutput)1 IClosableLock (org.metaborg.util.concurrent.IClosableLock)1 Timer (org.metaborg.util.time.Timer)1 IStrategoList (org.spoofax.interpreter.terms.IStrategoList)1 IStrategoString (org.spoofax.interpreter.terms.IStrategoString)1 IStrategoTerm (org.spoofax.interpreter.terms.IStrategoTerm)1 IStrategoTuple (org.spoofax.interpreter.terms.IStrategoTuple)1