Skip to content

Commit

Permalink
Resolve type from ExprOf<T> when used with reification (and making re…
Browse files Browse the repository at this point in the history
…lease 1.4.11)
  • Loading branch information
m0rkeulv committed Aug 6, 2023
1 parent 0161fbb commit 5ab9709
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 8 deletions.
13 changes: 7 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# Changelog

## [Unreleased]
* Improved support for anonymous structures (#1131)
* Fixed incorrect symbol resolve (#968)
* Support for special interface ArrayAccess<T> (#957)
* Added QuickNavigateInfo (ctrl+hover over symbols)
* Prevent automatic asterisk insert for haxedoc
## 1.4.11
* Added: better support for anonymous structures (#1131)
* Bugfix: Fixed incorrect symbol resolve (#968)
* Added: Support for special interface ArrayAccess<T> (#957)
* Added: Resolve type from ExprOf<T> when used with reification
* Added: QuickNavigateInfo (ctrl+hover over symbols)
* Bugfix: Prevent automatic asterisk insert for HaxeDoc


## 1.4.10
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pluginName = Haxe Toolkit Support
pluginRepositoryUrl = https://github.com/HaxeFoundation/intellij-haxe

# SemVer format -> https://semver.org
pluginVersion = 1.4.11 (beta 1)
pluginVersion = 1.4.11

# IntelliJ Platform Properties -> https://github.com/JetBrains/gradle-intellij-plugin#intellij-platform-properties
platformType = IU
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ questionOperator ::= <<ternary>> { extends=operator }
suffixOperator ::= '!' { extends=operator }

// KFROM and KTO are only keywords for abstracts and can be used as identifiers elsewhere in the code (KNEVER is only used for getters/setters)
identifier ::= ID | MACRO_ID | KFROM | KTO | KNEVER
identifier ::= ID | KFROM | KTO | KNEVER | macroIdentifierReification | MACRO_ID
{mixin="com.intellij.plugins.haxe.lang.psi.impl.HaxeIdentifierPsiMixinImpl" implements="com.intellij.plugins.haxe.lang.psi.HaxeIdentifierPsiMixin" name="identifier"}

thisExpression ::= 'this'
Expand Down
22 changes: 22 additions & 0 deletions src/main/java/com/intellij/plugins/haxe/lang/psi/HaxeResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ private List<? extends PsiElement> doResolveInner(@NotNull HaxeReference referen
if (result == null) result = checkIsSuperExpression(reference);
if (result == null) result = checkIsClassName(reference);
if (result == null) result = checkMemberReference(reference);
if (result == null) result = checkMacroIdentifier(reference);
if (result == null) result = checkIsChain(reference);
if (result == null) result = checkIsAccessor(reference);
if (result == null) result = checkIsSwitchVar(reference);
Expand Down Expand Up @@ -219,6 +220,20 @@ private List<? extends PsiElement> doResolveInner(@NotNull HaxeReference referen
return result == null ? EMPTY_LIST : result;
}

private List<? extends PsiElement> checkMacroIdentifier(HaxeReference reference) {
@NotNull PsiElement[] children = reference.getChildren();
if (children.length == 1) {
if (children[0] instanceof HaxeIdentifier identifier) {
PsiElement macroId = identifier.getMacroId();
if (macroId != null) {
String substring = macroId.getText().substring(1);
return checkByTreeWalk(reference, substring);
}
}
}
return null;
}

private List<? extends PsiElement> checkMemberReference(HaxeReference reference) {
final HaxeReference leftReference = HaxeResolveUtil.getLeftReference(reference);
// check if reference is to a member in class or abstract
Expand Down Expand Up @@ -523,6 +538,13 @@ private List<? extends PsiElement> checkByTreeWalk(HaxeReference reference) {
LogResolution(reference, "via tree walk.");
return result;
}
private List<? extends PsiElement> checkByTreeWalk(HaxeReference scope, String name) {
final List<PsiElement> result = new ArrayList<>();
PsiTreeUtil.treeWalkUp(new ResolveScopeProcessor(result, name), scope, null, new ResolveState());
if (result.isEmpty()) return null;
LogResolution(scope, "via tree walk.");
return result;
}

private List<? extends PsiElement> checkIsAccessor(HaxeReference reference) {
if (reference instanceof HaxePropertyAccessor) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,50 @@ private boolean isType(Object o, Class clazz) {

@NotNull
private HaxeResolveResult resolveHaxeClassInternal() {
HaxeResolveResult result = _resolveHaxeClassInternal();

//extract type from expression if this is a macro ExprOf before we return result
if (isMacroIdentifier()) {
HaxeResolveResult type = extractTypeFromMacro(result);
if (type != null) result = type;
}

return result;
}

@Nullable
private static HaxeResolveResult extractTypeFromMacro(HaxeResolveResult result) {
HaxeClass aClass = result.getHaxeClass();
if(aClass != null) {
if (aClass.getQualifiedName().equals("haxe.macro.ExprOf")
// TODO : TEMP hack since typeDef is resolved and `ExprOf` is typedef of `Expr`
|| aClass.getQualifiedName().equals("haxe.macro.Expr")) {
HaxeGenericResolver resolver = result.getGenericResolver();
@NotNull ResultHolder[] specifics = resolver.getSpecifics();
if (specifics.length > 0) {
ResultHolder resolve = resolver.resolve("T");
if (resolve != null && !resolve.isUnknown()) {
SpecificHaxeClassReference type = resolve.getClassType();
if (type != null) return type.asResolveResult();
}
}
}
}
return null;
}

private boolean isMacroIdentifier() {
PsiElement[] children = this.getChildren();
if(children.length == 1) {
if (children[0] instanceof HaxeIdentifier identifier) {
if (identifier.getMacroId() != null) return true;
}
}
return false;
}

@NotNull
private HaxeResolveResult _resolveHaxeClassInternal() {
ProgressIndicatorProvider.checkCanceled();

PsiElement resolve = null;
Expand Down

0 comments on commit 5ab9709

Please sign in to comment.