| Index: pkg/servicec/lib/validator.dart
|
| diff --git a/pkg/servicec/lib/validator.dart b/pkg/servicec/lib/validator.dart
|
| deleted file mode 100644
|
| index 04b31f2165e22f97664367dc47f5bd46ac3b3ba3..0000000000000000000000000000000000000000
|
| --- a/pkg/servicec/lib/validator.dart
|
| +++ /dev/null
|
| @@ -1,400 +0,0 @@
|
| -// Copyright (c) 2015, the Dartino project authors. Please see the AUTHORS file
|
| -// for details. All rights reserved. Use of this source code is governed by a
|
| -// BSD-style license that can be found in the LICENSE file.
|
| -
|
| -library servicec.validator;
|
| -
|
| -import 'node.dart' show
|
| - CompilationUnitNode,
|
| - FormalNode,
|
| - FunctionNode,
|
| - IdentifierNode,
|
| - ListType,
|
| - MemberNode,
|
| - FieldNode,
|
| - Node,
|
| - PointerType,
|
| - RecursiveVisitor,
|
| - ServiceNode,
|
| - StructNode,
|
| - TopLevelNode,
|
| - TypeNode,
|
| - UnionNode;
|
| -
|
| -import 'errors.dart' show
|
| - BadFieldTypeError,
|
| - BadListTypeError,
|
| - BadPointerTypeError,
|
| - BadReturnTypeError,
|
| - BadSingleFormalError,
|
| - BadTypeParameterError,
|
| - CompilationError,
|
| - CyclicStructError,
|
| - ErrorNode,
|
| - ErrorTag,
|
| - MultipleDefinitionsError,
|
| - MultipleUnionsError,
|
| - NotPrimitiveFormalError,
|
| - SyntaxError,
|
| - ServiceStructNameClashError,
|
| - UndefinedServiceError;
|
| -
|
| -import 'dart:collection' show
|
| - Queue;
|
| -
|
| -import 'cycle_detection.dart' show
|
| - StructGraph;
|
| -
|
| -// Validation functions.
|
| -List<CompilationError> validate(CompilationUnitNode compilationUnit) {
|
| - Validator validator = new Validator();
|
| - validator.process(compilationUnit);
|
| - return validator.errors;
|
| -}
|
| -
|
| -class Validator extends RecursiveVisitor {
|
| - List<CompilationError> errors;
|
| - Environment environment;
|
| - StructGraph structGraph;
|
| -
|
| - Validator()
|
| - : errors = <CompilationError>[],
|
| - environment = new Environment(),
|
| - structGraph = new StructGraph(),
|
| - super();
|
| -
|
| - void process(CompilationUnitNode compilationUnit) {
|
| - visitCompilationUnit(compilationUnit);
|
| - errors.addAll(structGraph.findCycles());
|
| - }
|
| -
|
| - // Visit methods.
|
| - void visitCompilationUnit(CompilationUnitNode compilationUnit) {
|
| - enterCompilationUnitScope(compilationUnit);
|
| - checkHasAtLeastOneService(compilationUnit);
|
| - super.visitCompilationUnit(compilationUnit);
|
| - leaveCompilationUnitScope(compilationUnit);
|
| - }
|
| -
|
| - void visitService(ServiceNode service) {
|
| - enterServiceScope(service);
|
| - checkIsNotError(service);
|
| - super.visitService(service);
|
| - leaveServiceScope(service);
|
| - }
|
| -
|
| - void visitStruct(StructNode struct) {
|
| - enterStructScope(struct);
|
| - checkIsNotError(struct);
|
| - checkHasAtMostOneUnion(struct);
|
| - super.visitStruct(struct);
|
| - structGraph.add(struct);
|
| - leaveStructScope(struct);
|
| - }
|
| -
|
| - void visitFunction(FunctionNode function) {
|
| - enterFunctionScope(function);
|
| - checkIsNotError(function);
|
| -
|
| - visitReturnType(function.returnType);
|
| - // Ensure formal parameters are either a single pointer to a user-defined
|
| - // type, or a list of primitives.
|
| - int length = function.formals.length;
|
| - if (length == 1) {
|
| - visitSingleFormal(function.formals[0]);
|
| - } else if (length > 1) {
|
| - for (FormalNode formal in function.formals) {
|
| - visitPrimitiveFormal(formal);
|
| - }
|
| - }
|
| -
|
| - leaveFunctionScope(function);
|
| - }
|
| -
|
| - void visitSingleFormal(FormalNode formal) {
|
| - checkIsNotError(formal);
|
| - visitType(formal.type);
|
| - checkSingleFormal(formal.type);
|
| - }
|
| -
|
| - void visitPrimitiveFormal(FormalNode formal) {
|
| - checkIsNotError(formal);
|
| - visitType(formal.type);
|
| - checkIsPrimitiveFormal(formal);
|
| - }
|
| -
|
| - void visitUnion(UnionNode union) {
|
| - // TODO(stanm): checkIsNotError(union);
|
| - super.visitUnion(union);
|
| - }
|
| -
|
| - void visitField(FieldNode field) {
|
| - checkIsNotError(field);
|
| - visitType(field.type); // resolve
|
| - if (field.type.isPointer()) {
|
| - checkPointeeTypeResolves(field.type);
|
| - } else if (field.type.isList()) {
|
| - ListType list = field.type;
|
| - visitListType(list);
|
| - } else {
|
| - checkFieldSimpleType(field.type);
|
| - }
|
| - }
|
| -
|
| - void visitReturnType(TypeNode type) {
|
| - visitType(type);
|
| - checkReturnType(type);
|
| - }
|
| -
|
| - void visitTypeParameter(TypeNode type) {
|
| - visitType(type);
|
| - checkTypeParameter(type);
|
| - }
|
| -
|
| - void visitPointerType(PointerType type) {
|
| - visitType(type);
|
| - checkPointeeTypeResolves(type);
|
| - }
|
| -
|
| - void visitListType(ListType type) {
|
| - visitType(type);
|
| - checkIsNotError(type);
|
| - checkIsListType(type);
|
| - super.visitListType(type);
|
| - }
|
| -
|
| - void visitType(TypeNode type) {
|
| - type.resolve(environment.structs);
|
| - }
|
| -
|
| - void visitError(ErrorNode error) {
|
| - errors.add(new SyntaxError(error));
|
| - }
|
| -
|
| - // Checks.
|
| - void checkIsNotError(Node node) {
|
| - // Using var as a work-around for compiler warnings about ErrorNode not
|
| - // being in the node hierarchy.
|
| - var dummy = node;
|
| - if (dummy is ErrorNode) {
|
| - ErrorNode error = dummy;
|
| - visitError(error);
|
| - }
|
| - }
|
| -
|
| - void checkHasAtLeastOneService(CompilationUnitNode compilationUnit) {
|
| - for (Node node in compilationUnit.topLevels) {
|
| - if (node is ServiceNode) return;
|
| - }
|
| - errors.add(new UndefinedServiceError());
|
| - }
|
| -
|
| - void checkHasAtMostOneUnion(StructNode struct) {
|
| - int count = 0;
|
| - for (MemberNode member in struct.members) {
|
| - if (member is UnionNode && ++count > 1) {
|
| - errors.add(new MultipleUnionsError(struct));
|
| - return;
|
| - }
|
| - }
|
| - }
|
| -
|
| - void checkIsPointerOrPrimitive(TypeNode type, CompilationError error) {
|
| - if (type.isPrimitive()) return;
|
| - if (type.isPointer()) {
|
| - checkPointeeTypeResolves(type);
|
| - } else {
|
| - errors.add(error);
|
| - }
|
| - }
|
| -
|
| - void checkSingleFormal(TypeNode type) {
|
| - checkIsPointerOrPrimitive(type, new BadSingleFormalError(type));
|
| - }
|
| -
|
| - void checkIsPrimitiveFormal(FormalNode formal) {
|
| - if (!formal.type.isPrimitive()) {
|
| - errors.add(new NotPrimitiveFormalError(formal));
|
| - }
|
| - }
|
| -
|
| - void checkPointeeTypeResolves(PointerType type) {
|
| - if (!type.pointeeResolves()) {
|
| - errors.add(new BadPointerTypeError(type));
|
| - }
|
| - }
|
| -
|
| - void checkIsListType(ListType type) {
|
| - if (!type.isList()) {
|
| - errors.add(new BadListTypeError(type));
|
| - }
|
| - }
|
| -
|
| - void checkReturnType(TypeNode type) {
|
| - checkIsPointerOrPrimitive(type, new BadReturnTypeError(type));
|
| - }
|
| -
|
| - void checkTypeParameter(TypeNode type) {
|
| - if (!(type.isPrimitive() || type.isStruct())) {
|
| - errors.add(new BadTypeParameterError(type));
|
| - }
|
| - }
|
| -
|
| - void checkFieldSimpleType(TypeNode type) {
|
| - if (!(type.isPrimitive() || type.isString() || type.isStruct())) {
|
| - errors.add(new BadFieldTypeError(type));
|
| - }
|
| - }
|
| -
|
| - // Scope management.
|
| - void enterCompilationUnitScope(CompilationUnitNode compilationUnit) {
|
| - compilationUnit.topLevels.forEach(addTopLevelSymbol);
|
| - }
|
| -
|
| - void enterServiceScope(ServiceNode service) {
|
| - service.functions.forEach(addFunctionSymbol);
|
| - }
|
| -
|
| - void enterStructScope(StructNode struct) {
|
| - struct.members.forEach(addMemberSymbol);
|
| - }
|
| -
|
| - void enterFunctionScope(FunctionNode function) {
|
| - function.formals.forEach(addFormalSymbol);
|
| - }
|
| -
|
| -
|
| - void leaveCompilationUnitScope(CompilationUnitNode compilationUnit) {
|
| - compilationUnit.topLevels.forEach(removeTopLevelSymbol);
|
| - }
|
| -
|
| - void leaveServiceScope(ServiceNode service) {
|
| - service.functions.forEach(removeFunctionSymbol);
|
| - }
|
| -
|
| - void leaveStructScope(StructNode struct) {
|
| - struct.members.forEach(removeMemberSymbol);
|
| - }
|
| -
|
| - void leaveFunctionScope(FunctionNode function) {
|
| - function.formals.forEach(removeFormalSymbol);
|
| - }
|
| -
|
| - void addTopLevelSymbol(TopLevelNode node) {
|
| - if (node is ServiceNode) {
|
| - addServiceSymbol(node);
|
| - } else if (node is StructNode) {
|
| - addStructSymbol(node);
|
| - }
|
| - }
|
| -
|
| - void addServiceSymbol(ServiceNode service) {
|
| - checkIsNotNameClash(environment.structs.keys.toSet(), service.identifier);
|
| - addSymbol(environment.services, service.identifier);
|
| - }
|
| -
|
| - void addStructSymbol(StructNode struct) {
|
| - checkIsNotNameClash(environment.services, struct.identifier);
|
| - if (environment.structs.containsKey(struct.identifier)) {
|
| - IdentifierNode original =
|
| - environment.structs.keys.toSet().lookup(struct.identifier);
|
| - errors.add(new MultipleDefinitionsError(original, struct.identifier));
|
| - } else {
|
| - environment.structs[struct.identifier] = struct;
|
| - }
|
| - }
|
| -
|
| - void addFunctionSymbol(FunctionNode function) {
|
| - addSymbol(environment.properties, function.identifier);
|
| - }
|
| -
|
| - void addMemberSymbol(MemberNode member) {
|
| - if (member is UnionNode) {
|
| - UnionNode union = member;
|
| - union.fields.forEach(addFieldSymbol);
|
| - } else {
|
| - addFieldSymbol(member);
|
| - }
|
| - }
|
| -
|
| - void addFieldSymbol(FieldNode field) {
|
| - addSymbol(environment.properties, field.identifier);
|
| - }
|
| -
|
| - void addFormalSymbol(FormalNode formal) {
|
| - addSymbol(environment.formals, formal.identifier);
|
| - }
|
| -
|
| - void removeTopLevelSymbol(TopLevelNode node) {
|
| - if (node is ServiceNode) {
|
| - removeServiceSymbol(node);
|
| - } else if (node is StructNode) {
|
| - removeStructSymbol(node);
|
| - }
|
| - }
|
| -
|
| - void removeServiceSymbol(ServiceNode service) {
|
| - removeSymbol(environment.services, service.identifier);
|
| - }
|
| -
|
| - void removeStructSymbol(StructNode struct) {
|
| - environment.structs.remove(struct.identifier);
|
| - }
|
| -
|
| - void removeFunctionSymbol(FunctionNode function) {
|
| - removeSymbol(environment.properties, function.identifier);
|
| - }
|
| -
|
| - void removeMemberSymbol(MemberNode member) {
|
| - if (member is UnionNode) {
|
| - UnionNode union = member;
|
| - union.fields.forEach(removeFieldSymbol);
|
| - } else {
|
| - removeFieldSymbol(member);
|
| - }
|
| - }
|
| -
|
| - void removeFieldSymbol(FieldNode field) {
|
| - removeSymbol(environment.properties, field.identifier);
|
| - }
|
| -
|
| - void removeFormalSymbol(FormalNode formal) {
|
| - removeSymbol(environment.formals, formal.identifier);
|
| - }
|
| -
|
| - void checkIsNotNameClash(Set<IdentifierNode> symbols,
|
| - IdentifierNode identifier) {
|
| - IdentifierNode original = symbols.lookup(identifier);
|
| - if (null != original) {
|
| - errors.add(new ServiceStructNameClashError(original, identifier));
|
| - }
|
| - }
|
| -
|
| - void addSymbol(Set<IdentifierNode> symbols, IdentifierNode identifier) {
|
| - IdentifierNode original = symbols.lookup(identifier);
|
| - if (null != original) {
|
| - errors.add(new MultipleDefinitionsError(original, identifier));
|
| - } else {
|
| - symbols.add(identifier);
|
| - }
|
| - }
|
| -
|
| - void removeSymbol(Set<IdentifierNode> symbols, IdentifierNode identifier) {
|
| - symbols.remove(identifier);
|
| - }
|
| -}
|
| -
|
| -class Environment {
|
| - Set<IdentifierNode> services;
|
| - Map<IdentifierNode, StructNode> structs;
|
| - Set<IdentifierNode> properties;
|
| - Set<IdentifierNode> formals;
|
| -
|
| - Environment()
|
| - : services = new Set<IdentifierNode>(),
|
| - structs = new Map<IdentifierNode, StructNode>(),
|
| - properties = new Set<IdentifierNode>(),
|
| - formals = new Set<IdentifierNode>();
|
| -}
|
| -
|
| -
|
|
|