|
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