Search in sources :

Example 1 with CoverageEventNode

use of org.graalvm.tools.lsp.server.utils.CoverageEventNode in project graal by oracle.

the class HoverRequestHandler method tryFrameScope.

private Hover tryFrameScope(MaterializedFrame frame, CoverageEventNode node, String textAtHoverPosition, LanguageInfo langInfo, SourceSection hoverSection) {
    Node instrumentedNode = node.getInstrumentedNode();
    NodeLibrary nodeLibrary = NodeLibrary.getUncached(instrumentedNode);
    if (nodeLibrary.hasScope(instrumentedNode, frame)) {
        try {
            Object scope = nodeLibrary.getScope(instrumentedNode, frame, true);
            Object keys = INTEROP.getMembers(scope);
            long size = INTEROP.getArraySize(keys);
            for (long i = 0; i < size; i++) {
                String key = INTEROP.asString(INTEROP.readArrayElement(keys, i));
                if (key.equals(textAtHoverPosition)) {
                    Object var = INTEROP.readMember(scope, key);
                    return Hover.create(createDefaultHoverInfos(textAtHoverPosition, var, langInfo)).setRange(SourceUtils.sourceSectionToRange(hoverSection));
                }
            }
        } catch (UnsupportedMessageException | UnknownIdentifierException | InvalidArrayIndexException e) {
        }
    }
    return null;
}
Also used : NodeLibrary(com.oracle.truffle.api.interop.NodeLibrary) InvalidArrayIndexException(com.oracle.truffle.api.interop.InvalidArrayIndexException) UnsupportedMessageException(com.oracle.truffle.api.interop.UnsupportedMessageException) UnknownIdentifierException(com.oracle.truffle.api.interop.UnknownIdentifierException) ExecutableNode(com.oracle.truffle.api.nodes.ExecutableNode) Node(com.oracle.truffle.api.nodes.Node) InstrumentableNode(com.oracle.truffle.api.instrumentation.InstrumentableNode) CoverageEventNode(org.graalvm.tools.lsp.server.utils.CoverageEventNode) TruffleObject(com.oracle.truffle.api.interop.TruffleObject)

Example 2 with CoverageEventNode

use of org.graalvm.tools.lsp.server.utils.CoverageEventNode in project graal by oracle.

the class HoverRequestHandler method tryCoverageDataEvaluation.

private Hover tryCoverageDataEvaluation(SourceSection hoverSection, LanguageInfo langInfo, String textAtHoverPosition, CoverageData coverageData) {
    InstrumentableNode instrumentable = ((InstrumentableNode) coverageData.getCoverageEventNode().getInstrumentedNode());
    if (!instrumentable.hasTag(StandardTags.ExpressionTag.class)) {
        return null;
    }
    Future<Hover> future = contextAwareExecutor.executeWithNestedContext(() -> {
        final LanguageInfo rootLangInfo = coverageData.getCoverageEventNode().getRootNode().getLanguageInfo();
        final Source inlineEvalSource = Source.newBuilder(rootLangInfo.getId(), textAtHoverPosition, "in-line eval (hover request)").cached(false).build();
        ExecutableNode executableNode = null;
        try {
            executableNode = env.parseInline(inlineEvalSource, coverageData.getCoverageEventNode(), coverageData.getFrame());
        } catch (Exception e) {
        }
        if (executableNode == null) {
            return Hover.create(Collections.emptyList());
        }
        CoverageEventNode coverageEventNode = coverageData.getCoverageEventNode();
        coverageEventNode.insertOrReplaceChild(executableNode);
        Object evalResult = null;
        try {
            logger.fine("Trying coverage-based eval...");
            evalResult = executableNode.execute(coverageData.getFrame());
        } catch (Exception e) {
            if (!(INTEROP.isException(e) || (e instanceof ControlFlowException))) {
                e.printStackTrace(err);
            }
            return Hover.create(Collections.emptyList());
        } finally {
            coverageEventNode.clearChild();
        }
        if (evalResult instanceof TruffleObject) {
            Hover signatureHover = trySignature(hoverSection, langInfo, (TruffleObject) evalResult);
            if (signatureHover != null) {
                return signatureHover;
            }
        }
        return Hover.create(createDefaultHoverInfos(textAtHoverPosition, evalResult, langInfo)).setRange(SourceUtils.sourceSectionToRange(hoverSection));
    }, true);
    return getFutureResultOrHandleExceptions(future);
}
Also used : InstrumentableNode(com.oracle.truffle.api.instrumentation.InstrumentableNode) LanguageInfo(com.oracle.truffle.api.nodes.LanguageInfo) ControlFlowException(com.oracle.truffle.api.nodes.ControlFlowException) Hover(org.graalvm.tools.lsp.server.types.Hover) CoverageEventNode(org.graalvm.tools.lsp.server.utils.CoverageEventNode) ExpressionTag(com.oracle.truffle.api.instrumentation.StandardTags.ExpressionTag) TruffleObject(com.oracle.truffle.api.interop.TruffleObject) ExecutableNode(com.oracle.truffle.api.nodes.ExecutableNode) Source(com.oracle.truffle.api.source.Source) InvalidArrayIndexException(com.oracle.truffle.api.interop.InvalidArrayIndexException) UnknownIdentifierException(com.oracle.truffle.api.interop.UnknownIdentifierException) UnsupportedMessageException(com.oracle.truffle.api.interop.UnsupportedMessageException) ControlFlowException(com.oracle.truffle.api.nodes.ControlFlowException) TruffleObject(com.oracle.truffle.api.interop.TruffleObject)

