Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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 @@ -149,6 +149,7 @@
import com.as3mxml.vscode.project.ILspProject;
import com.as3mxml.vscode.project.IProjectConfigStrategy;
import com.as3mxml.vscode.project.IProjectConfigStrategyFactory;
import com.as3mxml.vscode.project.LspASCompilationUnit;
import com.as3mxml.vscode.project.ProjectOptions;
import com.as3mxml.vscode.project.SimpleProjectConfigStrategy;
import com.as3mxml.vscode.providers.CodeActionProvider;
Expand Down Expand Up @@ -218,6 +219,8 @@ public class ActionScriptServices implements TextDocumentService, WorkspaceServi
private RealTimeProblemsChecker realTimeProblemsChecker;
private Future<?> realTimeProblemsFuture;
private Set<URI> notOnSourcePathSet = new HashSet<>();
private ILspProject purgeProject;
private boolean autoMemoryPurge = false;
private boolean realTimeProblems = true;
private boolean showFileOutsideSourcePath = true;
private boolean concurrentRequests = true;
Expand Down Expand Up @@ -375,13 +378,16 @@ private Either<List<CompletionItem>, CompletionList> completion2(CompletionParam
cancelToken.checkCanceled();
}

LspASCompilationUnit.pinASTsToKeepAlive();
compilerWorkspace.startBuilding();
try {
CompletionProvider provider = new CompletionProvider(actionScriptProjectManager, fileTracker,
completionSupportsSnippets, completionSupportsSimpleSnippets, frameworkSDKIsRoyale);
return provider.completion(params, cancelToken);
} finally {
compilerWorkspace.doneBuilding();
updatePurgeState();
LspASCompilationUnit.unpinAndRemoveASTs(purgeProject);
}
}

Expand Down Expand Up @@ -420,12 +426,15 @@ private Hover hover2(HoverParams params, CancelChecker cancelToken) {
cancelToken.checkCanceled();
}

LspASCompilationUnit.pinASTsToKeepAlive();
compilerWorkspace.startBuilding();
try {
HoverProvider provider = new HoverProvider(actionScriptProjectManager, fileTracker);
return provider.hover(params, cancelToken);
} finally {
compilerWorkspace.doneBuilding();
updatePurgeState();
LspASCompilationUnit.unpinAndRemoveASTs(purgeProject);
}
}

Expand Down Expand Up @@ -456,12 +465,15 @@ private SignatureHelp signatureHelp2(SignatureHelpParams params, CancelChecker c
cancelToken.checkCanceled();
}

LspASCompilationUnit.pinASTsToKeepAlive();
compilerWorkspace.startBuilding();
try {
SignatureHelpProvider provider = new SignatureHelpProvider(actionScriptProjectManager, fileTracker);
return provider.signatureHelp(params, cancelToken);
} finally {
compilerWorkspace.doneBuilding();
updatePurgeState();
LspASCompilationUnit.unpinAndRemoveASTs(purgeProject);
}
}

Expand Down Expand Up @@ -493,12 +505,15 @@ private Either<List<? extends Location>, List<? extends LocationLink>> definitio
cancelToken.checkCanceled();
}

LspASCompilationUnit.pinASTsToKeepAlive();
compilerWorkspace.startBuilding();
try {
DefinitionProvider provider = new DefinitionProvider(actionScriptProjectManager, fileTracker);
return provider.definition(params, cancelToken);
} finally {
compilerWorkspace.doneBuilding();
updatePurgeState();
LspASCompilationUnit.unpinAndRemoveASTs(purgeProject);
}
}

Expand Down Expand Up @@ -530,12 +545,15 @@ private Either<List<? extends Location>, List<? extends LocationLink>> typeDefin
cancelToken.checkCanceled();
}

LspASCompilationUnit.pinASTsToKeepAlive();
compilerWorkspace.startBuilding();
try {
TypeDefinitionProvider provider = new TypeDefinitionProvider(actionScriptProjectManager, fileTracker);
return provider.typeDefinition(params, cancelToken);
} finally {
compilerWorkspace.doneBuilding();
updatePurgeState();
LspASCompilationUnit.unpinAndRemoveASTs(purgeProject);
}
}

Expand Down Expand Up @@ -566,12 +584,15 @@ private Either<List<? extends Location>, List<? extends LocationLink>> implement
cancelToken.checkCanceled();
}

LspASCompilationUnit.pinASTsToKeepAlive();
compilerWorkspace.startBuilding();
try {
ImplementationProvider provider = new ImplementationProvider(actionScriptProjectManager, fileTracker);
return provider.implementation(params, cancelToken);
} finally {
compilerWorkspace.doneBuilding();
updatePurgeState();
LspASCompilationUnit.unpinAndRemoveASTs(purgeProject);
}
}

Expand Down Expand Up @@ -602,12 +623,15 @@ private List<? extends Location> references2(ReferenceParams params, CancelCheck
cancelToken.checkCanceled();
}

