mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into fixDeFaultOfFindAllRefsToMaster
Conflicts: src/compiler/checker.ts src/compiler/types.ts
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
/// <reference path='services.ts' />
|
||||
|
||||
/* @internal */
|
||||
module ts.BreakpointResolver {
|
||||
namespace ts.BreakpointResolver {
|
||||
/**
|
||||
* Get the breakpoint span in given sourceFile
|
||||
*/
|
||||
@@ -75,7 +75,7 @@ module ts.BreakpointResolver {
|
||||
return textSpan(node);
|
||||
}
|
||||
|
||||
if (node.parent.kind == SyntaxKind.ArrowFunction && (<FunctionLikeDeclaration>node.parent).body == node) {
|
||||
if (node.parent.kind === SyntaxKind.ArrowFunction && (<FunctionLikeDeclaration>node.parent).body === node) {
|
||||
// If this is body of arrow function, it is allowed to have the breakpoint
|
||||
return textSpan(node);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
///<reference path='references.ts' />
|
||||
|
||||
/* @internal */
|
||||
module ts.formatting {
|
||||
namespace ts.formatting {
|
||||
|
||||
export interface TextRangeWithKind extends TextRange {
|
||||
kind: SyntaxKind;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/// <reference path="references.ts"/>
|
||||
|
||||
/* @internal */
|
||||
module ts.formatting {
|
||||
namespace ts.formatting {
|
||||
export class FormattingContext {
|
||||
public currentTokenSpan: TextRangeWithKind;
|
||||
public nextTokenSpan: TextRangeWithKind;
|
||||
@@ -59,7 +59,7 @@ module ts.formatting {
|
||||
if (this.tokensAreOnSameLine === undefined) {
|
||||
let startLine = this.sourceFile.getLineAndCharacterOfPosition(this.currentTokenSpan.pos).line;
|
||||
let endLine = this.sourceFile.getLineAndCharacterOfPosition(this.nextTokenSpan.pos).line;
|
||||
this.tokensAreOnSameLine = (startLine == endLine);
|
||||
this.tokensAreOnSameLine = (startLine === endLine);
|
||||
}
|
||||
|
||||
return this.tokensAreOnSameLine;
|
||||
@@ -84,7 +84,7 @@ module ts.formatting {
|
||||
private NodeIsOnOneLine(node: Node): boolean {
|
||||
let startLine = this.sourceFile.getLineAndCharacterOfPosition(node.getStart(this.sourceFile)).line;
|
||||
let endLine = this.sourceFile.getLineAndCharacterOfPosition(node.getEnd()).line;
|
||||
return startLine == endLine;
|
||||
return startLine === endLine;
|
||||
}
|
||||
|
||||
private BlockIsOnOneLine(node: Node): boolean {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/// <reference path="references.ts"/>
|
||||
|
||||
/* @internal */
|
||||
module ts.formatting {
|
||||
namespace ts.formatting {
|
||||
export const enum FormattingRequestKind {
|
||||
FormatDocument,
|
||||
FormatSelection,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/// <reference path="..\..\compiler\scanner.ts"/>
|
||||
|
||||
/* @internal */
|
||||
module ts.formatting {
|
||||
namespace ts.formatting {
|
||||
let scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false);
|
||||
|
||||
export interface FormattingScanner {
|
||||
@@ -224,7 +224,7 @@ module ts.formatting {
|
||||
}
|
||||
|
||||
function isOnToken(): boolean {
|
||||
let current = (lastTokenInfo && lastTokenInfo.token.kind) || scanner.getToken();
|
||||
let current = (lastTokenInfo && lastTokenInfo.token.kind) || scanner.getToken();
|
||||
let startPos = (lastTokenInfo && lastTokenInfo.token.pos) || scanner.getStartPos();
|
||||
return startPos < endPos && current !== SyntaxKind.EndOfFileToken && !isTrivia(current);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
///<reference path='references.ts' />
|
||||
|
||||
/* @internal */
|
||||
module ts.formatting {
|
||||
namespace ts.formatting {
|
||||
export class Rule {
|
||||
constructor(
|
||||
public Descriptor: RuleDescriptor,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
///<reference path='references.ts' />
|
||||
|
||||
/* @internal */
|
||||
module ts.formatting {
|
||||
namespace ts.formatting {
|
||||
export const enum RuleAction {
|
||||
Ignore = 0x00000001,
|
||||
Space = 0x00000002,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
///<reference path='references.ts' />
|
||||
|
||||
/* @internal */
|
||||
module ts.formatting {
|
||||
namespace ts.formatting {
|
||||
export class RuleDescriptor {
|
||||
constructor(public LeftTokenRange: Shared.TokenRange, public RightTokenRange: Shared.TokenRange) {
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
|
||||
/* @internal */
|
||||
module ts.formatting {
|
||||
namespace ts.formatting {
|
||||
export const enum RuleFlags {
|
||||
None,
|
||||
CanDeleteNewLines
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
///<reference path='references.ts' />
|
||||
|
||||
/* @internal */
|
||||
module ts.formatting {
|
||||
namespace ts.formatting {
|
||||
export class RuleOperation {
|
||||
public Context: RuleOperationContext;
|
||||
public Action: RuleAction;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
///<reference path='references.ts' />
|
||||
|
||||
/* @internal */
|
||||
module ts.formatting {
|
||||
namespace ts.formatting {
|
||||
|
||||
export class RuleOperationContext {
|
||||
private customContextChecks: { (context: FormattingContext): boolean; }[];
|
||||
@@ -14,7 +14,7 @@ module ts.formatting {
|
||||
|
||||
|
||||
public IsAny(): boolean {
|
||||
return this == RuleOperationContext.Any;
|
||||
return this === RuleOperationContext.Any;
|
||||
}
|
||||
|
||||
public InContext(context: FormattingContext): boolean {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
///<reference path='references.ts' />
|
||||
|
||||
/* @internal */
|
||||
module ts.formatting {
|
||||
namespace ts.formatting {
|
||||
export class Rules {
|
||||
public getRuleName(rule: Rule) {
|
||||
let o: ts.Map<any> = <any>this;
|
||||
@@ -193,7 +193,7 @@ module ts.formatting {
|
||||
// Insert space after function keyword for anonymous functions
|
||||
public SpaceAfterAnonymousFunctionKeyword: Rule;
|
||||
public NoSpaceAfterAnonymousFunctionKeyword: Rule;
|
||||
|
||||
|
||||
// Insert space after @ in decorator
|
||||
public SpaceBeforeAt: Rule;
|
||||
public NoSpaceAfterAt: Rule;
|
||||
@@ -470,8 +470,9 @@ module ts.formatting {
|
||||
switch (context.contextNode.kind) {
|
||||
case SyntaxKind.BinaryExpression:
|
||||
case SyntaxKind.ConditionalExpression:
|
||||
case SyntaxKind.TypePredicate:
|
||||
return true;
|
||||
|
||||
|
||||
// equals in binding elements: function foo([[x, y] = [1, 2]])
|
||||
case SyntaxKind.BindingElement:
|
||||
// equals in type X = ...
|
||||
@@ -691,7 +692,7 @@ module ts.formatting {
|
||||
}
|
||||
|
||||
static IsNotFormatOnEnter(context: FormattingContext): boolean {
|
||||
return context.formattingRequestKind != FormattingRequestKind.FormatOnEnter;
|
||||
return context.formattingRequestKind !== FormattingRequestKind.FormatOnEnter;
|
||||
}
|
||||
|
||||
static IsModuleDeclContext(context: FormattingContext): boolean {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
///<reference path='references.ts' />
|
||||
|
||||
/* @internal */
|
||||
module ts.formatting {
|
||||
namespace ts.formatting {
|
||||
export class RulesMap {
|
||||
public map: RulesBucket[];
|
||||
public mapRowLength: number;
|
||||
@@ -41,15 +41,15 @@ module ts.formatting {
|
||||
}
|
||||
|
||||
private FillRule(rule: Rule, rulesBucketConstructionStateList: RulesBucketConstructionState[]): void {
|
||||
let specificRule = rule.Descriptor.LeftTokenRange != Shared.TokenRange.Any &&
|
||||
rule.Descriptor.RightTokenRange != Shared.TokenRange.Any;
|
||||
let specificRule = rule.Descriptor.LeftTokenRange !== Shared.TokenRange.Any &&
|
||||
rule.Descriptor.RightTokenRange !== Shared.TokenRange.Any;
|
||||
|
||||
rule.Descriptor.LeftTokenRange.GetTokens().forEach((left) => {
|
||||
rule.Descriptor.RightTokenRange.GetTokens().forEach((right) => {
|
||||
let rulesBucketIndex = this.GetRuleBucketIndex(left, right);
|
||||
|
||||
let rulesBucket = this.map[rulesBucketIndex];
|
||||
if (rulesBucket == undefined) {
|
||||
if (rulesBucket === undefined) {
|
||||
rulesBucket = this.map[rulesBucketIndex] = new RulesBucket();
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ module ts.formatting {
|
||||
public IncreaseInsertionIndex(maskPosition: RulesPosition): void {
|
||||
let value = (this.rulesInsertionIndexBitmap >> maskPosition) & Mask;
|
||||
value++;
|
||||
Debug.assert((value & Mask) == value, "Adding more rules into the sub-bucket than allowed. Maximum allowed is 32 rules.");
|
||||
Debug.assert((value & Mask) === value, "Adding more rules into the sub-bucket than allowed. Maximum allowed is 32 rules.");
|
||||
|
||||
let temp = this.rulesInsertionIndexBitmap & ~(Mask << maskPosition);
|
||||
temp |= value << maskPosition;
|
||||
@@ -147,7 +147,7 @@ module ts.formatting {
|
||||
public AddRule(rule: Rule, specificTokens: boolean, constructionState: RulesBucketConstructionState[], rulesBucketIndex: number): void {
|
||||
let position: RulesPosition;
|
||||
|
||||
if (rule.Operation.Action == RuleAction.Ignore) {
|
||||
if (rule.Operation.Action === RuleAction.Ignore) {
|
||||
position = specificTokens ?
|
||||
RulesPosition.IgnoreRulesSpecific :
|
||||
RulesPosition.IgnoreRulesAny;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/// <reference path="references.ts"/>
|
||||
|
||||
/* @internal */
|
||||
module ts.formatting {
|
||||
namespace ts.formatting {
|
||||
export class RulesProvider {
|
||||
private globalRules: Rules;
|
||||
private options: ts.FormatCodeOptions;
|
||||
@@ -25,6 +25,7 @@ module ts.formatting {
|
||||
}
|
||||
|
||||
public ensureUpToDate(options: ts.FormatCodeOptions) {
|
||||
// TODO: Should this be '==='?
|
||||
if (this.options == null || !ts.compareDataObjects(this.options, options)) {
|
||||
let activeRules = this.createActiveRules(options);
|
||||
let rulesMap = RulesMap.create(activeRules);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
///<reference path='..\services.ts' />
|
||||
|
||||
/* @internal */
|
||||
module ts.formatting {
|
||||
namespace ts.formatting {
|
||||
export module SmartIndenter {
|
||||
|
||||
const enum Value {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
///<reference path='references.ts' />
|
||||
|
||||
/* @internal */
|
||||
module ts.formatting {
|
||||
namespace ts.formatting {
|
||||
export module Shared {
|
||||
export interface ITokenAccess {
|
||||
GetTokens(): SyntaxKind[];
|
||||
@@ -54,7 +54,7 @@ module ts.formatting {
|
||||
}
|
||||
|
||||
public Contains(tokenValue: SyntaxKind): boolean {
|
||||
return tokenValue == this.token;
|
||||
return tokenValue === this.token;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ module ts.formatting {
|
||||
static AnyIncludingMultilineComments = TokenRange.FromTokens(TokenRange.Any.GetTokens().concat([SyntaxKind.MultiLineCommentTrivia]));
|
||||
static Keywords = TokenRange.FromRange(SyntaxKind.FirstKeyword, SyntaxKind.LastKeyword);
|
||||
static BinaryOperators = TokenRange.FromRange(SyntaxKind.FirstBinaryOperator, SyntaxKind.LastBinaryOperator);
|
||||
static BinaryKeywordOperators = TokenRange.FromTokens([SyntaxKind.InKeyword, SyntaxKind.InstanceOfKeyword, SyntaxKind.OfKeyword]);
|
||||
static BinaryKeywordOperators = TokenRange.FromTokens([SyntaxKind.InKeyword, SyntaxKind.InstanceOfKeyword, SyntaxKind.OfKeyword, SyntaxKind.IsKeyword]);
|
||||
static UnaryPrefixOperators = TokenRange.FromTokens([SyntaxKind.PlusPlusToken, SyntaxKind.MinusMinusToken, SyntaxKind.TildeToken, SyntaxKind.ExclamationToken]);
|
||||
static UnaryPrefixExpressions = TokenRange.FromTokens([SyntaxKind.NumericLiteral, SyntaxKind.Identifier, SyntaxKind.OpenParenToken, SyntaxKind.OpenBracketToken, SyntaxKind.OpenBraceToken, SyntaxKind.ThisKeyword, SyntaxKind.NewKeyword]);
|
||||
static UnaryPreincrementExpressions = TokenRange.FromTokens([SyntaxKind.Identifier, SyntaxKind.OpenParenToken, SyntaxKind.ThisKeyword, SyntaxKind.NewKeyword]);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* @internal */
|
||||
module ts.NavigateTo {
|
||||
namespace ts.NavigateTo {
|
||||
type RawNavigateToItem = { name: string; fileName: string; matchKind: PatternMatchKind; isCaseSensitive: boolean; declaration: Declaration };
|
||||
|
||||
export function getNavigateToItems(program: Program, cancellationToken: CancellationTokenObject, searchValue: string, maxResultCount: number): NavigateToItem[] {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/// <reference path='services.ts' />
|
||||
|
||||
/* @internal */
|
||||
module ts.NavigationBar {
|
||||
namespace ts.NavigationBar {
|
||||
export function getNavigationBarItems(sourceFile: SourceFile): ts.NavigationBarItem[] {
|
||||
// If the source file has any child items, then it included in the tree
|
||||
// and takes lexical ownership of all other top-level items.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* @internal */
|
||||
module ts {
|
||||
namespace ts {
|
||||
export module OutliningElementsCollector {
|
||||
export function collectElements(sourceFile: SourceFile): OutliningSpan[] {
|
||||
let elements: OutliningSpan[] = [];
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* @internal */
|
||||
module ts {
|
||||
namespace ts {
|
||||
// Note(cyrusn): this enum is ordered from strongest match type to weakest match type.
|
||||
export enum PatternMatchKind {
|
||||
exact,
|
||||
@@ -686,7 +686,7 @@ module ts {
|
||||
|
||||
if (charIsPunctuation(identifier.charCodeAt(i - 1)) ||
|
||||
charIsPunctuation(identifier.charCodeAt(i)) ||
|
||||
lastIsDigit != currentIsDigit ||
|
||||
lastIsDigit !== currentIsDigit ||
|
||||
hasTransitionFromLowerToUpper ||
|
||||
hasTransitionFromUpperToLower) {
|
||||
|
||||
@@ -757,7 +757,7 @@ module ts {
|
||||
// 3) HTMLDocument -> HTML, Document
|
||||
//
|
||||
// etc.
|
||||
if (index != wordStart &&
|
||||
if (index !== wordStart &&
|
||||
index + 1 < identifier.length) {
|
||||
let currentIsUpper = isUpperCaseLetter(identifier.charCodeAt(index));
|
||||
let nextIsLower = isLowerCaseLetter(identifier.charCodeAt(index + 1));
|
||||
|
||||
+125
-83
@@ -10,7 +10,7 @@
|
||||
/// <reference path='formatting\formatting.ts' />
|
||||
/// <reference path='formatting\smartIndenter.ts' />
|
||||
|
||||
module ts {
|
||||
namespace ts {
|
||||
/** The version of the language service API */
|
||||
export let servicesVersion = "0.4"
|
||||
|
||||
@@ -167,7 +167,7 @@ module ts {
|
||||
}
|
||||
|
||||
public getFullWidth(): number {
|
||||
return this.end - this.getFullStart();
|
||||
return this.end - this.pos;
|
||||
}
|
||||
|
||||
public getLeadingTriviaWidth(sourceFile?: SourceFile): number {
|
||||
@@ -735,7 +735,7 @@ module ts {
|
||||
public endOfFileToken: Node;
|
||||
|
||||
public amdDependencies: { name: string; path: string }[];
|
||||
public amdModuleName: string;
|
||||
public moduleName: string;
|
||||
public referencedFiles: FileReference[];
|
||||
|
||||
public syntacticDiagnostics: Diagnostic[];
|
||||
@@ -743,6 +743,7 @@ module ts {
|
||||
public parseDiagnostics: Diagnostic[];
|
||||
public bindDiagnostics: Diagnostic[];
|
||||
|
||||
public isDefaultLib: boolean;
|
||||
public hasNoDefaultLib: boolean;
|
||||
public externalModuleIndicator: Node; // The first node that causes this file to be an external module
|
||||
public nodeCount: number;
|
||||
@@ -960,6 +961,7 @@ module ts {
|
||||
log? (s: string): void;
|
||||
trace? (s: string): void;
|
||||
error? (s: string): void;
|
||||
useCaseSensitiveFileNames? (): boolean;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -971,6 +973,9 @@ module ts {
|
||||
|
||||
getSyntacticDiagnostics(fileName: string): Diagnostic[];
|
||||
getSemanticDiagnostics(fileName: string): Diagnostic[];
|
||||
|
||||
// TODO: Rename this to getProgramDiagnostics to better indicate that these are any
|
||||
// diagnostics present for the program level, and not just 'options' diagnostics.
|
||||
getCompilerOptionsDiagnostics(): Diagnostic[];
|
||||
|
||||
/**
|
||||
@@ -1632,12 +1637,12 @@ module ts {
|
||||
// at each language service public entry point, since we don't know when
|
||||
// set of scripts handled by the host changes.
|
||||
class HostCache {
|
||||
private fileNameToEntry: Map<HostFileInformation>;
|
||||
private fileNameToEntry: FileMap<HostFileInformation>;
|
||||
private _compilationSettings: CompilerOptions;
|
||||
|
||||
constructor(private host: LanguageServiceHost, private getCanonicalFileName: (fileName: string) => string) {
|
||||
constructor(private host: LanguageServiceHost, getCanonicalFileName: (fileName: string) => string) {
|
||||
// script id => script index
|
||||
this.fileNameToEntry = {};
|
||||
this.fileNameToEntry = createFileMap<HostFileInformation>(getCanonicalFileName);
|
||||
|
||||
// Initialize the list with the root file names
|
||||
let rootFileNames = host.getScriptFileNames();
|
||||
@@ -1653,10 +1658,6 @@ module ts {
|
||||
return this._compilationSettings;
|
||||
}
|
||||
|
||||
private normalizeFileName(fileName: string): string {
|
||||
return this.getCanonicalFileName(normalizeSlashes(fileName));
|
||||
}
|
||||
|
||||
private createEntry(fileName: string) {
|
||||
let entry: HostFileInformation;
|
||||
let scriptSnapshot = this.host.getScriptSnapshot(fileName);
|
||||
@@ -1668,15 +1669,16 @@ module ts {
|
||||
};
|
||||
}
|
||||
|
||||
return this.fileNameToEntry[this.normalizeFileName(fileName)] = entry;
|
||||
this.fileNameToEntry.set(fileName, entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
private getEntry(fileName: string): HostFileInformation {
|
||||
return lookUp(this.fileNameToEntry, this.normalizeFileName(fileName));
|
||||
return this.fileNameToEntry.get(fileName);
|
||||
}
|
||||
|
||||
private contains(fileName: string): boolean {
|
||||
return hasProperty(this.fileNameToEntry, this.normalizeFileName(fileName));
|
||||
return this.fileNameToEntry.contains(fileName);
|
||||
}
|
||||
|
||||
public getOrCreateEntry(fileName: string): HostFileInformation {
|
||||
@@ -1690,10 +1692,9 @@ module ts {
|
||||
public getRootFileNames(): string[] {
|
||||
let fileNames: string[] = [];
|
||||
|
||||
forEachKey(this.fileNameToEntry, key => {
|
||||
let entry = this.getEntry(key);
|
||||
if (entry) {
|
||||
fileNames.push(entry.hostFileName);
|
||||
this.fileNameToEntry.forEachValue(value => {
|
||||
if (value) {
|
||||
fileNames.push(value.hostFileName);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1765,8 +1766,10 @@ module ts {
|
||||
* Extra compiler options that will unconditionally be used bu this function are:
|
||||
* - isolatedModules = true
|
||||
* - allowNonTsExtensions = true
|
||||
* - noLib = true
|
||||
* - noResolve = true
|
||||
*/
|
||||
export function transpile(input: string, compilerOptions?: CompilerOptions, fileName?: string, diagnostics?: Diagnostic[]): string {
|
||||
export function transpile(input: string, compilerOptions?: CompilerOptions, fileName?: string, diagnostics?: Diagnostic[], moduleName?: string): string {
|
||||
let options = compilerOptions ? clone(compilerOptions) : getDefaultCompilerOptions();
|
||||
|
||||
options.isolatedModules = true;
|
||||
@@ -1774,15 +1777,23 @@ module ts {
|
||||
// Filename can be non-ts file.
|
||||
options.allowNonTsExtensions = true;
|
||||
|
||||
// Parse
|
||||
var inputFileName = fileName || "module.ts";
|
||||
var sourceFile = createSourceFile(inputFileName, input, options.target);
|
||||
// We are not returning a sourceFile for lib file when asked by the program,
|
||||
// so pass --noLib to avoid reporting a file not found error.
|
||||
options.noLib = true;
|
||||
|
||||
// Store syntactic diagnostics
|
||||
if (diagnostics && sourceFile.parseDiagnostics) {
|
||||
diagnostics.push(...sourceFile.parseDiagnostics);
|
||||
// We are not doing a full typecheck, we are not resolving the whole context,
|
||||
// so pass --noResolve to avoid reporting missing file errors.
|
||||
options.noResolve = true;
|
||||
|
||||
// Parse
|
||||
let inputFileName = fileName || "module.ts";
|
||||
let sourceFile = createSourceFile(inputFileName, input, options.target);
|
||||
if (moduleName) {
|
||||
sourceFile.moduleName = moduleName;
|
||||
}
|
||||
|
||||
let newLine = getNewLineCharacter(options);
|
||||
|
||||
// Output
|
||||
let outputText: string;
|
||||
|
||||
@@ -1797,14 +1808,13 @@ module ts {
|
||||
useCaseSensitiveFileNames: () => false,
|
||||
getCanonicalFileName: fileName => fileName,
|
||||
getCurrentDirectory: () => "",
|
||||
getNewLine: () => (sys && sys.newLine) || "\r\n"
|
||||
getNewLine: () => newLine
|
||||
};
|
||||
|
||||
var program = createProgram([inputFileName], options, compilerHost);
|
||||
|
||||
if (diagnostics) {
|
||||
diagnostics.push(...program.getGlobalDiagnostics());
|
||||
}
|
||||
addRange(/*to*/ diagnostics, /*from*/ program.getSyntacticDiagnostics(sourceFile));
|
||||
addRange(/*to*/ diagnostics, /*from*/ program.getOptionsDiagnostics());
|
||||
|
||||
// Emit
|
||||
program.emit();
|
||||
@@ -1873,20 +1883,28 @@ module ts {
|
||||
return createLanguageServiceSourceFile(sourceFile.fileName, scriptSnapshot, sourceFile.languageVersion, version, /*setNodeParents:*/ true);
|
||||
}
|
||||
|
||||
export function createDocumentRegistry(): DocumentRegistry {
|
||||
function createGetCanonicalFileName(useCaseSensitivefileNames: boolean): (fileName: string) => string {
|
||||
return useCaseSensitivefileNames
|
||||
? ((fileName) => fileName)
|
||||
: ((fileName) => fileName.toLowerCase());
|
||||
}
|
||||
|
||||
|
||||
export function createDocumentRegistry(useCaseSensitiveFileNames?: boolean): DocumentRegistry {
|
||||
// Maps from compiler setting target (ES3, ES5, etc.) to all the cached documents we have
|
||||
// for those settings.
|
||||
let buckets: Map<Map<DocumentRegistryEntry>> = {};
|
||||
let buckets: Map<FileMap<DocumentRegistryEntry>> = {};
|
||||
let getCanonicalFileName = createGetCanonicalFileName(!!useCaseSensitiveFileNames);
|
||||
|
||||
function getKeyFromCompilationSettings(settings: CompilerOptions): string {
|
||||
return "_" + settings.target; // + "|" + settings.propagateEnumConstantoString()
|
||||
}
|
||||
|
||||
function getBucketForCompilationSettings(settings: CompilerOptions, createIfMissing: boolean): Map<DocumentRegistryEntry> {
|
||||
function getBucketForCompilationSettings(settings: CompilerOptions, createIfMissing: boolean): FileMap<DocumentRegistryEntry> {
|
||||
let key = getKeyFromCompilationSettings(settings);
|
||||
let bucket = lookUp(buckets, key);
|
||||
if (!bucket && createIfMissing) {
|
||||
buckets[key] = bucket = {};
|
||||
buckets[key] = bucket = createFileMap<DocumentRegistryEntry>(getCanonicalFileName);
|
||||
}
|
||||
return bucket;
|
||||
}
|
||||
@@ -1896,7 +1914,7 @@ module ts {
|
||||
let entries = lookUp(buckets, name);
|
||||
let sourceFiles: { name: string; refCount: number; references: string[]; }[] = [];
|
||||
for (let i in entries) {
|
||||
let entry = entries[i];
|
||||
let entry = entries.get(i);
|
||||
sourceFiles.push({
|
||||
name: i,
|
||||
refCount: entry.languageServiceRefCount,
|
||||
@@ -1928,18 +1946,19 @@ module ts {
|
||||
acquiring: boolean): SourceFile {
|
||||
|
||||
let bucket = getBucketForCompilationSettings(compilationSettings, /*createIfMissing*/ true);
|
||||
let entry = lookUp(bucket, fileName);
|
||||
let entry = bucket.get(fileName);
|
||||
if (!entry) {
|
||||
Debug.assert(acquiring, "How could we be trying to update a document that the registry doesn't have?");
|
||||
|
||||
// Have never seen this file with these settings. Create a new source file for it.
|
||||
let sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, compilationSettings.target, version, /*setNodeParents:*/ false);
|
||||
|
||||
bucket[fileName] = entry = {
|
||||
entry = {
|
||||
sourceFile: sourceFile,
|
||||
languageServiceRefCount: 0,
|
||||
owners: []
|
||||
};
|
||||
bucket.set(fileName, entry);
|
||||
}
|
||||
else {
|
||||
// We have an entry for this file. However, it may be for a different version of
|
||||
@@ -1967,12 +1986,12 @@ module ts {
|
||||
let bucket = getBucketForCompilationSettings(compilationSettings, false);
|
||||
Debug.assert(bucket !== undefined);
|
||||
|
||||
let entry = lookUp(bucket, fileName);
|
||||
let entry = bucket.get(fileName);
|
||||
entry.languageServiceRefCount--;
|
||||
|
||||
Debug.assert(entry.languageServiceRefCount >= 0);
|
||||
if (entry.languageServiceRefCount === 0) {
|
||||
delete bucket[fileName];
|
||||
bucket.remove(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2400,9 +2419,7 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getCanonicalFileName(fileName: string) {
|
||||
return useCaseSensitivefileNames ? fileName : fileName.toLowerCase();
|
||||
}
|
||||
let getCanonicalFileName = createGetCanonicalFileName(useCaseSensitivefileNames);
|
||||
|
||||
function getValidSourceFile(fileName: string): SourceFile {
|
||||
fileName = normalizeSlashes(fileName);
|
||||
@@ -2776,7 +2793,7 @@ module ts {
|
||||
|
||||
function getCompilerOptionsDiagnostics() {
|
||||
synchronizeHostData();
|
||||
return program.getGlobalDiagnostics();
|
||||
return program.getOptionsDiagnostics().concat(program.getGlobalDiagnostics());
|
||||
}
|
||||
|
||||
/// Completion
|
||||
@@ -4168,7 +4185,7 @@ module ts {
|
||||
var result: DefinitionInfo[] = [];
|
||||
forEach((<UnionType>type).types, t => {
|
||||
if (t.symbol) {
|
||||
result.push(...getDefinitionFromSymbol(t.symbol, node));
|
||||
addRange(/*to*/ result, /*from*/ getDefinitionFromSymbol(t.symbol, node));
|
||||
}
|
||||
});
|
||||
return result;
|
||||
@@ -5756,7 +5773,8 @@ module ts {
|
||||
node = node.parent;
|
||||
}
|
||||
|
||||
return node.parent.kind === SyntaxKind.TypeReference || node.parent.kind === SyntaxKind.ExpressionWithTypeArguments;
|
||||
return node.parent.kind === SyntaxKind.TypeReference ||
|
||||
(node.parent.kind === SyntaxKind.ExpressionWithTypeArguments && !isExpressionWithTypeArgumentsInClassExtendsClause(<ExpressionWithTypeArguments>node.parent));
|
||||
}
|
||||
|
||||
function isNamespaceReference(node: Node): boolean {
|
||||
@@ -5937,6 +5955,7 @@ module ts {
|
||||
let typeChecker = program.getTypeChecker();
|
||||
|
||||
let result: number[] = [];
|
||||
let classifiableNames = program.getClassifiableNames();
|
||||
processNode(sourceFile);
|
||||
|
||||
return { spans: result, endOfLineState: EndOfLineState.None };
|
||||
@@ -5949,6 +5968,9 @@ module ts {
|
||||
|
||||
function classifySymbol(symbol: Symbol, meaningAtPosition: SemanticMeaning): ClassificationType {
|
||||
let flags = symbol.getFlags();
|
||||
if ((flags & SymbolFlags.Classifiable) === SymbolFlags.None) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (flags & SymbolFlags.Class) {
|
||||
return ClassificationType.className;
|
||||
@@ -5984,20 +6006,28 @@ module ts {
|
||||
*/
|
||||
function hasValueSideModule(symbol: Symbol): boolean {
|
||||
return forEach(symbol.declarations, declaration => {
|
||||
return declaration.kind === SyntaxKind.ModuleDeclaration && getModuleInstanceState(declaration) == ModuleInstanceState.Instantiated;
|
||||
return declaration.kind === SyntaxKind.ModuleDeclaration &&
|
||||
getModuleInstanceState(declaration) === ModuleInstanceState.Instantiated;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function processNode(node: Node) {
|
||||
// Only walk into nodes that intersect the requested span.
|
||||
if (node && textSpanIntersectsWith(span, node.getStart(), node.getWidth())) {
|
||||
if (node.kind === SyntaxKind.Identifier && node.getWidth() > 0) {
|
||||
let symbol = typeChecker.getSymbolAtLocation(node);
|
||||
if (symbol) {
|
||||
let type = classifySymbol(symbol, getMeaningFromLocation(node));
|
||||
if (type) {
|
||||
pushClassification(node.getStart(), node.getWidth(), type);
|
||||
if (node && textSpanIntersectsWith(span, node.getFullStart(), node.getFullWidth())) {
|
||||
if (node.kind === SyntaxKind.Identifier && !nodeIsMissing(node)) {
|
||||
let identifier = <Identifier>node;
|
||||
|
||||
// Only bother calling into the typechecker if this is an identifier that
|
||||
// could possibly resolve to a type name. This makes classification run
|
||||
// in a third of the time it would normally take.
|
||||
if (classifiableNames[identifier.text]) {
|
||||
let symbol = typeChecker.getSymbolAtLocation(node);
|
||||
if (symbol) {
|
||||
let type = classifySymbol(symbol, getMeaningFromLocation(node));
|
||||
if (type) {
|
||||
pushClassification(node.getStart(), node.getWidth(), type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6050,6 +6080,8 @@ module ts {
|
||||
function getEncodedSyntacticClassifications(fileName: string, span: TextSpan): Classifications {
|
||||
// doesn't use compiler - no need to synchronize with host
|
||||
let sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
|
||||
let spanStart = span.start;
|
||||
let spanLength = span.length;
|
||||
|
||||
// Make a scanner we can get trivia from.
|
||||
let triviaScanner = createScanner(ScriptTarget.Latest, /*skipTrivia:*/ false, sourceFile.text);
|
||||
@@ -6066,48 +6098,55 @@ module ts {
|
||||
result.push(type);
|
||||
}
|
||||
|
||||
function classifyLeadingTrivia(token: Node): void {
|
||||
let tokenStart = skipTrivia(sourceFile.text, token.pos, /*stopAfterLineBreak:*/ false);
|
||||
if (tokenStart === token.pos) {
|
||||
return;
|
||||
}
|
||||
|
||||
// token has trivia. Classify them appropriately.
|
||||
function classifyLeadingTriviaAndGetTokenStart(token: Node): number {
|
||||
triviaScanner.setTextPos(token.pos);
|
||||
while (true) {
|
||||
let start = triviaScanner.getTextPos();
|
||||
// only bother scanning if we have something that could be trivia.
|
||||
if (!couldStartTrivia(sourceFile.text, start)) {
|
||||
return start;
|
||||
}
|
||||
|
||||
let kind = triviaScanner.scan();
|
||||
let end = triviaScanner.getTextPos();
|
||||
let width = end - start;
|
||||
|
||||
// The moment we get something that isn't trivia, then stop processing.
|
||||
if (!isTrivia(kind)) {
|
||||
return;
|
||||
return start;
|
||||
}
|
||||
|
||||
// Don't bother with newlines/whitespace.
|
||||
if (kind === SyntaxKind.NewLineTrivia || kind === SyntaxKind.WhitespaceTrivia) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Only bother with the trivia if it at least intersects the span of interest.
|
||||
if (textSpanIntersectsWith(span, start, width)) {
|
||||
if (isComment(kind)) {
|
||||
classifyComment(token, kind, start, width);
|
||||
if (isComment(kind)) {
|
||||
classifyComment(token, kind, start, width);
|
||||
|
||||
// Classifying a comment might cause us to reuse the trivia scanner
|
||||
// (because of jsdoc comments). So after we classify the comment make
|
||||
// sure we set the scanner position back to where it needs to be.
|
||||
triviaScanner.setTextPos(end);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (kind === SyntaxKind.ConflictMarkerTrivia) {
|
||||
let text = sourceFile.text;
|
||||
let ch = text.charCodeAt(start);
|
||||
|
||||
// for the <<<<<<< and >>>>>>> markers, we just add them in as comments
|
||||
// in the classification stream.
|
||||
if (ch === CharacterCodes.lessThan || ch === CharacterCodes.greaterThan) {
|
||||
pushClassification(start, width, ClassificationType.comment);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (kind === SyntaxKind.ConflictMarkerTrivia) {
|
||||
let text = sourceFile.text;
|
||||
let ch = text.charCodeAt(start);
|
||||
|
||||
// for the <<<<<<< and >>>>>>> markers, we just add them in as comments
|
||||
// in the classification stream.
|
||||
if (ch === CharacterCodes.lessThan || ch === CharacterCodes.greaterThan) {
|
||||
pushClassification(start, width, ClassificationType.comment);
|
||||
continue;
|
||||
}
|
||||
|
||||
// for the ======== add a comment for the first line, and then lex all
|
||||
// subsequent lines up until the end of the conflict marker.
|
||||
Debug.assert(ch === CharacterCodes.equals);
|
||||
classifyDisabledMergeCode(text, start, end);
|
||||
}
|
||||
// for the ======== add a comment for the first line, and then lex all
|
||||
// subsequent lines up until the end of the conflict marker.
|
||||
Debug.assert(ch === CharacterCodes.equals);
|
||||
classifyDisabledMergeCode(text, start, end);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6226,12 +6265,14 @@ module ts {
|
||||
}
|
||||
|
||||
function classifyToken(token: Node): void {
|
||||
classifyLeadingTrivia(token);
|
||||
let tokenStart = classifyLeadingTriviaAndGetTokenStart(token);
|
||||
|
||||
if (token.getWidth() > 0) {
|
||||
let tokenWidth = token.end - tokenStart;
|
||||
Debug.assert(tokenWidth >= 0);
|
||||
if (tokenWidth > 0) {
|
||||
let type = classifyTokenType(token.kind, token);
|
||||
if (type) {
|
||||
pushClassification(token.getStart(), token.getWidth(), type);
|
||||
pushClassification(tokenStart, tokenWidth, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6336,9 +6377,10 @@ module ts {
|
||||
}
|
||||
|
||||
// Ignore nodes that don't intersect the original span to classify.
|
||||
if (textSpanIntersectsWith(span, element.getFullStart(), element.getFullWidth())) {
|
||||
if (decodedTextSpanIntersectsWith(spanStart, spanLength, element.pos, element.getFullWidth())) {
|
||||
let children = element.getChildren(sourceFile);
|
||||
for (let child of children) {
|
||||
for (let i = 0, n = children.length; i < n; i++) {
|
||||
let child = children[i];
|
||||
if (isToken(child)) {
|
||||
classifyToken(child);
|
||||
}
|
||||
|
||||
+31
-12
@@ -19,7 +19,7 @@
|
||||
var debugObjectHost = (<any>this);
|
||||
|
||||
/* @internal */
|
||||
module ts {
|
||||
namespace ts {
|
||||
export interface ScriptSnapshotShim {
|
||||
/** Gets a portion of the script snapshot specified by [start, end). */
|
||||
getText(start: number, end: number): string;
|
||||
@@ -56,6 +56,7 @@ module ts {
|
||||
getDefaultLibFileName(options: string): string;
|
||||
getNewLine?(): string;
|
||||
getProjectVersion?(): string;
|
||||
useCaseSensitiveFileNames?(): boolean;
|
||||
}
|
||||
|
||||
/** Public interface of the the of a config service shim instance.*/
|
||||
@@ -233,6 +234,7 @@ module ts {
|
||||
public getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange {
|
||||
var oldSnapshotShim = <ScriptSnapshotShimAdapter>oldSnapshot;
|
||||
var encoded = this.scriptSnapshotShim.getChangeRange(oldSnapshotShim.scriptSnapshotShim);
|
||||
// TODO: should this be '==='?
|
||||
if (encoded == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -245,16 +247,22 @@ module ts {
|
||||
|
||||
export class LanguageServiceShimHostAdapter implements LanguageServiceHost {
|
||||
private files: string[];
|
||||
private loggingEnabled = false;
|
||||
private tracingEnabled = false;
|
||||
|
||||
constructor(private shimHost: LanguageServiceShimHost) {
|
||||
}
|
||||
|
||||
public log(s: string): void {
|
||||
this.shimHost.log(s);
|
||||
if (this.loggingEnabled) {
|
||||
this.shimHost.log(s);
|
||||
}
|
||||
}
|
||||
|
||||
public trace(s: string): void {
|
||||
this.shimHost.trace(s);
|
||||
if (this.tracingEnabled) {
|
||||
this.shimHost.trace(s);
|
||||
}
|
||||
}
|
||||
|
||||
public error(s: string): void {
|
||||
@@ -270,8 +278,13 @@ module ts {
|
||||
return this.shimHost.getProjectVersion();
|
||||
}
|
||||
|
||||
public useCaseSensitiveFileNames(): boolean {
|
||||
return this.shimHost.useCaseSensitiveFileNames ? this.shimHost.useCaseSensitiveFileNames() : false;
|
||||
}
|
||||
|
||||
public getCompilationSettings(): CompilerOptions {
|
||||
var settingsJson = this.shimHost.getCompilationSettings();
|
||||
// TODO: should this be '==='?
|
||||
if (settingsJson == null || settingsJson == "") {
|
||||
throw Error("LanguageServiceShimHostAdapter.getCompilationSettings: empty compilationSettings");
|
||||
return null;
|
||||
@@ -344,15 +357,15 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
function simpleForwardCall(logger: Logger, actionDescription: string, action: () => any, noPerfLogging: boolean): any {
|
||||
if (!noPerfLogging) {
|
||||
function simpleForwardCall(logger: Logger, actionDescription: string, action: () => any, logPerformance: boolean): any {
|
||||
if (logPerformance) {
|
||||
logger.log(actionDescription);
|
||||
var start = Date.now();
|
||||
}
|
||||
|
||||
var result = action();
|
||||
|
||||
if (!noPerfLogging) {
|
||||
if (logPerformance) {
|
||||
var end = Date.now();
|
||||
logger.log(actionDescription + " completed in " + (end - start) + " msec");
|
||||
if (typeof (result) === "string") {
|
||||
@@ -367,9 +380,9 @@ module ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function forwardJSONCall(logger: Logger, actionDescription: string, action: () => any, noPerfLogging: boolean): string {
|
||||
function forwardJSONCall(logger: Logger, actionDescription: string, action: () => any, logPerformance: boolean): string {
|
||||
try {
|
||||
var result = simpleForwardCall(logger, actionDescription, action, noPerfLogging);
|
||||
var result = simpleForwardCall(logger, actionDescription, action, logPerformance);
|
||||
return JSON.stringify({ result: result });
|
||||
}
|
||||
catch (err) {
|
||||
@@ -408,6 +421,7 @@ module ts {
|
||||
|
||||
class LanguageServiceShimObject extends ShimBase implements LanguageServiceShim {
|
||||
private logger: Logger;
|
||||
private logPerformance = false;
|
||||
|
||||
constructor(factory: ShimFactory,
|
||||
private host: LanguageServiceShimHost,
|
||||
@@ -417,7 +431,7 @@ module ts {
|
||||
}
|
||||
|
||||
public forwardJSONCall(actionDescription: string, action: () => any): string {
|
||||
return forwardJSONCall(this.logger, actionDescription, action, /*noPerfLogging:*/ false);
|
||||
return forwardJSONCall(this.logger, actionDescription, action, this.logPerformance);
|
||||
}
|
||||
|
||||
/// DISPOSE
|
||||
@@ -806,6 +820,7 @@ module ts {
|
||||
|
||||
class ClassifierShimObject extends ShimBase implements ClassifierShim {
|
||||
public classifier: Classifier;
|
||||
private logPerformance = false;
|
||||
|
||||
constructor(factory: ShimFactory, private logger: Logger) {
|
||||
super(factory);
|
||||
@@ -815,7 +830,7 @@ module ts {
|
||||
public getEncodedLexicalClassifications(text: string, lexState: EndOfLineState, syntacticClassifierAbsent?: boolean): string {
|
||||
return forwardJSONCall(this.logger, "getEncodedLexicalClassifications",
|
||||
() => convertClassifications(this.classifier.getEncodedLexicalClassifications(text, lexState, syntacticClassifierAbsent)),
|
||||
/*noPerfLogging:*/ true);
|
||||
this.logPerformance);
|
||||
}
|
||||
|
||||
/// COLORIZATION
|
||||
@@ -833,13 +848,14 @@ module ts {
|
||||
}
|
||||
|
||||
class CoreServicesShimObject extends ShimBase implements CoreServicesShim {
|
||||
private logPerformance = false;
|
||||
|
||||
constructor(factory: ShimFactory, public logger: Logger, private host: CoreServicesShimHostAdapter) {
|
||||
super(factory);
|
||||
}
|
||||
|
||||
private forwardJSONCall(actionDescription: string, action: () => any): any {
|
||||
return forwardJSONCall(this.logger, actionDescription, action, /*noPerfLogging:*/ false);
|
||||
return forwardJSONCall(this.logger, actionDescription, action, this.logPerformance);
|
||||
}
|
||||
|
||||
public getPreProcessedFileInfo(fileName: string, sourceTextSnapshot: IScriptSnapshot): string {
|
||||
@@ -909,7 +925,7 @@ module ts {
|
||||
|
||||
export class TypeScriptServicesFactory implements ShimFactory {
|
||||
private _shims: Shim[] = [];
|
||||
private documentRegistry: DocumentRegistry = createDocumentRegistry();
|
||||
private documentRegistry: DocumentRegistry;
|
||||
|
||||
/*
|
||||
* Returns script API version.
|
||||
@@ -920,6 +936,9 @@ module ts {
|
||||
|
||||
public createLanguageServiceShim(host: LanguageServiceShimHost): LanguageServiceShim {
|
||||
try {
|
||||
if (this.documentRegistry === undefined) {
|
||||
this.documentRegistry = createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames());
|
||||
}
|
||||
var hostAdapter = new LanguageServiceShimHostAdapter(host);
|
||||
var languageService = createLanguageService(hostAdapter, this.documentRegistry);
|
||||
return new LanguageServiceShimObject(this, host, languageService);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
///<reference path='services.ts' />
|
||||
/* @internal */
|
||||
module ts.SignatureHelp {
|
||||
namespace ts.SignatureHelp {
|
||||
|
||||
// A partially written generic type expression is not guaranteed to have the correct syntax tree. the expression could be parsed as less than/greater than expression or a comma expression
|
||||
// or some other combination depending on what the user has typed so far. For the purposes of signature help we need to consider any location after "<" as a possible generic type reference.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// These utilities are common to multiple language service features.
|
||||
/* @internal */
|
||||
module ts {
|
||||
namespace ts {
|
||||
export interface ListItemInfo {
|
||||
listItemIndex: number;
|
||||
list: Node;
|
||||
@@ -502,7 +502,7 @@ module ts {
|
||||
|
||||
// Display-part writer helpers
|
||||
/* @internal */
|
||||
module ts {
|
||||
namespace ts {
|
||||
export function isFirstDeclarationOfSymbolParameter(symbol: Symbol) {
|
||||
return symbol.declarations && symbol.declarations.length > 0 && symbol.declarations[0].kind === SyntaxKind.Parameter;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user