001/* 002 * Copyright (c) 2012-2021 Institut National des Sciences Appliquées de Lyon (INSA Lyon) and others 003 * 004 * This program and the accompanying materials are made available under the 005 * terms of the Eclipse Public License 2.0 which is available at 006 * http://www.eclipse.org/legal/epl-2.0. 007 * 008 * SPDX-License-Identifier: EPL-2.0 009 */ 010 011package gololang.ir; 012 013import org.eclipse.golo.compiler.PackageAndClass; 014 015/** 016 * An import of a Golo or Java module, class or package. 017 * 018 * <p>Represents golo code such as 019 * <pre class="listing"><code class="lang-golo" data-lang="golo"> 020 * import java.util.Collections 021 * </code></pre> 022 */ 023public final class ModuleImport extends GoloElement<ModuleImport> implements ToplevelGoloElement { 024 025 private final PackageAndClass packageAndClass; 026 private final boolean implicit; 027 028 private ModuleImport(PackageAndClass packageAndClass, boolean implicit) { 029 super(); 030 this.packageAndClass = packageAndClass; 031 this.implicit = implicit; 032 } 033 034 /** 035 * Create an implicit module import. 036 * 037 * <p> 038 * Implicit imports are ones automatically added to a module, contrary to ones added by the developer. 039 * If the given name is already a module import, it is returned unchanged if already implicit; a new one is created 040 * otherwise. 041 * The name to import is derived using {@link PackageAndClass#of(Object)}. 042 */ 043 public static ModuleImport implicit(Object name) { 044 if (name instanceof ModuleImport) { 045 ModuleImport mod = (ModuleImport) name; 046 if (mod.implicit) { 047 return mod; 048 } 049 return new ModuleImport(mod.packageAndClass, true); 050 } 051 return new ModuleImport(PackageAndClass.of(name), true); 052 } 053 054 /** 055 * Create a module import. 056 * 057 * <p> 058 * If the given name is already a module import, it is returned unchanged. 059 * The name to import is derived using {@link PackageAndClass#of(Object)}. 060 */ 061 public static ModuleImport of(Object name) { 062 if (name instanceof ModuleImport) { 063 return (ModuleImport) name; 064 } 065 return new ModuleImport(PackageAndClass.of(name), false); 066 } 067 068 protected ModuleImport self() { return this; } 069 070 /** 071 * Returns the {@link PackageAndClass} of the module to be imported. 072 */ 073 public PackageAndClass getPackageAndClass() { 074 return packageAndClass; 075 } 076 077 /** 078 * Checks if this import is implicit. 079 * <p> 080 * Implicit imports are ones automatically added to a module, contrary to ones added by the developer. 081 */ 082 public boolean isImplicit() { 083 return this.implicit; 084 } 085 086 /** 087 * {@inheritDoc} 088 */ 089 @Override 090 public String toString() { 091 return "ModuleImport{" 092 + "packageAndClass=" + packageAndClass 093 + (implicit ? ", implicit" : "") 094 + '}'; 095 } 096 097 /** 098 * {@inheritDoc} 099 * <p> 100 * Equality ignores the implicit status. 101 * Therefore, adding explicitly a import that is already implicit is a noop. 102 */ 103 @Override 104 public boolean equals(Object o) { 105 if (this == o) { return true; } 106 if (o == null || getClass() != o.getClass()) { return false; } 107 108 ModuleImport that = (ModuleImport) o; 109 return packageAndClass.equals(that.packageAndClass); 110 } 111 112 /** 113 * {@inheritDoc} 114 */ 115 @Override 116 public int hashCode() { 117 return packageAndClass.hashCode(); 118 } 119 120 /** 121 * {@inheritDoc} 122 */ 123 @Override 124 public void accept(GoloIrVisitor visitor) { 125 visitor.visitModuleImport(this); 126 } 127 128 /** 129 * {@inheritDoc} 130 */ 131 @Override 132 protected void replaceElement(GoloElement<?> original, GoloElement<?> newElement) { 133 throw cantReplace(); 134 } 135}