src/jdk.compiler/share/classes/com/sun/tools/javac/code/ModuleFinder.java
author Dusan Balek <dbalek@netbeans.org>
Mon, 31 Jul 2017 11:07:41 +0200
changeset 5955 f54cccaf6e6c
parent 5855 0fb5201da354
permissions -rw-r--r--
Mergin jlahoda's fix of #8182450: javac aborts when generating ct.sym intermittently - Initialize the module system model even in presence of missing/broken module-infos; BadClassFiles should not immediatelly abort compilation anymore, but should be handled as if the classfile did not exist.
alanb@5016
     1
/*
jlahoda@5832
     2
 * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
alanb@5016
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
alanb@5016
     4
 *
alanb@5016
     5
 * This code is free software; you can redistribute it and/or modify it
alanb@5016
     6
 * under the terms of the GNU General Public License version 2 only, as
alanb@5016
     7
 * published by the Free Software Foundation.  Oracle designates this
alanb@5016
     8
 * particular file as subject to the "Classpath" exception as provided
alanb@5016
     9
 * by Oracle in the LICENSE file that accompanied this code.
alanb@5016
    10
 *
alanb@5016
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
alanb@5016
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
alanb@5016
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
alanb@5016
    14
 * version 2 for more details (a copy is included in the LICENSE file that
alanb@5016
    15
 * accompanied this code).
alanb@5016
    16
 *
alanb@5016
    17
 * You should have received a copy of the GNU General Public License version
alanb@5016
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
alanb@5016
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
alanb@5016
    20
 *
alanb@5016
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
alanb@5016
    22
 * or visit www.oracle.com if you need additional information or have any
alanb@5016
    23
 * questions.
alanb@5016
    24
 */
alanb@5016
    25
package com.sun.tools.javac.code;
alanb@5016
    26
alanb@5016
    27
import java.io.IOException;
alanb@5016
    28
import java.util.Arrays;
alanb@5016
    29
import java.util.HashMap;
alanb@5016
    30
import java.util.Iterator;
alanb@5016
    31
import java.util.Map;
alanb@5016
    32
import java.util.NoSuchElementException;
alanb@5016
    33
import java.util.Set;
alanb@5016
    34
alanb@5016
    35
import javax.tools.JavaFileManager;
alanb@5016
    36
import javax.tools.JavaFileManager.Location;
alanb@5016
    37
import javax.tools.JavaFileObject;
alanb@5016
    38
import javax.tools.JavaFileObject.Kind;
alanb@5016
    39
import javax.tools.StandardLocation;
alanb@5016
    40
jlahoda@5832
    41
import com.sun.tools.javac.code.Symbol.ClassSymbol;
jlahoda@5420
    42
import com.sun.tools.javac.code.Symbol.Completer;
alanb@5016
    43
import com.sun.tools.javac.code.Symbol.CompletionFailure;
alanb@5016
    44
import com.sun.tools.javac.code.Symbol.ModuleSymbol;
jlahoda@5420
    45
import com.sun.tools.javac.jvm.ModuleNameReader;
jlahoda@5420
    46
import com.sun.tools.javac.jvm.ModuleNameReader.BadClassFile;
alanb@5016
    47
import com.sun.tools.javac.resources.CompilerProperties.Errors;
alanb@5016
    48
import com.sun.tools.javac.resources.CompilerProperties.Fragments;
jlahoda@5420
    49
import com.sun.tools.javac.util.Assert;
alanb@5016
    50
import com.sun.tools.javac.util.Context;
alanb@5016
    51
import com.sun.tools.javac.util.JCDiagnostic;
alanb@5016
    52
import com.sun.tools.javac.util.JCDiagnostic.Fragment;
alanb@5016
    53
import com.sun.tools.javac.util.List;
alanb@5016
    54
import com.sun.tools.javac.util.ListBuffer;
alanb@5016
    55
import com.sun.tools.javac.util.Log;
alanb@5016
    56
import com.sun.tools.javac.util.Name;
alanb@5016
    57
import com.sun.tools.javac.util.Names;
alanb@5016
    58
alanb@5016
    59
import static com.sun.tools.javac.code.Kinds.Kind.*;
dbalek@5955
    60
import com.sun.tools.javac.comp.Check;
alanb@5016
    61
alanb@5016
    62