Example 3 with CoverageEventNode

use of org.graalvm.tools.lsp.server.utils.CoverageEventNode in project graal by oracle.

the class LSPInstrument method onCreate.

@Override
protected void onCreate(Env env) {
    env.registerService(this);
    this.environment = env;
    options = env.getOptions();
    if (options.hasSetOptions()) {
        final TruffleAdapter truffleAdapter = launchServer(new PrintWriter(env.out(), true), new PrintWriter(env.err(), true));
        SourceSectionFilter eventFilter = SourceSectionFilter.newBuilder().includeInternal(options.get(Internal)).build();
        eventFactoryBinding = env.getInstrumenter().attachExecutionEventFactory(eventFilter, new ExecutionEventNodeFactory() {

            private final long creatorThreadId = Thread.currentThread().getId();

            @Override
            public ExecutionEventNode create(final EventContext eventContext) {
                final SourceSection section = eventContext.getInstrumentedSourceSection();
                if (section != null && section.isAvailable()) {
                    final Node instrumentedNode = eventContext.getInstrumentedNode();
                    return new CoverageEventNode(section, instrumentedNode, null, truffleAdapter.surrogateGetter(instrumentedNode.getRootNode().getLanguageInfo()), creatorThreadId);
                } else {
                    return null;
                }
            }
        });
    }
}
Also used : EventContext(com.oracle.truffle.api.instrumentation.EventContext) TruffleAdapter(org.graalvm.tools.lsp.server.TruffleAdapter) ExecutionEventNodeFactory(com.oracle.truffle.api.instrumentation.ExecutionEventNodeFactory) Node(com.oracle.truffle.api.nodes.Node) ExecutionEventNode(com.oracle.truffle.api.instrumentation.ExecutionEventNode) CoverageEventNode(org.graalvm.tools.lsp.server.utils.CoverageEventNode) CoverageEventNode(org.graalvm.tools.lsp.server.utils.CoverageEventNode) SourceSectionFilter(com.oracle.truffle.api.instrumentation.SourceSectionFilter) SourceSection(com.oracle.truffle.api.source.SourceSection) PrintWriter(java.io.PrintWriter)

Example 4 with CoverageEventNode

use of org.graalvm.tools.lsp.server.utils.CoverageEventNode in project graal by oracle.

the class CoverageRequestHandler method runCoverageAnalysisWithEnteredContext.

