Skip to content

Commit

Permalink
filtering files to index based on definitions/platform + added functi…
Browse files Browse the repository at this point in the history
…onType as a completion variant of methods.
  • Loading branch information
m0rkeulv committed May 18, 2024
1 parent 11e5f48 commit 81e8b1a
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@
import com.intellij.plugins.haxe.ide.lookup.*;
import com.intellij.plugins.haxe.lang.psi.*;
import com.intellij.plugins.haxe.model.*;
import com.intellij.plugins.haxe.model.type.HaxeExpressionEvaluator;
import com.intellij.plugins.haxe.model.type.ResultHolder;
import com.intellij.plugins.haxe.model.type.SpecificHaxeClassReference;
import com.intellij.plugins.haxe.model.type.*;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
Expand All @@ -33,37 +31,109 @@ public static Set<CompletionResult> calculatePriority(Set<CompletionResult> comp
.toList();

PsiElement position = parameters.getPosition();
PsiElement parent = position.getParent();
if (identifierInNewExpression.accepts(position)) {
return prioritizeConstructorsRemoveOtherMembers(completions);
}
// is argument (get parameter type)
boolean sorted = false;
if (!sorted) sorted = trySortForExtends(position, lookupList);
if (!sorted) sorted = trySortForArgument(position, lookupList); // NOTE TO SELF: function keyword if parameter is function typ
//if (!sorted) sorted = trySortForAssign(position, lookupList);
if (!sorted) sorted = trySortForAssign(position, lookupList);
if (!sorted) sorted = trySortForLoops(position, lookupList);
if (!sorted) sorted = trySortForIf(position, lookupList);
if (!sorted) sorted = trySortForBlock(position, lookupList);

//TODO WiP
// is for-loop (prioritize itrables)
// is extends (if class, then class, if interface then interfaces)
// is implements (interfaces)
//TODO support functionType reference ?
// is IF (prioritize bool)
// is switch block (find expression type, prioritize type)
// - if enumvalue compare declaring class with type

// local variables first (3), then fields(2) then methods (1)
return completions;
}

//DEBUG STUFF:
List<HaxeLookupElement> debugSortedList = lookupList.stream().sorted((o1, o2) -> {
double calculate1 = o1.getPriority().calculate();
double calculate2 = o2.getPriority().calculate();
if (calculate1 > calculate2) return -1;
if (calculate1 < calculate2) return 1;
return 0;
private static boolean trySortForAssign(PsiElement position, List<HaxeLookupElement> list) {
HaxeReferenceExpression reference = PsiTreeUtil.getParentOfType(position, HaxeReferenceExpression.class);
ResultHolder assignToType = null;

}).toList();
if(reference != null && reference.getParent() instanceof HaxeAssignExpression assignExpression) {
HaxeExpression assignTo = assignExpression.getExpressionList().get(0);
assignToType = HaxeExpressionEvaluator.evaluate(assignTo, null).result;

return completions;
}
if(reference != null && reference.getParent() instanceof HaxeVarInit init) {
PsiElement parent = init.getParent();
if(parent instanceof HaxeLocalVarDeclaration varDeclaration) {
HaxeTypeTag tag = varDeclaration.getTypeTag();
if (tag != null) {
assignToType = HaxeTypeResolver.getTypeFromTypeTag(tag, varDeclaration);
}
}
}

for (HaxeLookupElement element : list) {
if (element instanceof HaxeMemberLookupElement memberLookup) {
HaxeBaseMemberModel model = memberLookup.getModel();
if (model != null) {
if (assignToType != null && !assignToType.isUnknown()) {
ResultHolder lookupType = model.getResultType(null);
if (lookupType.canAssign(assignToType)) {
memberLookup.getPriority().type += 0.5;
}
}

if (model instanceof HaxeLocalVarModel || model instanceof HaxeParameterModel) {
element.getPriority().type += LOCAL_VAR;
}

if (model instanceof HaxeFieldModel) {
element.getPriority().type += FIELD;
}

if (model instanceof HaxeMethodModel) {
element.getPriority().type += METHOD;
}
}
}
}
return false;
}

