From b4bd5e235e411a29055db27384f366cd4863bb8e Mon Sep 17 00:00:00 2001 From: Gireesh Punathil Date: Wed, 5 Apr 2023 19:20:22 +0530 Subject: [PATCH] refix: quick-fix for extraneous empty line(s) in manifest editor Extraneous lines are errneous to the manifest compiler, but it does not recommend / provide a resolution. Add a quick fix to remove extraneous line. Takes care of the empty valid empty lines at the end of manifests. In the main iteration loop, identify empty lines and push into a list. At the end of the loop, aggregate all the empty lines into one single marker. This way, we address issues that can arise from race conditions when two threas try to manipulate the document context simultaneously. Fixes: https://github.com/eclipse-pde/eclipse.pde/issues/563 --- .../builders/JarManifestErrorReporter.java | 41 ++++++++++- .../core/builders/PDEMarkerFactory.java | 4 +- .../pde/internal/ui/PDEUIMessages.java | 4 + .../correction/ExtraneousLinesResolution.java | 73 +++++++++++++++++++ .../ui/correction/ResolutionGenerator.java | 5 +- .../pde/internal/ui/pderesources.properties | 2 + 6 files changed, 124 insertions(+), 5 deletions(-) create mode 100644 ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/ExtraneousLinesResolution.java diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/JarManifestErrorReporter.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/JarManifestErrorReporter.java index bc9a1d16196..bb3394ffd21 100644 --- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/JarManifestErrorReporter.java +++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/JarManifestErrorReporter.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2017 IBM Corporation and others. + * Copyright (c) 2000, 2023 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -15,9 +15,11 @@ import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.Map; - +import java.util.StringJoiner; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; @@ -121,6 +123,9 @@ protected void parseManifest(IDocument document, IProgressMonitor monitor) { fHeaders = new HashMap<>(); JarManifestHeader header = null; int l = 0; + ArrayList emptyLineCandidates = new ArrayList<>(); + ArrayList emptyLines = new ArrayList<>(); + int numLines = document.getNumberOfLines(); for (; l < document.getNumberOfLines(); l++) { if (l % 100 == 0) { checkCanceled(monitor); @@ -140,10 +145,15 @@ protected void parseManifest(IDocument document, IProgressMonitor monitor) { } // parse if (line.length() == 0) { - // Empty Line + // Empty Line in the beginning if (l == 0) { report(PDECoreMessages.BundleErrorReporter_noMainSection, 1, CompilerFlags.ERROR, PDEMarkerFactory.CAT_FATAL); return; + + // empty line elsewhere + } else if (l != numLines - 1) { + emptyLineCandidates.add(Integer.valueOf(l)); + continue; } /* flush last line */ if (header != null) { @@ -152,6 +162,10 @@ protected void parseManifest(IDocument document, IProgressMonitor monitor) { } break; /* done processing main attributes */ } + + emptyLines.addAll(emptyLineCandidates); + emptyLineCandidates.clear(); + if (line.charAt(0) == ' ') { // Continuation Line if (l == 0) { /* if no previous line */ @@ -194,6 +208,27 @@ protected void parseManifest(IDocument document, IProgressMonitor monitor) { } } + if (emptyLines.size() > 0) { + // reverse the list to aid the quick-fix resolver + // to remove the line starting from the fag end, + // saving additional calculations to adjust the + // line numbers after each removal in-line. + Collections.reverse(emptyLines); + + // build a marker with all the line info aggregated into it, + // with the first empty line as the anchor line. + StringJoiner str = new StringJoiner(","); //$NON-NLS-1$ + int start = emptyLines.get(emptyLines.size() - 1); + for (Integer i : emptyLines) { + str.add(i.toString()); + } + VirtualMarker marker = report(PDECoreMessages.BundleErrorReporter_noNameHeader, start + 1, + CompilerFlags.ERROR, PDEMarkerFactory.M_EXTRANEOUS_EMPTY_LINES, PDEMarkerFactory.CAT_FATAL); + if (marker != null) { + marker.setAttribute(PDEMarkerFactory.EMPTY_LINE, str.toString()); + } + } + if (header != null) { // lingering header, line not terminated VirtualMarker marker = report(PDECoreMessages.BundleErrorReporter_noLineTermination, l, CompilerFlags.ERROR, PDEMarkerFactory.M_NO_LINE_TERMINATION, PDEMarkerFactory.CAT_FATAL); diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/PDEMarkerFactory.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/PDEMarkerFactory.java index 6616b25b4f1..993c2e68446 100644 --- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/PDEMarkerFactory.java +++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/PDEMarkerFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2021 IBM Corporation and others. + * Copyright (c) 2000, 2023 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -76,6 +76,7 @@ public class PDEMarkerFactory { public static final int M_EXEC_ENV_TOO_LOW = 0x1029; // other problem public static final int M_CONFLICTING_AUTOMATIC_MODULE = 0x1030; // other // problem + public static final int M_EXTRANEOUS_EMPTY_LINES = 0X1031; // fatal problem // build properties fixes public static final int B_APPEND_SLASH_FOLDER_ENTRY = 0x2001; @@ -99,6 +100,7 @@ public class PDEMarkerFactory { public static final String ATTR_CAN_ADD = "deprecatedAutostart.canAdd"; //$NON-NLS-1$ public static final String ATTR_HEADER = "deprecatedAutostart.header"; //$NON-NLS-1$ public static final String REQUIRED_EXEC_ENV = "executionEnvironment.key"; //$NON-NLS-1$ + public static final String EMPTY_LINE = "emptyLine"; //$NON-NLS-1$ /** * Boolean attribute for marker added when no newline is found at the end of a manifest. Value is * true if there is character content on the last line that should be diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/PDEUIMessages.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/PDEUIMessages.java index 40f3c7d6d9d..16ce4bae0af 100644 --- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/PDEUIMessages.java +++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/PDEUIMessages.java @@ -2617,6 +2617,10 @@ public class PDEUIMessages extends NLS { public static String NoLineTerminationResolutionRemove_label; + public static String ExtraneousLineResolutionRemove_description; + + public static String ExtraneousLineResolutionRemove_label; + public static String OptionalImportPkgResolution_description; public static String OptionalImportPkgResolution_label; diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/ExtraneousLinesResolution.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/ExtraneousLinesResolution.java new file mode 100644 index 00000000000..93f722c30fd --- /dev/null +++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/ExtraneousLinesResolution.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2023 IBM Corporation and others. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - initial API and implementation + * Gireesh Punathil Initial implementation + *******************************************************************************/ + +package org.eclipse.pde.internal.ui.correction; + +import java.util.StringTokenizer; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jface.text.*; +import org.eclipse.pde.internal.core.builders.PDEMarkerFactory; +import org.eclipse.pde.internal.core.text.bundle.BundleModel; +import org.eclipse.pde.internal.ui.PDEPlugin; +import org.eclipse.pde.internal.ui.PDEUIMessages; + +/** + *

