/cpp/src/main/java/com/google/test/metric/cpp/CppClassRepository.java
http://testability-explorer.googlecode.com/ · Java · 187 lines · 145 code · 25 blank · 17 comment · 8 complexity · 49b47054cc72d10a66cee164ee2ff9f5 MD5 · raw file
- /*
- * Copyright 2008 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
- package com.google.test.metric.cpp;
- import com.google.test.metric.ClassInfo;
- import com.google.test.metric.ClassRepository;
- import com.google.test.metric.FieldInfo;
- import com.google.test.metric.LocalVariableInfo;
- import com.google.test.metric.MethodInfo;
- import com.google.test.metric.Type;
- import com.google.test.metric.Variable;
- import com.google.test.metric.cpp.dom.AssignmentExpression;
- import com.google.test.metric.cpp.dom.ClassDeclaration;
- import com.google.test.metric.cpp.dom.FunctionDefinition;
- import com.google.test.metric.cpp.dom.Name;
- import com.google.test.metric.cpp.dom.Node;
- import com.google.test.metric.cpp.dom.ReturnStatement;
- import com.google.test.metric.cpp.dom.TranslationUnit;
- import com.google.test.metric.cpp.dom.VariableDeclaration;
- import com.google.test.metric.cpp.dom.Visitor;
- import com.google.test.metric.method.op.turing.FieldAssignment;
- import com.google.test.metric.method.op.turing.LocalAssignment;
- import com.google.test.metric.method.op.turing.Operation;
- import com.google.test.metric.method.op.turing.ReturnOperation;
- import java.io.InputStream;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.Stack;
- public class CppClassRepository implements ClassRepository {
- private final Map<String, ClassInfo> classes = new HashMap<String, ClassInfo>();
- private static class LocalVariableExtractor extends Visitor {
- private final List<LocalVariableInfo> variables = new ArrayList<LocalVariableInfo>();
- List<LocalVariableInfo> getResult() {
- return variables;
- }
- @Override
- public void visit(VariableDeclaration localVariableDeclaration) {
- Type variableType = CppType.fromName(localVariableDeclaration.getName(),
- localVariableDeclaration.isPointer());
- variables.add(new LocalVariableInfo(localVariableDeclaration.getName(),
- variableType));
- }
- }
- private static class OperationBuilder extends Visitor {
- private final List<Operation> operations = new ArrayList<Operation>();
- private final CppClassRepository repository;
- public OperationBuilder(CppClassRepository repository) {
- this.repository = repository;
- }
- List<Operation> getResult() {
- return operations;
- }
- @Override
- public void visit(AssignmentExpression assignmentExpression) {
- Node leftSide = assignmentExpression.getExpression(0);
- Node rightSide = assignmentExpression.getExpression(1);
- Variable leftVar = null;
- Variable rightVar = null;
- VariableDeclaration leftDeclaration = null;
- if (leftSide instanceof Name) {
- Name leftName = (Name) leftSide;
- leftDeclaration = leftName.lookupVariable(leftName.getIdentifier());
- leftVar = new Variable(leftDeclaration.getName(),
- CppType.fromName(leftDeclaration.getType()), false, false);
- }
- if (rightSide instanceof Name) {
- Name rightName = (Name) rightSide;
- VariableDeclaration declaration = rightName.lookupVariable(
- rightName.getIdentifier());
- rightVar = new Variable(declaration.getName(),
- CppType.fromName(declaration.getType()), false, false);
- }
- if (leftVar != null && rightVar != null) {
- Node leftParent = leftDeclaration.getParent();
- if (leftParent instanceof ClassDeclaration) {
- ClassInfo classInfo = repository.getClass(leftDeclaration.getName());
- Type fieldType = CppType.fromName(leftDeclaration.getType());
- FieldInfo fieldInfo = new FieldInfo(classInfo, leftDeclaration
- .getName(), fieldType, false, false, false);
- operations.add(new FieldAssignment(assignmentExpression
- .getLineNumber(), leftVar, fieldInfo, rightVar));
- } else {
- operations.add(new LocalAssignment(assignmentExpression
- .getLineNumber(), leftVar, rightVar));
- }
- }
- }
- @Override
- public void beginVisit(ReturnStatement returnStatement) {
- operations.add(new ReturnOperation(returnStatement.getLineNumber(), null));
- }
- }
- private class ClassInfoBuilder extends Visitor {
- private final Stack<ClassInfo> stack = new Stack<ClassInfo>();
- private final CppClassRepository repository;
- public ClassInfoBuilder(CppClassRepository repository) {
- this.repository = repository;
- }
- @Override
- public void beginVisit(ClassDeclaration classDeclaration) {
- //TODO: when the class repository is actually wired, the name of the source file should
- // be provided in the constructor
- ClassInfo classInfo = new ClassInfo(classDeclaration.getName(), false,
- null, new ArrayList<ClassInfo>(), "[unknown source]");
- classes.put(classDeclaration.getName(), classInfo);
- stack.push(classInfo);
- }
- @Override
- public void endVisit(ClassDeclaration classDeclaration) {
- stack.pop();
- }
- @Override
- public void beginVisit(FunctionDefinition functionDefinition) {
- LocalVariableExtractor localVariablesExtractor = new LocalVariableExtractor();
- functionDefinition.accept(localVariablesExtractor);
- OperationBuilder operationBuilder = new OperationBuilder(repository);
- functionDefinition.accept(operationBuilder);
- ClassInfo classInfo = stack.peek();
- classInfo.addMethod(new MethodInfo(
- classInfo,
- functionDefinition.getName(),
- functionDefinition.getLine(),
- null,
- functionDefinition.getParameters(),
- localVariablesExtractor.getResult(),
- functionDefinition.getVisibility(),
- operationBuilder.getResult(),
- false,
- false, new ArrayList<Integer>()));
- }
- }
- public ClassInfo getClass(String clazzName) {
- return classes.get(clazzName);
- }
- public void addClass(ClassInfo classInfo) {
- classes.put(classInfo.getName(), classInfo);
- }
- void parse(InputStream in) throws Exception {
- TranslationUnit unit = new Parser().parse(in);
- ClassInfoBuilder builder = new ClassInfoBuilder(this);
- unit.accept(builder);
- }
- public void parse(String in) throws Exception {
- TranslationUnit unit = new Parser().parse(in);
- ClassInfoBuilder builder = new ClassInfoBuilder(this);
- unit.accept(builder);
- }
- }