public static OptimizerStats exec(JProgram program, OptimizerContext optimizerCtx) {
   Event optimizeEvent = SpeedTracerLogger.start(CompilerEventType.OPTIMIZE, "optimizer", NAME);
   OptimizerStats stats = new SameParameterValueOptimizer(program).execImpl(program, optimizerCtx);
   optimizerCtx.incOptimizationStep();
   optimizeEvent.end("didChange", "" + stats.didChange());
   return stats;
 }
  @Override
  protected boolean doSlowStartup() {
    tempWorkDir = options.getWorkDir() == null;
    if (tempWorkDir) {
      try {
        options.setWorkDir(Utility.makeTemporaryDirectory(null, "gwtc"));
      } catch (IOException e) {
        System.err.println("Unable to create hosted mode work directory");
        e.printStackTrace();
        return false;
      }
    }

    TreeLogger branch = getTopLogger().branch(TreeLogger.TRACE, "Linking modules");
    Event slowStartupEvent = SpeedTracerLogger.start(DevModeEventType.SLOW_STARTUP);
    try {
      for (ModuleDef module : startupModules.values()) {
        TreeLogger loadLogger =
            branch.branch(
                TreeLogger.DEBUG,
                "Bootstrap link for command-line module '" + module.getCanonicalName() + "'");
        link(loadLogger, module);
      }
    } catch (UnableToCompleteException e) {
      // Already logged.
      return false;
    } finally {
      slowStartupEvent.end();
    }
    return true;
  }
Beispiel #3
0
 public static OptimizerStats exec(
     JProgram program, boolean noSpecialTypes, OptimizerContext optimizerCtx) {
   Event optimizeEvent = SpeedTracerLogger.start(CompilerEventType.OPTIMIZE, "optimizer", NAME);
   OptimizerStats stats = new Pruner(program, noSpecialTypes).execImpl(optimizerCtx);
   optimizeEvent.end("didChange", "" + stats.didChange());
   return stats;
 }
