|
17 | 17 | import com.intellij.openapi.util.TextRange;
|
18 | 18 | import com.intellij.openapi.vfs.VfsUtilCore;
|
19 | 19 | import com.intellij.openapi.vfs.VirtualFile;
|
20 |
| -import com.intellij.psi.JavaRecursiveElementVisitor; |
21 |
| -import com.intellij.psi.PsiAnnotation; |
22 |
| -import com.intellij.psi.PsiClass; |
23 |
| -import com.intellij.psi.PsiClassType; |
24 |
| -import com.intellij.psi.PsiElement; |
25 |
| -import com.intellij.psi.PsiField; |
26 |
| -import com.intellij.psi.PsiFile; |
27 |
| -import com.intellij.psi.PsiIdentifier; |
28 |
| -import com.intellij.psi.PsiLiteralValue; |
29 |
| -import com.intellij.psi.PsiMethod; |
30 |
| -import com.intellij.psi.PsiType; |
| 20 | +import com.intellij.psi.*; |
31 | 21 | import com.intellij.psi.util.PsiTreeUtil;
|
32 | 22 | import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.utils.IPsiUtils;
|
33 | 23 | import com.redhat.devtools.intellij.lsp4ij.LSPIJUtils;
|
34 | 24 | import com.redhat.devtools.intellij.qute.psi.internal.AnnotationLocationSupport;
|
35 | 25 | import com.redhat.devtools.intellij.qute.psi.utils.AnnotationUtils;
|
36 | 26 | import com.redhat.devtools.intellij.qute.psi.utils.PsiQuteProjectUtils;
|
37 | 27 | import com.redhat.devtools.intellij.qute.psi.utils.PsiTypeUtils;
|
| 28 | +import com.redhat.devtools.intellij.qute.psi.utils.TemplatePathInfo; |
38 | 29 | import org.eclipse.lsp4j.Range;
|
39 | 30 | import org.jetbrains.annotations.Nullable;
|
40 | 31 |
|
|
45 | 36 |
|
46 | 37 | import static com.redhat.devtools.intellij.qute.psi.internal.QuteJavaConstants.CHECKED_TEMPLATE_ANNOTATION;
|
47 | 38 | import static com.redhat.devtools.intellij.qute.psi.internal.QuteJavaConstants.OLD_CHECKED_TEMPLATE_ANNOTATION;
|
| 39 | +import static com.redhat.devtools.intellij.qute.psi.internal.QuteJavaConstants.CHECKED_TEMPLATE_ANNOTATION_IGNORE_FRAGMENTS; |
48 | 40 | import static com.redhat.devtools.intellij.qute.psi.internal.QuteJavaConstants.TEMPLATE_CLASS;
|
49 | 41 |
|
50 | 42 | /**
|
@@ -113,7 +105,7 @@ public void visitField(PsiField node) {
|
113 | 105 | .getLocationExpressionFromConstructorParameter(node.getName());
|
114 | 106 | }
|
115 | 107 | String fieldName = node.getName();
|
116 |
| - collectTemplateLink(node, locationExpression, getTypeDeclaration(node), null, fieldName); |
| 108 | + collectTemplateLink(node, locationExpression, getTypeDeclaration(node), null, fieldName, false); |
117 | 109 | }
|
118 | 110 | super.visitField(node);
|
119 | 111 | }
|
@@ -141,46 +133,78 @@ public void visitClass(PsiClass node) {
|
141 | 133 | // @CheckedTemplate
|
142 | 134 | // public static class Templates {
|
143 | 135 | // public static native TemplateInstance book(Book book);
|
| 136 | + boolean ignoreFragments = isIgnoreFragments(annotation); |
144 | 137 | for(PsiMethod method : node.getMethods()) {
|
145 |
| - collectTemplateLink(method, node); |
| 138 | + collectTemplateLink(method, node, ignoreFragments ); |
146 | 139 | }
|
147 | 140 | }
|
148 | 141 | }
|
149 | 142 | super.visitClass(node);
|
150 | 143 | levelTypeDecl--;
|
151 | 144 | }
|
152 | 145 |
|
| 146 | + /** |
| 147 | + * Returns true if @CheckedTemplate annotation declares that fragment must be |
| 148 | + * ignored and false otherwise. |
| 149 | + * |
| 150 | + * <code> |
| 151 | + * @CheckedTemplate(ignoreFragments=true) |
| 152 | + * </code> |
| 153 | + * |
| 154 | + * @param checkedTemplateAnnotation the CheckedTemplate annotation. |
| 155 | + * |
| 156 | + * @return true if @CheckedTemplate annotation declares that fragment must be |
| 157 | + * ignored and false otherwise. |
| 158 | + */ |
| 159 | + private static boolean isIgnoreFragments(PsiAnnotation checkedTemplateAnnotation) { |
| 160 | + Boolean ignoreFragment = null; |
| 161 | + try { |
| 162 | + for(PsiNameValuePair pair : checkedTemplateAnnotation.getParameterList().getAttributes()) { |
| 163 | + if (CHECKED_TEMPLATE_ANNOTATION_IGNORE_FRAGMENTS.equalsIgnoreCase(pair.getAttributeName())) { |
| 164 | + ignoreFragment = AnnotationUtils.getValueAsBoolean(pair); |
| 165 | + } |
| 166 | + } |
| 167 | + } catch (Exception e) { |
| 168 | + // Do nothing |
| 169 | + } |
| 170 | + return ignoreFragment != null ? ignoreFragment.booleanValue() : false; |
| 171 | + } |
| 172 | + |
153 | 173 | private static PsiClass getTypeDeclaration(PsiElement node) {
|
154 | 174 | return PsiTreeUtil.getParentOfType(node, PsiClass.class);
|
155 | 175 | }
|
156 | 176 |
|
157 | 177 |
|
158 |
| - private void collectTemplateLink(PsiMethod methodDeclaration, PsiClass type) { |
| 178 | + private void collectTemplateLink(PsiMethod methodDeclaration, PsiClass type, boolean ignoreFragments) { |
159 | 179 | String className = null;
|
160 | 180 | boolean innerClass = levelTypeDecl > 1;
|
161 | 181 | if (innerClass) {
|
162 | 182 | className = PsiTypeUtils.getSimpleClassName(typeRoot.getName());
|
163 | 183 | }
|
164 | 184 | String methodName = methodDeclaration.getName();
|
165 |
| - collectTemplateLink(methodDeclaration, null, type, className, methodName); |
| 185 | + collectTemplateLink(methodDeclaration, null, type, className, methodName, ignoreFragments ); |
166 | 186 | }
|
167 | 187 |
|
168 | 188 | private void collectTemplateLink(PsiElement fieldOrMethod, PsiLiteralValue locationAnnotation, PsiClass type, String className,
|
169 |
| - String fieldOrMethodName) { |
| 189 | + String fieldOrMethodName, boolean ignoreFragment ) { |
170 | 190 | try {
|
171 | 191 | String location = locationAnnotation != null && locationAnnotation.getValue() instanceof String ? (String) locationAnnotation.getValue() : null;
|
172 | 192 | Module project = utils.getModule();
|
173 |
| - String templateFilePath = location != null ? PsiQuteProjectUtils.getTemplatePath(null, location) |
174 |
| - : PsiQuteProjectUtils.getTemplatePath(className, fieldOrMethodName); |
| 193 | + TemplatePathInfo templatePathInfo = location != null |
| 194 | + ? PsiQuteProjectUtils.getTemplatePath(null, location, ignoreFragment) |
| 195 | + : PsiQuteProjectUtils.getTemplatePath(className, fieldOrMethodName, ignoreFragment); |
| 196 | + |
175 | 197 | VirtualFile templateFile = null;
|
176 | 198 | if (location == null) {
|
177 |
| - templateFile = getTemplateFile(project, templateFilePath); |
178 |
| - templateFilePath = getRelativePath(templateFilePath, templateFile, project); |
| 199 | + templateFile = getTemplateFile(project, templatePathInfo.getTemplateUri()); |
| 200 | + templatePathInfo = new TemplatePathInfo( |
| 201 | + getRelativePath(templatePathInfo.getTemplateUri(), templateFile, project), |
| 202 | + templatePathInfo.getFragmentId()); |
179 | 203 | } else {
|
180 |
| - templateFile = getVirtualFile(project, templateFilePath, ""); |
| 204 | + templateFile = getVirtualFile(project, templatePathInfo.getTemplateUri(), ""); |
181 | 205 | }
|
182 | 206 | collectTemplateLink(fieldOrMethod, locationAnnotation, type, className, fieldOrMethodName, location,
|
183 |
| - templateFile, templateFilePath); |
| 207 | + templateFile, templatePathInfo); |
184 | 208 | } catch (RuntimeException e) {
|
185 | 209 | LOGGER.log(Level.WARNING, "Error while creating Qute CodeLens for Java file.", e);
|
186 | 210 | }
|
@@ -245,7 +269,7 @@ protected Range createRange(PsiElement fieldOrMethod) {
|
245 | 269 | }
|
246 | 270 |
|
247 | 271 | protected abstract void collectTemplateLink(PsiElement node, PsiLiteralValue locationAnnotation, PsiClass type,
|
248 |
| - String className, String fieldOrMethodName, String location, VirtualFile templateFile, String templateFilePath); |
| 272 | + String className, String fieldOrMethodName, String location, VirtualFile templateFile, TemplatePathInfo templatePathInfo); |
249 | 273 |
|
250 | 274 | private static boolean isTemplateType(PsiType type) {
|
251 | 275 | if (type instanceof PsiClassType) {
|
|
0 commit comments