• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (c) 2021-2022 Huawei Device Co., Ltd.
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6//     http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14import * as ts from "typescript";
15import * as jshelpers from "./jshelpers"
16import { LOGE } from "./log"
17export class DiagnosticError {
18  irnode:ts.Node | undefined;
19  code:number;
20  file: ts.SourceFile | undefined;
21  args: (string | number | undefined)[];
22
23  constructor(irnode:ts.Node | undefined, code:number, file?:ts.SourceFile | undefined, args?:(string | number | undefined)[]) {
24    this.code = code
25    this.irnode = irnode
26    this.file = file ? file : undefined
27    this.args = args ? args : []
28  }
29}
30
31export function printDiagnostic(diagnostic: ts.Diagnostic) {
32
33  let message = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n");
34  if (diagnostic.file && diagnostic.start!= undefined) {
35    let { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
36    LOGE(`${diagnostic.file.fileName} (${line + 1},${character + 1})`, `${message}`);
37  } else {
38    LOGE("Error",message);
39  }
40
41}
42
43export function createDiagnosticOnFirstToken(file:ts.SourceFile, node: ts.Node ,message: ts.DiagnosticMessage,...args:(string | number | undefined)[]) {
44   let span = jshelpers.getSpanOfTokenAtPosition(file, node.pos);
45   let diagnostic = jshelpers.createFileDiagnostic(file,span.start,span.length,message,...args);
46   return diagnostic;
47}
48
49export function createFileDiagnostic(node: ts.Node, message: ts.DiagnosticMessage, ...args: (string | number | undefined)[]) {
50    let diagnostic;
51    let soureceFile: ts.SourceFile = jshelpers.getSourceFileOfNode(node);
52    let span = jshelpers.getErrorSpanForNode(soureceFile, node);
53    switch (node.kind) {
54        case ts.SyntaxKind.Identifier:
55            diagnostic = jshelpers.createFileDiagnostic(soureceFile, span.start, span.length, message, ts.idText(<ts.Identifier>node));
56            break;
57        case ts.SyntaxKind.PrivateIdentifier:
58            diagnostic = jshelpers.createFileDiagnostic(soureceFile, span.start, span.length, message, ts.idText(<ts.PrivateIdentifier>node));
59            break;
60        case ts.SyntaxKind.ReturnStatement:
61            diagnostic = createDiagnosticOnFirstToken(soureceFile, node, message, ...args);
62            break;
63        default:
64            diagnostic = jshelpers.createDiagnosticForNode(node, message, ...args);
65            break;
66    }
67
68    return diagnostic;
69}
70
71export function createDiagnostic(file:ts.SourceFile | undefined, location: ts.Node | undefined, message: ts.DiagnosticMessage,...args:(string | number | undefined)[]) {
72  var diagnostic;
73
74  if (!location) {
75    return jshelpers.createCompilerDiagnostic(message, ...args);
76   }
77
78  if (file) {
79    diagnostic = createFileDiagnostic(location, message, ...args);
80  } else {
81    diagnostic = jshelpers.createDiagnosticForNode(location, message, ...args)
82  }
83
84  return diagnostic
85}
86
87// @ts-ignore
88function diag(code:number, category:ts.DiagnosticCategory, key:string, message:string, reportsUnnecessary?:{},elidedInCompatabilityPyramid?:{}):ts.DiagnosticMessage {
89   return { code: code, category: category, key: key, message: message, reportsUnnecessary: reportsUnnecessary };
90}
91
92% def convertPropertyName(origName)
93%   result = ""
94%   origName.each_char{|char|
95%   if char == "*"
96%      result += "_Asterisk"
97%   elsif char == "/"
98%      result +=  "_Slash"
99%   elsif char == ":"
100%      result += "_Colon"
101%   elsif /\w/.match(char)
102%      result += char
103%   else
104%      result += "_"
105%   end
106%   }
107%   #get rid of all multi-underscores
108%   result = result.gsub(/_+/, "_");
109%
110%   #remove any leading underscore, unless it is followed by a number.
111%   result = result.gsub(/^_([^\d])/, "$1");
112%
113%   #get rid of all trailing underscores.
114%   result = result.gsub(/_$/, "");
115%   return result
116% end
117
118export enum DiagnosticCode {
119% Diagnostic::datas.each do |data|
120% name = data[0]
121% propName = convertPropertyName(name)
122% code = data[1]["code"]
123   <%= propName %> = <%= code %>,
124%end
125};
126
127export function getDiagnostic(code:DiagnosticCode): ts.DiagnosticMessage|undefined {
128   switch (code) {
129%
130% def createKey(name,code)
131%   key = ""
132%   name = name.slice(0,100)
133%   key = name + "_" + code.to_s
134%   return key
135% end
136%
137% def genReportsUnnecessary(reportsUnnecessary)
138%   if reportsUnnecessary.nil?
139%      return ""
140%   end
141%   return ", /*reportsUnnecessary*/ " + reportsUnnecessary.to_s
142% end
143%
144% def genElidedInCompatabilityPyramid(elidedInCompatabilityPyramid,reportsUnnecessary)
145%   reportsUnnecessaryVal = ""
146%   if reportsUnnecessary.nil? || !reportsUnnecessary
147%      reportsUnnecessaryVal = ", /*reportsUnnecessary*/ undefined"
148%   end
149%   if elidedInCompatabilityPyramid.nil? || !elidedInCompatabilityPyramid
150%      return ""
151%   end
152%   return reportsUnnecessaryVal + ", /*elidedInCompatabilityPyramid*/ " + elidedInCompatabilityPyramid.to_s
153% end
154%
155% def genReportsDeprecated(reportsDeprecated,argElidedInCompatabilityPyramid)
156%   argElidedInCompatabilityPyramidVal = ""
157%   if argElidedInCompatabilityPyramid.nil?
158%      argElidedInCompatabilityPyramidVal = ", /*reportsUnnecessary*/ undefined, /*elidedInCompatabilityPyramid*/ undefined"
159%   end
160%   if reportsDeprecated.nil? || !reportsDeprecated
161%      return ""
162%   end
163%   return argElidedInCompatabilityPyramidVal + "/*reportsDeprecated*/ " + reportsDeprecated.to_s
164% end
165%
166% Diagnostic::datas.each do |data|
167% name = data[0]
168% propName = convertPropertyName(name)
169% diagnosticDetials = data[1]
170% code = diagnosticDetials["code"]
171% category = diagnosticDetials["category"]
172% reportsUnnecessary = diagnosticDetials["reportsUnnecessary"]
173% elidedInCompatabilityPyramid = diagnosticDetials["elidedInCompatabilityPyramid"]
174% reportsDeprecated = diagnosticDetials["reportsDeprecated"]
175% key = createKey(propName,code)
176% argReportsUnnecessary = genReportsUnnecessary(reportsUnnecessary)
177% argElidedInCompatabilityPyramid = genElidedInCompatabilityPyramid(elidedInCompatabilityPyramid,reportsUnnecessary)
178% argReportsDeprecated = genReportsDeprecated(reportsDeprecated,argElidedInCompatabilityPyramid)
179% message = name.to_json + argReportsUnnecessary + argElidedInCompatabilityPyramid + argReportsDeprecated
180   case <%= code %> :
181      return diag(<%= code %>, ts.DiagnosticCategory.<%= category %>, "<%= key %>", <%= message %>);
182% end
183   default :
184      console.log('The syntax error code is not supported.');
185      return undefined;
186    }
187};