Beispiel #4
0
 public int getNodeCount() {
   Event countEvent = SpeedTracerLogger.start(CompilerEventType.OPTIMIZE, "phase", "countNodes");
   TreeStatistics treeStats = new TreeStatistics();
   treeStats.accept(this);
   int numNodes = treeStats.getNodeCount();
   countEvent.end();
   return numNodes;
 }
 /**
  * Compiles generated source files (unless cached) and adds them to the CompilationState. If the
  * compiler aborts, logs an error and throws UnableToCompleteException.
  */
 public Collection<CompilationUnit> addGeneratedTypes(
     TreeLogger logger, Collection<GeneratedUnit> generatedUnits)
     throws UnableToCompleteException {
   Event event = SpeedTracerLogger.start(DevModeEventType.CSB_ADD_GENERATED_TYPES);
   try {
     return doBuildGeneratedTypes(logger, compilerContext, generatedUnits, this);
   } finally {
     event.end();
   }
 }
 @Override
 protected void optimizeJava() {
   Event draftOptimizeEvent = SpeedTracerLogger.start(CompilerEventType.DRAFT_OPTIMIZE);
   Finalizer.exec(jprogram);
   jprogram.typeOracle.recomputeAfterOptimizations();
   // Certain libraries depend on dead stripping.
   DeadCodeElimination.exec(jprogram);
   jprogram.typeOracle.recomputeAfterOptimizations();
   draftOptimizeEvent.end();
 }
  /**
   * Compiles the given set of units. The units will be internally modified to reflect the results
   * of compilation.
   */
  public static List<CompilationUnit> compile(Collection<CompilationUnitBuilder> builders) {
    Event jdtCompilerEvent = SpeedTracerLogger.start(CompilerEventType.JDT_COMPILER);

    try {
      DefaultUnitProcessor processor = new DefaultUnitProcessor();
      JdtCompiler compiler = new JdtCompiler(processor);
      compiler.doCompile(builders);
      return processor.getResults();
    } finally {
      jdtCompilerEvent.end();
    }
  }
 /**
  * Compiles the given source files and adds them to the CompilationState. See {@link
  * CompileMoreLater#compile} for details.
  *
  * @throws UnableToCompleteException if the compiler aborts (not a normal compile error).
  */
 public static CompilationState buildFrom(
     TreeLogger logger,
     CompilerContext compilerContext,
     Set<Resource> resources,
     AdditionalTypeProviderDelegate delegate)
     throws UnableToCompleteException {
   Event event = SpeedTracerLogger.start(DevModeEventType.CSB_BUILD_FROM_ORACLE);
   try {
     return instance.doBuildFrom(logger, compilerContext, resources, delegate);
   } finally {
     event.end();
   }
 }
  /*
   * Create a field serializer for a type if it does not have a custom
   * serializer.
   */
  private void createFieldSerializer(TreeLogger logger, GeneratorContextExt ctx, JType type) {
    Event event = SpeedTracerLogger.start(CompilerEventType.GENERATOR_RPC_FIELD_SERIALIZER);
    try {
      assert (type != null);
      assert (serializationOracle.isSerializable(type)
          || deserializationOracle.isSerializable(type));

      JParameterizedType parameterizedType = type.isParameterized();
      if (parameterizedType != null) {
        createFieldSerializer(logger, ctx, parameterizedType.getRawType());
        return;
      }

      /*
       * Only a JClassType can reach this point in the code. JPrimitives have been
       * removed because their serialization is built in, interfaces have been
       * removed because they are not an instantiable type and parameterized types
       * have been broken down into their raw types.
       */
      assert (type.isClass() != null || type.isArray() != null);

      if (findCacheableFieldSerializerAndMarkForReuseIfAvailable(ctx, type)) {
        // skip generation of field serializer
        return;
      }

      JClassType customFieldSerializer =
          SerializableTypeOracleBuilder.findCustomFieldSerializer(typeOracle, type);
      FieldSerializerCreator creator =
          new FieldSerializerCreator(
              context,
              serializationOracle,
              deserializationOracle,
              (JClassType) type,
              customFieldSerializer);
      creator.realize(logger, ctx);
    } finally {
      event.end();
    }
  }
Beispiel #10
0
  protected void generateTypeHandlers(
      TreeLogger logger,
      GeneratorContextExt context,
      SerializableTypeOracle typesSentFromBrowser,
      SerializableTypeOracle typesSentToBrowser)
      throws UnableToCompleteException {
    Event event = SpeedTracerLogger.start(CompilerEventType.GENERATOR_RPC_TYPE_SERIALIZER);
    TypeSerializerCreator tsc =
        new TypeSerializerCreator(
            logger,
            typesSentFromBrowser,
            typesSentToBrowser,
            context,
            SerializationUtils.getTypeSerializerQualifiedName(serviceIntf),
            SerializationUtils.getTypeSerializerSimpleName(serviceIntf));
    tsc.realize(logger);
    event.end();

    typeStrings = new HashMap<JType, String>(tsc.getTypeStrings());
    typeStrings.put(serviceIntf, TypeNameObfuscator.SERVICE_INTERFACE_ID);

    cachedTypeLastModifiedTimes = tsc.getTypeLastModifiedTimeMap();
  }
