Search in sources :

Example 1 with Timer

use of org.metaborg.util.time.Timer in project spoofax by metaborg.

the class ConstraintMultiFileAnalyzer method analyzeSemiIncremental.

private ISpoofaxAnalyzeResults analyzeSemiIncremental(Map<String, ISpoofaxParseUnit> changed, java.util.Set<String> removed, IMultiFileScopeGraphContext context, HybridInterpreter runtime, String strategy, IProgress progress, ICancel cancel) throws AnalysisException {
    final NaBL2DebugConfig debugConfig = context.config().debug();
    final Timer totalTimer = new Timer(true);
    final AggregateTimer collectionTimer = new AggregateTimer();
    final AggregateTimer solverTimer = new AggregateTimer();
    final AggregateTimer finalizeTimer = new AggregateTimer();
    final String globalSource = "";
    final Function1<String, String> globalFresh = base -> context.unit(globalSource).fresh().fresh(base);
    for (String input : removed) {
        context.removeUnit(input);
    }
    final int n = changed.size();
    final int w = context.units().size() / 2;
    progress.setWorkRemaining(n + w + 1);
    if (debugConfig.analysis() || debugConfig.files()) {
        logger.info("Analyzing {} files in {}.", n, context.location());
    }
    final Collection<ISpoofaxAnalyzeUnit> results = Lists.newArrayList();
    final Collection<ISpoofaxAnalyzeUnitUpdate> updateResults = Lists.newArrayList();
    try {
        // initial
        InitialResult initialResult;
        final Optional<ITerm> customInitial;
        {
            if (debugConfig.collection()) {
                logger.info("Collecting initial constraints.");
            }
            if (context.initialResult().isPresent()) {
                initialResult = context.initialResult().get();
                customInitial = context.initialResult().flatMap(r -> r.getCustomResult());
            } else {
                collectionTimer.start();
                try {
                    final ITerm globalAST = Actions.sourceTerm(globalSource, B.EMPTY_TUPLE);
                    ITerm initialResultTerm = doAction(strategy, Actions.analyzeInitial(globalSource, globalAST), context, runtime).orElseThrow(() -> new AnalysisException(context, "No initial result."));
                    initialResult = InitialResult.matcher().match(initialResultTerm).orElseThrow(() -> new AnalysisException(context, "Invalid initial results."));
                    customInitial = doCustomAction(strategy, Actions.customInitial(globalSource, globalAST), context, runtime);
                    initialResult = initialResult.withCustomResult(customInitial);
                    context.setInitialResult(initialResult);
                } finally {
                    collectionTimer.stop();
                }
            }
            if (debugConfig.collection()) {
                logger.info("Initial constraints collected.");
            }
        }
        // global parameters, that form the interface for a single unit
        final java.util.Set<ITermVar> intfVars = Sets.newHashSet();
        {
            initialResult.getArgs().getParams().stream().forEach(param -> intfVars.addAll(param.getVars()));
            initialResult.getArgs().getType().ifPresent(type -> intfVars.addAll(type.getVars()));
        }
        final SemiIncrementalMultiFileSolver solver = new SemiIncrementalMultiFileSolver(context.config().debug(), callExternal(runtime));
        // global
        ISolution initialSolution;
        {
            if (context.initialSolution().isPresent()) {
                initialSolution = context.initialSolution().get();
            } else {
                try {
                    solverTimer.start();
                    final IProgress subprogress = progress.subProgress(1);
                    GraphSolution preSolution = solver.solveGraph(ImmutableBaseSolution.of(initialResult.getConfig(), initialResult.getConstraints(), PersistentUnifier.Immutable.of()), globalFresh, cancel, subprogress);
                    preSolution = solver.reportUnsolvedGraphConstraints(preSolution);
                    initialSolution = solver.solveIntra(preSolution, intfVars, null, globalFresh, cancel, subprogress);
                    if (debugConfig.resolution()) {
                        logger.info("Reduced file constraints to {}.", initialSolution.constraints().size());
                    }
                } catch (SolverException e) {
                    throw new AnalysisException(context, e);
                } finally {
                    solverTimer.stop();
                }
                context.setInitialSolution(initialSolution);
            }
        }
        final java.util.Set<Scope> intfScopes = Sets.newHashSet();
        {
            initialResult.getArgs().getParams().stream().forEach(param -> Scope.matcher().match(param, initialSolution.unifier()).ifPresent(intfScopes::add));
        }
        // units
        final Map<String, IStrategoTerm> astsByFile = Maps.newHashMap();
        final Map<String, IMessage> failures = Maps.newHashMap();
        final Multimap<String, IMessage> ambiguitiesByFile = HashMultimap.create();
        for (Map.Entry<String, ISpoofaxParseUnit> input : changed.entrySet()) {
            final String source = input.getKey();
            final ISpoofaxParseUnit parseUnit = input.getValue();
            final ITerm ast = strategoTerms.fromStratego(parseUnit.ast());
            if (debugConfig.files()) {
                logger.info("Analyzing {}.", source);
            }
            final IMultiFileScopeGraphUnit unit = context.unit(source);
            unit.clear();
            try {
                UnitResult unitResult;
                final Optional<ITerm> customUnit;
                {
                    if (debugConfig.collection()) {
                        logger.info("Collecting constraints of {}.", source);
                    }
                    try {
                        collectionTimer.start();
                        final ITerm unitResultTerm = doAction(strategy, Actions.analyzeUnit(source, ast, initialResult.getArgs()), context, runtime).orElseThrow(() -> new AnalysisException(context, "No unit result."));
                        unitResult = UnitResult.matcher().match(unitResultTerm).orElseThrow(() -> new MetaborgException("Invalid unit results."));
                        final ITerm desugaredAST = unitResult.getAST();
                        customUnit = doCustomAction(strategy, Actions.customUnit(source, desugaredAST, customInitial.orElse(B.EMPTY_TUPLE)), context, runtime);
                        unitResult = unitResult.withCustomResult(customUnit);
                        final IStrategoTerm analyzedAST = strategoTerms.toStratego(desugaredAST);
                        astsByFile.put(source, analyzedAST);
                        ambiguitiesByFile.putAll(source, analysisCommon.ambiguityMessages(parseUnit.source(), parseUnit.ast()));
                        unit.setUnitResult(unitResult);
                    } finally {
                        collectionTimer.stop();
                    }
                    if (debugConfig.collection()) {
                        logger.info("Collected {} constraints of {}.", unitResult.getConstraints().size(), source);
                    }
                }
                {
                    final ISolution unitSolution;
                    if (debugConfig.resolution()) {
                        logger.info("Reducing {} constraints of {}.", unitResult.getConstraints().size(), source);
                    }
                    try {
                        solverTimer.start();
                        final Function1<String, String> fresh = base -> context.unit(source).fresh().fresh(base);
                        final IProgress subprogress = progress.subProgress(1);
                        GraphSolution preSolution = solver.solveGraph(ImmutableBaseSolution.of(initialResult.getConfig(), unitResult.getConstraints(), initialSolution.unifier()), fresh, cancel, subprogress);
                        preSolution = solver.reportUnsolvedGraphConstraints(preSolution);
                        unitSolution = solver.solveIntra(preSolution, intfVars, intfScopes, fresh, cancel, subprogress);
                        if (debugConfig.resolution()) {
                            logger.info("Reduced file constraints to {}.", unitSolution.constraints().size());
                        }
                    } catch (SolverException e) {
                        throw new AnalysisException(context, e);
                    } finally {
                        solverTimer.stop();
                    }
                    unit.setPartialSolution(unitSolution);
                    if (debugConfig.files() || debugConfig.resolution()) {
                        logger.info("Analyzed {}: {} errors, {} warnings, {} notes, {} unsolved constraints.", source, unitSolution.messages().getErrors().size(), unitSolution.messages().getWarnings().size(), unitSolution.messages().getNotes().size(), unitSolution.constraints().size());
                    }
                }
            } catch (MetaborgException e) {
                logger.warn("Analysis of " + source + " failed.", e);
                failures.put(source, MessageFactory.newAnalysisErrorAtTop(parseUnit.source(), "File analysis failed.", e));
            }
        }
        // solve
        final ISolution solution;
        final List<Optional<ITerm>> customUnits = Lists.newArrayList();
        {
            final List<ISolution> partialSolutions = Lists.newArrayList();
            for (IMultiFileScopeGraphUnit unit : context.units()) {
                unit.partialSolution().ifPresent(partialSolutions::add);
                unit.unitResult().map(UnitResult::getCustomResult).ifPresent(customUnits::add);
            }
            if (debugConfig.resolution()) {
                logger.info("Solving {} partial solutions.", partialSolutions.size());
            }
            ISolution sol;
            try {
                solverTimer.start();
                Function1<String, String> fresh = base -> context.unit(globalSource).fresh().fresh(base);
                IMessageInfo message = ImmutableMessageInfo.of(MessageKind.ERROR, MessageContent.of(), Actions.sourceTerm(globalSource));
                sol = solver.solveInter(initialSolution, partialSolutions, message, fresh, cancel, progress.subProgress(w));
                sol = solver.reportUnsolvedConstraints(sol);
            } catch (SolverException e) {
                throw new AnalysisException(context, e);
            } finally {
                solverTimer.stop();
            }
            if (!sol.flowSpecSolution().controlFlowGraph().isEmpty()) {
                logger.debug("CFG is not empty: calling FlowSpec dataflow solver");
                sol = new FixedPoint().entryPoint(sol, getFlowSpecTransferFunctions(context.language()));
            }
            solution = sol;
            context.setSolution(solution);
            if (debugConfig.resolution()) {
                logger.info("Project constraints solved.");
            }
        }
        // final
        FinalResult finalResult;
        final Optional<ITerm> customFinal;
        final Optional<CustomSolution> customSolution;
        {
            if (debugConfig.analysis()) {
                logger.info("Finalizing project analysis.");
            }
            finalizeTimer.start();
            try {
                ITerm finalResultTerm = doAction(strategy, Actions.analyzeFinal(globalSource), context, runtime).orElseThrow(() -> new AnalysisException(context, "No final result."));
                finalResult = FinalResult.matcher().match(finalResultTerm, solution.unifier()).orElseThrow(() -> new AnalysisException(context, "Invalid final results."));
                customFinal = doCustomAction(strategy, Actions.customFinal(globalSource, customInitial.orElse(B.EMPTY_TUPLE), Optionals.filter(customUnits)), context, runtime);
                finalResult = finalResult.withCustomResult(customFinal);
                context.setFinalResult(finalResult);
                customSolution = customFinal.flatMap(cs -> CustomSolution.matcher().match(cs, solution.unifier()));
                customSolution.ifPresent(cs -> context.setCustomSolution(cs));
            } finally {
                finalizeTimer.stop();
            }
            if (debugConfig.analysis()) {
                logger.info("Project analysis finalized.");
            }
        }
        // errors
        {
            if (debugConfig.analysis()) {
                logger.info("Processing project messages.");
            }
            Messages.Transient messageBuilder = Messages.Transient.of();
            messageBuilder.addAll(Messages.unsolvedErrors(solution.constraints()));
            messageBuilder.addAll(solution.messages().getAll());
            customSolution.map(CustomSolution::getMessages).map(IMessages::getAll).ifPresent(messageBuilder::addAll);
            IMessages messages = messageBuilder.freeze();
            IRelation3.Transient<String, MessageSeverity, IMessage> messagesByFile = HashTrieRelation3.Transient.of();
            messagesByFile(failures.values(), messagesByFile, context);
            messagesByFile(messages(messages.getAll(), solution.unifier(), context, context.location()), messagesByFile, context);
            // precondition: the messagesByFile should not contain any files that do not have corresponding units
            for (IMultiFileScopeGraphUnit unit : context.units()) {
                final String source = unit.resource();
                final java.util.Set<IMessage> fileMessages = messagesByFile.get(source).stream().map(Map.Entry::getValue).collect(Collectors2.toHashSet());
                if (changed.containsKey(source)) {
                    fileMessages.addAll(ambiguitiesByFile.get(source));
                    final boolean valid = !failures.containsKey(source);
                    final boolean success = valid && messagesByFile.get(source, MessageSeverity.ERROR).isEmpty();
                    final IStrategoTerm analyzedAST = astsByFile.get(source);
                    results.add(unitService.analyzeUnit(changed.get(source), new AnalyzeContrib(valid, success, analyzedAST != null, analyzedAST, fileMessages, -1), context));
                } else {
                    try {
                        final FileObject file = context.location().resolveFile(source);
                        updateResults.add(unitService.analyzeUnitUpdate(file, new AnalyzeUpdateData(fileMessages), context));
                    } catch (IOException ex) {
                        logger.error("Could not resolve {} to update messages", source);
                    }
                }
                messagesByFile.remove(source);
            }
            if (!messagesByFile.keySet().isEmpty()) {
                logger.error("Found messages for unanalyzed files {}", messagesByFile.keySet());
            }
            if (debugConfig.analysis() || debugConfig.files() || debugConfig.resolution()) {
                logger.info("Analyzed {} files: {} errors, {} warnings, {} notes.", n, messages.getErrors().size(), messages.getWarnings().size(), messages.getNotes().size());
            }
        }
    } catch (InterruptedException e) {
        logger.debug("Analysis was interrupted.");
    } finally {
        totalTimer.stop();
    }
    final ConstraintDebugData debugData = new ConstraintDebugData(totalTimer.stop(), collectionTimer.total(), solverTimer.total(), finalizeTimer.total());
    if (debugConfig.analysis()) {
        logger.info("{}", debugData);
    }
    return new SpoofaxAnalyzeResults(results, updateResults, context, debugData);
}
Also used : UnitResult(mb.nabl2.spoofax.analysis.UnitResult) ITerm(mb.nabl2.terms.ITerm) ISpoofaxAnalyzeUnit(org.metaborg.spoofax.core.unit.ISpoofaxAnalyzeUnit) IProgress(org.metaborg.util.task.IProgress) Inject(com.google.inject.Inject) IRelation3(mb.nabl2.util.collections.IRelation3) MetaborgException(org.metaborg.core.MetaborgException) HashMultimap(com.google.common.collect.HashMultimap) ICancel(org.metaborg.util.task.ICancel) Map(java.util.Map) ITermVar(mb.nabl2.terms.ITermVar) SolverException(mb.nabl2.solver.SolverException) ISolution(mb.nabl2.solver.ISolution) IStrategoTerm(org.spoofax.interpreter.terms.IStrategoTerm) B(mb.nabl2.terms.build.TermBuild.B) GraphSolution(mb.nabl2.solver.solvers.BaseSolver.GraphSolution) ISpoofaxAnalyzer(org.metaborg.spoofax.core.analysis.ISpoofaxAnalyzer) ISpoofaxParseUnit(org.metaborg.spoofax.core.unit.ISpoofaxParseUnit) Collection(java.util.Collection) ISpoofaxTracingService(org.metaborg.spoofax.core.tracing.ISpoofaxTracingService) IMessageInfo(mb.nabl2.constraints.messages.IMessageInfo) SemiIncrementalMultiFileSolver(mb.nabl2.solver.solvers.SemiIncrementalMultiFileSolver) AnalyzeUpdateData(org.metaborg.spoofax.core.unit.AnalyzeUpdateData) Sets(com.google.common.collect.Sets) FinalResult(mb.nabl2.spoofax.analysis.FinalResult) List(java.util.List) Optionals(org.metaborg.util.optionals.Optionals) Optional(java.util.Optional) LoggerUtils(org.metaborg.util.log.LoggerUtils) Timer(org.metaborg.util.time.Timer) ImmutableBaseSolution(mb.nabl2.solver.solvers.ImmutableBaseSolution) IMultiFileScopeGraphContext(org.metaborg.spoofax.core.context.scopegraph.IMultiFileScopeGraphContext) ITermFactoryService(org.metaborg.spoofax.core.terms.ITermFactoryService) AggregateTimer(org.metaborg.util.time.AggregateTimer) Function1(org.metaborg.util.functions.Function1) AnalysisCommon(org.metaborg.spoofax.core.analysis.AnalysisCommon) ISpoofaxAnalyzeResults(org.metaborg.spoofax.core.analysis.ISpoofaxAnalyzeResults) Multimap(com.google.common.collect.Multimap) Actions(mb.nabl2.spoofax.analysis.Actions) Lists(com.google.common.collect.Lists) ISpoofaxAnalyzeUnitUpdate(org.metaborg.spoofax.core.unit.ISpoofaxAnalyzeUnitUpdate) IMultiFileScopeGraphUnit(org.metaborg.spoofax.core.context.scopegraph.IMultiFileScopeGraphUnit) ISpoofaxUnitService(org.metaborg.spoofax.core.unit.ISpoofaxUnitService) HybridInterpreter(org.strategoxt.HybridInterpreter) PersistentUnifier(mb.nabl2.terms.unification.PersistentUnifier) ILogger(org.metaborg.util.log.ILogger) ImmutableMessageInfo(mb.nabl2.constraints.messages.ImmutableMessageInfo) HashTrieRelation3(mb.nabl2.util.collections.HashTrieRelation3) Messages(mb.nabl2.solver.messages.Messages) IOException(java.io.IOException) MessageKind(mb.nabl2.constraints.messages.MessageKind) Scope(mb.nabl2.scopegraph.terms.Scope) CustomSolution(mb.nabl2.spoofax.analysis.CustomSolution) IMessage(org.metaborg.core.messages.IMessage) FileObject(org.apache.commons.vfs2.FileObject) Maps(com.google.common.collect.Maps) NaBL2DebugConfig(mb.nabl2.config.NaBL2DebugConfig) MessageContent(mb.nabl2.constraints.messages.MessageContent) AnalyzeContrib(org.metaborg.spoofax.core.unit.AnalyzeContrib) IMessages(mb.nabl2.solver.messages.IMessages) SpoofaxAnalyzeResults(org.metaborg.spoofax.core.analysis.SpoofaxAnalyzeResults) Collectors2(org.metaborg.util.stream.Collectors2) FixedPoint(mb.flowspec.runtime.solver.FixedPoint) IResourceService(org.metaborg.core.resource.IResourceService) IStrategoCommon(org.metaborg.spoofax.core.stratego.IStrategoCommon) InitialResult(mb.nabl2.spoofax.analysis.InitialResult) MessageSeverity(org.metaborg.core.messages.MessageSeverity) AnalysisException(org.metaborg.core.analysis.AnalysisException) IStrategoRuntimeService(org.metaborg.spoofax.core.stratego.IStrategoRuntimeService) MessageFactory(org.metaborg.core.messages.MessageFactory) ISpoofaxAnalyzeResults(org.metaborg.spoofax.core.analysis.ISpoofaxAnalyzeResults) SpoofaxAnalyzeResults(org.metaborg.spoofax.core.analysis.SpoofaxAnalyzeResults) ITermVar(mb.nabl2.terms.ITermVar) GraphSolution(mb.nabl2.solver.solvers.BaseSolver.GraphSolution) List(java.util.List) FileObject(org.apache.commons.vfs2.FileObject) InitialResult(mb.nabl2.spoofax.analysis.InitialResult) IProgress(org.metaborg.util.task.IProgress) Optional(java.util.Optional) AnalyzeUpdateData(org.metaborg.spoofax.core.unit.AnalyzeUpdateData) FinalResult(mb.nabl2.spoofax.analysis.FinalResult) IMessage(org.metaborg.core.messages.IMessage) Function1(org.metaborg.util.functions.Function1) ISolution(mb.nabl2.solver.ISolution) IMultiFileScopeGraphUnit(org.metaborg.spoofax.core.context.scopegraph.IMultiFileScopeGraphUnit) CustomSolution(mb.nabl2.spoofax.analysis.CustomSolution) NaBL2DebugConfig(mb.nabl2.config.NaBL2DebugConfig) Map(java.util.Map) IStrategoTerm(org.spoofax.interpreter.terms.IStrategoTerm) ISpoofaxAnalyzeUnitUpdate(org.metaborg.spoofax.core.unit.ISpoofaxAnalyzeUnitUpdate) SemiIncrementalMultiFileSolver(mb.nabl2.solver.solvers.SemiIncrementalMultiFileSolver) MetaborgException(org.metaborg.core.MetaborgException) UnitResult(mb.nabl2.spoofax.analysis.UnitResult) AggregateTimer(org.metaborg.util.time.AggregateTimer) IMessageInfo(mb.nabl2.constraints.messages.IMessageInfo) AnalyzeContrib(org.metaborg.spoofax.core.unit.AnalyzeContrib) FixedPoint(mb.flowspec.runtime.solver.FixedPoint) ISpoofaxAnalyzeUnit(org.metaborg.spoofax.core.unit.ISpoofaxAnalyzeUnit) ISpoofaxParseUnit(org.metaborg.spoofax.core.unit.ISpoofaxParseUnit) IMessages(mb.nabl2.solver.messages.IMessages) IOException(java.io.IOException) FixedPoint(mb.flowspec.runtime.solver.FixedPoint) Timer(org.metaborg.util.time.Timer) AggregateTimer(org.metaborg.util.time.AggregateTimer) Scope(mb.nabl2.scopegraph.terms.Scope) AnalysisException(org.metaborg.core.analysis.AnalysisException) ITerm(mb.nabl2.terms.ITerm) SolverException(mb.nabl2.solver.SolverException)