public Boolean runCoverageAnalysisWithEnteredContext(final URI uri) throws DiagnosticsNotification {
    final TextDocumentSurrogate surrogateOfOpenedFile = surrogateMap.get(uri);
    if (surrogateOfOpenedFile == null) {
        return Boolean.FALSE;
    }
    TextDocumentSurrogate surrogateOfTestFile = sourceCodeEvaluator.createSurrogateForTestFile(surrogateOfOpenedFile, null);
    final URI runScriptUri = surrogateOfTestFile.getUri();
    clearRelatedCoverageData(runScriptUri);
    try {
        final CallTarget callTarget = sourceCodeEvaluator.parse(surrogateOfTestFile);
        LanguageInfo languageInfo = surrogateOfTestFile.getLanguageInfo();
        SourcePredicate predicate = SourcePredicateBuilder.newBuilder().language(languageInfo).excludeInternal(env.getOptions()).build();
        SourceSectionFilter eventFilter = SourceSectionFilter.newBuilder().sourceIs(predicate).build();
        EventBinding<ExecutionEventNodeFactory> eventFactoryBinding = env.getInstrumenter().attachExecutionEventFactory(eventFilter, new ExecutionEventNodeFactory() {

            private final long creatorThreadId = Thread.currentThread().getId();

            @Override
            public ExecutionEventNode create(final EventContext eventContext) {
                final SourceSection section = eventContext.getInstrumentedSourceSection();
                if (section != null && section.isAvailable()) {
                    final Node instrumentedNode = eventContext.getInstrumentedNode();
                    Function<URI, TextDocumentSurrogate> func = (sourceUri) -> {
                        return surrogateMap.getOrCreateSurrogate(sourceUri, () -> instrumentedNode.getRootNode().getLanguageInfo());
                    };
                    return new CoverageEventNode(section, instrumentedNode, runScriptUri, func, creatorThreadId);
                } else {
                    return null;
                }
            }
        });
        try {
            callTarget.call();
        } finally {
            eventFactoryBinding.dispose();
        }
        surrogateOfOpenedFile.setCoverageAnalysisDone(true);
        return Boolean.TRUE;
    } catch (DiagnosticsNotification e) {
        throw e;
    } catch (Exception e) {
        InteropLibrary interopLib = InteropLibrary.getUncached();
        if (interopLib.isException(e)) {
            SourceSection sourceSection;
            try {
                sourceSection = interopLib.hasSourceLocation(e) ? interopLib.getSourceLocation(e) : null;
            } catch (UnsupportedMessageException um) {
                throw CompilerDirectives.shouldNotReachHere(um);
            }
            URI uriOfErronousSource = sourceSection != null ? sourceSection.getSource().getURI() : null;
            if (uriOfErronousSource == null) {
                uriOfErronousSource = uri;
            }
            throw DiagnosticsNotification.create(uriOfErronousSource, Diagnostic.create(SourceUtils.getRangeFrom(e, interopLib), e.getMessage(), DiagnosticSeverity.Error, null, "Coverage analysis", null));
        }
        throw e;
    }
}
Also used : ExecutionEventNodeFactory(com.oracle.truffle.api.instrumentation.ExecutionEventNodeFactory) CallTarget(com.oracle.truffle.api.CallTarget) Node(com.oracle.truffle.api.nodes.Node) ExecutionEventNode(com.oracle.truffle.api.instrumentation.ExecutionEventNode) CoverageEventNode(org.graalvm.tools.lsp.server.utils.CoverageEventNode) TextDocumentSurrogate(org.graalvm.tools.lsp.server.utils.TextDocumentSurrogate) SourceSectionFilter(com.oracle.truffle.api.instrumentation.SourceSectionFilter) DiagnosticsNotification(org.graalvm.tools.lsp.exceptions.DiagnosticsNotification) URI(java.net.URI) UnsupportedMessageException(com.oracle.truffle.api.interop.UnsupportedMessageException) EventContext(com.oracle.truffle.api.instrumentation.EventContext) LanguageInfo(com.oracle.truffle.api.nodes.LanguageInfo) Function(java.util.function.Function) SourcePredicate(com.oracle.truffle.api.instrumentation.SourceSectionFilter.SourcePredicate) UnsupportedMessageException(com.oracle.truffle.api.interop.UnsupportedMessageException) InteropLibrary(com.oracle.truffle.api.interop.InteropLibrary) CoverageEventNode(org.graalvm.tools.lsp.server.utils.CoverageEventNode) SourceSection(com.oracle.truffle.api.source.SourceSection) ExecutionEventNode(com.oracle.truffle.api.instrumentation.ExecutionEventNode)

Example 5 with CoverageEventNode

use of org.graalvm.tools.lsp.server.utils.CoverageEventNode in project graal by oracle.

the class SourceCodeEvaluator method evalWithCoverageData.

