Add specialized semantic diagnostics for JavaScript files.

This commit is contained in:
Cyrus Najmabadi 2015-03-17 15:38:26 -07:00
parent 6155832ce7
commit 4a346045ce
3 changed files with 229 additions and 1 deletions

View File

@ -486,6 +486,21 @@ 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_TypeScript: { code: 8002, category: DiagnosticCategory.Error, key: "'import ... =' can only be used in TypeScript." },
export_can_only_be_used_in_TypeScript: { code: 8003, category: DiagnosticCategory.Error, key: "'export=' can only be used in TypeScript." },
type_parameter_declarations_can_only_be_used_in_TypeScript: { code: 8004, category: DiagnosticCategory.Error, key: "'type parameter declarations' can only be used in TypeScript." },
implements_clauses_can_only_be_used_in_TypeScript: { code: 8005, category: DiagnosticCategory.Error, key: "'implements clauses' can only be used in TypeScript." },
interface_declarations_can_only_be_used_in_TypeScript: { code: 8006, category: DiagnosticCategory.Error, key: "'interface declarations' can only be used in TypeScript." },
module_declarations_can_only_be_used_in_TypeScript: { code: 8007, category: DiagnosticCategory.Error, key: "'module declarations' can only be used in TypeScript." },
type_aliases_can_only_be_used_in_TypeScript: { code: 8007, category: DiagnosticCategory.Error, key: "'type aliases' can only be used in TypeScript." },
_0_can_only_be_used_in_TypeScript: { code: 8008, category: DiagnosticCategory.Error, key: "'{0}' can only be used in TypeScript." },
types_can_only_be_used_in_TypeScript: { code: 8009, category: DiagnosticCategory.Error, key: "'types' can only be used in TypeScript." },
type_arguments_can_only_be_used_in_TypeScript: { code: 8010, category: DiagnosticCategory.Error, key: "'type arguments' can only be used in TypeScript." },
parameter_modifiers_can_only_be_used_in_TypeScript: { code: 8011, category: DiagnosticCategory.Error, key: "'parameter modifiers' can only be used in TypeScript." },
can_only_be_used_in_TypeScript: { code: 8012, category: DiagnosticCategory.Error, key: "'?' can only be used in TypeScript." },
property_declarations_can_only_be_used_in_TypeScript: { code: 8013, category: DiagnosticCategory.Error, key: "'property declarations' can only be used in TypeScript." },
enum_declarations_can_only_be_used_in_TypeScript: { code: 8014, category: DiagnosticCategory.Error, key: "'enum declarations' can only be used in TypeScript." },
type_assertion_expressions_can_only_be_used_in_TypeScript: { code: 8014, category: DiagnosticCategory.Error, key: "'type assertion expressions' can only be used in TypeScript." },
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." },
The_arguments_object_cannot_be_referenced_in_an_arrow_function_Consider_using_a_standard_function_expression: { code: 9002, category: DiagnosticCategory.Error, key: "The 'arguments' object cannot be referenced in an arrow function. Consider using a standard function expression." },

View File

