Navigation Menu

Skip to content

Commit

Permalink
Fix: CompilationUnit needs to trim all commonly used line delimiters
Browse files Browse the repository at this point in the history
Fix: If a file already exists, try sensing its line delimiter instead of
just using the preferences (e.g. for refactoring)
Fix: JavaDoc type references did not work when opening Unix delimited
files on Windows

Signed-off-by: Stefan Oehme <stefan.oehme@itemis.de>
  • Loading branch information
oehme committed Mar 24, 2014
1 parent 09c955d commit 1a87a70
Show file tree
Hide file tree
Showing 14 changed files with 240 additions and 141 deletions.
Expand Up @@ -94,7 +94,6 @@ import org.eclipse.xtext.common.types.util.TypeReferences
import org.eclipse.xtext.diagnostics.Severity
import org.eclipse.xtext.documentation.IEObjectDocumentationProvider
import org.eclipse.xtext.documentation.IFileHeaderProvider
import org.eclipse.xtext.formatting.IWhitespaceInformationProvider
import org.eclipse.xtext.resource.CompilerPhases
import org.eclipse.xtext.validation.EObjectDiagnosticImpl
import org.eclipse.xtext.xbase.XExpression
Expand All @@ -111,6 +110,7 @@ import org.eclipse.xtext.xbase.typesystem.references.OwnedConverter
import org.eclipse.xtext.xbase.typesystem.util.CommonTypeComputationServices
import org.eclipse.xtext.xtype.impl.XComputedTypeReferenceImplCustom
import org.eclipse.xtext.common.types.JvmArrayType
import org.eclipse.xtext.util.Strings

