From 267153f4e3b56ffe138752ea4bdb228895d2c9ac Mon Sep 17 00:00:00 2001 From: Sergey Simonchik Date: Thu, 6 Nov 2014 17:22:42 +0300 Subject: [PATCH 1/3] json: don't warn about comments in .eslintrc files (compliance level for JSON can be configured now) --- .../JsonStandardComplianceInspection.java | 4 +- .../JsonStandardComplianceProvider.java | 44 +++++++++++++++++++ .../src/META-INF/JsonPlugin.xml | 6 +++ 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 json/src/com/intellij/json/codeinsight/JsonStandardComplianceProvider.java diff --git a/json/src/com/intellij/json/codeinsight/JsonStandardComplianceInspection.java b/json/src/com/intellij/json/codeinsight/JsonStandardComplianceInspection.java index 8c17715d696c..d1c83ec03952 100644 --- a/json/src/com/intellij/json/codeinsight/JsonStandardComplianceInspection.java +++ b/json/src/com/intellij/json/codeinsight/JsonStandardComplianceInspection.java @@ -54,7 +54,9 @@ public class JsonStandardComplianceInspection extends LocalInspectionTool { @Override public void visitComment(PsiComment comment) { if (myWarnAboutComments) { - holder.registerProblem(comment, JsonBundle.message("msg.compliance.problem.comments"), ProblemHighlightType.WEAK_WARNING); + if (JsonStandardComplianceProvider.shouldWarnAboutComment(comment)) { + holder.registerProblem(comment, JsonBundle.message("msg.compliance.problem.comments"), ProblemHighlightType.WEAK_WARNING); + } } } diff --git a/json/src/com/intellij/json/codeinsight/JsonStandardComplianceProvider.java b/json/src/com/intellij/json/codeinsight/JsonStandardComplianceProvider.java new file mode 100644 index 000000000000..996cc82a6867 --- /dev/null +++ b/json/src/com/intellij/json/codeinsight/JsonStandardComplianceProvider.java @@ -0,0 +1,44 @@ +/* + * Copyright 2000-2014 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 com.intellij.json.codeinsight; + +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.psi.PsiComment; +import org.jetbrains.annotations.NotNull; + +/** + * Allows to configure a compliance level for JSON. + * For example, some tools ignore comments in JSON silently when parsing, so there is no need to warn users about it. + */ +public abstract class JsonStandardComplianceProvider { + public static final ExtensionPointName EP_NAME = + ExtensionPointName.create("com.intellij.json.jsonStandardComplianceProvider"); + + public abstract boolean isCommentAllowed(@NotNull PsiComment comment); + + public static boolean shouldWarnAboutComment(@NotNull PsiComment comment) { + JsonStandardComplianceProvider[] providers = EP_NAME.getExtensions(); + if (providers.length == 0) { + return true; + } + for (JsonStandardComplianceProvider provider : providers) { + if (provider.isCommentAllowed(comment)) { + return false; + } + } + return true; + } +} diff --git a/platform/platform-resources/src/META-INF/JsonPlugin.xml b/platform/platform-resources/src/META-INF/JsonPlugin.xml index deeec3ad3fa2..c3d643a5d1da 100644 --- a/platform/platform-resources/src/META-INF/JsonPlugin.xml +++ b/platform/platform-resources/src/META-INF/JsonPlugin.xml @@ -58,4 +58,10 @@ implementationClass="com.intellij.json.psi.JsonStringLiteralManipulator"/> + + + + + \ No newline at end of file From a1c6a7e8611efb041660521d851012a158c6f8ef Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Thu, 6 Nov 2014 14:29:11 +0100 Subject: [PATCH 2/3] show definition optimization: do not load psi for anonymouses when possible --- .../hint/ImplementationViewComponent.java | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/ImplementationViewComponent.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/ImplementationViewComponent.java index b83d832f8348..38063e097f0d 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/hint/ImplementationViewComponent.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/ImplementationViewComponent.java @@ -39,6 +39,7 @@ import com.intellij.openapi.util.Comparing; import com.intellij.openapi.vcs.FileStatusManager; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtilCore; import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.ListCellRendererWrapper; @@ -329,12 +330,26 @@ public class ImplementationViewComponent extends JPanel { if (element instanceof PsiNamedElement) { names.add(((PsiNamedElement)element).getName()); } + if (names.size() > 1) { + break; + } } + for (PsiElement element : elements) { PsiFile file = getContainingFile(element); if (file == null) continue; - final PsiElement parent = element.getParent(); - files.add(new FileDescriptor(file, names.size() > 1 || parent == file ? element : parent)); + if (names.size() > 1) { + files.add(new FileDescriptor(file, element)); + } + else { + final PsiElement parent = PsiTreeUtil.getStubOrPsiParent(element); + if (parent == file) { + files.add(new FileDescriptor(file, element)); + } + else { + files.add(new FileDescriptor(file, parent)); + } + } candidates.add(element); } From 237f36c3ede475b70adf16bd4f7665e6520f1833 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Thu, 6 Nov 2014 15:26:59 +0100 Subject: [PATCH 3/3] functional expressions search: process all files with ->/:: as there are about 400 methods in jdk with type parameter as parameter type which all should be processed on each functional expression search (IDEA-132407) --- .../cache/impl/idCache/JavaFilterLexer.java | 4 +- .../index/JavaMethodParameterTypesIndex.java | 50 ------ .../JavaFunctionalExpressionSearcher.java | 157 ++++++++---------- .../java/stubs/JavaMethodElementType.java | 31 ---- .../java/stubs/index/JavaStubIndexKeys.java | 1 - .../psi/impl/source/JavaFileElementType.java | 2 +- .../psi/impl/cache/impl/id/IdIndex.java | 2 +- resources/src/META-INF/IdeaPlugin.xml | 1 - 8 files changed, 71 insertions(+), 177 deletions(-) delete mode 100644 java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaMethodParameterTypesIndex.java diff --git a/java/java-impl/src/com/intellij/psi/impl/cache/impl/idCache/JavaFilterLexer.java b/java/java-impl/src/com/intellij/psi/impl/cache/impl/idCache/JavaFilterLexer.java index 44207d32b640..8ea446e46786 100644 --- a/java/java-impl/src/com/intellij/psi/impl/cache/impl/idCache/JavaFilterLexer.java +++ b/java/java-impl/src/com/intellij/psi/impl/cache/impl/idCache/JavaFilterLexer.java @@ -58,7 +58,9 @@ public class JavaFilterLexer extends BaseFilterLexer { if (tokenType == JavaTokenType.IDENTIFIER || tokenType == JavaTokenType.LONG_LITERAL || tokenType == JavaTokenType.INTEGER_LITERAL - || tokenType == JavaTokenType.CHARACTER_LITERAL) { + || tokenType == JavaTokenType.CHARACTER_LITERAL + || tokenType == JavaTokenType.ARROW + || tokenType == JavaTokenType.DOUBLE_COLON) { addOccurrenceInToken(UsageSearchContext.IN_CODE); } else if (tokenType == JavaTokenType.STRING_LITERAL) { diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaMethodParameterTypesIndex.java b/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaMethodParameterTypesIndex.java deleted file mode 100644 index 23f4ffac729e..000000000000 --- a/java/java-indexing-impl/src/com/intellij/psi/impl/java/stubs/index/JavaMethodParameterTypesIndex.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2000-2014 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. - */ - -/* - * @author max - */ -package com.intellij.psi.impl.java.stubs.index; - -import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiMethod; -import com.intellij.psi.impl.search.JavaSourceFilterScope; -import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.psi.stubs.StringStubIndexExtension; -import com.intellij.psi.stubs.StubIndex; -import com.intellij.psi.stubs.StubIndexKey; -import org.jetbrains.annotations.NotNull; - -import java.util.Collection; - -public class JavaMethodParameterTypesIndex extends StringStubIndexExtension { - - private static final JavaMethodParameterTypesIndex ourInstance = new JavaMethodParameterTypesIndex(); - public static JavaMethodParameterTypesIndex getInstance() { - return ourInstance; - } - - @NotNull - @Override - public StubIndexKey getKey() { - return JavaStubIndexKeys.METHOD_TYPES; - } - - @Override - public Collection get(@NotNull final String s, @NotNull final Project project, @NotNull final GlobalSearchScope scope) { - return StubIndex.getElements(getKey(), s, project, new JavaSourceFilterScope(scope), PsiMethod.class); - } -} \ No newline at end of file diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaFunctionalExpressionSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaFunctionalExpressionSearcher.java index cb5d6be103fd..2652cb3aa51d 100644 --- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaFunctionalExpressionSearcher.java +++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaFunctionalExpressionSearcher.java @@ -15,37 +15,39 @@ */ package com.intellij.psi.impl.search; +import com.intellij.ide.highlighter.JavaFileType; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; import com.intellij.openapi.module.impl.scopes.ModulesScope; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.LanguageLevelModuleExtension; import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.Ref; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.*; -import com.intellij.psi.impl.java.stubs.JavaMethodElementType; -import com.intellij.psi.impl.java.stubs.index.JavaMethodParameterTypesIndex; -import com.intellij.psi.search.EverythingGlobalScope; -import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.psi.search.SearchScope; +import com.intellij.psi.search.*; import com.intellij.psi.search.searches.FunctionalExpressionSearch; -import com.intellij.psi.search.searches.MethodReferencesSearch; -import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.PsiUtilCore; +import com.intellij.util.CommonProcessors; import com.intellij.util.Processor; import com.intellij.util.QueryExecutor; import com.intellij.util.containers.HashSet; import org.jetbrains.annotations.NotNull; import java.util.Collection; -import java.util.LinkedHashSet; import java.util.Set; public class JavaFunctionalExpressionSearcher implements QueryExecutor { + private static final Logger LOG = Logger.getInstance("#" + JavaFunctionalExpressionSearcher.class.getName()); + @Override public boolean execute(@NotNull final FunctionalExpressionSearch.SearchParameters queryParameters, @NotNull final Processor consumer) { @@ -98,102 +100,75 @@ public class JavaFunctionalExpressionSearcher implements QueryExecutor lambdaCandidates = ApplicationManager.getApplication().runReadAction(new Computable>() { + + final ProjectFileIndex index = ProjectRootManager.getInstance(project).getFileIndex(); + CommonProcessors.CollectProcessor processor = new CommonProcessors.CollectProcessor() { @Override - public Collection compute() { - final String functionalInterfaceName = aClass.getName(); - final GlobalSearchScope useClassScope = classScope instanceof GlobalSearchScope ? (GlobalSearchScope)classScope : scope; - JavaMethodParameterTypesIndex parameterTypesIndex = JavaMethodParameterTypesIndex.getInstance(); - LinkedHashSet methods = new LinkedHashSet(parameterTypesIndex.get(functionalInterfaceName, project, useClassScope)); - methods.addAll(parameterTypesIndex.get(JavaMethodElementType.TYPE_PARAMETER_PSEUDO_NAME, project, - GlobalSearchScope.allScope(project))); - return methods; + protected boolean accept(VirtualFile virtualFile) { + return scope.contains(virtualFile) && virtualFile.getFileType() == JavaFileType.INSTANCE && index.isInSource(virtualFile); } - }); - for (PsiMethod psiMethod : lambdaCandidates) { - for (final PsiReference ref : MethodReferencesSearch.search(psiMethod, scope, false)) { - boolean accepted = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public Boolean compute() { - final PsiElement refElement = ref.getElement(); - if (refElement != null) { - final PsiElement candidateElement = refElement.getParent(); - if (candidateElement instanceof PsiCallExpression) { - final PsiExpressionList argumentList = ((PsiCallExpression)candidateElement).getArgumentList(); - if (argumentList != null) { - final PsiExpression[] args = argumentList.getExpressions(); - for (PsiExpression arg : args) { - if (arg instanceof PsiFunctionalExpression) { - final PsiFunctionalExpression functionalExpression = (PsiFunctionalExpression)arg; - final PsiType functionalType = functionalExpression.getFunctionalInterfaceType(); - if (PsiUtil.resolveClassInType(functionalType) == aClass) { - if (!consumer.process(functionalExpression)) return false; - } - } - } - } - } - } - return true; - } - }); - if (!accepted) return false; - } - } + }; - for (final PsiReference reference : ReferencesSearch.search(aClass, scope)) { - boolean accepted = ApplicationManager.getApplication().runReadAction(new Computable() { + final PsiSearchHelperImpl helper = (PsiSearchHelperImpl)PsiSearchHelper.SERVICE.getInstance(project); + helper.processFilesWithText(scope, UsageSearchContext.IN_CODE, true, "::", processor); + helper.processFilesWithText(scope, UsageSearchContext.IN_CODE, true, "->", processor); + + Collection files = processor.getResults(); + LOG.info("#files: " + files.size()); + + final PsiManager psiManager = PsiManager.getInstance(project); + for (final VirtualFile file : files) { + if (!ApplicationManager.getApplication().runReadAction(new Computable() { @Override public Boolean compute() { - final PsiElement element = reference.getElement(); - if (element != null) { - final PsiElement parent = element.getParent(); - if (parent instanceof PsiTypeElement) { - final PsiElement gParent = parent.getParent(); - if (gParent instanceof PsiVariable) { - final PsiExpression initializer = PsiUtil.skipParenthesizedExprDown(((PsiVariable)gParent).getInitializer()); - if (initializer instanceof PsiFunctionalExpression) { - if (!consumer.process((PsiFunctionalExpression)initializer)) return false; - } - for (PsiReference varRef : ReferencesSearch.search(parent, scope)) { - final PsiElement varElement = varRef.getElement(); - if (varElement != null) { - final PsiElement varElementParent = varElement.getParent(); - if (varElementParent instanceof PsiAssignmentExpression && - ((PsiAssignmentExpression)varElementParent).getLExpression() == varElement) { - final PsiExpression rExpression = PsiUtil.skipParenthesizedExprDown(((PsiAssignmentExpression)varElementParent).getRExpression()); - if (rExpression instanceof PsiFunctionalExpression) { - if (!consumer.process((PsiFunctionalExpression)rExpression)) return false; - } - } - } - } - } else if (gParent instanceof PsiMethod) { - final PsiReturnStatement[] returnStatements = ApplicationManager.getApplication().runReadAction( - new Computable() { - @Override - public PsiReturnStatement[] compute() { - return PsiUtil.findReturnStatements((PsiMethod)gParent); - } - }); - for (PsiReturnStatement returnStatement : returnStatements) { - final PsiExpression returnValue = returnStatement.getReturnValue(); - if (returnValue instanceof PsiFunctionalExpression) { - if (!consumer.process((PsiFunctionalExpression)returnValue)) return false; - } - } - } + return processFileWithFunctionalInterfaces(aClass, consumer, psiManager, file); + } + })) return false; + } + return true; + } + + private static boolean processFileWithFunctionalInterfaces(final PsiClass aClass, + final Processor consumer, + final PsiManager psiManager, VirtualFile file) { + final PsiFile psiFile = psiManager.findFile(file); + if (psiFile != null) { + final Ref ref = new Ref(true); + psiFile.accept(new JavaRecursiveElementWalkingVisitor() { + @Override + public void visitElement(PsiElement element) { + if (!ref.get()) { + return; + } + super.visitElement(element); + } + + private void visitFunctionalExpression(PsiFunctionalExpression expression) { + PsiType functionalInterfaceType = expression.getFunctionalInterfaceType(); + if (psiManager.areElementsEquivalent(PsiUtil.resolveClassInType(functionalInterfaceType), aClass)) { + if (!consumer.process(expression)) { + ref.set(false); } } + } - return true; + @Override + public void visitLambdaExpression(PsiLambdaExpression expression) { + super.visitLambdaExpression(expression); + visitFunctionalExpression(expression); + } + + @Override + public void visitMethodReferenceExpression(PsiMethodReferenceExpression expression) { + super.visitMethodReferenceExpression(expression); + visitFunctionalExpression(expression); } }); - if (!accepted) return false; - + if (!ref.get()) return false; } return true; } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaMethodElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaMethodElementType.java index 53033115a85c..06369c9f7379 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaMethodElementType.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaMethodElementType.java @@ -50,7 +50,6 @@ import java.util.Set; * @author max */ public abstract class JavaMethodElementType extends JavaStubElementType { - public static final String TYPE_PARAMETER_PSEUDO_NAME = "$TYPE_PARAMETER$"; public JavaMethodElementType(@NonNls final String name) { super(name); } @@ -150,35 +149,5 @@ public abstract class JavaMethodElementType extends JavaStubElementType methodTypeParams = null; - for (StubElement stubElement : stub.getChildrenStubs()) { - if (stubElement instanceof PsiTypeParameterListStub) { - for (Object tStub : stubElement.getChildrenStubs()) { - if (tStub instanceof PsiTypeParameterStub) { - if (methodTypeParams == null) { - methodTypeParams = new HashSet(); - } - methodTypeParams.add(((PsiTypeParameterStub)tStub).getName()); - } - } - } - else if (stubElement instanceof PsiParameterListStub) { - for (StubElement paramStub : ((PsiParameterListStub)stubElement).getChildrenStubs()) { - if (paramStub instanceof PsiParameterStub) { - TypeInfo type = ((PsiParameterStub)paramStub).getType(false); - if (type.arrayCount > 0) continue; - String typeName = type.getShortTypeText(); - if (TypeConversionUtil.isPrimitive(typeName) || TypeConversionUtil.isPrimitiveWrapper(typeName)) continue; - sink.occurrence(JavaStubIndexKeys.METHOD_TYPES, typeName); - if (methodTypeParams != null && methodTypeParams.contains(typeName)) { - sink.occurrence(JavaStubIndexKeys.METHOD_TYPES, TYPE_PARAMETER_PSEUDO_NAME); - methodTypeParams = null; - } - } - } - break; - } - } } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/index/JavaStubIndexKeys.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/index/JavaStubIndexKeys.java index a3e247f73de8..e8760f5f95fa 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/index/JavaStubIndexKeys.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/index/JavaStubIndexKeys.java @@ -29,7 +29,6 @@ public class JavaStubIndexKeys { public static final StubIndexKey JVM_STATIC_MEMBERS_NAMES = StubIndexKey.createIndexKey("jvm.static.member.name"); public static final StubIndexKey JVM_STATIC_MEMBERS_TYPES = StubIndexKey.createIndexKey("jvm.static.member.type"); public static final StubIndexKey ANONYMOUS_BASEREF = StubIndexKey.createIndexKey("java.anonymous.baseref"); - public static final StubIndexKey METHOD_TYPES = StubIndexKey.createIndexKey("java.method.parameter.types"); public static final StubIndexKey CLASS_SHORT_NAMES = StubIndexKey.createIndexKey("java.class.shortname"); public static final StubIndexKey CLASS_FQN = StubIndexKey.createIndexKey("java.class.fqn"); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaFileElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaFileElementType.java index eedf4abf13cb..cec30eb3c8af 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaFileElementType.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaFileElementType.java @@ -38,7 +38,7 @@ import java.io.IOException; * @author max */ public class JavaFileElementType extends ILightStubFileElementType { - public static final int STUB_VERSION = 18; + public static final int STUB_VERSION = 19; public JavaFileElementType() { super("java.FILE", JavaLanguage.INSTANCE); diff --git a/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdIndex.java b/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdIndex.java index af193348c71b..aed1ccf7277f 100644 --- a/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdIndex.java +++ b/platform/indexing-impl/src/com/intellij/psi/impl/cache/impl/id/IdIndex.java @@ -91,7 +91,7 @@ public class IdIndex extends FileBasedIndexExtension { @Override public int getVersion() { - return 13 + (ourSnapshotMappingsEnabled ? 0xFF:0); // TODO: version should enumerate all word scanner versions and build version upon that set + return 14 + (ourSnapshotMappingsEnabled ? 0xFF:0); // TODO: version should enumerate all word scanner versions and build version upon that set } @Override diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 4a9f2b5fe5cb..bae70d18ab02 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -1375,7 +1375,6 @@ -