mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into parseClassInStrictMode
Conflicts: src/compiler/diagnosticInformationMap.generated.ts src/compiler/diagnosticMessages.json
This commit is contained in:
+11
-6
@@ -388,23 +388,28 @@ module ts {
|
||||
bindChildren(node, /*symbolKind:*/ 0, /*isBlockScopeContainer:*/ true);
|
||||
}
|
||||
|
||||
function bindBlockScopedVariableDeclaration(node: Declaration) {
|
||||
function bindBlockScopedDeclaration(node: Declaration, symbolKind: SymbolFlags, symbolExcludes: SymbolFlags) {
|
||||
switch (blockScopeContainer.kind) {
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
declareModuleMember(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes);
|
||||
declareModuleMember(node, symbolKind, symbolExcludes);
|
||||
break;
|
||||
case SyntaxKind.SourceFile:
|
||||
if (isExternalModule(<SourceFile>container)) {
|
||||
declareModuleMember(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes);
|
||||
declareModuleMember(node, symbolKind, symbolExcludes);
|
||||
break;
|
||||
}
|
||||
// fall through.
|
||||
default:
|
||||
if (!blockScopeContainer.locals) {
|
||||
blockScopeContainer.locals = {};
|
||||
}
|
||||
declareSymbol(blockScopeContainer.locals, undefined, node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes);
|
||||
declareSymbol(blockScopeContainer.locals, undefined, node, symbolKind, symbolExcludes);
|
||||
}
|
||||
bindChildren(node, SymbolFlags.BlockScopedVariable, /*isBlockScopeContainer*/ false);
|
||||
bindChildren(node, symbolKind, /*isBlockScopeContainer*/ false);
|
||||
}
|
||||
|
||||
function bindBlockScopedVariableDeclaration(node: Declaration) {
|
||||
bindBlockScopedDeclaration(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes);
|
||||
}
|
||||
|
||||
function getDestructuringParameterName(node: Declaration) {
|
||||
@@ -493,7 +498,7 @@ module ts {
|
||||
bindCatchVariableDeclaration(<CatchClause>node);
|
||||
break;
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.Class, SymbolFlags.ClassExcludes, /*isBlockScopeContainer*/ false);
|
||||
bindBlockScopedDeclaration(<Declaration>node, SymbolFlags.Class, SymbolFlags.ClassExcludes);
|
||||
break;
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
bindDeclaration(<Declaration>node, SymbolFlags.Interface, SymbolFlags.InterfaceExcludes, /*isBlockScopeContainer*/ false);
|
||||
|
||||
@@ -9760,6 +9760,10 @@ module ts {
|
||||
grammarErrorOnNode(node, Diagnostics.class_declarations_are_only_supported_directly_inside_a_module_or_as_a_top_level_declaration);
|
||||
}
|
||||
|
||||
if (!node.name && !(node.flags & NodeFlags.Default)) {
|
||||
grammarErrorOnFirstToken(node, Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name);
|
||||
}
|
||||
|
||||
checkGrammarClassDeclarationHeritageClauses(node);
|
||||
checkDecorators(node);
|
||||
if (node.name) {
|
||||
|
||||
@@ -168,6 +168,7 @@ module ts {
|
||||
Cannot_compile_non_external_modules_when_the_separateCompilation_flag_is_provided: { code: 1208, category: DiagnosticCategory.Error, key: "Cannot compile non-external modules when the '--separateCompilation' flag is provided." },
|
||||
Ambient_const_enums_are_not_allowed_when_the_separateCompilation_flag_is_provided: { code: 1209, category: DiagnosticCategory.Error, key: "Ambient const enums are not allowed when the '--separateCompilation' flag is provided." },
|
||||
Invalid_use_of_0_because_class_definition_is_considered_a_strict_mode_code: { code: 1210, category: DiagnosticCategory.Error, key: "Invalid use of '{0}' because class definition is considered a strict mode code " },
|
||||
A_class_declaration_without_the_default_modifier_must_have_a_name: { code: 1211, category: DiagnosticCategory.Error, key: "A class declaration without the 'default' modifier must have a name" },
|
||||
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." },
|
||||
@@ -506,6 +507,22 @@ module ts {
|
||||
Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: { code: 7024, category: DiagnosticCategory.Error, key: "Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions." },
|
||||
You_cannot_rename_this_element: { code: 8000, category: DiagnosticCategory.Error, key: "You cannot rename this element." },
|
||||
You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library: { code: 8001, category: DiagnosticCategory.Error, key: "You cannot rename elements that are defined in the standard TypeScript library." },
|
||||
import_can_only_be_used_in_a_ts_file: { code: 8002, category: DiagnosticCategory.Error, key: "'import ... =' can only be used in a .ts file." },
|
||||
export_can_only_be_used_in_a_ts_file: { code: 8003, category: DiagnosticCategory.Error, key: "'export=' can only be used in a .ts file." },
|
||||
type_parameter_declarations_can_only_be_used_in_a_ts_file: { code: 8004, category: DiagnosticCategory.Error, key: "'type parameter declarations' can only be used in a .ts file." },
|
||||
implements_clauses_can_only_be_used_in_a_ts_file: { code: 8005, category: DiagnosticCategory.Error, key: "'implements clauses' can only be used in a .ts file." },
|
||||
interface_declarations_can_only_be_used_in_a_ts_file: { code: 8006, category: DiagnosticCategory.Error, key: "'interface declarations' can only be used in a .ts file." },
|
||||
module_declarations_can_only_be_used_in_a_ts_file: { code: 8007, category: DiagnosticCategory.Error, key: "'module declarations' can only be used in a .ts file." },
|
||||
type_aliases_can_only_be_used_in_a_ts_file: { code: 8008, category: DiagnosticCategory.Error, key: "'type aliases' can only be used in a .ts file." },
|
||||
_0_can_only_be_used_in_a_ts_file: { code: 8009, category: DiagnosticCategory.Error, key: "'{0}' can only be used in a .ts file." },
|
||||
types_can_only_be_used_in_a_ts_file: { code: 8010, category: DiagnosticCategory.Error, key: "'types' can only be used in a .ts file." },
|
||||
type_arguments_can_only_be_used_in_a_ts_file: { code: 8011, category: DiagnosticCategory.Error, key: "'type arguments' can only be used in a .ts file." },
|
||||
parameter_modifiers_can_only_be_used_in_a_ts_file: { code: 8012, category: DiagnosticCategory.Error, key: "'parameter modifiers' can only be used in a .ts file." },
|
||||
can_only_be_used_in_a_ts_file: { code: 8013, category: DiagnosticCategory.Error, key: "'?' can only be used in a .ts file." },
|
||||
property_declarations_can_only_be_used_in_a_ts_file: { code: 8014, category: DiagnosticCategory.Error, key: "'property declarations' can only be used in a .ts file." },
|
||||
enum_declarations_can_only_be_used_in_a_ts_file: { code: 8015, category: DiagnosticCategory.Error, key: "'enum declarations' can only be used in a .ts file." },
|
||||
type_assertion_expressions_can_only_be_used_in_a_ts_file: { code: 8016, category: DiagnosticCategory.Error, key: "'type assertion expressions' can only be used in a .ts file." },
|
||||
decorators_can_only_be_used_in_a_ts_file: { code: 8017, category: DiagnosticCategory.Error, key: "'decorators' can only be used in a .ts file." },
|
||||
yield_expressions_are_not_currently_supported: { code: 9000, category: DiagnosticCategory.Error, key: "'yield' expressions are not currently supported." },
|
||||
Generators_are_not_currently_supported: { code: 9001, category: DiagnosticCategory.Error, key: "Generators are not currently supported." },
|
||||
Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_class_extends_clauses: { code: 9002, category: DiagnosticCategory.Error, key: "Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clauses." },
|
||||
|
||||
@@ -663,6 +663,10 @@
|
||||
"category": "Error",
|
||||
"code": 1210
|
||||
},
|
||||
"A class declaration without the 'default' modifier must have a name": {
|
||||
"category": "Error",
|
||||
"code": 1211
|
||||
},
|
||||
"Duplicate identifier '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 2300
|
||||
@@ -2017,6 +2021,71 @@
|
||||
"category": "Error",
|
||||
"code": 8001
|
||||
},
|
||||
"'import ... =' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8002
|
||||
},
|
||||
"'export=' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8003
|
||||
},
|
||||
"'type parameter declarations' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8004
|
||||
},
|
||||
"'implements clauses' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8005
|
||||
},
|
||||
"'interface declarations' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8006
|
||||
},
|
||||
"'module declarations' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8007
|
||||
},
|
||||
"'type aliases' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8008
|
||||
},
|
||||
"'{0}' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8009
|
||||
},
|
||||
"'types' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8010
|
||||
},
|
||||
"'type arguments' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8011
|
||||
},
|
||||
"'parameter modifiers' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8012
|
||||
},
|
||||
"'?' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8013
|
||||
},
|
||||
"'property declarations' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8014
|
||||
},
|
||||
"'enum declarations' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8015
|
||||
},
|
||||
"'type assertion expressions' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8016
|
||||
},
|
||||
"'decorators' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8017
|
||||
},
|
||||
|
||||
"'yield' expressions are not currently supported.": {
|
||||
"category": "Error",
|
||||
"code": 9000
|
||||
|
||||
+94
-30
@@ -262,6 +262,7 @@ module ts {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.ClassExpression:
|
||||
generateNameForFunctionOrClassDeclaration(<Declaration>node);
|
||||
break;
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
@@ -3198,28 +3199,49 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
function emitMemberAssignments(node: ClassLikeDeclaration, staticFlag: NodeFlags) {
|
||||
forEach(node.members, member => {
|
||||
if (member.kind === SyntaxKind.PropertyDeclaration && (member.flags & NodeFlags.Static) === staticFlag && (<PropertyDeclaration>member).initializer) {
|
||||
writeLine();
|
||||
emitLeadingComments(member);
|
||||
emitStart(member);
|
||||
emitStart((<PropertyDeclaration>member).name);
|
||||
if (staticFlag) {
|
||||
emitDeclarationName(node);
|
||||
}
|
||||
else {
|
||||
write("this");
|
||||
}
|
||||
emitMemberAccessForPropertyName((<PropertyDeclaration>member).name);
|
||||
emitEnd((<PropertyDeclaration>member).name);
|
||||
write(" = ");
|
||||
emit((<PropertyDeclaration>member).initializer);
|
||||
write(";");
|
||||
emitEnd(member);
|
||||
emitTrailingComments(member);
|
||||
function getInitializedProperties(node: ClassLikeDeclaration, static: boolean) {
|
||||
let properties: PropertyDeclaration[] = [];
|
||||
for (let member of node.members) {
|
||||
if (member.kind === SyntaxKind.PropertyDeclaration && static === ((member.flags & NodeFlags.Static) !== 0) && (<PropertyDeclaration>member).initializer) {
|
||||
properties.push(<PropertyDeclaration>member);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
function emitPropertyDeclarations(node: ClassLikeDeclaration, properties: PropertyDeclaration[]) {
|
||||
for (let property of properties) {
|
||||
emitPropertyDeclaration(node, property);
|
||||
}
|
||||
}
|
||||
|
||||
function emitPropertyDeclaration(node: ClassLikeDeclaration, property: PropertyDeclaration, receiver?: Identifier, isExpression?: boolean) {
|
||||
writeLine();
|
||||
emitLeadingComments(property);
|
||||
emitStart(property);
|
||||
emitStart(property.name);
|
||||
if (receiver) {
|
||||
emit(receiver);
|
||||
}
|
||||
else {
|
||||
if (property.flags & NodeFlags.Static) {
|
||||
emitDeclarationName(node);
|
||||
}
|
||||
else {
|
||||
write("this");
|
||||
}
|
||||
}
|
||||
emitMemberAccessForPropertyName(property.name);
|
||||
emitEnd(property.name);
|
||||
write(" = ");
|
||||
emit(property.initializer);
|
||||
if (!isExpression) {
|
||||
write(";");
|
||||
}
|
||||
|
||||
emitEnd(property);
|
||||
emitTrailingComments(property);
|
||||
}
|
||||
|
||||
function emitMemberFunctionsForES5AndLower(node: ClassLikeDeclaration) {
|
||||
@@ -3337,6 +3359,14 @@ module ts {
|
||||
tempVariables = undefined;
|
||||
tempParameters = undefined;
|
||||
|
||||
emitConstructorWorker(node, baseTypeElement);
|
||||
|
||||
tempFlags = saveTempFlags;
|
||||
tempVariables = saveTempVariables;
|
||||
tempParameters = saveTempParameters;
|
||||
}
|
||||
|
||||
function emitConstructorWorker(node: ClassLikeDeclaration, baseTypeElement: HeritageClauseElement) {
|
||||
// Check if we have property assignment inside class declaration.
|
||||
// If there is property assignment, we need to emit constructor whether users define it or not
|
||||
// If there is no property assignment, we can omit constructor if users do not define it
|
||||
@@ -3424,7 +3454,7 @@ module ts {
|
||||
emitEnd(baseTypeElement);
|
||||
}
|
||||
}
|
||||
emitMemberAssignments(node, /*staticFlag*/0);
|
||||
emitPropertyDeclarations(node, getInitializedProperties(node, /*static:*/ false));
|
||||
if (ctor) {
|
||||
var statements: Node[] = (<Block>ctor.body).statements;
|
||||
if (superCall) {
|
||||
@@ -3444,10 +3474,6 @@ module ts {
|
||||
if (ctor) {
|
||||
emitTrailingComments(ctor);
|
||||
}
|
||||
|
||||
tempFlags = saveTempFlags;
|
||||
tempVariables = saveTempVariables;
|
||||
tempParameters = saveTempParameters;
|
||||
}
|
||||
|
||||
function emitClassExpression(node: ClassExpression) {
|
||||
@@ -3539,6 +3565,29 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
// If the class has static properties, and it's a class expression, then we'll need
|
||||
// to specialize the emit a bit. for a class expression of the form:
|
||||
//
|
||||
// class C { static a = 1; static b = 2; ... }
|
||||
//
|
||||
// We'll emit:
|
||||
//
|
||||
// (_temp = class C { ... }, _temp.a = 1, _temp.b = 2, _temp)
|
||||
//
|
||||
// This keeps the expression as an expression, while ensuring that the static parts
|
||||
// of it have been initialized by the time it is used.
|
||||
let staticProperties = getInitializedProperties(node, /*static:*/ true);
|
||||
let isClassExpressionWithStaticProperties = staticProperties.length > 0 && node.kind === SyntaxKind.ClassExpression;
|
||||
let tempVariable: Identifier;
|
||||
|
||||
if (isClassExpressionWithStaticProperties) {
|
||||
tempVariable = createAndRecordTempVariable(TempFlags.Auto);
|
||||
write("(");
|
||||
increaseIndent();
|
||||
emit(tempVariable);
|
||||
write(" = ")
|
||||
}
|
||||
|
||||
write("class");
|
||||
|
||||
// check if this is an "export default class" as it may not have a name. Do not emit the name if the class is decorated.
|
||||
@@ -3589,9 +3638,24 @@ module ts {
|
||||
// From ES6 specification:
|
||||
// HasLexicalDeclaration (N) : Determines if the argument identifier has a binding in this environment record that was created using
|
||||
// a lexical declaration such as a LexicalDeclaration or a ClassDeclaration.
|
||||
writeLine();
|
||||
emitMemberAssignments(node, NodeFlags.Static);
|
||||
emitDecoratorsOfClass(node);
|
||||
|
||||
if (isClassExpressionWithStaticProperties) {
|
||||
for (var property of staticProperties) {
|
||||
write(",");
|
||||
writeLine();
|
||||
emitPropertyDeclaration(node, property, /*receiver:*/ tempVariable, /*isExpression:*/ true);
|
||||
}
|
||||
write(",");
|
||||
writeLine();
|
||||
emit(tempVariable);
|
||||
decreaseIndent();
|
||||
write(")");
|
||||
}
|
||||
else {
|
||||
writeLine();
|
||||
emitPropertyDeclarations(node, staticProperties);
|
||||
emitDecoratorsOfClass(node);
|
||||
}
|
||||
|
||||
// If this is an exported class, but not on the top level (i.e. on an internal
|
||||
// module), export it
|
||||
@@ -3647,7 +3711,7 @@ module ts {
|
||||
writeLine();
|
||||
emitConstructor(node, baseTypeNode);
|
||||
emitMemberFunctionsForES5AndLower(node);
|
||||
emitMemberAssignments(node, NodeFlags.Static);
|
||||
emitPropertyDeclarations(node, getInitializedProperties(node, /*static:*/ true));
|
||||
writeLine();
|
||||
emitDecoratorsOfClass(node);
|
||||
writeLine();
|
||||
|
||||
@@ -828,7 +828,7 @@ module ts {
|
||||
// to reuse are already at the appropriate position in the new text. That way when we
|
||||
// reuse them, we don't have to figure out if they need to be adjusted. Second, it makes
|
||||
// it very easy to determine if we can reuse a node. If the node's position is at where
|
||||
// we are in the text, then we can reuse it. Otherwise we can't. If hte node's position
|
||||
// we are in the text, then we can reuse it. Otherwise we can't. If the node's position
|
||||
// is ahead of us, then we'll need to rescan tokens. If the node's position is behind
|
||||
// us, then we'll need to skip it or crumble it as appropriate
|
||||
//
|
||||
@@ -1033,7 +1033,7 @@ module ts {
|
||||
// that some tokens that would be considered identifiers may be considered keywords.
|
||||
//
|
||||
// When adding more parser context flags, consider which is the more common case that the
|
||||
// flag will be in. This should be hte 'false' state for that flag. The reason for this is
|
||||
// flag will be in. This should be the 'false' state for that flag. The reason for this is
|
||||
// that we don't store data in our nodes unless the value is in the *non-default* state. So,
|
||||
// for example, more often than code 'allows-in' (or doesn't 'disallow-in'). We opt for
|
||||
// 'disallow-in' set to 'false'. Otherwise, if we had 'allowsIn' set to 'true', then almost
|
||||
@@ -1044,7 +1044,7 @@ module ts {
|
||||
//
|
||||
// An important thing about these context concepts. By default they are effectively inherited
|
||||
// while parsing through every grammar production. i.e. if you don't change them, then when
|
||||
// you parse a sub-production, it will have the same context values as hte parent production.
|
||||
// you parse a sub-production, it will have the same context values as the parent production.
|
||||
// This is great most of the time. After all, consider all the 'expression' grammar productions
|
||||
// and how nearly all of them pass along the 'in' and 'yield' context values:
|
||||
//
|
||||
@@ -1836,7 +1836,7 @@ module ts {
|
||||
// some node, then we cannot get a node from the old source tree. This is because we
|
||||
// want to mark the next node we encounter as being unusable.
|
||||
//
|
||||
// Note: This may be too conservative. Perhaps we could reuse hte node and set the bit
|
||||
// Note: This may be too conservative. Perhaps we could reuse the node and set the bit
|
||||
// on it (or its leftmost child) as having the error. For now though, being conservative
|
||||
// is nice and likely won't ever affect perf.
|
||||
if (parseErrorBeforeNextFinishedNode) {
|
||||
@@ -4762,7 +4762,7 @@ module ts {
|
||||
node.decorators = decorators;
|
||||
setModifiers(node, modifiers);
|
||||
parseExpected(SyntaxKind.ClassKeyword);
|
||||
node.name = node.flags & NodeFlags.Default ? parseOptionalIdentifier() : parseIdentifier();
|
||||
node.name = parseOptionalIdentifier();
|
||||
node.typeParameters = parseTypeParameters();
|
||||
node.heritageClauses = parseHeritageClauses(/*isClassHeritageClause:*/ true);
|
||||
|
||||
|
||||
+30
-18
@@ -14,6 +14,7 @@
|
||||
//
|
||||
|
||||
/// <reference path='..\services\services.ts' />
|
||||
/// <reference path='..\services\shims.ts' />
|
||||
/// <reference path='harnessLanguageService.ts' />
|
||||
/// <reference path='harness.ts' />
|
||||
/// <reference path='fourslashRunner.ts' />
|
||||
@@ -115,7 +116,7 @@ module FourSlash {
|
||||
// Name of testcase metadata including ts.CompilerOptions properties that will be used by globalOptions
|
||||
// To add additional option, add property into the testOptMetadataNames, refer the property in either globalMetadataNames or fileMetadataNames
|
||||
// Add cases into convertGlobalOptionsToCompilationsSettings function for the compiler to acknowledge such option from meta data
|
||||
var testOptMetadataNames = {
|
||||
var metadataOptionNames = {
|
||||
baselineFile: 'BaselineFile',
|
||||
declaration: 'declaration',
|
||||
emitThisFile: 'emitThisFile', // This flag is used for testing getEmitOutput feature. It allows test-cases to indicate what file to be output in multiple files project
|
||||
@@ -126,14 +127,15 @@ module FourSlash {
|
||||
outDir: 'outDir',
|
||||
sourceMap: 'sourceMap',
|
||||
sourceRoot: 'sourceRoot',
|
||||
allowNonTsExtensions: 'allowNonTsExtensions',
|
||||
resolveReference: 'ResolveReference', // This flag is used to specify entry file for resolve file references. The flag is only allow once per test file
|
||||
};
|
||||
|
||||
// List of allowed metadata names
|
||||
var fileMetadataNames = [testOptMetadataNames.fileName, testOptMetadataNames.emitThisFile, testOptMetadataNames.resolveReference];
|
||||
var globalMetadataNames = [testOptMetadataNames.baselineFile, testOptMetadataNames.declaration,
|
||||
testOptMetadataNames.mapRoot, testOptMetadataNames.module, testOptMetadataNames.out,
|
||||
testOptMetadataNames.outDir, testOptMetadataNames.sourceMap, testOptMetadataNames.sourceRoot]
|
||||
var fileMetadataNames = [metadataOptionNames.fileName, metadataOptionNames.emitThisFile, metadataOptionNames.resolveReference];
|
||||
var globalMetadataNames = [metadataOptionNames.allowNonTsExtensions, metadataOptionNames.baselineFile, metadataOptionNames.declaration,
|
||||
metadataOptionNames.mapRoot, metadataOptionNames.module, metadataOptionNames.out,
|
||||
metadataOptionNames.outDir, metadataOptionNames.sourceMap, metadataOptionNames.sourceRoot]
|
||||
|
||||
function convertGlobalOptionsToCompilerOptions(globalOptions: { [idx: string]: string }): ts.CompilerOptions {
|
||||
var settings: ts.CompilerOptions = { target: ts.ScriptTarget.ES5 };
|
||||
@@ -141,13 +143,16 @@ module FourSlash {
|
||||
for (var prop in globalOptions) {
|
||||
if (globalOptions.hasOwnProperty(prop)) {
|
||||
switch (prop) {
|
||||
case testOptMetadataNames.declaration:
|
||||
case metadataOptionNames.allowNonTsExtensions:
|
||||
settings.allowNonTsExtensions = true;
|
||||
break;
|
||||
case metadataOptionNames.declaration:
|
||||
settings.declaration = true;
|
||||
break;
|
||||
case testOptMetadataNames.mapRoot:
|
||||
case metadataOptionNames.mapRoot:
|
||||
settings.mapRoot = globalOptions[prop];
|
||||
break;
|
||||
case testOptMetadataNames.module:
|
||||
case metadataOptionNames.module:
|
||||
// create appropriate external module target for CompilationSettings
|
||||
switch (globalOptions[prop]) {
|
||||
case "AMD":
|
||||
@@ -162,16 +167,16 @@ module FourSlash {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case testOptMetadataNames.out:
|
||||
case metadataOptionNames.out:
|
||||
settings.out = globalOptions[prop];
|
||||
break;
|
||||
case testOptMetadataNames.outDir:
|
||||
case metadataOptionNames.outDir:
|
||||
settings.outDir = globalOptions[prop];
|
||||
break;
|
||||
case testOptMetadataNames.sourceMap:
|
||||
case metadataOptionNames.sourceMap:
|
||||
settings.sourceMap = true;
|
||||
break;
|
||||
case testOptMetadataNames.sourceRoot:
|
||||
case metadataOptionNames.sourceRoot:
|
||||
settings.sourceRoot = globalOptions[prop];
|
||||
break;
|
||||
}
|
||||
@@ -303,7 +308,7 @@ module FourSlash {
|
||||
ts.forEach(testData.files, file => {
|
||||
// Create map between fileName and its content for easily looking up when resolveReference flag is specified
|
||||
this.inputFiles[file.fileName] = file.content;
|
||||
if (!startResolveFileRef && file.fileOptions[testOptMetadataNames.resolveReference]) {
|
||||
if (!startResolveFileRef && file.fileOptions[metadataOptionNames.resolveReference]) {
|
||||
startResolveFileRef = file;
|
||||
} else if (startResolveFileRef) {
|
||||
// If entry point for resolving file references is already specified, report duplication error
|
||||
@@ -793,6 +798,13 @@ module FourSlash {
|
||||
return "\nActual " + name + ":\n\t" + actualValue + "\nExpected value:\n\t" + expectedValue;
|
||||
}
|
||||
|
||||
public getSemanticDiagnostics(expected: string) {
|
||||
var diagnostics = this.languageService.getSemanticDiagnostics(this.activeFile.fileName);
|
||||
var realized = ts.realizeDiagnostics(diagnostics, "\r\n");
|
||||
var actual = JSON.stringify(realized, null, " ");
|
||||
assert.equal(actual, expected);
|
||||
}
|
||||
|
||||
public verifyQuickInfoString(negative: boolean, expectedText?: string, expectedDocumentation?: string) {
|
||||
[expectedText, expectedDocumentation].forEach(str => {
|
||||
if (str) {
|
||||
@@ -1131,7 +1143,7 @@ module FourSlash {
|
||||
|
||||
Harness.Baseline.runBaseline(
|
||||
"Breakpoint Locations for " + this.activeFile.fileName,
|
||||
this.testData.globalOptions[testOptMetadataNames.baselineFile],
|
||||
this.testData.globalOptions[metadataOptionNames.baselineFile],
|
||||
() => {
|
||||
return this.baselineCurrentFileLocations(pos => this.getBreakpointStatementLocation(pos));
|
||||
},
|
||||
@@ -1146,7 +1158,7 @@ module FourSlash {
|
||||
var allFourSlashFiles = this.testData.files;
|
||||
for (var idx = 0; idx < allFourSlashFiles.length; ++idx) {
|
||||
var file = allFourSlashFiles[idx];
|
||||
if (file.fileOptions[testOptMetadataNames.emitThisFile]) {
|
||||
if (file.fileOptions[metadataOptionNames.emitThisFile]) {
|
||||
// Find a file with the flag emitThisFile turned on
|
||||
emitFiles.push(file);
|
||||
}
|
||||
@@ -1159,7 +1171,7 @@ module FourSlash {
|
||||
|
||||
Harness.Baseline.runBaseline(
|
||||
"Generate getEmitOutput baseline : " + emitFiles.join(" "),
|
||||
this.testData.globalOptions[testOptMetadataNames.baselineFile],
|
||||
this.testData.globalOptions[metadataOptionNames.baselineFile],
|
||||
() => {
|
||||
var resultString = "";
|
||||
// Loop through all the emittedFiles and emit them one by one
|
||||
@@ -1704,7 +1716,7 @@ module FourSlash {
|
||||
|
||||
Harness.Baseline.runBaseline(
|
||||
"Name OrDottedNameSpans for " + this.activeFile.fileName,
|
||||
this.testData.globalOptions[testOptMetadataNames.baselineFile],
|
||||
this.testData.globalOptions[metadataOptionNames.baselineFile],
|
||||
() => {
|
||||
return this.baselineCurrentFileLocations(pos =>
|
||||
this.getNameOrDottedNameSpan(pos));
|
||||
@@ -2280,7 +2292,7 @@ module FourSlash {
|
||||
if (globalMetadataNamesIndex === -1) {
|
||||
if (fileMetadataNamesIndex === -1) {
|
||||
throw new Error('Unrecognized metadata name "' + match[1] + '". Available global metadata names are: ' + globalMetadataNames.join(', ') + '; file metadata names are: ' + fileMetadataNames.join(', '));
|
||||
} else if (fileMetadataNamesIndex === fileMetadataNames.indexOf(testOptMetadataNames.fileName)) {
|
||||
} else if (fileMetadataNamesIndex === fileMetadataNames.indexOf(metadataOptionNames.fileName)) {
|
||||
// Found an @FileName directive, if this is not the first then create a new subfile
|
||||
if (currentFileContent) {
|
||||
var file = parseFileContent(currentFileContent, currentFileName, markerPositions, markers, ranges);
|
||||
|
||||
Vendored
+18
-1
@@ -617,12 +617,29 @@ declare module ts.server.protocol {
|
||||
* Optional modifiers for the kind (such as 'public').
|
||||
*/
|
||||
kindModifiers: string;
|
||||
/**
|
||||
* A string that is used for comparing completion items so that they can be ordered. This
|
||||
* is often the same as the name but may be different in certain circumstances.
|
||||
*/
|
||||
sortText: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional completion entry details, available on demand
|
||||
*/
|
||||
export interface CompletionEntryDetails extends CompletionEntry {
|
||||
export interface CompletionEntryDetails {
|
||||
/**
|
||||
* The symbol's name.
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* The symbol's kind (such as 'className' or 'parameterName').
|
||||
*/
|
||||
kind: string;
|
||||
/**
|
||||
* Optional modifiers for the kind (such as 'public').
|
||||
*/
|
||||
kindModifiers: string;
|
||||
/**
|
||||
* Display parts of the symbol (similar to quick info).
|
||||
*/
|
||||
|
||||
@@ -22,7 +22,7 @@ module ts.NavigateTo {
|
||||
continue;
|
||||
}
|
||||
|
||||
// It was a match! If the pattern has dots in it, then also see if hte
|
||||
// It was a match! If the pattern has dots in it, then also see if the
|
||||
// declaration container matches as well.
|
||||
if (patternMatcher.patternContainsDots) {
|
||||
let containers = getContainers(declaration);
|
||||
|
||||
@@ -418,10 +418,10 @@ module ts.NavigationBar {
|
||||
}
|
||||
|
||||
function createFunctionItem(node: FunctionDeclaration) {
|
||||
if ((node.name || node.flags & NodeFlags.Default) && node.body && node.body.kind === SyntaxKind.Block) {
|
||||
if (node.body && node.body.kind === SyntaxKind.Block) {
|
||||
let childItems = getItemsWorker(sortNodes((<Block>node.body).statements), createChildItem);
|
||||
|
||||
return getNavigationBarItem((!node.name && node.flags & NodeFlags.Default) ? "default": node.name.text ,
|
||||
return getNavigationBarItem(!node.name ? "default": node.name.text ,
|
||||
ts.ScriptElementKind.functionElement,
|
||||
getNodeModifiers(node),
|
||||
[getNodeSpan(node)],
|
||||
@@ -470,7 +470,7 @@ module ts.NavigationBar {
|
||||
childItems = getItemsWorker(sortNodes(nodes), createChildItem);
|
||||
}
|
||||
|
||||
var nodeName = !node.name && (node.flags & NodeFlags.Default) ? "default" : node.name.text;
|
||||
var nodeName = !node.name ? "default" : node.name.text;
|
||||
|
||||
return getNavigationBarItem(
|
||||
nodeName,
|
||||
|
||||
@@ -471,7 +471,7 @@ module ts {
|
||||
|
||||
// Helper function to compare two matches to determine which is better. Matches are first
|
||||
// ordered by kind (so all prefix matches always beat all substring matches). Then, if the
|
||||
// match is a camel case match, the relative weights of hte match are used to determine
|
||||
// match is a camel case match, the relative weights of the match are used to determine
|
||||
// which is better (with a greater weight being better). Then if the match is of the same
|
||||
// type, then a case sensitive match is considered better than an insensitive one.
|
||||
function patternMatchCompareTo(match1: PatternMatch, match2: PatternMatch): number {
|
||||
|
||||
+288
-52
@@ -1148,6 +1148,7 @@ module ts {
|
||||
name: string;
|
||||
kind: string; // see ScriptElementKind
|
||||
kindModifiers: string; // see ScriptElementKindModifier, comma separated
|
||||
sortText: string;
|
||||
}
|
||||
|
||||
export interface CompletionEntryDetails {
|
||||
@@ -1316,6 +1317,7 @@ module ts {
|
||||
// TODO: move these to enums
|
||||
export class ScriptElementKind {
|
||||
static unknown = "";
|
||||
static warning = "warning";
|
||||
|
||||
// predefined type (void) or keyword (class)
|
||||
static keyword = "keyword";
|
||||
@@ -2166,7 +2168,8 @@ module ts {
|
||||
keywordCompletions.push({
|
||||
name: tokenToString(i),
|
||||
kind: ScriptElementKind.keyword,
|
||||
kindModifiers: ScriptElementKindModifier.none
|
||||
kindModifiers: ScriptElementKindModifier.none,
|
||||
sortText: "0"
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2430,15 +2433,26 @@ module ts {
|
||||
return program.getSyntacticDiagnostics(getValidSourceFile(fileName));
|
||||
}
|
||||
|
||||
function isJavaScript(fileName: string) {
|
||||
return fileExtensionIs(fileName, ".js");
|
||||
}
|
||||
|
||||
/**
|
||||
* getSemanticDiagnostiscs return array of Diagnostics. If '-d' is not enabled, only report semantic errors
|
||||
* If '-d' enabled, report both semantic and emitter errors
|
||||
*/
|
||||
function getSemanticDiagnostics(fileName: string) {
|
||||
function getSemanticDiagnostics(fileName: string): Diagnostic[] {
|
||||
synchronizeHostData();
|
||||
|
||||
let targetSourceFile = getValidSourceFile(fileName);
|
||||
|
||||
// For JavaScript files, we don't want to report the normal typescript semantic errors.
|
||||
// Instead, we just report errors for using TypeScript-only constructs from within a
|
||||
// JavaScript file.
|
||||
if (isJavaScript(fileName)) {
|
||||
return getJavaScriptSemanticDiagnostics(targetSourceFile);
|
||||
}
|
||||
|
||||
// Only perform the action per file regardless of '-out' flag as LanguageServiceHost is expected to call this function per file.
|
||||
// Therefore only get diagnostics for given file.
|
||||
|
||||
@@ -2452,35 +2466,199 @@ module ts {
|
||||
return concatenate(semanticDiagnostics, declarationDiagnostics);
|
||||
}
|
||||
|
||||
function getJavaScriptSemanticDiagnostics(sourceFile: SourceFile): Diagnostic[] {
|
||||
let diagnostics: Diagnostic[] = [];
|
||||
walk(sourceFile);
|
||||
|
||||
return diagnostics;
|
||||
|
||||
function walk(node: Node): boolean {
|
||||
if (!node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.import_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.ExportAssignment:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.export_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
let classDeclaration = <ClassDeclaration>node;
|
||||
if (checkModifiers(classDeclaration.modifiers) ||
|
||||
checkTypeParameters(classDeclaration.typeParameters)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.HeritageClause:
|
||||
let heritageClause = <HeritageClause>node;
|
||||
if (heritageClause.token === SyntaxKind.ImplementsKeyword) {
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.implements_clauses_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.interface_declarations_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.module_declarations_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.type_aliases_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.MethodSignature:
|
||||
case SyntaxKind.Constructor:
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
let functionDeclaration = <FunctionLikeDeclaration>node;
|
||||
if (checkModifiers(functionDeclaration.modifiers) ||
|
||||
checkTypeParameters(functionDeclaration.typeParameters) ||
|
||||
checkTypeAnnotation(functionDeclaration.type)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.VariableStatement:
|
||||
let variableStatement = <VariableStatement>node;
|
||||
if (checkModifiers(variableStatement.modifiers)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
let variableDeclaration = <VariableDeclaration>node;
|
||||
if (checkTypeAnnotation(variableDeclaration.type)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.CallExpression:
|
||||
case SyntaxKind.NewExpression:
|
||||
let expression = <CallExpression>node;
|
||||
if (expression.typeArguments && expression.typeArguments.length > 0) {
|
||||
let start = expression.typeArguments.pos;
|
||||
diagnostics.push(createFileDiagnostic(sourceFile, start, expression.typeArguments.end - start,
|
||||
Diagnostics.type_arguments_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.Parameter:
|
||||
let parameter = <ParameterDeclaration>node;
|
||||
if (parameter.modifiers) {
|
||||
let start = parameter.modifiers.pos;
|
||||
diagnostics.push(createFileDiagnostic(sourceFile, start, parameter.modifiers.end - start,
|
||||
Diagnostics.parameter_modifiers_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
if (parameter.questionToken) {
|
||||
diagnostics.push(createDiagnosticForNode(parameter.questionToken, Diagnostics.can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
if (parameter.type) {
|
||||
diagnostics.push(createDiagnosticForNode(parameter.type, Diagnostics.types_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.property_declarations_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.enum_declarations_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.TypeAssertionExpression:
|
||||
let typeAssertionExpression = <TypeAssertion>node;
|
||||
diagnostics.push(createDiagnosticForNode(typeAssertionExpression.type, Diagnostics.type_assertion_expressions_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
case SyntaxKind.Decorator:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.decorators_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
|
||||
return forEachChild(node, walk);
|
||||
}
|
||||
|
||||
function checkTypeParameters(typeParameters: NodeArray<TypeParameterDeclaration>): boolean {
|
||||
if (typeParameters) {
|
||||
let start = typeParameters.pos;
|
||||
diagnostics.push(createFileDiagnostic(sourceFile, start, typeParameters.end - start, Diagnostics.type_parameter_declarations_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkTypeAnnotation(type: TypeNode): boolean {
|
||||
if (type) {
|
||||
diagnostics.push(createDiagnosticForNode(type, Diagnostics.types_can_only_be_used_in_a_ts_file));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkModifiers(modifiers: ModifiersArray): boolean {
|
||||
if (modifiers) {
|
||||
for (let modifier of modifiers) {
|
||||
switch (modifier.kind) {
|
||||
case SyntaxKind.PublicKeyword:
|
||||
case SyntaxKind.PrivateKeyword:
|
||||
case SyntaxKind.ProtectedKeyword:
|
||||
case SyntaxKind.DeclareKeyword:
|
||||
diagnostics.push(createDiagnosticForNode(modifier, Diagnostics._0_can_only_be_used_in_a_ts_file, tokenToString(modifier.kind)));
|
||||
return true;
|
||||
|
||||
// These are all legal modifiers.
|
||||
case SyntaxKind.StaticKeyword:
|
||||
case SyntaxKind.ExportKeyword:
|
||||
case SyntaxKind.ConstKeyword:
|
||||
case SyntaxKind.DefaultKeyword:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function getCompilerOptionsDiagnostics() {
|
||||
synchronizeHostData();
|
||||
return program.getGlobalDiagnostics();
|
||||
}
|
||||
|
||||
/// Completion
|
||||
function getCompletionEntryDisplayName(symbol: Symbol, target: ScriptTarget, performCharacterChecks: boolean): string {
|
||||
function getCompletionEntryDisplayNameForSymbol(symbol: Symbol, target: ScriptTarget, performCharacterChecks: boolean): string {
|
||||
let displayName = symbol.getName();
|
||||
if (displayName) {
|
||||
// If this is the default export, get the name of the declaration if it exists
|
||||
if (displayName === "default") {
|
||||
let localSymbol = getLocalSymbolForExportDefault(symbol);
|
||||
if (localSymbol && localSymbol.name) {
|
||||
displayName = symbol.valueDeclaration.localSymbol.name;
|
||||
}
|
||||
}
|
||||
|
||||
let firstCharCode = displayName.charCodeAt(0);
|
||||
// First check of the displayName is not external module; if it is an external module, it is not valid entry
|
||||
if ((symbol.flags & SymbolFlags.Namespace) && (firstCharCode === CharacterCodes.singleQuote || firstCharCode === CharacterCodes.doubleQuote)) {
|
||||
// If the symbol is external module, don't show it in the completion list
|
||||
// (i.e declare module "http" { let x; } | // <= request completion here, "http" should not be there)
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
return getCompletionEntryDisplayName(displayName, target, performCharacterChecks);
|
||||
}
|
||||
|
||||
function getCompletionEntryDisplayName(displayName: string, target: ScriptTarget, performCharacterChecks: boolean): string {
|
||||
if (!displayName) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// If this is the default export, get the name of the declaration if it exists
|
||||
if (displayName === "default") {
|
||||
let localSymbol = getLocalSymbolForExportDefault(symbol);
|
||||
if (localSymbol && localSymbol.name) {
|
||||
displayName = symbol.valueDeclaration.localSymbol.name;
|
||||
}
|
||||
}
|
||||
|
||||
let firstCharCode = displayName.charCodeAt(0);
|
||||
// First check of the displayName is not external module; if it is an external module, it is not valid entry
|
||||
if ((symbol.flags & SymbolFlags.Namespace) && (firstCharCode === CharacterCodes.singleQuote || firstCharCode === CharacterCodes.doubleQuote)) {
|
||||
// If the symbol is external module, don't show it in the completion list
|
||||
// (i.e declare module "http" { let x; } | // <= request completion here, "http" should not be there)
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (displayName && displayName.length >= 2 && firstCharCode === displayName.charCodeAt(displayName.length - 1) &&
|
||||
if (displayName.length >= 2 &&
|
||||
firstCharCode === displayName.charCodeAt(displayName.length - 1) &&
|
||||
(firstCharCode === CharacterCodes.singleQuote || firstCharCode === CharacterCodes.doubleQuote)) {
|
||||
// If the user entered name for the symbol was quoted, removing the quotes is not enough, as the name could be an
|
||||
// invalid identifier name. We need to check if whatever was inside the quotes is actually a valid identifier name.
|
||||
@@ -2510,19 +2688,24 @@ module ts {
|
||||
// Try to get a valid display name for this symbol, if we could not find one, then ignore it.
|
||||
// We would like to only show things that can be added after a dot, so for instance numeric properties can
|
||||
// not be accessed with a dot (a.1 <- invalid)
|
||||
let displayName = getCompletionEntryDisplayName(symbol, program.getCompilerOptions().target, /*performCharacterChecks:*/ true);
|
||||
let displayName = getCompletionEntryDisplayNameForSymbol(symbol, program.getCompilerOptions().target, /*performCharacterChecks:*/ true);
|
||||
if (!displayName) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// TODO(drosen): Right now we just permit *all* semantic meanings when calling 'getSymbolKind'
|
||||
// which is permissible given that it is backwards compatible; but really we should consider
|
||||
// passing the meaning for the node so that we don't report that a suggestion for a value is an interface.
|
||||
// We COULD also just do what 'getSymbolModifiers' does, which is to use the first declaration.
|
||||
// TODO(drosen): Right now we just permit *all* semantic meanings when calling
|
||||
// 'getSymbolKind' which is permissible given that it is backwards compatible; but
|
||||
// really we should consider passing the meaning for the node so that we don't report
|
||||
// that a suggestion for a value is an interface. We COULD also just do what
|
||||
// 'getSymbolModifiers' does, which is to use the first declaration.
|
||||
|
||||
// Use a 'sortText' of 0' so that all symbol completion entries come before any other
|
||||
// entries (like JavaScript identifier entries).
|
||||
return {
|
||||
name: displayName,
|
||||
kind: getSymbolKind(symbol, typeChecker, location),
|
||||
kindModifiers: getSymbolModifiers(symbol)
|
||||
kindModifiers: getSymbolModifiers(symbol),
|
||||
sortText: "0",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2566,8 +2749,9 @@ module ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Find the node where completion is requested on, in the case of a completion after a dot, it is the member access expression
|
||||
// otherwise, it is a request for all visible symbols in the scope, and the node is the current location
|
||||
// Find the node where completion is requested on, in the case of a completion after
|
||||
// a dot, it is the member access expression other wise, it is a request for all
|
||||
// visible symbols in the scope, and the node is the current location.
|
||||
let node = currentToken;
|
||||
let isRightOfDot = false;
|
||||
if (contextToken && contextToken.kind === SyntaxKind.DotToken && contextToken.parent.kind === SyntaxKind.PropertyAccessExpression) {
|
||||
@@ -2585,11 +2769,26 @@ module ts {
|
||||
let semanticStart = new Date().getTime();
|
||||
let isMemberCompletion: boolean;
|
||||
let isNewIdentifierLocation: boolean;
|
||||
let symbols: Symbol[];
|
||||
let symbols: Symbol[] = [];
|
||||
|
||||
if (isRightOfDot) {
|
||||
getTypeScriptMemberSymbols();
|
||||
}
|
||||
else {
|
||||
// For JavaScript or TypeScript, if we're not after a dot, then just try to get the
|
||||
// global symbols in scope. These results should be valid for either language as
|
||||
// the set of symbols that can be referenced from this location.
|
||||
if (!tryGetGlobalSymbols()) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
log("getCompletionData: Semantic work: " + (new Date().getTime() - semanticStart));
|
||||
|
||||
return { symbols, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot };
|
||||
|
||||
function getTypeScriptMemberSymbols(): void {
|
||||
// Right of dot member completion list
|
||||
symbols = [];
|
||||
isMemberCompletion = true;
|
||||
isNewIdentifierLocation = false;
|
||||
|
||||
@@ -2622,7 +2821,8 @@ module ts {
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
function tryGetGlobalSymbols(): boolean {
|
||||
let containingObjectLiteral = getContainingObjectLiteralApplicableForCompletion(contextToken);
|
||||
if (containingObjectLiteral) {
|
||||
// Object literal expression, look up possible property names from contextual type
|
||||
@@ -2631,7 +2831,7 @@ module ts {
|
||||
|
||||
let contextualType = typeInfoResolver.getContextualType(containingObjectLiteral);
|
||||
if (!contextualType) {
|
||||
return undefined;
|
||||
return false;
|
||||
}
|
||||
|
||||
let contextualTypeMembers = typeInfoResolver.getPropertiesOfType(contextualType);
|
||||
@@ -2704,12 +2904,10 @@ module ts {
|
||||
let symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Alias;
|
||||
symbols = typeInfoResolver.getSymbolsInScope(scopeNode, symbolMeanings);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
log("getCompletionData: Semantic work: " + (new Date().getTime() - semanticStart));
|
||||
|
||||
return { symbols, isMemberCompletion, isNewIdentifierLocation, location };
|
||||
|
||||
/**
|
||||
* Finds the first node that "embraces" the position, so that one may
|
||||
* accurately aggregate locals from the closest containing scope.
|
||||
@@ -3016,12 +3214,20 @@ module ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let { symbols, isMemberCompletion, isNewIdentifierLocation, location } = completionData;
|
||||
if (!symbols || symbols.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
let { symbols, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot } = completionData;
|
||||
|
||||
var entries = getCompletionEntriesFromSymbols(symbols);
|
||||
let entries: CompletionEntry[];
|
||||
if (isRightOfDot && isJavaScript(fileName)) {
|
||||
entries = getCompletionEntriesFromSymbols(symbols);
|
||||
addRange(entries, getJavaScriptCompletionEntries());
|
||||
}
|
||||
else {
|
||||
if (!symbols || symbols.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
entries = getCompletionEntriesFromSymbols(symbols);
|
||||
}
|
||||
|
||||
// Add keywords if this is not a member completion list
|
||||
if (!isMemberCompletion) {
|
||||
@@ -3030,21 +3236,51 @@ module ts {
|
||||
|
||||
return { isMemberCompletion, isNewIdentifierLocation, entries };
|
||||
|
||||
function getCompletionEntriesFromSymbols(symbols: Symbol[]): CompletionEntry[] {
|
||||
let start = new Date().getTime();
|
||||
var entries: CompletionEntry[] = [];
|
||||
var nameToSymbol: Map<Symbol> = {};
|
||||
function getJavaScriptCompletionEntries(): CompletionEntry[] {
|
||||
let entries: CompletionEntry[] = [];
|
||||
let allNames: Map<string> = {};
|
||||
let target = program.getCompilerOptions().target;
|
||||
|
||||
for (let symbol of symbols) {
|
||||
let entry = createCompletionEntry(symbol, typeInfoResolver, location);
|
||||
if (entry) {
|
||||
let id = escapeIdentifier(entry.name);
|
||||
if (!lookUp(nameToSymbol, id)) {
|
||||
entries.push(entry);
|
||||
nameToSymbol[id] = symbol;
|
||||
for (let sourceFile of program.getSourceFiles()) {
|
||||
let nameTable = getNameTable(sourceFile);
|
||||
for (let name in nameTable) {
|
||||
if (!allNames[name]) {
|
||||
allNames[name] = name;
|
||||
let displayName = getCompletionEntryDisplayName(name, target, /*performCharacterChecks:*/ true);
|
||||
if (displayName) {
|
||||
let entry = {
|
||||
name: displayName,
|
||||
kind: ScriptElementKind.warning,
|
||||
kindModifiers: "",
|
||||
sortText: "1"
|
||||
};
|
||||
entries.push(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
function getCompletionEntriesFromSymbols(symbols: Symbol[]): CompletionEntry[] {
|
||||
let start = new Date().getTime();
|
||||
var entries: CompletionEntry[] = [];
|
||||
|
||||
if (symbols) {
|
||||
var nameToSymbol: Map<Symbol> = {};
|
||||
for (let symbol of symbols) {
|
||||
let entry = createCompletionEntry(symbol, typeInfoResolver, location);
|
||||
if (entry) {
|
||||
let id = escapeIdentifier(entry.name);
|
||||
if (!lookUp(nameToSymbol, id)) {
|
||||
entries.push(entry);
|
||||
nameToSymbol[id] = symbol;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log("getCompletionsAtPosition: getCompletionEntriesFromSymbols: " + (new Date().getTime() - start));
|
||||
return entries;
|
||||
}
|
||||
@@ -3063,7 +3299,7 @@ module ts {
|
||||
// We don't need to perform character checks here because we're only comparing the
|
||||
// name against 'entryName' (which is known to be good), not building a new
|
||||
// completion entry.
|
||||
let symbol = forEach(symbols, s => getCompletionEntryDisplayName(s, target, /*performCharacterChecks:*/ false) === entryName ? s : undefined);
|
||||
let symbol = forEach(symbols, s => getCompletionEntryDisplayNameForSymbol(s, target, /*performCharacterChecks:*/ false) === entryName ? s : undefined);
|
||||
|
||||
if (symbol) {
|
||||
let displayPartsDocumentationsAndSymbolKind = getSymbolDisplayPartsDocumentationAndSymbolKind(symbol, getValidSourceFile(fileName), location, typeInfoResolver, location, SemanticMeaning.All);
|
||||
|
||||
+17
-12
@@ -331,6 +331,22 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function realizeDiagnostics(diagnostics: Diagnostic[], newLine: string): { message: string; start: number; length: number; category: string; } []{
|
||||
return diagnostics.map(d => realizeDiagnostic(d, newLine));
|
||||
}
|
||||
|
||||
function realizeDiagnostic(diagnostic: Diagnostic, newLine: string): { message: string; start: number; length: number; category: string; } {
|
||||
return {
|
||||
message: flattenDiagnosticMessageText(diagnostic.messageText, newLine),
|
||||
start: diagnostic.start,
|
||||
length: diagnostic.length,
|
||||
/// TODO: no need for the tolowerCase call
|
||||
category: DiagnosticCategory[diagnostic.category].toLowerCase(),
|
||||
code: diagnostic.code
|
||||
};
|
||||
}
|
||||
|
||||
class LanguageServiceShimObject extends ShimBase implements LanguageServiceShim {
|
||||
private logger: Logger;
|
||||
|
||||
@@ -391,18 +407,7 @@ module ts {
|
||||
|
||||
private realizeDiagnostics(diagnostics: Diagnostic[]): { message: string; start: number; length: number; category: string; }[]{
|
||||
var newLine = this.getNewLine();
|
||||
return diagnostics.map(d => this.realizeDiagnostic(d, newLine));
|
||||
}
|
||||
|
||||
private realizeDiagnostic(diagnostic: Diagnostic, newLine: string): { message: string; start: number; length: number; category: string; } {
|
||||
return {
|
||||
message: flattenDiagnosticMessageText(diagnostic.messageText, newLine),
|
||||
start: diagnostic.start,
|
||||
length: diagnostic.length,
|
||||
/// TODO: no need for the tolowerCase call
|
||||
category: DiagnosticCategory[diagnostic.category].toLowerCase(),
|
||||
code: diagnostic.code
|
||||
};
|
||||
return ts.realizeDiagnostics(diagnostics, newLine);
|
||||
}
|
||||
|
||||
public getSyntacticClassifications(fileName: string, start: number, length: number): string {
|
||||
|
||||
@@ -1802,6 +1802,7 @@ declare module "typescript" {
|
||||
name: string;
|
||||
kind: string;
|
||||
kindModifiers: string;
|
||||
sortText: string;
|
||||
}
|
||||
interface CompletionEntryDetails {
|
||||
name: string;
|
||||
@@ -1944,6 +1945,7 @@ declare module "typescript" {
|
||||
}
|
||||
class ScriptElementKind {
|
||||
static unknown: string;
|
||||
static warning: string;
|
||||
static keyword: string;
|
||||
static scriptElement: string;
|
||||
static moduleElement: string;
|
||||
|
||||
@@ -5757,6 +5757,9 @@ declare module "typescript" {
|
||||
|
||||
kindModifiers: string;
|
||||
>kindModifiers : string
|
||||
|
||||
sortText: string;
|
||||
>sortText : string
|
||||
}
|
||||
interface CompletionEntryDetails {
|
||||
>CompletionEntryDetails : CompletionEntryDetails
|
||||
@@ -6026,6 +6029,9 @@ declare module "typescript" {
|
||||
static unknown: string;
|
||||
>unknown : string
|
||||
|
||||
static warning: string;
|
||||
>warning : string
|
||||
|
||||
static keyword: string;
|
||||
>keyword : string
|
||||
|
||||
|
||||
@@ -1833,6 +1833,7 @@ declare module "typescript" {
|
||||
name: string;
|
||||
kind: string;
|
||||
kindModifiers: string;
|
||||
sortText: string;
|
||||
}
|
||||
interface CompletionEntryDetails {
|
||||
name: string;
|
||||
@@ -1975,6 +1976,7 @@ declare module "typescript" {
|
||||
}
|
||||
class ScriptElementKind {
|
||||
static unknown: string;
|
||||
static warning: string;
|
||||
static keyword: string;
|
||||
static scriptElement: string;
|
||||
static moduleElement: string;
|
||||
|
||||
@@ -5903,6 +5903,9 @@ declare module "typescript" {
|
||||
|
||||
kindModifiers: string;
|
||||
>kindModifiers : string
|
||||
|
||||
sortText: string;
|
||||
>sortText : string
|
||||
}
|
||||
interface CompletionEntryDetails {
|
||||
>CompletionEntryDetails : CompletionEntryDetails
|
||||
@@ -6172,6 +6175,9 @@ declare module "typescript" {
|
||||
static unknown: string;
|
||||
>unknown : string
|
||||
|
||||
static warning: string;
|
||||
>warning : string
|
||||
|
||||
static keyword: string;
|
||||
>keyword : string
|
||||
|
||||
|
||||
@@ -5903,6 +5903,9 @@ declare module "typescript" {
|
||||
|
||||
kindModifiers: string;
|
||||
>kindModifiers : string
|
||||
|
||||
sortText: string;
|
||||
>sortText : string
|
||||
}
|
||||
interface CompletionEntryDetails {
|
||||
>CompletionEntryDetails : CompletionEntryDetails
|
||||
@@ -6172,6 +6175,9 @@ declare module "typescript" {
|
||||
static unknown: string;
|
||||
>unknown : string
|
||||
|
||||
static warning: string;
|
||||
>warning : string
|
||||
|
||||
static keyword: string;
|
||||
>keyword : string
|
||||
|
||||
|
||||
@@ -1834,6 +1834,7 @@ declare module "typescript" {
|
||||
name: string;
|
||||
kind: string;
|
||||
kindModifiers: string;
|
||||
sortText: string;
|
||||
}
|
||||
interface CompletionEntryDetails {
|
||||
name: string;
|
||||
@@ -1976,6 +1977,7 @@ declare module "typescript" {
|
||||
}
|
||||
class ScriptElementKind {
|
||||
static unknown: string;
|
||||
static warning: string;
|
||||
static keyword: string;
|
||||
static scriptElement: string;
|
||||
static moduleElement: string;
|
||||
|
||||
@@ -5853,6 +5853,9 @@ declare module "typescript" {
|
||||
|
||||
kindModifiers: string;
|
||||
>kindModifiers : string
|
||||
|
||||
sortText: string;
|
||||
>sortText : string
|
||||
}
|
||||
interface CompletionEntryDetails {
|
||||
>CompletionEntryDetails : CompletionEntryDetails
|
||||
@@ -6122,6 +6125,9 @@ declare module "typescript" {
|
||||
static unknown: string;
|
||||
>unknown : string
|
||||
|
||||
static warning: string;
|
||||
>warning : string
|
||||
|
||||
static keyword: string;
|
||||
>keyword : string
|
||||
|
||||
|
||||
@@ -1871,6 +1871,7 @@ declare module "typescript" {
|
||||
name: string;
|
||||
kind: string;
|
||||
kindModifiers: string;
|
||||
sortText: string;
|
||||
}
|
||||
interface CompletionEntryDetails {
|
||||
name: string;
|
||||
@@ -2013,6 +2014,7 @@ declare module "typescript" {
|
||||
}
|
||||
class ScriptElementKind {
|
||||
static unknown: string;
|
||||
static warning: string;
|
||||
static keyword: string;
|
||||
static scriptElement: string;
|
||||
static moduleElement: string;
|
||||
|
||||
@@ -6026,6 +6026,9 @@ declare module "typescript" {
|
||||
|
||||
kindModifiers: string;
|
||||
>kindModifiers : string
|
||||
|
||||
sortText: string;
|
||||
>sortText : string
|
||||
}
|
||||
interface CompletionEntryDetails {
|
||||
>CompletionEntryDetails : CompletionEntryDetails
|
||||
@@ -6295,6 +6298,9 @@ declare module "typescript" {
|
||||
static unknown: string;
|
||||
>unknown : string
|
||||
|
||||
static warning: string;
|
||||
>warning : string
|
||||
|
||||
static keyword: string;
|
||||
>keyword : string
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
tests/cases/compiler/anonymousClassExpression1.ts(2,19): error TS9003: 'class' expressions are not currently supported.
|
||||
|
||||
|
||||
==== tests/cases/compiler/anonymousClassExpression1.ts (1 errors) ====
|
||||
function f() {
|
||||
return typeof class {} === "function";
|
||||
~~~~~
|
||||
!!! error TS9003: 'class' expressions are not currently supported.
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
//// [anonymousClassExpression1.ts]
|
||||
function f() {
|
||||
return typeof class {} === "function";
|
||||
}
|
||||
|
||||
//// [anonymousClassExpression1.js]
|
||||
function f() {
|
||||
return typeof (function () {
|
||||
function default_1() {
|
||||
}
|
||||
return default_1;
|
||||
})() === "function";
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
tests/cases/compiler/classDeclarationBlockScoping1.ts(5,11): error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration.
|
||||
|
||||
|
||||
==== tests/cases/compiler/classDeclarationBlockScoping1.ts (1 errors) ====
|
||||
class C {
|
||||
}
|
||||
|
||||
{
|
||||
class C {
|
||||
~
|
||||
!!! error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
//// [classDeclarationBlockScoping1.ts]
|
||||
class C {
|
||||
}
|
||||
|
||||
{
|
||||
class C {
|
||||
}
|
||||
}
|
||||
|
||||
//// [classDeclarationBlockScoping1.js]
|
||||
var C = (function () {
|
||||
function C() {
|
||||
}
|
||||
return C;
|
||||
})();
|
||||
{
|
||||
var C = (function () {
|
||||
function C() {
|
||||
}
|
||||
return C;
|
||||
})();
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
tests/cases/compiler/classDeclarationBlockScoping2.ts(2,11): error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration.
|
||||
tests/cases/compiler/classDeclarationBlockScoping2.ts(5,15): error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration.
|
||||
|
||||
|
||||
==== tests/cases/compiler/classDeclarationBlockScoping2.ts (2 errors) ====
|
||||
function f() {
|
||||
class C {}
|
||||
~
|
||||
!!! error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration.
|
||||
var c1 = C;
|
||||
{
|
||||
class C {}
|
||||
~
|
||||
!!! error TS9004: 'class' declarations are only supported directly inside a module or as a top level declaration.
|
||||
var c2 = C;
|
||||
}
|
||||
return C === c1;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
//// [classDeclarationBlockScoping2.ts]
|
||||
function f() {
|
||||
class C {}
|
||||
var c1 = C;
|
||||
{
|
||||
class C {}
|
||||
var c2 = C;
|
||||
}
|
||||
return C === c1;
|
||||
}
|
||||
|
||||
//// [classDeclarationBlockScoping2.js]
|
||||
function f() {
|
||||
var C = (function () {
|
||||
function C() {
|
||||
}
|
||||
return C;
|
||||
})();
|
||||
var c1 = C;
|
||||
{
|
||||
var C = (function () {
|
||||
function C() {
|
||||
}
|
||||
return C;
|
||||
})();
|
||||
var c2 = C;
|
||||
}
|
||||
return C === c1;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
tests/cases/compiler/classExpressionWithDecorator1.ts(1,9): error TS1109: Expression expected.
|
||||
tests/cases/compiler/classExpressionWithDecorator1.ts(1,10): error TS2304: Cannot find name 'decorate'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/classExpressionWithDecorator1.ts (2 errors) ====
|
||||
var v = @decorate class C { static p = 1 };
|
||||
~
|
||||
!!! error TS1109: Expression expected.
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'decorate'.
|
||||
@@ -0,0 +1,26 @@
|
||||
//// [classExpressionWithDecorator1.ts]
|
||||
var v = @decorate class C { static p = 1 };
|
||||
|
||||
//// [classExpressionWithDecorator1.js]
|
||||
var __decorate = this.__decorate || function (decorators, target, key, value) {
|
||||
var kind = typeof (arguments.length == 2 ? value = target : value);
|
||||
for (var i = decorators.length - 1; i >= 0; --i) {
|
||||
var decorator = decorators[i];
|
||||
switch (kind) {
|
||||
case "function": value = decorator(value) || value; break;
|
||||
case "number": decorator(target, key, value); break;
|
||||
case "undefined": decorator(target, key); break;
|
||||
case "object": value = decorator(target, key, value) || value; break;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
};
|
||||
var v = ;
|
||||
var C = (function () {
|
||||
function C() {
|
||||
}
|
||||
C.p = 1;
|
||||
C = __decorate([decorate], C);
|
||||
return C;
|
||||
})();
|
||||
;
|
||||
@@ -0,0 +1,7 @@
|
||||
tests/cases/compiler/classExpressionWithStaticProperties1.ts(1,15): error TS9003: 'class' expressions are not currently supported.
|
||||
|
||||
|
||||
==== tests/cases/compiler/classExpressionWithStaticProperties1.ts (1 errors) ====
|
||||
var v = class C { static a = 1; static b = 2 };
|
||||
~
|
||||
!!! error TS9003: 'class' expressions are not currently supported.
|
||||
@@ -0,0 +1,11 @@
|
||||
//// [classExpressionWithStaticProperties1.ts]
|
||||
var v = class C { static a = 1; static b = 2 };
|
||||
|
||||
//// [classExpressionWithStaticProperties1.js]
|
||||
var v = (function () {
|
||||
function C() {
|
||||
}
|
||||
C.a = 1;
|
||||
C.b = 2;
|
||||
return C;
|
||||
})();
|
||||
@@ -0,0 +1,7 @@
|
||||
tests/cases/compiler/classExpressionWithStaticProperties2.ts(1,15): error TS9003: 'class' expressions are not currently supported.
|
||||
|
||||
|
||||
==== tests/cases/compiler/classExpressionWithStaticProperties2.ts (1 errors) ====
|
||||
var v = class C { static a = 1; static b };
|
||||
~
|
||||
!!! error TS9003: 'class' expressions are not currently supported.
|
||||
@@ -0,0 +1,10 @@
|
||||
//// [classExpressionWithStaticProperties2.ts]
|
||||
var v = class C { static a = 1; static b };
|
||||
|
||||
//// [classExpressionWithStaticProperties2.js]
|
||||
var v = (function () {
|
||||
function C() {
|
||||
}
|
||||
C.a = 1;
|
||||
return C;
|
||||
})();
|
||||
@@ -0,0 +1,7 @@
|
||||
tests/cases/compiler/classExpressionWithStaticPropertiesES61.ts(1,15): error TS9003: 'class' expressions are not currently supported.
|
||||
|
||||
|
||||
==== tests/cases/compiler/classExpressionWithStaticPropertiesES61.ts (1 errors) ====
|
||||
var v = class C { static a = 1; static b = 2 };
|
||||
~
|
||||
!!! error TS9003: 'class' expressions are not currently supported.
|
||||
@@ -0,0 +1,10 @@
|
||||
//// [classExpressionWithStaticPropertiesES61.ts]
|
||||
var v = class C { static a = 1; static b = 2 };
|
||||
|
||||
//// [classExpressionWithStaticPropertiesES61.js]
|
||||
var v = (_a = class C {
|
||||
},
|
||||
_a.a = 1,
|
||||
_a.b = 2,
|
||||
_a);
|
||||
var _a;
|
||||
@@ -0,0 +1,7 @@
|
||||
tests/cases/compiler/classExpressionWithStaticPropertiesES62.ts(1,15): error TS9003: 'class' expressions are not currently supported.
|
||||
|
||||
|
||||
==== tests/cases/compiler/classExpressionWithStaticPropertiesES62.ts (1 errors) ====
|
||||
var v = class C { static a = 1; static b };
|
||||
~
|
||||
!!! error TS9003: 'class' expressions are not currently supported.
|
||||
@@ -0,0 +1,9 @@
|
||||
//// [classExpressionWithStaticPropertiesES62.ts]
|
||||
var v = class C { static a = 1; static b };
|
||||
|
||||
//// [classExpressionWithStaticPropertiesES62.js]
|
||||
var v = (_a = class C {
|
||||
},
|
||||
_a.a = 1,
|
||||
_a);
|
||||
var _a;
|
||||
@@ -1,4 +1,4 @@
|
||||
tests/cases/conformance/classes/classDeclarations/classWithPredefinedTypesAsNames2.ts(3,7): error TS1003: Identifier expected.
|
||||
tests/cases/conformance/classes/classDeclarations/classWithPredefinedTypesAsNames2.ts(3,7): error TS1005: '{' expected.
|
||||
|
||||
|
||||
==== tests/cases/conformance/classes/classDeclarations/classWithPredefinedTypesAsNames2.ts (1 errors) ====
|
||||
@@ -6,4 +6,4 @@ tests/cases/conformance/classes/classDeclarations/classWithPredefinedTypesAsName
|
||||
|
||||
class void {}
|
||||
~~~~
|
||||
!!! error TS1003: Identifier expected.
|
||||
!!! error TS1005: '{' expected.
|
||||
@@ -5,9 +5,9 @@ class void {}
|
||||
|
||||
//// [classWithPredefinedTypesAsNames2.js]
|
||||
// classes cannot use predefined types as names
|
||||
var = (function () {
|
||||
function () {
|
||||
var default_1 = (function () {
|
||||
function default_1() {
|
||||
}
|
||||
return ;
|
||||
return default_1;
|
||||
})();
|
||||
void {};
|
||||
|
||||
@@ -8,9 +8,13 @@ tests/cases/compiler/externModule.ts(18,6): error TS2390: Constructor implementa
|
||||
tests/cases/compiler/externModule.ts(20,13): error TS2391: Function implementation is missing or not immediately following the declaration.
|
||||
tests/cases/compiler/externModule.ts(26,13): error TS2391: Function implementation is missing or not immediately following the declaration.
|
||||
tests/cases/compiler/externModule.ts(28,13): error TS2391: Function implementation is missing or not immediately following the declaration.
|
||||
tests/cases/compiler/externModule.ts(32,11): error TS2304: Cannot find name 'XDate'.
|
||||
tests/cases/compiler/externModule.ts(34,7): error TS2304: Cannot find name 'XDate'.
|
||||
tests/cases/compiler/externModule.ts(36,7): error TS2304: Cannot find name 'XDate'.
|
||||
tests/cases/compiler/externModule.ts(37,3): error TS2304: Cannot find name 'XDate'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/externModule.ts (10 errors) ====
|
||||
==== tests/cases/compiler/externModule.ts (14 errors) ====
|
||||
declare module {
|
||||
~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'declare'.
|
||||
@@ -63,10 +67,18 @@ tests/cases/compiler/externModule.ts(28,13): error TS2391: Function implementati
|
||||
}
|
||||
|
||||
var d=new XDate();
|
||||
~~~~~
|
||||
!!! error TS2304: Cannot find name 'XDate'.
|
||||
d.getDay();
|
||||
d=new XDate(1978,2);
|
||||
~~~~~
|
||||
!!! error TS2304: Cannot find name 'XDate'.
|
||||
d.getXDate();
|
||||
var n=XDate.parse("3/2/2004");
|
||||
~~~~~
|
||||
!!! error TS2304: Cannot find name 'XDate'.
|
||||
n=XDate.UTC(1964,2,1);
|
||||
~~~~~
|
||||
!!! error TS2304: Cannot find name 'XDate'.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
tests/cases/conformance/types/specifyingTypes/predefinedTypes/objectTypesWithPredefinedTypesAsName2.ts(3,7): error TS1003: Identifier expected.
|
||||
tests/cases/conformance/types/specifyingTypes/predefinedTypes/objectTypesWithPredefinedTypesAsName2.ts(3,7): error TS1005: '{' expected.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/specifyingTypes/predefinedTypes/objectTypesWithPredefinedTypesAsName2.ts (1 errors) ====
|
||||
@@ -6,4 +6,4 @@ tests/cases/conformance/types/specifyingTypes/predefinedTypes/objectTypesWithPre
|
||||
|
||||
class void {} // parse error unlike the others
|
||||
~~~~
|
||||
!!! error TS1003: Identifier expected.
|
||||
!!! error TS1005: '{' expected.
|
||||
@@ -5,9 +5,9 @@ class void {} // parse error unlike the others
|
||||
|
||||
//// [objectTypesWithPredefinedTypesAsName2.js]
|
||||
// it is an error to use a predefined type as a type name
|
||||
var = (function () {
|
||||
function () {
|
||||
var default_1 = (function () {
|
||||
function default_1() {
|
||||
}
|
||||
return ;
|
||||
return default_1;
|
||||
})();
|
||||
void {}; // parse error unlike the others
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/VariableLists/parserInvalidIdentifiersInVariableStatements1.ts(1,5): error TS1134: Variable declaration expected.
|
||||
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/VariableLists/parserInvalidIdentifiersInVariableStatements1.ts(3,5): error TS1134: Variable declaration expected.
|
||||
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/VariableLists/parserInvalidIdentifiersInVariableStatements1.ts(3,10): error TS1003: Identifier expected.
|
||||
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/VariableLists/parserInvalidIdentifiersInVariableStatements1.ts(3,10): error TS1005: '{' expected.
|
||||
|
||||
|
||||
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/VariableLists/parserInvalidIdentifiersInVariableStatements1.ts (3 errors) ====
|
||||
@@ -12,6 +12,6 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/VariableLists/parserInv
|
||||
~~~~~
|
||||
!!! error TS1134: Variable declaration expected.
|
||||
~
|
||||
!!! error TS1003: Identifier expected.
|
||||
!!! error TS1005: '{' expected.
|
||||
var bar;
|
||||
|
||||
@@ -9,10 +9,10 @@ var bar;
|
||||
var ;
|
||||
var foo;
|
||||
var ;
|
||||
var = (function () {
|
||||
function () {
|
||||
var default_1 = (function () {
|
||||
function default_1() {
|
||||
}
|
||||
return ;
|
||||
return default_1;
|
||||
})();
|
||||
;
|
||||
var bar;
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
function f() {
|
||||
return typeof class {} === "function";
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
class C {
|
||||
}
|
||||
|
||||
{
|
||||
class C {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
function f() {
|
||||
class C {}
|
||||
var c1 = C;
|
||||
{
|
||||
class C {}
|
||||
var c2 = C;
|
||||
}
|
||||
return C === c1;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
var v = @decorate class C { static p = 1 };
|
||||
@@ -0,0 +1 @@
|
||||
var v = class C { static a = 1; static b = 2 };
|
||||
@@ -0,0 +1 @@
|
||||
var v = class C { static a = 1; static b };
|
||||
@@ -0,0 +1,2 @@
|
||||
//@target: es6
|
||||
var v = class C { static a = 1; static b = 2 };
|
||||
@@ -0,0 +1,2 @@
|
||||
//@target: es6
|
||||
var v = class C { static a = 1; static b };
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
// this line triggers a semantic/syntactic error check, remove line when 788570 is fixed
|
||||
edit.insert('');
|
||||
|
||||
debugger;
|
||||
goTo.marker('1');
|
||||
verify.completionListContains("multiM", "module multiM", "this is multi declare module\nthi is multi module 2\nthis is multi module 3 comment");
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
//// declare module 'https' {
|
||||
//// }
|
||||
//// /*2*/
|
||||
|
||||
debugger;
|
||||
goTo.marker("1");
|
||||
verify.not.completionListContains("http");
|
||||
goTo.marker("2");
|
||||
|
||||
@@ -439,6 +439,10 @@ module FourSlashInterface {
|
||||
displayParts: ts.SymbolDisplayPart[], documentation: ts.SymbolDisplayPart[]) {
|
||||
FourSlash.currentTestState.verifyQuickInfoDisplayParts(kind, kindModifiers, textSpan, displayParts, documentation);
|
||||
}
|
||||
|
||||
public getSemanticDiagnostics(expected: string) {
|
||||
FourSlash.currentTestState.getSemanticDiagnostics(expected);
|
||||
}
|
||||
}
|
||||
|
||||
export class edit {
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @allowNonTsExtensions: true
|
||||
// @Filename: a.js
|
||||
//// import a = b;
|
||||
|
||||
verify.getSemanticDiagnostics(`[
|
||||
{
|
||||
"message": "'import ... =' can only be used in a .ts file.",
|
||||
"start": 0,
|
||||
"length": 13,
|
||||
"category": "error",
|
||||
"code": 8002
|
||||
}
|
||||
]`);
|
||||
@@ -0,0 +1,15 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @allowNonTsExtensions: true
|
||||
// @Filename: a.js
|
||||
//// function F<T>() { }
|
||||
|
||||
verify.getSemanticDiagnostics(`[
|
||||
{
|
||||
"message": "'type parameter declarations' can only be used in a .ts file.",
|
||||
"start": 11,
|
||||
"length": 1,
|
||||
"category": "error",
|
||||
"code": 8004
|
||||
}
|
||||
]`);
|
||||
@@ -0,0 +1,15 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @allowNonTsExtensions: true
|
||||
// @Filename: a.js
|
||||
//// function F(): number { }
|
||||
|
||||
verify.getSemanticDiagnostics(`[
|
||||
{
|
||||
"message": "'types' can only be used in a .ts file.",
|
||||
"start": 14,
|
||||
"length": 6,
|
||||
"category": "error",
|
||||
"code": 8010
|
||||
}
|
||||
]`);
|
||||
@@ -0,0 +1,15 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @allowNonTsExtensions: true
|
||||
// @Filename: a.js
|
||||
//// declare var v;
|
||||
|
||||
verify.getSemanticDiagnostics(`[
|
||||
{
|
||||
"message": "'declare' can only be used in a .ts file.",
|
||||
"start": 0,
|
||||
"length": 7,
|
||||
"category": "error",
|
||||
"code": 8009
|
||||
}
|
||||
]`);
|
||||
@@ -0,0 +1,15 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @allowNonTsExtensions: true
|
||||
// @Filename: a.js
|
||||
//// var v: () => number;
|
||||
|
||||
verify.getSemanticDiagnostics(`[
|
||||
{
|
||||
"message": "'types' can only be used in a .ts file.",
|
||||
"start": 7,
|
||||
"length": 12,
|
||||
"category": "error",
|
||||
"code": 8010
|
||||
}
|
||||
]`);
|
||||
@@ -0,0 +1,15 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @allowNonTsExtensions: true
|
||||
// @Filename: a.js
|
||||
//// Foo<number>();
|
||||
|
||||
verify.getSemanticDiagnostics(`[
|
||||
{
|
||||
"message": "'type arguments' can only be used in a .ts file.",
|
||||
"start": 4,
|
||||
"length": 6,
|
||||
"category": "error",
|
||||
"code": 8011
|
||||
}
|
||||
]`);
|
||||
@@ -0,0 +1,15 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @allowNonTsExtensions: true
|
||||
// @Filename: a.js
|
||||
//// function F(public p) { }
|
||||
|
||||
verify.getSemanticDiagnostics(`[
|
||||
{
|
||||
"message": "'parameter modifiers' can only be used in a .ts file.",
|
||||
"start": 11,
|
||||
"length": 6,
|
||||
"category": "error",
|
||||
"code": 8012
|
||||
}
|
||||
]`);
|
||||
@@ -0,0 +1,15 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @allowNonTsExtensions: true
|
||||
// @Filename: a.js
|
||||
//// function F(p?) { }
|
||||
|
||||
verify.getSemanticDiagnostics(`[
|
||||
{
|
||||
"message": "'?' can only be used in a .ts file.",
|
||||
"start": 12,
|
||||
"length": 1,
|
||||
"category": "error",
|
||||
"code": 8013
|
||||
}
|
||||
]`);
|
||||
@@ -0,0 +1,15 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @allowNonTsExtensions: true
|
||||
// @Filename: a.js
|
||||
//// function F(a: number) { }
|
||||
|
||||
verify.getSemanticDiagnostics(`[
|
||||
{
|
||||
"message": "'types' can only be used in a .ts file.",
|
||||
"start": 14,
|
||||
"length": 6,
|
||||
"category": "error",
|
||||
"code": 8010
|
||||
}
|
||||
]`);
|
||||
@@ -0,0 +1,15 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @allowNonTsExtensions: true
|
||||
// @Filename: a.js
|
||||
//// class C { v }
|
||||
|
||||
verify.getSemanticDiagnostics(`[
|
||||
{
|
||||
"message": "'property declarations' can only be used in a .ts file.",
|
||||
"start": 10,
|
||||
"length": 1,
|
||||
"category": "error",
|
||||
"code": 8014
|
||||
}
|
||||
]`);
|
||||
@@ -0,0 +1,15 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @allowNonTsExtensions: true
|
||||
// @Filename: a.js
|
||||
//// enum E { }
|
||||
|
||||
verify.getSemanticDiagnostics(`[
|
||||
{
|
||||
"message": "'enum declarations' can only be used in a .ts file.",
|
||||
"start": 5,
|
||||
"length": 1,
|
||||
"category": "error",
|
||||
"code": 8015
|
||||
}
|
||||
]`);
|
||||
@@ -0,0 +1,15 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @allowNonTsExtensions: true
|
||||
// @Filename: a.js
|
||||
//// export = b;
|
||||
|
||||
verify.getSemanticDiagnostics(`[
|
||||
{
|
||||
"message": "'export=' can only be used in a .ts file.",
|
||||
"start": 0,
|
||||
"length": 11,
|
||||
"category": "error",
|
||||
"code": 8003
|
||||
}
|
||||
]`);
|
||||
@@ -0,0 +1,15 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @allowNonTsExtensions: true
|
||||
// @Filename: a.js
|
||||
//// var v = <string>undefined;
|
||||
|
||||
verify.getSemanticDiagnostics(`[
|
||||
{
|
||||
"message": "'type assertion expressions' can only be used in a .ts file.",
|
||||
"start": 9,
|
||||
"length": 6,
|
||||
"category": "error",
|
||||
"code": 8016
|
||||
}
|
||||
]`);
|
||||
@@ -0,0 +1,15 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @allowNonTsExtensions: true
|
||||
// @Filename: a.js
|
||||
//// @internal class C {}
|
||||
|
||||
verify.getSemanticDiagnostics(`[
|
||||
{
|
||||
"message": "'decorators' can only be used in a .ts file.",
|
||||
"start": 0,
|
||||
"length": 9,
|
||||
"category": "error",
|
||||
"code": 8017
|
||||
}
|
||||
]`);
|
||||
@@ -0,0 +1,15 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @allowNonTsExtensions: true
|
||||
// @Filename: a.js
|
||||
//// class C<T> { }
|
||||
|
||||
verify.getSemanticDiagnostics(`[
|
||||
{
|
||||
"message": "'type parameter declarations' can only be used in a .ts file.",
|
||||
"start": 8,
|
||||
"length": 1,
|
||||
"category": "error",
|
||||
"code": 8004
|
||||
}
|
||||
]`);
|
||||
@@ -0,0 +1,15 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @allowNonTsExtensions: true
|
||||
// @Filename: a.js
|
||||
//// public class C { }
|
||||
|
||||
verify.getSemanticDiagnostics(`[
|
||||
{
|
||||
"message": "'public' can only be used in a .ts file.",
|
||||
"start": 0,
|
||||
"length": 6,
|
||||
"category": "error",
|
||||
"code": 8009
|
||||
}
|
||||
]`);
|
||||
@@ -0,0 +1,15 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @allowNonTsExtensions: true
|
||||
// @Filename: a.js
|
||||
//// class C implements D { }
|
||||
|
||||
verify.getSemanticDiagnostics(`[
|
||||
{
|
||||
"message": "'implements clauses' can only be used in a .ts file.",
|
||||
"start": 8,
|
||||
"length": 12,
|
||||
"category": "error",
|
||||
"code": 8005
|
||||
}
|
||||
]`);
|
||||
@@ -0,0 +1,15 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @allowNonTsExtensions: true
|
||||
// @Filename: a.js
|
||||
//// interface I { }
|
||||
|
||||
verify.getSemanticDiagnostics(`[
|
||||
{
|
||||
"message": "'interface declarations' can only be used in a .ts file.",
|
||||
"start": 10,
|
||||
"length": 1,
|
||||
"category": "error",
|
||||
"code": 8006
|
||||
}
|
||||
]`);
|
||||
@@ -0,0 +1,15 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @allowNonTsExtensions: true
|
||||
// @Filename: a.js
|
||||
//// module M { }
|
||||
|
||||
verify.getSemanticDiagnostics(`[
|
||||
{
|
||||
"message": "'module declarations' can only be used in a .ts file.",
|
||||
"start": 7,
|
||||
"length": 1,
|
||||
"category": "error",
|
||||
"code": 8007
|
||||
}
|
||||
]`);
|
||||
@@ -0,0 +1,15 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @allowNonTsExtensions: true
|
||||
// @Filename: a.js
|
||||
//// type a = b;
|
||||
|
||||
verify.getSemanticDiagnostics(`[
|
||||
{
|
||||
"message": "'type aliases' can only be used in a .ts file.",
|
||||
"start": 0,
|
||||
"length": 11,
|
||||
"category": "error",
|
||||
"code": 8008
|
||||
}
|
||||
]`);
|
||||
@@ -0,0 +1,15 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @allowNonTsExtensions: true
|
||||
// @Filename: a.js
|
||||
//// public function F() { }
|
||||
|
||||
verify.getSemanticDiagnostics(`[
|
||||
{
|
||||
"message": "'public' can only be used in a .ts file.",
|
||||
"start": 0,
|
||||
"length": 6,
|
||||
"category": "error",
|
||||
"code": 8009
|
||||
}
|
||||
]`);
|
||||
@@ -8,5 +8,5 @@ edit.insertLine("module A");
|
||||
edit.insert("export class ");
|
||||
|
||||
// should not crash
|
||||
verify.getScriptLexicalStructureListCount(1);
|
||||
verify.getScriptLexicalStructureListCount(2);
|
||||
|
||||
|
||||
@@ -8,4 +8,4 @@
|
||||
|
||||
|
||||
// The class is unnamed, so its method is not included either.
|
||||
verify.getScriptLexicalStructureListCount(0);
|
||||
verify.getScriptLexicalStructureListCount(2);
|
||||
|
||||
Reference in New Issue
Block a user