Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.function.Function;
Expand Down Expand Up @@ -166,12 +167,15 @@ IFunction makeParseTreeGetter(Evaluator e) {
return e.getFunctionValueFactory().function(getParseTreeType, (t, u) -> {
ISourceLocation resolvedLocation = Locations.toClientLocation((ISourceLocation) t[0]);
try {
var tree = rascalTextDocumentService.getFile(resolvedLocation).getLastTreeWithoutErrors();
var tree = rascalTextDocumentService.getFile(resolvedLocation).getCurrentTreeAsync(true).get();
if (tree != null) {
return tree.get();
}
} catch (ResponseErrorException e1) {
// File is not open in the IDE
} catch (ResponseErrorException | ExecutionException e1) {
// File is not open in the IDE | Parse threw an exception
// In either case, fall through and try a direct parse
} catch (InterruptedException e1) {
Thread.currentThread().interrupt();
}
// Parse the source file
try (var reader = URIResolverRegistry.getInstance().getCharacterReader(resolvedLocation)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import Location;
import analysis::graphs::Graph;
import util::FileSystem;
import util::Monitor;
import util::ParseErrorRecovery;
import util::Reflective;

import lang::rascal::\syntax::Rascal;
Expand All @@ -53,27 +54,41 @@ import lang::rascalcore::check::ModuleLocations;
}
map[loc, set[Message]] checkFile(loc l, set[loc] workspaceFolders, start[Module](loc file) getParseTree, PathConfig(loc file) getPathConfig)
= job("Rascal check", map[loc, set[Message]](void(str, int) step) {
checkForImports = [getParseTree(l)];
openFile = getParseTree(l);
openFileHeader = openFile.top.header.name;

if (hasParseErrors(openFile)) {
// We cannot typecheck this file, since it has type errors. Do not return any errors, since the parse triggered by the IDE will take care of that.
return ();
}

checkForImports = [openFile];
checkedForImports = {};
initialProject = inferProjectRoot(l);

rel[loc, loc] dependencies = {};

step("Dependency graph", 1);
job("Building dependency graph", bool (void (str, int) step2) {
parseMsgs = job("Building dependency graph", rel[loc, Message] (void (str, int) step2) {
while (tree <- checkForImports) {
step2("Calculating imports for <tree.top.header.name>", 1);
currentSrc = tree.src.top;
currentProject = inferProjectRoot(currentSrc);
if (currentProject in workspaceFolders && currentProject.file notin {"rascal", "rascal-lsp"}) {
for (i <- tree.top.header.imports, i has \module) {
modName = "<i.\module>";
try {
ml = locateRascalModule("<i.\module>", getPathConfig(currentProject), getPathConfig, workspaceFolders);
ml = locateRascalModule(modName, getPathConfig(currentProject), getPathConfig, workspaceFolders);
if (ml.extension == "rsc", mlpt := getParseTree(ml), mlpt.src.top notin checkedForImports) {
if (hasParseErrors(mlpt)) {
return {<l, error("Cannot typecheck this module, since <modName> has parse error(s) (<tree.src.top>).", openFileHeader.src)>};
}
checkForImports += mlpt;
jobTodo("Building dependency graph");
dependencies += <currentProject, inferProjectRoot(mlpt.src.top)>;
}
} catch ParseError(loc l): {
return {<l, error("Cannot typecheck this module, since <modName> has parse error(s) (<tree.src.top>).", openFileHeader.src)>};
} catch _: {
;// Continue
}
Expand All @@ -82,9 +97,13 @@ map[loc, set[Message]] checkFile(loc l, set[loc] workspaceFolders, start[Module]
checkedForImports += currentSrc;
checkForImports -= tree;
}
return true;
return {};
}, totalWork=1);

if ({} !:= parseMsgs) {
return toMap(parseMsgs);
}

cyclicDependencies = {p | <p, p> <- (dependencies - ident(carrier(dependencies)))+};
if (cyclicDependencies != {}) {
return (l : {error("Cyclic dependencies detected between projects {<intercalate(", ", [*cyclicDependencies])>}. This is not supported. Fix your project setup.", l)});
Expand Down
Loading