Example 2 with Timer

use of org.metaborg.util.time.Timer in project spoofax by metaborg.

the class StrategoAnalyzer method analyze.

private ISpoofaxAnalyzeUnit analyze(ISpoofaxParseUnit input, IContext context, HybridInterpreter runtime, String strategy, ITermFactory termFactory) throws AnalysisException {
    final FileObject source = input.source();
    final IStrategoString contextPath = strategoCommon.locationTerm(context.location());
    final IStrategoString resourcePath = strategoCommon.resourceTerm(source, context.location());
    final IStrategoTuple inputTerm = termFactory.makeTuple(input.ast(), resourcePath, contextPath);
    try {
        logger.trace("Analysing {}", source);
        final Timer timer = new Timer(true);
        final IStrategoTerm resultTerm = strategoCommon.invoke(runtime, inputTerm, strategy);
        final long duration = timer.stop();
        if (resultTerm == null) {
            logger.trace("Analysis for {} failed", source);
            return result(analysisCommon.analysisFailedMessage(runtime), input, context, null, duration);
        } else if (!(resultTerm instanceof IStrategoTuple)) {
            logger.trace("Analysis for {} has unexpected result, not a tuple", source);
            final String message = logger.format("Unexpected results from analysis {}", resultTerm);
            return result(message, input, context, null, duration);
        } else if (resultTerm.getSubtermCount() == 4) {
            logger.trace("Analysis for {} done", source);
            return result(resultTerm, input, context, duration);
        } else if (resultTerm.getSubtermCount() == 3) {
            logger.trace("Analysis for {} done", source);
            return resultNoAst(resultTerm, input, context, duration);
        } else {
            logger.trace("Analysis for {} has unexpected result; tuple with more than 4 or less than 2 elements", source);
            final String message = logger.format("Unexpected results from analysis {}", resultTerm);
            return result(message, input, context, null, duration);
        }
    } catch (MetaborgException e) {
        final String message = logger.format("Analysis for {} failed", source);
        logger.trace(message, e);
        throw new AnalysisException(context, message, e);
    }
}
Also used : IStrategoTerm(org.spoofax.interpreter.terms.IStrategoTerm) Timer(org.metaborg.util.time.Timer) MetaborgException(org.metaborg.core.MetaborgException) AnalysisException(org.metaborg.core.analysis.AnalysisException) IStrategoString(org.spoofax.interpreter.terms.IStrategoString) IStrategoTuple(org.spoofax.interpreter.terms.IStrategoTuple) FileObject(org.apache.commons.vfs2.FileObject) IStrategoString(org.spoofax.interpreter.terms.IStrategoString)

