Uast 1.0.9

This commit is contained in:
Vyacheslav Gerasimov
2017-02-02 19:31:43 +03:00
parent 5888c75d41
commit 10517c16ee
43 changed files with 479 additions and 368 deletions
@@ -16,13 +16,9 @@
package com.android.tools.klint.client.api;
import static com.android.SdkConstants.ANDROID_PKG;
import static com.android.SdkConstants.R_CLASS;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.annotations.VisibleForTesting;
import com.android.resources.ResourceType;
import com.android.tools.klint.detector.api.Detector;
import com.android.tools.klint.detector.api.Detector.JavaPsiScanner;
import com.android.tools.klint.detector.api.Detector.UastScanner;
@@ -35,30 +31,15 @@ import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.StandardFileSystems;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.JavaElementVisitor;
import com.intellij.psi.JavaRecursiveElementVisitor;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiJavaCodeReferenceElement;
import com.intellij.psi.PsiManager;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiMethodCallExpression;
import com.intellij.psi.PsiNewExpression;
import com.intellij.psi.PsiReferenceExpression;
import com.intellij.psi.PsiTypeParameter;
import com.intellij.psi.*;
import org.jetbrains.uast.*;
import org.jetbrains.uast.expressions.UTypeReferenceExpression;
import org.jetbrains.uast.util.UastExpressionUtils;
import org.jetbrains.uast.visitor.AbstractUastVisitor;
import org.jetbrains.uast.visitor.UastVisitor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import static com.android.SdkConstants.ANDROID_PKG;
/**
* Specialized visitor for running detectors on a Java AST.
@@ -26,7 +26,7 @@ import com.google.common.base.Joiner;
import com.intellij.psi.*;
import org.jetbrains.uast.*;
import org.jetbrains.uast.expressions.UReferenceExpression;
import org.jetbrains.uast.UReferenceExpression;
import org.jetbrains.uast.java.JavaAbstractUExpression;
import org.jetbrains.uast.java.JavaUDeclarationsExpression;
@@ -64,7 +64,7 @@ import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.uast.*;
import org.jetbrains.uast.expressions.UReferenceExpression;
import org.jetbrains.uast.UReferenceExpression;
import org.jetbrains.uast.util.UastExpressionUtils;
import org.jetbrains.uast.visitor.AbstractUastVisitor;
@@ -39,7 +39,7 @@ import org.jetbrains.uast.UCallExpression;
import org.jetbrains.uast.UClass;
import org.jetbrains.uast.UElement;
import org.jetbrains.uast.UMethod;
import org.jetbrains.uast.expressions.UReferenceExpression;
import org.jetbrains.uast.UReferenceExpression;
import org.jetbrains.uast.visitor.UastVisitor;
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode;
import org.jetbrains.org.objectweb.asm.tree.ClassNode;
@@ -60,7 +60,7 @@ import org.jetbrains.uast.UIfExpression;
import org.jetbrains.uast.UParenthesizedExpression;
import org.jetbrains.uast.UQualifiedReferenceExpression;
import org.jetbrains.uast.UastUtils;
import org.jetbrains.uast.expressions.UReferenceExpression;
import org.jetbrains.uast.UReferenceExpression;
import java.util.EnumSet;
import java.util.List;
@@ -56,7 +56,7 @@ import org.jetbrains.uast.UExpression;
import org.jetbrains.uast.UMethod;
import org.jetbrains.uast.UVariable;
import org.jetbrains.uast.UastUtils;
import org.jetbrains.uast.expressions.UReferenceExpression;
import org.jetbrains.uast.UReferenceExpression;
import org.jetbrains.uast.util.UastExpressionUtils;
import java.util.ListIterator;
@@ -38,7 +38,7 @@ import com.android.tools.klint.detector.api.XmlContext;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiField;
import org.jetbrains.uast.expressions.UReferenceExpression;
import org.jetbrains.uast.UReferenceExpression;
import org.jetbrains.uast.visitor.UastVisitor;
import org.w3c.dom.Attr;
@@ -16,102 +16,33 @@
package com.android.tools.klint.checks;
import static com.android.SdkConstants.ATTR_VALUE;
import static com.android.SdkConstants.FQCN_SUPPRESS_LINT;
import static com.android.SdkConstants.INT_DEF_ANNOTATION;
import static com.android.SdkConstants.STRING_DEF_ANNOTATION;
import static com.android.SdkConstants.SUPPORT_ANNOTATIONS_PREFIX;
import static com.android.SdkConstants.TYPE_DEF_FLAG_ATTRIBUTE;
import static com.android.tools.klint.checks.PermissionRequirement.getAnnotationBooleanValue;
import static com.android.tools.klint.checks.SupportAnnotationDetector.ATTR_ALL_OF;
import static com.android.tools.klint.checks.SupportAnnotationDetector.ATTR_ANY_OF;
import static com.android.tools.klint.checks.SupportAnnotationDetector.ATTR_FROM;
import static com.android.tools.klint.checks.SupportAnnotationDetector.ATTR_MAX;
import static com.android.tools.klint.checks.SupportAnnotationDetector.ATTR_MIN;
import static com.android.tools.klint.checks.SupportAnnotationDetector.ATTR_MULTIPLE;
import static com.android.tools.klint.checks.SupportAnnotationDetector.ATTR_TO;
import static com.android.tools.klint.checks.SupportAnnotationDetector.CHECK_RESULT_ANNOTATION;
import static com.android.tools.klint.checks.SupportAnnotationDetector.FLOAT_RANGE_ANNOTATION;
import static com.android.tools.klint.checks.SupportAnnotationDetector.INT_RANGE_ANNOTATION;
import static com.android.tools.klint.checks.SupportAnnotationDetector.PERMISSION_ANNOTATION;
import static com.android.tools.klint.checks.SupportAnnotationDetector.PERMISSION_ANNOTATION_READ;
import static com.android.tools.klint.checks.SupportAnnotationDetector.PERMISSION_ANNOTATION_WRITE;
import static com.android.tools.klint.checks.SupportAnnotationDetector.SIZE_ANNOTATION;
import static com.android.tools.klint.checks.SupportAnnotationDetector.filterRelevantAnnotations;
import static com.android.tools.klint.checks.SupportAnnotationDetector.getDoubleAttribute;
import static com.android.tools.klint.checks.SupportAnnotationDetector.getLongAttribute;
import static com.android.tools.klint.client.api.JavaParser.TYPE_DOUBLE;
import static com.android.tools.klint.client.api.JavaParser.TYPE_FLOAT;
import static com.android.tools.klint.client.api.JavaParser.TYPE_INT;
import static com.android.tools.klint.client.api.JavaParser.TYPE_LONG;
import static com.android.tools.klint.client.api.JavaParser.TYPE_STRING;
import static com.android.tools.klint.detector.api.LintUtils.findSubstring;
import static com.android.tools.klint.detector.api.LintUtils.getAutoBoxedType;
import static com.android.tools.klint.detector.api.ResourceEvaluator.COLOR_INT_ANNOTATION;
import static com.android.tools.klint.detector.api.ResourceEvaluator.PX_ANNOTATION;
import static com.android.tools.klint.detector.api.ResourceEvaluator.RES_SUFFIX;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.tools.klint.client.api.ExternalReferenceExpression;
import com.android.tools.klint.client.api.IssueRegistry;
import com.android.tools.klint.client.api.JavaEvaluator;
import com.android.tools.klint.client.api.UastLintUtils;
import com.android.tools.klint.detector.api.Category;
import com.android.tools.klint.detector.api.ConstantEvaluator;
import com.android.tools.klint.detector.api.Detector;
import com.android.tools.klint.detector.api.Implementation;
import com.android.tools.klint.detector.api.Issue;
import com.android.tools.klint.detector.api.JavaContext;
import com.android.tools.klint.detector.api.Location;
import com.android.tools.klint.detector.api.Scope;
import com.android.tools.klint.detector.api.Severity;
import com.android.tools.klint.detector.api.TextFormat;
import com.android.tools.klint.detector.api.*;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.intellij.psi.PsiAnnotation;
import com.intellij.psi.PsiAnnotationMemberValue;
import com.intellij.psi.PsiAnnotationOwner;
import com.intellij.psi.PsiArrayInitializerMemberValue;
import com.intellij.psi.PsiArrayType;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiClassType;
import com.intellij.psi.PsiDeclarationStatement;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiField;
import com.intellij.psi.PsiJavaCodeReferenceElement;
import com.intellij.psi.PsiLiteral;
import com.intellij.psi.PsiLocalVariable;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifierList;
import com.intellij.psi.PsiModifierListOwner;
import com.intellij.psi.PsiNameValuePair;
import com.intellij.psi.PsiParameter;
import com.intellij.psi.PsiReferenceExpression;
import com.intellij.psi.PsiType;
import com.intellij.psi.PsiVariable;
import com.intellij.psi.*;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.uast.*;
import org.jetbrains.uast.expressions.UReferenceExpression;
import org.jetbrains.uast.java.JavaUAnnotation;
import org.jetbrains.uast.java.JavaUTypeCastExpression;
import org.jetbrains.uast.util.UastExpressionUtils;
import org.jetbrains.uast.visitor.AbstractUastVisitor;
import org.jetbrains.uast.visitor.UastVisitor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import java.util.*;
import static com.android.SdkConstants.*;
import static com.android.tools.klint.checks.PermissionRequirement.getAnnotationBooleanValue;
import static com.android.tools.klint.checks.SupportAnnotationDetector.*;
import static com.android.tools.klint.client.api.JavaParser.*;
import static com.android.tools.klint.detector.api.LintUtils.getAutoBoxedType;
import static com.android.tools.klint.detector.api.ResourceEvaluator.*;
/**
* Checks annotations to make sure they are valid
@@ -40,8 +40,6 @@ import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.android.inspections.klint.IntellijLintUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.uast.*;
import org.jetbrains.uast.expressions.UReferenceExpression;
import org.jetbrains.uast.expressions.UTypeReferenceExpression;
import org.jetbrains.uast.util.UastExpressionUtils;
import org.jetbrains.uast.visitor.AbstractUastVisitor;
import org.jetbrains.uast.visitor.UastVisitor;
@@ -1028,6 +1026,10 @@ public class ApiDetector extends ResourceXmlDetector
}
}
}
} else {
for (UTypeReferenceExpression t : aClass.getUastSuperTypes()) {
checkType(t.getType(), t);
}
}
return super.visitClass(aClass);
@@ -1320,8 +1322,8 @@ public class ApiDetector extends ResourceXmlDetector
}
@Override
public boolean visitTryExpression(UTryExpression statement) {
if (statement.isResources()) {
public boolean visitTryExpression(@NotNull UTryExpression statement) {
if (statement.getHasResources()) {
int api = 19; // minSdk for try with resources
int minSdk = getMinSdk(mContext);
@@ -16,26 +16,12 @@
package com.android.tools.klint.checks;
import static com.android.SdkConstants.ANDROID_URI;
import static com.android.SdkConstants.ATTR_NAME;
import static com.android.SdkConstants.TAG_RECEIVER;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.tools.klint.detector.api.Category;
import com.android.tools.klint.detector.api.Detector;
import com.android.tools.klint.detector.api.Implementation;
import com.android.tools.klint.detector.api.Issue;
import com.android.tools.klint.detector.api.JavaContext;
import com.android.tools.klint.detector.api.ResourceXmlDetector;
import com.android.tools.klint.detector.api.Scope;
import com.android.tools.klint.detector.api.Severity;
import com.android.tools.klint.detector.api.XmlContext;
import com.intellij.psi.JavaElementVisitor;
import com.android.tools.klint.detector.api.*;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiField;
import org.jetbrains.uast.expressions.UReferenceExpression;
import org.jetbrains.uast.UReferenceExpression;
import org.jetbrains.uast.visitor.UastVisitor;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
@@ -45,6 +31,8 @@ import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import static com.android.SdkConstants.*;
/**
* Checks looking for issues that negatively affect battery life
*/
@@ -39,7 +39,7 @@ import com.intellij.psi.PsiMethod;
import org.jetbrains.uast.UElement;
import org.jetbrains.uast.UMethod;
import org.jetbrains.uast.USuperExpression;
import org.jetbrains.uast.expressions.UReferenceExpression;
import org.jetbrains.uast.UReferenceExpression;
import org.jetbrains.uast.visitor.AbstractUastVisitor;
import org.jetbrains.uast.visitor.UastVisitor;
@@ -63,7 +63,7 @@ import org.jetbrains.uast.UVariable;
import org.jetbrains.uast.UWhileExpression;
import org.jetbrains.uast.UastCallKind;
import org.jetbrains.uast.UastUtils;
import org.jetbrains.uast.expressions.UReferenceExpression;
import org.jetbrains.uast.UReferenceExpression;
import org.jetbrains.uast.util.UastExpressionUtils;
import org.jetbrains.uast.visitor.AbstractUastVisitor;
import org.jetbrains.uast.visitor.UastVisitor;
@@ -16,41 +16,12 @@
package com.android.tools.klint.checks;
import static com.android.SdkConstants.RESOURCE_CLZ_ID;
import static com.android.tools.klint.detector.api.LintUtils.skipParentheses;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.tools.klint.detector.api.Category;
import com.android.tools.klint.detector.api.Detector;
import com.android.tools.klint.detector.api.Implementation;
import com.android.tools.klint.detector.api.Issue;
import com.android.tools.klint.detector.api.JavaContext;
import com.android.tools.klint.detector.api.Location;
import com.android.tools.klint.detector.api.Scope;
import com.android.tools.klint.detector.api.Severity;
import com.android.tools.klint.detector.api.*;
import com.google.common.collect.Maps;
import com.intellij.psi.PsiBreakStatement;
import com.intellij.psi.PsiContinueStatement;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiIfStatement;
import com.intellij.psi.PsiJavaToken;
import com.intellij.psi.PsiLoopStatement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiReturnStatement;
import com.intellij.psi.PsiStatement;
import com.intellij.psi.PsiWhiteSpace;
import org.jetbrains.uast.UArrayAccessExpression;
import org.jetbrains.uast.*;
import org.jetbrains.uast.UCallExpression;
import org.jetbrains.uast.UElement;
import org.jetbrains.uast.UExpression;
import org.jetbrains.uast.ULocalVariable;
import org.jetbrains.uast.UMethod;
import org.jetbrains.uast.UQualifiedReferenceExpression;
import org.jetbrains.uast.UastUtils;
import org.jetbrains.uast.expressions.UReferenceExpression;
import org.jetbrains.uast.util.UastExpressionUtils;
import org.jetbrains.uast.visitor.AbstractUastVisitor;
import org.jetbrains.uast.visitor.UastVisitor;
@@ -59,6 +30,8 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import static com.android.SdkConstants.RESOURCE_CLZ_ID;
/**
* Detector looking for cut & paste issues
*/
@@ -16,32 +16,6 @@
package com.android.tools.klint.checks;
import static com.android.SdkConstants.ANDROID_MANIFEST_XML;
import static com.android.SdkConstants.ANDROID_URI;
import static com.android.SdkConstants.ATTR_ICON;
import static com.android.SdkConstants.DOT_9PNG;
import static com.android.SdkConstants.DOT_GIF;
import static com.android.SdkConstants.DOT_JPEG;
import static com.android.SdkConstants.DOT_JPG;
import static com.android.SdkConstants.DOT_PNG;
import static com.android.SdkConstants.DOT_WEBP;
import static com.android.SdkConstants.DOT_XML;
import static com.android.SdkConstants.DRAWABLE_FOLDER;
import static com.android.SdkConstants.DRAWABLE_HDPI;
import static com.android.SdkConstants.DRAWABLE_LDPI;
import static com.android.SdkConstants.DRAWABLE_MDPI;
import static com.android.SdkConstants.DRAWABLE_PREFIX;
import static com.android.SdkConstants.DRAWABLE_XHDPI;
import static com.android.SdkConstants.DRAWABLE_XXHDPI;
import static com.android.SdkConstants.DRAWABLE_XXXHDPI;
import static com.android.SdkConstants.TAG_ACTIVITY;
import static com.android.SdkConstants.TAG_APPLICATION;
import static com.android.SdkConstants.TAG_ITEM;
import static com.android.SdkConstants.TAG_PROVIDER;
import static com.android.SdkConstants.TAG_RECEIVER;
import static com.android.SdkConstants.TAG_SERVICE;
import static com.android.tools.klint.detector.api.LintUtils.endsWith;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.builder.model.ProductFlavor;
@@ -50,74 +24,31 @@ import com.android.ide.common.resources.ResourceUrl;
import com.android.resources.Density;
import com.android.resources.ResourceFolderType;
import com.android.resources.ResourceType;
import com.android.tools.klint.detector.api.Category;
import com.android.tools.klint.detector.api.Context;
import com.android.tools.klint.detector.api.Detector;
import com.android.tools.klint.detector.api.Implementation;
import com.android.tools.klint.detector.api.Issue;
import com.android.tools.klint.detector.api.JavaContext;
import com.android.tools.klint.detector.api.LintUtils;
import com.android.tools.klint.detector.api.Location;
import com.android.tools.klint.detector.api.Project;
import com.android.tools.klint.detector.api.ResourceEvaluator;
import com.android.tools.klint.detector.api.ResourceXmlDetector;
import com.android.tools.klint.detector.api.Scope;
import com.android.tools.klint.detector.api.Severity;
import com.android.tools.klint.detector.api.XmlContext;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import com.intellij.psi.JavaRecursiveElementVisitor;
import com.intellij.psi.PsiAnonymousClass;
import com.android.tools.klint.detector.api.*;
import com.google.common.collect.*;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiMethodCallExpression;
import com.intellij.psi.PsiReferenceExpression;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.uast.UAnonymousClass;
import org.jetbrains.uast.UCallExpression;
import org.jetbrains.uast.UClass;
import org.jetbrains.uast.UElement;
import org.jetbrains.uast.UExpression;
import org.jetbrains.uast.UMethod;
import org.jetbrains.uast.USimpleNameReferenceExpression;
import org.jetbrains.uast.UastUtils;
import org.jetbrains.uast.expressions.UReferenceExpression;
import org.jetbrains.uast.*;
import org.jetbrains.uast.util.UastExpressionUtils;
import org.jetbrains.uast.visitor.AbstractUastVisitor;
import org.jetbrains.uast.visitor.UastVisitor;
import org.w3c.dom.Element;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.List;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static com.android.SdkConstants.*;
import static com.android.tools.klint.detector.api.LintUtils.endsWith;
/**
* Checks for common icon problems, such as wrong icon sizes, placing icons in the
@@ -60,7 +60,7 @@ import org.jetbrains.uast.USuperExpression;
import org.jetbrains.uast.UThisExpression;
import org.jetbrains.uast.UThrowExpression;
import org.jetbrains.uast.UastUtils;
import org.jetbrains.uast.expressions.UReferenceExpression;
import org.jetbrains.uast.UReferenceExpression;
import org.jetbrains.uast.util.UastExpressionUtils;
import org.jetbrains.uast.visitor.AbstractUastVisitor;
import org.jetbrains.uast.visitor.UastVisitor;
@@ -16,58 +16,24 @@
package com.android.tools.klint.checks;
import static com.android.SdkConstants.ANDROID_URI;
import static com.android.SdkConstants.ATTR_BACKGROUND;
import static com.android.SdkConstants.ATTR_FOREGROUND;
import static com.android.SdkConstants.ATTR_LAYOUT;
import static com.android.SdkConstants.ATTR_LAYOUT_GRAVITY;
import static com.android.SdkConstants.FRAME_LAYOUT;
import static com.android.SdkConstants.LAYOUT_RESOURCE_PREFIX;
import static com.android.SdkConstants.VIEW_INCLUDE;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.resources.ResourceType;
import com.android.tools.klint.client.api.AndroidReference;
import com.android.tools.klint.client.api.UastLintUtils;
import com.android.tools.klint.detector.api.Category;
import com.android.tools.klint.detector.api.Context;
import com.android.tools.klint.detector.api.Detector;
import com.android.tools.klint.detector.api.Detector.JavaPsiScanner;
import com.android.tools.klint.detector.api.Implementation;
import com.android.tools.klint.detector.api.Issue;
import com.android.tools.klint.detector.api.JavaContext;
import com.android.tools.klint.detector.api.LayoutDetector;
import com.android.tools.klint.detector.api.LintUtils;
import com.android.tools.klint.detector.api.Location;
import com.android.tools.klint.detector.api.*;
import com.android.tools.klint.detector.api.Location.Handle;
import com.android.tools.klint.detector.api.Scope;
import com.android.tools.klint.detector.api.Severity;
import com.android.tools.klint.detector.api.XmlContext;
import com.android.utils.Pair;
import com.intellij.psi.JavaElementVisitor;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiMethodCallExpression;
import com.intellij.psi.PsiReferenceExpression;
import org.jetbrains.uast.UCallExpression;
import org.jetbrains.uast.UExpression;
import org.jetbrains.uast.UMethod;
import org.jetbrains.uast.UQualifiedReferenceExpression;
import org.jetbrains.uast.expressions.UReferenceExpression;
import org.jetbrains.uast.visitor.UastVisitor;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
import static com.android.SdkConstants.*;
/**
* Checks whether a root FrameLayout can be replaced with a {@code <merge>} tag.
@@ -30,7 +30,6 @@ import com.intellij.psi.PsiField;
import com.intellij.psi.PsiVariable;
import org.jetbrains.uast.*;
import org.jetbrains.uast.expressions.UReferenceExpression;
import org.jetbrains.uast.util.UastExpressionUtils;
import java.util.List;
@@ -40,7 +40,6 @@ import com.intellij.psi.PsiParameter;
import com.intellij.psi.PsiVariable;
import org.jetbrains.uast.*;
import org.jetbrains.uast.expressions.UReferenceExpression;
import org.jetbrains.uast.util.UastExpressionUtils;
import org.jetbrains.uast.visitor.AbstractUastVisitor;
@@ -36,7 +36,7 @@ import org.jetbrains.uast.UElement;
import org.jetbrains.uast.UExpression;
import org.jetbrains.uast.UMethod;
import org.jetbrains.uast.UastUtils;
import org.jetbrains.uast.expressions.UReferenceExpression;
import org.jetbrains.uast.UReferenceExpression;
import org.jetbrains.uast.util.UastExpressionUtils;
import org.jetbrains.uast.visitor.UastVisitor;
@@ -78,7 +78,7 @@ import org.jetbrains.uast.UCallExpression;
import org.jetbrains.uast.UExpression;
import org.jetbrains.uast.ULiteralExpression;
import org.jetbrains.uast.UMethod;
import org.jetbrains.uast.expressions.UReferenceExpression;
import org.jetbrains.uast.UReferenceExpression;
import org.jetbrains.uast.util.UastExpressionUtils;
import org.jetbrains.uast.visitor.UastVisitor;
import org.w3c.dom.Element;
@@ -88,7 +88,6 @@ import com.intellij.psi.PsiType;
import com.intellij.psi.PsiVariable;
import org.jetbrains.uast.*;
import org.jetbrains.uast.expressions.UReferenceExpression;
import org.jetbrains.uast.java.JavaUAnnotation;
import org.jetbrains.uast.util.UastExpressionUtils;
import org.jetbrains.uast.visitor.AbstractUastVisitor;
@@ -18,17 +18,13 @@ package org.jetbrains.uast.kotlin
import com.intellij.lang.Language
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiVariable
import com.intellij.psi.*
import com.intellij.psi.impl.source.tree.LeafPsiElement
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.asJava.LightClassUtil
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass
import org.jetbrains.kotlin.asJava.elements.KtLightField
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.asJava.elements.KtLightParameter
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
import org.jetbrains.kotlin.asJava.elements.*
import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
@@ -41,8 +37,7 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.uast.*
import org.jetbrains.uast.java.JavaUastLanguagePlugin
import org.jetbrains.uast.kotlin.declarations.KotlinUMethod
import org.jetbrains.uast.kotlin.expressions.KotlinUBreakExpression
import org.jetbrains.uast.kotlin.expressions.KotlinUContinueExpression
import org.jetbrains.uast.kotlin.expressions.*
import org.jetbrains.uast.kotlin.kinds.KotlinSpecialExpressionKinds
import org.jetbrains.uast.kotlin.psi.UastKotlinPsiParameter
import org.jetbrains.uast.kotlin.psi.UastKotlinPsiVariable
@@ -73,6 +68,7 @@ class KotlinUastLanguagePlugin(override val project: Project) : UastLanguagePlug
override fun convertElementWithParent(element: PsiElement, requiredType: Class<out UElement>?): UElement? {
if (element !is PsiElement) return null
if (element is PsiFile) return convertDeclaration(element, null, requiredType)
if (element is KtLightClassForFacade) return convertDeclaration(element, null, requiredType)
val parent = element.parent ?: return null
val parentUElement = convertElementWithParent(parent, null) ?: return null
@@ -191,6 +187,13 @@ internal object KotlinConverter {
is KtContainerNode -> element.getExpression()?.let {
KotlinConverter.convertExpression(it, parent, requiredType)
} ?: UastEmptyExpression
is KtLightAnnotation.LightExpressionValue<*> -> {
val expression = element.originalExpression
when (expression) {
is KtExpression -> KotlinConverter.convertExpression(expression, parent, requiredType)
else -> UastEmptyExpression
}
}
else -> {
if (element is LeafPsiElement && element.elementType == KtTokens.IDENTIFIER) {
el<UIdentifier> { UIdentifier(element, parent) }
@@ -209,20 +212,6 @@ internal object KotlinConverter {
val variable = KotlinUVariable.create(UastKotlinPsiVariable.create(psi, parentPsiElement, parent!!), parent)
return KotlinUDeclarationsExpression(parent).apply { declarations = listOf(variable) }
}
private fun convertStringTemplateExpression(
expression: KtStringTemplateExpression,
parent: UElement?,
i: Int
): UExpression {
return if (i == 1) KotlinStringTemplateUBinaryExpression(expression, parent).apply {
leftOperand = convert(expression.entries[0], this)
rightOperand = convert(expression.entries[1], this)
} else KotlinStringTemplateUBinaryExpression(expression, parent).apply {
leftOperand = convertStringTemplateExpression(expression, parent, i - 1)
rightOperand = convert(expression.entries[i], this)
}
}
internal fun convert(entry: KtStringTemplateEntry, parent: UElement?): UExpression = when (entry) {
is KtStringTemplateEntryWithExpression -> convertOrEmpty(entry.expression, parent)
@@ -242,7 +231,7 @@ internal object KotlinConverter {
else if (expression.entries.size == 1)
convert(expression.entries[0], parent)
else
convertStringTemplateExpression(expression, parent, expression.entries.size - 1)
KotlinStringTemplateUPolyadicExpression(expression, parent)
}
is KtDestructuringDeclaration -> expr<UDeclarationsExpression> {
KotlinUDeclarationsExpression(parent).apply {
@@ -267,7 +256,12 @@ internal object KotlinConverter {
KotlinUSimpleReferenceExpression(expression, expression.getReferencedName(), parent)
}
is KtCallExpression -> expr<UCallExpression> { KotlinUFunctionCallExpression(expression, parent) }
is KtBinaryExpression -> expr<UBinaryExpression> { KotlinUBinaryExpression(expression, parent) }
is KtBinaryExpression -> {
if (expression.operationToken == KtTokens.ELVIS) {
expr<UExpressionList> { createElvisExpression(expression, parent) ?: UastEmptyExpression }
}
else expr<UBinaryExpression> { KotlinUBinaryExpression(expression, parent) }
}
is KtParenthesizedExpression -> expr<UParenthesizedExpression> { KotlinUParenthesizedExpression(expression, parent) }
is KtPrefixExpression -> expr<UPrefixExpression> { KotlinUPrefixExpression(expression, parent) }
is KtPostfixExpression -> expr<UPostfixExpression> { KotlinUPostfixExpression(expression, parent) }
@@ -290,6 +284,20 @@ internal object KotlinConverter {
is KtArrayAccessExpression -> expr<UArrayAccessExpression> { KotlinUArrayAccessExpression(expression, parent) }
is KtLambdaExpression -> expr<ULambdaExpression> { KotlinULambdaExpression(expression, parent) }
is KtBinaryExpressionWithTypeRHS -> expr<UBinaryExpressionWithType> { KotlinUBinaryExpressionWithType(expression, parent) }
is KtClassOrObject -> expr<UDeclarationsExpression> {
expression.toLightClass()?.let { lightClass ->
KotlinUDeclarationsExpression(parent).apply {
declarations = listOf(KotlinUClass.create(lightClass, this))
}
} ?: UastEmptyExpression
}
is KtFunction -> if (expression.name.isNullOrEmpty()) {
expr<ULambdaExpression> { createLocalFunctionLambdaExpression(expression, parent) }
}
else {
expr<UDeclarationsExpression> { createLocalFunctionDeclaration(expression, parent) }
}
else -> UnknownKotlinExpression(expression, parent)
}}
@@ -19,9 +19,12 @@ package org.jetbrains.uast.kotlin
import com.intellij.psi.PsiAnonymousClass
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.asJava.toLightMethods
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.psi.KtEnumEntry
import org.jetbrains.kotlin.psi.KtObjectDeclaration
import org.jetbrains.uast.*
import org.jetbrains.uast.java.AbstractJavaUClass
@@ -31,7 +34,9 @@ class KotlinUClass private constructor(
psi: KtLightClass,
override val containingElement: UElement?
) : AbstractJavaUClass(), PsiClass by psi {
val ktClass = psi.kotlinOrigin
override val psi = unwrap<UClass, PsiClass>(psi)
override fun getOriginalElement(): PsiElement? {
@@ -40,15 +45,25 @@ class KotlinUClass private constructor(
override val uastAnchor: UElement
get() = UIdentifier(psi.nameIdentifier, this)
override val uastNestedClasses: List<UClass> by lz {
// filter DefaultImpls to avoid processing same methods from original interface multiple times
// filter Enum entry classes to avoid duplication with PsiEnumConstant initializer class
psi.innerClasses.filter {
it.name != JvmAbi.DEFAULT_IMPLS_CLASS_NAME && !it.isEnumEntryLightClass()
}.map {
getLanguagePlugin().convert<UClass>(it, this)
}
}
override val uastMethods: List<UMethod> by lz {
val primaryConstructor = ktClass?.getPrimaryConstructor()?.toLightMethods()?.firstOrNull()
val initBlocks = ktClass?.getAnonymousInitializers() ?: emptyList()
psi.methods.map {
if (it is KtLightMethod && it.isConstructor && initBlocks.isNotEmpty()
&& (primaryConstructor == null || it == primaryConstructor)) {
object : KotlinUMethod(it, this@KotlinUClass) {
fun createUMethod(psiMethod: PsiMethod): UMethod {
return if (psiMethod is KtLightMethod && psiMethod.isConstructor && initBlocks.isNotEmpty()
&& (primaryConstructor == null || psiMethod == primaryConstructor)) {
object : KotlinUMethod(psiMethod, this@KotlinUClass) {
override val uastBody by lz {
val initializers = ktClass?.getAnonymousInitializers() ?: return@lz UastEmptyExpression
val containingMethod = this
@@ -68,13 +83,21 @@ class KotlinUClass private constructor(
}
}
}
} else {
getLanguagePlugin().convert<UMethod>(psiMethod, this)
}
else {
getLanguagePlugin().convert<UMethod>(it, this)
}
}
}
fun isDelegatedMethod(psiMethod: PsiMethod) = psiMethod is KtLightMethod && psiMethod.isDelegated
psi.methods.asSequence()
.filterNot(::isDelegatedMethod)
.map(::createUMethod)
.toList()
}
private fun PsiClass.isEnumEntryLightClass() = (this as? KtLightClass)?.kotlinOrigin is KtEnumEntry
companion object {
fun create(psi: KtLightClass, containingElement: UElement?): UClass {
return if (psi is PsiAnonymousClass)
@@ -89,6 +112,7 @@ class KotlinUAnonymousClass(
psi: PsiAnonymousClass,
override val containingElement: UElement?
) : AbstractJavaUClass(), UAnonymousClass, PsiAnonymousClass by psi {
override val psi: PsiAnonymousClass = unwrap<UAnonymousClass, PsiAnonymousClass>(psi)
override fun getOriginalElement(): PsiElement? {
@@ -16,8 +16,12 @@
package org.jetbrains.uast.kotlin
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiComment
import com.intellij.psi.PsiRecursiveElementWalkingVisitor
import org.jetbrains.kotlin.asJava.findFacadeClass
import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.uast.*
import java.util.*
@@ -40,5 +44,16 @@ class KotlinUFile(override val psi: KtFile, override val languagePlugin: UastLan
}
override val imports by lz { psi.importDirectives.map { KotlinUImportStatement(it, this) } }
override val classes by lz { psi.classes.map { languagePlugin.convert<UClass>(it, this) } }
override val classes by lz {
fun PsiClass.toUClass() = languagePlugin.convert<UClass>(this, this@KotlinUFile)
val classes = psi.findFacadeClass()?.let { mutableListOf(it.toUClass()) } ?: mutableListOf()
for (declaration in psi.declarations) {
(declaration as? KtClassOrObject)?.toLightClass()?.let { classes += it.toUClass() }
}
return@lz classes
}
}
@@ -20,13 +20,12 @@ import com.intellij.psi.PsiCodeBlock
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiNameIdentifierOwner
import org.jetbrains.kotlin.asJava.elements.KtLightElement
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.asJava.elements.KtLightMethodImpl
import org.jetbrains.kotlin.asJava.elements.*
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtCallableDeclaration
import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.uast.*
import org.jetbrains.uast.java.JavaUAnnotation
import org.jetbrains.uast.java.annotations
@@ -54,7 +53,16 @@ open class KotlinUMethod(
override val uastBody by lz {
val bodyExpression = (kotlinOrigin as? KtFunction)?.bodyExpression ?: return@lz null
val bodyExpression = when (kotlinOrigin) {
is KtFunction -> kotlinOrigin.bodyExpression
is KtProperty -> when {
psi.isGetter -> kotlinOrigin.getter?.bodyExpression
psi.isSetter -> kotlinOrigin.setter?.bodyExpression
else -> null
}
else -> null
} ?: return@lz null
getLanguagePlugin().convertElement(bodyExpression, this) as? UExpression
}
@@ -65,6 +73,10 @@ open class KotlinUMethod(
override fun getOriginalElement(): PsiElement? = super.getOriginalElement()
override fun equals(other: Any?) = other is KotlinUMethod && psi == other.psi
override fun hashCode() = psi.hashCode()
companion object {
fun create(psi: KtLightMethod, containingElement: UElement?) = when (psi) {
is KtLightMethodImpl.KtLightAnnotationMethod -> KotlinUAnnotationMethod(psi, containingElement)
@@ -21,8 +21,6 @@ import org.jetbrains.kotlin.asJava.elements.KtLightElement
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.psi.KtVariableDeclaration
import org.jetbrains.uast.*
import org.jetbrains.uast.expressions.UReferenceExpression
import org.jetbrains.uast.expressions.UTypeReferenceExpression
import org.jetbrains.uast.java.AbstractJavaUVariable
import org.jetbrains.uast.java.JavaAbstractUExpression
import org.jetbrains.uast.java.JavaUAnnotation
@@ -58,6 +56,9 @@ class KotlinUVariable(
) : AbstractKotlinUVariable(), UVariable, PsiVariable by psi {
override val psi = unwrap<UVariable, PsiVariable>(psi)
override val annotations by lz { psi.annotations.map { JavaUAnnotation(it, this) } }
override val typeReference by lz { getLanguagePlugin().convertOpt<UTypeReferenceExpression>(psi.typeElement, this) }
override fun getInitializer(): PsiExpression? {
return super<AbstractKotlinUVariable>.getInitializer()
}
@@ -66,9 +67,6 @@ class KotlinUVariable(
return super<AbstractKotlinUVariable>.getOriginalElement()
}
override val annotations by lz { psi.annotations.map { JavaUAnnotation(it, this) } }
override val typeReference by lz { getLanguagePlugin().convertOpt<UTypeReferenceExpression>(psi.typeElement, this) }
companion object {
fun create(psi: PsiVariable, containingElement: UElement?): UVariable {
return when (psi) {
@@ -86,6 +84,7 @@ open class KotlinUParameter(
psi: PsiParameter,
override val containingElement: UElement?
) : AbstractKotlinUVariable(), UParameter, PsiParameter by psi {
override val psi = unwrap<UParameter, PsiParameter>(psi)
override fun getInitializer(): PsiExpression? {
@@ -95,13 +94,13 @@ open class KotlinUParameter(
override fun getOriginalElement(): PsiElement? {
return super<AbstractKotlinUVariable>.getOriginalElement()
}
}
open class KotlinUField(
psi: PsiField,
override val containingElement: UElement?
) : AbstractKotlinUVariable(), UField, PsiField by psi {
override val psi = unwrap<UField, PsiField>(psi)
override fun getInitializer(): PsiExpression? {
@@ -111,13 +110,13 @@ open class KotlinUField(
override fun getOriginalElement(): PsiElement? {
return super<AbstractKotlinUVariable>.getOriginalElement()
}
}
open class KotlinULocalVariable(
psi: PsiLocalVariable,
override val containingElement: UElement?
) : AbstractKotlinUVariable(), ULocalVariable, PsiLocalVariable by psi {
override val psi = unwrap<ULocalVariable, PsiLocalVariable>(psi)
override fun getInitializer(): PsiExpression? {
@@ -134,6 +133,8 @@ open class KotlinUEnumConstant(
psi: PsiEnumConstant,
override val containingElement: UElement?
) : AbstractKotlinUVariable(), UEnumConstant, PsiEnumConstant by psi {
override val initializingClass: UClass? by lz { getLanguagePlugin().convertOpt<UClass>(psi.initializingClass, this) }
override val psi = unwrap<UEnumConstant, PsiEnumConstant>(psi)
override fun getInitializer(): PsiExpression? {
@@ -0,0 +1,58 @@
package org.jetbrains.uast.kotlin.evaluation
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.uast.UastBinaryOperator
import org.jetbrains.uast.UastPostfixOperator
import org.jetbrains.uast.evaluation.UEvaluationInfo
import org.jetbrains.uast.evaluation.UEvaluationState
import org.jetbrains.uast.evaluation.UEvaluatorExtension
import org.jetbrains.uast.kotlin.KotlinBinaryOperators
import org.jetbrains.uast.kotlin.KotlinPostfixOperators
import org.jetbrains.uast.values.*
class KotlinEvaluatorExtension : UEvaluatorExtension {
private data class Range(val from: UValue, val to: UValue) {
override fun toString() = "$from..$to"
}
private class UClosedRangeConstant(override val value: Range) : UAbstractConstant() {
constructor(from: UValue, to: UValue): this(Range(from, to))
}
override val language: KotlinLanguage = KotlinLanguage.INSTANCE
override fun evaluatePostfix(
operator: UastPostfixOperator,
operandValue: UValue,
state: UEvaluationState
): UEvaluationInfo {
return when (operator) {
KotlinPostfixOperators.EXCLEXCL -> when (operandValue.toConstant()) {
UNullConstant -> UValue.UNREACHABLE
is UConstant -> operandValue
else -> UUndeterminedValue
} to state
else -> return super.evaluatePostfix(operator, operandValue, state)
}
}
private fun UValue.contains(value: UValue): UValue {
val range = (this as? UClosedRangeConstant)?.value ?: return UUndeterminedValue
return (value greaterOrEquals range.from) and (value lessOrEquals range.to)
}
override fun evaluateBinary(
operator: UastBinaryOperator,
leftValue: UValue,
rightValue: UValue,
state: UEvaluationState
): UEvaluationInfo {
return when (operator) {
KotlinBinaryOperators.IN -> rightValue.contains(leftValue)
KotlinBinaryOperators.NOT_IN -> !rightValue.contains(leftValue)
KotlinBinaryOperators.RANGE_TO -> UClosedRangeConstant(leftValue, rightValue)
else -> UUndeterminedValue
} to state
}
}
@@ -0,0 +1,82 @@
package org.jetbrains.uast.kotlin.expressions
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod
import org.jetbrains.kotlin.psi.KtBinaryExpression
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.uast.*
import org.jetbrains.uast.kotlin.*
import org.jetbrains.uast.kotlin.kinds.KotlinSpecialExpressionKinds
import org.jetbrains.uast.kotlin.psi.UastKotlinPsiVariable
private fun createVariableReferenceExpression(variable: UVariable, containingElement: UElement?) =
object : USimpleNameReferenceExpression {
override fun resolve(): PsiElement? = variable
override val containingElement: UElement? = containingElement
override val resolvedName: String? = variable.name
override val annotations: List<UAnnotation> = emptyList()
override val identifier: String = variable.name.orAnonymous()
}
private fun createNullLiteralExpression(containingElement: UElement?) =
object : ULiteralExpression {
override val containingElement: UElement? = containingElement
override val value: Any? = null
override val annotations: List<UAnnotation> = emptyList()
}
private fun createNotEqWithNullExpression(variable: UVariable, containingElement: UElement?) =
object : UBinaryExpression {
override val containingElement: UElement? = containingElement
override val leftOperand: UExpression by lz { createVariableReferenceExpression(variable, this) }
override val rightOperand: UExpression by lz { createNullLiteralExpression(this) }
override val operator: UastBinaryOperator = UastBinaryOperator.NOT_EQUALS
override val operatorIdentifier: UIdentifier? = UIdentifier(null, this)
override fun resolveOperator(): PsiMethod? = null
override val annotations: List<UAnnotation> = emptyList()
}
private fun createElvisExpressions(
left: KtExpression,
right: KtExpression,
containingElement: UElement?,
psiParent: PsiElement): List<UExpression> {
val declaration = KotlinUDeclarationsExpression(containingElement)
val tempVariable = KotlinUVariable.create(UastKotlinPsiVariable.create(left, declaration, psiParent),
declaration)
declaration.declarations = listOf(tempVariable)
val ifExpression = object : UIfExpression {
override val containingElement: UElement? = containingElement
override val condition: UExpression by lz { createNotEqWithNullExpression(tempVariable, this) }
override val thenExpression: UExpression? by lz { createVariableReferenceExpression(tempVariable, this) }
override val elseExpression: UExpression? by lz { KotlinConverter.convertExpression(right, this) }
override val isTernary: Boolean = false
override val annotations: List<UAnnotation> = emptyList()
override val ifIdentifier: UIdentifier = UIdentifier(null, this)
override val elseIdentifier: UIdentifier? = UIdentifier(null, this)
}
return listOf(declaration, ifExpression)
}
fun createElvisExpression(elvisExpression: KtBinaryExpression, containingElement: UElement?): UExpressionList? {
val left = elvisExpression.left ?: return null
val right = elvisExpression.right ?: return null
return object : UExpressionList, KotlinEvaluatableUElement, KotlinUElementWithType {
override val psi: PsiElement? = elvisExpression
override val kind = KotlinSpecialExpressionKinds.ELVIS
override val containingElement: UElement? = containingElement
override val annotations: List<UAnnotation> = emptyList()
override val expressions: List<UExpression> by lz {
createElvisExpressions(left, right, this, elvisExpression.parent)
}
override fun asRenderString(): String = kind.name + " " +
expressions.joinToString(separator = "\n", prefix = "{\n", postfix = "\n}") {
it.asRenderString().withMargin
}
}
}
@@ -0,0 +1,33 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.uast.kotlin
import org.jetbrains.kotlin.psi.KtStringTemplateExpression
import org.jetbrains.uast.*
import org.jetbrains.uast.psi.PsiElementBacked
class KotlinStringTemplateUPolyadicExpression(
override val psi: KtStringTemplateExpression,
override val containingElement: UElement?
) : KotlinAbstractUExpression(),
UPolyadicExpression,
PsiElementBacked,
KotlinUElementWithType,
KotlinEvaluatableUElement {
override val operands: List<UExpression> by lz { psi.entries.map { KotlinConverter.convert(it, this) } }
override val operator = UastBinaryOperator.PLUS
}
@@ -20,11 +20,7 @@ import com.intellij.psi.PsiElement
import com.intellij.psi.PsiType
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtBinaryExpressionWithTypeRHS
import org.jetbrains.uast.UBinaryExpressionWithType
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UExpression
import org.jetbrains.uast.UastBinaryExpressionWithTypeKind
import org.jetbrains.uast.expressions.UTypeReferenceExpression
import org.jetbrains.uast.*
import org.jetbrains.uast.psi.PsiElementBacked
class KotlinUBinaryExpressionWithType(
@@ -37,7 +33,7 @@ class KotlinUBinaryExpressionWithType(
override val type by lz { psi.right.toPsiType(this) }
override val typeReference by lz {
psi.right?.let { KotlinUTypeReferenceExpression(it.toPsiType(this), it, this) }
psi.right?.let { LazyKotlinUTypeReferenceExpression(it, this) { it.toPsiType(this) } }
}
override val operationKind = when (psi.operationReference.getReferencedNameElementType()) {
@@ -57,9 +53,8 @@ class KotlinCustomUBinaryExpressionWithType(
lateinit override var operationKind: UastBinaryExpressionWithTypeKind
internal set
lateinit override var type: PsiType
internal set
override val type: PsiType by lz { typeReference?.type ?: UastErrorType }
override var typeReference: UTypeReferenceExpression? = null
internal set
}
@@ -16,6 +16,7 @@
package org.jetbrains.uast.kotlin
import com.intellij.psi.PsiNamedElement
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
import org.jetbrains.kotlin.resolve.BindingContext.DOUBLE_COLON_LHS
import org.jetbrains.uast.UCallableReferenceExpression
@@ -41,4 +42,9 @@ class KotlinUCallableReferenceExpression(
override val callableName: String
get() = psi.callableReference.getReferencedName()
override val resolvedName: String?
get() = (resolve() as? PsiNamedElement)?.name
override fun resolve() = psi.callableReference.resolveCallToDeclaration(this)
}
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.psi.KtCatchClause
import org.jetbrains.uast.UCatchClause
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UParameter
import org.jetbrains.uast.expressions.UTypeReferenceExpression
import org.jetbrains.uast.UTypeReferenceExpression
import org.jetbrains.uast.kotlin.psi.UastKotlinPsiParameter
import org.jetbrains.uast.psi.PsiElementBacked
@@ -37,8 +37,7 @@ class KotlinUCatchClause(
override val typeReferences by lz {
val parameter = psi.catchParameter ?: return@lz emptyList<UTypeReferenceExpression>()
val typeReference = parameter.typeReference
val type = typeReference.toPsiType(this, boxed = true)
listOf(KotlinUTypeReferenceExpression(type, typeReference, this))
val typeReference = parameter.typeReference ?: return@lz emptyList<UTypeReferenceExpression>()
listOf(LazyKotlinUTypeReferenceExpression(typeReference, this) { typeReference.toPsiType(this, boxed = true) } )
}
}
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.psi.KtObjectLiteralExpression
import org.jetbrains.kotlin.psi.KtSuperTypeCallEntry
import org.jetbrains.uast.*
import org.jetbrains.uast.expressions.UReferenceExpression
import org.jetbrains.uast.psi.PsiElementBacked
class KotlinUObjectLiteralExpression(
@@ -31,7 +31,6 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
import org.jetbrains.kotlin.utils.addToStdlib.constant
import org.jetbrains.uast.*
import org.jetbrains.uast.expressions.UReferenceExpression
import org.jetbrains.uast.psi.PsiElementBacked
import org.jetbrains.uast.visitor.UastVisitor
@@ -67,9 +67,9 @@ class KotlinUSwitchEntry(
else -> UastBinaryExpressionWithTypeKind.INSTANCE_CHECK
}
val typeRef = it.typeReference
val type = typeRef.toPsiType(this, boxed = true)
this.type = type
typeReference = typeRef?.let { KotlinUTypeReferenceExpression(type, it, this) }
typeReference = typeRef?.let {
LazyKotlinUTypeReferenceExpression(it, this) { typeRef.toPsiType(this, boxed = true) }
}
}
is KtWhenConditionWithExpression -> KotlinConverter.convertOrEmpty(it.expression, this)
else -> UastEmptyExpression
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.psi.KtTryExpression
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UIdentifier
import org.jetbrains.uast.UTryExpression
import org.jetbrains.uast.UVariable
import org.jetbrains.uast.psi.PsiElementBacked
class KotlinUTryExpression(
@@ -31,10 +32,10 @@ class KotlinUTryExpression(
override val catchClauses by lz { psi.catchClauses.map { KotlinUCatchClause(it, this) } }
override val finallyClause by lz { psi.finallyBlock?.finalExpression?.let { KotlinConverter.convertExpression(it, this) } }
override val resources: List<PsiResourceListElement>?
get() = null
override val resourceVariables: List<UVariable>
get() = emptyList()
override val isResources: Boolean
override val hasResources: Boolean
get() = false
override val tryIdentifier: UIdentifier
@@ -19,6 +19,7 @@ package org.jetbrains.uast.kotlin
import org.jetbrains.kotlin.psi.KtIsExpression
import org.jetbrains.uast.UBinaryExpressionWithType
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UastBinaryExpressionWithTypeKind
import org.jetbrains.uast.psi.PsiElementBacked
class KotlinUTypeCheckExpression(
@@ -29,9 +30,13 @@ class KotlinUTypeCheckExpression(
override val type by lz { psi.typeReference.toPsiType(this) }
override val typeReference by lz {
psi.typeReference?.let { KotlinUTypeReferenceExpression(it.toPsiType(this), it, this) }
override val typeReference = psi.typeReference?.let {
LazyKotlinUTypeReferenceExpression(it, this) { it.toPsiType(this) }
}
override val operationKind = KotlinBinaryExpressionWithTypeKinds.NEGATED_INSTANCE_CHECK
override val operationKind =
if(psi.isNegated)
KotlinBinaryExpressionWithTypeKinds.NEGATED_INSTANCE_CHECK
else
UastBinaryExpressionWithTypeKind.INSTANCE_CHECK
}
@@ -3,11 +3,20 @@ package org.jetbrains.uast.kotlin
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiType
import org.jetbrains.uast.UElement
import org.jetbrains.uast.expressions.UTypeReferenceExpression
import org.jetbrains.uast.UTypeReferenceExpression
import org.jetbrains.uast.psi.PsiElementBacked
open class KotlinUTypeReferenceExpression(
override val type: PsiType,
override val psi: PsiElement?,
override val containingElement: UElement?
) : KotlinAbstractUExpression(), UTypeReferenceExpression, PsiElementBacked, KotlinUElementWithType
) : KotlinAbstractUExpression(), UTypeReferenceExpression, PsiElementBacked, KotlinUElementWithType
class LazyKotlinUTypeReferenceExpression(
override val psi: PsiElement,
override val containingElement: UElement?,
private val typeSupplier: () -> PsiType
) : KotlinAbstractUExpression(), UTypeReferenceExpression, PsiElementBacked {
override val type: PsiType by lz { typeSupplier() }
}
@@ -0,0 +1,61 @@
package org.jetbrains.uast.kotlin.expressions
import com.intellij.psi.PsiVariable
import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.uast.*
import org.jetbrains.uast.kotlin.*
import org.jetbrains.uast.kotlin.psi.UastKotlinPsiParameter
import org.jetbrains.uast.kotlin.psi.UastKotlinPsiVariable
import org.jetbrains.uast.psi.PsiElementBacked
private class KotlinLocalFunctionUVariable(
val function: KtFunction,
override val psi: PsiVariable,
override val containingElement: UElement?
) : UVariable, PsiVariable by psi {
override val uastInitializer: UExpression? by lz {
createLocalFunctionLambdaExpression(function, this)
}
override val typeReference: UTypeReferenceExpression? = null
override val uastAnchor: UElement? = null
override val annotations: List<UAnnotation> = emptyList()
override fun equals(other: Any?) = other is KotlinLocalFunctionUVariable && psi == other.psi
override fun hashCode() = psi.hashCode()
}
private class KotlinLocalFunctionULambdaExpression(
override val psi: KtFunction,
override val containingElement: UElement?
): KotlinAbstractUExpression(), ULambdaExpression, PsiElementBacked {
override val body by lz { KotlinConverter.convertOrEmpty(psi.bodyExpression, this) }
override val valueParameters by lz {
psi.valueParameters.mapIndexed { i, p ->
KotlinUParameter(UastKotlinPsiParameter.create(p, psi, this, i), this)
}
}
override fun asRenderString(): String {
val renderedValueParameters = valueParameters.joinToString(prefix = "(", postfix = ")",
transform = KotlinUParameter::asRenderString)
val expressions = (body as? UBlockExpression)?.expressions?.joinToString("\n") {
it.asRenderString().withMargin
} ?: body.asRenderString()
return "fun $renderedValueParameters {\n${expressions.withMargin}\n}"
}
}
fun createLocalFunctionDeclaration(function: KtFunction, parent: UElement?): UDeclarationsExpression {
return KotlinUDeclarationsExpression(parent).apply {
val functionVariable = UastKotlinPsiVariable.create(function.name.orAnonymous(), function, this)
declarations = listOf(KotlinLocalFunctionUVariable(function, functionVariable, this))
}
}
fun createLocalFunctionLambdaExpression(function: KtFunction, parent: UElement?): ULambdaExpression =
KotlinLocalFunctionULambdaExpression(function, parent)
@@ -20,8 +20,8 @@ import org.jetbrains.uast.UastBinaryExpressionWithTypeKind
object KotlinBinaryExpressionWithTypeKinds {
@JvmField
val NEGATED_INSTANCE_CHECK = UastBinaryExpressionWithTypeKind("!is")
val NEGATED_INSTANCE_CHECK = UastBinaryExpressionWithTypeKind.InstanceCheck("!is")
@JvmField
val SAFE_TYPE_CAST = UastBinaryExpressionWithTypeKind("!is")
val SAFE_TYPE_CAST = UastBinaryExpressionWithTypeKind.TypeCast("as?")
}
@@ -27,4 +27,7 @@ object KotlinSpecialExpressionKinds {
@JvmField
val CLASS_BODY = UastSpecialExpressionKind("class_body")
@JvmField
val ELVIS = UastSpecialExpressionKind("elvis")
}
@@ -4,10 +4,8 @@ import com.intellij.lang.Language
import com.intellij.psi.*
import org.jetbrains.kotlin.asJava.elements.LightVariableBuilder
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.psi.KtDestructuringDeclaration
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtVariableDeclaration
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.uast.UDeclaration
import org.jetbrains.uast.UElement
@@ -68,7 +66,7 @@ class UastKotlinPsiVariable(
val psiParent = containingElement.getParentOfType<UDeclaration>()?.psi ?: declaration.parent
return UastKotlinPsiVariable(
declaration.manager,
"var" + Integer.toHexString(declaration.hashCode()),
"var" + Integer.toHexString(declaration.getHashCode()),
UastErrorType, //TODO,
KotlinLanguage.INSTANCE,
declaration.initializer,
@@ -76,6 +74,32 @@ class UastKotlinPsiVariable(
containingElement,
declaration)
}
fun create(initializer: KtExpression, containingElement: UElement, parent: PsiElement): PsiVariable {
val psiParent = containingElement.getParentOfType<UDeclaration>()?.psi ?: parent
return UastKotlinPsiVariable(
initializer.manager,
"var" + Integer.toHexString(initializer.getHashCode()),
UastErrorType, //TODO,
KotlinLanguage.INSTANCE,
initializer,
psiParent,
containingElement,
initializer)
}
fun create(name: String, localFunction: KtFunction, containingElement: UElement): PsiVariable {
val psiParent = containingElement.getParentOfType<UDeclaration>()?.psi ?: localFunction.parent
return UastKotlinPsiVariable(
localFunction.manager,
name,
UastErrorType, // TODO,
KotlinLanguage.INSTANCE,
localFunction,
psiParent,
containingElement,
localFunction)
}
}
}
@@ -84,4 +108,12 @@ private class KotlinUastPsiExpression(val ktExpression: KtExpression, val parent
val ktType = ktExpression.analyze()[BindingContext.EXPRESSION_TYPE_INFO, ktExpression]?.type ?: return null
return ktType.toPsiType(parent, ktExpression, boxed = false)
}
}
private fun PsiElement.getHashCode(): Int {
var result = 42
result = 41 * result + containingFile.name.hashCode()
result = 41 * result + startOffset
result = 41 * result + text.hashCode()
return result
}
+1 -1
View File
@@ -31,7 +31,7 @@
<os family="windows"/>
</condition>
<property name="uast.version" value="1.0.8"/>
<property name="uast.version" value="1.0.9"/>
<property name="generators" value="${basedir}/generators"/>