private static boolean trySortForBlock(PsiElement position, List<HaxeLookupElement> list) {
HaxeReferenceExpression reference = PsiTreeUtil.getParentOfType(position, HaxeReferenceExpression.class);
if (reference != null && reference.getParent() instanceof HaxeBlockStatement blockStatement) {
for (HaxeLookupElement element : list) {
if (element instanceof HaxeMemberLookupElement memberLookup) {
if (memberLookup.isFunctionType()) {
// its less likely we want a functionType and more likely we want the call expression
memberLookup.getPriority().type -= 0.5;
}
}
}
return true;
}
return false;
}

private static boolean trySortForIf(PsiElement position, List<HaxeLookupElement> list) {
HaxeReferenceExpression reference = PsiTreeUtil.getParentOfType(position, HaxeReferenceExpression.class);
if (reference != null && reference.getParent() instanceof HaxeGuard) {
for (HaxeLookupElement element : list) {
if (element instanceof HaxeMemberLookupElement memberLookup) {
HaxeBaseMemberModel model = memberLookup.getModel();
if (model != null) {
ResultHolder type = model.getResultType(null);
if (type.isClassType()) {
if (type.getClassType().isBool()) {
memberLookup.getPriority().assignable += 3;
}
}
}
}
}
return true;
}
return false;
}

