Skip to content

Commit

Permalink
#303 - redesign reference resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
giraud committed May 19, 2021
1 parent 9262309 commit 649f67c
Show file tree
Hide file tree
Showing 179 changed files with 8,003 additions and 6,691 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ are solved.

## Unreleased

- :bug: [#303](https://github.com/reasonml-editor/reasonml-idea-plugin/issues/303) Incorrect resolution for record field
- :house: Reference resolution algorithm has been totally redesigned

## 0.100 - 2021/05/05

- :house: move to jfrog, bintray is no more available
Expand Down
18 changes: 10 additions & 8 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,26 +1,24 @@
plugins {
id 'org.jetbrains.intellij' version '0.7.2' // https://github.com/JetBrains/gradle-intellij-plugin
id 'java'
id 'org.jetbrains.intellij' version '0.7.3' // https://github.com/JetBrains/gradle-intellij-plugin
}

allprojects {
repositories {
jcenter()
mavenCentral()
}

apply plugin: 'java'
apply plugin: 'org.jetbrains.intellij'

sourceCompatibility = '1.8'
group 'com.reason'
version = pluginVersion + '-' + platformVersion
sourceCompatibility = '1.8'

compileJava.options.encoding = 'UTF-8'
group 'com.reason'

dependencies {
def powerMockVersion = '2.0.2'
testImplementation 'org.mockito:mockito-core:3.3.3'
testImplementation "org.powermock:powermock-module-junit4:${powerMockVersion}"
testImplementation "org.powermock:powermock-api-mockito2:${powerMockVersion}"
testImplementation 'junit:junit:4.12'
}

sourceSets {
Expand Down Expand Up @@ -59,6 +57,10 @@ allprojects {
}
}

runIde {
systemProperty 'idea.is.internal', true
}

verifyPlugin {
pluginDirectory 'resources'
}
Expand Down
91 changes: 54 additions & 37 deletions jps-plugin/src/com/reason/Joiner.java
Original file line number Diff line number Diff line change
@@ -1,52 +1,69 @@
package com.reason;

import org.jetbrains.annotations.*;

import java.util.function.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class Joiner {

private Joiner() {}

@NotNull
public static <T> String join(@NotNull String separator, @Nullable Iterable<T> items) {
return join(separator, items, Object::toString);
}
private Joiner() {
}

@NotNull
public static <T> String join(
@NotNull String separator, @Nullable Iterable<T> items, @NotNull Function<T, String> fn) {
if (items == null) {
return "<null>";
@NotNull
public static <T> String join(@NotNull String separator, @Nullable Iterable<T> items) {
return join(separator, items, Object::toString);
}

StringBuilder sb = new StringBuilder();
boolean first = true;
for (T item : items) {
if (!first) {
sb.append(separator);
}
sb.append(fn.apply(item));
first = false;
@NotNull
public static <T> String join(
@NotNull String separator, @Nullable Iterable<T> items, @NotNull Function<T, String> fn) {
if (items == null) {
return "<null>";
}

StringBuilder sb = new StringBuilder();
boolean first = true;
for (T item : items) {
if (!first) {
sb.append(separator);
}
sb.append(fn.apply(item));
first = false;
}
return sb.toString();
}
return sb.toString();
}

@NotNull
public static String join(@NotNull String separator, @Nullable Object[] items) {
if (items == null) {
return "<null>";
@NotNull
public static String join(@NotNull String separator, @Nullable Object[] items) {
if (items == null) {
return "<null>";
}

StringBuilder sb = new StringBuilder();
boolean first = true;
for (Object item : items) {
if (!first) {
sb.append(separator);
}
sb.append(item);
first = false;
}
return sb.toString();
}

StringBuilder sb = new StringBuilder();
boolean first = true;
for (Object item : items) {
if (!first) {
sb.append(separator);
}
sb.append(item);
first = false;
@NotNull
public static String joinFrom(@NotNull String separator, @Nullable Object[] items, int from) {
if (items == null) {
return "<null>";
}

StringBuilder sb = new StringBuilder();
for (int i = from; i < items.length; i++) {
if (i != from) {
sb.append(separator);
}
sb.append(items[i]);
}
return sb.toString();
}
return sb.toString();
}
}
15 changes: 3 additions & 12 deletions jps-plugin/src/com/reason/Log.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import com.intellij.openapi.project.*;
import com.intellij.openapi.vfs.*;
import com.intellij.psi.*;
import com.reason.lang.core.psi.*;
import org.jetbrains.annotations.*;

import java.io.*;
Expand Down Expand Up @@ -160,7 +159,7 @@ public void trace(String comment, @Nullable Collection<?> t) {
}
}

public void debug(String comment, @NotNull PsiQualifiedElement element) {
public void debug(String comment, @NotNull PsiQualifiedNamedElement element) {
if (m_log.isDebugEnabled()) {
m_log.debug(
comment
Expand All @@ -172,7 +171,7 @@ public void debug(String comment, @NotNull PsiQualifiedElement element) {
}
}

public void debug(String comment, @NotNull PsiQualifiedElement element, int position) {
public void debug(String comment, @NotNull PsiQualifiedNamedElement element, int position) {
if (m_log.isDebugEnabled()) {
m_log.debug(
comment
Expand Down Expand Up @@ -220,15 +219,7 @@ public void debug(String msg, VirtualFile[] files) {

public void debug(String msg, PsiElement element) {
if (m_log.isDebugEnabled()) {
m_log.debug(
msg
+ SEP
+ " "
+ element
+ SEP
+ (element instanceof PsiNamedElement
? " [" + ((PsiNamedElement) element).getName() + "]"
: ""));
m_log.debug(msg + SEP + element + (element instanceof PsiNamedElement ? ", name=[" + ((PsiNamedElement) element).getName() + "]" : ""));
}
}

Expand Down
12 changes: 0 additions & 12 deletions jps-plugin/src/com/reason/lang/core/psi/PsiQualifiedElement.java

This file was deleted.

5 changes: 5 additions & 0 deletions resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,8 @@
<stubIndex implementation="com.reason.ide.search.index.ModuleComponentIndex"/>
<stubIndex implementation="com.reason.ide.search.index.ModuleFqnIndex"/>
<stubIndex implementation="com.reason.ide.search.index.ModuleIndex"/>
<stubIndex implementation="com.reason.ide.search.index.ModuleAliasedIndex"/>
<stubIndex implementation="com.reason.ide.search.index.ModuleAliasesIndex"/>
<stubIndex implementation="com.reason.ide.search.index.LetIndex"/>
<stubIndex implementation="com.reason.ide.search.index.LetFqnIndex"/>
<stubIndex implementation="com.reason.ide.search.index.ValIndex"/>
Expand All @@ -252,12 +254,15 @@
<stubIndex implementation="com.reason.ide.search.index.RecordFieldIndex"/>
<stubIndex implementation="com.reason.ide.search.index.ParameterIndex"/>
<stubIndex implementation="com.reason.ide.search.index.ParameterFqnIndex"/>
<stubIndex implementation="com.reason.ide.search.index.IncludeIndex"/>
<stubIndex implementation="com.reason.ide.search.index.OpenIndex"/>

<fileBasedIndex implementation="com.reason.ide.search.index.FileModuleIndex"/>
<fileBasedIndex implementation="com.reason.ide.search.index.NamespaceIndex"/>
<applicationService serviceImplementation="com.reason.ide.search.FileModuleIndexService"/>

<projectService serviceImplementation="com.reason.ide.search.PsiFinder"/>
<projectService serviceImplementation="com.reason.lang.core.psi.reference.ORElementResolver"/>

<lang.findUsagesProvider language="Reason" implementationClass="com.reason.ide.search.RmlFindUsagesProvider"/>
<lang.findUsagesProvider language="NapkinScript"
Expand Down
63 changes: 26 additions & 37 deletions src/com/reason/ide/docs/ORDocumentationProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.util.*;

public class ORDocumentationProvider implements DocumentationProvider {
private static final Log LOG = Log.create("doc");

@Override
public @Nullable String generateDoc(PsiElement element, @Nullable PsiElement originalElement) {
Expand Down Expand Up @@ -86,16 +87,16 @@ public class ORDocumentationProvider implements DocumentationProvider {
return null;
}

@Nullable
@Override
public String getQuickNavigateInfo(
@NotNull PsiElement resolvedIdentifier, @NotNull PsiElement originalElement) {
public @Nullable String getQuickNavigateInfo(@NotNull PsiElement resolvedIdentifier, @NotNull PsiElement originalElement) {
String quickDoc = null;

if (resolvedIdentifier instanceof ORFakeResolvedElement) {
// A fake element, used to query inferred types
quickDoc = "Show usages of fake element '" + resolvedIdentifier.getText() + "'";
} else if (resolvedIdentifier instanceof FileBase) {
LOG.debug("Quickdoc of topModule", resolvedIdentifier);

FileBase resolvedFile = (FileBase) resolvedIdentifier;
String relative_path = Platform.getRelativePathToModule(resolvedFile);
quickDoc =
Expand All @@ -107,28 +108,26 @@ public String getQuickNavigateInfo(
+ resolvedFile.getModuleName()
+ DocFormatter.NAME_END;
} else {
PsiElement resolvedElement =
(resolvedIdentifier instanceof PsiLowerIdentifier
|| resolvedIdentifier instanceof PsiUpperIdentifier)
? resolvedIdentifier.getParent()
: resolvedIdentifier;
PsiElement resolvedElement = (resolvedIdentifier instanceof PsiLowerIdentifier
|| resolvedIdentifier instanceof PsiUpperIdentifier)
? resolvedIdentifier.getParent()
: resolvedIdentifier;

if (resolvedElement instanceof PsiType) {
PsiType type = (PsiType) resolvedElement;
String path = ORUtil.getQualifiedPath(type);
String typeBinding =
type.isAbstract()
? "This is an abstract type"
: DocFormatter.escapeCodeForHtml(type.getBinding());
String[] path = ORUtil.getQualifiedPath(type);
String typeBinding = type.isAbstract()
? "This is an abstract type"
: DocFormatter.escapeCodeForHtml(type.getBinding());
return createQuickDocTemplate(path, "type", resolvedIdentifier.getText(), typeBinding);
}

if (resolvedElement instanceof PsiSignatureElement) {
PsiSignature signature = ((PsiSignatureElement) resolvedElement).getSignature();
if (signature != null) {
String sig = DocFormatter.escapeCodeForHtml(signature.asText(originalElement.getLanguage()));
if (resolvedElement instanceof PsiQualifiedElement) {
PsiQualifiedElement qualifiedElement = (PsiQualifiedElement) resolvedElement;
if (resolvedElement instanceof PsiQualifiedPathElement) {
PsiQualifiedPathElement qualifiedElement = (PsiQualifiedPathElement) resolvedElement;
String elementType = PsiTypeElementProvider.getType(resolvedIdentifier);
return createQuickDocTemplate(qualifiedElement.getPath(), elementType, qualifiedElement.getName(), sig);
}
Expand All @@ -137,39 +136,34 @@ public String getQuickNavigateInfo(
}

// No signature found, but resolved
if (resolvedElement instanceof PsiQualifiedElement) {
if (resolvedElement instanceof PsiQualifiedNamedElement) {
LOG.debug("Quickdoc resolved to ", resolvedElement);

String elementType = PsiTypeElementProvider.getType(resolvedIdentifier);
String desc = ((PsiQualifiedElement) resolvedElement).getName();
String path = ORUtil.getQualifiedPath((PsiQualifiedElement) resolvedElement);
String desc = ((PsiQualifiedNamedElement) resolvedElement).getName();
String[] path = ORUtil.getQualifiedPath(resolvedElement);

PsiFile psiFile = originalElement.getContainingFile();
String inferredType =
getInferredSignature(originalElement, psiFile, originalElement.getLanguage());
String inferredType = getInferredSignature(originalElement, psiFile, originalElement.getLanguage());

if (inferredType == null) {
// Can't find type in the usage, try to get type from the definition
inferredType =
getInferredSignature(
resolvedIdentifier,
resolvedElement.getContainingFile(),
resolvedElement.getLanguage());
inferredType = getInferredSignature(resolvedIdentifier, resolvedElement.getContainingFile(), resolvedElement.getLanguage());
}

String sig = inferredType == null ? null : DocFormatter.escapeCodeForHtml(inferredType);
if (resolvedElement instanceof PsiVariantDeclaration) {
sig = "type " + ((PsiType) resolvedElement.getParent().getParent()).getName();
}

return createQuickDocTemplate(
path, elementType, desc, resolvedElement instanceof PsiModule ? null : sig);
return createQuickDocTemplate(path, elementType, desc, resolvedElement instanceof PsiModule ? null : sig);
}
}

return quickDoc;
}

@Nullable
private PsiElement findAboveComment(@Nullable PsiElement element) {
private @Nullable PsiElement findAboveComment(@Nullable PsiElement element) {
if (element == null) {
return null;
}
Expand Down Expand Up @@ -200,13 +194,8 @@ private PsiElement findBelowComment(@Nullable PsiElement element) {
return null;
}

@Nullable
@Override
public PsiElement getCustomDocumentationElement(
@NotNull Editor editor,
@NotNull PsiFile file,
@Nullable PsiElement contextElement,
int targetOffset) {
public @Nullable PsiElement getCustomDocumentationElement(@NotNull Editor editor, @NotNull PsiFile file, @Nullable PsiElement contextElement, int targetOffset) {
// When quick doc inside empty parenthesis, we want to display the function doc (github #155)
// functionName(<caret>) ==> functionName<caret>()
if (contextElement != null
Expand Down Expand Up @@ -254,8 +243,8 @@ private String getInferredSignature(@NotNull PsiElement element, @NotNull PsiFil
}

@NotNull
private String createQuickDocTemplate(@NotNull String qPath, @Nullable String type, @Nullable String name, @Nullable String signature) {
return qPath
private String createQuickDocTemplate(@Nullable String[] path, @Nullable String type, @Nullable String name, @Nullable String signature) {
return Joiner.join(".", path)
+ "<br/>"
+ (type == null ? "" : type)
+ (" <b>" + name + "</b>")
Expand Down
Loading

0 comments on commit 649f67c

Please sign in to comment.