Represents a resolution to the problem of the bundle manifest + * having extraneous lines.

+ */ +public class ExtraneousLinesResolution extends AbstractManifestMarkerResolution { + /** + * Creates a new resolution + * + * @param type + * {@link AbstractPDEMarkerResolution#REMOVE_TYPE} to delete + * lines + */ + public ExtraneousLinesResolution(int type, IMarker marker) { + super(type, marker); + } + + /** + * Resolves the problem by extracting the empty line and removing it. + */ + @Override + protected void createChange(BundleModel model) { + IDocument doc = model.getDocument(); + int line = 0; + try { + String emptyLines = (String) marker.getAttribute(PDEMarkerFactory.EMPTY_LINE); + StringTokenizer st = new StringTokenizer(emptyLines, ","); //$NON-NLS-1$ + while (st.hasMoreElements()) { + line = Integer.parseInt(st.nextToken()); + IRegion l = doc.getLineInformation(line); + doc.replace(l.getOffset(), l.getLength() + 1, ""); //$NON-NLS-1$ + } + } catch (BadLocationException | CoreException | NumberFormatException e) { + PDEPlugin.log(e); + } + } + + @Override + public String getDescription() { + return PDEUIMessages.ExtraneousLineResolutionRemove_description; + } + + @Override + public String getLabel() { + return PDEUIMessages.ExtraneousLineResolutionRemove_label; + } + +} diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/ResolutionGenerator.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/ResolutionGenerator.java index 2d5d69e0537..c597557cb3b 100644 --- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/ResolutionGenerator.java +++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/ResolutionGenerator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2022 IBM Corporation and others. + * Copyright (c) 2005, 2023 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -130,6 +130,9 @@ public IMarkerResolution[] getNonConfigSevResolutions(IMarker marker) { return new IMarkerResolution[] {new AddBundleClassPathMarkerResolution(AbstractPDEMarkerResolution.CREATE_TYPE, marker)}; case PDEMarkerFactory.M_LAZYLOADING_HAS_NO_EFFECT : return new IMarkerResolution[] {new RemoveLazyLoadingDirectiveResolution(AbstractPDEMarkerResolution.REMOVE_TYPE, marker.getAttribute("header", ICoreConstants.ECLIPSE_LAZYSTART), marker)}; //$NON-NLS-1$ + case PDEMarkerFactory.M_EXTRANEOUS_EMPTY_LINES: + return new IMarkerResolution[] { + new ExtraneousLinesResolution(AbstractPDEMarkerResolution.REMOVE_TYPE, marker) }; case PDEMarkerFactory.M_NO_LINE_TERMINATION : if (marker.getAttribute(PDEMarkerFactory.ATTR_HAS_CONTENT, true)) { return new IMarkerResolution[] {new NoLineTerminationResolution(AbstractPDEMarkerResolution.CREATE_TYPE,marker)}; diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/pderesources.properties b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/pderesources.properties index b7fc95737c7..463053ab428 100644 --- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/pderesources.properties +++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/pderesources.properties @@ -2353,6 +2353,8 @@ NoLineTerminationResolutionCreate_description=Adds a line break at the end of th NoLineTerminationResolutionCreate_label=Add a line break after the header NoLineTerminationResolutionRemove_description=Removes all whitespace characters from the last line of the manifest NoLineTerminationResolutionRemove_label=Remove excess whitespace from the end of the manifest +ExtraneousLineResolutionRemove_label=Remove extraneous lines +ExtraneousLineResolutionRemove_description=Removes extraneous lines in the manifest header OpenManifestsAction_title=Open Manifest OpenPluginManifestsAction_title=Plug-in Manifest Editor Error OpenManifestsAction_cannotFind=Cannot find manifest for {0}.