Skip to content

Commit a1037d1

Browse files
committed
checkpoint
1 parent dee2d5e commit a1037d1

File tree

7 files changed

+200
-56
lines changed

7 files changed

+200
-56
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ lib/*.jar
1717
lib/jxbrowser/*
1818
!lib/jxbrowser/jxbrowser-7.16.jar
1919
!lib/jxbrowser/jxbrowser-swing-7.16.jar
20+
!lib/java-string-similarity-2.0.0.jar
2021
material-design-icons/
2122
out/
2223
packages

flutter-idea/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ intellij {
5050
downloadSources false
5151
localPath "${project.rootDir.absolutePath}/artifacts/$ide"
5252
plugins "java", "Dart:$dartVersion", "properties", "junit", "Kotlin", "Git4Idea",
53-
"gradle", "Groovy", "smali", "IntelliLang", "org.jetbrains.android"
53+
"gradle", "Groovy", "smali", "IntelliLang", "org.jetbrains.android", "yaml"
5454
}
5555

5656
dependencies {

flutter-intellij.iml

+1
Original file line numberDiff line numberDiff line change
@@ -123,5 +123,6 @@
123123
<orderEntry type="library" name="com.google.protobuf:protobuf-java:3.5.1" level="project" />
124124
<orderEntry type="library" name="KotlinJavaRuntime" level="project" />
125125
<orderEntry type="library" name="Dart Packages" level="project" />
126+
<orderEntry type="library" name="java-string-similarity-2.0.0" level="project" />
126127
</component>
127128
</module>

lib/java-string-similarity-2.0.0.jar

35.3 KB
Binary file not shown.

src/io/flutter/editor/FlutterIconLineMarkerProvider.java

+45-39
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,12 @@
4343
import com.jetbrains.lang.dart.psi.DartVarInit;
4444
import com.jetbrains.lang.dart.util.DartPsiImplUtil;
4545
import com.jetbrains.lang.dart.util.DartResolveUtil;
46+
import gnu.trove.THashSet;
47+
import info.debatty.java.stringsimilarity.JaroWinkler;
4648
import io.flutter.FlutterBundle;
4749
import io.flutter.utils.IconPreviewGenerator;
48-
import java.util.ArrayList;
49-
import java.util.HashMap;
50-
import java.util.List;
51-
import java.util.Map;
50+
51+
import java.util.*;
5252
import javax.swing.Icon;
5353
import org.jetbrains.annotations.NotNull;
5454
import org.jetbrains.annotations.Nullable;
@@ -58,13 +58,13 @@
5858

5959
public class FlutterIconLineMarkerProvider extends LineMarkerProviderDescriptor {
6060

61-
public static final Map<String, String> KnownPaths = new HashMap<>();
61+
public static final Map<String, Set<String>> KnownPaths = new HashMap<>();
6262
private static final Logger LOG = Logger.getInstance(FlutterIconLineMarkerProvider.class);
6363

6464
static {
65-
KnownPaths.put("Icons", "packages/flutter/lib/src/material");
66-
KnownPaths.put("IconData", "packages/flutter/lib/src/widgets");
67-
KnownPaths.put("CupertinoIcons", "packages/flutter/lib/src/cupertino");
65+
KnownPaths.put("Icons", new THashSet<String>(Collections.singleton("packages/flutter/lib/src/material")));
66+
KnownPaths.put("IconData", new THashSet<String>(Collections.singleton("packages/flutter/lib/src/widgets")));
67+
KnownPaths.put("CupertinoIcons", new THashSet<String>(Collections.singleton("packages/flutter/lib/src/cupertino")));
6868
}
6969

7070
@Nullable("null means disabled")
@@ -84,6 +84,7 @@ public LineMarkerInfo<?> getLineMarkerInfo(@NotNull PsiElement element) {
8484
if (refExpr == null) return null;
8585
PsiElement parent = refExpr.getParent();
8686
if (parent == null) return null;
87+
String knownPath = null;
8788

8889
// Resolve the class reference and check that it is one of the known, cached classes.
8990
if (!ApplicationManager.getApplication().isUnitTestMode()) {
@@ -92,20 +93,25 @@ public LineMarkerInfo<?> getLineMarkerInfo(@NotNull PsiElement element) {
9293
final PsiElement result = ((DartReference)symbol).resolve();
9394
if (result == null) return null;
9495
final List<VirtualFile> library = DartResolveUtil.findLibrary(result.getContainingFile());
95-
boolean found = false;
9696
for (VirtualFile file : library) {
97-
VirtualFile dir = file.getParent();
97+
final VirtualFile dir = file.getParent();
9898
if (dir.isInLocalFileSystem()) {
9999
final String path = dir.getPath();
100-
final String knownPath = KnownPaths.get(name);
101-
if (path.endsWith(knownPath) || knownPath.contains(path)) {
102-
found = true;
100+
final Set<String> knownPaths = KnownPaths.get(name);
101+
if (knownPaths.contains(path)) {
102+
knownPath = path;
103103
break;
104104
}
105+
for (String aPath : knownPaths) {
106+
if (path.endsWith(aPath) || aPath.contains(path)) {
107+
knownPath = aPath;
108+
break;
109+
}
110+
}
105111
}
106112
}
107-
if (!found) return null;
108113
}
114+
if (knownPath == null) return null;
109115

110116
if (parent.getNode().getElementType() == DartTokenTypes.CALL_EXPRESSION) {
111117
// Check font family and package
@@ -170,9 +176,9 @@ else if (name.equals("CupertinoIcons")) {
170176
final PsiElement symbol = refExpr.getLastChild();
171177
if (symbol == null) return null; // TODO check for instance creation with codepoint
172178
final String iconName = symbol.getText();
173-
final IconInfo iconDef = findDefinition(name, iconName, element.getProject());
179+
final IconInfo iconDef = findDefinition(name, iconName, element.getProject(), knownPath);
174180
if (iconDef == null) return null;
175-
icon = findIconFromDef(name, iconDef);
181+
icon = findIconFromDef(name, iconDef, knownPath);
176182
}
177183
if (icon != null) {
178184
return createLineMarker(element, icon);
@@ -201,29 +207,28 @@ private Icon getIconFromCode(@NotNull String value) {
201207

202208
private LineMarkerInfo<PsiElement> createLineMarker(@Nullable PsiElement element, @NotNull Icon icon) {
203209
if (element == null) return null;
210+
//noinspection MissingRecentApi
204211
return new LineMarkerInfo<>(element, element.getTextRange(), icon, null, null,
205212
GutterIconRenderer.Alignment.LEFT, () -> "");
206213
}
207214

208-
private IconInfo findDefinition(@NotNull String className, @NotNull String iconName, @NotNull Project project) {
209-
final String path = KnownPaths.get(className);
215+
private IconInfo findDefinition(@NotNull String className, @NotNull String iconName, @NotNull Project project, @NotNull String path) {
210216
final VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByPath(path);
211217
if (virtualFile == null) return null;
212218
final PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile);
213219
if (psiFile == null) {
214220
return null;
215221
}
216-
IconInfoVisitor visitor = new IconInfoVisitor(iconName);
222+
final IconInfoVisitor visitor = new IconInfoVisitor(iconName);
217223
psiFile.accept(visitor);
218224
return visitor.info;
219225
}
220226

221-
private Icon findIconFromDef(String iconClassName, IconInfo iconDef) {
222-
final String path = KnownPaths.get(iconClassName);
227+
private Icon findIconFromDef(@NotNull String iconClassName, @NotNull IconInfo iconDef, @NotNull String path) {
223228
final VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByPath(path);
224229
if (virtualFile == null) return null;
225230
final VirtualFile parent = virtualFile.getParent();
226-
List<VirtualFile> ttfFiles = new ArrayList<>();
231+
final List<VirtualFile> ttfFiles = new ArrayList<>();
227232
VfsUtilCore.visitChildrenRecursively(parent, new VirtualFileVisitor<Object>() {
228233
@Override
229234
public boolean visitFile(@NotNull VirtualFile file) {
@@ -236,33 +241,34 @@ public boolean visitFile(@NotNull VirtualFile file) {
236241
}
237242
}
238243
});
239-
int match = -1;
244+
double match = -1;
240245
String family = iconDef.familyName;
241246
VirtualFile bestFileMatch = null;
242247
if (family == null) family = "FontAwesomeSolid";
243248
for (VirtualFile file : ttfFiles) {
244-
int n = findPattern(file.getNameWithoutExtension(), family);
249+
final double n = findPattern(file.getNameWithoutExtension(), family);
245250
if (n > match) {
246251
match = n;
247252
bestFileMatch = file;
248253
}
249254
}
250255
if (bestFileMatch != null) {
251-
IconPreviewGenerator generator = new IconPreviewGenerator(bestFileMatch.getPath());
252-
Icon icon = generator.convert(iconDef.codepoint);
256+
final IconPreviewGenerator generator = new IconPreviewGenerator(bestFileMatch.getPath());
257+
final Icon icon = generator.convert(iconDef.codepoint);
253258
if (icon != null) return icon;
254259
}
255260
for (VirtualFile file : ttfFiles) {
256-
IconPreviewGenerator generator = new IconPreviewGenerator(file.getPath());
257-
Icon icon = generator.convert(iconDef.codepoint);
261+
final IconPreviewGenerator generator = new IconPreviewGenerator(file.getPath());
262+
final Icon icon = generator.convert(iconDef.codepoint);
258263
if (icon != null) return icon;
259264
}
260265
return null;
261266
}
262267

263-
public int findPattern(String t, String p) {
268+
public double findPattern(@NotNull String t, @NotNull String p) {
264269
// TODO Experiment with https://github.com/tdebatty/java-string-similarity
265-
return 0;
270+
final JaroWinkler jw = new JaroWinkler();
271+
return jw.similarity(t, p);
266272
}
267273

268274
static class IconInfo {
@@ -299,7 +305,7 @@ else if (expression instanceof DartStringLiteralExpression) {
299305
}
300306
else if (expression.getNode().getElementType() == DartTokenTypes.REFERENCE_EXPRESSION) {
301307
final Pair<String, TextRange> pair = DartPsiImplUtil.getUnquotedDartStringAndItsRange(expression.getText().trim());
302-
String varName = pair.first;
308+
final String varName = pair.first;
303309
return staticVars.get(varName);
304310
}
305311
return null;
@@ -308,11 +314,11 @@ else if (expression.getNode().getElementType() == DartTokenTypes.REFERENCE_EXPRE
308314
@Override
309315
public void visitVarAccessDeclaration(@NotNull DartVarAccessDeclaration o) {
310316
if (o.getComponentName().getText().trim().equals(iconName)) {
311-
DartVarInit init = (DartVarInit)o.getParent().getLastChild();
317+
final DartVarInit init = (DartVarInit)o.getParent().getLastChild();
312318
final DartExpression expression = init.getExpression();
313319
if (expression instanceof DartNewExpression) {
314-
DartNewExpression newExpr = (DartNewExpression)expression;
315-
DartType type = newExpr.getType();
320+
final DartNewExpression newExpr = (DartNewExpression)expression;
321+
final DartType type = newExpr.getType();
316322
if (type != null) {
317323
final String className = type.getText();
318324
if (KnownPaths.containsKey(className)) {
@@ -322,9 +328,9 @@ public void visitVarAccessDeclaration(@NotNull DartVarAccessDeclaration o) {
322328
if (argumentList != null) {
323329
final List<DartExpression> list = argumentList.getExpressionList();
324330
if (!list.isEmpty()) {
325-
String codepoint = list.get(0).getText();
326-
final PsiElement family = getNamedArgumentExpression(arguments, "family");
327-
String familyName = findFamilyName(family, type);
331+
final String codepoint = list.get(0).getText();
332+
final PsiElement family = getNamedArgumentExpression(arguments, "fontFamily");
333+
final String familyName = findFamilyName(family, type);
328334
info = new IconInfo(className, iconName, familyName, codepoint);
329335
}
330336
}
@@ -335,8 +341,8 @@ public void visitVarAccessDeclaration(@NotNull DartVarAccessDeclaration o) {
335341
}
336342
else {
337343
if (o.getFirstChild().getText().trim().equals("static")) {
338-
String varName = o.getComponentName().getText().trim();
339-
DartVarInit init = (DartVarInit)o.getParent().getLastChild();
344+
final String varName = o.getComponentName().getText().trim();
345+
final DartVarInit init = (DartVarInit)o.getParent().getLastChild();
340346
final DartExpression expression = init.getExpression();
341347
if (expression instanceof DartStringLiteralExpression) {
342348
final Pair<String, TextRange> pair = DartPsiImplUtil.getUnquotedDartStringAndItsRange(expression.getText());

0 commit comments

Comments
 (0)