Use compilerAssert/throwDiagnostic as appropriate (#480)

This commit is contained in:
Nick Guerrera 2021-04-23 14:19:45 -07:00 коммит произвёл GitHub
Родитель 848bbd22af
Коммит 3b35f162c1
6 изменённых файлов: 68 добавлений и 53 удалений

Просмотреть файл

@ -1,4 +1,4 @@
import { NamespaceType, Program, Type } from "@azure-tools/adl";
import { NamespaceType, Program, throwDiagnostic, Type } from "@azure-tools/adl";
const basePaths = new Map<Type, string>();
@ -78,10 +78,10 @@ function setOperationRoute(entity: Type, verb: OperationRoute) {
if (!operationRoutes.has(entity)) {
operationRoutes.set(entity, verb);
} else {
throw new Error(`HTTP verb already applied to ${entity.name}`);
throwDiagnostic(`HTTP verb already applied to ${entity.name}`, entity);
}
} else {
throw new Error(`Cannot use @${verb} on a ${entity.kind}`);
throwDiagnostic(`Cannot use @${verb} on a ${entity.kind}`, entity);
}
}
@ -135,7 +135,7 @@ const serviceDetails: {
export function _setServiceNamespace(namespace: NamespaceType): void {
if (serviceDetails.namespace && serviceDetails.namespace !== namespace) {
throw new Error("Cannot set service namespace more than once in an ADL project.");
throwDiagnostic("Cannot set service namespace more than once in an ADL project.", namespace);
}
serviceDetails.namespace = namespace;
@ -147,11 +147,11 @@ export function _checkIfServiceNamespace(namespace: NamespaceType): boolean {
export function serviceTitle(program: Program, entity: Type, title: string) {
if (serviceDetails.title) {
throw new Error("Service title can only be set once per ADL document.");
throwDiagnostic("Service title can only be set once per ADL document.", entity);
}
if (entity.kind !== "Namespace") {
throw new Error("The @serviceTitle decorator can only be applied to namespaces.");
throwDiagnostic("The @serviceTitle decorator can only be applied to namespaces.", entity);
}
_setServiceNamespace(entity);
@ -165,11 +165,11 @@ export function getServiceTitle(): string {
export function serviceVersion(program: Program, entity: Type, version: string) {
// TODO: This will need to change once we support multiple service versions
if (serviceDetails.version) {
throw new Error("Service version can only be set once per ADL document.");
throwDiagnostic("Service version can only be set once per ADL document.", entity);
}
if (entity.kind !== "Namespace") {
throw new Error("The @serviceVersion decorator can only be applied to namespaces.");
throwDiagnostic("The @serviceVersion decorator can only be applied to namespaces.", entity);
}
_setServiceNamespace(entity);
@ -191,7 +191,7 @@ const producesTypes = new Map<Type, string[]>();
export function produces(program: Program, entity: Type, ...contentTypes: string[]) {
if (entity.kind !== "Namespace") {
throw new Error("The @produces decorator can only be applied to namespaces.");
throwDiagnostic("The @produces decorator can only be applied to namespaces.", entity);
}
const values = getProduces(entity);
@ -206,7 +206,7 @@ const consumesTypes = new Map<Type, string[]>();
export function consumes(program: Program, entity: Type, ...contentTypes: string[]) {
if (entity.kind !== "Namespace") {
throw new Error("The @consumes decorator can only be applied to namespaces.");
throwDiagnostic("The @consumes decorator can only be applied to namespaces.", entity);
}
const values = getConsumes(entity);

Просмотреть файл

@ -1,3 +1,4 @@
import { compilerAssert } from "./diagnostics.js";
import { visitChildren } from "./parser.js";
import { Program } from "./program.js";
import {
@ -187,20 +188,25 @@ export function createBinder(): Binder {
}
function declareSymbol(table: SymbolTable, node: Declaration, name: string) {
if (!table) throw new Error("Attempted to declare symbol on non-existent table");
compilerAssert(table, "Attempted to declare symbol on non-existent table");
const symbol = createTypeSymbol(node, name);
node.symbol = symbol;
if (scope.kind === SyntaxKind.NamespaceStatement) {
if (node.kind === SyntaxKind.TemplateParameterDeclaration) {
throw new Error("Attempted to declare template parameter in namespace");
}
compilerAssert(
node.kind !== SyntaxKind.TemplateParameterDeclaration,
"Attempted to declare template parameter in namespace",
node
);
node.namespaceSymbol = scope.symbol;
} else if (scope.kind === SyntaxKind.ADLScript) {
if (node.kind === SyntaxKind.TemplateParameterDeclaration) {
throw new Error("Attempted to declare template parameter in global scope");
}
compilerAssert(
node.kind !== SyntaxKind.TemplateParameterDeclaration,
"Attempted to declare template parameter in global scope",
node
);
node.namespaceSymbol = fileNamespace.symbol;
}

Просмотреть файл

@ -1,4 +1,4 @@
import { throwDiagnostic } from "./diagnostics.js";
import { compilerAssert, throwDiagnostic } from "./diagnostics.js";
import { Program } from "./program.js";
import {
ADLScriptNode,
@ -398,9 +398,7 @@ export function createChecker(program: Program) {
}
function initializeTypeForNamespace(node: NamespaceStatementNode) {
if (!node.symbol) {
throw new Error("Namespace is unbound, please file a bug.");
}
compilerAssert(node.symbol, "Namespace is unbound.", node);
const symbolLinks = getSymbolLinks(node.symbol);
if (!symbolLinks.type) {
@ -433,9 +431,7 @@ export function createChecker(program: Program) {
if (!node.namespaceSymbol) return undefined;
const symbolLinks = getSymbolLinks(node.namespaceSymbol);
if (!symbolLinks.type) {
throw new Error("Parent namespace isn't typed yet, please file a bug.");
}
compilerAssert(symbolLinks.type, "Parent namespace isn't typed yet.", node);
return symbolLinks.type as NamespaceType;
}
@ -543,7 +539,7 @@ export function createChecker(program: Program) {
return resolveIdentifier(node);
}
throw new Error("Unknown type reference kind");
compilerAssert(false, "Unknown type reference kind", node);
}
function checkStringLiteral(str: StringLiteralNode): StringLiteralType {

Просмотреть файл

@ -7,7 +7,7 @@ import url from "url";
import yargs from "yargs";
import { CompilerOptions } from "../compiler/options.js";
import { compile } from "../compiler/program.js";
import { DiagnosticError, dumpError, logDiagnostics } from "./diagnostics.js";
import { compilerAssert, DiagnosticError, dumpError, logDiagnostics } from "./diagnostics.js";
import { adlVersion, NodeHost } from "./util.js";
const args = yargs(process.argv.slice(2))
@ -172,9 +172,8 @@ async function installVsix(pkg: string, install: (vsixPath: string) => void) {
break;
}
}
if (!vsix) {
throw new Error(`Installed ${pkg} from npm, but didn't find its .vsix file.`);
}
compilerAssert(vsix, `Installed ${pkg} from npm, but didn't find its .vsix file.`);
// install extension
install(vsix);

Просмотреть файл

@ -221,9 +221,7 @@ function getSourceLocationOfNode(node: Node): SourceLocation {
root = root.parent;
}
if (root.kind !== SyntaxKind.ADLScript) {
throw new Error("Cannot obtain source file of unbound node.");
}
compilerAssert(root.kind === SyntaxKind.ADLScript, "Cannot obtain source file of unbound node.");
return {
file: root.file,
@ -277,7 +275,7 @@ export function dumpError(error: Error, writeLine: WriteLine) {
* what got the compiler off track.
*/
export function compilerAssert(
condition: boolean,
condition: any,
message: string,
target?: DiagnosticTarget
): asserts condition {

Просмотреть файл

@ -1,5 +1,6 @@
import { Program } from "../compiler/program";
import { ModelTypeProperty, NamespaceType, Type } from "../compiler/types";
import { throwDiagnostic } from "../compiler/diagnostics.js";
import { Program } from "../compiler/program.js";
import { ModelTypeProperty, NamespaceType, Type } from "../compiler/types.js";
const docs = new Map<Type, string>();
@ -53,12 +54,12 @@ const numericTypes = new Set<string>();
export function numeric(program: Program, target: Type) {
if (!isIntrinsic(target)) {
throw new Error("Cannot apply @numeric decorator to non-intrinsic type.");
throwDiagnostic("Cannot apply @numeric decorator to non-intrinsic type.", target);
}
if (target.kind === "Model") {
numericTypes.add(target.name);
} else {
throw new Error("Cannot apply @numeric decorator to non-model type.");
throwDiagnostic("Cannot apply @numeric decorator to non-model type.", target);
}
}
@ -77,10 +78,10 @@ export function format(program: Program, target: Type, format: string) {
if (getIntrinsicType(target) === "string") {
formatValues.set(target, format);
} else {
throw new Error("Cannot apply @format to a non-string type");
throwDiagnostic("Cannot apply @format to a non-string type", target);
}
} else {
throw new Error("Cannot apply @format to anything that isn't a Model or ModelProperty");
throwDiagnostic("Cannot apply @format to anything that isn't a Model or ModelProperty", target);
}
}
@ -98,10 +99,13 @@ export function minLength(program: Program, target: Type, minLength: number) {
if (getIntrinsicType(target) === "string") {
minLengthValues.set(target, minLength);
} else {
throw new Error("Cannot apply @minLength to a non-string type");
throwDiagnostic("Cannot apply @minLength to a non-string type", target);
}
} else {
throw new Error("Cannot apply @minLength to anything that isn't a Model or ModelProperty");
throwDiagnostic(
"Cannot apply @minLength to anything that isn't a Model or ModelProperty",
target
);
}
}
@ -119,10 +123,13 @@ export function maxLength(program: Program, target: Type, maxLength: number) {
if (getIntrinsicType(target) === "string") {
maxLengthValues.set(target, maxLength);
} else {
throw new Error("Cannot apply @maxLength to a non-string type");
throwDiagnostic("Cannot apply @maxLength to a non-string type", target);
}
} else {
throw new Error("Cannot apply @maxLength to anything that isn't a Model or ModelProperty");
throwDiagnostic(
"Cannot apply @maxLength to anything that isn't a Model or ModelProperty",
target
);
}
}
@ -140,10 +147,13 @@ export function minValue(program: Program, target: Type, minValue: number) {
if (isNumericType(target)) {
minValues.set(target, minValue);
} else {
throw new Error("Cannot apply @minValue to a non-numeric type");
throwDiagnostic("Cannot apply @minValue to a non-numeric type", target);
}
} else {
throw new Error("Cannot apply @minValue to anything that isn't a Model or ModelProperty");
throwDiagnostic(
"Cannot apply @minValue to anything that isn't a Model or ModelProperty",
target
);
}
}
@ -161,10 +171,13 @@ export function maxValue(program: Program, target: Type, maxValue: number) {
if (isNumericType(target)) {
maxValues.set(target, maxValue);
} else {
throw new Error("Cannot apply @maxValue to a non-numeric type");
throwDiagnostic("Cannot apply @maxValue to a non-numeric type", target);
}
} else {
throw new Error("Cannot apply @maxValue to anything that isn't a Model or ModelProperty");
throwDiagnostic(
"Cannot apply @maxValue to anything that isn't a Model or ModelProperty",
target
);
}
}
@ -182,10 +195,10 @@ export function secret(program: Program, target: Type) {
if (getIntrinsicType(target) === "string") {
secretTypes.set(target, true);
} else {
throw new Error("Cannot apply @secret to a non-string type");
throwDiagnostic("Cannot apply @secret to a non-string type", target);
}
} else {
throw new Error("Cannot apply @secret to anything that isn't a Model");
throwDiagnostic("Cannot apply @secret to anything that isn't a Model", target);
}
}
@ -201,7 +214,7 @@ export function visibility(program: Program, target: Type, ...visibilities: stri
if (target.kind === "ModelProperty") {
visibilitySettings.set(target, visibilities);
} else {
throw new Error("The @visibility decorator can only be applied to model properties.");
throwDiagnostic("The @visibility decorator can only be applied to model properties.", target);
}
}
@ -211,7 +224,7 @@ export function getVisibility(target: Type): string[] | undefined {
export function withVisibility(program: Program, target: Type, ...visibilities: string[]) {
if (target.kind !== "Model") {
throw new Error("The @withVisibility decorator can only be applied to models.");
throwDiagnostic("The @withVisibility decorator can only be applied to models.", target);
}
const filter = (_: any, prop: ModelTypeProperty) => {
@ -241,7 +254,10 @@ export function list(program: Program, target: Type) {
if (target.kind === "Operation" || target.kind === "ModelProperty") {
listProperties.add(target);
} else {
throw new Error("The @list decorator can only be applied to interface or model properties.");
throwDiagnostic(
"The @list decorator can only be applied to interface or model properties.",
target
);
}
}
@ -263,7 +279,7 @@ export function tag(program: Program, target: Type, tag: string) {
tagProperties.set(target, [tag]);
}
} else {
throw new Error("The @tag decorator can only be applied to namespace or operation.");
throwDiagnostic("The @tag decorator can only be applied to namespace or operation.", target);
}
}