Example 3 with Timer

use of org.metaborg.util.time.Timer 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)

Example 4 with Timer

use of org.metaborg.util.time.Timer in project spoofax by metaborg.

the class JSGLR1I method parse.

public ParseContrib parse(@Nullable JSGLRParserConfiguration parserConfig) throws IOException {
    if (parserConfig == null) {
        parserConfig = new JSGLRParserConfiguration();
    }
    final String fileName = resource != null ? resource.getName().getURI() : null;
    final JSGLRParseErrorHandler errorHandler = new JSGLRParseErrorHandler(this, resource, getParseTable(config.getParseTableProvider()).hasRecovers());
    final Timer timer = new Timer(true);
    SGLRParseResult result;
    try {
        // should throw a fatal, or return a non-null result
        result = actuallyParse(input, fileName, parserConfig);
        assert result != null;
    } catch (SGLRException | InterruptedException e) {
        result = null;
        errorHandler.setRecoveryFailed(parserConfig.recovery);
        errorHandler.processFatalException(new NullTokenizer(input, fileName), e);
    }
    final long duration = timer.stop();
    final IStrategoTerm ast;
    if (result != null) {
        // No fatals occurred, so either parsing succeeded or recovery succeeded
        ast = (IStrategoTerm) result.output;
        if (ast == null) {
            // so we have nothing to do
            assert parser.getTreeBuilder() instanceof NullTreeBuilder;
        } else {
            // in case recovery was required, collect the recoverable errors
            errorHandler.setRecoveryFailed(false);
            errorHandler.gatherNonFatalErrors(ast);
            if (resource != null) {
                SourceAttachment.putSource(ast, resource);
            }
        }
    } else {
        ast = null;
    }
    final boolean hasAst = ast != null;
    final Iterable<IMessage> messages = errorHandler.messages();
    final boolean hasErrors = MessageUtils.containsSeverity(messages, MessageSeverity.ERROR);
    return new ParseContrib(hasAst, hasAst && !hasErrors, ast, messages, duration);
}
Also used : ParseContrib(org.metaborg.spoofax.core.unit.ParseContrib) IStrategoTerm(org.spoofax.interpreter.terms.IStrategoTerm) IMessage(org.metaborg.core.messages.IMessage) NullTokenizer(org.spoofax.jsglr.client.imploder.NullTokenizer) SGLRParseResult(org.spoofax.jsglr.client.SGLRParseResult) Timer(org.metaborg.util.time.Timer) NullTreeBuilder(org.spoofax.jsglr.client.NullTreeBuilder) SGLRException(org.spoofax.jsglr.shared.SGLRException)