private static boolean trySortForLoops(PsiElement position, List<HaxeLookupElement> list) {
Expand Down Expand Up @@ -235,20 +305,26 @@ private static void memberCalculation(HaxeMemberLookupElement element, List<Stri
HaxeBaseMemberModel model = element.getModel();
if (model == null) return;

if(model instanceof HaxeLocalVarModel) {
ResultHolder lookupType = model.getResultType(null);

if(model instanceof HaxeLocalVarModel || model instanceof HaxeParameterModel) {
element.getPriority().type += LOCAL_VAR;
}

if(model instanceof HaxeFieldModel) {
if(model instanceof HaxeFieldModel ) {
element.getPriority().type += FIELD;
}

if (model instanceof HaxeMethodModel) {
if (model instanceof HaxeMethodModel methodModel) {
element.getPriority().type += METHOD;
// update lookupType with functionType instead of return type
if (element.isFunctionType()) {
lookupType = methodModel.getFunctionType(null).createHolder();
}
}

if (parameterTypes.size() <= argumentIndex) return;
ResultHolder lookupType = model.getResultType(null);

String lookupName = model.getName();
List<String> lookupWords = getWords(lookupName);

Expand Down Expand Up @@ -281,6 +357,14 @@ private static boolean calculateParameterPriority(HaxeMemberLookupElement elemen
matched = true;
}

if (expectedParameterType.isFunctionType() && lookupType.isFunctionType()) {
element.getPriority().assignable += 0.2 * boost;
}

if (!expectedParameterType.isFunctionType() && !lookupType.isFunctionType()) {
element.getPriority().assignable += 0.3 * boost;
}

String expectedParameterName = names.get(argumentIndex);
List<String> expectedWords = getWords(expectedParameterName);
int matches = findMatchingWords(words, expectedWords);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import com.google.common.collect.Sets;
import com.intellij.codeInsight.completion.*;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ReadAction;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
Expand Down Expand Up @@ -73,10 +72,12 @@ protected void addCompletions(@NotNull CompletionParameters parameters,
// for the sorting even tho it would be nice to also get the proximity sorting.
updatePsiElementValues(filteredCompletions);

// TODO mlo: suggest lambda / function when expected type is functionType

//TODO mlo: mechanism for filtering getters and setters ( get_X / set_x) when properties exists
//TODO mlo: mechanism for filtering getters and setters ( get_X / set_x) when properties exists ? (could be that noCompletion solves this)

// Since we've already run all of the providers, don't let them be repeated.

result.stopHere();
}
});
Expand Down Expand Up @@ -138,6 +139,8 @@ private static boolean shouldRemoveDuplicateCompletions(PsiFile file) {
}

private static Set<CompletionResult> removeDuplicateCompletions(Set<CompletionResult> unfilteredCompletions) {
//TODO not sure if this is preferred now that resolving works better, but if compiler data contains all necessary data then maybe

// We sort the elements according to name, giving preference to compiler-provided results
// if the two names are identical.
CompletionResult sorted[] = unfilteredCompletions.toArray(new CompletionResult[]{});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,16 @@ private static class MyDataIndexer implements DataIndexer<String, HaxeClassInfo,
public Map<String, HaxeClassInfo> map(final FileContent inputData) {
final PsiFile psiFile = inputData.getPsiFile();

//TODO might want to make a setting for this

// avoiding indexing platform specific versions of standard lib classes.
if (HaxeIndexUtil.fileBelongToPlatformSpecificStd(psiFile)) {
return Collections.emptyMap();
}

if (HaxeIndexUtil.belongToPlatformNotTargeted(psiFile)) {
return Collections.emptyMap();
}

final List<HaxeClass> classes = HaxeResolveUtil.findComponentDeclarations(psiFile);
if (classes.isEmpty()) {
return Collections.emptyMap();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,15 @@
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;

import com.intellij.plugins.haxe.haxelib.definitions.HaxeDefineDetectionManager;
import com.intellij.plugins.haxe.model.HaxeProjectModel;
import com.intellij.plugins.haxe.util.HaxeDebugUtil;
import com.intellij.psi.PsiFile;
import lombok.CustomLog;
import org.jetbrains.annotations.Nullable;

import java.util.Map;


/**
* Created by fedorkorotkov.
Expand Down Expand Up @@ -56,4 +59,34 @@ public static boolean warnIfDumbMode(Project project) {
}
return true;
}

public static boolean belongToPlatformNotTargeted(PsiFile file) {
Map<String, String> definitions = HaxeDefineDetectionManager.getInstance(file.getProject()).getAllDefinitions();
HaxeProjectModel project = HaxeProjectModel.fromElement(file);
if (project.getSdkRoot().contains(file)) {
String stdRootPath = project.getSdkRoot().access("").getVirtualFile().getPath();
String fileFullPath = file.getVirtualFile().getPath();
String replaced = fileFullPath.replace(stdRootPath, "");
String[] split = replaced.split("/");
if (split.length > 1) {
String scope = split[1];
return !switch (scope) {
case "cpp" -> definitions.containsKey("cpp");
case "cs" -> definitions.containsKey("cs");
case "flash" -> definitions.containsKey("flash");
case "hl" -> definitions.containsKey("hl");
case "java" -> definitions.containsKey("java");
case "js" -> definitions.containsKey("js");
case "jvm" -> definitions.containsKey("jvm");
case "lua" -> definitions.containsKey("lua");
case "php" -> definitions.containsKey("php");
case "python" -> definitions.containsKey("python");
default-> true;
};
}
}
return false;


}
}
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,9 @@ public Map<String, HaxeStaticMemberInfo> map(final FileContent inputData) {
if (HaxeIndexUtil.fileBelongToPlatformSpecificStd(psiFile)) {
return Collections.emptyMap();
}
//TODO
//if (HaxeIndexUtil.fileBelongToPlatformNotTargeted(psiFile)) {
// return Collections.emptyMap();
//}
if (HaxeIndexUtil.belongToPlatformNotTargeted(psiFile)) {
return Collections.emptyMap();
}

final List<HaxeClass> classes = HaxeResolveUtil.findComponentDeclarations(psiFile);
if (classes.isEmpty()) {
Expand Down
Loading

0 comments on commit 81e8b1a

Please sign in to comment.