Addition of the new flag "file-read-mode" into the analysis server to fix the offset bug with IntelliJs integration.

R=brianwilkerson@google.com, paulberry@google.com

Review URL: https://codereview.chromium.org//857283003

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@43028 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
jwren@google.com
2015-01-20 21:48:00 +00:00
parent f7915c7a84
commit 252c19c920
8 changed files with 122 additions and 6 deletions
+16
View File
@@ -173,6 +173,22 @@ dt.typeDefinition {
errors produced for all files in the actual analysis roots.
</dd>
</dl>
<dl>
<dt>--file-read-mode</dt>
<dd>
An enumeration of the ways files can be read from disk. Some clients
normalize end of line characters which would make the file offset and
range information incorrect. The default option is <tt>as-is</tt>, but
can also be set to <tt>normalize-eol-always</tt>. The default option
(<tt>as-is</tt>) reads files as they are on disk. The
<tt>normalize-eol-always</tt> option does the following:
<ul>
<li>'\r\n' is converted to '\n';</li>
<li>'\r' by itself is converted to '\n';</li>
<li>this happens regardless of the OS editor is running on.</li>
</ul>
</dd>
</dl>
</blockquote>
<h2 class="domain"><a name="domain_server">Domain: server</a></h2>
<p>
@@ -951,6 +951,7 @@ class AnalysisServerOptions {
bool enableIncrementalResolutionApi = false;
bool enableIncrementalResolutionValidation = false;
bool noErrorNotification = false;
String fileReadMode = 'as-is';
}
/**
+18 -1
View File
@@ -122,10 +122,15 @@ class Driver implements ServerStarter {
static const String SDK_OPTION = "sdk";
/**
* The name of the option used to disable error notifications.
* The name of the flag used to disable error notifications.
*/
static const String NO_ERROR_NOTIFICATION = "no-error-notification";
/**
* The name of the option used to set the file read mode.
*/
static const String FILE_READ_MODE = "file-read-mode";
/**
* The instrumentation server that is to be used by the analysis server.
*/
@@ -201,6 +206,7 @@ class Driver implements ServerStarter {
analysisServerOptions.enableIncrementalResolutionValidation =
results[INCREMENTAL_RESOLUTION_VALIDATION];
analysisServerOptions.noErrorNotification = results[NO_ERROR_NOTIFICATION];
analysisServerOptions.fileReadMode = results[FILE_READ_MODE];
_initIncrementalLogger(results[INCREMENTAL_RESOLUTION_LOG]);
@@ -328,6 +334,17 @@ class Driver implements ServerStarter {
help: "disable sending all analysis error notifications to the server",
defaultsTo: false,
negatable: false);
parser.addOption(
FILE_READ_MODE,
help: "an option of the ways files can be read from disk, " +
"some clients normalize end of line characters which would make " +
"the file offset and range information incorrect.",
allowed: ["as-is", "normalize-eol-always"],
allowedHelp: {
"as-is": "file contents are read as-is, no file changes occur",
"normalize-eol-always":
"file contents normalize the end of line characters to the single character new line `\n`"
}, defaultsTo: "as-is");
return parser;
}
+11 -2
View File
@@ -62,8 +62,17 @@ class SocketServer {
});
return;
}
PhysicalResourceProvider resourceProvider =
PhysicalResourceProvider.INSTANCE;
PhysicalResourceProvider resourceProvider;
if (analysisServerOptions.fileReadMode == 'as-is') {
resourceProvider = PhysicalResourceProvider.INSTANCE;
} else if (analysisServerOptions.fileReadMode == 'normalize-eol-always') {
resourceProvider =
new PhysicalResourceProvider(PhysicalResourceProvider.NORMALIZE_EOL_ALWAYS);
} else {
throw new Exception(
'File read mode was set to the unknown mode: $analysisServerOptions.fileReadMode');
}
analysisServer = new AnalysisServer(
serverChannel,
resourceProvider,
@@ -135,6 +135,22 @@
errors produced for all files in the actual analysis roots.
</dd>
</dl>
<dl>
<dt>--file-read-mode</dt>
<dd>
An enumeration of the ways files can be read from disk. Some clients
normalize end of line characters which would make the file offset and
range information incorrect. The default option is <tt>as-is</tt>, but
can also be set to <tt>normalize-eol-always</tt>. The default option
(<tt>as-is</tt>) reads files as they are on disk. The
<tt>normalize-eol-always</tt> option does the following:
<ul>
<li>'\r\n' is converted to '\n';</li>
<li>'\r' by itself is converted to '\n';</li>
<li>this happens regardless of the OS editor is running on.</li>
</ul>
</dd>
</dl>
</blockquote>
<domain name="server">
<p>
@@ -19,8 +19,12 @@ import 'file_system.dart';
* A `dart:io` based implementation of [ResourceProvider].
*/
class PhysicalResourceProvider implements ResourceProvider {
static final NORMALIZE_EOL_ALWAYS =
(String string) => string.replaceAll(new RegExp('\r\n?'), '\n');
static final PhysicalResourceProvider INSTANCE =
new PhysicalResourceProvider._();
new PhysicalResourceProvider(null);
/**
* The name of the directory containing plugin specific subfolders used to
@@ -28,7 +32,11 @@ class PhysicalResourceProvider implements ResourceProvider {
*/
static final String SERVER_DIR = ".dartServer";
PhysicalResourceProvider._();
PhysicalResourceProvider(String fileReadMode(String s)) {
if (fileReadMode != null) {
FileBasedSource.fileReadMode = fileReadMode;
}
}
@override
Context get pathContext => io.Platform.isWindows ? windows : posix;
@@ -87,6 +87,12 @@ class DirectoryBasedSourceContainer implements SourceContainer {
* Instances of the class `FileBasedSource` implement a source that represents a file.
*/
class FileBasedSource implements Source {
/**
* A function that changes the way that files are read off of disk.
*/
static Function fileReadMode = (String s) => s;
/**
* The URI from which this source was originally derived.
*/
@@ -146,7 +152,7 @@ class FileBasedSource implements Source {
TimestampedData<String> get contentsFromFile {
return new TimestampedData<String>(
file.lastModified(),
file.readAsStringSync());
fileReadMode(file.readAsStringSync()));
}
@override
@@ -9,6 +9,7 @@ library engine.all_the_rest_test;
import 'dart:collection';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator;
import 'package:analyzer/src/generated/constant.dart';
import 'package:analyzer/src/generated/element.dart';
@@ -7384,6 +7385,48 @@ class FileBasedSourceTest {
expect(source.shortName, "exist.dart");
}
void test_fileReadMode() {
expect(FileBasedSource.fileReadMode('a'), 'a');
expect(FileBasedSource.fileReadMode('a\n'), 'a\n');
expect(FileBasedSource.fileReadMode('ab'), 'ab');
expect(FileBasedSource.fileReadMode('abc'), 'abc');
expect(FileBasedSource.fileReadMode('a\nb'), 'a\nb');
expect(FileBasedSource.fileReadMode('a\rb'), 'a\rb');
expect(FileBasedSource.fileReadMode('a\r\nb'), 'a\r\nb');
}
void test_fileReadMode_changed() {
FileBasedSource.fileReadMode = (String s) => s + 'xyz';
expect(FileBasedSource.fileReadMode('a'), 'axyz');
expect(FileBasedSource.fileReadMode('a\n'), 'a\nxyz');
expect(FileBasedSource.fileReadMode('ab'), 'abxyz');
expect(FileBasedSource.fileReadMode('abc'), 'abcxyz');
FileBasedSource.fileReadMode = (String s) => s;
}
void test_fileReadMode_normalize_eol_always() {
FileBasedSource.fileReadMode =
PhysicalResourceProvider.NORMALIZE_EOL_ALWAYS;
expect(FileBasedSource.fileReadMode('a'), 'a');
// '\n' -> '\n' as first, last and only character
expect(FileBasedSource.fileReadMode('\n'), '\n');
expect(FileBasedSource.fileReadMode('a\n'), 'a\n');
expect(FileBasedSource.fileReadMode('\na'), '\na');
// '\r\n' -> '\n' as first, last and only character
expect(FileBasedSource.fileReadMode('\r\n'), '\n');
expect(FileBasedSource.fileReadMode('a\r\n'), 'a\n');
expect(FileBasedSource.fileReadMode('\r\na'), '\na');
// '\r' -> '\n' as first, last and only character
expect(FileBasedSource.fileReadMode('\r'), '\n');
expect(FileBasedSource.fileReadMode('a\r'), 'a\n');
expect(FileBasedSource.fileReadMode('\ra'), '\na');
FileBasedSource.fileReadMode = (String s) => s;
}
void test_hashCode() {
JavaFile file1 = FileUtilities2.createFile("/does/not/exist.dart");
JavaFile file2 = FileUtilities2.createFile("/does/not/exist.dart");