/**
alanb@5016
    63
 *  This class provides operations to locate module definitions
alanb@5016
    64
 *  from the source and class files on the paths provided to javac.
alanb@5016
    65
 *
alanb@5016
    66
 *  <p><b>This is NOT part of any supported API.
alanb@5016
    67
 *  If you write code that depends on this, you do so at your own risk.
alanb@5016
    68
 *  This code and its internal interfaces are subject to change or
alanb@5016
    69
 *  deletion without notice.</b>
alanb@5016
    70
 */
alanb@5016
    71
public class ModuleFinder {
alanb@5016
    72
    /** The context key for the module finder. */
alanb@5016
    73
    protected static final Context.Key<ModuleFinder> moduleFinderKey = new Context.Key<>();
alanb@5016
    74
alanb@5016
    75
    /** The log to use for verbose output. */
alanb@5016
    76
    private final Log log;
alanb@5016
    77
alanb@5016
    78
    /** The symbol table. */
alanb@5016
    79
    private final Symtab syms;
alanb@5016
    80
alanb@5016
    81
    /** The name table. */
alanb@5016
    82
    private final Names names;
alanb@5016
    83
alanb@5016
    84
    private final ClassFinder classFinder;
dbalek@5955
    85
    private final Check chk;
alanb@5016
    86
alanb@5016
    87
    /** Access to files
alanb@5016
    88
     */
alanb@5016
    89
    private final JavaFileManager fileManager;
alanb@5016
    90
alanb@5016
    91
    private final JCDiagnostic.Factory diags;
alanb@5016
    92
dbalek@5253
    93
    private ModuleNameReader moduleNameReader;
dbalek@5253
    94
jlahoda@5832
    95
    public ModuleNameFromSourceReader moduleNameFromSourceReader;
dbalek@5253
    96
alanb@5016
    97
    /** Get the ModuleFinder instance for this invocation. */
alanb@5016
    98
    public static ModuleFinder instance(Context context) {
alanb@5016
    99
        ModuleFinder instance = context.get(moduleFinderKey);
alanb@5016
   100
        if (instance == null)
alanb@5016
   101
            instance = new ModuleFinder(context);
alanb@5016
   102
        return instance;
alanb@5016
   103
    }
alanb@5016
   104
alanb@5016
   105
    /** Construct a new module finder. */
alanb@5016
   106
    protected ModuleFinder(Context context) {
alanb@5016
   107
        context.put(moduleFinderKey, this);
alanb@5016
   108
        names = Names.instance(context);
alanb@5016
   109
        syms = Symtab.instance(context);
alanb@5016
   110
        fileManager = context.get(JavaFileManager.class);
alanb@5016
   111
        log = Log.instance(context);
alanb@5016
   112
        classFinder = ClassFinder.instance(context);
dbalek@5955
   113
        chk = Check.instance(context);
alanb@5016
   114
alanb@5016
   115
        diags = JCDiagnostic.Factory.instance(context);
alanb@5016
   116
    }
alanb@5016
   117
alanb@5016
   118
    class ModuleLocationIterator implements Iterator<Set<Location>> {
alanb@5016
   119
        StandardLocation outer;
alanb@5016
   120
        Set<Location> next = null;
alanb@5016
   121
alanb@5016
   122
        Iterator<StandardLocation> outerIter = Arrays.asList(
alanb@5016
   123
                StandardLocation.MODULE_SOURCE_PATH,
alanb@5016
   124
                StandardLocation.UPGRADE_MODULE_PATH,
alanb@5016
   125
                StandardLocation.SYSTEM_MODULES,
alanb@5016
   126
                StandardLocation.MODULE_PATH
alanb@5016
   127
        ).iterator();
alanb@5016
   128
        Iterator<Set<Location>> innerIter = null;
alanb@5016
   129
alanb@5016
   130
        @Override
alanb@5016
   131
        public boolean hasNext() {
alanb@5016
   132
            while (next == null) {
alanb@5016
   133
                while (innerIter == null || !innerIter.hasNext()) {
alanb@5016
   134
                    if (outerIter.hasNext()) {
alanb@5016
   135
                        outer = outerIter.next();
alanb@5016
   136
                        try {
jjg@5528
   137
                            innerIter = fileManager.listLocationsForModules(outer).iterator();
alanb@5016
   138
                        } catch (IOException e) {
alanb@5016
   139
                            System.err.println("error listing module locations for " + outer + ": " + e);  // FIXME
alanb@5016
   140
                        }
alanb@5016
   141
                    } else
alanb@5016
   142
                        return false;
alanb@5016
   143
                }
alanb@5016
   144
alanb@5016
   145
                if (innerIter.hasNext())
alanb@5016
   146
                    next = innerIter.next();
alanb@5016
   147
            }
alanb@5016
   148
            return true;
alanb@5016
   149
        }
alanb@5016
   150
alanb@5016
   151
        @Override
alanb@5016
   152
        public Set<Location> next() {
alanb@5016
   153
            hasNext();
alanb@5016
   154
            if (next != null) {
alanb@5016
   155
                Set<Location> result = next;
alanb@5016
   156
                next = null;
alanb@5016
   157
                return result;
alanb@5016
   158
            }
alanb@5016
   159
            throw new NoSuchElementException();
alanb@5016
   160
        }
alanb@5016
   161
alanb@5016
   162
    }
alanb@5016
   163
alanb@5016
   164
    ModuleLocationIterator moduleLocationIterator = new ModuleLocationIterator();
alanb@5016
   165
alanb@5016
   166
    public ModuleSymbol findModule(Name name) {
alanb@5016
   167
        return findModule(syms.enterModule(name));
alanb@5016
   168
    }
alanb@5016
   169
alanb@5016
   170
    public ModuleSymbol findModule(ModuleSymbol msym) {
alanb@5016
   171
        if (msym.kind != ERR && msym.sourceLocation == null && msym.classLocation == null) {
alanb@5016
   172
            // fill in location
alanb@5016
   173
            List<ModuleSymbol> list = scanModulePath(msym);
alanb@5016
   174
            if (list.isEmpty()) {
alanb@5016
   175
                msym.kind = ERR;
alanb@5016
   176
            }
alanb@5016
   177
        }
alanb@5016
   178
        if (msym.kind != ERR && msym.module_info.sourcefile == null && msym.module_info.classfile == null) {
alanb@5016
   179
            // fill in module-info
alanb@5016
   180
            findModuleInfo(msym);
alanb@5016
   181
        }
alanb@5016
   182
        return msym;
alanb@5016
   183
    }
alanb@5016
   184
alanb@5016
   185
    public List<ModuleSymbol> findAllModules() {
alanb@5016
   186
        List<ModuleSymbol> list = scanModulePath(null);
alanb@5016
   187
        for (ModuleSymbol msym: list) {
alanb@5016
   188
            if (msym.kind != ERR && msym.module_info.sourcefile == null && msym.module_info.classfile == null) {
alanb@5016
   189
                // fill in module-info
alanb@5016
   190
                findModuleInfo(msym);
alanb@5016
   191
            }
alanb@5016
   192
        }
alanb@5016
   193
        return list;
alanb@5016
   194
    }
alanb@5016
   195
alanb@5016
   196
    public ModuleSymbol findSingleModule() {
alanb@5016
   197
        try {
alanb@5016
   198
            JavaFileObject src_fo = getModuleInfoFromLocation(StandardLocation.SOURCE_PATH, Kind.SOURCE);
alanb@5016
   199
            JavaFileObject class_fo = getModuleInfoFromLocation(StandardLocation.CLASS_OUTPUT, Kind.CLASS);
alanb@5016
   200
            JavaFileObject fo = (src_fo == null) ? class_fo
alanb@5016
   201
                    : (class_fo == null) ? src_fo
alanb@5016
   202
                            : classFinder.preferredFileObject(src_fo, class_fo);
alanb@5016
   203
alanb@5016
   204
            ModuleSymbol msym;
alanb@5016
   205
            if (fo == null) {
alanb@5016
   206
                msym = syms.unnamedModule;
alanb@5016
   207
            } else {
dbalek@5955
   208
                try {
dbalek@5955
   209
                    msym = readModule(fo);
dbalek@5955
   210
                } catch (CompletionFailure ex) {
dbalek@5955
   211
                    chk.completionError(null, ex);
dbalek@5955
   212
                    msym = syms.unnamedModule;
dbalek@5955
   213
                }
dbalek@5955
   214
                    
alanb@5016
   215
            }
alanb@5016
   216
jlahoda@5832
   217
            if (msym.patchLocation == null) {
jlahoda@5832
   218
                msym.classLocation = StandardLocation.CLASS_OUTPUT;
jlahoda@5832
   219
            } else {
jlahoda@5832
   220
                msym.patchOutputLocation = StandardLocation.CLASS_OUTPUT;
jlahoda@5832
   221
            }
alanb@5016
   222
            return msym;
alanb@5016
   223
alanb@5016
   224
        } catch (IOException e) {
alanb@5016
   225
            throw new Error(e); // FIXME
alanb@5016
   226
        }
alanb@5016
   227
    }
alanb@5016
   228
jlahoda@5832
   229
    private ModuleSymbol readModule(JavaFileObject fo) throws IOException {
jlahoda@5832
   230
        Name name;
jlahoda@5832
   231
        switch (fo.getKind()) {
jlahoda@5832
   232
            case SOURCE:
jlahoda@5832
   233
                name = moduleNameFromSourceReader.readModuleName(fo);
jlahoda@5832
   234
                if (name == null) {
jlahoda@5832
   235
                    JCDiagnostic diag =
jlahoda@5832
   236
                        diags.fragment("file.does.not.contain.module");
jlahoda@5832
   237
                    ClassSymbol errModuleInfo = syms.defineClass(names.module_info, syms.errModule);
jlahoda@5832
   238
                    throw new ClassFinder.BadClassFile(errModuleInfo, fo, diag, diags);
jlahoda@5832
   239
                }
jlahoda@5832
   240
                break;
jlahoda@5832
   241
            case CLASS:
jlahoda@5832
   242
                try {
jlahoda@5832
   243
                    name = names.fromString(readModuleName(fo));
jlahoda@5832
   244
                } catch (BadClassFile | IOException ex) {
jlahoda@5832
   245
                    //fillIn will report proper errors:
jlahoda@5832
   246
                    name = names.error;
jlahoda@5832
   247
                }
jlahoda@5832
   248
                break;
jlahoda@5832
   249
            default:
jlahoda@5832
   250
                Assert.error();
jlahoda@5832
   251
                name = names.error;
jlahoda@5832
   252
                break;
jlahoda@5832
   253
        }
jlahoda@5832
   254
jlahoda@5832
   255
        ModuleSymbol msym = syms.enterModule(name);
jlahoda@5832
   256
        msym.module_info.classfile = fo;
jlahoda@5832
   257
        if (fileManager.hasLocation(StandardLocation.PATCH_MODULE_PATH) && name != names.error) {
jlahoda@5832
   258
            msym.patchLocation = fileManager.getLocationForModule(StandardLocation.PATCH_MODULE_PATH, name.toString());
jlahoda@5832
   259
jlahoda@5832
   260
            if (msym.patchLocation != null) {
jlahoda@5832
   261
                JavaFileObject patchFO = getModuleInfoFromLocation(StandardLocation.CLASS_OUTPUT, Kind.CLASS);
jlahoda@5832
   262
                patchFO = preferredFileObject(getModuleInfoFromLocation(msym.patchLocation, Kind.CLASS), patchFO);
jlahoda@5832
   263
                patchFO = preferredFileObject(getModuleInfoFromLocation(msym.patchLocation, Kind.SOURCE), patchFO);
jlahoda@5832
   264
jlahoda@5832
   265
                if (patchFO != null) {
jlahoda@5832
   266
                    msym.module_info.classfile = patchFO;
jlahoda@5832
   267
                }
jlahoda@5832
   268
            }
jlahoda@5832
   269
        }
jlahoda@5832
   270
jlahoda@5832
   271
        msym.completer = Completer.NULL_COMPLETER;
jlahoda@5832
   272
        classFinder.fillIn(msym.module_info);
jlahoda@5832
   273
jlahoda@5832
   274
        return msym;
jlahoda@5832
   275
    }
jlahoda@5832
   276
dbalek@5253
   277
    private String readModuleName(JavaFileObject jfo) throws IOException, ModuleNameReader.BadClassFile {
dbalek@5253
   278
        if (moduleNameReader == null)
dbalek@5253
   279
            moduleNameReader = new ModuleNameReader();
dbalek@5253
   280
        return moduleNameReader.readModuleName(jfo);
dbalek@5253
   281
    }
dbalek@5253
   282
alanb@5016
   283
    private JavaFileObject getModuleInfoFromLocation(Location location, Kind kind) throws IOException {
jlahoda@5832
   284
        if (location == null || !fileManager.hasLocation(location))
alanb@5016
   285
            return null;
alanb@5016
   286
alanb@5016
   287
        return fileManager.getJavaFileForInput(location,
alanb@5016
   288
                                               names.module_info.toString(),
alanb@5016
   289
                                               kind);
alanb@5016
   290
    }
alanb@5016
   291
alanb@5016
   292
    private List<ModuleSymbol> scanModulePath(ModuleSymbol toFind) {
alanb@5016
   293
        ListBuffer<ModuleSymbol> results = new ListBuffer<>();
alanb@5016
   294
        Map<Name, Location> namesInSet = new HashMap<>();
jlahoda@5751
   295
        boolean multiModuleMode = fileManager.hasLocation(StandardLocation.MODULE_SOURCE_PATH);
alanb@5016
   296
        while (moduleLocationIterator.hasNext()) {
alanb@5016
   297
            Set<Location> locns = (moduleLocationIterator.next());
alanb@5016
   298
            namesInSet.clear();
alanb@5016
   299
            for (Location l: locns) {
alanb@5016
   300
                try {
alanb@5016
   301
                    Name n = names.fromString(fileManager.inferModuleName(l));
alanb@5016
   302
                    if (namesInSet.put(n, l) == null) {
alanb@5016
   303
                        ModuleSymbol msym = syms.enterModule(n);
alanb@5016
   304
                        if (msym.sourceLocation != null || msym.classLocation != null) {
alanb@5016
   305
                            // module has already been found, so ignore this instance
alanb@5016
   306
                            continue;
alanb@5016
   307
                        }
jlahoda@5751
   308
                        if (fileManager.hasLocation(StandardLocation.PATCH_MODULE_PATH) &&
jlahoda@5751
   309
                            msym.patchLocation == null) {
jlahoda@5751
   310
                            msym.patchLocation =
jlahoda@5751
   311
                                    fileManager.getLocationForModule(StandardLocation.PATCH_MODULE_PATH,
jlahoda@5751
   312
                                                                     msym.name.toString());
jlahoda@5751
   313
                            if (msym.patchLocation != null &&
jlahoda@5751
   314
                                multiModuleMode &&
jlahoda@5751
   315
                                fileManager.hasLocation(StandardLocation.CLASS_OUTPUT)) {
jlahoda@5751
   316
                                msym.patchOutputLocation =
jlahoda@5751
   317
                                        fileManager.getLocationForModule(StandardLocation.CLASS_OUTPUT,
jlahoda@5751
   318
                                                                         msym.name.toString());
jlahoda@5751
   319
                            }
jlahoda@5751
   320
                        }
alanb@5016
   321
                        if (moduleLocationIterator.outer == StandardLocation.MODULE_SOURCE_PATH) {
jlahoda@5832
   322
                            msym.sourceLocation = l;
jlahoda@5832
   323
                            if (fileManager.hasLocation(StandardLocation.CLASS_OUTPUT)) {
jlahoda@5832
   324
                                msym.classLocation =
jlahoda@5832
   325
                                        fileManager.getLocationForModule(StandardLocation.CLASS_OUTPUT,
jlahoda@5832
   326
                                                                         msym.name.toString());
alanb@5016
   327
                            }
alanb@5016
   328
                        } else {
alanb@5016
   329
                            msym.classLocation = l;
alanb@5016
   330
                        }
alanb@5016
   331
                        if (moduleLocationIterator.outer == StandardLocation.SYSTEM_MODULES ||
alanb@5016
   332
                            moduleLocationIterator.outer == StandardLocation.UPGRADE_MODULE_PATH) {
alanb@5016
   333
                            msym.flags_field |= Flags.SYSTEM_MODULE;
alanb@5016
   334
                        }
jlahoda@5751
   335
                        if (toFind == null ||
jlahoda@5751
   336
                            (toFind == msym && (msym.sourceLocation != null || msym.classLocation != null))) {
alanb@5016
   337
                            // Note: cannot return msym directly, because we must finish
alanb@5016
   338
                            // processing this set first
alanb@5016
   339
                            results.add(msym);
alanb@5016
   340
                        }
alanb@5016
   341
                    } else {
alanb@5016
   342
                        log.error(Errors.DuplicateModuleOnPath(
alanb@5016
   343
                                getDescription(moduleLocationIterator.outer), n));
alanb@5016
   344
                    }
alanb@5016
   345
                } catch (IOException e) {
alanb@5016
   346
                    // skip location for now?  log error?
alanb@5016
   347
                }
alanb@5016
   348
            }
alanb@5016
   349
            if (toFind != null && results.nonEmpty())
alanb@5016
   350
                return results.toList();
alanb@5016
   351
        }
alanb@5016
   352
alanb@5016
   353
        return results.toList();
alanb@5016
   354
    }
alanb@5016
   355
alanb@5016
   356
    private void findModuleInfo(ModuleSymbol msym) {
alanb@5016
   357
        try {
jlahoda@5832
   358
            JavaFileObject fo;
alanb@5016
   359
jlahoda@5832
   360
            fo = getModuleInfoFromLocation(msym.patchOutputLocation, Kind.CLASS);
jlahoda@5832
   361
            fo = preferredFileObject(getModuleInfoFromLocation(msym.patchLocation, Kind.CLASS), fo);
jlahoda@5832
   362
            fo = preferredFileObject(getModuleInfoFromLocation(msym.patchLocation, Kind.SOURCE), fo);
alanb@5016
   363
jlahoda@5832
   364
            if (fo == null) {
jlahoda@5832
   365
                fo = getModuleInfoFromLocation(msym.classLocation, Kind.CLASS);
jlahoda@5837
   366
                fo = preferredFileObject(getModuleInfoFromLocation(msym.sourceLocation, Kind.SOURCE), fo);
jlahoda@5832
   367
            }
alanb@5016
   368
alanb@5016
   369
            if (fo == null) {
alanb@5016
   370
                String moduleName = msym.sourceLocation == null && msym.classLocation != null ?
alanb@5016
   371
                    fileManager.inferModuleName(msym.classLocation) : null;
alanb@5016
   372
                if (moduleName != null) {
alanb@5016
   373
                    msym.module_info.classfile = null;
alanb@5016
   374
                    msym.flags_field |= Flags.AUTOMATIC_MODULE;
alanb@5016
   375
                } else {
alanb@5016
   376
                    msym.kind = ERR;
alanb@5016
   377
                }
alanb@5016
   378
            } else {
alanb@5016
   379
                msym.module_info.classfile = fo;
alanb@5016
   380
                msym.module_info.completer = new Symbol.Completer() {
alanb@5016
   381
                    @Override
alanb@5016
   382
                    public void complete(Symbol sym) throws CompletionFailure {
dbalek@5608
   383
                        try {
dbalek@5608
   384
                            classFinder.fillIn(msym.module_info);
dbalek@5608
   385
                        } catch (Exception ex) {
dbalek@5608
   386
                            msym.kind = ERR;
dbalek@5608
   387
                            //make sure the module is initialized:
dbalek@5608
   388
                            msym.directives = List.nil();
dbalek@5608
   389
                            msym.exports = List.nil();
dbalek@5608
   390
                            msym.provides = List.nil();
dbalek@5608
   391
                            msym.requires = List.nil();
dbalek@5608
   392
                            msym.uses = List.nil();
dbalek@5608
   393
                        }
alanb@5016
   394
                    }
alanb@5016
   395
                    @Override
alanb@5016
   396
                    public String toString() {
alanb@5016
   397
                        return "ModuleInfoCompleter";
alanb@5016
   398
                    }
alanb@5016
   399
                };
alanb@5016
   400
            }
alanb@5016
   401
        } catch (IOException e) {
alanb@5016
   402
            msym.kind = ERR;
alanb@5016
   403
        }
alanb@5016
   404
    }
alanb@5016
   405
jlahoda@5832
   406
    private JavaFileObject preferredFileObject(JavaFileObject fo1, JavaFileObject fo2) {
jlahoda@5832
   407
        if (fo1 == null) return fo2;
jlahoda@5832
   408
        if (fo2 == null) return fo1;
jlahoda@5832
   409
        return classFinder.preferredFileObject(fo1, fo2);
jlahoda@5832
   410
    }
jlahoda@5832
   411
alanb@5016
   412
    Fragment getDescription(StandardLocation l) {
alanb@5016
   413
        switch (l) {
alanb@5016
   414
            case MODULE_PATH: return Fragments.LocnModule_path;
alanb@5016
   415
            case MODULE_SOURCE_PATH: return Fragments.LocnModule_source_path;
alanb@5016
   416
            case SYSTEM_MODULES: return Fragments.LocnSystem_modules;
alanb@5016
   417
            case UPGRADE_MODULE_PATH: return Fragments.LocnUpgrade_module_path;
alanb@5016
   418
            default:
alanb@5016
   419
                throw new AssertionError();
alanb@5016
   420
        }
alanb@5016
   421
    }
alanb@5016
   422
jlahoda@5832
   423
    public interface ModuleNameFromSourceReader {
jlahoda@5832
   424
        public Name readModuleName(JavaFileObject file);
dbalek@5253
   425
    }
dbalek@5253
   426
alanb@5016
   427
}