Example 5 with Timer

use of org.metaborg.util.time.Timer in project spoofax by metaborg.

the class JSGLR2I method parse.

public ParseContrib parse(@Nullable JSGLRParserConfiguration parserConfig) throws IOException {
    if (parserConfig == null) {
        parserConfig = new JSGLRParserConfiguration();
    }
    final String fileName = resource != null ? resource.getName().getURI() : null;
    String startSymbol = getOrDefaultStartSymbol(parserConfig);
    final Timer timer = new Timer(true);
    final IStrategoTerm ast = parser.parse(input, fileName, startSymbol);
    final long duration = timer.stop();
    final boolean hasAst = ast != null;
    final boolean hasErrors = ast == null;
    final Iterable<IMessage> messages;
    if (hasErrors)
        messages = Collections.singletonList(MessageFactory.newParseErrorAtTop(resource, "Invalid syntax", null));
    else
        messages = Collections.emptyList();
    return new ParseContrib(hasAst, hasAst && !hasErrors, ast, messages, duration);
}
Also used : ParseContrib(org.metaborg.spoofax.core.unit.ParseContrib) IStrategoTerm(org.spoofax.interpreter.terms.IStrategoTerm) Timer(org.metaborg.util.time.Timer) IMessage(org.metaborg.core.messages.IMessage)

Aggregations

Timer (org.metaborg.util.time.Timer)4 IStrategoTerm (org.spoofax.interpreter.terms.IStrategoTerm)4 FileObject (org.apache.commons.vfs2.FileObject)3 MetaborgException (org.metaborg.core.MetaborgException)3 IMessage (org.metaborg.core.messages.IMessage)3 AnalysisException (org.metaborg.core.analysis.AnalysisException)2 ParseContrib (org.metaborg.spoofax.core.unit.ParseContrib)2 IStrategoString (org.spoofax.interpreter.terms.IStrategoString)2 IStrategoTuple (org.spoofax.interpreter.terms.IStrategoTuple)2 HashMultimap (com.google.common.collect.HashMultimap)1 Lists (com.google.common.collect.Lists)1 Maps (com.google.common.collect.Maps)1 Multimap (com.google.common.collect.Multimap)1 Sets (com.google.common.collect.Sets)1 Inject (com.google.inject.Inject)1 IOException (java.io.IOException)1 Collection (java.util.Collection)1 List (java.util.List)1 Map (java.util.Map)1 Optional (java.util.Optional)1