예제 #1
0
 private void loadCompiledModules(
     List<JCCompilationUnit> trees, LinkedList<JCCompilationUnit> moduleTrees) {
   compilerDelegate.visitModules(phasedUnits);
   Modules modules = ceylonContext.getModules();
   // now make sure the phase units have their modules and packages set correctly
   for (PhasedUnit pu : phasedUnits.getPhasedUnits()) {
     Package pkg = pu.getPackage();
     loadModuleFromSource(pkg, modules, moduleTrees, trees);
   }
   // also make sure we have packages and modules set up for every Java file we compile
   for (JCCompilationUnit cu : trees) {
     // skip Ceylon CUs
     if (cu instanceof CeylonCompilationUnit) continue;
     String packageName = "";
     if (cu.pid != null) packageName = TreeInfo.fullName(cu.pid).toString();
     /*
      * Stef: see javadoc for findOrCreateModulelessPackage() for why this is here.
      */
     Package pkg = modelLoader.findOrCreateModulelessPackage(packageName);
     loadModuleFromSource(pkg, modules, moduleTrees, trees);
   }
   for (PhasedUnit phasedUnit : phasedUnits.getPhasedUnits()) {
     for (Tree.ModuleDescriptor modDescr :
         phasedUnit.getCompilationUnit().getModuleDescriptors()) {
       String name = phasedUnit.getPackage().getNameAsString();
       CeylonPhasedUnit cpu = (CeylonPhasedUnit) phasedUnit;
       CeylonFileObject cfo = (CeylonFileObject) cpu.getFileObject();
       moduleNamesToFileObjects.put(name, cfo);
     }
   }
 }
예제 #2
0
 private void addResources() throws Abort {
   HashSet<String> written = new HashSet<String>();
   try {
     for (JavaFileObject fo : resourceFileObjects) {
       CeyloncFileManager dfm = (CeyloncFileManager) fileManager;
       String jarFileName =
           JarUtils.toPlatformIndependentPath(
               dfm.getLocation(CeylonLocation.RESOURCE_PATH), fo.getName());
       if (!written.contains(jarFileName)) {
         dfm.setModule(modelLoader.findModuleForFile(new File(jarFileName)));
         FileObject outFile =
             dfm.getFileForOutput(StandardLocation.CLASS_OUTPUT, "", jarFileName, null);
         OutputStream out = outFile.openOutputStream();
         try {
           InputStream in = new FileInputStream(new File(fo.getName()));
           try {
             JarUtils.copy(in, out);
           } finally {
             in.close();
           }
         } finally {
           out.close();
         }
         written.add(jarFileName);
       }
     }
   } catch (IOException ex) {
     throw new Abort(ex);
   }
 }
예제 #3
0
 // FIXME: This is only here for wildcard imports, and we should be able to make it lazy like the
 // rest
 // with a bit of work in the typechecker
 // FIXME: redo this method better: https://github.com/ceylon/ceylon-spec/issues/90
 @Override
 public List<Declaration> getMembers() {
   synchronized (modelLoader) {
     // make sure the package is loaded
     modelLoader.loadPackage(getQualifiedNameString(), true);
     List<Declaration> sourceDeclarations = super.getMembers();
     LinkedList<Declaration> ret = new LinkedList<Declaration>();
     ret.addAll(sourceDeclarations);
     ret.addAll(compiledDeclarations);
     return ret;
   }
 }
예제 #4
0
  // FIXME: redo this method better: https://github.com/ceylon/ceylon-spec/issues/90
  @Override
  public Declaration getDirectMember(String name, List<ProducedType> signature) {
    synchronized (modelLoader) {
      String pkgName = getQualifiedNameString();

      // we need its package ready first
      modelLoader.loadPackage(pkgName, false);

      // make sure we iterate over a copy of compiledDeclarations, to avoid lazy loading to modify
      // it and
      // cause a ConcurrentModificationException:
      // https://github.com/ceylon/ceylon-compiler/issues/399
      Declaration d = lookupMember(copy(compiledDeclarations), name, signature, false);
      if (d != null) {
        return d;
      }

      String className = getQualifiedName(pkgName, name);
      ClassMirror classSymbol = modelLoader.lookupClassMirror(className);

      // only get it from the classpath if we're not compiling it, unless
      // it happens to be a java source
      if (classSymbol != null
          && (!classSymbol.isLoadedFromSource() || classSymbol.isJavaSource())) {
        d = modelLoader.convertToDeclaration(className, DeclarationType.VALUE);
        if (d instanceof Class) {
          if (((Class) d).isAbstraction()) {
            // make sure we iterate over a copy of compiledDeclarations, to avoid lazy loading to
            // modify it and
            // cause a ConcurrentModificationException:
            // https://github.com/ceylon/ceylon-compiler/issues/399
            return lookupMember(copy(compiledDeclarations), name, signature, false);
          }
        }
        return d;
      }
      return getDirectMemberFromSource(name);
    }
  }
예제 #5
0
 @Override
 public List<JCCompilationUnit> parseFiles(Iterable<JavaFileObject> fileObjects) {
   timer.startTask("parse");
   /*
    * Stef: see javadoc for fixDefaultPackage() for why this is here.
    */
   modelLoader.fixDefaultPackage();
   List<JCCompilationUnit> trees = super.parseFiles(fileObjects);
   timer.startTask("loadCompiledModules");
   LinkedList<JCCompilationUnit> moduleTrees = new LinkedList<JCCompilationUnit>();
   // now load modules and associate their moduleless packages with the corresponding modules
   loadCompiledModules(trees, moduleTrees);
   for (JCCompilationUnit moduleTree : moduleTrees) {
     trees = trees.append(moduleTree);
   }
   /*
    * Stef: see javadoc for cacheModulelessPackages() for why this is here.
    */
   modelLoader.cacheModulelessPackages();
   timer.endTask();
   return trees;
 }