Beispiel #11
0
  public boolean run(TreeLogger logger, ModuleDef... modules) throws UnableToCompleteException {
    boolean tempWorkDir = false;
    try {
      if (options.getWorkDir() == null) {
        options.setWorkDir(Utility.makeTemporaryDirectory(null, "gwtc"));
        tempWorkDir = true;
      }
      if (options.isSoycEnabled() && options.getExtraDir() == null) {
        options.setExtraDir(new File("extras"));
      }

      File persistentUnitCacheDir = null;
      if (options.getWarDir() != null && !options.getWarDir().getName().endsWith(".jar")) {
        persistentUnitCacheDir = new File(options.getWarDir(), "../");
      }
      CompilationStateBuilder.init(logger, persistentUnitCacheDir);

      for (ModuleDef module : modules) {
        String moduleName = module.getCanonicalName();
        if (options.isValidateOnly()) {
          if (!Precompile.validate(logger, options, module, options.getGenDir())) {
            return false;
          }
        } else {
          long compileStart = System.currentTimeMillis();
          TreeLogger branch = logger.branch(TreeLogger.INFO, "Compiling module " + moduleName);

          // Optimize early since permutation compiles will run in process.
          options.setOptimizePrecompile(true);
          Precompilation precompilation =
              Precompile.precompile(branch, options, module, options.getGenDir());
          if (precompilation == null) {
            return false;
          }

          Event compilePermutationsEvent =
              SpeedTracerLogger.start(CompilerEventType.COMPILE_PERMUTATIONS);
          Permutation[] allPerms = precompilation.getPermutations();
          List<FileBackedObject<PermutationResult>> resultFiles =
              CompilePerms.makeResultFiles(options.getCompilerWorkDir(moduleName), allPerms);
          CompilePerms.compile(
              branch, precompilation, allPerms, options.getLocalWorkers(), resultFiles);
          compilePermutationsEvent.end();

          ArtifactSet generatedArtifacts = precompilation.getGeneratedArtifacts();
          JJSOptions precompileOptions = precompilation.getUnifiedAst().getOptions();

          precompilation = null; // No longer needed, so save the memory

          Event linkEvent = SpeedTracerLogger.start(CompilerEventType.LINK);
          File absPath = new File(options.getWarDir(), module.getName());
          absPath = absPath.getAbsoluteFile();

          String logMessage = "Linking into " + absPath;
          if (options.getExtraDir() != null) {
            File absExtrasPath = new File(options.getExtraDir(), module.getName());
            absExtrasPath = absExtrasPath.getAbsoluteFile();
            logMessage += "; Writing extras to " + absExtrasPath;
          }
          Link.link(
              logger.branch(TreeLogger.TRACE, logMessage),
              module,
              generatedArtifacts,
              allPerms,
              resultFiles,
              options.getWarDir(),
              options.getDeployDir(),
              options.getExtraDir(),
              precompileOptions);

          linkEvent.end();
          long compileDone = System.currentTimeMillis();
          long delta = compileDone - compileStart;
          if (branch.isLoggable(TreeLogger.INFO)) {
            branch.log(
                TreeLogger.INFO,
                "Compilation succeeded -- " + String.format("%.3f", delta / 1000d) + "s");
          }
        }
      }

    } catch (IOException e) {
      logger.log(TreeLogger.ERROR, "Unable to create compiler work directory", e);
      return false;
    } finally {
      if (tempWorkDir) {
        Util.recursiveDelete(options.getWorkDir(), false);
      }
    }
    return true;
  }
