wire in getCompletions

This commit is contained in:
Mohamed Hegazy 2014-07-23 16:52:21 -07:00
parent 8eda35afa0
commit 346809ba2b
8 changed files with 365 additions and 86 deletions

View File

@ -63,7 +63,33 @@ module ts {
var diagnostics: Diagnostic[] = [];
var diagnosticsModified: boolean = false;
var checker: TypeChecker;
var checker: TypeChecker = {
getProgram: () => program,
getDiagnostics: getDiagnostics,
getGlobalDiagnostics: getGlobalDiagnostics,
getNodeCount: () => sum(program.getSourceFiles(), "nodeCount"),
getIdentifierCount: () => sum(program.getSourceFiles(), "identifierCount"),
getSymbolCount: () => sum(program.getSourceFiles(), "symbolCount"),
getTypeCount: () => typeCount,
checkProgram: checkProgram,
emitFiles: invokeEmitter,
getSymbolOfNode: getSymbolOfNode,
getParentOfSymbol: getParentOfSymbol,
getTypeOfSymbol: getTypeOfSymbol,
getDeclaredTypeOfSymbol: getDeclaredTypeOfSymbol,
getPropertiesOfType: getPropertiesOfType,
getSignaturesOfType: getSignaturesOfType,
getIndexTypeOfType: getIndexTypeOfType,
getReturnTypeOfSignature: getReturnTypeOfSignature,
resolveEntityName: resolveEntityName,
getSymbolsInScope: getSymbolsInScope,
getSymbolOfIdentifier: getSymbolOfIdentifier,
getTypeOfExpression: getTypeOfExpression,
typeToString: typeToString,
symbolToString: symbolToString,
writeTypeToTextWriter: writeTypeToTextWriter,
getAugmentedPropertiesOfApparentType: getAugmentedPropertiesOfApparentType
};
function addDiagnostic(diagnostic: Diagnostic) {
diagnostics.push(diagnostic);
@ -4784,14 +4810,6 @@ module ts {
return (node.flags & NodeFlags.Private) && isInAmbientContext(node);
}
function isInAmbientContext(node: Node): boolean {
while (node) {
if (node.flags & (NodeFlags.Ambient | NodeFlags.DeclarationFile)) return true;
node = node.parent;
}
return false;
}
function checkSpecializedSignatureDeclaration(signatureDeclarationNode: SignatureDeclaration): void {
var signature = getSignatureFromDeclaration(signatureDeclarationNode);
if (!signature.hasStringLiterals) {
@ -6191,9 +6209,14 @@ module ts {
return false;
}
function isRightSideOfQualifiedName(node: Node) {
return (node.parent.kind === SyntaxKind.QualifiedName || node.parent.kind === SyntaxKind.PropertyAccess) &&
(<QualifiedName>node.parent).right === node;
}
function getSymbolOfIdentifier(identifier: Identifier) {
if (isExpression(identifier)) {
if (isRightSideOfQualifiedName()) {
if (isRightSideOfQualifiedName(identifier)) {
var node = <QualifiedName>identifier.parent;
var symbol = getNodeLinks(node).resolvedSymbol;
if (!symbol) {
@ -6207,16 +6230,58 @@ module ts {
return getSymbolOfNode(identifier.parent);
}
if (isTypeReferenceIdentifier(identifier)) {
var entityName = isRightSideOfQualifiedName() ? identifier.parent : identifier;
var entityName = isRightSideOfQualifiedName(identifier) ? identifier.parent : identifier;
var meaning = entityName.parent.kind === SyntaxKind.TypeReference ? SymbolFlags.Type : SymbolFlags.Namespace;
return resolveEntityName(entityName, entityName, meaning);
}
function isRightSideOfQualifiedName() {
return (identifier.parent.kind === SyntaxKind.QualifiedName || identifier.parent.kind === SyntaxKind.PropertyAccess) &&
(<QualifiedName>identifier.parent).right === identifier;
}
}
function getTypeOfExpression(node: Node) {
if (isExpression(node)) {
while (isRightSideOfQualifiedName(node)) {
node = node.parent;
}
return <Type>getApparentType(checkExpression(node));
}
return unknownType;
}
function getAugmentedPropertiesOfApparentType(type: Type): Symbol[]{
var apparentType = getApparentType(type);
if (apparentType.flags & TypeFlags.ObjectType) {
// Augment the apprent type with Function and Object memeber as applicaple
var propertiesByName: Map<Symbol> = {};
var results: Symbol[] = [];
forEach(getPropertiesOfType(apparentType), (s) => {
propertiesByName[s.name] = s;
results.push(s);
});
var resolved = resolveObjectTypeMembers(<ObjectType>type);
forEachValue(resolved.members, (s) => {
if (symbolIsValue(s) && !propertiesByName[s.name]) {
propertiesByName[s.name] = s;
results.push(s);
}
});
if (resolved === anyFunctionType || resolved.callSignatures.length || resolved.constructSignatures.length) {
forEach(getPropertiesOfType(globalFunctionType), (s) => {
if (!propertiesByName[s.name]) {
propertiesByName[s.name] = s;
results.push(s);
}
});
}
return results;
}
else {
return getPropertiesOfType(<Type>apparentType);
}
}
// Emitter support
function isExternalModuleSymbol(symbol: Symbol): boolean {
@ -6410,32 +6475,7 @@ module ts {
}
initializeTypeChecker();
checker = {
getProgram: () => program,
getDiagnostics: getDiagnostics,
getGlobalDiagnostics: getGlobalDiagnostics,
getNodeCount: () => sum(program.getSourceFiles(), "nodeCount"),
getIdentifierCount: () => sum(program.getSourceFiles(), "identifierCount"),
getSymbolCount: () => sum(program.getSourceFiles(), "symbolCount"),
getTypeCount: () => typeCount,
checkProgram: checkProgram,
emitFiles: invokeEmitter,
getSymbolOfNode: getSymbolOfNode,
getParentOfSymbol: getParentOfSymbol,
getTypeOfSymbol: getTypeOfSymbol,
getDeclaredTypeOfSymbol: getDeclaredTypeOfSymbol,
getPropertiesOfType: getPropertiesOfType,
getSignaturesOfType: getSignaturesOfType,
getIndexTypeOfType: getIndexTypeOfType,
getReturnTypeOfSignature: getReturnTypeOfSignature,
resolveEntityName: resolveEntityName,
getSymbolsInScope: getSymbolsInScope,
getSymbolOfIdentifier: getSymbolOfIdentifier,
getTypeOfExpression: checkExpression,
typeToString: typeToString,
symbolToString: symbolToString,
writeTypeToTextWriter: writeTypeToTextWriter
};
return checker;
}
}

View File

@ -327,6 +327,14 @@ module ts {
return s.parameters.length > 0 && (s.parameters[s.parameters.length - 1].flags & NodeFlags.Rest) !== 0;
}
export function isInAmbientContext(node: Node): boolean {
while (node) {
if (node.flags & (NodeFlags.Ambient | NodeFlags.DeclarationFile)) return true;
node = node.parent;
}
return false;
}
enum ParsingContext {
SourceElements, // Elements in source file
ModuleElements, // Elements in module declaration

View File

@ -603,6 +603,7 @@ module ts {
typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string;
symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): string;
writeTypeToTextWriter(type: Type, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: TextWriter): void;
getAugmentedPropertiesOfApparentType(type: Type): Symbol[];
}
export interface TextWriter {

View File

@ -9,46 +9,46 @@ module TypeScript.Services {
return new TextSpan(start(ast), width(ast));
}
private static symbolDeclarationIntersectsPosition(symbol: PullSymbol, fileName: string, position: number) {
var decl = symbol.getDeclarations()[0];
if (decl.fileName() === fileName && this.getSpan(decl.ast()).intersectsWithPosition(position)) {
// This is the symbol declaration from the given position in the file
return true;
}
//private static symbolDeclarationIntersectsPosition(symbol: PullSymbol, fileName: string, position: number) {
// var decl = symbol.getDeclarations()[0];
// if (decl.fileName() === fileName && this.getSpan(decl.ast()).intersectsWithPosition(position)) {
// // This is the symbol declaration from the given position in the file
// return true;
// }
return false;
}
// return false;
//}
public static filterContextualMembersList(contextualMemberSymbols: TypeScript.PullSymbol[], existingMembers: TypeScript.PullVisibleSymbolsInfo, fileName: string, position: number): TypeScript.PullSymbol[] {
if (!existingMembers || !existingMembers.symbols || existingMembers.symbols.length === 0) {
return contextualMemberSymbols;
}
//public static filterContextualMembersList(contextualMemberSymbols: TypeScript.PullSymbol[], existingMembers: TypeScript.PullVisibleSymbolsInfo, fileName: string, position: number): TypeScript.PullSymbol[] {
// if (!existingMembers || !existingMembers.symbols || existingMembers.symbols.length === 0) {
// return contextualMemberSymbols;
// }
var existingMemberSymbols = existingMembers.symbols;
var existingMemberNames = TypeScript.createIntrinsicsObject<boolean>();
for (var i = 0, n = existingMemberSymbols.length; i < n; i++) {
if (this.symbolDeclarationIntersectsPosition(existingMemberSymbols[i], fileName, position)) {
// If this is the current item we are editing right now, do not filter it out
continue;
}
// var existingMemberSymbols = existingMembers.symbols;
// var existingMemberNames = TypeScript.createIntrinsicsObject<boolean>();
// for (var i = 0, n = existingMemberSymbols.length; i < n; i++) {
// if (this.symbolDeclarationIntersectsPosition(existingMemberSymbols[i], fileName, position)) {
// // If this is the current item we are editing right now, do not filter it out
// continue;
// }
existingMemberNames[TypeScript.stripStartAndEndQuotes(existingMemberSymbols[i].getDisplayName())] = true;
}
// existingMemberNames[TypeScript.stripStartAndEndQuotes(existingMemberSymbols[i].getDisplayName())] = true;
// }
var filteredMembers: TypeScript.PullSymbol[] = [];
for (var j = 0, m = contextualMemberSymbols.length; j < m; j++) {
var contextualMemberSymbol = contextualMemberSymbols[j];
if (!existingMemberNames[TypeScript.stripStartAndEndQuotes(contextualMemberSymbol.getDisplayName())]) {
if (this.symbolDeclarationIntersectsPosition(contextualMemberSymbol, fileName, position)) {
// If this contextual member symbol was created as part of editing the current position, do not use it
continue;
}
filteredMembers.push(contextualMemberSymbol);
}
}
// var filteredMembers: TypeScript.PullSymbol[] = [];
// for (var j = 0, m = contextualMemberSymbols.length; j < m; j++) {
// var contextualMemberSymbol = contextualMemberSymbols[j];
// if (!existingMemberNames[TypeScript.stripStartAndEndQuotes(contextualMemberSymbol.getDisplayName())]) {
// if (this.symbolDeclarationIntersectsPosition(contextualMemberSymbol, fileName, position)) {
// // If this contextual member symbol was created as part of editing the current position, do not use it
// continue;
// }
// filteredMembers.push(contextualMemberSymbol);
// }
// }
return filteredMembers;
}
// return filteredMembers;
//}
public static isCompletionListBlocker(sourceUnit: TypeScript.SourceUnitSyntax, position: number): boolean {
// We shouldn't be getting a possition that is outside the file because
@ -173,7 +173,7 @@ module TypeScript.Services {
return false;
}
public static getValidCompletionEntryDisplayName(displayName: string): string {
public static getValidCompletionEntryDisplayName(displayName: string, target: ts.ScriptTarget): string {
if (displayName && displayName.length > 0) {
var firstChar = displayName.charCodeAt(0);
if (firstChar === TypeScript.CharacterCodes.singleQuote || firstChar === TypeScript.CharacterCodes.doubleQuote) {
@ -182,7 +182,7 @@ module TypeScript.Services {
displayName = TypeScript.stripStartAndEndQuotes(displayName);
}
if (TypeScript.Scanner.isValidIdentifier(TypeScript.SimpleText.fromString(displayName), TypeScript.LanguageVersion.EcmaScript5)) {
if (TypeScript.Scanner.isValidIdentifier(TypeScript.SimpleText.fromString(displayName), target)) {
return displayName;
}
}

View File

@ -53,15 +53,18 @@ module TypeScript.Services {
"with",
];
private static keywordCompletions: ResolvedCompletionEntry[] = null;
private static keywordCompletions: CompletionEntry[] = null;
public static getKeywordCompltions(): ResolvedCompletionEntry[]{
public static getKeywordCompltions(): CompletionEntry[]{
if (KeywordCompletions.keywordCompletions === null) {
var completions: ResolvedCompletionEntry[] = [];
var completions: CompletionEntry[] = [];
for (var i = 0, n = KeywordCompletions.keywords.length; i < n; i++) {
var keyword = KeywordCompletions.keywords[i];
var entry = new ResolvedCompletionEntry(/*name*/ keyword, ScriptElementKind.keyword, ScriptElementKindModifier.none, /*type*/null, /*fullName*/ keyword, /*docComment*/ null);
completions.push(entry);
completions.push({
name: keyword,
kind: ScriptElementKind.keyword,
kindModifiers: ScriptElementKindModifier.none
});
}
KeywordCompletions.keywordCompletions = completions;

View File

@ -7,6 +7,15 @@
/// <reference path="..\compiler\checker.ts"/>
module TypeScript.Services {
interface CompletionSession {
filename: string; // the file where the completion was requested
position: number; // position in the file where the completion was requested
entries: CompletionEntry[]; // entries for this completion
symbols: ts.Map<ts.Symbol>; // symbols by entry name map
location: ts.Node; // the node where the completion was requested
typeChecker: ts.TypeChecker;// the typeChecker used to generate this completion
}
// Information about a specific host file.
class HostFileInformation {
private _sourceText: TypeScript.IScriptSnapshot;
@ -420,6 +429,7 @@ module TypeScript.Services {
private documentsByName: ts.Map<Document> = {};
private documentRegistry: IDocumentRegistry
private cancellationToken: CancellationToken;
private activeCompletionSession: CompletionSession;
constructor(public host: ILanguageServiceHost, documentRegistry: IDocumentRegistry) {
this.logger = this.host;
@ -558,11 +568,206 @@ module TypeScript.Services {
this.synchronizeHostData();
return this.program.getGlobalDiagnostics();
}
private getCompletionEntriesFromSymbols(symbols: ts.Symbol[], session:CompletionSession): void {
ts.forEach(symbols, (symbol) => {
var entry = this.createCompletionEntry(symbol);
if (entry) {
session.entries.push(entry);
session.symbols[entry.name] = symbol;
}
});
}
private createCompletionEntry(symbol: ts.Symbol): CompletionEntry {
// Try to get a valid display name for this symbol, if we could not find one, then ignore it.
// We would like to only show things that can be added after a dot, so for instance numeric properties can
// not be accessed with a dot (a.1 <- invalid)
var displayName = CompletionHelpers.getValidCompletionEntryDisplayName(symbol.getName(), this.program.getCompilerOptions().target);
if (!displayName) {
return undefined;
}
var declarations = symbol.getDeclarations();
var firstDeclaration = [0];
return {
name: displayName,
kind: this.getSymbolKind(symbol),
kindModifiers: declarations ? this.getNodeModifiers(declarations[0]) : ScriptElementKindModifier.none
};
}
getCompletionsAtPosition(filename: string, position: number, isMemberCompletion: boolean) {
return undefined;
this.synchronizeHostData();
filename = TypeScript.switchToForwardSlashes(filename);
var document = this.documentsByName[filename];
var sourceUnit = document.sourceUnit();
if (CompletionHelpers.isCompletionListBlocker(document.syntaxTree().sourceUnit(), position)) {
this.logger.log("Returning an empty list because completion was blocked.");
return null;
}
var node = TypeScript.ASTHelpers.getAstAtPosition(sourceUnit, position, /*useTrailingTriviaAsLimChar*/ true, /*forceInclusive*/ true);
if (node && node.kind() === TypeScript.SyntaxKind.IdentifierName &&
start(node) === end(node)) {
// Ignore missing name nodes
node = node.parent;
}
var isRightOfDot = false;
if (node &&
node.kind() === TypeScript.SyntaxKind.MemberAccessExpression &&
end((<TypeScript.MemberAccessExpressionSyntax>node).expression) < position) {
isRightOfDot = true;
node = (<TypeScript.MemberAccessExpressionSyntax>node).expression;
}
else if (node &&
node.kind() === TypeScript.SyntaxKind.QualifiedName &&
end((<TypeScript.QualifiedNameSyntax>node).left) < position) {
isRightOfDot = true;
node = (<TypeScript.QualifiedNameSyntax>node).left;
}
else if (node && node.parent &&
node.kind() === TypeScript.SyntaxKind.IdentifierName &&
node.parent.kind() === TypeScript.SyntaxKind.MemberAccessExpression &&
(<TypeScript.MemberAccessExpressionSyntax>node.parent).name === node) {
isRightOfDot = true;
node = (<TypeScript.MemberAccessExpressionSyntax>node.parent).expression;
}
else if (node && node.parent &&
node.kind() === TypeScript.SyntaxKind.IdentifierName &&
node.parent.kind() === TypeScript.SyntaxKind.QualifiedName &&
(<TypeScript.QualifiedNameSyntax>node.parent).right === node) {
isRightOfDot = true;
node = (<TypeScript.QualifiedNameSyntax>node.parent).left;
}
// TODO: this is a hack for now, we need a proper walking mechanism to verify that we have the correct node
var mappedNode = this.getNodeAtPosition(document.sourceFile(), end(node) - 1);
Debug.assert(mappedNode, "Could not map a Fidelity node to an AST node");
// Get the completions
this.activeCompletionSession = {
filename: filename,
position: position,
entries: [],
symbols: {},
location: mappedNode,
typeChecker: this.typeChecker
};
// Right of dot member completion list
if (isRightOfDot) {
var type: ts.Type = this.typeChecker.getTypeOfExpression(mappedNode);
if (!type) {
return undefined;
}
var symbols = type.getApparentProperties();
isMemberCompletion = true;
this.getCompletionEntriesFromSymbols(symbols, this.activeCompletionSession);
}
else {
var containingObjectLiteral = CompletionHelpers.getContainingObjectLiteralApplicableForCompletion(document.syntaxTree().sourceUnit(), position);
// Object literal expression, look up possible property names from contextual type
if (containingObjectLiteral) {
var searchPosition = Math.min(position, end(containingObjectLiteral));
var path = TypeScript.ASTHelpers.getAstAtPosition(sourceUnit, searchPosition);
// Get the object literal node
while (node && node.kind() !== TypeScript.SyntaxKind.ObjectLiteralExpression) {
node = node.parent;
}
if (!node || node.kind() !== TypeScript.SyntaxKind.ObjectLiteralExpression) {
// AST Path look up did not result in the same node as Fidelity Syntax Tree look up.
// Once we remove AST this will no longer be a problem.
return null;
}
isMemberCompletion = true;
//// Try to get the object members form contextual typing
//var contextualMembers = this.compiler.getContextualMembersFromAST(node, document);
//if (contextualMembers && contextualMembers.symbols && contextualMembers.symbols.length > 0) {
// // get existing members
// var existingMembers = this.compiler.getVisibleMemberSymbolsFromAST(node, document);
// // Add filtterd items to the completion list
// this.getCompletionEntriesFromSymbols({
// symbols: CompletionHelpers.filterContextualMembersList(contextualMembers.symbols, existingMembers, filename, position),
// enclosingScopeSymbol: contextualMembers.enclosingScopeSymbol
// }, entries);
//}
}
// Get scope memebers
else {
isMemberCompletion = false;
/// TODO filter meaning based on the current context
var symbolMeanings = ts.SymbolFlags.Type | ts.SymbolFlags.Value | ts.SymbolFlags.Namespace;
var symbols = this.typeChecker.getSymbolsInScope(mappedNode, symbolMeanings);
this.getCompletionEntriesFromSymbols(symbols, this.activeCompletionSession);
}
}
// Add keywords if this is not a member completion list
if (!isMemberCompletion) {
Array.prototype.push.apply(this.activeCompletionSession.entries, KeywordCompletions.getKeywordCompltions());
}
return {
isMemberCompletion: isMemberCompletion,
entries: this.activeCompletionSession.entries
};
}
getCompletionEntryDetails(filename: string, position: number, entryName: string) {
return undefined;
// Note: No need to call synchronizeHostData, as we have captured all the data we need
// in the getCompletionsAtPosition erlier
filename = TypeScript.switchToForwardSlashes(filename);
var session = this.activeCompletionSession;
// Ensure that the current active completion session is still valid for this request
if (!session || session.filename !== filename || session.position !== position) {
return undefined;
}
var symbol = this.activeCompletionSession.symbols[entryName];
if (symbol) {
var type = session.typeChecker.getTypeOfSymbol(symbol);
Debug.assert(type, "Could not find type for symbol");
var completionEntry = this.createCompletionEntry(symbol);
return {
name: entryName,
kind: completionEntry.kind,
kindModifiers: completionEntry.kindModifiers,
type: session.typeChecker.typeToString(type, session.location),
fullSymbolName: this.typeChecker.symbolToString(symbol, session.location),
docComment: ""
};
}
else {
// No symbol, it is a keyword
return {
name: entryName,
kind: ScriptElementKind.keyword,
kindModifiers: ScriptElementKindModifier.none,
type: undefined,
fullSymbolName: entryName,
docComment: undefined
};
}
}
private getNodeAtPosition(sourceFile: ts.SourceFile, position: number) {
@ -581,7 +786,7 @@ module TypeScript.Services {
}
}
getEnclosingDeclaration(node: ts.Node): ts.Node {
private getEnclosingDeclaration(node: ts.Node): ts.Node {
while (true) {
node = node.parent;
if (!node) {
@ -601,10 +806,10 @@ module TypeScript.Services {
}
}
}
getSymbolKind(symbol: ts.Symbol): string {
var flags = symbol.getFlags();
if (flags & ts.SymbolFlags.Module) return ScriptElementKind.moduleElement;
if (flags & ts.SymbolFlags.Class) return ScriptElementKind.classElement;
if (flags & ts.SymbolFlags.Interface) return ScriptElementKind.interfaceElement;
@ -621,20 +826,36 @@ module TypeScript.Services {
if (flags & ts.SymbolFlags.Constructor) return ScriptElementKind.constructorImplementationElement;
if (flags & ts.SymbolFlags.TypeParameter) return ScriptElementKind.typeParameterElement;
if (flags & ts.SymbolFlags.EnumMember) return ScriptElementKind.variableElement;
return ScriptElementKind.unknown;
}
getTypeKind(type: ts.Type): string {
var flags = type.getFlags();
if (flags & ts.TypeFlags.Enum) return ScriptElementKind.enumElement;
if (flags & ts.TypeFlags.Class) return ScriptElementKind.classElement;
if (flags & ts.TypeFlags.Interface) return ScriptElementKind.interfaceElement;
if (flags & ts.TypeFlags.TypeParameter) return ScriptElementKind.typeParameterElement;
if (flags & ts.TypeFlags.Intrinsic) return ScriptElementKind.primitiveType;
if (flags & ts.TypeFlags.StringLiteral) return ScriptElementKind.primitiveType;
return ScriptElementKind.unknown;
}
getNodeModifiers(node: ts.Node): string {
var flags = node.flags;
var result: string[] = [];
if (flags & ts.NodeFlags.Private) result.push(ScriptElementKindModifier.privateMemberModifier);
if (flags & ts.NodeFlags.Public) result.push(ScriptElementKindModifier.publicMemberModifier);
if (flags & ts.NodeFlags.Static) result.push(ScriptElementKindModifier.staticModifier);
if (flags & ts.NodeFlags.Export) result.push(ScriptElementKindModifier.exportedModifier);
if (ts.isInAmbientContext(node)) result.push(ScriptElementKindModifier.ambientModifier);
return result.length > 0 ? result.join(',') : ScriptElementKindModifier.none;
}
getTypeAtPosition(filename: string, position: number): TypeInfo {
this.synchronizeHostData();

View File

@ -28,6 +28,7 @@ module ts {
getFlags(): TypeFlags;
getSymbol(): Symbol;
getProperties(): Symbol[];
getApparentProperties(): Symbol[];
getCallSignatures(): Signature[];
getConstructSignatures(): Signature[];
getStringIndexType(): Type;
@ -213,6 +214,9 @@ module ts {
getProperties(): Symbol[] {
return this.checker.getPropertiesOfType(this);
}
getApparentProperties(): Symbol[]{
return this.checker.getAugmentedPropertiesOfApparentType(this);
}
getCallSignatures(): Signature[] {
return this.checker.getSignaturesOfType(this, SignatureKind.Call);
}

View File

@ -34,6 +34,8 @@
/// <reference path='Breakpoints.ts' />
/// <reference path='indentation.ts' />
/// <reference path='formatting\formatting.ts' />
/// <reference path='completionHelpers.ts' />
/// <reference path='keywordCompletions.ts' />
/// <reference path='compiler\document.ts' />