diff --git a/Jakefile.js b/Jakefile.js
index 5b93462d855..b025bba4087 100644
--- a/Jakefile.js
+++ b/Jakefile.js
@@ -820,7 +820,8 @@ var tslintRuleDir = "scripts/tslint";
var tslintRules = ([
"nextLineRule",
"noNullRule",
- "booleanTriviaRule"
+ "booleanTriviaRule",
+ "typeOperatorSpacingRule"
]);
var tslintRulesFiles = tslintRules.map(function(p) {
return path.join(tslintRuleDir, p + ".ts");
diff --git a/scripts/tslint/typeOperatorSpacingRule.ts b/scripts/tslint/typeOperatorSpacingRule.ts
new file mode 100644
index 00000000000..23925493340
--- /dev/null
+++ b/scripts/tslint/typeOperatorSpacingRule.ts
@@ -0,0 +1,29 @@
+///
+///
+
+
+export class Rule extends Lint.Rules.AbstractRule {
+ public static FAILURE_STRING = "The '|' and '&' operators must be surrounded by single spaces";
+
+ public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
+ return this.applyWithWalker(new TypeOperatorSpacingWalker(sourceFile, this.getOptions()));
+ }
+}
+
+class TypeOperatorSpacingWalker extends Lint.RuleWalker {
+ public visitNode(node: ts.Node) {
+ if (node.kind === ts.SyntaxKind.UnionType || node.kind === ts.SyntaxKind.IntersectionType) {
+ let types = (node).types;
+ let expectedStart = types[0].end + 2; // space, | or &
+ for (let i = 1; i < types.length; i++) {
+ let currentType = types[i];
+ if (expectedStart !== currentType.pos || currentType.getLeadingTriviaWidth() !== 1) {
+ const failure = this.createFailure(currentType.pos, currentType.getWidth(), Rule.FAILURE_STRING);
+ this.addFailure(failure);
+ }
+ expectedStart = currentType.end + 2;
+ }
+ }
+ super.visitNode(node);
+ }
+}
diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index b44924abd7d..cfbd7090f5e 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -7040,7 +7040,7 @@ namespace ts {
return node === conditional.whenTrue || node === conditional.whenFalse ? getApparentTypeOfContextualType(conditional) : undefined;
}
- function getContextualTypeForJsxExpression(expr: JsxExpression|JsxSpreadAttribute): Type {
+ function getContextualTypeForJsxExpression(expr: JsxExpression | JsxSpreadAttribute): Type {
// Contextual type only applies to JSX expressions that are in attribute assignments (not in 'Children' positions)
if (expr.parent.kind === SyntaxKind.JsxAttribute) {
let attrib = expr.parent;
@@ -7558,7 +7558,7 @@ namespace ts {
/**
* Returns true iff React would emit this tag name as a string rather than an identifier or qualified name
*/
- function isJsxIntrinsicIdentifier(tagName: Identifier|QualifiedName) {
+ function isJsxIntrinsicIdentifier(tagName: Identifier | QualifiedName) {
if (tagName.kind === SyntaxKind.QualifiedName) {
return false;
}
@@ -7644,7 +7644,7 @@ namespace ts {
/// If this is a class-based tag (otherwise returns undefined), returns the symbol of the class
/// type or factory function.
/// Otherwise, returns unknownSymbol.
- function getJsxElementTagSymbol(node: JsxOpeningLikeElement|JsxClosingElement): Symbol {
+ function getJsxElementTagSymbol(node: JsxOpeningLikeElement | JsxClosingElement): Symbol {
let flags: JsxFlags = JsxFlags.UnknownElement;
let links = getNodeLinks(node);
if (!links.resolvedSymbol) {
@@ -7657,7 +7657,7 @@ namespace ts {
}
return links.resolvedSymbol;
- function lookupIntrinsicTag(node: JsxOpeningLikeElement|JsxClosingElement): Symbol {
+ function lookupIntrinsicTag(node: JsxOpeningLikeElement | JsxClosingElement): Symbol {
let intrinsicElementsType = getJsxIntrinsicElementsType();
if (intrinsicElementsType !== unknownType) {
// Property case
@@ -7685,7 +7685,7 @@ namespace ts {
}
}
- function lookupClassTag(node: JsxOpeningLikeElement|JsxClosingElement): Symbol {
+ function lookupClassTag(node: JsxOpeningLikeElement | JsxClosingElement): Symbol {
let valueSymbol: Symbol = resolveJsxTagName(node);
// Look up the value in the current scope
@@ -7699,7 +7699,7 @@ namespace ts {
return valueSymbol || unknownSymbol;
}
- function resolveJsxTagName(node: JsxOpeningLikeElement|JsxClosingElement): Symbol {
+ function resolveJsxTagName(node: JsxOpeningLikeElement | JsxClosingElement): Symbol {
if (node.tagName.kind === SyntaxKind.Identifier) {
let tag = node.tagName;
let sym = getResolvedSymbol(tag);
@@ -15578,7 +15578,7 @@ namespace ts {
}
}
- function checkGrammarJsxElement(node: JsxOpeningElement|JsxSelfClosingElement) {
+ function checkGrammarJsxElement(node: JsxOpeningLikeElement) {
const seen: Map = {};
for (let attr of node.attributes) {
if (attr.kind === SyntaxKind.JsxSpreadAttribute) {
diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts
index 70ab3606c6c..32f40e7f180 100644
--- a/src/compiler/emitter.ts
+++ b/src/compiler/emitter.ts
@@ -1404,10 +1404,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
emit(span.literal);
}
- function jsxEmitReact(node: JsxElement|JsxSelfClosingElement) {
+ function jsxEmitReact(node: JsxElement | JsxSelfClosingElement) {
/// Emit a tag name, which is either '"div"' for lower-cased names, or
/// 'Div' for upper-cased or dotted names
- function emitTagName(name: Identifier|QualifiedName) {
+ function emitTagName(name: Identifier | QualifiedName) {
if (name.kind === SyntaxKind.Identifier && isIntrinsicJsxName((name).text)) {
write("\"");
emit(name);
@@ -1557,7 +1557,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
}
}
- function jsxEmitPreserve(node: JsxElement|JsxSelfClosingElement) {
+ function jsxEmitPreserve(node: JsxElement | JsxSelfClosingElement) {
function emitJsxAttribute(node: JsxAttribute) {
emit(node.name);
if (node.initializer) {
@@ -1572,7 +1572,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
write("}");
}
- function emitAttributes(attribs: NodeArray) {
+ function emitAttributes(attribs: NodeArray) {
for (let i = 0, n = attribs.length; i < n; i++) {
if (i > 0) {
write(" ");
@@ -1588,7 +1588,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
}
}
- function emitJsxOpeningOrSelfClosingElement(node: JsxOpeningElement|JsxSelfClosingElement) {
+ function emitJsxOpeningOrSelfClosingElement(node: JsxOpeningElement | JsxSelfClosingElement) {
write("<");
emit(node.tagName);
if (node.attributes.length > 0 || (node.kind === SyntaxKind.JsxSelfClosingElement)) {
@@ -7246,7 +7246,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
return emitTemplateSpan(node);
case SyntaxKind.JsxElement:
case SyntaxKind.JsxSelfClosingElement:
- return emitJsxElement(node);
+ return emitJsxElement(node);
case SyntaxKind.JsxText:
return emitJsxText(node);
case SyntaxKind.JsxExpression:
diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts
index fd9a09f7785..c4786e7b2da 100644
--- a/src/compiler/parser.ts
+++ b/src/compiler/parser.ts
@@ -3533,7 +3533,7 @@ namespace ts {
return result;
}
- function parseJsxOpeningOrSelfClosingElement(inExpressionContext: boolean): JsxOpeningElement|JsxSelfClosingElement {
+ function parseJsxOpeningOrSelfClosingElement(inExpressionContext: boolean): JsxOpeningElement | JsxSelfClosingElement {
let fullStart = scanner.getStartPos();
parseExpected(SyntaxKind.LessThanToken);
diff --git a/tests/webTestServer.ts b/tests/webTestServer.ts
index 6d3144eeaec..18a1f05d47b 100644
--- a/tests/webTestServer.ts
+++ b/tests/webTestServer.ts
@@ -5,6 +5,7 @@ import fs = require("fs");
import path = require("path");
import url = require("url");
import child_process = require("child_process");
+import os = require('os');
/// Command line processing ///
@@ -263,7 +264,20 @@ http.createServer(function (req: http.ServerRequest, res: http.ServerResponse) {
var browserPath: string;
if ((browser && browser === 'chrome')) {
- var defaultChromePath = "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe";
+ let defaultChromePath = "";
+ switch (os.platform()) {
+ case "win32":
+ case "win64":
+ defaultChromePath = "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe";
+ break;
+ case "linux":
+ defaultChromePath = "/opt/google/chrome/chrome"
+ break;
+ default:
+ console.log(`default Chrome location is unknown for platform '${os.platform()}'`);
+ break;
+ }
+
if (fs.existsSync(defaultChromePath)) {
browserPath = defaultChromePath;
} else {
diff --git a/tslint.json b/tslint.json
index 19ccd30ca9f..db10daa3fcc 100644
--- a/tslint.json
+++ b/tslint.json
@@ -38,6 +38,7 @@
"no-trailing-whitespace": true,
"no-inferrable-types": true,
"no-null": true,
- "boolean-trivia": true
+ "boolean-trivia": true,
+ "type-operator-spacing": true
}
}