Beispiel #12
0
  /**
   * Creates the client-side proxy class.
   *
   * @throws UnableToCompleteException
   */
  public String create(TreeLogger logger, GeneratorContextExt context)
      throws UnableToCompleteException {
    TypeOracle typeOracle = context.getTypeOracle();

    JClassType serviceAsync = typeOracle.findType(serviceIntf.getQualifiedSourceName() + "Async");
    if (serviceAsync == null) {
      logger.branch(
          TreeLogger.ERROR,
          "Could not find an asynchronous version for the service interface "
              + serviceIntf.getQualifiedSourceName(),
          null);
      RemoteServiceAsyncValidator.logValidAsyncInterfaceDeclaration(logger, serviceIntf);
      throw new UnableToCompleteException();
    }

    SourceWriter srcWriter = getSourceWriter(logger, context, serviceAsync);
    if (srcWriter == null) {
      return getProxyQualifiedName();
    }

    // Make sure that the async and synchronous versions of the RemoteService
    // agree with one another
    //
    RemoteServiceAsyncValidator rsav = new RemoteServiceAsyncValidator(logger, typeOracle);
    Map<JMethod, JMethod> syncMethToAsyncMethMap = rsav.validate(logger, serviceIntf, serviceAsync);

    final PropertyOracle propertyOracle = context.getPropertyOracle();

    // Load the blacklist/whitelist
    TypeFilter blacklistTypeFilter = new BlacklistTypeFilter(logger, propertyOracle);

    // Determine the set of serializable types
    Event event = SpeedTracerLogger.start(CompilerEventType.GENERATOR_RPC_STOB);

    SerializableTypeOracleBuilder typesSentFromBrowserBuilder =
        new SerializableTypeOracleBuilder(logger, propertyOracle, context);
    typesSentFromBrowserBuilder.setTypeFilter(blacklistTypeFilter);
    SerializableTypeOracleBuilder typesSentToBrowserBuilder =
        new SerializableTypeOracleBuilder(logger, propertyOracle, context);
    typesSentToBrowserBuilder.setTypeFilter(blacklistTypeFilter);

    addRoots(logger, typeOracle, typesSentFromBrowserBuilder, typesSentToBrowserBuilder);

    try {
      ConfigurationProperty prop =
          context
              .getPropertyOracle()
              .getConfigurationProperty(TypeSerializerCreator.GWT_ELIDE_TYPE_NAMES_FROM_RPC);
      elideTypeNames = Boolean.parseBoolean(prop.getValues().get(0));
    } catch (BadPropertyValueException e) {
      logger.log(
          TreeLogger.ERROR,
          "Configuration property "
              + TypeSerializerCreator.GWT_ELIDE_TYPE_NAMES_FROM_RPC
              + " is not defined. Is RemoteService.gwt.xml inherited?");
      throw new UnableToCompleteException();
    }

    // Decide what types to send in each direction.
    // Log the decisions to a string that will be written later in this method
    SerializableTypeOracle typesSentFromBrowser;
    SerializableTypeOracle typesSentToBrowser;
    String rpcLog;
    {
      StringWriter stringWriter = new StringWriter();
      PrintWriter writer = new PrintWriter(stringWriter);

      typesSentFromBrowserBuilder.setLogOutputWriter(writer);
      typesSentToBrowserBuilder.setLogOutputWriter(writer);

      writer.write("====================================\n");
      writer.write("Types potentially sent from browser:\n");
      writer.write("====================================\n\n");
      writer.flush();
      typesSentFromBrowser = typesSentFromBrowserBuilder.build(logger);

      writer.write("===================================\n");
      writer.write("Types potentially sent from server:\n");
      writer.write("===================================\n\n");
      writer.flush();
      typesSentToBrowser = typesSentToBrowserBuilder.build(logger);

      writer.close();
      rpcLog = stringWriter.toString();
    }
    event.end();

    generateTypeHandlers(logger, context, typesSentFromBrowser, typesSentToBrowser);

    String serializationPolicyStrongName =
        writeSerializationPolicyFile(logger, context, typesSentFromBrowser, typesSentToBrowser);

    String remoteServiceInterfaceName =
        elideTypeNames
            ? TypeNameObfuscator.SERVICE_INTERFACE_ID
            : SerializationUtils.getRpcTypeName(serviceIntf);
    generateProxyFields(
        srcWriter, typesSentFromBrowser, serializationPolicyStrongName, remoteServiceInterfaceName);

    generateProxyContructor(srcWriter);

    generateProxyMethods(srcWriter, typesSentFromBrowser, typeOracle, syncMethToAsyncMethMap);

    generateStreamWriterOverride(srcWriter);

    generateCheckRpcTokenTypeOverride(srcWriter, typeOracle, typesSentFromBrowser);

    srcWriter.commit(logger);

    if (context.isProdMode() || logger.isLoggable(TreeLogger.DEBUG)) {
      // Create an artifact explaining STOB's decisions. It will be emitted by
      // RpcLogLinker
      context.commitArtifact(
          logger,
          new RpcLogArtifact(
              serviceIntf.getQualifiedSourceName(), serializationPolicyStrongName, rpcLog));
    }

    return getProxyQualifiedName();
  }
      /**
       * A callback after the JDT compiler has compiled a .java file and created a matching
       * CompilationUnitDeclaration. We take this opportunity to create a matching CompilationUnit.
       */
      @Override
      public void process(
          CompilationUnitBuilder builder,
          CompilationUnitDeclaration cud,
          List<CompiledClass> compiledClasses) {
        Event event = SpeedTracerLogger.start(DevModeEventType.CSB_PROCESS);
        try {
          Map<MethodDeclaration, JsniMethod> jsniMethods =
              JsniCollector.collectJsniMethods(
                  cud,
                  builder.getSourceMapPath(),
                  builder.getSource(),
                  JsRootScope.INSTANCE,
                  DummyCorrelationFactory.INSTANCE);

          JSORestrictionsChecker.check(jsoState, cud);

          // JSNI check + collect dependencies.
          final Set<String> jsniDeps = new HashSet<String>();
          Map<String, Binding> jsniRefs = new HashMap<String, Binding>();
          JsniChecker.check(
              cud,
              jsoState,
              jsniMethods,
              jsniRefs,
              new JsniChecker.TypeResolver() {
                @Override
                public ReferenceBinding resolveType(String sourceOrBinaryName) {
                  ReferenceBinding resolveType = compiler.resolveType(sourceOrBinaryName);
                  if (resolveType != null) {
                    jsniDeps.add(String.valueOf(resolveType.qualifiedSourceName()));
                  }
                  return resolveType;
                }
              });

          Map<TypeDeclaration, Binding[]> artificialRescues =
              new HashMap<TypeDeclaration, Binding[]>();
          ArtificialRescueChecker.check(cud, builder.isGenerated(), artificialRescues);
          if (compilerContext.shouldCompileMonolithic()) {
            // GWT drives JDT in a way that allows missing references in the source to be resolved
            // to precompiled bytecode on disk (see INameEnvironment). This is done so that
            // annotations can be supplied in bytecode form only. But since no AST is available for
            // these types it creates the danger that some functional class (not just an annotation)
            // gets filled in but is missing AST. This would cause later compiler stages to fail.
            //
            // Library compilation needs to ignore this check since it is expected behavior for the
            // source being compiled in a library to make references to other types which are only
            // available as bytecode coming out of dependency libraries.
            //
            // But if the referenced bytecode did not come from a dependency library but instead was
            // free floating in the classpath, then there is no guarrantee that AST for it was ever
            // seen and translated to JS anywhere in the dependency tree. This would be a mistake.
            //
            // TODO(stalcup): add a more specific check for library compiles such that binary types
            // can be referenced but only if they are an Annotation or if the binary type comes from
            // a dependency library.
            BinaryTypeReferenceRestrictionsChecker.check(cud);
          }

          MethodArgNamesLookup methodArgs =
              MethodParamCollector.collect(cud, builder.getSourceMapPath());

          Interner<String> interner = StringInterner.get();
          String packageName = interner.intern(Shared.getPackageName(builder.getTypeName()));
          List<String> unresolvedQualified = new ArrayList<String>();
          List<String> unresolvedSimple = new ArrayList<String>();
          for (char[] simpleRef : cud.compilationResult().simpleNameReferences) {
            unresolvedSimple.add(interner.intern(String.valueOf(simpleRef)));
          }
          for (char[][] qualifiedRef : cud.compilationResult().qualifiedReferences) {
            unresolvedQualified.add(interner.intern(CharOperation.toString(qualifiedRef)));
          }
          for (String jsniDep : jsniDeps) {
            unresolvedQualified.add(interner.intern(jsniDep));
          }
          ArrayList<String> apiRefs = compiler.collectApiRefs(cud);
          for (int i = 0; i < apiRefs.size(); ++i) {
            apiRefs.set(i, interner.intern(apiRefs.get(i)));
          }
          Dependencies dependencies =
              new Dependencies(packageName, unresolvedQualified, unresolvedSimple, apiRefs);

          List<JDeclaredType> types = Collections.emptyList();
          if (!cud.compilationResult().hasErrors()) {
            // Make a GWT AST.
            types =
                astBuilder.process(
                    cud, builder.getSourceMapPath(), artificialRescues, jsniMethods, jsniRefs);
          }

          for (CompiledClass cc : compiledClasses) {
            allValidClasses.put(cc.getSourceName(), cc);
          }

          builder
              .setClasses(compiledClasses)
              .setTypes(types)
              .setDependencies(dependencies)
              .setJsniMethods(jsniMethods.values())
              .setMethodArgs(methodArgs)
              .setProblems(cud.compilationResult().getProblems());
          buildQueue.add(builder);
        } finally {
          event.end();
        }
      }
    /**
     * Compiles the source code in each supplied CompilationUnitBuilder into a CompilationUnit and
     * reports errors.
     *
     * <p>A compilation unit is considered invalid if any of its dependencies (recursively) isn't
     * being compiled and isn't in allValidClasses, or if it has a signature that doesn't match a
     * dependency. Valid compilation units will be added to cachedUnits and the unit cache, and
     * their types will be added to allValidClasses. Invalid compilation units will be removed.
     *
     * <p>I/O: serializes the AST of each Java type to DiskCache. (This happens even if the
     * compilation unit is later dropped.) If we're using the persistent unit cache, each valid unit
     * will also be serialized to the gwt-unitcache file. (As a result, each AST will be copied
     * there from the DiskCache.) A new persistent unit cache file will be created each time
     * compile() is called (if there's at least one valid unit) and the entire cache will be
     * rewritten to disk every {@link PersistentUnitCache#CACHE_FILE_THRESHOLD} files.
     *
     * <p>This function won't report errors in invalid source files unless suppressErrors is false.
     * Instead, a summary giving the number of invalid files will be logged.
     *
     * <p>If the JDT compiler aborts, logs an error and throws UnableToCompleteException. (This
     * doesn't happen for normal compile errors.)
     */
    Collection<CompilationUnit> compile(
        TreeLogger logger,
        CompilerContext compilerContext,
        Collection<CompilationUnitBuilder> builders,
        Map<CompilationUnitBuilder, CompilationUnit> cachedUnits,
        EventType eventType)
        throws UnableToCompleteException {
      UnitCache unitCache = compilerContext.getUnitCache();
      // Initialize the set of valid classes to the initially cached units.
      for (CompilationUnit unit : cachedUnits.values()) {
        for (CompiledClass cc : unit.getCompiledClasses()) {
          // Map by source name.
          String sourceName = cc.getSourceName();
          allValidClasses.put(sourceName, cc);
        }
      }

      ArrayList<CompilationUnit> resultUnits = new ArrayList<CompilationUnit>();
      do {
        final TreeLogger branch = logger.branch(TreeLogger.TRACE, "Compiling...");
        // Compile anything that needs to be compiled.
        buildQueue = new LinkedBlockingQueue<CompilationUnitBuilder>();
        final ArrayList<CompilationUnit> newlyBuiltUnits = new ArrayList<CompilationUnit>();
        final CompilationUnitBuilder sentinel = CompilationUnitBuilder.create((GeneratedUnit) null);
        final Throwable[] workerException = new Throwable[1];
        final ProgressLogger progressLogger =
            new ProgressLogger(branch, TreeLogger.TRACE, builders.size(), 10);
        Thread buildThread =
            new Thread() {
              @Override
              public void run() {
                int processedCompilationUnitBuilders = 0;
                try {
                  do {
                    CompilationUnitBuilder builder = buildQueue.take();
                    if (!progressLogger.isTimerStarted()) {
                      // Set start time here, after first job has arrived, since it can take a
                      // little
                      // while for the first job to arrive, and this helps with the accuracy of the
                      // estimated times.
                      progressLogger.startTimer();
                    }
                    if (builder == sentinel) {
                      return;
                    }
                    // Expensive, must serialize GWT AST types to bytes.
                    CompilationUnit unit = builder.build();
                    newlyBuiltUnits.add(unit);

                    processedCompilationUnitBuilders++;
                    progressLogger.updateProgress(processedCompilationUnitBuilders);
                  } while (true);
                } catch (Throwable e) {
                  workerException[0] = e;
                }
              }
            };
        buildThread.setName("CompilationUnitBuilder");
        buildThread.start();
        Event jdtCompilerEvent = SpeedTracerLogger.start(eventType);
        long compilationStartNanos = System.nanoTime();
        try {
          compiler.doCompile(branch, builders);
        } finally {
          jdtCompilerEvent.end();
        }
        buildQueue.add(sentinel);
        try {
          buildThread.join();
          long compilationNanos = System.nanoTime() - compilationStartNanos;
          // Convert nanos to seconds.
          double compilationSeconds = compilationNanos / (double) TimeUnit.SECONDS.toNanos(1);
          branch.log(
              TreeLogger.TRACE,
              String.format("Compilation completed in %.02f seconds", compilationSeconds));
          if (workerException[0] != null) {
            throw workerException[0];
          }
        } catch (RuntimeException e) {
          throw e;
        } catch (Throwable e) {
          throw new RuntimeException("Exception processing units", e);
        } finally {
          buildQueue = null;
        }
        resultUnits.addAll(newlyBuiltUnits);
        builders.clear();

        // Resolve all newly built unit deps against the global classes.
        for (CompilationUnit unit : newlyBuiltUnits) {
          unit.getDependencies().resolve(allValidClasses);
        }

        /*
         * Invalidate any cached units with invalid refs.
         */
        Collection<CompilationUnit> invalidatedUnits = new ArrayList<CompilationUnit>();
        for (Iterator<Entry<CompilationUnitBuilder, CompilationUnit>> it =
                cachedUnits.entrySet().iterator();
            it.hasNext(); ) {
          Entry<CompilationUnitBuilder, CompilationUnit> entry = it.next();
          CompilationUnit unit = entry.getValue();
          boolean isValid = unit.getDependencies().validate(logger, allValidClasses);
          if (isValid && unit.isError()) {
            // See if the unit has classes that can't provide a
            // NameEnvironmentAnswer
            for (CompiledClass cc : unit.getCompiledClasses()) {
              try {
                cc.getNameEnvironmentAnswer();
              } catch (ClassFormatException ex) {
                isValid = false;
                break;
              }
            }
          }
          if (!isValid) {
            if (logger.isLoggable(TreeLogger.TRACE)) {
              logger.log(TreeLogger.TRACE, "Invalid Unit: " + unit.getTypeName());
            }
            invalidatedUnits.add(unit);
            builders.add(entry.getKey());
            it.remove();
          }
        }

        if (invalidatedUnits.size() > 0) {
          if (logger.isLoggable(TreeLogger.TRACE)) {
            logger.log(TreeLogger.TRACE, "Invalid units found: " + invalidatedUnits.size());
          }
        }

        // Any units we invalidated must now be removed from the valid classes.
        for (CompilationUnit unit : invalidatedUnits) {
          for (CompiledClass cc : unit.getCompiledClasses()) {
            allValidClasses.remove(cc.getSourceName());
          }
        }
      } while (builders.size() > 0);

      for (CompilationUnit unit : resultUnits) {
        unitCache.add(unit);
      }

      // Any remaining cached units are valid now.
      resultUnits.addAll(cachedUnits.values());

      // Done with a pass of the build - tell the cache its OK to cleanup
      // stale cache files.
      unitCache.cleanup(logger);

      // Sort, then report all errors (re-report for cached units).
      Collections.sort(resultUnits, CompilationUnit.COMPARATOR);
      logger = logger.branch(TreeLogger.DEBUG, "Validating units:");
      int errorCount = 0;
      for (CompilationUnit unit : resultUnits) {
        if (CompilationProblemReporter.reportErrors(logger, unit, suppressErrors)) {
          errorCount++;
        }
      }
      if (suppressErrors
          && errorCount > 0
          && !logger.isLoggable(TreeLogger.TRACE)
          && logger.isLoggable(TreeLogger.INFO)) {
        logger.log(
            TreeLogger.INFO,
            "Ignored "
                + errorCount
                + " unit"
                + (errorCount > 1 ? "s" : "")
                + " with compilation errors in first pass.\n"
                + "Compile with -strict or with -logLevel set to TRACE or DEBUG to see all errors.");
      }
      return resultUnits;
    }
