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;
}
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);
}
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;
}
}
});
}
}
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;
}
}
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();
}
Aggregations