private EvaluationResult evalWithCoverageData(TextDocumentSurrogate textDocumentSurrogate, Node nearestNode) {
    if (!textDocumentSurrogate.hasCoverageData()) {
        return EvaluationResult.createEvaluationSectionNotReached();
    }
    List<CoverageData> dataBeforeNode = findCoverageDataBeforeNode(textDocumentSurrogate, nearestNode);
    if (dataBeforeNode == null || dataBeforeNode.isEmpty()) {
        return EvaluationResult.createEvaluationSectionNotReached();
    }
    CoverageData coverageData = dataBeforeNode.get(dataBeforeNode.size() - 1);
    if (((InstrumentableNode) nearestNode).hasTag(StandardTags.ReadVariableTag.class)) {
        // Shortcut for variables
        InteropUtils.VariableInfo[] variables = InteropUtils.getNodeObjectVariables((InstrumentableNode) nearestNode);
        if (variables.length == 1) {
            InteropUtils.VariableInfo var = variables[0];
            NodeLibrary nodeLibrary = NodeLibrary.getUncached(nearestNode);
            if (nodeLibrary.hasScope(nearestNode, coverageData.getFrame())) {
                try {
                    Object scope = nodeLibrary.getScope(nearestNode, coverageData.getFrame(), true);
                    if (INTEROP.isMemberReadable(scope, var.getName())) {
                        logger.fine("Coverage-based variable look-up");
                        Object value = INTEROP.readMember(scope, var.getName());
                        return EvaluationResult.createResult(value);
                    }
                } catch (UnknownIdentifierException | UnsupportedMessageException ex) {
                    throw CompilerDirectives.shouldNotReachHere(ex);
                }
            }
        }
    }
    LanguageInfo info = nearestNode.getRootNode().getLanguageInfo();
    String code = nearestNode.getSourceSection().getCharacters().toString();
    Source inlineEvalSource = Source.newBuilder(info.getId(), code, "in-line eval (hover request)").cached(false).build();
    ExecutableNode executableNode = env.parseInline(inlineEvalSource, nearestNode, coverageData.getFrame());
    CoverageEventNode coverageEventNode = coverageData.getCoverageEventNode();
    coverageEventNode.insertOrReplaceChild(executableNode);
    try {
        logger.fine("Trying coverage-based eval...");
        Object result = executableNode.execute(coverageData.getFrame());
        return EvaluationResult.createResult(result);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        coverageEventNode.clearChild();
    }
    return EvaluationResult.createEvaluationSectionNotReached();
}
Also used : NodeLibrary(com.oracle.truffle.api.interop.NodeLibrary) CoverageData(org.graalvm.tools.lsp.server.utils.CoverageData) InteropUtils(org.graalvm.tools.lsp.server.utils.InteropUtils) ExecutableNode(com.oracle.truffle.api.nodes.ExecutableNode) StandardTags(com.oracle.truffle.api.instrumentation.StandardTags) Source(com.oracle.truffle.api.source.Source) UnknownLanguageException(org.graalvm.tools.lsp.exceptions.UnknownLanguageException) UnknownIdentifierException(com.oracle.truffle.api.interop.UnknownIdentifierException) UnsupportedMessageException(com.oracle.truffle.api.interop.UnsupportedMessageException) IOException(java.io.IOException) EvaluationResultException(org.graalvm.tools.lsp.exceptions.EvaluationResultException) InstrumentableNode(com.oracle.truffle.api.instrumentation.InstrumentableNode) LanguageInfo(com.oracle.truffle.api.nodes.LanguageInfo) UnsupportedMessageException(com.oracle.truffle.api.interop.UnsupportedMessageException) UnknownIdentifierException(com.oracle.truffle.api.interop.UnknownIdentifierException) CoverageEventNode(org.graalvm.tools.lsp.server.utils.CoverageEventNode) TruffleObject(com.oracle.truffle.api.interop.TruffleObject)

Aggregations

CoverageEventNode (org.graalvm.tools.lsp.server.utils.CoverageEventNode)5 UnsupportedMessageException (com.oracle.truffle.api.interop.UnsupportedMessageException)4 InstrumentableNode (com.oracle.truffle.api.instrumentation.InstrumentableNode)3 TruffleObject (com.oracle.truffle.api.interop.TruffleObject)3 UnknownIdentifierException (com.oracle.truffle.api.interop.UnknownIdentifierException)3 ExecutableNode (com.oracle.truffle.api.nodes.ExecutableNode)3 LanguageInfo (com.oracle.truffle.api.nodes.LanguageInfo)3 Node (com.oracle.truffle.api.nodes.Node)3 EventContext (com.oracle.truffle.api.instrumentation.EventContext)2 ExecutionEventNode (com.oracle.truffle.api.instrumentation.ExecutionEventNode)2 ExecutionEventNodeFactory (com.oracle.truffle.api.instrumentation.ExecutionEventNodeFactory)2 SourceSectionFilter (com.oracle.truffle.api.instrumentation.SourceSectionFilter)2 InvalidArrayIndexException (com.oracle.truffle.api.interop.InvalidArrayIndexException)2 NodeLibrary (com.oracle.truffle.api.interop.NodeLibrary)2 Source (com.oracle.truffle.api.source.Source)2 SourceSection (com.oracle.truffle.api.source.SourceSection)2 CallTarget (com.oracle.truffle.api.CallTarget)1 SourcePredicate (com.oracle.truffle.api.instrumentation.SourceSectionFilter.SourcePredicate)1 StandardTags (com.oracle.truffle.api.instrumentation.StandardTags)1 ExpressionTag (com.oracle.truffle.api.instrumentation.StandardTags.ExpressionTag)1