Use compilerAssert/throwDiagnostic as appropriate (#480)
This commit is contained in:
Родитель
848bbd22af
Коммит
3b35f162c1
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче