Package com.google.gwt.dev.jjs

Source Code of com.google.gwt.dev.jjs.ArtificialRescueRecorder

/*
* Copyright 2010 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.gwt.dev.jjs;

import com.google.gwt.core.client.impl.ArtificialRescue;
import com.google.gwt.core.client.impl.ArtificialRescue.Rescue;
import com.google.gwt.dev.jjs.ast.Context;
import com.google.gwt.dev.jjs.ast.JAnnotation;
import com.google.gwt.dev.jjs.ast.JDeclaredType;
import com.google.gwt.dev.jjs.ast.JField;
import com.google.gwt.dev.jjs.ast.JInterfaceType;
import com.google.gwt.dev.jjs.ast.JNode;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.ast.JReferenceType;
import com.google.gwt.dev.jjs.ast.JType;
import com.google.gwt.dev.jjs.ast.JVisitor;
import com.google.gwt.dev.jjs.impl.JsniRefLookup;
import com.google.gwt.dev.util.JsniRef;
import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
* Process ArtificialRescue annotations.
*/
public class ArtificialRescueRecorder {
  private class Recorder extends JVisitor {
    private JDeclaredType currentClass;

    @Override
    public void endVisit(JAnnotation x, Context ctx) {
      if (x.getType() == artificialRescueType) {
        ArtificialRescue annotation = JAnnotation.createAnnotation(
            ArtificialRescue.class, x);
        for (Rescue rescue : annotation.value()) {
          process(rescue);
        }
      }
    }

    @Override
    public void endVisit(JDeclaredType x, Context ctx) {
      assert currentClass == x;
    }

    @Override
    public boolean visit(JDeclaredType x, Context ctx) {
      currentClass = x;

      /*
       * We only care about annotations declared on the type itself, so we can
       * skip the traversal of fields and methods.
       */
      accept(x.getAnnotations());
      return false;
    }

    private void process(Rescue rescue) {
      assert rescue != null : "rescue";

      String typeName = rescue.className();
      JReferenceType classType = (JReferenceType) program.getTypeFromJsniRef(typeName);
      String[] fields = rescue.fields();
      boolean instantiable = rescue.instantiable();
      String[] methods = rescue.methods();

      assert classType != null : "classType " + typeName;
      assert fields != null : "fields";
      assert methods != null : "methods";

      if (instantiable) {
        currentClass.addArtificialRescue(classType);
      }

      if (classType instanceof JDeclaredType) {
        List<String> toRescue = new ArrayList<String>();
        Collections.addAll(toRescue, fields);
        Collections.addAll(toRescue, methods);

        for (String name : toRescue) {
          JsniRef ref = JsniRef.parse("@" + classType.getName() + "::" + name);
          final String[] errors = {null};
          JNode node = JsniRefLookup.findJsniRefTarget(ref, program,
              new JsniRefLookup.ErrorReporter() {
                public void reportError(String error) {
                  errors[0] = error;
                }
              });
          if (errors[0] != null) {
            // Should have been caught by ArtificialRescueChecker
            throw new InternalCompilerException(
                "Unable to artificially rescue " + name + ": " + errors[0]);
          }

          if (node instanceof JType) {
            // Already added the type above.
          } else {
            currentClass.addArtificialRescue(node);
          }
          if (node instanceof JField) {
            JField field = (JField) node;
            if (!field.isFinal()) {
              field.setVolatile();
            }
          }
        }
      }
    }
  }

  public static void exec(JProgram program) {
    Event artificialRescueReorderEvent =
        SpeedTracerLogger.start(CompilerEventType.ARTIFICIAL_RESCUE_REORDER);
    new ArtificialRescueRecorder(program).execImpl();
    artificialRescueReorderEvent.end();
  }

  private final JInterfaceType artificialRescueType;
  private final JProgram program;

  private ArtificialRescueRecorder(JProgram program) {
    this.program = program;
    artificialRescueType = (JInterfaceType) program.getFromTypeMap(ArtificialRescue.class.getName());
  }

  private void execImpl() {
    new Recorder().accept(program);
  }
}
TOP

Related Classes of com.google.gwt.dev.jjs.ArtificialRescueRecorder

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.