class CompilationUnitImpl implements CompilationUnit {

Expand Down Expand Up @@ -168,8 +168,6 @@ class CompilationUnitImpl implements CompilationUnit {
@Inject AbstractFileSystemSupport fileSystemSupport
@Inject FileLocations fileLocations

@Inject extension IWhitespaceInformationProvider

@Property val ProblemSupport problemSupport = new ProblemSupportImpl(this)
@Property val TypeReferenceProvider typeReferenceProvider = new TypeReferenceProviderImpl(this)
@Property val TypeLookupImpl typeLookup = new TypeLookupImpl(this)
Expand Down Expand Up @@ -587,14 +585,7 @@ class CompilationUnitImpl implements CompilationUnit {
}

protected def trimTrailingLinebreak(CharSequence sequence, EObject context) {
val lineBreak = context?.eResource?.URI?.lineSeparatorInformation?.lineSeparator
if(sequence != null
&& lineBreak != null
&& sequence.length >= lineBreak.length
&& lineBreak.equals(sequence.subSequence(sequence.length - lineBreak.length, sequence.length)))
sequence.subSequence(0, sequence.length - lineBreak.length)
else
sequence
Strings.trimTrailingLineBreak(sequence)
}

def void setCompilationStrategy(JvmField field, CompilationStrategy compilationStrategy) {
Expand Down
Expand Up @@ -150,9 +150,8 @@
import org.eclipse.xtext.diagnostics.Severity;
import org.eclipse.xtext.documentation.IEObjectDocumentationProvider;
import org.eclipse.xtext.documentation.IFileHeaderProvider;
import org.eclipse.xtext.formatting.ILineSeparatorInformation;
import org.eclipse.xtext.formatting.IWhitespaceInformationProvider;
import org.eclipse.xtext.resource.CompilerPhases;
import org.eclipse.xtext.util.Strings;
import org.eclipse.xtext.validation.EObjectDiagnosticImpl;
import org.eclipse.xtext.xbase.XExpression;
import org.eclipse.xtext.xbase.annotations.xAnnotations.XAnnotation;
Expand All @@ -164,7 +163,6 @@
import org.eclipse.xtext.xbase.lib.CollectionLiterals;
import org.eclipse.xtext.xbase.lib.Exceptions;
import org.eclipse.xtext.xbase.lib.ExclusiveRange;
import org.eclipse.xtext.xbase.lib.Extension;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ListExtensions;
Expand Down Expand Up @@ -272,10 +270,6 @@ public XtendFile getXtendFile() {
@Inject
private FileLocations fileLocations;

@Inject
@Extension
private IWhitespaceInformationProvider _iWhitespaceInformationProvider;

private final ProblemSupport _problemSupport = new ProblemSupportImpl(this);

public ProblemSupport getProblemSupport() {
Expand Down Expand Up @@ -1131,66 +1125,7 @@ public void setCompilationTemplate(final JvmExecutable executable, final StringC
}

protected CharSequence trimTrailingLinebreak(final CharSequence sequence, final EObject context) {
CharSequence _xblockexpression = null;
{
Resource _eResource = null;
if (context!=null) {
_eResource=context.eResource();
}
URI _uRI = null;
if (_eResource!=null) {
_uRI=_eResource.getURI();
}
ILineSeparatorInformation _lineSeparatorInformation = null;
if (_uRI!=null) {
_lineSeparatorInformation=this._iWhitespaceInformationProvider.getLineSeparatorInformation(_uRI);
}
String _lineSeparator = null;
if (_lineSeparatorInformation!=null) {
_lineSeparator=_lineSeparatorInformation.getLineSeparator();
}
final String lineBreak = _lineSeparator;
CharSequence _xifexpression = null;
boolean _and = false;
boolean _and_1 = false;
boolean _and_2 = false;
boolean _notEquals = (!Objects.equal(sequence, null));
if (!_notEquals) {
_and_2 = false;
} else {
boolean _notEquals_1 = (!Objects.equal(lineBreak, null));
_and_2 = _notEquals_1;
}
if (!_and_2) {
_and_1 = false;
} else {
int _length = sequence.length();
int _length_1 = lineBreak.length();
boolean _greaterEqualsThan = (_length >= _length_1);
_and_1 = _greaterEqualsThan;
}
if (!_and_1) {
_and = false;
} else {
int _length_2 = sequence.length();
int _length_3 = lineBreak.length();
int _minus = (_length_2 - _length_3);
int _length_4 = sequence.length();
CharSequence _subSequence = sequence.subSequence(_minus, _length_4);
boolean _equals = lineBreak.equals(_subSequence);
_and = _equals;
}
if (_and) {
int _length_5 = sequence.length();
int _length_6 = lineBreak.length();
int _minus_1 = (_length_5 - _length_6);
_xifexpression = sequence.subSequence(0, _minus_1);
} else {
_xifexpression = sequence;
}
_xblockexpression = _xifexpression;
}
return _xblockexpression;
return Strings.trimTrailingLineBreak(sequence);
}

public void setCompilationStrategy(final JvmField field, final CompilationStrategy compilationStrategy) {
Expand Down
Expand Up @@ -7,10 +7,17 @@
*******************************************************************************/
package org.eclipse.xtext.ui.editor.formatting;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.core.runtime.preferences.InstanceScope;
Expand All @@ -20,6 +27,7 @@
import org.eclipse.xtext.formatting.IWhitespaceInformationProvider;
import org.eclipse.xtext.ui.resource.IStorage2UriMapper;
import org.eclipse.xtext.util.Pair;
import org.eclipse.xtext.util.RuntimeIOException;

import com.google.inject.Inject;

Expand Down Expand Up @@ -52,6 +60,11 @@ public String getLineSeparator() {
}

protected String getLineSeparatorPreference(URI uri) {
if (uri.isPlatformResource()) {
IFile file = workspace.getRoot().getFile(new Path(uri.toPlatformString(true)));
String delimiter = senseLineDelimiter(file);
if (delimiter != null) return delimiter;
}
IProject project = null;
if (uri.isPlatformResource()) {
project = workspace.getRoot().getProject(uri.segment(1));
Expand All @@ -71,6 +84,48 @@ protected String getLineSeparatorPreference(URI uri) {
return result;
return System.getProperty("line.separator");
}

private String senseLineDelimiter(IFile file) {
if (file.exists()) {
InputStream content = null;
try {
content = file.getContents();
Reader reader = new InputStreamReader(content, file.getCharset());
int read;
boolean rFound = false;
while ((read = reader.read()) != -1) {
char c = (char) read;
if (c == '\n') {
if (rFound) {
return "\r\n";
} else {
return "\n";
}
}
if (rFound) {
return "\r";
}
if (c == '\r') {
rFound = true;
}
}
if (rFound) {
return "\r";
}
} catch (Exception e) {
throw new RuntimeIOException(e);
} finally {
try {
if (content != null) {
content.close();
}
} catch (IOException e) {
throw new RuntimeIOException(e);
}
}
}
return null;
}

protected String getLineSeparatorPreference(IScopeContext scopeContext) {
String lineDelimiter = Platform.getPreferencesService().getString(Platform.PI_RUNTIME,
Expand Down
Expand Up @@ -452,6 +452,29 @@ public static int countLineBreaks(CharSequence text) {
}
return result;
}

/**
* Assumes {@code '\r'}, {@code '\n'} or {@code '\r\n'} to be valid line breaks.
*
* @since 2.6
*/
public static CharSequence trimTrailingLineBreak(CharSequence s) {
if (s == null)
return null;
if (s.length() == 0)
return s;
if (s.charAt(s.length() - 1) == '\n') {
if (s.length() > 1 && s.charAt(s.length() - 2) == '\r') {
return s.subSequence(0, s.length() - 2);
}
return s.subSequence(0, s.length() - 1);
}
if (s.charAt(s.length() - 1) == '\r') {
return s.subSequence(0, s.length() - 1);
}
return s;
}


/**
* Counts the number of lines where {@link #separator} is assumed to be a valid line break.
Expand Down
@@ -1,3 +1,4 @@

/*******************************************************************************
* Copyright (c) 2012 itemis AG (http://www.itemis.eu) and others.
* All rights reserved. This program and the accompanying materials
Expand All @@ -23,21 +24,21 @@
*/
public class MultiLineJavaDocTypeReferenceProvider implements IJavaDocTypeReferenceProvider {

//TODO this does not work when opening a Unix-delimited file on a Windows machine
@Deprecated
protected String lineDelimiter = System.getProperty("line.separator");

public List<ReplaceRegion> computeTypeRefRegions(INode node) {
List<ReplaceRegion> regions = Lists.newArrayList();
Iterable<ILeafNode> leafNodes = node.getLeafNodes();
computeRegions(regions, leafNodes, LINK_TAG_WITH_SUFFIX, "#", " ", "}");
computeRegions(regions, leafNodes, SEE_TAG_WITH_SUFFIX, "#" , " ", lineDelimiter);
computeRegions(regions, leafNodes, LINK_TAG_WITH_SUFFIX, new String[]{"#", " ", "}"});
computeRegions(regions, leafNodes, SEE_TAG_WITH_SUFFIX, new String[]{"#" , " ", "\r", "\n"});
return regions;
}

public List<ReplaceRegion> computeParameterTypeRefRegions(INode node) {
List<ReplaceRegion> regions = Lists.newArrayList();
Iterable<ILeafNode> leafNodes = node.getLeafNodes();
computeRegions(regions, leafNodes, "@param ", " ", "-", lineDelimiter);
computeRegions(regions, leafNodes, "@param ", new String[]{" ", "-", "\r", "\n"});
return regions;
}

Expand All @@ -50,8 +51,23 @@ public List<ReplaceRegion> computeParameterTypeRefRegions(INode node) {
* @param end - end with highest precedence
* @param optionalEnd - end with lower precedence
* @param optionalEnd2 - end with lowest precedence
* @deprecated use {@link #computeRegions(List, Iterable, String, String...)}
*/
@Deprecated
protected void computeRegions(List<ReplaceRegion> regions, Iterable<ILeafNode> leafNodes, String toSearch, String end, String optionalEnd, String optionalEnd2) {
computeRegions(regions, leafNodes, toSearch, new String[]{end, optionalEnd, optionalEnd2});
}

/**
* Computes regions between a given string to search and different ends searched by their precedence
*
* @param regions - List to put new regions in
* @param leafNodes - nodes to search in
* @param toSearch - String to search
* @param ends - ends in decreasing precedence
* @since 2.6
*/
protected void computeRegions(List<ReplaceRegion> regions, Iterable<ILeafNode> leafNodes, String toSearch, String... ends) {
for (ILeafNode leafNode : leafNodes) {
String text = leafNode.getText();
int offset = leafNode.getOffset();
Expand All @@ -65,32 +81,30 @@ protected void computeRegions(List<ReplaceRegion> regions, Iterable<ILeafNode> l
beginIndex ++;
}
}
int endLink = -1;
if(end != null && endLink == -1)
endLink = text.indexOf(end, beginIndex);
if(optionalEnd != null && endLink == -1)
endLink = text.indexOf(optionalEnd, beginIndex);
if(optionalEnd2 != null){
int lastEndLink = text.indexOf(optionalEnd2, beginIndex);
if(lastEndLink != -1) {
if(endLink != -1){
if(endLink > lastEndLink)
endLink = lastEndLink;
int endIndex = -1;
for (int i = ends.length -1; i >= 0; i--) {
String end = ends[i];
int endCandidate = text.indexOf(end, beginIndex);
if (endCandidate != -1) {
if (endIndex == -1) {
endIndex = endCandidate;
} else {
endLink = lastEndLink;
if (endIndex > endCandidate) {
endIndex = endCandidate;
}
}
}
}
if (endLink == -1) {
if (endIndex == -1) {
break;
} else {
String simpleName = text.substring(beginIndex, endLink).replaceAll(" ", "");
String simpleName = text.substring(beginIndex, endIndex).replaceAll(" ", "");
if(simpleName.length() > 0 && simpleName.matches("[0-9a-zA-Z\\.\\$_]*")){
ReplaceRegion region = new ReplaceRegion(offset + beginIndex, simpleName.length(), simpleName);
regions.add(region);
}
}
position = text.indexOf(toSearch, endLink);
position = text.indexOf(toSearch, endIndex);
}
}
}
Expand Down

0 comments on commit 1a87a70

Please sign in to comment.