예제 #6
0
 @Override
 public void removeUnit(Unit unit) {
   synchronized (modelLoader) {
     if (lazyUnits.remove(unit)) {
       for (Declaration d : unit.getDeclarations()) {
         compiledDeclarations.remove(d);
         // TODO : remove the declaration from the declaration map in AbstractModelLoader
       }
       modelLoader.removeDeclarations(unit.getDeclarations());
     } else {
       super.removeUnit(unit);
     }
   }
 }
예제 #7
0
 private JavaFileObject genCodeUnlessError(Env<AttrContext> env, JCClassDecl cdef)
     throws IOException {
   CeylonFileObject sourcefile = (CeylonFileObject) env.toplevel.sourcefile;
   try {
     // do not look at the global number of errors but only those for this file
     if (super.gen.genClass(env, cdef) && !sourcefile.hasError(cdef.pos)) {
       String packageName = cdef.sym.packge().getQualifiedName().toString();
       Package pkg = modelLoader.findPackage(packageName);
       if (pkg == null) throw new RuntimeException("Failed to find package: " + packageName);
       Module module = pkg.getModule();
       if (!module.isDefault()) {
         String moduleName = module.getNameAsString();
         CeylonFileObject moduleFileObject = moduleNamesToFileObjects.get(moduleName);
         // if there's no module source file object it means the module descriptor had parse errors
         if (moduleFileObject == null || moduleFileObject.hasError()) {
           // we do not produce any class files for modules with errors
           if (options.get(OptionName.VERBOSE) != null) {
             Log.printLines(
                 log.noticeWriter,
                 "[Not writing class "
                     + cdef.sym.className()
                     + " because its module has errors: "
                     + moduleName
                     + "]");
           }
           return null;
         }
       }
       return writer.writeClass(cdef.sym);
     }
   } catch (ClassWriter.PoolOverflow ex) {
     log.error(cdef.pos(), "limit.pool");
   } catch (ClassWriter.StringOverflow ex) {
     log.error(cdef.pos(), "limit.string.overflow", ex.value.substring(0, 20));
   } catch (CompletionFailure ex) {
     chk.completionError(cdef.pos(), ex);
   } catch (AssertionError e) {
     throw new RuntimeException("Error generating bytecode for " + sourcefile.getName(), e);
   }
   return null;
 }
예제 #8
0
  private JCCompilationUnit ceylonParse(JavaFileObject filename, CharSequence readSource) {
    if (ceylonEnter.hasRun())
      throw new RuntimeException(
          "Trying to load new source file after CeylonEnter has been called: " + filename);
    try {
      ModuleManager moduleManager = phasedUnits.getModuleManager();
      File sourceFile = new File(filename.getName());
      // FIXME: temporary solution
      VirtualFile file = vfs.getFromFile(sourceFile);
      VirtualFile srcDir = vfs.getFromFile(getSrcDir(sourceFile));

      String source = readSource.toString();
      char[] chars = source.toCharArray();
      LineMap map = Position.makeLineMap(chars, chars.length, false);

      PhasedUnit phasedUnit = null;

      PhasedUnit externalPhasedUnit = compilerDelegate.getExternalSourcePhasedUnit(srcDir, file);

      if (externalPhasedUnit != null) {
        phasedUnit = new CeylonPhasedUnit(externalPhasedUnit, filename, map);
        phasedUnits.addPhasedUnit(externalPhasedUnit.getUnitFile(), phasedUnit);
        gen.setMap(map);

        String pkgName = phasedUnit.getPackage().getQualifiedNameString();
        if ("".equals(pkgName)) {
          pkgName = null;
        }
        return gen.makeJCCompilationUnitPlaceholder(
            phasedUnit.getCompilationUnit(), filename, pkgName, phasedUnit);
      }
      if (phasedUnit == null) {
        ANTLRStringStream input = new ANTLRStringStream(source);
        CeylonLexer lexer = new CeylonLexer(input);

        CommonTokenStream tokens = new CommonTokenStream(lexer);

        CeylonParser parser = new CeylonParser(tokens);
        CompilationUnit cu = parser.compilationUnit();

        java.util.List<LexError> lexerErrors = lexer.getErrors();
        for (LexError le : lexerErrors) {
          printError(le, le.getMessage(), "ceylon.lexer", map);
        }

        java.util.List<ParseError> parserErrors = parser.getErrors();
        for (ParseError pe : parserErrors) {
          printError(pe, pe.getMessage(), "ceylon.parser", map);
        }

        if (lexerErrors.size() == 0 && parserErrors.size() == 0) {
          // FIXME: this is bad in many ways
          String pkgName = getPackage(filename);
          // make a Package with no module yet, we will resolve them later
          /*
           * Stef: see javadoc for findOrCreateModulelessPackage() for why this is here.
           */
          com.redhat.ceylon.compiler.typechecker.model.Package p =
              modelLoader.findOrCreateModulelessPackage(pkgName == null ? "" : pkgName);
          phasedUnit =
              new CeylonPhasedUnit(
                  file, srcDir, cu, p, moduleManager, ceylonContext, filename, map);
          phasedUnits.addPhasedUnit(file, phasedUnit);
          gen.setMap(map);

          return gen.makeJCCompilationUnitPlaceholder(cu, filename, pkgName, phasedUnit);
        }
      }
    } catch (RuntimeException e) {
      throw e;
    } catch (Exception e) {
      throw new RuntimeException(e);
    }

    JCCompilationUnit result =
        make.TopLevel(List.<JCAnnotation>nil(), null, List.<JCTree>of(make.Erroneous()));
    result.sourcefile = filename;
    return result;
  }