@ -1938,6 +1938,67 @@
"category": "Error",
"code": 8001
},
"'import ... =' can only be used in TypeScript.": {
"category": "Error",
"code": 8002
},
"'export=' can only be used in TypeScript.": {
"category": "Error",
"code": 8003
},
"'type parameter declarations' can only be used in TypeScript.": {
"category": "Error",
"code": 8004
},
"'implements clauses' can only be used in TypeScript.": {
"category": "Error",
"code": 8005
},
"'interface declarations' can only be used in TypeScript.": {
"category": "Error",
"code": 8006
},
"'module declarations' can only be used in TypeScript.": {
"category": "Error",
"code": 8007
},
"'type aliases' can only be used in TypeScript.": {
"category": "Error",
"code": 8007
},
"'{0}' can only be used in TypeScript.": {
"category": "Error",
"code": 8008
},
"'types' can only be used in TypeScript.": {
"category": "Error",
"code": 8009
},
"'type arguments' can only be used in TypeScript.": {
"category": "Error",
"code": 8010
},
"'parameter modifiers' can only be used in TypeScript.": {
"category": "Error",
"code": 8011
},
"'?' can only be used in TypeScript.": {
"category": "Error",
"code": 8012
},
"'property declarations' can only be used in TypeScript.": {
"category": "Error",
"code": 8013
},
"'enum declarations' can only be used in TypeScript.": {
"category": "Error",
"code": 8014
},
"'type assertion expressions' can only be used in TypeScript.": {
"category": "Error",
"code": 8014
},
"'yield' expressions are not currently supported.": {
"category": "Error",
"code": 9000

View File

@ -2370,15 +2370,25 @@ module ts {
return program.getSyntacticDiagnostics(getValidSourceFile(fileName));
}
function isJavaScript(fileName: string) {
return fileExtensionIs(fileName, ".tsjs");
}
/**
* 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
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.
@ -2392,6 +2402,148 @@ module ts {
return semanticDiagnostics.concat(declarationDiagnostics);
}
function getJavaScriptSemanticDiagnostics(sourceFile: SourceFile): Diagnostic[] {
let diagnostics: Diagnostic[] = [];
walk(sourceFile);
return diagnostics;
function walk(node: Node) {
if (!node) {
return;
}
switch (node.kind) {
case SyntaxKind.ImportEqualsDeclaration:
diagnostics.push(createDiagnosticForNode(node, Diagnostics.import_can_only_be_used_in_TypeScript));
return;
case SyntaxKind.ExportAssignment:
diagnostics.push(createDiagnosticForNode(node, Diagnostics.export_can_only_be_used_in_TypeScript));
return;
case SyntaxKind.TypeParameter:
diagnostics.push(createDiagnosticForNode(node, Diagnostics.type_parameter_declarations_can_only_be_used_in_TypeScript));
return;
case SyntaxKind.ClassDeclaration:
let classDeclaration = <ClassDeclaration>node;
if (checkModifiers(classDeclaration.modifiers)) {
return;
}
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_TypeScript));
return;
}
break;
case SyntaxKind.InterfaceDeclaration:
diagnostics.push(createDiagnosticForNode(node, Diagnostics.interface_declarations_can_only_be_used_in_TypeScript));
return;
case SyntaxKind.ModuleDeclaration:
diagnostics.push(createDiagnosticForNode(node, Diagnostics.module_declarations_can_only_be_used_in_TypeScript));
return;
case SyntaxKind.TypeAliasDeclaration:
diagnostics.push(createDiagnosticForNode(node, Diagnostics.type_aliases_can_only_be_used_in_TypeScript));
return;
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) ||
checkTypeAnnotation(functionDeclaration.type)) {
return;
}
break;
case SyntaxKind.VariableStatement:
let variableStatement = <VariableStatement>node;
if (checkModifiers(variableStatement.modifiers)) {
return;
}
break;
case SyntaxKind.VariableDeclaration:
let variableDeclaration = <VariableDeclaration>node;
if (checkTypeAnnotation(variableDeclaration.type)) {
return;
}
break;
case SyntaxKind.CallExpression:
case SyntaxKind.NewExpression:
let expression = <CallExpression>node;
if (expression.typeArguments && expression.typeArguments.length > 0) {
diagnostics.push(createFileDiagnostic(sourceFile, expression.typeArguments.pos, expression.typeArguments.end,
Diagnostics.type_arguments_can_only_be_used_in_TypeScript));
return;
}
break;
case SyntaxKind.Parameter:
let parameter = <ParameterDeclaration>node;
if (parameter.modifiers) {
diagnostics.push(createFileDiagnostic(sourceFile, parameter.modifiers.pos, parameter.modifiers.end,
Diagnostics.parameter_modifiers_can_only_be_used_in_TypeScript));
return;
}
if (parameter.questionToken) {
diagnostics.push(createDiagnosticForNode(parameter.questionToken, Diagnostics.can_only_be_used_in_TypeScript));
return;
}
if (parameter.type) {
diagnostics.push(createDiagnosticForNode(parameter.type, Diagnostics.types_can_only_be_used_in_TypeScript));
return;
}
break;
case SyntaxKind.PropertyDeclaration:
diagnostics.push(createDiagnosticForNode(node, Diagnostics.property_declarations_can_only_be_used_in_TypeScript));
return
case SyntaxKind.EnumDeclaration:
diagnostics.push(createDiagnosticForNode(node, Diagnostics.enum_declarations_can_only_be_used_in_TypeScript));
return;
case SyntaxKind.TypeAssertionExpression:
diagnostics.push(createDiagnosticForNode(node, Diagnostics.type_assertion_expressions_can_only_be_used_in_TypeScript));
return;
}
forEachChild(node, walk);
}
function checkTypeAnnotation(type: TypeNode): boolean {
if (type) {
diagnostics.push(createDiagnosticForNode(type, Diagnostics.types_can_only_be_used_in_TypeScript));
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_TypeScript, 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();