Path: blob/master/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Preview.java
41241 views
/*1* Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.tools.javac.code;2627import com.sun.tools.javac.code.Lint.LintCategory;28import com.sun.tools.javac.code.Source.Feature;29import com.sun.tools.javac.jvm.Target;30import com.sun.tools.javac.resources.CompilerProperties.Errors;31import com.sun.tools.javac.resources.CompilerProperties.Warnings;32import com.sun.tools.javac.util.Assert;33import com.sun.tools.javac.util.Context;34import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;35import com.sun.tools.javac.util.JCDiagnostic.Error;36import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;37import com.sun.tools.javac.util.JCDiagnostic.Warning;38import com.sun.tools.javac.util.Log;39import com.sun.tools.javac.util.MandatoryWarningHandler;40import com.sun.tools.javac.util.Options;4142import javax.tools.JavaFileObject;43import java.util.HashMap;44import java.util.HashSet;45import java.util.Map;46import java.util.Set;4748import static com.sun.tools.javac.code.Flags.RECORD;49import static com.sun.tools.javac.code.Flags.SEALED;50import static com.sun.tools.javac.code.Flags.NON_SEALED;51import static com.sun.tools.javac.main.Option.PREVIEW;5253/**54* Helper class to handle preview language features. This class maps certain language features55* (see {@link Feature} into 'preview' features; the mapping is completely ad-hoc, so as to allow56* for maximum flexibility, which allows to migrate preview feature into supported features with ease.57*58* This class acts as a centralized point against which usages of preview features are reported by59* clients (e.g. other javac classes). Internally, this class collects all such usages and generates60* diagnostics to inform the user of such usages. Such diagnostics can be enabled using the61* {@link LintCategory#PREVIEW} lint category, and are suppressible by usual means.62*/63public class Preview {6465/** flag: are preview features enabled */66private final boolean enabled;6768/** the diag handler to manage preview feature usage diagnostics */69private final MandatoryWarningHandler previewHandler;7071/** test flag: should all features be considered as preview features? */72private final boolean forcePreview;7374/** a mapping from classfile numbers to Java SE versions */75private final Map<Integer, Source> majorVersionToSource;7677private final Set<JavaFileObject> sourcesWithPreviewFeatures = new HashSet<>();7879private final Lint lint;80private final Log log;8182private static final Context.Key<Preview> previewKey = new Context.Key<>();8384public static Preview instance(Context context) {85Preview instance = context.get(previewKey);86if (instance == null) {87instance = new Preview(context);88}89return instance;90}9192Preview(Context context) {93context.put(previewKey, this);94Options options = Options.instance(context);95enabled = options.isSet(PREVIEW);96log = Log.instance(context);97lint = Lint.instance(context);98Source source = Source.instance(context);99this.previewHandler =100new MandatoryWarningHandler(log, source, lint.isEnabled(LintCategory.PREVIEW), true, "preview", LintCategory.PREVIEW);101forcePreview = options.isSet("forcePreview");102majorVersionToSource = initMajorVersionToSourceMap();103}104105private Map<Integer, Source> initMajorVersionToSourceMap() {106Map<Integer, Source> majorVersionToSource = new HashMap<>();107for (Target t : Target.values()) {108int major = t.majorVersion;109Source source = Source.lookup(t.name);110if (source != null) {111majorVersionToSource.put(major, source);112}113}114return majorVersionToSource;115}116117/**118* Report usage of a preview feature. Usages reported through this method will affect the119* set of sourcefiles with dependencies on preview features.120* @param pos the position at which the preview feature was used.121* @param feature the preview feature used.122*/123public void warnPreview(int pos, Feature feature) {124warnPreview(new SimpleDiagnosticPosition(pos), feature);125}126127/**128* Report usage of a preview feature. Usages reported through this method will affect the129* set of sourcefiles with dependencies on preview features.130* @param pos the position at which the preview feature was used.131* @param feature the preview feature used.132*/133public void warnPreview(DiagnosticPosition pos, Feature feature) {134Assert.check(isEnabled());135Assert.check(isPreview(feature));136if (!lint.isSuppressed(LintCategory.PREVIEW)) {137sourcesWithPreviewFeatures.add(log.currentSourceFile());138previewHandler.report(pos, feature.isPlural() ?139Warnings.PreviewFeatureUsePlural(feature.nameFragment()) :140Warnings.PreviewFeatureUse(feature.nameFragment()));141}142}143144/**145* Report usage of a preview feature in classfile.146* @param classfile the name of the classfile with preview features enabled147* @param majorVersion the major version found in the classfile.148*/149public void warnPreview(JavaFileObject classfile, int majorVersion) {150Assert.check(isEnabled());151if (lint.isEnabled(LintCategory.PREVIEW)) {152sourcesWithPreviewFeatures.add(log.currentSourceFile());153log.mandatoryWarning(LintCategory.PREVIEW, null,154Warnings.PreviewFeatureUseClassfile(classfile, majorVersionToSource.get(majorVersion).name));155}156}157158public void markUsesPreview(DiagnosticPosition pos) {159sourcesWithPreviewFeatures.add(log.currentSourceFile());160}161162public void reportPreviewWarning(DiagnosticPosition pos, Warning warnKey) {163previewHandler.report(pos, warnKey);164}165166public boolean usesPreview(JavaFileObject file) {167return sourcesWithPreviewFeatures.contains(file);168}169170/**171* Are preview features enabled?172* @return true, if preview features are enabled.173*/174public boolean isEnabled() {175return enabled;176}177178/**179* Is given feature a preview feature?180* @param feature the feature to be tested.181* @return true, if given feature is a preview feature.182*/183public boolean isPreview(Feature feature) {184return switch (feature) {185//Note: this is a backdoor which allows to optionally treat all features as 'preview' (for testing).186//When real preview features will be added, this method can be implemented to return 'true'187//for those selected features, and 'false' for all the others.188default -> forcePreview;189};190}191192/**193* Generate an error key which captures the fact that a given preview feature could not be used194* due to the preview feature support being disabled.195* @param feature the feature for which the diagnostic has to be generated.196* @return the diagnostic.197*/198public Error disabledError(Feature feature) {199Assert.check(!isEnabled());200return feature.isPlural() ?201Errors.PreviewFeatureDisabledPlural(feature.nameFragment()) :202Errors.PreviewFeatureDisabled(feature.nameFragment());203}204205/**206* Generate an error key which captures the fact that a preview classfile cannot be loaded207* due to the preview feature support being disabled.208* @param classfile the name of the classfile with preview features enabled209* @param majorVersion the major version found in the classfile.210*/211public Error disabledError(JavaFileObject classfile, int majorVersion) {212Assert.check(!isEnabled());213return Errors.PreviewFeatureDisabledClassfile(classfile, majorVersionToSource.get(majorVersion).name);214}215216/**217* Check whether the given symbol has been declared using218* a preview language feature.219*220* @param sym Symbol to check221* @return true iff sym has been declared using a preview language feature222*/223public boolean declaredUsingPreviewFeature(Symbol sym) {224return false;225}226227/**228* Report any deferred diagnostics.229*/230public void reportDeferredDiagnostics() {231previewHandler.reportDeferredDiagnostic();232}233234public void clear() {235previewHandler.clear();236}237238}239240241