Fixed: [Issue 211] Multi-line imports are broken
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/hyperlinking/ProtobufHyperlinkDetector.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/hyperlinking/ProtobufHyperlinkDetector.java
index 88d2473..db92a2e 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/hyperlinking/ProtobufHyperlinkDetector.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/hyperlinking/ProtobufHyperlinkDetector.java
@@ -8,22 +8,23 @@
*/
package com.google.eclipse.protobuf.ui.editor.hyperlinking;
+import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.IMPORT__IMPORT_URI;
import static org.eclipse.emf.common.util.URI.createURI;
-import com.google.eclipse.protobuf.model.util.Imports;
-import com.google.eclipse.protobuf.protobuf.Import;
-import com.google.eclipse.protobuf.ui.editor.FileOpener;
-import com.google.inject.Inject;
-
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.text.*;
import org.eclipse.jface.text.hyperlink.*;
import org.eclipse.xtext.CrossReference;
+import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.resource.*;
import org.eclipse.xtext.ui.editor.hyperlinking.DefaultHyperlinkDetector;
import org.eclipse.xtext.ui.editor.model.IXtextDocument;
import org.eclipse.xtext.util.concurrent.IUnitOfWork;
+import com.google.eclipse.protobuf.model.util.*;
+import com.google.eclipse.protobuf.protobuf.Import;
+import com.google.eclipse.protobuf.ui.editor.FileOpener;
+import com.google.inject.Inject;
/**
* Represents an implementation of interface <code>{@link IHyperlinkDetector}</code> to find and convert
@@ -34,6 +35,7 @@
public class ProtobufHyperlinkDetector extends DefaultHyperlinkDetector {
private static final IHyperlink[] NO_HYPERLINKS = null;
+ @Inject private INodes nodes;
@Inject private EObjectAtOffsetHelper eObjectAtOffsetHelper;
@Inject private FileOpener fileOpener;
@Inject private Imports imports;
@@ -63,31 +65,15 @@
if (!imports.isResolved(anImport)) {
return NO_HYPERLINKS;
}
- String importUri = imports.uriAsEnteredByUser(anImport);
- if (importUri == null) {
+ INode importUriNode = nodes.firstNodeForFeature(anImport, IMPORT__IMPORT_URI);
+ int importUriLength = importUriNode.getLength();
+ if (importUriLength == 0) {
return NO_HYPERLINKS;
}
- IRegion importUriRegion;
- try {
- importUriRegion = importUriRegion(document, region.getOffset(), importUri);
- } catch (BadLocationException e) {
- return NO_HYPERLINKS;
- }
- if (importUriRegion == null) {
- return NO_HYPERLINKS;
- }
+ IRegion importUriRegion = new Region(importUriNode.getOffset(), importUriLength);
IHyperlink hyperlink = new ImportHyperlink(createURI(anImport.getImportURI()), importUriRegion, fileOpener);
return new IHyperlink[] { hyperlink };
}
});
}
-
- private IRegion importUriRegion(IXtextDocument document, int offset, String importUri) throws BadLocationException {
- int lineNumber = document.getLineOfOffset(offset);
- int lineLength = document.getLineLength(lineNumber);
- int lineOffset = document.getLineOffset(lineNumber);
- String line = document.get(lineOffset, lineLength);
- int uriIndex = line.indexOf(importUri);
- return new Region(lineOffset + uriIndex, importUri.length());
- }
}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/conversion/STRINGValueConverter.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/conversion/STRINGValueConverter.java
index a1a64a2..8176a2d 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/conversion/STRINGValueConverter.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/conversion/STRINGValueConverter.java
@@ -8,9 +8,11 @@
*/
package com.google.eclipse.protobuf.conversion;
-import static com.google.eclipse.protobuf.util.Strings.*;
+import static com.google.eclipse.protobuf.util.Strings.unquote;
import static org.eclipse.xtext.util.Strings.convertToJavaString;
+import java.util.Scanner;
+
import org.eclipse.xtext.conversion.ValueConverterException;
import org.eclipse.xtext.conversion.impl.AbstractLexerBasedConverter;
import org.eclipse.xtext.nodemodel.INode;
@@ -26,14 +28,14 @@
return null;
}
// TODO check if we really need to quote
- return '"' + convertToJavaString(removeLineBreaksFrom(value), false) + '"';
+ return '"' + toValue(value) + '"';
}
/**
* Creates a {@code String} from the given input, if the given input represents a multiple-line string.
* @param string the given input.
* @param node the parsed node including hidden parts.
- * @return the new integer.
+ * @return the new {@code String}.
* @throws ValueConverterException if the given input has illegal characters.
*/
@Override public String toValue(String string, INode node) throws ValueConverterException {
@@ -41,12 +43,22 @@
return null;
}
try {
- return convertToJavaString(unquote(removeLineBreaksFrom(string).trim()), true);
- } catch (IllegalArgumentException e) {
+ return toValue(string);
+ } catch (RuntimeException e) {
throw parsingError(string, node, e);
}
}
+ private String toValue(String string) {
+ StringBuilder valueBuilder = new StringBuilder();
+ Scanner scanner = new Scanner(string);
+ while (scanner.hasNextLine()) {
+ String line = scanner.nextLine();
+ valueBuilder.append(convertToJavaString(unquote(line.trim()), true));
+ }
+ return valueBuilder.toString();
+ }
+
private ValueConverterException parsingError(String string, INode node, Exception cause) {
return new ValueConverterException("Couldn't convert '" + string + "' to String.", node, cause);
}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/Imports.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/Imports.java
index d308b3f..a2b4e79 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/Imports.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/Imports.java
@@ -9,19 +9,19 @@
package com.google.eclipse.protobuf.model.util;
import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.IMPORT__IMPORT_URI;
-import static com.google.eclipse.protobuf.util.Strings.*;
-import static org.eclipse.xtext.util.Strings.*;
-
-import com.google.eclipse.protobuf.protobuf.Import;
-import com.google.eclipse.protobuf.resource.ResourceSets;
-import com.google.eclipse.protobuf.scoping.ProtoDescriptorProvider;
-import com.google.inject.Inject;
+import static org.eclipse.xtext.util.Strings.isEmpty;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.*;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.scoping.impl.ImportUriResolver;
+import com.google.eclipse.protobuf.conversion.STRINGValueConverter;
+import com.google.eclipse.protobuf.protobuf.Import;
+import com.google.eclipse.protobuf.resource.ResourceSets;
+import com.google.eclipse.protobuf.scoping.ProtoDescriptorProvider;
+import com.google.inject.Inject;
+
/**
* Utility methods related to imports.
*
@@ -31,6 +31,7 @@
@Inject private ProtoDescriptorProvider descriptorProvider;
@Inject private INodes nodes;
@Inject private ResourceSets resourceSets;
+ @Inject private STRINGValueConverter converter;
@Inject private ImportUriResolver uriResolver;
/**
@@ -81,7 +82,7 @@
if (text == null) {
return null;
}
- return convertToJavaString(unquote(removeLineBreaksFrom(text).trim()), true);
+ return converter.toValue(text, node);
}
/**
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/ProtobufQualifiedNameConverter.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/ProtobufQualifiedNameConverter.java
index ecc2601..6d736f4 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/ProtobufQualifiedNameConverter.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/ProtobufQualifiedNameConverter.java
@@ -8,6 +8,7 @@
*/
package com.google.eclipse.protobuf.naming;
+import static com.google.eclipse.protobuf.util.Strings.removeLineBreaksFrom;
import static org.eclipse.xtext.util.Strings.isEmpty;
import java.util.regex.Pattern;
@@ -15,7 +16,6 @@
import org.eclipse.xtext.naming.IQualifiedNameConverter.DefaultImpl;
import org.eclipse.xtext.naming.*;
-import com.google.eclipse.protobuf.util.Strings;
import com.google.inject.Singleton;
/**
@@ -39,7 +39,7 @@
if (isEmpty(s)) {
throw new IllegalArgumentException("Qualified name cannot be null or empty");
}
- String withoutLineBreaks = Strings.removeLineBreaksFrom(s);
+ String withoutLineBreaks = removeLineBreaksFrom(s);
String[] segments = delimiterPattern.split(withoutLineBreaks);
return QualifiedName.create(segments);
}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/Strings.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/Strings.java
index bcaf5fa..e29605e 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/Strings.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/Strings.java
@@ -8,10 +8,9 @@
*/
package com.google.eclipse.protobuf.util;
-import static java.util.regex.Pattern.compile;
import static org.eclipse.xtext.util.Strings.isEmpty;
-import java.util.regex.Pattern;
+import java.util.Scanner;
/**
* Utility methods related to {@code String}.s
@@ -19,8 +18,6 @@
* @author alruiz@google.com (Alex Ruiz)
*/
public final class Strings {
- private static final Pattern LINE_BREAK = compile("\"[\t\r\n]+\"|'[\t\r\n]+'");
-
/**
* Returns a {@code String} containing the given one in double quotes.
* @param s the given {@code String}, may be {@code null}.
@@ -64,7 +61,13 @@
if (isEmpty(s)) {
return s;
}
- return LINE_BREAK.matcher(s).replaceAll("");
+ StringBuilder valueBuilder = new StringBuilder();
+ Scanner scanner = new Scanner(s);
+ while (scanner.hasNextLine()) {
+ String line = scanner.nextLine();
+ valueBuilder.append(line.trim());
+ }
+ return valueBuilder.toString();
}
private Strings() {}
}