LspASCompilationUnit.pinASTsToKeepAlive();
compilerWorkspace.startBuilding();
try {
ReferencesProvider provider = new ReferencesProvider(actionScriptProjectManager, fileTracker);
return provider.references(params, cancelToken);
} finally {
compilerWorkspace.doneBuilding();
updatePurgeState();
LspASCompilationUnit.unpinAndRemoveASTs(purgeProject);
}
}

Expand Down Expand Up @@ -758,6 +782,7 @@ private List<Either<Command, CodeAction>> codeAction2(CodeActionParams params, C
cancelToken.checkCanceled();
}

LspASCompilationUnit.pinASTsToKeepAlive();
compilerWorkspace.startBuilding();
try {
CodeActionProvider provider = new CodeActionProvider(actionScriptProjectManager, fileTracker);
Expand All @@ -766,6 +791,8 @@ private List<Either<Command, CodeAction>> codeAction2(CodeActionParams params, C
return provider.codeAction(params, cancelToken);
} finally {
compilerWorkspace.doneBuilding();
updatePurgeState();
LspASCompilationUnit.unpinAndRemoveASTs(purgeProject);
}
}

Expand Down Expand Up @@ -864,6 +891,7 @@ private WorkspaceEdit rename2(RenameParams params, CancelChecker cancelToken) {
cancelToken.checkCanceled();
}

LspASCompilationUnit.pinASTsToKeepAlive();
compilerWorkspace.startBuilding();
try {
RenameProvider provider = new RenameProvider(actionScriptProjectManager, fileTracker);
Expand All @@ -880,6 +908,8 @@ private WorkspaceEdit rename2(RenameParams params, CancelChecker cancelToken) {
return result;
} finally {
compilerWorkspace.doneBuilding();
updatePurgeState();
LspASCompilationUnit.unpinAndRemoveASTs(purgeProject);
}
}

Expand Down Expand Up @@ -923,6 +953,7 @@ private List<InlayHint> inlayHint2(InlayHintParams params, CancelChecker cancelT
cancelToken.checkCanceled();
}

LspASCompilationUnit.pinASTsToKeepAlive();
compilerWorkspace.startBuilding();
try {
InlayHintProvider provider = new InlayHintProvider(actionScriptProjectManager);
Expand All @@ -931,6 +962,8 @@ private List<InlayHint> inlayHint2(InlayHintParams params, CancelChecker cancelT
return provider.inlayHint(params, cancelToken);
} finally {
compilerWorkspace.doneBuilding();
updatePurgeState();
LspASCompilationUnit.unpinAndRemoveASTs(purgeProject);
}
}