Beispiel #15
0
 public static OptimizerStats exec(JProgram program) {
   Event optimizeEvent = SpeedTracerLogger.start(CompilerEventType.OPTIMIZE, "optimizer", NAME);
   OptimizerStats stats = new MethodInliner(program).execImpl();
   optimizeEvent.end("didChange", "" + stats.didChange());
   return stats;
 }
  @Override
  protected int doStartUpServer() {
    // Create the war directory if it doesn't exist
    File warDir = options.getWarDir();
    if (!warDir.exists() && !warDir.mkdirs()) {
      getTopLogger().log(TreeLogger.ERROR, "Unable to create war directory " + warDir);
      return -1;
    }

    Event jettyStartupEvent = SpeedTracerLogger.start(DevModeEventType.JETTY_STARTUP);
    boolean clearCallback = true;
    try {
      ui.setCallback(RestartServerEvent.getType(), this);

      ServletContainerLauncher scl = options.getServletContainerLauncher();

      TreeLogger serverLogger = ui.getWebServerLogger(getWebServerName(), scl.getIconBytes());

      String sclArgs = options.getServletContainerLauncherArgs();
      if (sclArgs != null) {
        if (!scl.processArguments(serverLogger, sclArgs)) {
          return -1;
        }
      }

      isHttps = scl.isSecure();

      // Tell the UI if the web server is secure
      if (isHttps) {
        ui.setWebServerSecure(serverLogger);
      }

      /*
       * TODO: This is a hack to pass the base log level to the SCL. We'll have
       * to figure out a better way to do this for SCLs in general.
       */
      if (scl instanceof JettyLauncher) {
        JettyLauncher jetty = (JettyLauncher) scl;
        jetty.setBaseRequestLogLevel(getBaseLogLevelForUI());
      }
      scl.setBindAddress(bindAddress);

      if (serverLogger.isLoggable(TreeLogger.TRACE)) {
        serverLogger.log(TreeLogger.TRACE, "Starting HTTP on port " + getPort(), null);
      }
      server = scl.start(serverLogger, getPort(), options.getWarDir());
      assert (server != null);
      clearCallback = false;
      return server.getPort();
    } catch (BindException e) {
      System.err.println(
          "Port "
              + bindAddress
              + ':'
              + getPort()
              + " is already is use; you probably still have another session active");
    } catch (Exception e) {
      System.err.println("Unable to start embedded HTTP server");
      e.printStackTrace();
    } finally {
      jettyStartupEvent.end();
      if (clearCallback) {
        // Clear the callback if we failed to start the server
        ui.setCallback(RestartServerEvent.getType(), null);
      }
    }
    return -1;
  }