merge with master, accepted baselines

This commit is contained in:
Vladimir Matveev
2015-03-17 17:05:30 -07:00
271 changed files with 5555 additions and 891 deletions
+7 -6
View File
@@ -322,13 +322,14 @@ module ts {
}
else {
bindDeclaration(node, SymbolFlags.ValueModule, SymbolFlags.ValueModuleExcludes, /*isBlockScopeContainer*/ true);
if (state === ModuleInstanceState.ConstEnumOnly) {
// mark value module as module that contains only enums
node.symbol.constEnumOnlyModule = true;
let currentModuleIsConstEnumOnly = state === ModuleInstanceState.ConstEnumOnly;
if (node.symbol.constEnumOnlyModule === undefined) {
// non-merged case - use the current state
node.symbol.constEnumOnlyModule = currentModuleIsConstEnumOnly;
}
else if (node.symbol.constEnumOnlyModule) {
// const only value module was merged with instantiated module - reset flag
node.symbol.constEnumOnlyModule = false;
else {
// merged case: module is const enum only if all its pieces are non-instantiated or const enum
node.symbol.constEnumOnlyModule = node.symbol.constEnumOnlyModule && currentModuleIsConstEnumOnly;
}
}
}
+107 -48
View File
@@ -79,8 +79,7 @@ module ts {
let emptyObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
let anyFunctionType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
let noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
let inferenceFailureType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
let anySignature = createSignature(undefined, undefined, emptyArray, anyType, 0, false, false);
let unknownSignature = createSignature(undefined, undefined, emptyArray, unknownType, 0, false, false);
@@ -797,7 +796,7 @@ module ts {
}
function getExportsForModule(moduleSymbol: Symbol): SymbolTable {
if (compilerOptions.target < ScriptTarget.ES6) {
if (languageVersion < ScriptTarget.ES6) {
// A default export hides all other exports in CommonJS and AMD modules
let defaultSymbol = getExportAssignmentSymbol(moduleSymbol);
if (defaultSymbol) {
@@ -3577,6 +3576,7 @@ module ts {
return t => {
for (let i = 0; i < context.typeParameters.length; i++) {
if (t === context.typeParameters[i]) {
context.inferences[i].isFixed = true;
return getInferredType(context, i);
}
}
@@ -4435,8 +4435,11 @@ module ts {
}
function reportNoCommonSupertypeError(types: Type[], errorLocation: Node, errorMessageChainHead: DiagnosticMessageChain): void {
// The downfallType/bestSupertypeDownfallType is the first type that caused a particular candidate
// to not be the common supertype. So if it weren't for this one downfallType (and possibly others),
// the type in question could have been the common supertype.
let bestSupertype: Type;
let bestSupertypeDownfallType: Type; // The type that caused bestSupertype not to be the common supertype
let bestSupertypeDownfallType: Type;
let bestSupertypeScore = 0;
for (let i = 0; i < types.length; i++) {
@@ -4451,6 +4454,8 @@ module ts {
}
}
Debug.assert(!!downfallType, "If there is no common supertype, each type should have a downfallType");
if (score > bestSupertypeScore) {
bestSupertype = types[i];
bestSupertypeDownfallType = downfallType;
@@ -4633,13 +4638,12 @@ module ts {
function createInferenceContext(typeParameters: TypeParameter[], inferUnionTypes: boolean): InferenceContext {
let inferences: TypeInferences[] = [];
for (let unused of typeParameters) {
inferences.push({ primary: undefined, secondary: undefined });
inferences.push({ primary: undefined, secondary: undefined, isFixed: false });
}
return {
typeParameters: typeParameters,
inferUnionTypes: inferUnionTypes,
inferenceCount: 0,
inferences: inferences,
typeParameters,
inferUnionTypes,
inferences,
inferredTypes: new Array(typeParameters.length),
};
}
@@ -4685,11 +4689,21 @@ module ts {
for (let i = 0; i < typeParameters.length; i++) {
if (target === typeParameters[i]) {
let inferences = context.inferences[i];
let candidates = inferiority ?
inferences.secondary || (inferences.secondary = []) :
inferences.primary || (inferences.primary = []);
if (!contains(candidates, source)) candidates.push(source);
break;
if (!inferences.isFixed) {
// Any inferences that are made to a type parameter in a union type are inferior
// to inferences made to a flat (non-union) type. This is because if we infer to
// T | string[], we really don't know if we should be inferring to T or not (because
// the correct constituent on the target side could be string[]). Therefore, we put
// such inferior inferences into a secondary bucket, and only use them if the primary
// bucket is empty.
let candidates = inferiority ?
inferences.secondary || (inferences.secondary = []) :
inferences.primary || (inferences.primary = []);
if (!contains(candidates, source)) {
candidates.push(source);
}
}
return;
}
}
}
@@ -4795,21 +4809,35 @@ module ts {
function getInferredType(context: InferenceContext, index: number): Type {
let inferredType = context.inferredTypes[index];
let inferenceSucceeded: boolean;
if (!inferredType) {
let inferences = getInferenceCandidates(context, index);
if (inferences.length) {
// Infer widened union or supertype, or the undefined type for no common supertype
// Infer widened union or supertype, or the unknown type for no common supertype
let unionOrSuperType = context.inferUnionTypes ? getUnionType(inferences) : getCommonSupertype(inferences);
inferredType = unionOrSuperType ? getWidenedType(unionOrSuperType) : inferenceFailureType;
inferredType = unionOrSuperType ? getWidenedType(unionOrSuperType) : unknownType;
inferenceSucceeded = !!unionOrSuperType;
}
else {
// Infer the empty object type when no inferences were made
// Infer the empty object type when no inferences were made. It is important to remember that
// in this case, inference still succeeds, meaning there is no error for not having inference
// candidates. An inference error only occurs when there are *conflicting* candidates, i.e.
// candidates with no common supertype.
inferredType = emptyObjectType;
inferenceSucceeded = true;
}
if (inferredType !== inferenceFailureType) {
// Only do the constraint check if inference succeeded (to prevent cascading errors)
if (inferenceSucceeded) {
let constraint = getConstraintOfTypeParameter(context.typeParameters[index]);
inferredType = constraint && !isTypeAssignableTo(inferredType, constraint) ? constraint : inferredType;
}
else if (context.failedTypeParameterIndex === undefined || context.failedTypeParameterIndex > index) {
// If inference failed, it is necessary to record the index of the failed type parameter (the one we are on).
// It might be that inference has already failed on a later type parameter on a previous call to inferTypeArguments.
// So if this failure is on preceding type parameter, this type parameter is the new failure index.
context.failedTypeParameterIndex = index;
}
context.inferredTypes[index] = inferredType;
}
return inferredType;
@@ -6406,11 +6434,32 @@ module ts {
return getSignatureInstantiation(signature, getInferredTypes(context));
}
function inferTypeArguments(signature: Signature, args: Expression[], excludeArgument: boolean[]): InferenceContext {
function inferTypeArguments(signature: Signature, args: Expression[], excludeArgument: boolean[], context: InferenceContext): void {
let typeParameters = signature.typeParameters;
let context = createInferenceContext(typeParameters, /*inferUnionTypes*/ false);
let inferenceMapper = createInferenceMapper(context);
// Clear out all the inference results from the last time inferTypeArguments was called on this context
for (let i = 0; i < typeParameters.length; i++) {
// As an optimization, we don't have to clear (and later recompute) inferred types
// for type parameters that have already been fixed on the previous call to inferTypeArguments.
// It would be just as correct to reset all of them. But then we'd be repeating the same work
// for the type parameters that were fixed, namely the work done by getInferredType.
if (!context.inferences[i].isFixed) {
context.inferredTypes[i] = undefined;
}
}
// On this call to inferTypeArguments, we may get more inferences for certain type parameters that were not
// fixed last time. This means that a type parameter that failed inference last time may succeed this time,
// or vice versa. Therefore, the failedTypeParameterIndex is useless if it points to an unfixed type parameter,
// because it may change. So here we reset it. However, getInferredType will not revisit any type parameters
// that were previously fixed. So if a fixed type parameter failed previously, it will fail again because
// it will contain the exact same set of inferences. So if we reset the index from a fixed type parameter,
// we will lose information that we won't recover this time around.
if (context.failedTypeParameterIndex !== undefined && !context.inferences[context.failedTypeParameterIndex].isFixed) {
context.failedTypeParameterIndex = undefined;
}
// We perform two passes over the arguments. In the first pass we infer from all arguments, but use
// wildcards for all context sensitive function expressions.
for (let i = 0; i < args.length; i++) {
@@ -6445,18 +6494,7 @@ module ts {
}
}
let inferredTypes = getInferredTypes(context);
// Inference has failed if the inferenceFailureType type is in list of inferences
context.failedTypeParameterIndex = indexOf(inferredTypes, inferenceFailureType);
// Wipe out the inferenceFailureType from the array so that error recovery can work properly
for (let i = 0; i < inferredTypes.length; i++) {
if (inferredTypes[i] === inferenceFailureType) {
inferredTypes[i] = unknownType;
}
}
return context;
getInferredTypes(context);
}
function checkTypeArguments(signature: Signature, typeArguments: TypeNode[], typeArgumentResultTypes: Type[], reportErrors: boolean): boolean {
@@ -6690,15 +6728,17 @@ module ts {
return resolveErrorCall(node);
function chooseOverload(candidates: Signature[], relation: Map<RelationComparisonResult>) {
for (let current of candidates) {
if (!hasCorrectArity(node, args, current)) {
for (let originalCandidate of candidates) {
if (!hasCorrectArity(node, args, originalCandidate)) {
continue;
}
let originalCandidate = current;
let inferenceResult: InferenceContext;
let candidate: Signature;
let typeArgumentsAreValid: boolean;
let inferenceContext = originalCandidate.typeParameters
? createInferenceContext(originalCandidate.typeParameters, /*inferUnionTypes*/ false)
: undefined;
while (true) {
candidate = originalCandidate;
if (candidate.typeParameters) {
@@ -6708,9 +6748,9 @@ module ts {
typeArgumentsAreValid = checkTypeArguments(candidate, typeArguments, typeArgumentTypes, /*reportErrors*/ false)
}
else {
inferenceResult = inferTypeArguments(candidate, args, excludeArgument);
typeArgumentsAreValid = inferenceResult.failedTypeParameterIndex < 0;
typeArgumentTypes = inferenceResult.inferredTypes;
inferTypeArguments(candidate, args, excludeArgument, inferenceContext);
typeArgumentsAreValid = inferenceContext.failedTypeParameterIndex === undefined;
typeArgumentTypes = inferenceContext.inferredTypes;
}
if (!typeArgumentsAreValid) {
break;
@@ -6740,7 +6780,7 @@ module ts {
else {
candidateForTypeArgumentError = originalCandidate;
if (!typeArguments) {
resultOfFailedInference = inferenceResult;
resultOfFailedInference = inferenceContext;
}
}
}
@@ -10116,6 +10156,12 @@ module ts {
}
}
}
else {
if (languageVersion >= ScriptTarget.ES6) {
// Import equals declaration is deprecated in es6 or above
grammarErrorOnNode(node, Diagnostics.Import_assignment_cannot_be_used_when_targeting_ECMAScript_6_or_higher_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_or_import_d_from_mod_instead);
}
}
}
}
@@ -10163,6 +10209,11 @@ module ts {
}
checkExternalModuleExports(container);
if (node.isExportEquals && languageVersion >= ScriptTarget.ES6) {
// export assignment is deprecated in es6 or above
grammarErrorOnNode(node, Diagnostics.Export_assignment_cannot_be_used_when_targeting_ECMAScript_6_or_higher_Consider_using_export_default_instead);
}
}
function getModuleStatements(node: Declaration): ModuleElement[] {
@@ -10205,7 +10256,7 @@ module ts {
if (!links.exportsChecked) {
let defaultSymbol = getExportAssignmentSymbol(moduleSymbol);
if (defaultSymbol) {
if (hasExportedMembers(moduleSymbol)) {
if (languageVersion < ScriptTarget.ES6 && hasExportedMembers(moduleSymbol)) {
let declaration = getDeclarationOfAliasSymbol(defaultSymbol) || defaultSymbol.valueDeclaration;
error(declaration, Diagnostics.An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements);
}
@@ -11028,7 +11079,15 @@ module ts {
function getExportNameSubstitution(symbol: Symbol, location: Node): string {
if (isExternalModuleSymbol(symbol.parent)) {
return "exports." + unescapeIdentifier(symbol.name);
var symbolName = unescapeIdentifier(symbol.name);
// If this is es6 or higher, just use the name of the export
// no need to qualify it.
if (languageVersion >= ScriptTarget.ES6) {
return symbolName;
}
else {
return "exports." + symbolName;
}
}
let node = location;
let containerSymbol = getParentOfSymbol(symbol);
@@ -11056,7 +11115,7 @@ module ts {
return getExportNameSubstitution(exportSymbol, node.parent);
}
// Named imports from ES6 import declarations are rewritten
if (symbol.flags & SymbolFlags.Alias) {
if (symbol.flags & SymbolFlags.Alias && languageVersion < ScriptTarget.ES6) {
return getAliasNameSubstitution(symbol);
}
}
@@ -11092,7 +11151,6 @@ module ts {
return true;
}
}
return forEachChild(node, isReferencedAliasDeclaration);
}
function isImplementationOfOverload(node: FunctionLikeDeclaration) {
@@ -12148,8 +12206,8 @@ module ts {
}
function checkGrammarTopLevelElementForRequiredDeclareModifier(node: Node): boolean {
// A declare modifier is required for any top level .d.ts declaration except export=, interfaces and imports:
// categories:
// A declare modifier is required for any top level .d.ts declaration except export=, export default,
// interfaces and imports categories:
//
// DeclarationElement:
// ExportAssignment
@@ -12163,7 +12221,8 @@ module ts {
node.kind === SyntaxKind.ImportEqualsDeclaration ||
node.kind === SyntaxKind.ExportDeclaration ||
node.kind === SyntaxKind.ExportAssignment ||
(node.flags & NodeFlags.Ambient)) {
(node.flags & NodeFlags.Ambient) ||
(node.flags & (NodeFlags.Export | NodeFlags.Default))) {
return false;
}
@@ -159,6 +159,9 @@ module ts {
Unterminated_Unicode_escape_sequence: { code: 1199, category: DiagnosticCategory.Error, key: "Unterminated Unicode escape sequence." },
Line_terminator_not_permitted_before_arrow: { code: 1200, category: DiagnosticCategory.Error, key: "Line terminator not permitted before arrow." },
A_type_annotation_on_an_export_statement_is_only_allowed_in_an_ambient_external_module_declaration: { code: 1201, category: DiagnosticCategory.Error, key: "A type annotation on an export statement is only allowed in an ambient external module declaration." },
Import_assignment_cannot_be_used_when_targeting_ECMAScript_6_or_higher_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_or_import_d_from_mod_instead: { code: 1202, category: DiagnosticCategory.Error, key: "Import assignment cannot be used when targeting ECMAScript 6 or higher. Consider using 'import * as ns from \"mod\"', 'import {a} from \"mod\"' or 'import d from \"mod\"' instead." },
Export_assignment_cannot_be_used_when_targeting_ECMAScript_6_or_higher_Consider_using_export_default_instead: { code: 1203, category: DiagnosticCategory.Error, key: "Export assignment cannot be used when targeting ECMAScript 6 or higher. Consider using 'export default' instead." },
Cannot_compile_external_modules_into_amd_or_commonjs_when_targeting_es6_or_higher: { code: 1204, category: DiagnosticCategory.Error, key: "Cannot compile external modules into amd or commonjs when targeting es6 or higher." },
Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." },
Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." },
Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." },
+12
View File
@@ -627,6 +627,18 @@
"category": "Error",
"code": 1201
},
"Import assignment cannot be used when targeting ECMAScript 6 or higher. Consider using 'import * as ns from \"mod\"', 'import {a} from \"mod\"' or 'import d from \"mod\"' instead.": {
"category": "Error",
"code": 1202
},
"Export assignment cannot be used when targeting ECMAScript 6 or higher. Consider using 'export default' instead.": {
"category": "Error",
"code": 1203
},
"Cannot compile external modules into amd or commonjs when targeting es6 or higher.": {
"category": "Error",
"code": 1204
},
"Duplicate identifier '{0}'.": {
"category": "Error",
+328 -89
View File
@@ -3492,7 +3492,7 @@ module ts {
}
function emitTaggedTemplateExpression(node: TaggedTemplateExpression): void {
if (compilerOptions.target >= ScriptTarget.ES6) {
if (languageVersion >= ScriptTarget.ES6) {
emit(node.tag);
write(" ");
emit(node.template);
@@ -4092,8 +4092,14 @@ module ts {
function emitModuleMemberName(node: Declaration) {
emitStart(node.name);
if (getCombinedNodeFlags(node) & NodeFlags.Export) {
emitContainingModuleName(node);
write(".");
var container = getContainingModule(node);
if (container) {
write(resolver.getGeneratedNameForNode(container));
write(".");
}
else if (languageVersion < ScriptTarget.ES6) {
write("exports.");
}
}
emitNodeWithoutSourceMap(node.name);
emitEnd(node.name);
@@ -4448,10 +4454,21 @@ module ts {
generatedBlockScopeNames[variableId] = generatedName;
}
function isES6ModuleMemberDeclaration(node: Node) {
return !!(node.flags & NodeFlags.Export) &&
languageVersion >= ScriptTarget.ES6 &&
node.parent.kind === SyntaxKind.SourceFile;
}
function emitVariableStatement(node: VariableStatement) {
if (!(node.flags & NodeFlags.Export)) {
emitStartOfVariableDeclarationList(node.declarationList);
}
else if (languageVersion >= ScriptTarget.ES6 && node.parent.kind === SyntaxKind.SourceFile) {
// Exported ES6 module member
write("export ");
emitStartOfVariableDeclarationList(node.declarationList);
}
emitCommaList(node.declarationList.declarations);
write(";");
if (languageVersion < ScriptTarget.ES6 && node.parent === currentSourceFile) {
@@ -4570,6 +4587,19 @@ module ts {
}
}
function shouldEmitFunctionName(node: Declaration): boolean {
// Emit a declaration name for the function iff:
// it is a function expression with a name provided
// it is a function declaration with a name provided
// it is a function declaration is not the default export, and is missing a name (emit a generated name for it)
if (node.kind === SyntaxKind.FunctionExpression) {
return !!node.name;
}
else if (node.kind === SyntaxKind.FunctionDeclaration) {
return !!node.name || (languageVersion >= ScriptTarget.ES6 && !(node.flags & NodeFlags.Default));
}
}
function emitFunctionDeclaration(node: FunctionLikeDeclaration) {
if (nodeIsMissing(node.body)) {
return emitPinnedOrTripleSlashComments(node);
@@ -4583,12 +4613,19 @@ module ts {
// For targeting below es6, emit functions-like declaration including arrow function using function keyword.
// When targeting ES6, emit arrow function natively in ES6 by omitting function keyword and using fat arrow instead
if (!shouldEmitAsArrowFunction(node)) {
if (isES6ModuleMemberDeclaration(node)) {
write("export ");
if (node.flags & NodeFlags.Default) {
write("default ");
}
}
write("function ");
}
if (node.kind === SyntaxKind.FunctionDeclaration || (node.kind === SyntaxKind.FunctionExpression && node.name)) {
if (shouldEmitFunctionName(node)) {
emitDeclarationName(node);
}
emitSignatureAndBody(node);
if (languageVersion < ScriptTarget.ES6 && node.kind === SyntaxKind.FunctionDeclaration && node.parent === currentSourceFile && node.name) {
emitExportMemberAssignments((<FunctionDeclaration>node).name);
@@ -4659,7 +4696,7 @@ module ts {
emitExpressionFunctionBody(node, <Expression>node.body);
}
if (node.flags & NodeFlags.Export && !(node.flags & NodeFlags.Default)) {
if (node.flags & NodeFlags.Export && !(node.flags & NodeFlags.Default) && !isES6ModuleMemberDeclaration(node)) {
writeLine();
emitStart(node);
emitModuleMemberName(node);
@@ -5094,7 +5131,7 @@ module ts {
}
function emitClassDeclarationForES6AndHigher(node: ClassDeclaration) {
if (node.flags & NodeFlags.Export) {
if (isES6ModuleMemberDeclaration(node)) {
write("export ");
if (node.flags & NodeFlags.Default) {
@@ -5103,7 +5140,10 @@ module ts {
}
write("class ");
emitDeclarationName(node);
// check if this is an "export default class" as it may not have a name
if (node.name || !(node.flags & NodeFlags.Default)) {
emitDeclarationName(node);
}
var baseTypeNode = getClassBaseTypeNode(node);
if (baseTypeNode) {
write(" extends ");
@@ -5127,6 +5167,18 @@ module ts {
// a lexical declaration such as a LexicalDeclaration or a ClassDeclaration.
writeLine();
emitMemberAssignments(node, NodeFlags.Static);
// If this is an exported class, but not on the top level (i.e. on an internal
// module), export it
if (!isES6ModuleMemberDeclaration(node) && (node.flags & NodeFlags.Export)) {
writeLine();
emitStart(node);
emitModuleMemberName(node);
write(" = ");
emitDeclarationName(node);
emitEnd(node);
write(";");
}
}
function emitClassDeclarationBelowES6(node: ClassDeclaration) {
@@ -5169,6 +5221,7 @@ module ts {
}
write(");");
emitEnd(node);
if (node.flags & NodeFlags.Export && !(node.flags & NodeFlags.Default)) {
writeLine();
emitStart(node);
@@ -5178,6 +5231,7 @@ module ts {
emitEnd(node);
write(";");
}
if (languageVersion < ScriptTarget.ES6 && node.parent === currentSourceFile && node.name) {
emitExportMemberAssignments(node.name);
}
@@ -5198,7 +5252,7 @@ module ts {
return;
}
if (!(node.flags & NodeFlags.Export)) {
if (!(node.flags & NodeFlags.Export) || isES6ModuleMemberDeclaration(node)) {
emitStart(node);
write("var ");
emit(node.name);
@@ -5225,7 +5279,10 @@ module ts {
emitModuleMemberName(node);
write(" = {}));");
emitEnd(node);
if (node.flags & NodeFlags.Export) {
if (isES6ModuleMemberDeclaration(node)) {
emitES6NamedExportForDeclaration(node);
}
else if (node.flags & NodeFlags.Export) {
writeLine();
emitStart(node);
write("var ");
@@ -5331,7 +5388,8 @@ module ts {
scopeEmitEnd();
}
write(")(");
if (node.flags & NodeFlags.Export) {
// write moduleDecl = containingModule.m only if it is not exported es6 module member
if ((node.flags & NodeFlags.Export) && !isES6ModuleMemberDeclaration(node)) {
emit(node.name);
write(" = ");
}
@@ -5340,11 +5398,23 @@ module ts {
emitModuleMemberName(node);
write(" = {}));");
emitEnd(node);
if (languageVersion < ScriptTarget.ES6 && node.name.kind === SyntaxKind.Identifier && node.parent === currentSourceFile) {
if (isES6ModuleMemberDeclaration(node)) {
emitES6NamedExportForDeclaration(node);
}
else if (languageVersion < ScriptTarget.ES6 && node.name.kind === SyntaxKind.Identifier && node.parent === currentSourceFile) {
emitExportMemberAssignments(<Identifier>node.name);
}
}
function emitES6NamedExportForDeclaration(node: Declaration) {
writeLine();
emitStart(node);
write("export { ");
emit(node.name);
write(" };");
emitEnd(node);
}
function emitRequire(moduleName: Expression) {
if (moduleName.kind === SyntaxKind.StringLiteral) {
write("require(");
@@ -5359,7 +5429,95 @@ module ts {
}
}
function emitImportDeclaration(node: ImportDeclaration | ImportEqualsDeclaration) {
function emitImportDeclaration(node: ImportDeclaration) {
if (languageVersion < ScriptTarget.ES6) {
return emitExternalImportDeclaration(node);
}
// ES6 import
if (node.importClause) {
let shouldEmitDefaultBindings = hasReferencedDefaultName(node.importClause);
let shouldEmitNamedBindings = hasReferencedNamedBindings(node.importClause);
if (shouldEmitDefaultBindings || shouldEmitNamedBindings) {
write("import ");
emitStart(node.importClause);
if (shouldEmitDefaultBindings) {
emit(node.importClause.name);
if (shouldEmitNamedBindings) {
write(", ");
}
}
if (shouldEmitNamedBindings) {
emitLeadingComments(node.importClause.namedBindings);
emitStart(node.importClause.namedBindings);
if (node.importClause.namedBindings.kind === SyntaxKind.NamespaceImport) {
write("* as ");
emit((<NamespaceImport>node.importClause.namedBindings).name);
}
else {
write("{ ");
let importSpecifiers = (<NamedImports>node.importClause.namedBindings).elements;
let currentTextPos = writer.getTextPos();
let needsComma = false;
for (var i = 0, n = importSpecifiers.length; i < n; i++) {
if (resolver.isReferencedAliasDeclaration(importSpecifiers[i])) {
if (needsComma) {
write(", ");
}
needsComma = true;
emit(importSpecifiers[i]);
}
}
write(" }");
}
emitEnd(node.importClause.namedBindings);
emitTrailingComments(node.importClause.namedBindings);
}
emitEnd(node.importClause);
write(" from ");
emit(node.moduleSpecifier);
write(";");
}
}
else {
write("import ");
emit(node.moduleSpecifier);
write(";");
}
}
function hasReferencedDefaultName(importClause: ImportClause) {
// If the default import is used, the mark will be on the importClause,
// as the alias declaration.
// If there are other named bindings on the import clause, we will
// will mark either the namedBindings(import * as n) or the NamedImport
// in the case of import {a}
return resolver.isReferencedAliasDeclaration(importClause);
}
function hasReferencedNamedBindings(importClause: ImportClause) {
if (importClause && importClause.namedBindings) {
if (importClause.namedBindings.kind === SyntaxKind.NamespaceImport) {
return resolver.isReferencedAliasDeclaration(importClause.namedBindings);
}
else {
return forEach((<NamedImports>importClause.namedBindings).elements,
namedImport => resolver.isReferencedAliasDeclaration(namedImport));
}
}
}
function emitImportOrExportSpecifier(node: ImportSpecifier) {
Debug.assert(languageVersion >= ScriptTarget.ES6);
if (node.propertyName) {
emit(node.propertyName);
write(" as ");
}
emit(node.name);
}
function emitExternalImportDeclaration(node: ImportDeclaration | ImportEqualsDeclaration) {
let info = getExternalImportInfo(node);
if (info) {
let declarationNode = info.declarationNode;
@@ -5401,7 +5559,7 @@ module ts {
function emitImportEqualsDeclaration(node: ImportEqualsDeclaration) {
if (isExternalModuleImportEqualsDeclaration(node)) {
emitImportDeclaration(node);
emitExternalImportDeclaration(node);
return;
}
// preserve old compiler's behavior: emit 'var' for import declaration (even if we do not consider them referenced) when
@@ -5411,7 +5569,13 @@ module ts {
(!isExternalModule(currentSourceFile) && resolver.isTopLevelValueImportEqualsWithEntityName(node))) {
emitLeadingComments(node);
emitStart(node);
if (!(node.flags & NodeFlags.Export)) write("var ");
if (isES6ModuleMemberDeclaration(node)) {
write("export ");
write("var ");
}
else if (!(node.flags & NodeFlags.Export)) {
write("var ");
}
emitModuleMemberName(node);
write(" = ");
emit(node.moduleReference);
@@ -5422,77 +5586,121 @@ module ts {
}
function emitExportDeclaration(node: ExportDeclaration) {
if (node.moduleSpecifier) {
emitStart(node);
let generatedName = resolver.getGeneratedNameForNode(node);
if (compilerOptions.module !== ModuleKind.AMD) {
write("var ");
write(generatedName);
write(" = ");
emitRequire(getExternalModuleName(node));
}
if (node.exportClause) {
// export { x, y, ... }
forEach(node.exportClause.elements, specifier => {
writeLine();
emitStart(specifier);
emitContainingModuleName(specifier);
write(".");
emitNodeWithoutSourceMap(specifier.name);
write(" = ");
if (languageVersion < ScriptTarget.ES6 || node.parent.kind !== SyntaxKind.SourceFile) {
if (node.moduleSpecifier) {
emitStart(node);
let generatedName = resolver.getGeneratedNameForNode(node);
if (compilerOptions.module !== ModuleKind.AMD) {
write("var ");
write(generatedName);
write(".");
emitNodeWithoutSourceMap(specifier.propertyName || specifier.name);
write(";");
emitEnd(specifier);
});
write(" = ");
emitRequire(getExternalModuleName(node));
}
if (node.exportClause) {
// export { x, y, ... }
forEach(node.exportClause.elements, specifier => {
writeLine();
emitStart(specifier);
emitContainingModuleName(specifier);
write(".");
emitNodeWithoutSourceMap(specifier.name);
write(" = ");
write(generatedName);
write(".");
emitNodeWithoutSourceMap(specifier.propertyName || specifier.name);
write(";");
emitEnd(specifier);
});
}
else {
// export *
let tempName = createTempVariable(node).text;
writeLine();
write("for (var " + tempName + " in " + generatedName + ") if (!");
emitContainingModuleName(node);
write(".hasOwnProperty(" + tempName + ")) ");
emitContainingModuleName(node);
write("[" + tempName + "] = " + generatedName + "[" + tempName + "];");
}
emitEnd(node);
}
else {
// export *
let tempName = createTempVariable(node).text;
writeLine();
write("for (var " + tempName + " in " + generatedName + ") if (!");
emitContainingModuleName(node);
write(".hasOwnProperty(" + tempName + ")) ");
emitContainingModuleName(node);
write("[" + tempName + "] = " + generatedName + "[" + tempName + "];");
// internal module
if (node.exportClause) {
// export { x, y, ... }
forEach(node.exportClause.elements, specifier => {
writeLine();
emitStart(specifier);
emitContainingModuleName(specifier);
write(".");
emitNodeWithoutSourceMap(specifier.name);
write(" = ");
emitNodeWithoutSourceMap(specifier.propertyName || specifier.name);
write(";");
emitEnd(specifier);
});
}
}
emitEnd(node);
}
else {
write("export ");
if (node.exportClause) {
// export { x, y, ... }
write("{ ");
emitCommaList(node.exportClause.elements);
write(" }");
}
else {
write("*");
}
if (node.moduleSpecifier) {
write(" from ");
emit(node.moduleSpecifier);
}
write(";");
}
}
function createExternalImportInfo(node: Node): ExternalImportInfo {
if (node.kind === SyntaxKind.ImportEqualsDeclaration) {
if ((<ImportEqualsDeclaration>node).moduleReference.kind === SyntaxKind.ExternalModuleReference) {
return {
rootNode: <ImportEqualsDeclaration>node,
declarationNode: <ImportEqualsDeclaration>node
};
if (resolver.isReferencedAliasDeclaration(node)) {
return {
rootNode: <ImportEqualsDeclaration>node,
declarationNode: <ImportEqualsDeclaration>node
};
}
}
}
else if (node.kind === SyntaxKind.ImportDeclaration) {
let importClause = (<ImportDeclaration>node).importClause;
if (importClause) {
if (importClause.name) {
if (importClause.name && resolver.isReferencedAliasDeclaration(importClause)) {
return {
rootNode: <ImportDeclaration>node,
declarationNode: importClause
};
}
if (importClause.namedBindings.kind === SyntaxKind.NamespaceImport) {
return {
rootNode: <ImportDeclaration>node,
declarationNode: <NamespaceImport>importClause.namedBindings
};
if (hasReferencedNamedBindings(importClause)) {
if (importClause.namedBindings.kind === SyntaxKind.NamespaceImport) {
return {
rootNode: <ImportDeclaration>node,
declarationNode: <NamespaceImport>importClause.namedBindings
};
}
else {
return {
rootNode: <ImportDeclaration>node,
namedImports: <NamedImports>importClause.namedBindings,
localName: resolver.getGeneratedNameForNode(<ImportDeclaration>node)
};
}
}
return {
rootNode: <ImportDeclaration>node,
namedImports: <NamedImports>importClause.namedBindings,
localName: resolver.getGeneratedNameForNode(<ImportDeclaration>node)
};
}
return {
rootNode: <ImportDeclaration>node
else {
return {
rootNode: <ImportDeclaration>node
};
}
}
else if (node.kind === SyntaxKind.ExportDeclaration) {
@@ -5529,9 +5737,7 @@ module ts {
else {
let info = createExternalImportInfo(node);
if (info) {
if ((!info.declarationNode && !info.namedImports) || resolver.isReferencedAliasDeclaration(node)) {
externalImports.push(info);
}
externalImports.push(info);
}
}
});
@@ -5547,14 +5753,6 @@ module ts {
}
}
function getFirstExportAssignment(sourceFile: SourceFile) {
return forEach(sourceFile.statements, node => {
if (node.kind === SyntaxKind.ExportAssignment) {
return <ExportAssignment>node;
}
});
}
function sortAMDModules(amdModules: {name: string; path: string}[]) {
// AMD modules with declared variable names go first
return amdModules.sort((moduleA, moduleB) => {
@@ -5569,6 +5767,7 @@ module ts {
}
function emitAMDModule(node: SourceFile, startIndex: number) {
createExternalModuleInfo(node);
writeLine();
write("define(");
sortAMDModules(node.amdDependencies);
@@ -5619,28 +5818,60 @@ module ts {
}
function emitCommonJSModule(node: SourceFile, startIndex: number) {
createExternalModuleInfo(node);
emitCaptureThisForNodeIfNecessary(node);
emitLinesStartingAt(node.statements, startIndex);
emitTempDeclarations(/*newLine*/ true);
emitExportDefault(node, /*emitAsReturn*/ false);
}
function emitExportDefault(sourceFile: SourceFile, emitAsReturn: boolean) {
if (exportDefault && resolver.hasExportDefaultValue(sourceFile)) {
function emitES6Module(node: SourceFile, startIndex: number) {
externalImports = undefined;
exportSpecifiers = undefined;
exportDefault = undefined;
emitCaptureThisForNodeIfNecessary(node);
emitLinesStartingAt(node.statements, startIndex);
emitTempDeclarations(/*newLine*/ true);
// Emit exportDefault if it exists will happen as part
// or normal statment emit.
}
function emitExportAssignment(node: ExportAssignment) {
// Only emit exportAssignment/export default if we are in ES6
// Other modules will handel it diffrentlly
if (languageVersion >= ScriptTarget.ES6) {
writeLine();
emitStart(exportDefault);
write(emitAsReturn ? "return " : "module.exports = ");
if (exportDefault.kind === SyntaxKind.ExportAssignment) {
emit((<ExportAssignment>exportDefault).expression);
emitStart(node);
write("export default ");
var expression = node.expression;
emit(expression);
if (expression.kind !== SyntaxKind.FunctionDeclaration &&
expression.kind !== SyntaxKind.ClassDeclaration) {
write(";");
}
else if (exportDefault.kind === SyntaxKind.ExportSpecifier) {
emit((<ExportSpecifier>exportDefault).propertyName);
emitEnd(node);
}
}
function emitExportDefault(sourceFile: SourceFile, emitAsReturn: boolean) {
// ES6 emit is handled in emitExportAssignment
if (exportDefault && resolver.hasExportDefaultValue(sourceFile)) {
if (languageVersion < ScriptTarget.ES6) {
writeLine();
emitStart(exportDefault);
write(emitAsReturn ? "return " : "module.exports = ");
if (exportDefault.kind === SyntaxKind.ExportAssignment) {
emit((<ExportAssignment>exportDefault).expression);
}
else if (exportDefault.kind === SyntaxKind.ExportSpecifier) {
emit((<ExportSpecifier>exportDefault).propertyName);
}
else {
emitDeclarationName(<Declaration>exportDefault);
}
write(";");
emitEnd(exportDefault);
}
else {
emitDeclarationName(<Declaration>exportDefault);
}
write(";");
emitEnd(exportDefault);
}
}
@@ -5687,8 +5918,10 @@ module ts {
extendsEmitted = true;
}
if (isExternalModule(node)) {
createExternalModuleInfo(node);
if (compilerOptions.module === ModuleKind.AMD) {
if (languageVersion >= ScriptTarget.ES6) {
emitES6Module(node, startIndex);
}
else if (compilerOptions.module === ModuleKind.AMD) {
emitAMDModule(node, startIndex);
}
else {
@@ -5912,10 +6145,15 @@ module ts {
return emitModuleDeclaration(<ModuleDeclaration>node);
case SyntaxKind.ImportDeclaration:
return emitImportDeclaration(<ImportDeclaration>node);
case SyntaxKind.ImportSpecifier:
case SyntaxKind.ExportSpecifier:
return emitImportOrExportSpecifier(<ImportOrExportSpecifier>node);
case SyntaxKind.ImportEqualsDeclaration:
return emitImportEqualsDeclaration(<ImportEqualsDeclaration>node);
case SyntaxKind.ExportDeclaration:
return emitExportDeclaration(<ExportDeclaration>node);
case SyntaxKind.ExportAssignment:
return emitExportAssignment(<ExportAssignment>node);
case SyntaxKind.SourceFile:
return emitSourceFileNode(<SourceFile>node);
}
@@ -6093,3 +6331,4 @@ module ts {
}
}
}
+41 -26
View File
@@ -2,8 +2,10 @@
/// <reference path="emitter.ts" />
module ts {
/* @internal */ export let programTime = 0;
/* @internal */ export let emitTime = 0;
/* @internal */ export let ioReadTime = 0;
/* @internal */ export let ioWriteTime = 0;
/** The version of the TypeScript compiler release */
export let version = "1.5.0.0";
@@ -36,33 +38,34 @@ module ts {
}
text = "";
}
return text !== undefined ? createSourceFile(fileName, text, languageVersion) : undefined;
}
function directoryExists(directoryPath: string): boolean {
if (hasProperty(existingDirectories, directoryPath)) {
return true;
}
if (sys.directoryExists(directoryPath)) {
existingDirectories[directoryPath] = true;
return true;
}
return false;
}
function ensureDirectoriesExist(directoryPath: string) {
if (directoryPath.length > getRootLength(directoryPath) && !directoryExists(directoryPath)) {
let parentDirectory = getDirectoryPath(directoryPath);
ensureDirectoriesExist(parentDirectory);
sys.createDirectory(directoryPath);
}
}
function writeFile(fileName: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void) {
function directoryExists(directoryPath: string): boolean {
if (hasProperty(existingDirectories, directoryPath)) {
return true;
}
if (sys.directoryExists(directoryPath)) {
existingDirectories[directoryPath] = true;
return true;
}
return false;
}
function ensureDirectoriesExist(directoryPath: string) {
if (directoryPath.length > getRootLength(directoryPath) && !directoryExists(directoryPath)) {
let parentDirectory = getDirectoryPath(directoryPath);
ensureDirectoriesExist(parentDirectory);
sys.createDirectory(directoryPath);
}
}
try {
var start = new Date().getTime();
ensureDirectoriesExist(getDirectoryPath(normalizePath(fileName)));
sys.writeFile(fileName, data, writeByteOrderMark);
ioWriteTime += new Date().getTime() - start;
}
catch (e) {
if (onError) {
@@ -120,16 +123,19 @@ module ts {
let diagnostics = createDiagnosticCollection();
let seenNoDefaultLib = options.noLib;
let commonSourceDirectory: string;
host = host || createCompilerHost(options);
let diagnosticsProducingTypeChecker: TypeChecker;
let noDiagnosticsTypeChecker: TypeChecker;
let start = new Date().getTime();
host = host || createCompilerHost(options);
forEach(rootNames, name => processRootFile(name, false));
if (!seenNoDefaultLib) {
processRootFile(host.getDefaultLibFileName(options), true);
}
verifyCompilerOptions();
let diagnosticsProducingTypeChecker: TypeChecker;
let noDiagnosticsTypeChecker: TypeChecker;
programTime += new Date().getTime() - start;
program = {
getSourceFile: getSourceFile,
@@ -430,11 +436,20 @@ module ts {
return;
}
let languageVersion = options.target || ScriptTarget.ES3;
let firstExternalModuleSourceFile = forEach(files, f => isExternalModule(f) ? f : undefined);
if (firstExternalModuleSourceFile && !options.module) {
// We cannot use createDiagnosticFromNode because nodes do not have parents yet
let span = getErrorSpanForNode(firstExternalModuleSourceFile, firstExternalModuleSourceFile.externalModuleIndicator);
diagnostics.add(createFileDiagnostic(firstExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_compile_external_modules_unless_the_module_flag_is_provided));
if (!options.module && languageVersion < ScriptTarget.ES6) {
// We cannot use createDiagnosticFromNode because nodes do not have parents yet
let span = getErrorSpanForNode(firstExternalModuleSourceFile, firstExternalModuleSourceFile.externalModuleIndicator);
diagnostics.add(createFileDiagnostic(firstExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_compile_external_modules_unless_the_module_flag_is_provided));
}
}
// Cannot specify module gen target when in es6 or above
if (options.module && languageVersion >= ScriptTarget.ES6) {
diagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_compile_external_modules_into_amd_or_commonjs_when_targeting_es6_or_higher));
}
// there has to be common source directory if user specified --outdir || --sourcRoot
+15 -24
View File
@@ -320,22 +320,16 @@ module ts {
}
function compile(fileNames: string[], compilerOptions: CompilerOptions, compilerHost: CompilerHost) {
ts.ioReadTime = 0;
ts.parseTime = 0;
ts.bindTime = 0;
ts.checkTime = 0;
ts.emitTime = 0;
var start = new Date().getTime();
ioReadTime = 0;
ioWriteTime = 0;
programTime = 0;
bindTime = 0;
checkTime = 0;
emitTime = 0;
var program = createProgram(fileNames, compilerOptions, compilerHost);
var programTime = new Date().getTime() - start;
var exitStatus = compileProgram();
var end = new Date().getTime() - start;
var compileTime = end - programTime;
if (compilerOptions.listFiles) {
forEach(program.getSourceFiles(), file => {
sys.write(file.fileName + sys.newLine);
@@ -356,19 +350,16 @@ module ts {
}
// Individual component times.
// Note: we output 'programTime' as parseTime to match the tsc 1.3 behavior. tsc 1.3
// measured parse time along with read IO as a single counter. We preserve that
// behavior so we can accurately compare times. For actual parse times (in isolation)
// is reported below.
// Note: To match the behavior of previous versions of the compiler, the reported parse time includes
// I/O read time and processing time for triple-slash references and module imports, and the reported
// emit time includes I/O write time. We preserve this behavior so we can accurately compare times.
reportTimeStatistic("I/O read", ioReadTime);
reportTimeStatistic("I/O write", ioWriteTime);
reportTimeStatistic("Parse time", programTime);
reportTimeStatistic("Bind time", ts.bindTime);
reportTimeStatistic("Check time", ts.checkTime);
reportTimeStatistic("Emit time", ts.emitTime);
reportTimeStatistic("Parse time w/o IO", ts.parseTime);
reportTimeStatistic("IO read", ts.ioReadTime);
reportTimeStatistic("Compile time", compileTime);
reportTimeStatistic("Total time", end);
reportTimeStatistic("Bind time", bindTime);
reportTimeStatistic("Check time", checkTime);
reportTimeStatistic("Emit time", emitTime);
reportTimeStatistic("Total time", programTime + bindTime + checkTime + emitTime);
}
return { program, exitStatus };
+4
View File
@@ -1491,11 +1491,15 @@ module ts {
(t: Type): Type;
}
// @internal
export interface TypeInferences {
primary: Type[]; // Inferences made directly to a type parameter
secondary: Type[]; // Inferences made to a type parameter in a union type
isFixed: boolean; // Whether the type parameter is fixed, as defined in section 4.12.2 of the TypeScript spec
// If a type parameter is fixed, no more inferences can be made for the type parameter
}
// @internal
export interface InferenceContext {
typeParameters: TypeParameter[]; // Type parameters for which inferences are made
inferUnionTypes: boolean; // Infer union types for disjoint candidates (otherwise undefinedType)
+5 -3
View File
@@ -1621,8 +1621,9 @@ module FourSlash {
this.taoInvalidReason = 'verifyIndentationAtCurrentPosition NYI';
var actual = this.getIndentation(this.activeFile.fileName, this.currentCaretPosition);
if (actual != numberOfSpaces) {
this.raiseError('verifyIndentationAtCurrentPosition failed - expected: ' + numberOfSpaces + ', actual: ' + actual);
var lineCol = this.getLineColStringAtPosition(this.currentCaretPosition);
if (actual !== numberOfSpaces) {
this.raiseError('verifyIndentationAtCurrentPosition failed at ' + lineCol + ' - expected: ' + numberOfSpaces + ', actual: ' + actual);
}
}
@@ -1630,8 +1631,9 @@ module FourSlash {
this.taoInvalidReason = 'verifyIndentationAtPosition NYI';
var actual = this.getIndentation(fileName, position);
var lineCol = this.getLineColStringAtPosition(position);
if (actual !== numberOfSpaces) {
this.raiseError('verifyIndentationAtPosition failed - expected: ' + numberOfSpaces + ', actual: ' + actual);
this.raiseError('verifyIndentationAtPosition failed at ' + lineCol + ' - expected: ' + numberOfSpaces + ', actual: ' + actual);
}
}
+53 -9
View File
@@ -359,6 +359,7 @@ module ts.formatting {
case SyntaxKind.ModuleBlock:
case SyntaxKind.ObjectLiteralExpression:
case SyntaxKind.TypeLiteral:
case SyntaxKind.TupleType:
case SyntaxKind.CaseBlock:
case SyntaxKind.DefaultClause:
case SyntaxKind.CaseClause:
@@ -370,6 +371,8 @@ module ts.formatting {
case SyntaxKind.ExportAssignment:
case SyntaxKind.ReturnStatement:
case SyntaxKind.ConditionalExpression:
case SyntaxKind.ArrayBindingPattern:
case SyntaxKind.ObjectBindingPattern:
return true;
}
return false;
@@ -390,6 +393,7 @@ module ts.formatting {
case SyntaxKind.FunctionExpression:
case SyntaxKind.MethodDeclaration:
case SyntaxKind.MethodSignature:
case SyntaxKind.CallSignature:
case SyntaxKind.ArrowFunction:
case SyntaxKind.Constructor:
case SyntaxKind.GetAccessor:
@@ -431,46 +435,85 @@ module ts.formatting {
case SyntaxKind.InterfaceDeclaration:
case SyntaxKind.EnumDeclaration:
case SyntaxKind.ObjectLiteralExpression:
case SyntaxKind.ObjectBindingPattern:
case SyntaxKind.TypeLiteral:
case SyntaxKind.Block:
case SyntaxKind.ModuleBlock:
case SyntaxKind.CaseBlock:
return nodeEndsWith(n, SyntaxKind.CloseBraceToken, sourceFile);
case SyntaxKind.CatchClause:
return isCompletedNode((<CatchClause>n).block, sourceFile);
case SyntaxKind.ParenthesizedExpression:
case SyntaxKind.CallSignature:
case SyntaxKind.NewExpression:
if (!(<NewExpression>n).arguments) {
return true;
}
// fall through
case SyntaxKind.CallExpression:
case SyntaxKind.ConstructSignature:
case SyntaxKind.ParenthesizedExpression:
case SyntaxKind.ParenthesizedType:
return nodeEndsWith(n, SyntaxKind.CloseParenToken, sourceFile);
case SyntaxKind.FunctionType:
case SyntaxKind.ConstructorType:
return isCompletedNode((<SignatureDeclaration>n).type, sourceFile);
case SyntaxKind.Constructor:
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.FunctionExpression:
case SyntaxKind.MethodDeclaration:
case SyntaxKind.MethodSignature:
case SyntaxKind.ConstructSignature:
case SyntaxKind.CallSignature:
case SyntaxKind.ArrowFunction:
return !(<FunctionLikeDeclaration>n).body || isCompletedNode((<FunctionLikeDeclaration>n).body, sourceFile);
if ((<FunctionLikeDeclaration>n).body) {
return isCompletedNode((<FunctionLikeDeclaration>n).body, sourceFile);
}
if ((<FunctionLikeDeclaration>n).type) {
return isCompletedNode((<FunctionLikeDeclaration>n).type, sourceFile);
}
// Even though type parameters can be unclosed, we can get away with
// having at least a closing paren.
return hasChildOfKind(n, SyntaxKind.CloseParenToken, sourceFile);
case SyntaxKind.ModuleDeclaration:
return (<ModuleDeclaration>n).body && isCompletedNode((<ModuleDeclaration>n).body, sourceFile);
case SyntaxKind.IfStatement:
if ((<IfStatement>n).elseStatement) {
return isCompletedNode((<IfStatement>n).elseStatement, sourceFile);
}
return isCompletedNode((<IfStatement>n).thenStatement, sourceFile);
case SyntaxKind.ExpressionStatement:
return isCompletedNode((<ExpressionStatement>n).expression, sourceFile);
case SyntaxKind.ArrayLiteralExpression:
case SyntaxKind.ArrayBindingPattern:
case SyntaxKind.ComputedPropertyName:
case SyntaxKind.TupleType:
return nodeEndsWith(n, SyntaxKind.CloseBracketToken, sourceFile);
case SyntaxKind.IndexSignature:
if ((<IndexSignatureDeclaration>n).type) {
return isCompletedNode((<IndexSignatureDeclaration>n).type, sourceFile);
}
return hasChildOfKind(n, SyntaxKind.CloseBracketToken, sourceFile);
case SyntaxKind.CaseClause:
case SyntaxKind.DefaultClause:
// there is no such thing as terminator token for CaseClause\DefaultClause so for simplicitly always consider them non-completed
// there is no such thing as terminator token for CaseClause/DefaultClause so for simplicitly always consider them non-completed
return false;
case SyntaxKind.ForStatement:
return isCompletedNode((<ForStatement>n).statement, sourceFile);
case SyntaxKind.ForInStatement:
return isCompletedNode((<ForInStatement>n).statement, sourceFile);
case SyntaxKind.ForOfStatement:
return isCompletedNode((<ForOfStatement>n).statement, sourceFile);
case SyntaxKind.WhileStatement:
return isCompletedNode((<WhileStatement>n).statement, sourceFile);
return isCompletedNode((<IterationStatement>n).statement, sourceFile);
case SyntaxKind.DoStatement:
// rough approximation: if DoStatement has While keyword - then if node is completed is checking the presence of ')';
let hasWhileKeyword = findChildOfKind(n, SyntaxKind.WhileKeyword, sourceFile);
@@ -478,6 +521,7 @@ module ts.formatting {
return nodeEndsWith(n, SyntaxKind.CloseParenToken, sourceFile);
}
return isCompletedNode((<DoStatement>n).statement, sourceFile);
default:
return true;
}
+4
View File
@@ -79,6 +79,10 @@ module ts {
};
}
export function hasChildOfKind(n: Node, kind: SyntaxKind, sourceFile?: SourceFile): boolean {
return !!findChildOfKind(n, kind, sourceFile);
}
export function findChildOfKind(n: Node, kind: SyntaxKind, sourceFile?: SourceFile): Node {
return forEach(n.getChildren(sourceFile), c => c.kind === kind && c);
}