Expand Down Expand Up @@ -1398,6 +1431,7 @@ public void didChangeConfiguration(DidChangeConfigurationParams params) {
this.updateSourcePathWarning(settings);
this.updateJVMArgs(settings);
this.updateConcurrentRequests(settings);
this.updateAutoMemoryPurge(settings);
this.updateCodeGenerationGetterSettersForcePublicFunctions(settings);
this.updateCodeGenerationGetterSettersForcePrivateVariable(settings);
this.updateSourcesOrganizeImportsAddMissingImports(settings);
Expand Down Expand Up @@ -2038,6 +2072,19 @@ private ILspProject getProject(ActionScriptProjectData projectData) {
return project;
}

private void updatePurgeState() {
Set<String> openPaths = new HashSet<>();
for (Path openFilePath : fileTracker.getOpenFiles()) {
openPaths.add(openFilePath.toAbsolutePath().normalize().toString());
}
LspASCompilationUnit.setOpenPaths(openPaths);
purgeProject = null;
ActionScriptProjectData projectData = actionScriptProjectManager.getFallbackProjectData();
if (projectData != null) {
purgeProject = projectData.project;
}
}

private void clearProblemsForURI(URI uri) {
PublishDiagnosticsParams publish = new PublishDiagnosticsParams();
ArrayList<Diagnostic> diagnostics = new ArrayList<>();
Expand Down Expand Up @@ -2067,6 +2114,7 @@ private void checkProjectForProblems(ActionScriptProjectData projectData) {
}

ProblemQuery problemQuery = projectDataToProblemQuery(projectData);
LspASCompilationUnit.pinASTsToKeepAlive();
compilerWorkspace.startBuilding();
try {
if (!project.equals(projectData.project)) {
Expand Down Expand Up @@ -2103,6 +2151,8 @@ private void checkProjectForProblems(ActionScriptProjectData projectData) {
}
} finally {
compilerWorkspace.doneBuilding();
updatePurgeState();
LspASCompilationUnit.unpinAndRemoveASTs(purgeProject);
}
publishDiagnosticsForProblemQuery(problemQuery, projectData.codeProblemTracker, projectData, true);
}
Expand Down Expand Up @@ -2554,6 +2604,26 @@ private void updateConcurrentRequests(JsonObject settings) {
concurrentRequests = newConcurrentRequests;
}

private void updateAutoMemoryPurge(JsonObject settings) {
if (!settings.has("as3mxml")) {
return;
}
JsonObject as3mxml = settings.get("as3mxml").getAsJsonObject();
if (!as3mxml.has("languageServer")) {
return;
}
JsonObject languageServer = as3mxml.get("languageServer").getAsJsonObject();
if (!languageServer.has("autoMemoryPurge")) {
return;
}
boolean newAutoMemoryPurge = languageServer.get("autoMemoryPurge").getAsBoolean();
if (autoMemoryPurge == newAutoMemoryPurge) {
return;
}
autoMemoryPurge = newAutoMemoryPurge;
LspASCompilationUnit.setPurgeEnabled(autoMemoryPurge);
}

private void updateCodeGenerationGetterSettersForcePublicFunctions(JsonObject settings) {
if (!settings.has("as3mxml")) {
return;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,76 @@
package com.as3mxml.vscode.project;

import java.util.Collections;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.royale.compiler.internal.projects.CompilerProject;
import org.apache.royale.compiler.internal.projects.DefinitionPriority;
import org.apache.royale.compiler.internal.units.ASCompilationUnit;
import org.apache.royale.compiler.targets.ITarget.TargetType;
import org.apache.royale.compiler.units.ICompilationUnit;

public class LspASCompilationUnit extends ASCompilationUnit {
private static volatile boolean purgeEnabled = false;
private static final AtomicInteger pinCount = new AtomicInteger(0);
private static volatile LspASCompilationUnit activeUnit = null;
private static volatile Set<String> openPaths = Collections.emptySet();

public static void setPurgeEnabled(boolean enabled) {
purgeEnabled = enabled;
if (!enabled) {
pinCount.set(0);
activeUnit = null;
openPaths = Collections.emptySet();
}
}

public static void setActiveUnit(LspASCompilationUnit unit) {
activeUnit = unit;
}

public static void setOpenPaths(Set<String> paths) {
if (paths == null) {
openPaths = Collections.emptySet();
} else {
openPaths = paths;
}
}

public static void pinASTsToKeepAlive() {
if (!purgeEnabled) {
return;
}
pinCount.incrementAndGet();
}

public static void unpinAndRemoveASTs(ILspProject project) {
if (!purgeEnabled) {
return;
}
int count = pinCount.decrementAndGet();
if (count < 0) {
pinCount.compareAndSet(count, 0);
}
if (count <= 0) {
purgeUnpinnedASTs(project);
}
}

private static void purgeUnpinnedASTs(ILspProject project) {
if (project == null) {
return;
}
try {
for (ICompilationUnit unit : project.getCompilationUnits()) {
if (unit instanceof LspASCompilationUnit) {
((LspASCompilationUnit) unit).removeAST();
}
}
} catch (Exception e) {
}
}

public LspASCompilationUnit(CompilerProject project, String path,
DefinitionPriority.BasePriority basePriority,
int order,
Expand All @@ -15,10 +80,23 @@ public LspASCompilationUnit(CompilerProject project, String path,

@Override
protected void removeAST() {
// using a custom subclass of ASCompilationUnit to override this method
// because the default implementation allows ASTs to be garbage
// collected, and the scopes can get out of sync.
// that's probably a Royale compiler bug, but a workaround is easier.
if (!purgeEnabled || pinCount.get() > 0 || (this == activeUnit) || isOpen()) {
return;
}
super.removeAST();
}

private boolean isOpen() {
String filename = getAbsoluteFilename();
if (openPaths.contains(filename)) {
return true;
}
try {
String normalized = java.nio.file.Paths.get(filename).toAbsolutePath().normalize().toString();
return openPaths.contains(normalized);
} catch (Exception e) {
return false;
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.io.StringReader;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
Expand All @@ -47,7 +48,7 @@ public boolean isOpen(Path path) {
}

public Set<Path> getOpenFiles() {
return sourceByPath.keySet();
return new HashSet<>(sourceByPath.keySet());
}

public void openFile(Path path, String text) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

import com.as3mxml.vscode.project.ILspProject;
import com.as3mxml.vscode.project.ActionScriptProjectData;
import com.as3mxml.vscode.project.LspASCompilationUnit;

import org.apache.royale.compiler.clients.problems.ProblemQuery;
import org.apache.royale.compiler.filespecs.IFileSpecification;
Expand Down Expand Up @@ -85,6 +86,7 @@ public synchronized void setCompilationUnit(ICompilationUnit compilationUnit, IF
pendingProjectData = null;
pendingCompilationUnit = null;
pendingFileSpec = null;
LspASCompilationUnit.setActiveUnit((LspASCompilationUnit) compilationUnit);
// make these requests, but allow the compiler to handle things in a
// background thread for now. we can force it to complete synchronously
// later, if we need to.
Expand All @@ -101,6 +103,7 @@ public synchronized void clear() {
pendingProjectData = null;
pendingCompilationUnit = null;
pendingFileSpec = null;
LspASCompilationUnit.setActiveUnit(null);
}

public synchronized void updateNow() {
Expand Down
Loading