< prev index next >

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/InferenceContext.java

Print this page


   1 /*
   2  * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.tools.javac.comp;
  27 
  28 import java.util.Collections;
  29 import java.util.EnumSet;
  30 import java.util.HashMap;
  31 import java.util.HashSet;
  32 import java.util.LinkedHashMap;
  33 import java.util.LinkedHashSet;
  34 import java.util.Map;
  35 import java.util.Set;
  36 
  37 import com.sun.tools.javac.code.Type;
  38 import com.sun.tools.javac.code.Type.ArrayType;
  39 import com.sun.tools.javac.code.Type.ClassType;
  40 import com.sun.tools.javac.code.Type.TypeVar;
  41 import com.sun.tools.javac.code.Type.UndetVar;
  42 import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
  43 import com.sun.tools.javac.code.Type.WildcardType;
  44 import com.sun.tools.javac.code.TypeTag;
  45 import com.sun.tools.javac.code.Types;
  46 import com.sun.tools.javac.comp.Infer.FreeTypeListener;
  47 import com.sun.tools.javac.comp.Infer.GraphSolver;
  48 import com.sun.tools.javac.comp.Infer.GraphStrategy;
  49 import com.sun.tools.javac.comp.Infer.InferenceException;
  50 import com.sun.tools.javac.comp.Infer.InferenceStep;
  51 import com.sun.tools.javac.tree.JCTree;
  52 import com.sun.tools.javac.util.Assert;
  53 import com.sun.tools.javac.util.Filter;


 350         //compute new undet variables (bounds associated to redundant variables are dropped)
 351         ListBuffer<Type> minUndetVars = new ListBuffer<>();
 352         for (Type minVar : minVars) {
 353             UndetVar uv = (UndetVar)asUndetVar(minVar);
 354             Assert.check(uv.incorporationActions.isEmpty());
 355             UndetVar uv2 = uv.dup(types);
 356             for (InferenceBound ib : InferenceBound.values()) {
 357                 List<Type> newBounds = uv.getBounds(ib).stream()
 358                         .filter(b -> !redundantVars.contains(b))
 359                         .collect(List.collector());
 360                 uv2.setBounds(ib, newBounds);
 361             }
 362             minUndetVars.add(uv2);
 363         }
 364 
 365         //compute new minimal inference context
 366         InferenceContext minContext = new InferenceContext(infer, minVars, minUndetVars.toList());
 367         for (Type t : minContext.inferencevars) {
 368             //add listener that forwards notifications to original context
 369             minContext.addFreeTypeListener(List.of(t), (inferenceContext) -> {
 370                 Type instType = inferenceContext.asInstType(t);
 371                 for (Type eq : rv.minMap.get(t)) {
 372                     ((UndetVar)asUndetVar(eq)).setInst(instType);
 373                 }
 374                 infer.doIncorporation(this, warn);
 375                 notifyChange();
 376             });
 377         }
 378         if (shouldSolve) {
 379             //solve definitively unreachable variables
 380             List<Type> unreachableVars = redundantVars.diff(List.from(rv.equiv));
 381             minContext.addFreeTypeListener(minVars, (inferenceContext) -> {
 382                 solve(unreachableVars, warn);
 383                 notifyChange();
 384             });
 385         }
 386         return minContext;
 387     }
 388 
 389     class ReachabilityVisitor extends Types.UnaryVisitor<Void> {
 390 
 391         Set<Type> equiv = new LinkedHashSet<>();
 392         Set<Type> min = new LinkedHashSet<>();
 393         Map<Type, Set<Type>> minMap = new LinkedHashMap<>();
 394 
 395         void scan(List<Type> roots) {
 396             roots.stream().forEach(this::visit);
 397         }
 398 
 399         @Override
 400         public Void visitType(Type t, Void _unused) {
 401             return null;
 402         }
 403 
 404         @Override
 405         public Void visitUndetVar(UndetVar t, Void _unused) {
 406             if (min.add(t.qtype)) {
 407                 Set<Type> deps = minMap.getOrDefault(t.qtype, new LinkedHashSet<>(Collections.singleton(t.qtype)));
 408                 for (InferenceBound boundKind : InferenceBound.values()) {
 409                     for (Type b : t.getBounds(boundKind)) {
 410                         Type undet = asUndetVar(b);
 411                         if (!undet.hasTag(TypeTag.UNDETVAR)) {
 412                             visit(undet);
 413                         } else if (isEquiv(t, b, boundKind)) {
 414                             deps.add(b);
 415                             equiv.add(b);
 416                         } else {
 417                             visit(undet);
 418                         }
 419                     }
 420                 }
 421                 minMap.put(t.qtype, deps);
 422             }
 423             return null;
 424         }
 425 
 426         @Override
 427         public Void visitWildcardType(WildcardType t, Void _unused) {


   1 /*
   2  * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.tools.javac.comp;
  27 
  28 import java.util.Collections;
  29 import java.util.EnumSet;
  30 import java.util.HashMap;
  31 import java.util.HashSet;
  32 import java.util.LinkedHashMap;

  33 import java.util.Map;
  34 import java.util.Set;
  35 
  36 import com.sun.tools.javac.code.Type;
  37 import com.sun.tools.javac.code.Type.ArrayType;
  38 import com.sun.tools.javac.code.Type.ClassType;
  39 import com.sun.tools.javac.code.Type.TypeVar;
  40 import com.sun.tools.javac.code.Type.UndetVar;
  41 import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
  42 import com.sun.tools.javac.code.Type.WildcardType;
  43 import com.sun.tools.javac.code.TypeTag;
  44 import com.sun.tools.javac.code.Types;
  45 import com.sun.tools.javac.comp.Infer.FreeTypeListener;
  46 import com.sun.tools.javac.comp.Infer.GraphSolver;
  47 import com.sun.tools.javac.comp.Infer.GraphStrategy;
  48 import com.sun.tools.javac.comp.Infer.InferenceException;
  49 import com.sun.tools.javac.comp.Infer.InferenceStep;
  50 import com.sun.tools.javac.tree.JCTree;
  51 import com.sun.tools.javac.util.Assert;
  52 import com.sun.tools.javac.util.Filter;


 349         //compute new undet variables (bounds associated to redundant variables are dropped)
 350         ListBuffer<Type> minUndetVars = new ListBuffer<>();
 351         for (Type minVar : minVars) {
 352             UndetVar uv = (UndetVar)asUndetVar(minVar);
 353             Assert.check(uv.incorporationActions.isEmpty());
 354             UndetVar uv2 = uv.dup(types);
 355             for (InferenceBound ib : InferenceBound.values()) {
 356                 List<Type> newBounds = uv.getBounds(ib).stream()
 357                         .filter(b -> !redundantVars.contains(b))
 358                         .collect(List.collector());
 359                 uv2.setBounds(ib, newBounds);
 360             }
 361             minUndetVars.add(uv2);
 362         }
 363 
 364         //compute new minimal inference context
 365         InferenceContext minContext = new InferenceContext(infer, minVars, minUndetVars.toList());
 366         for (Type t : minContext.inferencevars) {
 367             //add listener that forwards notifications to original context
 368             minContext.addFreeTypeListener(List.of(t), (inferenceContext) -> {
 369                 ((UndetVar)asUndetVar(t)).setInst(inferenceContext.asInstType(t));
 370                 infer.doIncorporation(inferenceContext, warn);
 371                 solve(List.from(rv.minMap.get(t)), warn);


 372                 notifyChange();
 373             });
 374         }
 375         if (shouldSolve) {
 376             //solve definitively unreachable variables
 377             List<Type> unreachableVars = redundantVars.diff(List.from(rv.equiv));
 378             minContext.addFreeTypeListener(minVars, (inferenceContext) -> {
 379                 solve(unreachableVars, warn);
 380                 notifyChange();
 381             });
 382         }
 383         return minContext;
 384     }
 385 
 386     class ReachabilityVisitor extends Types.UnaryVisitor<Void> {
 387 
 388         Set<Type> equiv = new HashSet<>();
 389         Set<Type> min = new HashSet<>();
 390         Map<Type, Set<Type>> minMap = new HashMap<>();
 391 
 392         void scan(List<Type> roots) {
 393             roots.stream().forEach(this::visit);
 394         }
 395 
 396         @Override
 397         public Void visitType(Type t, Void _unused) {
 398             return null;
 399         }
 400 
 401         @Override
 402         public Void visitUndetVar(UndetVar t, Void _unused) {
 403             if (min.add(t.qtype)) {
 404                 Set<Type> deps = minMap.getOrDefault(t.qtype, new HashSet<>(Collections.singleton(t.qtype)));
 405                 for (InferenceBound boundKind : InferenceBound.values()) {
 406                     for (Type b : t.getBounds(boundKind)) {
 407                         Type undet = asUndetVar(b);
 408                         if (!undet.hasTag(TypeTag.UNDETVAR)) {
 409                             visit(undet);
 410                         } else if (isEquiv(t, b, boundKind)) {
 411                             deps.add(b);
 412                             equiv.add(b);
 413                         } else {
 414                             visit(undet);
 415                         }
 416                     }
 417                 }
 418                 minMap.put(t.qtype, deps);
 419             }
 420             return null;
 421         }
 422 
 423         @Override
 424         public Void visitWildcardType(WildcardType t, Void _unused) {


< prev index next >