Package com.google.test.metric.cpp

Source Code of com.google.test.metric.cpp.CppClassRepository$ClassInfoBuilder

/*
* 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);
  }
}
TOP

Related Classes of com.google.test.metric.cpp.CppClassRepository$ClassInfoBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.