mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge remote-tracking branch 'origin/master' into
serverConfigurationMessage.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -505,7 +506,7 @@ module ts {
|
||||
bindChildren(node, 0, /*isBlockScopeContainer*/ false);
|
||||
break;
|
||||
case SyntaxKind.ExportAssignment:
|
||||
if ((<ExportAssignment>node).expression.kind === SyntaxKind.Identifier) {
|
||||
if ((<ExportAssignment>node).expression && (<ExportAssignment>node).expression.kind === SyntaxKind.Identifier) {
|
||||
// An export default clause with an identifier exports all meanings of that identifier
|
||||
declareSymbol(container.symbol.exports, container.symbol, <Declaration>node, SymbolFlags.Alias, SymbolFlags.AliasExcludes);
|
||||
}
|
||||
|
||||
+138
-72
@@ -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);
|
||||
|
||||
@@ -567,7 +566,7 @@ module ts {
|
||||
}
|
||||
|
||||
function getTargetOfExportAssignment(node: ExportAssignment): Symbol {
|
||||
return resolveEntityName(<Identifier>node.expression, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace);
|
||||
return node.expression && resolveEntityName(<Identifier>node.expression, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace);
|
||||
}
|
||||
|
||||
function getTargetOfImportDeclaration(node: Declaration): Symbol {
|
||||
@@ -623,7 +622,7 @@ module ts {
|
||||
if (!links.referenced) {
|
||||
links.referenced = true;
|
||||
let node = getDeclarationOfAliasSymbol(symbol);
|
||||
if (node.kind === SyntaxKind.ExportAssignment) {
|
||||
if (node.kind === SyntaxKind.ExportAssignment && (<ExportAssignment>node).expression) {
|
||||
// export default <symbol>
|
||||
checkExpressionCached((<ExportAssignment>node).expression);
|
||||
}
|
||||
@@ -784,7 +783,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) {
|
||||
@@ -1813,6 +1812,11 @@ module ts {
|
||||
case SyntaxKind.ParenthesizedType:
|
||||
return isDeclarationVisible(<Declaration>node.parent);
|
||||
|
||||
case SyntaxKind.ImportClause:
|
||||
case SyntaxKind.NamespaceImport:
|
||||
case SyntaxKind.ImportSpecifier:
|
||||
return false;
|
||||
|
||||
// Type parameters are always visible
|
||||
case SyntaxKind.TypeParameter:
|
||||
// Source file is always visible
|
||||
@@ -2073,7 +2077,16 @@ module ts {
|
||||
}
|
||||
// Handle export default expressions
|
||||
if (declaration.kind === SyntaxKind.ExportAssignment) {
|
||||
return links.type = checkExpression((<ExportAssignment>declaration).expression);
|
||||
var exportAssignment = <ExportAssignment>declaration;
|
||||
if (exportAssignment.expression) {
|
||||
return links.type = checkExpression(exportAssignment.expression);
|
||||
}
|
||||
else if (exportAssignment.type) {
|
||||
return links.type = getTypeFromTypeNode(exportAssignment.type);
|
||||
}
|
||||
else {
|
||||
return links.type = anyType;
|
||||
}
|
||||
}
|
||||
// Handle variable, parameter or property
|
||||
links.type = resolvingType;
|
||||
@@ -3505,6 +3518,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);
|
||||
}
|
||||
}
|
||||
@@ -4363,8 +4377,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++) {
|
||||
@@ -4379,6 +4396,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;
|
||||
@@ -4561,13 +4580,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),
|
||||
};
|
||||
}
|
||||
@@ -4613,11 +4631,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4723,21 +4751,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;
|
||||
@@ -6334,11 +6376,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++) {
|
||||
@@ -6373,18 +6436,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 {
|
||||
@@ -6618,15 +6670,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) {
|
||||
@@ -6636,9 +6690,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;
|
||||
@@ -6668,7 +6722,7 @@ module ts {
|
||||
else {
|
||||
candidateForTypeArgumentError = originalCandidate;
|
||||
if (!typeArguments) {
|
||||
resultOfFailedInference = inferenceResult;
|
||||
resultOfFailedInference = inferenceContext;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10044,6 +10098,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10075,13 +10135,27 @@ module ts {
|
||||
if (!checkGrammarModifiers(node) && (node.flags & NodeFlags.Modifier)) {
|
||||
grammarErrorOnFirstToken(node, Diagnostics.An_export_assignment_cannot_have_modifiers);
|
||||
}
|
||||
if (node.expression.kind === SyntaxKind.Identifier) {
|
||||
markExportAsReferenced(node);
|
||||
if (node.expression) {
|
||||
if (node.expression.kind === SyntaxKind.Identifier) {
|
||||
markExportAsReferenced(node);
|
||||
}
|
||||
else {
|
||||
checkExpressionCached(node.expression);
|
||||
}
|
||||
}
|
||||
else {
|
||||
checkExpressionCached(node.expression);
|
||||
if (node.type) {
|
||||
checkSourceElement(node.type);
|
||||
if (!isInAmbientContext(node)) {
|
||||
grammarErrorOnFirstToken(node.type, Diagnostics.A_type_annotation_on_an_export_statement_is_only_allowed_in_an_ambient_external_module_declaration);
|
||||
}
|
||||
}
|
||||
|
||||
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[] {
|
||||
@@ -10124,7 +10198,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);
|
||||
}
|
||||
@@ -10914,7 +10988,7 @@ module ts {
|
||||
}
|
||||
|
||||
function generateNameForExportAssignment(node: ExportAssignment) {
|
||||
if (node.expression.kind !== SyntaxKind.Identifier) {
|
||||
if (node.expression && node.expression.kind !== SyntaxKind.Identifier) {
|
||||
assignGeneratedName(node, makeUniqueName("default"));
|
||||
}
|
||||
}
|
||||
@@ -10947,7 +11021,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);
|
||||
@@ -10975,7 +11057,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);
|
||||
}
|
||||
}
|
||||
@@ -11011,7 +11093,6 @@ module ts {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return forEachChild(node, isReferencedAliasDeclaration);
|
||||
}
|
||||
|
||||
function isImplementationOfOverload(node: FunctionLikeDeclaration) {
|
||||
@@ -11085,26 +11166,11 @@ module ts {
|
||||
function getBlockScopedVariableId(n: Identifier): number {
|
||||
Debug.assert(!nodeIsSynthesized(n));
|
||||
|
||||
// ignore name parts of property access expressions
|
||||
if (n.parent.kind === SyntaxKind.PropertyAccessExpression &&
|
||||
(<PropertyAccessExpression>n.parent).name === n) {
|
||||
return undefined;
|
||||
}
|
||||
let isVariableDeclarationOrBindingElement =
|
||||
n.parent.kind === SyntaxKind.BindingElement || (n.parent.kind === SyntaxKind.VariableDeclaration && (<VariableDeclaration>n.parent).name === n);
|
||||
|
||||
// ignore property names in object binding patterns
|
||||
if (n.parent.kind === SyntaxKind.BindingElement &&
|
||||
(<BindingElement>n.parent).propertyName === n) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// for names in variable declarations and binding elements try to short circuit and fetch symbol from the node
|
||||
let declarationSymbol: Symbol =
|
||||
(n.parent.kind === SyntaxKind.VariableDeclaration && (<VariableDeclaration>n.parent).name === n) ||
|
||||
n.parent.kind === SyntaxKind.BindingElement
|
||||
? getSymbolOfNode(n.parent)
|
||||
: undefined;
|
||||
|
||||
let symbol = declarationSymbol ||
|
||||
let symbol =
|
||||
(isVariableDeclarationOrBindingElement ? getSymbolOfNode(n.parent) : undefined) ||
|
||||
getNodeLinks(n).resolvedSymbol ||
|
||||
resolveName(n, n.text, SymbolFlags.Value | SymbolFlags.Alias, /*nodeNotFoundMessage*/ undefined, /*nameArg*/ undefined);
|
||||
|
||||
|
||||
@@ -158,6 +158,10 @@ module ts {
|
||||
An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive: { code: 1198, category: DiagnosticCategory.Error, key: "An extended Unicode escape value must be between 0x0 and 0x10FFFF inclusive." },
|
||||
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." },
|
||||
|
||||
@@ -617,12 +617,29 @@
|
||||
},
|
||||
"Unterminated Unicode escape sequence.": {
|
||||
"category": "Error",
|
||||
"code": 1199
|
||||
"code": 1199
|
||||
},
|
||||
"Line terminator not permitted before arrow.": {
|
||||
"category": "Error",
|
||||
"code": 1200
|
||||
},
|
||||
"A type annotation on an export statement is only allowed in an ambient external module declaration.": {
|
||||
"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",
|
||||
"code": 2300
|
||||
|
||||
+579
-210
File diff suppressed because it is too large
Load Diff
+29
-14
@@ -283,7 +283,8 @@ module ts {
|
||||
visitNode(cbNode, (<ImportOrExportSpecifier>node).name);
|
||||
case SyntaxKind.ExportAssignment:
|
||||
return visitNodes(cbNodes, node.modifiers) ||
|
||||
visitNode(cbNode, (<ExportAssignment>node).expression);
|
||||
visitNode(cbNode, (<ExportAssignment>node).expression) ||
|
||||
visitNode(cbNode, (<ExportAssignment>node).type);
|
||||
case SyntaxKind.TemplateExpression:
|
||||
return visitNode(cbNode, (<TemplateExpression>node).head) || visitNodes(cbNodes, (<TemplateExpression>node).templateSpans);
|
||||
case SyntaxKind.TemplateSpan:
|
||||
@@ -613,7 +614,7 @@ module ts {
|
||||
// change the token touching it, we actually need to look back *at least* one token so
|
||||
// that the prior token sees that change.
|
||||
let maxLookahead = 1;
|
||||
|
||||
|
||||
let start = changeRange.span.start;
|
||||
|
||||
// the first iteration aligns us with the change start. subsequent iteration move us to
|
||||
@@ -831,7 +832,7 @@ module ts {
|
||||
// will immediately bail out of walking any subtrees when we can see that their parents
|
||||
// are already correct.
|
||||
let result = parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, syntaxCursor, /* setParentNode */ true)
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1986,7 +1987,7 @@ module ts {
|
||||
//
|
||||
// let v = new List < A, B >()
|
||||
//
|
||||
// then we have a problem. "v = new List<A" doesn't intersect the change range, so we
|
||||
// then we have a problem. "v = new List<A" doesn't intersect the change range, so we
|
||||
// start reparsing at "B" and we completely fail to handle this properly.
|
||||
//
|
||||
// In order to prevent this, we do not allow a variable declarator to be reused if it
|
||||
@@ -3008,9 +3009,9 @@ module ts {
|
||||
Debug.assert(token === SyntaxKind.EqualsGreaterThanToken, "parseSimpleArrowFunctionExpression should only have been called if we had a =>");
|
||||
|
||||
let node = <ArrowFunction>createNode(SyntaxKind.ArrowFunction, identifier.pos);
|
||||
|
||||
|
||||
let parameter = <ParameterDeclaration>createNode(SyntaxKind.Parameter, identifier.pos);
|
||||
parameter.name = identifier;
|
||||
parameter.name = identifier;
|
||||
finishNode(parameter);
|
||||
|
||||
node.parameters = <NodeArray<ParameterDeclaration>>[parameter];
|
||||
@@ -3140,8 +3141,8 @@ module ts {
|
||||
|
||||
function parseParenthesizedArrowFunctionExpressionHead(allowAmbiguity: boolean): ArrowFunction {
|
||||
let node = <ArrowFunction>createNode(SyntaxKind.ArrowFunction);
|
||||
// Arrow functions are never generators.
|
||||
//
|
||||
// Arrow functions are never generators.
|
||||
//
|
||||
// If we're speculatively parsing a signature for a parenthesized arrow function, then
|
||||
// we have to have a complete parameter list. Otherwise we might see something like
|
||||
// a => (b => c)
|
||||
@@ -3206,7 +3207,7 @@ module ts {
|
||||
// Note: we explicitly 'allowIn' in the whenTrue part of the condition expression, and
|
||||
// we do not that for the 'whenFalse' part.
|
||||
let node = <ConditionalExpression>createNode(SyntaxKind.ConditionalExpression, leftOperand.pos);
|
||||
node.condition = leftOperand;
|
||||
node.condition = leftOperand;
|
||||
node.questionToken = questionToken;
|
||||
node.whenTrue = allowInAnd(parseAssignmentExpressionOrHigher);
|
||||
node.colonToken = parseExpectedToken(SyntaxKind.ColonToken, /*reportAtCurrentPosition:*/ false,
|
||||
@@ -4526,7 +4527,13 @@ module ts {
|
||||
}
|
||||
|
||||
function parseClassDeclaration(fullStart: number, modifiers: ModifiersArray): ClassDeclaration {
|
||||
let node = <ClassDeclaration>createNode(SyntaxKind.ClassDeclaration, fullStart);
|
||||
// In ES6 specification, All parts of a ClassDeclaration or a ClassExpression are strict mode code
|
||||
let savedStrictModeContext = inStrictModeContext();
|
||||
if (languageVersion >= ScriptTarget.ES6) {
|
||||
setStrictModeContext(true);
|
||||
}
|
||||
|
||||
var node = <ClassDeclaration>createNode(SyntaxKind.ClassDeclaration, fullStart);
|
||||
setModifiers(node, modifiers);
|
||||
parseExpected(SyntaxKind.ClassKeyword);
|
||||
node.name = node.flags & NodeFlags.Default ? parseOptionalIdentifier() : parseIdentifier();
|
||||
@@ -4546,7 +4553,10 @@ module ts {
|
||||
else {
|
||||
node.members = createMissingList<ClassElement>();
|
||||
}
|
||||
return finishNode(node);
|
||||
|
||||
var finishedNode = finishNode(node);
|
||||
setStrictModeContext(savedStrictModeContext);
|
||||
return finishedNode;
|
||||
}
|
||||
|
||||
function parseHeritageClauses(isClassHeritageClause: boolean): NodeArray<HeritageClause> {
|
||||
@@ -4774,7 +4784,7 @@ module ts {
|
||||
// walker.
|
||||
let result = parseExpression();
|
||||
// Ensure the string being required is in our 'identifier' table. This will ensure
|
||||
// that features like 'find refs' will look inside this file when search for its name.
|
||||
// that features like 'find refs' will look inside this file when search for its name.
|
||||
if (result.kind === SyntaxKind.StringLiteral) {
|
||||
internIdentifier((<LiteralExpression>result).text);
|
||||
}
|
||||
@@ -4867,12 +4877,17 @@ module ts {
|
||||
setModifiers(node, modifiers);
|
||||
if (parseOptional(SyntaxKind.EqualsToken)) {
|
||||
node.isExportEquals = true;
|
||||
node.expression = parseAssignmentExpressionOrHigher();
|
||||
}
|
||||
else {
|
||||
parseExpected(SyntaxKind.DefaultKeyword);
|
||||
if (parseOptional(SyntaxKind.ColonToken)) {
|
||||
node.type = parseType();
|
||||
}
|
||||
else {
|
||||
node.expression = parseAssignmentExpressionOrHigher();
|
||||
}
|
||||
}
|
||||
//node.exportName = parseIdentifier();
|
||||
node.expression = parseAssignmentExpressionOrHigher();
|
||||
parseSemicolon();
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
+41
-26
@@ -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
@@ -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 };
|
||||
|
||||
@@ -944,7 +944,8 @@ module ts {
|
||||
|
||||
export interface ExportAssignment extends Declaration, ModuleElement {
|
||||
isExportEquals?: boolean;
|
||||
expression: Expression;
|
||||
expression?: Expression;
|
||||
type?: TypeNode;
|
||||
}
|
||||
|
||||
export interface FileReference extends TextRange {
|
||||
@@ -1486,11 +1487,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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,15 +19,19 @@ module ts.server {
|
||||
class ScriptInfo {
|
||||
svc: ScriptVersionCache;
|
||||
children: ScriptInfo[] = []; // files referenced by this file
|
||||
|
||||
defaultProject: Project; // project to use by default for file
|
||||
|
||||
fileWatcher: FileWatcher;
|
||||
formatCodeOptions = ts.clone(CompilerService.defaultFormatCodeOptions);
|
||||
|
||||
constructor(private host: ServerHost, public fileName: string, public content: string, public isOpen = false) {
|
||||
this.svc = ScriptVersionCache.fromString(content);
|
||||
}
|
||||
|
||||
setFormatOptions(tabSize: number, indentSize: number) {
|
||||
this.formatCodeOptions.TabSize = tabSize;
|
||||
this.formatCodeOptions.IndentSize = indentSize;
|
||||
}
|
||||
|
||||
close() {
|
||||
this.isOpen = false;
|
||||
}
|
||||
@@ -153,15 +157,18 @@ module ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
reloadScript(filename: string, tmpfilename: string, tabSize: number, cb: () => any) {
|
||||
reloadScript(filename: string, tmpfilename: string, cb: () => any) {
|
||||
var script = this.getScriptInfo(filename);
|
||||
if (script) {
|
||||
script.svc.reloadFromFile(tmpfilename, tabSize, cb);
|
||||
script.svc.reloadFromFile(tmpfilename, script.formatCodeOptions.TabSize, cb);
|
||||
}
|
||||
}
|
||||
|
||||
editScript(filename: string, start: number, end: number, newText: string) {
|
||||
var script = this.getScriptInfo(filename);
|
||||
if (newText && (newText.length > 0)) {
|
||||
newText = expandTabs(newText, script.formatCodeOptions.TabSize);
|
||||
}
|
||||
if (script) {
|
||||
script.editContent(start, end, newText);
|
||||
return;
|
||||
@@ -365,6 +372,12 @@ module ts.server {
|
||||
hostInfo: string;
|
||||
}
|
||||
|
||||
export function expandTabs(text: string, tabSize: number) {
|
||||
var spaces = generateSpaces(tabSize);
|
||||
return text.replace(/\t/g, spaces);
|
||||
}
|
||||
|
||||
|
||||
export class ProjectService {
|
||||
filenameToScriptInfo: ts.Map<ScriptInfo> = {};
|
||||
// open, non-configured files in two lists
|
||||
@@ -386,7 +399,13 @@ module ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
getFormatCodeOptions() {
|
||||
getFormatCodeOptions(file?: string) {
|
||||
if (file) {
|
||||
var info = this.filenameToScriptInfo[file];
|
||||
if (info) {
|
||||
return info.formatCodeOptions;
|
||||
}
|
||||
}
|
||||
return this.hostConfiguration.formatCodeOptions;
|
||||
}
|
||||
|
||||
@@ -402,7 +421,7 @@ module ts.server {
|
||||
}
|
||||
else {
|
||||
if (info && (!info.isOpen)) {
|
||||
info.svc.reloadFromFile(info.fileName, this.hostConfiguration.formatCodeOptions.TabSize);
|
||||
info.svc.reloadFromFile(info.fileName, info.formatCodeOptions.TabSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -412,15 +431,19 @@ module ts.server {
|
||||
}
|
||||
|
||||
setHostConfiguration(args: ts.server.protocol.ConfigureRequestArguments) {
|
||||
this.hostConfiguration.formatCodeOptions.TabSize = args.tabSize;
|
||||
this.hostConfiguration.formatCodeOptions.IndentSize = args.indentSize;
|
||||
this.hostConfiguration.hostInfo = args.hostInfo;
|
||||
this.log("Host information " + args.hostInfo, "Info");
|
||||
}
|
||||
|
||||
expandTabs(text: string) {
|
||||
var spaces = generateSpaces(this.hostConfiguration.formatCodeOptions.TabSize);
|
||||
return text.replace(/\t/g, spaces);
|
||||
if (args.file) {
|
||||
var info = this.filenameToScriptInfo[args.file];
|
||||
if (info) {
|
||||
info.setFormatOptions(args.tabSize, args.indentSize);
|
||||
this.log("Host configuration update for file " + args.file + " tab size " + args.tabSize);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.hostConfiguration.formatCodeOptions.TabSize = args.tabSize;
|
||||
this.hostConfiguration.formatCodeOptions.IndentSize = args.indentSize;
|
||||
this.hostConfiguration.hostInfo = args.hostInfo;
|
||||
this.log("Host information " + args.hostInfo, "Info");
|
||||
}
|
||||
}
|
||||
|
||||
closeLog() {
|
||||
@@ -623,7 +646,7 @@ module ts.server {
|
||||
/**
|
||||
* @param filename is absolute pathname
|
||||
*/
|
||||
openFile(fileName: string, openedByClient = false) {
|
||||
openFile(fileName: string, openedByClient: boolean, tabSize?: number) {
|
||||
fileName = ts.normalizePath(fileName);
|
||||
var info = ts.lookUp(this.filenameToScriptInfo, fileName);
|
||||
if (!info) {
|
||||
@@ -637,12 +660,26 @@ module ts.server {
|
||||
}
|
||||
}
|
||||
if (content !== undefined) {
|
||||
content = this.expandTabs(content);
|
||||
var indentSize: number;
|
||||
if (!tabSize) {
|
||||
tabSize = this.hostConfiguration.formatCodeOptions.TabSize;
|
||||
indentSize = this.hostConfiguration.formatCodeOptions.IndentSize;
|
||||
}
|
||||
else {
|
||||
indentSize = tabSize;
|
||||
}
|
||||
if (openedByClient) {
|
||||
this.log("Expanding tabs for file " + fileName + " with tab size " + tabSize.toString());
|
||||
content = expandTabs(content, tabSize);
|
||||
}
|
||||
info = new ScriptInfo(this.host, fileName, content, openedByClient);
|
||||
this.filenameToScriptInfo[fileName] = info;
|
||||
if (!info.isOpen) {
|
||||
info.fileWatcher = this.host.watchFile(fileName, _ => { this.watchedFileChanged(fileName); });
|
||||
}
|
||||
else {
|
||||
info.setFormatOptions(tabSize, indentSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (info) {
|
||||
@@ -658,9 +695,9 @@ module ts.server {
|
||||
* @param filename is absolute pathname
|
||||
*/
|
||||
|
||||
openClientFile(filename: string) {
|
||||
openClientFile(filename: string, tabSize?: number) {
|
||||
// TODO: tsconfig check
|
||||
var info = this.openFile(filename, true);
|
||||
var info = this.openFile(filename, true, tabSize);
|
||||
this.addOpenFile(info);
|
||||
this.printProjects();
|
||||
return info;
|
||||
@@ -760,7 +797,8 @@ module ts.server {
|
||||
var normRootFilename = ts.normalizePath(rootFilename);
|
||||
normRootFilename = getAbsolutePath(normRootFilename, dirPath);
|
||||
if (this.host.fileExists(normRootFilename)) {
|
||||
var info = this.openFile(normRootFilename);
|
||||
// TODO: pass true for file exiplicitly opened
|
||||
var info = this.openFile(normRootFilename, false);
|
||||
proj.addRoot(info);
|
||||
}
|
||||
else {
|
||||
@@ -1123,6 +1161,7 @@ module ts.server {
|
||||
|
||||
reloadFromFile(filename: string, tabSize: number, cb?: () => any) {
|
||||
var content = ts.sys.readFile(filename);
|
||||
content = expandTabs(content, tabSize);
|
||||
this.reload(content);
|
||||
if (cb)
|
||||
cb();
|
||||
|
||||
Vendored
+14
-1
@@ -312,6 +312,10 @@ declare module ts.server.protocol {
|
||||
* 'Sublime Text version 3075'
|
||||
*/
|
||||
hostInfo: string;
|
||||
/**
|
||||
* If present, tab settings apply only to this file.
|
||||
*/
|
||||
file?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -329,6 +333,14 @@ declare module ts.server.protocol {
|
||||
export interface ConfigureResponse extends Response {
|
||||
}
|
||||
|
||||
/**
|
||||
* Information found in an "open" request.
|
||||
*/
|
||||
export interface OpenRequestArgs extends FileRequestArgs {
|
||||
/** Initial tab size of file. */
|
||||
tabSize?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open request; value of command field is "open". Notify the
|
||||
* server that the client has file open. The server will not
|
||||
@@ -337,7 +349,8 @@ declare module ts.server.protocol {
|
||||
* reload messages) when the file changes. Server does not currently
|
||||
* send a response to an open request.
|
||||
*/
|
||||
export interface OpenRequest extends FileRequest {
|
||||
export interface OpenRequest extends Request {
|
||||
arguments: OpenRequestArgs;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/// <reference path="editorServices.ts" />
|
||||
|
||||
module ts.server {
|
||||
var spaceCache = [" ", " ", " ", " "];
|
||||
var spaceCache:string[] = [];
|
||||
|
||||
interface StackTraceError extends Error {
|
||||
stack?: string;
|
||||
@@ -397,9 +397,9 @@ module ts.server {
|
||||
};
|
||||
}
|
||||
|
||||
openClientFile(fileName: string) {
|
||||
openClientFile(fileName: string, tabSize?: number) {
|
||||
var file = ts.normalizePath(fileName);
|
||||
this.projectService.openClientFile(file);
|
||||
this.projectService.openClientFile(file, tabSize);
|
||||
}
|
||||
|
||||
getQuickInfo(line: number, col: number, fileName: string): protocol.QuickInfoResponseBody {
|
||||
@@ -441,7 +441,7 @@ module ts.server {
|
||||
|
||||
// TODO: avoid duplicate code (with formatonkey)
|
||||
var edits = compilerService.languageService.getFormattingEditsForRange(file, startPosition, endPosition,
|
||||
this.projectService.getFormatCodeOptions());
|
||||
this.projectService.getFormatCodeOptions(file));
|
||||
if (!edits) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -465,7 +465,7 @@ module ts.server {
|
||||
|
||||
var compilerService = project.compilerService;
|
||||
var position = compilerService.host.lineColToPosition(file, line, col);
|
||||
var formatOptions = this.projectService.getFormatCodeOptions();
|
||||
var formatOptions = this.projectService.getFormatCodeOptions(file);
|
||||
var edits = compilerService.languageService.getFormattingEditsAfterKeystroke(file, position, key,
|
||||
formatOptions);
|
||||
// Check whether we should auto-indent. This will be when
|
||||
@@ -611,8 +611,7 @@ module ts.server {
|
||||
if (project) {
|
||||
this.changeSeq++;
|
||||
// make sure no changes happen before this one is finished
|
||||
project.compilerService.host.reloadScript(file, tmpfile,
|
||||
this.projectService.getFormatCodeOptions().TabSize, () => {
|
||||
project.compilerService.host.reloadScript(file, tmpfile, () => {
|
||||
this.output(undefined, CommandNames.Reload, reqSeq);
|
||||
});
|
||||
}
|
||||
@@ -756,8 +755,8 @@ module ts.server {
|
||||
break;
|
||||
}
|
||||
case CommandNames.Open: {
|
||||
var openArgs = <protocol.FileRequestArgs>request.arguments;
|
||||
this.openClientFile(openArgs.file);
|
||||
var openArgs = <protocol.OpenRequestArgs>request.arguments;
|
||||
this.openClientFile(openArgs.file,openArgs.tabSize);
|
||||
responseRequired = false;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -173,6 +173,10 @@ module ts.BreakpointResolver {
|
||||
return textSpan(node, (<ThrowStatement>node).expression);
|
||||
|
||||
case SyntaxKind.ExportAssignment:
|
||||
if (!(<ExportAssignment>node).expression) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// span on export = id
|
||||
return textSpan(node, (<ExportAssignment>node).expression);
|
||||
|
||||
|
||||
@@ -1008,10 +1008,20 @@ module ts.formatting {
|
||||
return SyntaxKind.Unknown;
|
||||
}
|
||||
|
||||
let internedTabsIndentation: string[];
|
||||
let internedSpacesIndentation: string[];
|
||||
var internedSizes: { tabSize: number; indentSize: number };
|
||||
var internedTabsIndentation: string[];
|
||||
var internedSpacesIndentation: string[];
|
||||
|
||||
export function getIndentationString(indentation: number, options: FormatCodeOptions): string {
|
||||
// reset interned strings if FormatCodeOptions were changed
|
||||
let resetInternedStrings =
|
||||
!internedSizes || (internedSizes.tabSize !== options.TabSize || internedSizes.indentSize !== options.IndentSize);
|
||||
|
||||
if (resetInternedStrings) {
|
||||
internedSizes = { tabSize: options.TabSize, indentSize: options.IndentSize };
|
||||
internedTabsIndentation = internedSpacesIndentation = undefined;
|
||||
}
|
||||
|
||||
if (!options.ConvertTabsToSpaces) {
|
||||
let tabs = Math.floor(indentation / options.TabSize);
|
||||
let spaces = indentation - tabs * options.TabSize;
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
module ts.formatting {
|
||||
|
||||
var internedTabsIndentation: string[];
|
||||
var internedSpacesIndentation: string[];
|
||||
|
||||
export function getIndentationString(indentation: number, options: FormatCodeOptions): string {
|
||||
if (!options.ConvertTabsToSpaces) {
|
||||
var tabs = Math.floor(indentation / options.TabSize);
|
||||
var spaces = indentation - tabs * options.TabSize;
|
||||
|
||||
var tabString: string;
|
||||
if (!internedTabsIndentation) {
|
||||
internedTabsIndentation = [];
|
||||
}
|
||||
|
||||
if (internedTabsIndentation[tabs] === undefined) {
|
||||
internedTabsIndentation[tabs] = tabString = repeat('\t', tabs);
|
||||
}
|
||||
else {
|
||||
tabString = internedTabsIndentation[tabs];
|
||||
}
|
||||
|
||||
return spaces ? tabString + repeat(" ", spaces) : tabString;
|
||||
}
|
||||
else {
|
||||
var spacesString: string;
|
||||
var quotient = Math.floor(indentation / options.IndentSize);
|
||||
var remainder = indentation % options.IndentSize;
|
||||
if (!internedSpacesIndentation) {
|
||||
internedSpacesIndentation = [];
|
||||
}
|
||||
|
||||
if (internedSpacesIndentation[quotient] === undefined) {
|
||||
spacesString = repeat(" ", options.IndentSize * quotient);
|
||||
internedSpacesIndentation[quotient] = spacesString;
|
||||
}
|
||||
else {
|
||||
spacesString = internedSpacesIndentation[quotient];
|
||||
}
|
||||
|
||||
|
||||
return remainder ? spacesString + repeat(" ", remainder) : spacesString;
|
||||
}
|
||||
|
||||
function repeat(value: string, count: number): string {
|
||||
var s = "";
|
||||
for (var i = 0; i < count; ++i) {
|
||||
s += value;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -833,3 +833,5 @@ module ts {
|
||||
module TypeScript.Services {
|
||||
export var TypeScriptServicesFactory = ts.TypeScriptServicesFactory;
|
||||
}
|
||||
|
||||
let toolsVersion = "1.4";
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user