Skip to content

Commit 16dd0ec

Browse files
committed
Tighten up control flow and fix tests
1 parent db773ae commit 16dd0ec

8 files changed

+182
-129
lines changed

.idea/runConfigurations/Flutter_Plugin.xml

+6-5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/io/flutter/FlutterBundle.properties

+4
Original file line numberDiff line numberDiff line change
@@ -238,3 +238,7 @@ coverage.path.not.found=Coverage file not found: {0}
238238
progress.title.loading.coverage.data=Loading coverage data...
239239
project.root.not.found=Could not find project root
240240
coverage.data.not.read=Cannot read coverage data from file: {0}
241+
icon.preview.disallow.flutter_icons=Package "flutter_icons" is not supported.
242+
icon.preview.disallow.flutter_vector_icons=Package "flutter_vector_icons" cannot show previews because it does not include a font file.
243+
icon.preview.disallow.material_design_icons_flutter=Package "material_design_icons_flutter" always displays blank icon previews.
244+
icon.preview.disallow.package.title=Unsupported icon package

src/io/flutter/FlutterMessages.java

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
public class FlutterMessages {
2020
public static final String FLUTTER_NOTIFICATION_GROUP_ID = "Flutter Messages";
21+
public static final String FLUTTER_LOGGING_NOTIFICATION_GROUP_ID = "Flutter Notifications";
2122

2223
private FlutterMessages() {
2324
}

src/io/flutter/editor/FlutterIconLineMarkerProvider.java

+58-71
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,9 @@
55
*/
66
package io.flutter.editor;
77

8-
import static io.flutter.dart.DartPsiUtil.getNamedArgumentExpression;
9-
import static io.flutter.dart.DartPsiUtil.getNewExprFromType;
10-
import static io.flutter.dart.DartPsiUtil.getValueOfNamedArgument;
11-
import static io.flutter.dart.DartPsiUtil.getValueOfPositionalArgument;
12-
import static io.flutter.dart.DartPsiUtil.parseLiteralNumber;
13-
import static io.flutter.dart.DartPsiUtil.topmostReferenceExpression;
14-
158
import com.intellij.codeInsight.daemon.GutterName;
169
import com.intellij.codeInsight.daemon.LineMarkerInfo;
1710
import com.intellij.codeInsight.daemon.LineMarkerProviderDescriptor;
18-
import com.intellij.openapi.application.ApplicationManager;
1911
import com.intellij.openapi.diagnostic.Logger;
2012
import com.intellij.openapi.editor.markup.GutterIconRenderer;
2113
import com.intellij.openapi.project.Project;
@@ -30,42 +22,37 @@
3022
import com.intellij.psi.PsiManager;
3123
import com.intellij.psi.impl.source.tree.AstBufferUtil;
3224
import com.jetbrains.lang.dart.DartTokenTypes;
33-
import com.jetbrains.lang.dart.psi.DartArgumentList;
34-
import com.jetbrains.lang.dart.psi.DartArguments;
35-
import com.jetbrains.lang.dart.psi.DartCallExpression;
36-
import com.jetbrains.lang.dart.psi.DartExpression;
37-
import com.jetbrains.lang.dart.psi.DartNewExpression;
38-
import com.jetbrains.lang.dart.psi.DartRecursiveVisitor;
39-
import com.jetbrains.lang.dart.psi.DartReference;
40-
import com.jetbrains.lang.dart.psi.DartStringLiteralExpression;
41-
import com.jetbrains.lang.dart.psi.DartType;
42-
import com.jetbrains.lang.dart.psi.DartVarAccessDeclaration;
43-
import com.jetbrains.lang.dart.psi.DartVarInit;
25+
import com.jetbrains.lang.dart.psi.*;
4426
import com.jetbrains.lang.dart.psi.impl.DartCallExpressionImpl;
4527
import com.jetbrains.lang.dart.util.DartPsiImplUtil;
4628
import com.jetbrains.lang.dart.util.DartResolveUtil;
4729
import gnu.trove.THashSet;
4830
import info.debatty.java.stringsimilarity.JaroWinkler;
4931
import io.flutter.FlutterBundle;
5032
import io.flutter.utils.IconPreviewGenerator;
51-
52-
import java.util.*;
53-
import javax.swing.Icon;
5433
import org.jetbrains.annotations.NotNull;
5534
import org.jetbrains.annotations.Nullable;
5635
import org.jetbrains.yaml.psi.YAMLCompoundValue;
5736
import org.jetbrains.yaml.psi.YAMLKeyValue;
5837
import org.jetbrains.yaml.psi.YamlRecursivePsiElementVisitor;
5938

39+
import javax.swing.*;
40+
import java.util.*;
41+
42+
import static io.flutter.dart.DartPsiUtil.*;
43+
44+
// Style note: Normally we put control flow changing statements on a separate line in a block.
45+
// When working with PSI elements nearly everything can return null. There are a lot of null checks
46+
// that could return null, but they seldom trigger, so the return is on the same line as the if statement.
6047
public class FlutterIconLineMarkerProvider extends LineMarkerProviderDescriptor {
6148

6249
public static final Map<String, Set<String>> KnownPaths = new HashMap<>();
6350
private static final Logger LOG = Logger.getInstance(FlutterIconLineMarkerProvider.class);
6451

6552
static {
66-
KnownPaths.put("Icons", new THashSet<String>(Collections.singleton("packages/flutter/lib/src/material")));
67-
KnownPaths.put("IconData", new THashSet<String>(Collections.singleton("packages/flutter/lib/src/widgets")));
68-
KnownPaths.put("CupertinoIcons", new THashSet<String>(Collections.singleton("packages/flutter/lib/src/cupertino")));
53+
KnownPaths.put("Icons", new THashSet<>(Collections.singleton("packages/flutter/lib/src/material")));
54+
KnownPaths.put("IconData", new THashSet<>(Collections.singleton("packages/flutter/lib/src/widgets")));
55+
KnownPaths.put("CupertinoIcons", new THashSet<>(Collections.singleton("packages/flutter/lib/src/cupertino")));
6956
}
7057

7158
@Nullable("null means disabled")
@@ -88,34 +75,32 @@ public LineMarkerInfo<?> getLineMarkerInfo(@NotNull PsiElement element) {
8875
String knownPath = null;
8976

9077
// Resolve the class reference and check that it is one of the known, cached classes.
91-
if (!ApplicationManager.getApplication().isUnitTestMode()) {
92-
final PsiElement symbol = "IconData".equals(name) ? refExpr : refExpr.getFirstChild();
93-
if (!(symbol instanceof DartReference)) return null;
94-
final PsiElement result = ((DartReference)symbol).resolve();
95-
if (result == null) return null;
96-
final List<VirtualFile> library = DartResolveUtil.findLibrary(result.getContainingFile());
97-
for (VirtualFile file : library) {
98-
final VirtualFile dir = file.getParent();
99-
if (dir.isInLocalFileSystem()) {
100-
final String path = dir.getPath();
101-
String trimmedPath = path;
102-
if (!path.endsWith("lib")) {
103-
final int index = path.indexOf("lib");
104-
if (index >= 0) {
105-
trimmedPath = path.substring(0, index + 3);
106-
}
78+
final PsiElement symbol = "IconData".equals(name) ? refExpr : refExpr.getFirstChild();
79+
if (!(symbol instanceof DartReference)) return null;
80+
final PsiElement result = ((DartReference)symbol).resolve();
81+
if (result == null) return null;
82+
final List<VirtualFile> library = DartResolveUtil.findLibrary(result.getContainingFile());
83+
for (VirtualFile file : library) {
84+
final VirtualFile dir = file.getParent();
85+
if (dir.isInLocalFileSystem()) {
86+
final String path = dir.getPath();
87+
String trimmedPath = path;
88+
if (!path.endsWith("lib")) {
89+
final int index = path.indexOf("lib");
90+
if (index >= 0) {
91+
trimmedPath = path.substring(0, index + 3);
10792
}
108-
final Set<String> knownPaths = KnownPaths.get(name);
109-
if (knownPaths.contains(path) || knownPaths.contains(trimmedPath)) {
93+
}
94+
final Set<String> knownPaths = KnownPaths.get(name);
95+
if (knownPaths.contains(path) || knownPaths.contains(trimmedPath)) {
96+
knownPath = file.getPath();
97+
break;
98+
}
99+
for (String aPath : knownPaths) {
100+
if (path.endsWith(aPath) || aPath.contains(path) || trimmedPath.endsWith(aPath) || aPath.contains(trimmedPath)) {
110101
knownPath = file.getPath();
111102
break;
112103
}
113-
for (String aPath : knownPaths) {
114-
if (path.endsWith(aPath) || aPath.contains(path) || trimmedPath.endsWith(aPath) || aPath.contains(trimmedPath)) {
115-
knownPath = file.getPath();
116-
break;
117-
}
118-
}
119104
}
120105
}
121106
}
@@ -126,24 +111,18 @@ public LineMarkerInfo<?> getLineMarkerInfo(@NotNull PsiElement element) {
126111
final DartArguments arguments = DartPsiImplUtil.getArguments((DartCallExpression)parent);
127112
if (arguments == null) return null;
128113
final String family = getValueOfNamedArgument(arguments, "fontFamily");
129-
//if (family != null) {
130-
// // TODO https://github.com/flutter/flutter-intellij/issues/2334
131-
// if (!"MaterialIcons".equals(family)) return null;
132-
//}
133114
final PsiElement fontPackage = getNamedArgumentExpression(arguments, "fontPackage");
134-
//if (fontPackage != null) return null; // See previous TODO
135115
final String argument = getValueOfPositionalArgument(arguments, 0);
136116
if (argument == null) return null;
117+
final Icon icon;
137118
if (family == null || "MaterialIcons".equals(family)) {
138-
final Icon icon = getIconFromCode(argument);
139-
if (icon != null) {
140-
return createLineMarker(element, icon);
141-
}
142-
} else {
143-
final Icon icon = getIconFromPackage(fontPackage, family, argument);
144-
if (icon != null) {
145-
return createLineMarker(element, icon);
146-
}
119+
icon = getIconFromCode(argument);
120+
}
121+
else {
122+
icon = getIconFromPackage(fontPackage, family, argument);
123+
}
124+
if (icon != null) {
125+
return createLineMarker(element, icon);
147126
}
148127
}
149128
else if (parent.getNode().getElementType() == DartTokenTypes.SIMPLE_TYPE) {
@@ -188,9 +167,9 @@ else if (name.equals("CupertinoIcons")) {
188167
// final HashMap<String, String> assetMap = visitor.assetMap;
189168
// }
190169
//}
191-
final PsiElement symbol = refExpr.getLastChild();
192-
if (symbol == null) return null; // TODO check for instance creation with codepoint
193-
final String iconName = symbol.getText();
170+
final PsiElement iconElement = refExpr.getLastChild();
171+
if (iconElement == null) return null; // TODO check for instance creation with codepoint
172+
final String iconName = iconElement.getText();
194173
final IconInfo iconDef = findDefinition(name, iconName, element.getProject(), knownPath);
195174
if (iconDef == null) return null;
196175
icon = findIconFromDef(name, iconDef, knownPath);
@@ -203,6 +182,8 @@ else if (name.equals("CupertinoIcons")) {
203182
return null;
204183
}
205184

185+
// TODO Implement this if we ever support the package flutter_icons.
186+
// That package is not currently supported because it takes forever to analyze it.
206187
private Icon getIconFromPackage(PsiElement aPackage, String family, String argument) {
207188
if (aPackage == null || family == null || argument == null) {
208189
return null;
@@ -265,7 +246,7 @@ private Icon findIconFromDef(@NotNull String iconClassName, @NotNull IconInfo ic
265246
return null;
266247
}
267248
final List<VirtualFile> ttfFiles = new ArrayList<>();
268-
VfsUtilCore.visitChildrenRecursively(parent, new VirtualFileVisitor<Object>() {
249+
VfsUtilCore.visitChildrenRecursively(parent, new VirtualFileVisitor<>() {
269250
@Override
270251
public boolean visitFile(@NotNull VirtualFile file) {
271252
if ("ttf".equals(file.getExtension())) {
@@ -288,7 +269,7 @@ public boolean visitFile(@NotNull VirtualFile file) {
288269
bestFileMatch = file;
289270
}
290271
}
291-
}
272+
} // If the family is null we could do a search for font files named similar to the package.
292273
if (bestFileMatch != null) {
293274
final IconPreviewGenerator generator = new IconPreviewGenerator(bestFileMatch.getPath());
294275
final Icon icon = generator.convert(iconDef.codepoint);
@@ -303,7 +284,8 @@ public boolean visitFile(@NotNull VirtualFile file) {
303284
}
304285

305286
public double findPattern(@NotNull String t, @NotNull String p) {
306-
// TODO Experiment with https://github.com/tdebatty/java-string-similarity
287+
// This is from https://github.com/tdebatty/java-string-similarity
288+
// It's MIT license file is: https://github.com/tdebatty/java-string-similarity/blob/master/LICENSE.md
307289
final JaroWinkler jw = new JaroWinkler();
308290
return jw.similarity(t, p);
309291
}
@@ -363,7 +345,9 @@ public void visitVarAccessDeclaration(@NotNull DartVarAccessDeclaration o) {
363345
className = type.getText();
364346
arguments = newExpr.getArguments();
365347
}
366-
} else if (expression instanceof DartCallExpression) {
348+
}
349+
else if (expression instanceof DartCallExpression) {
350+
// The Dart parser sometimes generates a call expression where we expect a new expression.
367351
final DartCallExpressionImpl callExpr = (DartCallExpressionImpl)expression;
368352
arguments = callExpr.getArguments();
369353
className = callExpr.getExpression().getText();
@@ -385,6 +369,9 @@ public void visitVarAccessDeclaration(@NotNull DartVarAccessDeclaration o) {
385369
}
386370
else {
387371
if (o.getFirstChild().getText().trim().equals("static")) {
372+
// Fortunately, in all packages checked so far, static variables defining font family and
373+
// package names appear at the beginning of the file. So this simple visitor works, but it
374+
// will fail if the static variables are defined at the end of the file.
388375
final String varName = o.getComponentName().getText().trim();
389376
final DartVarInit init = (DartVarInit)o.getParent().getLastChild();
390377
final DartExpression expression = init.getExpression();
@@ -397,7 +384,7 @@ public void visitVarAccessDeclaration(@NotNull DartVarAccessDeclaration o) {
397384
}
398385
}
399386

400-
@Deprecated
387+
@Deprecated // This might be useful if we eliminate the preference pane that defines packages to analyze.
401388
static class YamlAssetMapVisitor extends YamlRecursivePsiElementVisitor {
402389
HashMap<String, String> assetMap = new HashMap<>();
403390
List<String> iconClassNames = new ArrayList<>();

0 commit comments

Comments
 (0)