| /* |
| * Copyright 2006 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.cfg; |
| |
| import com.google.gwt.core.ext.TreeLogger; |
| import com.google.gwt.core.ext.UnableToCompleteException; |
| import com.google.gwt.core.ext.typeinfo.JClassType; |
| import com.google.gwt.core.ext.typeinfo.TypeOracle; |
| import com.google.gwt.dev.javac.CompilationProblemReporter; |
| |
| /** |
| * A deferred binding condition to determine whether the type being rebound is |
| * assignment-compatible with a particular type. |
| */ |
| public class ConditionWhenTypeAssignableTo extends Condition { |
| |
| private static boolean warnedMissingValidationJar = false; |
| |
| private final String assignableToTypeName; |
| |
| public ConditionWhenTypeAssignableTo(String assignableToTypeName) { |
| this.assignableToTypeName = assignableToTypeName; |
| } |
| |
| public String getAssignableToTypeName() { |
| return assignableToTypeName; |
| } |
| |
| @Override |
| public String toString() { |
| return "<when-assignable class='" + assignableToTypeName + "'/>"; |
| } |
| |
| @Override |
| protected boolean doEval(TreeLogger logger, DeferredBindingQuery query) |
| throws UnableToCompleteException { |
| TypeOracle typeOracle = query.getTypeOracle(); |
| String testType = query.getTestType(); |
| JClassType fromType = typeOracle.findType(testType); |
| if (fromType == null) { |
| CompilationProblemReporter.logMissingTypeErrorWithHints(logger, testType, |
| query.getCompilationState()); |
| throw new UnableToCompleteException(); |
| } |
| |
| JClassType toType = typeOracle.findType(assignableToTypeName); |
| if (toType == null) { |
| // If we don't know the type, it can't be assignable to it. |
| // This isn't a strict failure case because stale rules can reference |
| // types that have been deleted. |
| // |
| TreeLogger.Type level = TreeLogger.WARN; |
| if (shouldSuppressWarning(logger, assignableToTypeName)) { |
| // Suppress validation related errors |
| level = TreeLogger.DEBUG; |
| } |
| logger.log(level, "Unknown type '" + assignableToTypeName |
| + "' specified in deferred binding rule", null); |
| return false; |
| } |
| |
| if (fromType.isAssignableTo(toType)) { |
| return true; |
| } else { |
| return false; |
| } |
| } |
| |
| @Override |
| protected String getEvalAfterMessage(String testType, boolean result) { |
| if (result) { |
| return "Yes, the requested type was assignable"; |
| } else { |
| return "No, the requested type was not assignable"; |
| } |
| } |
| |
| @Override |
| protected String getEvalBeforeMessage(String testType) { |
| return toString(); |
| } |
| |
| /** |
| * Suppress multiple validation related messages and replace with a hint. |
| * |
| * @param typeName fully qualified type name to check for filtering |
| */ |
| // TODO(zundel): Can be removed when javax.validation is included in the JRE |
| private boolean shouldSuppressWarning(TreeLogger logger, String typeName) { |
| if (typeName.startsWith("javax.validation.") |
| || typeName.startsWith("com.google.gwt.validation.") |
| || typeName.startsWith("com.google.gwt.editor.client")) { |
| if (!warnedMissingValidationJar) { |
| warnedMissingValidationJar = true; |
| logger.log(TreeLogger.WARN, "Detected warnings related to '" + typeName + "'. " |
| + " Are validation-api-<version>.jar and validation-api-<version>-sources.jar on the classpath?"); |
| logger.log(TreeLogger.INFO, "Specify -logLevel DEBUG to see all errors."); |
| // Show the first error that matches |
| return false; |
| } |
| // Suppress subsequent errors that match |
| return true; |
| } |
| return false; |
| } |
| } |