// Copyright (c) 2021-2022 Huawei Device Co., Ltd. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. import * as ts from "typescript"; import * as jshelpers from "./jshelpers" import { LOGE } from "./log" export class DiagnosticError { irnode:ts.Node | undefined; code:number; file: ts.SourceFile | undefined; args: (string | number | undefined)[]; constructor(irnode:ts.Node | undefined, code:number, file?:ts.SourceFile | undefined, args?:(string | number | undefined)[]) { this.code = code this.irnode = irnode this.file = file ? file : undefined this.args = args ? args : [] } } export function printDiagnostic(diagnostic: ts.Diagnostic) { let message = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n"); if (diagnostic.file && diagnostic.start!= undefined) { let { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start); LOGE(`${diagnostic.file.fileName} (${line + 1},${character + 1})`, `${message}`); } else { LOGE("Error",message); } } export function createDiagnosticOnFirstToken(file:ts.SourceFile, node: ts.Node ,message: ts.DiagnosticMessage,...args:(string | number | undefined)[]) { let span = jshelpers.getSpanOfTokenAtPosition(file, node.pos); let diagnostic = jshelpers.createFileDiagnostic(file,span.start,span.length,message,...args); return diagnostic; } export function createFileDiagnostic(node: ts.Node, message: ts.DiagnosticMessage, ...args: (string | number | undefined)[]) { let diagnostic; let soureceFile: ts.SourceFile = jshelpers.getSourceFileOfNode(node); let span = jshelpers.getErrorSpanForNode(soureceFile, node); switch (node.kind) { case ts.SyntaxKind.Identifier: diagnostic = jshelpers.createFileDiagnostic(soureceFile, span.start, span.length, message, ts.idText(node)); break; case ts.SyntaxKind.PrivateIdentifier: diagnostic = jshelpers.createFileDiagnostic(soureceFile, span.start, span.length, message, ts.idText(node)); break; case ts.SyntaxKind.ReturnStatement: diagnostic = createDiagnosticOnFirstToken(soureceFile, node, message, ...args); break; default: diagnostic = jshelpers.createDiagnosticForNode(node, message, ...args); break; } return diagnostic; } export function createDiagnostic(file:ts.SourceFile | undefined, location: ts.Node | undefined, message: ts.DiagnosticMessage,...args:(string | number | undefined)[]) { var diagnostic; if (!location) { return jshelpers.createCompilerDiagnostic(message, ...args); } if (file) { diagnostic = createFileDiagnostic(location, message, ...args); } else { diagnostic = jshelpers.createDiagnosticForNode(location, message, ...args) } return diagnostic } // @ts-ignore function diag(code:number, category:ts.DiagnosticCategory, key:string, message:string, reportsUnnecessary?:{},elidedInCompatabilityPyramid?:{}):ts.DiagnosticMessage { return { code: code, category: category, key: key, message: message, reportsUnnecessary: reportsUnnecessary }; } % def convertPropertyName(origName) % result = "" % origName.each_char{|char| % if char == "*" % result += "_Asterisk" % elsif char == "/" % result += "_Slash" % elsif char == ":" % result += "_Colon" % elsif /\w/.match(char) % result += char % else % result += "_" % end % } % #get rid of all multi-underscores % result = result.gsub(/_+/, "_"); % % #remove any leading underscore, unless it is followed by a number. % result = result.gsub(/^_([^\d])/, "$1"); % % #get rid of all trailing underscores. % result = result.gsub(/_$/, ""); % return result % end export enum DiagnosticCode { % Diagnostic::datas.each do |data| % name = data[0] % propName = convertPropertyName(name) % code = data[1]["code"] <%= propName %> = <%= code %>, %end }; export function getDiagnostic(code:DiagnosticCode): ts.DiagnosticMessage|undefined { switch (code) { % % def createKey(name,code) % key = "" % name = name.slice(0,100) % key = name + "_" + code.to_s % return key % end % % def genReportsUnnecessary(reportsUnnecessary) % if reportsUnnecessary.nil? % return "" % end % return ", /*reportsUnnecessary*/ " + reportsUnnecessary.to_s % end % % def genElidedInCompatabilityPyramid(elidedInCompatabilityPyramid,reportsUnnecessary) % reportsUnnecessaryVal = "" % if reportsUnnecessary.nil? || !reportsUnnecessary % reportsUnnecessaryVal = ", /*reportsUnnecessary*/ undefined" % end % if elidedInCompatabilityPyramid.nil? || !elidedInCompatabilityPyramid % return "" % end % return reportsUnnecessaryVal + ", /*elidedInCompatabilityPyramid*/ " + elidedInCompatabilityPyramid.to_s % end % % def genReportsDeprecated(reportsDeprecated,argElidedInCompatabilityPyramid) % argElidedInCompatabilityPyramidVal = "" % if argElidedInCompatabilityPyramid.nil? % argElidedInCompatabilityPyramidVal = ", /*reportsUnnecessary*/ undefined, /*elidedInCompatabilityPyramid*/ undefined" % end % if reportsDeprecated.nil? || !reportsDeprecated % return "" % end % return argElidedInCompatabilityPyramidVal + "/*reportsDeprecated*/ " + reportsDeprecated.to_s % end % % Diagnostic::datas.each do |data| % name = data[0] % propName = convertPropertyName(name) % diagnosticDetials = data[1] % code = diagnosticDetials["code"] % category = diagnosticDetials["category"] % reportsUnnecessary = diagnosticDetials["reportsUnnecessary"] % elidedInCompatabilityPyramid = diagnosticDetials["elidedInCompatabilityPyramid"] % reportsDeprecated = diagnosticDetials["reportsDeprecated"] % key = createKey(propName,code) % argReportsUnnecessary = genReportsUnnecessary(reportsUnnecessary) % argElidedInCompatabilityPyramid = genElidedInCompatabilityPyramid(elidedInCompatabilityPyramid,reportsUnnecessary) % argReportsDeprecated = genReportsDeprecated(reportsDeprecated,argElidedInCompatabilityPyramid) % message = name.to_json + argReportsUnnecessary + argElidedInCompatabilityPyramid + argReportsDeprecated case <%= code %> : return diag(<%= code %>, ts.DiagnosticCategory.<%= category %>, "<%= key %>", <%= message %>); % end default : console.log('The syntax error code is not supported.'); return undefined; } };