com.google.dart.java2dart.engine.EngineAnnotationProcessor.java Source code

Java tutorial

Introduction

Here is the source code for com.google.dart.java2dart.engine.EngineAnnotationProcessor.java

Source

/*
 * Copyright (c) 2014, the Dart project authors.
 * 
 * Licensed under the Eclipse Public License v1.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.eclipse.org/legal/epl-v10.html
 * 
 * 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.dart.java2dart.engine;

import com.google.common.collect.Lists;
import com.google.dart.engine.ast.AstNode;
import com.google.dart.engine.ast.ClassDeclaration;
import com.google.dart.engine.ast.CompilationUnit;
import com.google.dart.engine.ast.ConstructorDeclaration;
import com.google.dart.engine.ast.DefaultFormalParameter;
import com.google.dart.engine.ast.Expression;
import com.google.dart.engine.ast.FieldDeclaration;
import com.google.dart.engine.ast.FormalParameterList;
import com.google.dart.engine.ast.MethodDeclaration;
import com.google.dart.engine.ast.MethodInvocation;
import com.google.dart.engine.ast.SimpleFormalParameter;
import com.google.dart.engine.ast.SimpleIdentifier;
import com.google.dart.engine.ast.VariableDeclaration;
import com.google.dart.engine.utilities.translation.DartBlockBody;
import com.google.dart.java2dart.Context;
import com.google.dart.java2dart.ParsedAnnotation;
import com.google.dart.java2dart.processor.SemanticProcessor;
import com.google.dart.java2dart.util.ToFormattedSourceVisitor;

import static com.google.dart.java2dart.util.AstFactory.annotation;
import static com.google.dart.java2dart.util.AstFactory.identifier;
import static com.google.dart.java2dart.util.AstFactory.namedExpression;
import static com.google.dart.java2dart.util.AstFactory.namedFormalParameter;
import static com.google.dart.java2dart.util.AstFactory.positionalFormalParameter;

import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
 * Applies {@link DartBlockBody} and other annotations.
 */
public class EngineAnnotationProcessor extends SemanticProcessor {
    public EngineAnnotationProcessor(Context context) {
        super(context);
    }

    @Override
    @SuppressWarnings("unchecked")
    public void process(CompilationUnit unit) {
        Map<AstNode, List<ParsedAnnotation>> nodeAnnotations = context.getNodeAnnotations();
        for (Entry<AstNode, List<ParsedAnnotation>> entry : nodeAnnotations.entrySet()) {
            AstNode node = entry.getKey();
            for (ParsedAnnotation annotation : entry.getValue()) {
                String annotationName = annotation.getName();
                if (annotationName.equals("DartBlockBody")) {
                    List<String> bodyLines = (List<String>) annotation.get("value");
                    String bodySource = "";
                    if (!bodyLines.isEmpty()) {
                        bodySource = StringUtils.join(bodyLines, "\n    ");
                        bodySource = "    " + bodySource.trim();
                    }
                    node.setProperty(ToFormattedSourceVisitor.BLOCK_BODY_KEY, bodySource);
                } else if (annotationName.equals("DartExpressionBody")) {
                    String bodySource = (String) annotation.get("value");
                    node.setProperty(ToFormattedSourceVisitor.EXPRESSION_BODY_KEY, bodySource);
                } else if (annotationName.equals("DartName")) {
                    String newName = (String) annotation.get("value");
                    if (node instanceof ClassDeclaration) {
                        ClassDeclaration classDeclaration = (ClassDeclaration) node;
                        SimpleIdentifier nameNode = classDeclaration.getName();
                        context.renameIdentifier(nameNode, newName);
                    } else if (node instanceof ConstructorDeclaration) {
                        ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration) node;
                        context.renameConstructor(constructorDeclaration, newName);
                    } else if (node instanceof FieldDeclaration) {
                        FieldDeclaration fieldDeclaration = (FieldDeclaration) node;
                        List<VariableDeclaration> fields = fieldDeclaration.getFields().getVariables();
                        if (fields.size() != 1) {
                            throw new IllegalArgumentException(
                                    "@DartName is supported only field declarations with a single field.");
                        }
                        SimpleIdentifier nameNode = fields.get(0).getName();
                        context.renameIdentifier(nameNode, newName);
                    } else if (node instanceof MethodDeclaration) {
                        MethodDeclaration methodDeclaration = (MethodDeclaration) node;
                        SimpleIdentifier nameNode = methodDeclaration.getName();
                        context.renameIdentifier(nameNode, newName);
                    } else {
                        throw new IllegalArgumentException("@DartName is not supported for: " + node.getClass());
                    }
                } else if (annotationName.equals("DartOmit")) {
                    AstNode parent = node.getParent();
                    if (parent instanceof CompilationUnit) {
                        unit.getDeclarations().remove(node);
                    } else if (parent instanceof ClassDeclaration) {
                        ((ClassDeclaration) parent).getMembers().remove(node);
                    }
                } else if (annotationName.equals("DartOptional")) {
                    SimpleFormalParameter parameter = (SimpleFormalParameter) node;
                    AstNode parameterList = parameter.getParent();
                    // prepare annotation arguments
                    String kindName = (String) annotation.get("kind");
                    String defaultValueSource = (String) annotation.get("defaultValue");
                    // replace normal parameter with default
                    DefaultFormalParameter defaultParameter;
                    if (kindName == null || kindName.endsWith(".POSITIONAL")) {
                        defaultParameter = positionalFormalParameter(parameter, null);
                    } else {
                        replaceInvocationArgumentWithNamed(parameter);
                        defaultParameter = namedFormalParameter(parameter, null);
                    }
                    replaceNode(parameterList, parameter, defaultParameter);
                    // set default value
                    defaultParameter.setProperty(ToFormattedSourceVisitor.DEFAULT_VALUE_KEY, defaultValueSource);
                } else if (annotationName.equals("Override")) {
                    if (node instanceof MethodDeclaration) {
                        MethodDeclaration method = (MethodDeclaration) node;
                        method.setMetadata(Lists.newArrayList(annotation(identifier("override"))));
                    }
                } else {
                    //          throw new IllegalArgumentException("Unknown annotation: " + annotationName);
                }
            }
        }
    }

    private void replaceInvocationArgumentWithNamed(SimpleFormalParameter parameter) {
        String parameterName = parameter.getIdentifier().getName();
        FormalParameterList parameterList = (FormalParameterList) parameter.getParent();
        AstNode member = parameterList.getParent();
        int index = parameterList.getParameters().indexOf(parameter);
        if (member instanceof MethodDeclaration) {
            MethodDeclaration method = (MethodDeclaration) member;
            List<MethodInvocation> invocations = context.getInvocations(method);
            for (MethodInvocation invocation : invocations) {
                List<Expression> arguments = invocation.getArgumentList().getArguments();
                Expression argument = arguments.get(index);
                arguments.set(index, namedExpression(parameterName, argument));
            }
        }
    }
}