@neo-one/smart-contract-compiler
Version:
NEO•ONE TypeScript smart contract compiler.
72 lines (70 loc) • 3.58 kB
JavaScript
import { tsUtils } from '@neo-one/ts-utils';
import _ from 'lodash';
import ts, { DiagnosticCategory } from 'typescript';
import { format } from 'util';
import { AnalysisService } from './analysis';
import { createBuiltins } from './compile/builtins';
import { CompilerDiagnostic } from './CompilerDiagnostic';
import { DiagnosticCode } from './DiagnosticCode';
import { DiagnosticMessage } from './DiagnosticMessage';
const getErrorKey = (diagnostic) => `${diagnostic.file}:${diagnostic.start}:${diagnostic.length}:${diagnostic.code}`;
const getFullKey = (diagnostic) => `${diagnostic.file}:${diagnostic.start}:${diagnostic.length}:${diagnostic.category}:${diagnostic.code}:${diagnostic.messageText}`;
export class Context {
constructor(sourceFiles, program, typeChecker, languageService, host, mutableDiagnostics = [...ts.getPreEmitDiagnostics(program)]) {
this.sourceFiles = sourceFiles;
this.program = program;
this.typeChecker = typeChecker;
this.languageService = languageService;
this.host = host;
this.mutableDiagnostics = mutableDiagnostics;
this.analysis = new AnalysisService(this);
this.builtins = createBuiltins(this);
}
get diagnostics() {
const errorDiagnostics = new Set();
for (const diagnostic of this.mutableDiagnostics) {
if (diagnostic.category === DiagnosticCategory.Error) {
errorDiagnostics.add(getErrorKey(diagnostic));
}
}
const diagnostics = this.mutableDiagnostics.filter((diagnostic) => diagnostic.category === DiagnosticCategory.Error || !errorDiagnostics.has(getErrorKey(diagnostic)));
return _.uniqBy(diagnostics, getFullKey);
}
update(sourceFiles, program, typeChecker, languageService) {
return new Context(sourceFiles, program, typeChecker, languageService, this.host, [...this.mutableDiagnostics]);
}
reportError(node, code, message, ...args) {
if (!this.isDeclarationFile(node)) {
this.mutableDiagnostics.push(new CompilerDiagnostic(node, this.getDiagnosticMessage(message, ...args), code, ts.DiagnosticCategory.Error));
}
}
reportWarning(node, code, message, ...args) {
if (!this.isDeclarationFile(node)) {
this.mutableDiagnostics.push(new CompilerDiagnostic(node, this.getDiagnosticMessage(message, ...args), code, ts.DiagnosticCategory.Warning));
}
}
reportUnsupported(node) {
this.reportError(node, DiagnosticCode.UnsupportedSyntax, DiagnosticMessage.UnsupportedSyntax);
}
reportUnsupportedEfficiency(node) {
this.reportError(node, DiagnosticCode.UnsupportedSyntax, DiagnosticMessage.EfficiencyUnsupportedSyntax);
}
reportTypeError(node) {
this.reportError(node, DiagnosticCode.UnknownType, DiagnosticMessage.CouldNotInferType);
}
reportTypeWarning(node) {
this.reportWarning(node, DiagnosticCode.UnknownType, DiagnosticMessage.CouldNotInferTypeDeopt);
}
getDiagnosticMessage(message, ...args) {
const match = message.match(/%[dfijoOs]/g);
const expectedLength = (match === null ? [] : match).length;
if (expectedLength !== args.length) {
throw new Error(`The provided arguments length (${args.length}) does not match the required arguments length (${expectedLength})`);
}
return format(message, ...args);
}
isDeclarationFile(node) {
return tsUtils.file.isDeclarationFile(tsUtils.node.getSourceFile(node));
}
}
//# sourceMappingURL=Context.js.map