├── .classpath ├── .gitattributes ├── .gitignore ├── .project ├── .settings ├── org.eclipse.jdt.core.prefs └── org.eclipse.jdt.ui.prefs ├── LICENSE ├── README.md ├── build.properties ├── build.xml ├── lib └── junit-4.9b2.jar ├── src └── com │ └── redhat │ └── ceylon │ └── model │ ├── cmr │ ├── ArtifactResult.java │ ├── ArtifactResultType.java │ ├── ImportType.java │ ├── JDKUtils.java │ ├── PathFilter.java │ ├── Repository.java │ ├── RepositoryException.java │ ├── VisibilityType.java │ ├── package-list.jdk7 │ ├── package-list.jdk8 │ ├── package-list.oracle.jdk7 │ └── package-list.oracle.jdk8 │ ├── loader │ ├── AbstractModelLoader.java │ ├── ContentAwareArtifactResult.java │ ├── JvmBackendUtil.java │ ├── LanguageAnnotation.java │ ├── LoaderJULLogger.java │ ├── ModelCompleter.java │ ├── ModelLoader.java │ ├── ModelResolutionException.java │ ├── NamingBase.java │ ├── ParameterNameLexer.java │ ├── ParameterNameParser.java │ ├── ParameterNameParserException.java │ ├── SimpleReflType.java │ ├── Timer.java │ ├── TypeLexer.java │ ├── TypeParser.java │ ├── TypeParserException.java │ ├── impl │ │ └── reflect │ │ │ ├── CachedTOCJars.java │ │ │ ├── ReflectionModelLoader.java │ │ │ ├── mirror │ │ │ ├── ReflectionAnnotation.java │ │ │ ├── ReflectionClass.java │ │ │ ├── ReflectionField.java │ │ │ ├── ReflectionMethod.java │ │ │ ├── ReflectionPackage.java │ │ │ ├── ReflectionType.java │ │ │ ├── ReflectionTypeParameter.java │ │ │ ├── ReflectionUtils.java │ │ │ └── ReflectionVariable.java │ │ │ └── model │ │ │ ├── ReflectionModule.java │ │ │ └── ReflectionModuleManager.java │ ├── mirror │ │ ├── AccessibleMirror.java │ │ ├── AnnotatedMirror.java │ │ ├── AnnotationMirror.java │ │ ├── ClassMirror.java │ │ ├── FieldMirror.java │ │ ├── MethodMirror.java │ │ ├── PackageMirror.java │ │ ├── TypeMirror.java │ │ ├── TypeParameterMirror.java │ │ └── VariableMirror.java │ └── model │ │ ├── AnnotationProxyClass.java │ │ ├── AnnotationProxyMethod.java │ │ ├── AnnotationTarget.java │ │ ├── FieldValue.java │ │ ├── FunctionOrValueInterface.java │ │ ├── JavaBeanValue.java │ │ ├── JavaMethod.java │ │ ├── LazyClass.java │ │ ├── LazyClassAlias.java │ │ ├── LazyContainer.java │ │ ├── LazyElement.java │ │ ├── LazyFunction.java │ │ ├── LazyInterface.java │ │ ├── LazyInterfaceAlias.java │ │ ├── LazyModule.java │ │ ├── LazyModuleManager.java │ │ ├── LazyPackage.java │ │ ├── LazyTypeAlias.java │ │ ├── LazyValue.java │ │ ├── LocalDeclarationContainer.java │ │ ├── OutputElement.java │ │ └── SetterWithLocalDeclarations.java │ └── typechecker │ ├── context │ └── TypeCache.java │ ├── model │ ├── Annotated.java │ ├── Annotation.java │ ├── Class.java │ ├── ClassAlias.java │ ├── ClassOrInterface.java │ ├── ConditionScope.java │ ├── Constructor.java │ ├── ControlBlock.java │ ├── DecidabilityException.java │ ├── Declaration.java │ ├── DeclarationCompleter.java │ ├── DeclarationKind.java │ ├── DeclarationWithProximity.java │ ├── Element.java │ ├── ExternalUnit.java │ ├── Function.java │ ├── FunctionOrValue.java │ ├── Functional.java │ ├── Generic.java │ ├── Getter.java │ ├── Import.java │ ├── ImportList.java │ ├── ImportableScope.java │ ├── Interface.java │ ├── InterfaceAlias.java │ ├── IntersectionType.java │ ├── LazyType.java │ ├── ModelUtil.java │ ├── Module.java │ ├── ModuleImport.java │ ├── Modules.java │ ├── NamedArgumentList.java │ ├── NothingType.java │ ├── Package.java │ ├── Parameter.java │ ├── ParameterList.java │ ├── Reference.java │ ├── Referenceable.java │ ├── Scope.java │ ├── Setter.java │ ├── SiteVariance.java │ ├── Specification.java │ ├── Type.java │ ├── TypeAlias.java │ ├── TypeDeclaration.java │ ├── TypeParameter.java │ ├── TypedDeclaration.java │ ├── TypedReference.java │ ├── UnionType.java │ ├── Unit.java │ ├── UnknownType.java │ └── Value.java │ └── util │ ├── ModuleManager.java │ └── TypePrinter.java └── test └── .ceylon └── config /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Always enforce LF line-endings for all text files 2 | * text eol=lf 3 | 4 | # Specific Windows text files 5 | *.bat text eol=crlf 6 | 7 | # Binary files 8 | *.jar binary 9 | *.car binary 10 | *.car.idx binary 11 | *.zip bibary 12 | *.png binary 13 | *.jpg binary 14 | *.gif binary 15 | 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | ceylon-model 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /.settings/org.eclipse.jdt.ui.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | formatter_profile=_ceylon 3 | formatter_settings_version=12 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | DEPRECATED 2 | ========== 3 | 4 | This project is deprecated go here instead: https://github.com/ceylon/ceylon 5 | -------------------------------------------------------------------------------- /build.properties: -------------------------------------------------------------------------------- 1 | 2 | # ----- JUnit Unit Test Suite, version 4.9 or later --- 3 | junit.version=4.9b2 4 | junit.jar=junit-${junit.version}.jar 5 | junit.url=http://cloud.github.com/downloads/KentBeck/junit/junit${junit.version}.zip 6 | junit.lib=${base.path}/${junit.jar} 7 | -------------------------------------------------------------------------------- /build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 161 | 162 | 163 | 164 | 165 | 166 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | -------------------------------------------------------------------------------- /lib/junit-4.9b2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ceylon/ceylon-model/420b5057259ffb4835866538dced2f7bc95ac1bf/lib/junit-4.9b2.jar -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/cmr/ArtifactResult.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.cmr; 2 | 3 | import java.io.File; 4 | import java.util.List; 5 | 6 | /** 7 | * Artifact result. 8 | * 9 | * @author Ales Justin 10 | */ 11 | public interface ArtifactResult { 12 | /** 13 | * Get name. 14 | * 15 | * @return the artifact name. 16 | */ 17 | String name(); 18 | 19 | /** 20 | * Get version. 21 | * 22 | * @return the version. 23 | */ 24 | String version(); 25 | 26 | /** 27 | * Get import type. 28 | * 29 | * @return the import type 30 | */ 31 | ImportType importType(); 32 | 33 | /** 34 | * The result type. 35 | * 36 | * @return the type 37 | */ 38 | ArtifactResultType type(); 39 | 40 | /** 41 | * Get visibility type. 42 | * 43 | * @return visibility type 44 | */ 45 | VisibilityType visibilityType(); 46 | 47 | /** 48 | * The requested artifact. 49 | * 50 | * @return the requested artifact 51 | * @throws RepositoryException for any I/O error 52 | */ 53 | File artifact() throws RepositoryException; 54 | 55 | /** 56 | * The resources filter. 57 | * 58 | * @return the path filter or null if there is none 59 | */ 60 | PathFilter filter(); 61 | 62 | /** 63 | * Dependencies. 64 | *

65 | * They could be lazily recursively fetched 66 | * or they could be fetched in one go. 67 | * 68 | * @return dependencies, empty list if none 69 | * @throws RepositoryException for any I/O error 70 | */ 71 | List dependencies() throws RepositoryException; 72 | 73 | /** 74 | * Get the display string of the repository this 75 | * result comes from 76 | * 77 | * @return the repository display string. 78 | */ 79 | String repositoryDisplayString(); 80 | 81 | /** 82 | * Get the repository this result was resolved from. 83 | * 84 | * @return the repository this result was resolved from. 85 | */ 86 | Repository repository(); 87 | } 88 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/cmr/ArtifactResultType.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.cmr; 2 | 3 | /** 4 | * Artifact result type. 5 | * 6 | * @author Ales Justin 7 | */ 8 | public enum ArtifactResultType { 9 | CEYLON, 10 | MAVEN, 11 | OTHER 12 | } 13 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/cmr/ImportType.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.cmr; 2 | 3 | /** 4 | * ImportType type. 5 | * 6 | * @author Ales Justin 7 | */ 8 | public enum ImportType { 9 | UNDEFINED, 10 | OPTIONAL, 11 | EXPORT 12 | } 13 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/cmr/PathFilter.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.cmr; 2 | 3 | /** 4 | * Filter used to determine whether a path should be included or excluded from imports and exports. 5 | * 6 | * @author John Bailey 7 | * @author Ales Justin 8 | */ 9 | public interface PathFilter { 10 | 11 | /** 12 | * Determine whether a path should be accepted. The given name is a path separated 13 | * by "{@code /}" characters. 14 | * 15 | * @param path the path to check 16 | * @return true if the path should be accepted, false if not 17 | */ 18 | boolean accept(String path); 19 | } -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/cmr/Repository.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.cmr; 2 | 3 | /** 4 | * Abstraction over the CMR Repository type 5 | * 6 | * @author Stéphane Épardaud 7 | */ 8 | public interface Repository { 9 | /** 10 | * Returns a display string that represents this Repository 11 | */ 12 | String getDisplayString(); 13 | 14 | /** 15 | * Return true if this is a Maven repo 16 | */ 17 | boolean isMaven(); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/cmr/RepositoryException.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.cmr; 2 | 3 | /** 4 | * Wrap any exception into this runtime exception. 5 | * 6 | * @author Ales Justin 7 | */ 8 | @SuppressWarnings("serial") 9 | public class RepositoryException extends RuntimeException { 10 | public RepositoryException(String message) { 11 | super(message); 12 | } 13 | 14 | public RepositoryException(String message, Throwable cause) { 15 | super(message, cause); 16 | } 17 | 18 | public RepositoryException(Throwable cause) { 19 | super(cause); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/cmr/VisibilityType.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.cmr; 2 | 3 | /** 4 | * Visibility type. 5 | * 6 | * @author Ales Justin 7 | */ 8 | public enum VisibilityType { 9 | STRICT, // all deps must be explicity declared; even JDK paths 10 | LOOSE 11 | } 12 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/cmr/package-list.jdk7: -------------------------------------------------------------------------------- 1 | # List of JDK modules as currently defined in Jigsaw at 2 | # http://hg.openjdk.java.net/jigsaw/jigsaw/jdk/file/e3ad33822fa3/make/modules/modules.config 3 | # for the package-granularity, and 4 | # http://hg.openjdk.java.net/jigsaw/jigsaw/jdk/file/e3ad33822fa3/make/modules/modules.group 5 | # for the module names. 6 | # 7 | # oracle/sun APIs have been excluded from those modules for now, perhaps this is wrong. 8 | # 9 | # Syntax: 10 | # 11 | # - lines that start with a '#' are comments and are ignored 12 | # - lines that are only whitespace are ignored 13 | # - lines that start with a '=' define the start of a new module name 14 | # - other lines are package names that belong to the current module 15 | 16 | =java.base 17 | java.lang 18 | java.lang.annotation 19 | java.lang.ref 20 | java.lang.reflect 21 | java.math 22 | # Jigsaw excludes java.net.SecureCacheResponse which is in security-jsse 23 | java.net 24 | java.util 25 | java.util.concurrent 26 | java.util.concurrent.atomic 27 | java.util.concurrent.locks 28 | # Jigsaw excludes Pack200 29 | java.util.jar 30 | java.util.regex 31 | java.util.spi 32 | java.util.zip 33 | java.text 34 | java.text.spi 35 | java.lang.invoke 36 | java.io 37 | java.nio 38 | java.nio.channels 39 | java.nio.channels.spi 40 | java.nio.charset 41 | java.nio.charset.spi 42 | java.nio.file 43 | java.nio.file.attribute 44 | java.nio.file.spi 45 | java.security 46 | java.security.cert 47 | java.security.interfaces 48 | java.security.spec 49 | javax.security.auth 50 | javax.security.auth.callback 51 | javax.security.auth.login 52 | javax.security.auth.spi 53 | javax.security.auth.x500 54 | javax.crypto 55 | javax.crypto.interfaces 56 | javax.crypto.spec 57 | # java.beans is only included partially in Jigsaw 58 | java.beans 59 | java.beans.beancontext 60 | 61 | =java.logging 62 | java.util.logging 63 | 64 | =java.management 65 | java.lang.management 66 | javax.management 67 | javax.management.loading 68 | javax.management.modelmbean 69 | javax.management.monitor 70 | javax.management.openmbean 71 | javax.management.relation 72 | javax.management.remote 73 | javax.management.remote.rmi 74 | javax.management.timer 75 | 76 | =java.instrument 77 | java.lang.instrument 78 | 79 | =java.rmi 80 | java.rmi 81 | java.rmi.activation 82 | java.rmi.dgc 83 | java.rmi.registry 84 | java.rmi.server 85 | javax.rmi.ssl 86 | 87 | =java.prefs 88 | java.util.prefs 89 | 90 | # aka security-jsse 91 | =java.tls 92 | javax.net 93 | javax.net.ssl 94 | javax.security.cert 95 | 96 | # aka security-kerberos 97 | =java.auth.kerberos 98 | javax.security.auth.kerberos 99 | org.ietf.jgss 100 | 101 | # aka security-sasl 102 | =java.auth 103 | javax.security.sasl 104 | 105 | # aka security-xmldsig 106 | =javax.xmldsig 107 | javax.xml.crypto 108 | javax.xml.crypto.dom 109 | javax.xml.crypto.dsig 110 | javax.xml.crypto.dsig.dom 111 | javax.xml.crypto.dsig.keyinfo 112 | javax.xml.crypto.dsig.spec 113 | # Seems we're missing org.jcp.xml.dsig, not sure why 114 | 115 | # aka security-acl 116 | =java.security.acl 117 | java.security.acl 118 | 119 | # aka jndi-ldap and jndi 120 | =javax.naming 121 | javax.naming.ldap 122 | javax.naming 123 | javax.naming.directory 124 | javax.naming.event 125 | javax.naming.spi 126 | # seems this includes javax.naming.ldap as well, from jndi-ldap, but it must be a bug in Jigsaw? 127 | 128 | # aka jta 129 | =javax.transaction 130 | javax.transaction 131 | javax.transaction.xa 132 | 133 | =java.jdbc 134 | java.sql 135 | javax.sql 136 | 137 | =java.jdbc.rowset 138 | javax.sql.rowset 139 | javax.sql.rowset.serial 140 | javax.sql.rowset.spi 141 | 142 | # aka scripting 143 | =javax.script 144 | javax.script 145 | 146 | =javax.xml 147 | javax.xml 148 | javax.xml.datatype 149 | javax.xml.namespace 150 | javax.xml.parsers 151 | javax.xml.stream 152 | javax.xml.stream.events 153 | javax.xml.stream.util 154 | javax.xml.transform 155 | javax.xml.transform.dom 156 | javax.xml.transform.sax 157 | javax.xml.transform.stax 158 | javax.xml.transform.stream 159 | javax.xml.validation 160 | javax.xml.xpath 161 | org.w3c.dom 162 | org.w3c.dom.bootstrap 163 | org.w3c.dom.events 164 | org.w3c.dom.ls 165 | org.xml.sax 166 | org.xml.sax.ext 167 | org.xml.sax.helpers 168 | 169 | =javax.jaxws 170 | javax.jws 171 | javax.jws.soap 172 | javax.xml.bind 173 | javax.xml.bind.annotation 174 | javax.xml.bind.annotation.adapters 175 | javax.xml.bind.attachment 176 | javax.xml.bind.helpers 177 | javax.xml.bind.util 178 | javax.xml.soap 179 | javax.xml.ws 180 | javax.xml.ws.handler 181 | javax.xml.ws.handler.soap 182 | javax.xml.ws.http 183 | javax.xml.ws.soap 184 | javax.xml.ws.spi 185 | javax.xml.ws.spi.http 186 | javax.xml.ws.wsaddressing 187 | javax.activation 188 | 189 | =javax.annotation 190 | javax.annotation 191 | 192 | =java.corba 193 | javax.activity 194 | javax.rmi 195 | javax.rmi.CORBA 196 | org.omg.CORBA 197 | org.omg.CORBA.DynAnyPackage 198 | org.omg.CORBA.ORBPackage 199 | org.omg.CORBA.TypeCodePackage 200 | org.omg.CORBA.portable 201 | org.omg.CORBA_2_3 202 | org.omg.CORBA_2_3.portable 203 | org.omg.CosNaming 204 | org.omg.CosNaming.NamingContextExtPackage 205 | org.omg.CosNaming.NamingContextPackage 206 | org.omg.Dynamic 207 | org.omg.DynamicAny 208 | org.omg.DynamicAny.DynAnyFactoryPackage 209 | org.omg.DynamicAny.DynAnyPackage 210 | org.omg.IOP 211 | org.omg.IOP.CodecFactoryPackage 212 | org.omg.IOP.CodecPackage 213 | org.omg.Messaging 214 | org.omg.PortableInterceptor 215 | org.omg.PortableInterceptor.ORBInitInfoPackage 216 | org.omg.PortableServer 217 | org.omg.PortableServer.CurrentPackage 218 | org.omg.PortableServer.POAManagerPackage 219 | org.omg.PortableServer.POAPackage 220 | org.omg.PortableServer.ServantLocatorPackage 221 | org.omg.PortableServer.portable 222 | org.omg.SendingContext 223 | org.omg.stub.java.rmi 224 | 225 | # That one consists in beans, client and applet. But beans is in base for us, because we don't 226 | # do partial package modules, and client consists in awt, imageio, print, sound and swing with 227 | # accessibility 228 | =java.desktop 229 | #applet 230 | java.applet 231 | #client 232 | # awt 233 | java.awt 234 | java.awt.color 235 | java.awt.datatransfer 236 | java.awt.dnd 237 | java.awt.event 238 | java.awt.font 239 | java.awt.geom 240 | java.awt.im 241 | java.awt.im.spi 242 | java.awt.image 243 | java.awt.image.renderable 244 | java.awt.print 245 | # imageio 246 | javax.imageio 247 | javax.imageio.event 248 | javax.imageio.metadata 249 | javax.imageio.plugins.bmp 250 | javax.imageio.plugins.jpeg 251 | javax.imageio.spi 252 | javax.imageio.stream 253 | # print 254 | javax.print 255 | javax.print.attribute 256 | javax.print.attribute.standard 257 | javax.print.event 258 | # sound 259 | javax.sound.midi 260 | javax.sound.midi.spi 261 | javax.sound.sampled 262 | javax.sound.sampled.spi 263 | # swing 264 | javax.swing 265 | javax.swing.border 266 | javax.swing.colorchooser 267 | javax.swing.event 268 | javax.swing.filechooser 269 | javax.swing.plaf 270 | javax.swing.plaf.basic 271 | javax.swing.plaf.basic.icons 272 | javax.swing.plaf.metal 273 | javax.swing.plaf.metal.icons 274 | javax.swing.plaf.metal.icons.ocean 275 | javax.swing.plaf.metal.sounds 276 | javax.swing.plaf.multi 277 | javax.swing.plaf.multi.doc-files 278 | javax.swing.plaf.nimbus 279 | javax.swing.plaf.nimbus.doc-files 280 | javax.swing.plaf.synth 281 | javax.swing.plaf.synth.doc-files 282 | javax.swing.table 283 | javax.swing.text 284 | javax.swing.text.html 285 | javax.swing.text.html.parser 286 | javax.swing.text.rtf 287 | javax.swing.tree 288 | javax.swing.undo 289 | # accessibility 290 | javax.accessibility 291 | 292 | =java.compiler 293 | javax.tools 294 | javax.lang.model 295 | javax.lang.model.element 296 | javax.lang.model.type 297 | javax.lang.model.util 298 | javax.annotation.processing 299 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/cmr/package-list.jdk8: -------------------------------------------------------------------------------- 1 | # List of JDK modules as guessed from package-list.jdk7 + new packages in Java 8: 2 | # 3 | # (added to java.base) 4 | # java.util.function 5 | # java.util.stream 6 | # java.time 7 | # java.time.chrono 8 | # java.time.format 9 | # java.time.temporal 10 | # java.time.zone 11 | # 12 | # (added to javax.xml) 13 | # org.w3c.dom.views 14 | # 15 | # see package-list.jdk7 for syntax and origin 16 | 17 | =java.base 18 | java.lang 19 | java.lang.annotation 20 | java.lang.ref 21 | java.lang.reflect 22 | java.math 23 | # Jigsaw excludes java.net.SecureCacheResponse which is in security-jsse 24 | java.net 25 | java.util 26 | java.util.concurrent 27 | java.util.concurrent.atomic 28 | java.util.concurrent.locks 29 | # Jigsaw excludes Pack200 30 | java.util.function 31 | java.util.jar 32 | java.util.regex 33 | java.util.spi 34 | java.util.stream 35 | java.util.zip 36 | java.text 37 | java.text.spi 38 | java.lang.invoke 39 | java.io 40 | java.nio 41 | java.nio.channels 42 | java.nio.channels.spi 43 | java.nio.charset 44 | java.nio.charset.spi 45 | java.nio.file 46 | java.nio.file.attribute 47 | java.nio.file.spi 48 | java.security 49 | java.security.cert 50 | java.security.interfaces 51 | java.security.spec 52 | javax.security.auth 53 | javax.security.auth.callback 54 | javax.security.auth.login 55 | javax.security.auth.spi 56 | javax.security.auth.x500 57 | javax.crypto 58 | javax.crypto.interfaces 59 | javax.crypto.spec 60 | # java.beans is only included partially in Jigsaw 61 | java.beans 62 | java.beans.beancontext 63 | java.time 64 | java.time.chrono 65 | java.time.format 66 | java.time.temporal 67 | java.time.zone 68 | 69 | =java.logging 70 | java.util.logging 71 | 72 | =java.management 73 | java.lang.management 74 | javax.management 75 | javax.management.loading 76 | javax.management.modelmbean 77 | javax.management.monitor 78 | javax.management.openmbean 79 | javax.management.relation 80 | javax.management.remote 81 | javax.management.remote.rmi 82 | javax.management.timer 83 | 84 | =java.instrument 85 | java.lang.instrument 86 | 87 | =java.rmi 88 | java.rmi 89 | java.rmi.activation 90 | java.rmi.dgc 91 | java.rmi.registry 92 | java.rmi.server 93 | javax.rmi.ssl 94 | 95 | =java.prefs 96 | java.util.prefs 97 | 98 | # aka security-jsse 99 | =java.tls 100 | javax.net 101 | javax.net.ssl 102 | javax.security.cert 103 | 104 | # aka security-kerberos 105 | =java.auth.kerberos 106 | javax.security.auth.kerberos 107 | org.ietf.jgss 108 | 109 | # aka security-sasl 110 | =java.auth 111 | javax.security.sasl 112 | 113 | # aka security-xmldsig 114 | =javax.xmldsig 115 | javax.xml.crypto 116 | javax.xml.crypto.dom 117 | javax.xml.crypto.dsig 118 | javax.xml.crypto.dsig.dom 119 | javax.xml.crypto.dsig.keyinfo 120 | javax.xml.crypto.dsig.spec 121 | # Seems we're missing org.jcp.xml.dsig, not sure why 122 | 123 | # aka security-acl 124 | =java.security.acl 125 | java.security.acl 126 | 127 | # aka jndi-ldap and jndi 128 | =javax.naming 129 | javax.naming.ldap 130 | javax.naming 131 | javax.naming.directory 132 | javax.naming.event 133 | javax.naming.spi 134 | # seems this includes javax.naming.ldap as well, from jndi-ldap, but it must be a bug in Jigsaw? 135 | 136 | # aka jta 137 | =javax.transaction 138 | javax.transaction 139 | javax.transaction.xa 140 | 141 | =java.jdbc 142 | java.sql 143 | javax.sql 144 | 145 | =java.jdbc.rowset 146 | javax.sql.rowset 147 | javax.sql.rowset.serial 148 | javax.sql.rowset.spi 149 | 150 | # aka scripting 151 | =javax.script 152 | javax.script 153 | 154 | =javax.xml 155 | javax.xml 156 | javax.xml.datatype 157 | javax.xml.namespace 158 | javax.xml.parsers 159 | javax.xml.stream 160 | javax.xml.stream.events 161 | javax.xml.stream.util 162 | javax.xml.transform 163 | javax.xml.transform.dom 164 | javax.xml.transform.sax 165 | javax.xml.transform.stax 166 | javax.xml.transform.stream 167 | javax.xml.validation 168 | javax.xml.xpath 169 | org.w3c.dom 170 | org.w3c.dom.bootstrap 171 | org.w3c.dom.events 172 | org.w3c.dom.ls 173 | org.w3c.dom.views 174 | org.xml.sax 175 | org.xml.sax.ext 176 | org.xml.sax.helpers 177 | 178 | =javax.jaxws 179 | javax.jws 180 | javax.jws.soap 181 | javax.xml.bind 182 | javax.xml.bind.annotation 183 | javax.xml.bind.annotation.adapters 184 | javax.xml.bind.attachment 185 | javax.xml.bind.helpers 186 | javax.xml.bind.util 187 | javax.xml.soap 188 | javax.xml.ws 189 | javax.xml.ws.handler 190 | javax.xml.ws.handler.soap 191 | javax.xml.ws.http 192 | javax.xml.ws.soap 193 | javax.xml.ws.spi 194 | javax.xml.ws.spi.http 195 | javax.xml.ws.wsaddressing 196 | javax.activation 197 | 198 | =javax.annotation 199 | javax.annotation 200 | 201 | =java.corba 202 | javax.activity 203 | javax.rmi 204 | javax.rmi.CORBA 205 | org.omg.CORBA 206 | org.omg.CORBA.DynAnyPackage 207 | org.omg.CORBA.ORBPackage 208 | org.omg.CORBA.TypeCodePackage 209 | org.omg.CORBA.portable 210 | org.omg.CORBA_2_3 211 | org.omg.CORBA_2_3.portable 212 | org.omg.CosNaming 213 | org.omg.CosNaming.NamingContextExtPackage 214 | org.omg.CosNaming.NamingContextPackage 215 | org.omg.Dynamic 216 | org.omg.DynamicAny 217 | org.omg.DynamicAny.DynAnyFactoryPackage 218 | org.omg.DynamicAny.DynAnyPackage 219 | org.omg.IOP 220 | org.omg.IOP.CodecFactoryPackage 221 | org.omg.IOP.CodecPackage 222 | org.omg.Messaging 223 | org.omg.PortableInterceptor 224 | org.omg.PortableInterceptor.ORBInitInfoPackage 225 | org.omg.PortableServer 226 | org.omg.PortableServer.CurrentPackage 227 | org.omg.PortableServer.POAManagerPackage 228 | org.omg.PortableServer.POAPackage 229 | org.omg.PortableServer.ServantLocatorPackage 230 | org.omg.PortableServer.portable 231 | org.omg.SendingContext 232 | org.omg.stub.java.rmi 233 | 234 | # That one consists in beans, client and applet. But beans is in base for us, because we don't 235 | # do partial package modules, and client consists in awt, imageio, print, sound and swing with 236 | # accessibility 237 | =java.desktop 238 | #applet 239 | java.applet 240 | #client 241 | # awt 242 | java.awt 243 | java.awt.color 244 | java.awt.datatransfer 245 | java.awt.dnd 246 | java.awt.event 247 | java.awt.font 248 | java.awt.geom 249 | java.awt.im 250 | java.awt.im.spi 251 | java.awt.image 252 | java.awt.image.renderable 253 | java.awt.print 254 | # imageio 255 | javax.imageio 256 | javax.imageio.event 257 | javax.imageio.metadata 258 | javax.imageio.plugins.bmp 259 | javax.imageio.plugins.jpeg 260 | javax.imageio.spi 261 | javax.imageio.stream 262 | # print 263 | javax.print 264 | javax.print.attribute 265 | javax.print.attribute.standard 266 | javax.print.event 267 | # sound 268 | javax.sound.midi 269 | javax.sound.midi.spi 270 | javax.sound.sampled 271 | javax.sound.sampled.spi 272 | # swing 273 | javax.swing 274 | javax.swing.border 275 | javax.swing.colorchooser 276 | javax.swing.event 277 | javax.swing.filechooser 278 | javax.swing.plaf 279 | javax.swing.plaf.basic 280 | javax.swing.plaf.basic.icons 281 | javax.swing.plaf.metal 282 | javax.swing.plaf.metal.icons 283 | javax.swing.plaf.metal.icons.ocean 284 | javax.swing.plaf.metal.sounds 285 | javax.swing.plaf.multi 286 | javax.swing.plaf.multi.doc-files 287 | javax.swing.plaf.nimbus 288 | javax.swing.plaf.nimbus.doc-files 289 | javax.swing.plaf.synth 290 | javax.swing.plaf.synth.doc-files 291 | javax.swing.table 292 | javax.swing.text 293 | javax.swing.text.html 294 | javax.swing.text.html.parser 295 | javax.swing.text.rtf 296 | javax.swing.tree 297 | javax.swing.undo 298 | # accessibility 299 | javax.accessibility 300 | 301 | =java.compiler 302 | javax.tools 303 | javax.lang.model 304 | javax.lang.model.element 305 | javax.lang.model.type 306 | javax.lang.model.util 307 | javax.annotation.processing 308 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/ContentAwareArtifactResult.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader; 2 | 3 | import java.net.URI; 4 | import java.util.Collection; 5 | import java.util.List; 6 | 7 | import com.redhat.ceylon.model.cmr.ArtifactResult; 8 | 9 | public interface ContentAwareArtifactResult extends ArtifactResult { 10 | Collection getPackages(); 11 | Collection getEntries(); 12 | byte[] getContents(String path); 13 | URI getContentUri(String path); 14 | List getFileNames(String path); 15 | } -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/LoaderJULLogger.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader; 2 | 3 | import com.redhat.ceylon.common.log.JULLogger; 4 | 5 | /** 6 | * Simple logger impl. 7 | * 8 | * @author Stephane Epardaud, Tako Schotanus 9 | */ 10 | public class LoaderJULLogger extends JULLogger { 11 | 12 | static java.util.logging.Logger log = java.util.logging.Logger.getLogger("com.redhat.ceylon.log.loader"); 13 | 14 | @Override 15 | protected java.util.logging.Logger logger() { 16 | return log; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/ModelCompleter.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader; 2 | 3 | import com.redhat.ceylon.model.loader.model.LazyClass; 4 | import com.redhat.ceylon.model.loader.model.LazyClassAlias; 5 | import com.redhat.ceylon.model.loader.model.LazyInterface; 6 | import com.redhat.ceylon.model.loader.model.LazyInterfaceAlias; 7 | import com.redhat.ceylon.model.loader.model.LazyFunction; 8 | import com.redhat.ceylon.model.loader.model.LazyTypeAlias; 9 | import com.redhat.ceylon.model.loader.model.LazyValue; 10 | 11 | /** 12 | * Represents something which can complete a model if needed. This is used because we load declarations lazily, 13 | * so we only fully load them when needed. 14 | * 15 | * @author Stéphane Épardaud 16 | */ 17 | public interface ModelCompleter { 18 | 19 | /** 20 | * Completes loading of a class 21 | */ 22 | void complete(LazyClass lazyClass); 23 | 24 | /** 25 | * Completes loading of a class's type parameters only 26 | */ 27 | void completeTypeParameters(LazyClass lazyClass); 28 | 29 | /** 30 | * Completes loading of an interface 31 | */ 32 | void complete(LazyInterface lazyInterface); 33 | 34 | /** 35 | * Completes loading of an interface's type parameters only 36 | */ 37 | void completeTypeParameters(LazyInterface lazyInterface); 38 | 39 | /** 40 | * Completes loading of a toplevel attribute 41 | */ 42 | void complete(LazyValue lazyValue); 43 | 44 | /** 45 | * Completes loading of a toplevel method 46 | */ 47 | void complete(LazyFunction lazyMethod); 48 | 49 | /** 50 | * Completes loading of a lazy class alias 51 | */ 52 | void complete(LazyClassAlias lazyClassAlias); 53 | 54 | /** 55 | * Completes loading of a lazy class alias's type parameters only 56 | */ 57 | void completeTypeParameters(LazyClassAlias lazyClassAlias); 58 | 59 | /** 60 | * Completes loading of a lazy interface alias 61 | */ 62 | void complete(LazyInterfaceAlias lazyInterfaceAlias); 63 | 64 | /** 65 | * Completes loading of a lazy interface alias's type parameters only 66 | */ 67 | void completeTypeParameters(LazyInterfaceAlias lazyInterfaceAlias); 68 | 69 | /** 70 | * Completes loading of a lazy type alias 71 | */ 72 | void complete(LazyTypeAlias lazyTypeAlias); 73 | 74 | /** 75 | * Completes loading of a lazy type alias's type parameters only 76 | */ 77 | void completeTypeParameters(LazyTypeAlias lazyTypeAlias); 78 | 79 | /** 80 | * Returns a lock we can use for thread-safety 81 | */ 82 | Object getLock(); 83 | } 84 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/ModelLoader.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader; 2 | 3 | import com.redhat.ceylon.model.typechecker.model.Declaration; 4 | import com.redhat.ceylon.model.typechecker.model.Module; 5 | import com.redhat.ceylon.model.typechecker.model.Type; 6 | import com.redhat.ceylon.model.typechecker.model.Scope; 7 | 8 | /** 9 | * Represents a ModelLoader's public API 10 | * 11 | * @author Stéphane Épardaud 12 | */ 13 | public interface ModelLoader { 14 | 15 | /** 16 | * The type of declaration we're looking for. This is useful for toplevel attributes and classes who 17 | * can share the same name (in the case of singletons). 18 | * 19 | * @author Stéphane Épardaud 20 | */ 21 | enum DeclarationType { 22 | /** 23 | * We're looking for a type 24 | */ 25 | TYPE, 26 | /** 27 | * We're looking for an attribute 28 | */ 29 | VALUE; 30 | } 31 | 32 | /** 33 | * Loads a declaration by name and type 34 | * 35 | * @param module the module to load it from 36 | * @param typeName the fully-qualified declaration name 37 | * @param declarationType the declaration type 38 | * @return the declaration, if found, or null. 39 | */ 40 | public Declaration getDeclaration(Module module, String typeName, DeclarationType declarationType); 41 | 42 | /** 43 | * Returns the Type of a name in a given scope 44 | 45 | * @param module the module to load it from 46 | * @param pkg the package name 47 | * @param name the fully-qualified name of the type 48 | * @param scope the scope in which to find it 49 | * @return the Type found 50 | */ 51 | public Type getType(Module module, String pkg, String name, Scope scope); 52 | 53 | /** 54 | * Returns the Declaration of a name in a given scope 55 | 56 | * @param module the module to load it from 57 | * @param pkg the package name 58 | * @param name the fully-qualified name of the type 59 | * @param scope the scope in which to find it 60 | * @return the Type found 61 | */ 62 | public Declaration getDeclaration(Module module, String pkg, String name, Scope scope); 63 | 64 | /** 65 | * Returns a loaded module by name and version 66 | * @return null if module is not already loaded 67 | */ 68 | public Module getLoadedModule(String moduleName, String version); 69 | } 70 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/ModelResolutionException.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader; 2 | 3 | @SuppressWarnings("serial") 4 | public class ModelResolutionException extends RuntimeException { 5 | 6 | public ModelResolutionException() { 7 | super(); 8 | } 9 | 10 | public ModelResolutionException(String message, Throwable cause) { 11 | super(message, cause); 12 | } 13 | 14 | public ModelResolutionException(String message) { 15 | super(message); 16 | } 17 | 18 | public ModelResolutionException(Throwable cause) { 19 | super(cause); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/ParameterNameLexer.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader; 2 | 3 | class ParameterNameLexer { 4 | 5 | public static final int COMMA = 0; 6 | public static final int LEFT_PAREN = COMMA+1; 7 | public static final int RIGHT_PAREN = LEFT_PAREN+1; 8 | public static final int IDENT = RIGHT_PAREN+1; 9 | public static final int PLUS = IDENT+1; 10 | public static final int STAR = PLUS+1; 11 | public static final int BANG = STAR+1; 12 | public static final int EOI = BANG+1; 13 | 14 | // type string to parse 15 | String input; 16 | int index = 0; 17 | int mark = -1; 18 | 19 | public ParameterNameLexer(){} 20 | 21 | public String toString() { 22 | StringBuilder sb = new StringBuilder(); 23 | sb.append(input).append(System.lineSeparator()); 24 | for (int ii = 0; ii < index; ii++) { 25 | sb.append(' '); 26 | } 27 | sb.append('^'); 28 | return sb.toString(); 29 | } 30 | 31 | public void setup(String input){ 32 | this.input = input; 33 | index = 0; 34 | } 35 | 36 | private int peek(){ 37 | if(index >= input.length()) 38 | return EOI; 39 | int c = input.codePointAt(index); 40 | int token; 41 | switch(c){ 42 | case '(': token = LEFT_PAREN; break; 43 | case ')': token = RIGHT_PAREN; break; 44 | case ',': token = COMMA; break; 45 | case '+': token = PLUS; break; 46 | case '*': token = STAR; break; 47 | case '!': token = BANG; break; 48 | default: 49 | if (isIdentifierPart(c)) { 50 | token = IDENT; 51 | } else { 52 | throw new ParameterNameParserException("Unknown codepoint=" + c + "\n" + this); 53 | } 54 | } 55 | return token; 56 | } 57 | 58 | private boolean isIdentifierPart(int codepoint) { 59 | return Character.isLowerCase(codepoint) 60 | || Character.isUpperCase(codepoint) 61 | || Character.isDigit(codepoint) 62 | || codepoint == '_'; 63 | } 64 | 65 | public void eat() { 66 | int token = peek(); 67 | switch(token) { 68 | case LEFT_PAREN: 69 | case RIGHT_PAREN: 70 | case COMMA: 71 | case PLUS: 72 | case STAR: 73 | case BANG: 74 | index += 1; 75 | return; 76 | case IDENT: 77 | index += Character.charCount(input.codePointAt(index)); 78 | int c = input.codePointAt(index); 79 | while (index < input.length() 80 | && isIdentifierPart(c)) { 81 | index += Character.charCount(input.codePointAt(index)); 82 | c = input.codePointAt(index); 83 | } 84 | return; 85 | case EOI: 86 | return; 87 | default: 88 | throw new ParameterNameParserException("Unknown token=" + token+"\n" + this); 89 | } 90 | } 91 | 92 | public String eatIdentifier() { 93 | int index = this.index; 94 | eat(IDENT); 95 | return input.substring(index, this.index); 96 | } 97 | 98 | public void eat(int token) { 99 | if(!lookingAt(token)){ 100 | throw new ParameterNameParserException("Missing expected token: "+tokenToString(token)+System.lineSeparator() 101 | + this); 102 | } 103 | eat(); 104 | } 105 | 106 | private String tokenToString(int token) { 107 | switch (token) { 108 | case COMMA: return "COMMA"; 109 | case IDENT: return "IDENT"; 110 | case LEFT_PAREN: return "LEFT_PAREN"; 111 | case RIGHT_PAREN: return "RIGHT_PAREN"; 112 | case EOI: return "EOI"; 113 | case PLUS: return "PLUS"; 114 | case STAR: return "STAR"; 115 | case BANG: return "BANG"; 116 | } 117 | throw new ParameterNameParserException("Unknown token " + token); 118 | } 119 | 120 | public boolean lookingAt(int token) { 121 | return peek() == token; 122 | } 123 | 124 | } 125 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/ParameterNameParser.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader; 2 | 3 | import static com.redhat.ceylon.model.loader.ParameterNameLexer.*; 4 | 5 | import java.util.ArrayList; 6 | import java.util.Iterator; 7 | import java.util.List; 8 | 9 | import com.redhat.ceylon.model.typechecker.model.Function; 10 | import com.redhat.ceylon.model.typechecker.model.FunctionOrValue; 11 | import com.redhat.ceylon.model.typechecker.model.Parameter; 12 | import com.redhat.ceylon.model.typechecker.model.ParameterList; 13 | import com.redhat.ceylon.model.typechecker.model.Type; 14 | import com.redhat.ceylon.model.typechecker.model.Unit; 15 | import com.redhat.ceylon.model.typechecker.model.Value; 16 | 17 | /** 18 | * Parser for {@link com.redhat.ceylon.compiler.java.metadata.FunctionalParameter#value()}. 19 | *

 20 |  * input     ::= ( '!' )? nameList ( nameList )*
 21 |  * nameList  ::= '(' ( name ( ',' name )* )? ')'
 22 |  * name      ::= identifier ( '+' | '*' )? ( '!' )? ( nameList )*
 23 |  * 
24 | * 29 | * @author tom 30 | */ 31 | class ParameterNameParser { 32 | 33 | private final ParameterNameLexer lexer = new ParameterNameLexer(); 34 | private final AbstractModelLoader loader; 35 | private Unit unit; 36 | 37 | 38 | 39 | ParameterNameParser(AbstractModelLoader loader) { 40 | this.loader = loader; 41 | } 42 | 43 | public void parse(String input, Type type, Function method) { 44 | lexer.setup(input); 45 | this.unit = method.getUnit(); 46 | boolean declaredVoid = false; 47 | ArrayList lists = new ArrayList<>(); 48 | if (lexer.lookingAt(BANG)) { 49 | lexer.eat(); 50 | declaredVoid = true; 51 | } 52 | lists.add(parseNameList(type, method)); 53 | while (lexer.lookingAt(LEFT_PAREN)) {// mpl 54 | type = loader.getSimpleCallableReturnType(type); 55 | lists.add(parseNameList(type, method)); 56 | } 57 | for (ParameterList parameterList : lists) { 58 | method.addParameterList(parameterList); 59 | } 60 | method.setDeclaredVoid(declaredVoid); 61 | method.setType(loader.getSimpleCallableReturnType(type)); 62 | if (!lexer.lookingAt(EOI)) { 63 | throw new ParameterNameParserException("Expected end of input" + System.lineSeparator() + input); 64 | } 65 | } 66 | public void parseMpl(String input, Type type, Function method) { 67 | lexer.setup(input); 68 | this.unit = method.getUnit(); 69 | ArrayList lists = new ArrayList<>(); 70 | lists.add(parseNameList(type, method)); 71 | while (lexer.lookingAt(LEFT_PAREN)) {// mpl 72 | type = loader.getSimpleCallableReturnType(type); 73 | lists.add(parseNameList(type, method)); 74 | } 75 | for (ParameterList parameterList : lists) { 76 | method.addParameterList(parameterList); 77 | } 78 | method.setType(loader.getSimpleCallableReturnType(type)); 79 | if (!lexer.lookingAt(EOI)) { 80 | throw new ParameterNameParserException("Expected end of input" + System.lineSeparator() + input); 81 | } 82 | } 83 | private ParameterList parseNameList(Type type, Function method) { 84 | ParameterList pl = new ParameterList(); 85 | List parameters = pl.getParameters(); 86 | //startParameterList(); 87 | lexer.eat(LEFT_PAREN); 88 | if (!lexer.lookingAt(RIGHT_PAREN)) { 89 | Iterator ct = loader.getSimpleCallableArgumentTypes(type).iterator(); 90 | if (!ct.hasNext()) { 91 | throw new ParameterNameParserException("Too few parameter types"); 92 | } 93 | parameters.add(parseName(ct.next(), method)); 94 | // addParameter() 95 | while (lexer.lookingAt(COMMA)) { 96 | lexer.eat(); 97 | if (!ct.hasNext()) { 98 | throw new ParameterNameParserException("Too few parameter types"); 99 | } 100 | parameters.add(parseName(ct.next(), method)); 101 | } 102 | if (ct.hasNext()) { 103 | throw new ParameterNameParserException("Too many parameter types"); 104 | } 105 | } 106 | lexer.eat(RIGHT_PAREN); 107 | //endParameterList(); 108 | return pl; 109 | } 110 | 111 | private Parameter parseName(Type type, Function container) { 112 | String identifier = lexer.eatIdentifier(); 113 | boolean declaredVoid = false; 114 | boolean sequenced = false; 115 | boolean atLeastOne = false; 116 | if (lexer.lookingAt(STAR)) { 117 | lexer.eat(); 118 | sequenced = true; 119 | } else if (lexer.lookingAt(PLUS)) { 120 | lexer.eat(); 121 | sequenced = true; 122 | atLeastOne = true; 123 | } 124 | if (lexer.lookingAt(BANG)) { 125 | lexer.eat(); 126 | declaredVoid = true; 127 | } 128 | 129 | final FunctionOrValue result; 130 | if (lexer.lookingAt(LEFT_PAREN)) { 131 | // functionParameter() 132 | result = parseMethod(type, declaredVoid); 133 | } else { 134 | if (declaredVoid) { 135 | throw new ParameterNameParserException("void Value"); 136 | } 137 | // valueParameter(); 138 | result = parseValue(type); 139 | } 140 | result.setName(identifier); 141 | result.setUnit(unit); 142 | result.setContainer(container); 143 | result.setScope(container); 144 | Parameter p = new Parameter(); 145 | p.setName(identifier); 146 | p.setSequenced(sequenced); 147 | p.setAtLeastOne(atLeastOne); 148 | p.setDeclaredAnything(declaredVoid); 149 | p.setModel(result); 150 | result.setInitializerParameter(p); 151 | container.addMember(result); 152 | return p; 153 | } 154 | 155 | private Value parseValue(Type type) { 156 | Value value = new Value(); 157 | value.setType(type); 158 | return value; 159 | } 160 | 161 | private Function parseMethod(Type type, boolean declaredVoid) { 162 | Function method = new Function(); 163 | method.setDeclaredVoid(declaredVoid); 164 | method.setType(loader.getSimpleCallableReturnType(type)); 165 | while (lexer.lookingAt(LEFT_PAREN)) { 166 | method.addParameterList(parseNameList(type, method)); 167 | type = loader.getSimpleCallableReturnType(type); 168 | } 169 | return method; 170 | } 171 | 172 | } 173 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/ParameterNameParserException.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader; 2 | 3 | @SuppressWarnings("serial") 4 | class ParameterNameParserException extends RuntimeException { 5 | 6 | public ParameterNameParserException(String message) { 7 | super(message); 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/SimpleReflType.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | import javax.lang.model.type.TypeKind; 7 | 8 | import com.redhat.ceylon.model.loader.mirror.ClassMirror; 9 | import com.redhat.ceylon.model.loader.mirror.TypeMirror; 10 | import com.redhat.ceylon.model.loader.mirror.TypeParameterMirror; 11 | 12 | /** 13 | * Simple Type Mirror. 14 | * 15 | * @author Stéphane Épardaud 16 | */ 17 | public class SimpleReflType implements TypeMirror { 18 | 19 | public enum Module { 20 | CEYLON, JDK; 21 | } 22 | 23 | private String name; 24 | private TypeKind kind; 25 | private TypeMirror[] typeParameters; 26 | private Module module; 27 | 28 | public SimpleReflType(String name, Module module, TypeKind kind, TypeMirror... typeParameters) { 29 | this.name = name; 30 | this.kind = kind; 31 | this.typeParameters = typeParameters; 32 | this.module = module; 33 | } 34 | 35 | public String toString() { 36 | String p = Arrays.toString(typeParameters); 37 | return getClass().getSimpleName() + " of " + name + "<" + p.substring(1, p.length()-1) + ">"; 38 | } 39 | 40 | @Override 41 | public String getQualifiedName() { 42 | return name; 43 | } 44 | 45 | @Override 46 | public List getTypeArguments() { 47 | return Arrays.asList(typeParameters); 48 | } 49 | 50 | @Override 51 | public TypeKind getKind() { 52 | return kind; 53 | } 54 | 55 | @Override 56 | public TypeMirror getComponentType() { 57 | return null; 58 | } 59 | 60 | @Override 61 | public boolean isPrimitive() { 62 | return kind.isPrimitive(); 63 | } 64 | 65 | @Override 66 | public TypeMirror getUpperBound() { 67 | return null; 68 | } 69 | 70 | @Override 71 | public TypeMirror getLowerBound() { 72 | return null; 73 | } 74 | 75 | @Override 76 | public boolean isRaw() { 77 | return false; 78 | } 79 | 80 | @Override 81 | public ClassMirror getDeclaredClass() { 82 | return null; 83 | } 84 | 85 | public Module getModule() { 86 | return module; 87 | } 88 | 89 | @Override 90 | public TypeParameterMirror getTypeParameter() { 91 | return null; 92 | } 93 | 94 | @Override 95 | public TypeMirror getQualifyingType() { 96 | return null; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/Timer.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader; 2 | 3 | import java.io.PrintWriter; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | public class Timer { 8 | private long programStart; 9 | private String currentTask; 10 | private long currentTaskStart; 11 | protected boolean verbose; 12 | private final Map ignoredCategories; 13 | protected PrintWriter out; 14 | 15 | protected Timer(){ 16 | ignoredCategories = new HashMap(); 17 | } 18 | 19 | private Timer(PrintWriter out, long programStart, boolean verbose, Map ignoredCategories) { 20 | this.programStart = programStart; 21 | this.verbose = verbose; 22 | this.ignoredCategories = ignoredCategories; 23 | this.out = out; 24 | } 25 | 26 | public Timer(boolean verbose) { 27 | ignoredCategories = new HashMap(); 28 | setup(verbose); 29 | } 30 | 31 | private void setup(boolean verbose) { 32 | // we delay printing the program start because we don't know if the verbose option is set yet at 33 | // that time, so we fake it later on with the correct time 34 | } 35 | 36 | /** 37 | * Initializes this timer and {@linkplain #log(String) logs} a 38 | * "program start" message. 39 | */ 40 | public void init(){ 41 | programStart = System.nanoTime(); 42 | if(verbose) 43 | log("Program start", programStart); 44 | } 45 | 46 | public void end() { 47 | if(!verbose) 48 | return; 49 | log("Program end"); 50 | } 51 | 52 | /** 53 | * {@linkplain #endTask() Ends} the current task (if any) and starts a 54 | * timed task with the given name, 55 | * {@linkplain #log(String) logging} the task name. 56 | * 57 | * @param name The name of the task to start. 58 | * 59 | * @see #nestedTimer() 60 | */ 61 | public void startTask(String name){ 62 | if(!verbose) 63 | return; 64 | if(currentTask != null) 65 | endTask(); 66 | currentTask = name; 67 | currentTaskStart = System.nanoTime(); 68 | log("Task "+currentTask+" start"); 69 | } 70 | 71 | /** 72 | * Logs a message, including the elapsed time since this Timer was 73 | * {@linkplain #init() initialized}. 74 | * @param string The message 75 | */ 76 | public void log(String string) { 77 | if(!verbose) 78 | return; 79 | log(string, System.nanoTime()); 80 | } 81 | 82 | private void log(String string, long now) { 83 | long delta = (now - programStart)/1_000_000; 84 | String msg = "["+delta+"ms] "+string; 85 | if(out != null) 86 | out.println(msg); 87 | else 88 | System.err.println(msg); 89 | } 90 | 91 | /** 92 | * Prints a message 93 | * @param string The message 94 | */ 95 | public void print(String string) { 96 | if(!verbose) 97 | return; 98 | if(out != null) 99 | out.println(string); 100 | else 101 | System.err.println(string); 102 | } 103 | 104 | /** 105 | * Ends the current task, {@linkplain #log(String) logging} the name of 106 | * the task and its elapsed time 107 | * @see #startTask(String) 108 | */ 109 | public void endTask() { 110 | if(!verbose) 111 | return; 112 | long time = System.nanoTime(); 113 | long delta = (time - currentTaskStart)/1_000_000L; 114 | log("Task "+currentTask+" end: "+delta+"ms"); 115 | printIgnoredCategories(); 116 | currentTask = null; 117 | } 118 | 119 | public void startIgnore(String category) { 120 | if(!verbose) 121 | return; 122 | IgnoredCategory ignoredCategory = ignoredCategories.get(category); 123 | if(ignoredCategory == null){ 124 | ignoredCategory = new IgnoredCategory(category); 125 | ignoredCategories.put(category, ignoredCategory); 126 | } 127 | ignoredCategory.start(); 128 | } 129 | 130 | public void stopIgnore(String category) { 131 | if(!verbose) 132 | return; 133 | IgnoredCategory ignoredCategory = ignoredCategories.get(category); 134 | if (ignoredCategory != null) { 135 | ignoredCategory.stop(); 136 | } 137 | } 138 | 139 | private void printIgnoredCategories(){ 140 | for(IgnoredCategory category : ignoredCategories.values()){ 141 | if(category.total != 0){ 142 | print(" Including "+category.name+" for "+category.total+"ms"); 143 | } 144 | category.reset(); 145 | } 146 | } 147 | 148 | private final class IgnoredCategory { 149 | String name; 150 | long start; 151 | long total; 152 | int count; 153 | public IgnoredCategory(String category) { 154 | this.name = category; 155 | } 156 | public void start() { 157 | if(count++ == 0){ 158 | start = System.nanoTime(); 159 | } 160 | } 161 | public void stop() { 162 | if(--count == 0){ 163 | long end = System.nanoTime(); 164 | long delta = (end - start)/1_000_000; 165 | total += delta; 166 | } 167 | } 168 | public void reset() { 169 | if(count != 0) 170 | print("Ignored category "+name+" count is "+count+" during reset: timings will be wrong"); 171 | // try to fix it for next time? 172 | count = 0; 173 | total = 0; 174 | } 175 | } 176 | 177 | /** 178 | * Creates and returns a new timer suitable for timing sub-tasks 179 | * without stopping the 'outer' timer. Necessary because 180 | * {@link #startTask(String)} stops the current timer. 181 | * @return The new timer 182 | */ 183 | public Timer nestedTimer() { 184 | return new Timer(out, programStart, verbose, ignoredCategories); 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/TypeParserException.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader; 2 | 3 | @SuppressWarnings("serial") 4 | public class TypeParserException extends RuntimeException { 5 | 6 | public TypeParserException(String message) { 7 | super(message); 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/impl/reflect/ReflectionModelLoader.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader.impl.reflect; 2 | 3 | import java.lang.reflect.Member; 4 | import java.util.List; 5 | 6 | import com.redhat.ceylon.common.JVMModuleUtil; 7 | import com.redhat.ceylon.common.log.Logger; 8 | import com.redhat.ceylon.model.loader.AbstractModelLoader; 9 | import com.redhat.ceylon.model.loader.Timer; 10 | import com.redhat.ceylon.model.loader.TypeParser; 11 | import com.redhat.ceylon.model.loader.impl.reflect.mirror.ReflectionClass; 12 | import com.redhat.ceylon.model.loader.impl.reflect.mirror.ReflectionMethod; 13 | import com.redhat.ceylon.model.loader.mirror.ClassMirror; 14 | import com.redhat.ceylon.model.loader.mirror.MethodMirror; 15 | import com.redhat.ceylon.model.typechecker.model.Module; 16 | import com.redhat.ceylon.model.typechecker.model.Modules; 17 | import com.redhat.ceylon.model.typechecker.model.Unit; 18 | import com.redhat.ceylon.model.typechecker.util.ModuleManager; 19 | 20 | /** 21 | * A model loader which uses Java reflection. 22 | * 23 | * @author Stéphane Épardaud 24 | */ 25 | public abstract class ReflectionModelLoader extends AbstractModelLoader { 26 | protected Logger log; 27 | 28 | public ReflectionModelLoader(ModuleManager moduleManager, Modules modules, Logger log){ 29 | this.moduleManager = moduleManager; 30 | this.modules = modules; 31 | this.typeFactory = new Unit(); 32 | this.typeParser = new TypeParser(this); 33 | this.timer = new Timer(false); 34 | this.log = log; 35 | } 36 | 37 | protected abstract List getPackageList(Module module, String packageName); 38 | protected abstract boolean packageExists(Module module, String packageName); 39 | protected abstract Class loadClass(Module module, String name); 40 | 41 | @Override 42 | public void loadStandardModules() { 43 | super.loadStandardModules(); 44 | // load two packages for the language module 45 | Module languageModule = modules.getLanguageModule(); 46 | findOrCreatePackage(languageModule, AbstractModelLoader.CEYLON_LANGUAGE); 47 | findOrCreatePackage(languageModule, AbstractModelLoader.CEYLON_LANGUAGE_MODEL); 48 | findOrCreatePackage(languageModule, AbstractModelLoader.CEYLON_LANGUAGE_MODEL_DECLARATION); 49 | findOrCreatePackage(languageModule, AbstractModelLoader.CEYLON_LANGUAGE_SERIALIZATION); 50 | } 51 | 52 | @Override 53 | public boolean loadPackage(Module module, String packageName, boolean loadDeclarations) { 54 | // abort if we already loaded it, but only record that we loaded it if we want 55 | // to load the declarations, because merely calling complete() on the package 56 | // is OK 57 | packageName = JVMModuleUtil.quoteJavaKeywords(packageName); 58 | if(loadDeclarations && !loadedPackages.add(cacheKeyByModule(module, packageName))){ 59 | return true; 60 | } 61 | if(!packageExists(module, packageName)) 62 | return false; 63 | if(loadDeclarations){ 64 | for(String file : getPackageList(module, packageName)){ 65 | // ignore non-class stuff 66 | if(!file.toLowerCase().endsWith(".class")) 67 | continue; 68 | // turn it into a class name 69 | // FIXME: this is terrible 70 | String className = file.substring(0, file.length()-6).replace('/', '.'); 71 | // get the last part 72 | int lastDot = className.lastIndexOf('.'); 73 | String lastPart = lastDot == -1 ? className : className.substring(lastDot+1); 74 | int dollar = lastPart.indexOf('$'); 75 | // if we have a dollar after the first char (where it would be quoting), skip it 76 | // because those are local/member/anonymous/impl ones 77 | if(dollar > 0) 78 | continue; 79 | // skip module/package declarations too (do not strip before checking) 80 | if(isModuleOrPackageDescriptorName(lastPart)) 81 | continue; 82 | 83 | // the logic for lower-cased names should be abstracted somewhere sane 84 | if(!isLoadedFromSource(className) 85 | && (!className.endsWith("_") || !isLoadedFromSource(className.substring(0, className.length()-1))) 86 | && !isTypeHidden(module, className)) 87 | convertToDeclaration(module, className, DeclarationType.TYPE); 88 | } 89 | if(module.getNameAsString().equals(JAVA_BASE_MODULE_NAME) 90 | && packageName.equals("java.lang")) 91 | loadJavaBaseArrays(); 92 | } 93 | return true; 94 | } 95 | 96 | protected boolean isLoadedFromSource(String className) { 97 | return false; 98 | } 99 | 100 | @Override 101 | public ClassMirror lookupNewClassMirror(Module module, String name) { 102 | Class klass = null; 103 | // first try with the same name, for Java interop with classes with lowercase name 104 | klass = loadClass(module, JVMModuleUtil.quoteJavaKeywords(name)); 105 | if (klass == null && lastPartHasLowerInitial(name) && !name.endsWith("_")) { 106 | klass = loadClass(module, JVMModuleUtil.quoteJavaKeywords(name+"_")); 107 | } 108 | return klass != null ? new ReflectionClass(klass) : null; 109 | } 110 | 111 | @Override 112 | protected String assembleJavaClass(String javaClass, String packageName) { 113 | // strip the java class name of its package part 114 | if(!packageName.isEmpty()) 115 | javaClass = javaClass.substring(packageName.length()+1); // pkg + dot 116 | // now replace every dot in the name part with $ 117 | javaClass = javaClass.replace('.', '$'); 118 | // assemble back 119 | if(packageName.isEmpty()) 120 | return javaClass; 121 | return packageName + "." + javaClass; 122 | } 123 | 124 | @Override 125 | protected boolean isOverridingMethod(MethodMirror methodSymbol) { 126 | final Member method = ((ReflectionMethod)methodSymbol).method; 127 | if (method.getDeclaringClass().getName().contentEquals("ceylon.language.Identifiable")) { 128 | if (method.getName().contentEquals("equals") || method.getName().contentEquals("hashCode")) { 129 | return true; 130 | } 131 | } 132 | if (method.getDeclaringClass().getName().contentEquals("ceylon.language.Object")) { 133 | if (method.getName().contentEquals("equals") || method.getName().contentEquals("hashCode") || method.getName().contentEquals("toString")) { 134 | return false; 135 | } 136 | } 137 | return ((ReflectionMethod)methodSymbol).isOverridingMethod(); 138 | } 139 | 140 | @Override 141 | protected boolean isOverloadingMethod(MethodMirror methodSymbol) { 142 | return ((ReflectionMethod)methodSymbol).isOverloadingMethod(); 143 | } 144 | 145 | @Override 146 | protected void logError(String message) { 147 | log.error(message); 148 | } 149 | 150 | @Override 151 | protected void logWarning(String message) { 152 | log.warning(message); 153 | } 154 | 155 | @Override 156 | protected void logVerbose(String message) { 157 | log.debug(message); 158 | } 159 | 160 | } 161 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/impl/reflect/mirror/ReflectionAnnotation.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader.impl.reflect.mirror; 2 | 3 | import java.lang.annotation.Annotation; 4 | import java.lang.reflect.Method; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import com.redhat.ceylon.model.loader.mirror.AnnotationMirror; 9 | 10 | public class ReflectionAnnotation implements AnnotationMirror { 11 | 12 | private Annotation annotation; 13 | 14 | public ReflectionAnnotation(Annotation annotation) { 15 | this.annotation = annotation; 16 | } 17 | 18 | @Override 19 | public Object getValue(String fieldName) { 20 | try { 21 | Method method = annotation.getClass().getMethod(fieldName); 22 | return convertValue(method.invoke(annotation)); 23 | } catch (Exception e) { 24 | e.printStackTrace(); 25 | return null; 26 | } 27 | } 28 | 29 | private Object convertValue(Object value) { 30 | Class valueClass = value.getClass(); 31 | if(valueClass.isArray()){ 32 | if (valueClass.getComponentType().isPrimitive()) { 33 | Class componentType = valueClass.getComponentType(); 34 | if (componentType == short.class) { 35 | short[] array = (short[])value; 36 | List values = new ArrayList(array.length); 37 | for(short val : array) 38 | values.add(val); 39 | return values; 40 | } else if (componentType == int.class) { 41 | int[] array = (int[])value; 42 | List values = new ArrayList(array.length); 43 | for(int val : array) 44 | values.add(val); 45 | return values; 46 | } else if (componentType == long.class) { 47 | long[] array = (long[])value; 48 | List values = new ArrayList(array.length); 49 | for(long val : array) 50 | values.add(val); 51 | return values; 52 | } else if (componentType == boolean.class) { 53 | boolean[] array = (boolean[])value; 54 | List values = new ArrayList(array.length); 55 | for(boolean val : array) 56 | values.add(val); 57 | return values; 58 | } else if (componentType == char.class) { 59 | char[] array = (char[])value; 60 | List values = new ArrayList(array.length); 61 | for(char val : array) 62 | values.add(val); 63 | return values; 64 | } else if (componentType == float.class) { 65 | float[] array = (float[])value; 66 | List values = new ArrayList(array.length); 67 | for(float val : array) 68 | values.add(val); 69 | return values; 70 | } else if (componentType == double.class) { 71 | double[] array = (double[])value; 72 | List values = new ArrayList(array.length); 73 | for(double val : array) 74 | values.add(val); 75 | return values; 76 | } 77 | } else { 78 | Object[] array = (Object[])value; 79 | List values = new ArrayList(array.length); 80 | for(Object val : array) 81 | values.add(convertValue(val)); 82 | return values; 83 | } 84 | } 85 | if(value instanceof Annotation){ 86 | return new ReflectionAnnotation((Annotation) value); 87 | } 88 | if(value instanceof Enum){ 89 | return ((Enum)value).name(); 90 | } 91 | if(value instanceof Class){ 92 | return new ReflectionType((Class)value); 93 | } 94 | return value; 95 | } 96 | 97 | @Override 98 | public Object getValue() { 99 | return getValue("value"); 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/impl/reflect/mirror/ReflectionField.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader.impl.reflect.mirror; 2 | 3 | import java.lang.reflect.Field; 4 | import java.lang.reflect.Modifier; 5 | import java.util.Map; 6 | 7 | import com.redhat.ceylon.model.loader.mirror.AnnotationMirror; 8 | import com.redhat.ceylon.model.loader.mirror.FieldMirror; 9 | import com.redhat.ceylon.model.loader.mirror.TypeMirror; 10 | 11 | public class ReflectionField implements FieldMirror { 12 | 13 | private Field field; 14 | private ReflectionType type; 15 | private Map annotations; 16 | 17 | public ReflectionField(Field field) { 18 | this.field = field; 19 | } 20 | 21 | @Override 22 | public AnnotationMirror getAnnotation(String type) { 23 | return getAnnotations().get(type); 24 | } 25 | 26 | private Map getAnnotations() { 27 | // profiling revealed we need to cache this 28 | if(annotations == null){ 29 | annotations = ReflectionUtils.getAnnotations(field); 30 | } 31 | return annotations; 32 | } 33 | 34 | @Override 35 | public String getName() { 36 | return field.getName(); 37 | } 38 | 39 | @Override 40 | public boolean isStatic() { 41 | return Modifier.isStatic(field.getModifiers()); 42 | } 43 | 44 | @Override 45 | public boolean isPublic() { 46 | return Modifier.isPublic(field.getModifiers()); 47 | } 48 | 49 | @Override 50 | public boolean isProtected() { 51 | return Modifier.isProtected(field.getModifiers()); 52 | } 53 | 54 | @Override 55 | public boolean isDefaultAccess() { 56 | return !Modifier.isPrivate(field.getModifiers()) 57 | && !Modifier.isPublic(field.getModifiers()) 58 | && !Modifier.isProtected(field.getModifiers()); 59 | } 60 | 61 | @Override 62 | public boolean isFinal() { 63 | return Modifier.isFinal(field.getModifiers()); 64 | } 65 | 66 | @Override 67 | public TypeMirror getType() { 68 | if(type != null) 69 | return type; 70 | type = new ReflectionType(field.getGenericType()); 71 | return type; 72 | } 73 | 74 | @Override 75 | public String toString() { 76 | return "[ReflectionField: "+field.toString()+"]"; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/impl/reflect/mirror/ReflectionPackage.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader.impl.reflect.mirror; 2 | 3 | import com.redhat.ceylon.model.loader.mirror.PackageMirror; 4 | 5 | public class ReflectionPackage implements PackageMirror { 6 | 7 | private String pkg; 8 | 9 | public ReflectionPackage(Class klass) { 10 | pkg = ReflectionUtils.getPackageName(klass); 11 | } 12 | 13 | @Override 14 | public String getQualifiedName() { 15 | return pkg; 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/impl/reflect/mirror/ReflectionTypeParameter.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader.impl.reflect.mirror; 2 | 3 | import java.lang.reflect.Type; 4 | import java.lang.reflect.TypeVariable; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import com.redhat.ceylon.model.loader.mirror.TypeMirror; 9 | import com.redhat.ceylon.model.loader.mirror.TypeParameterMirror; 10 | 11 | public class ReflectionTypeParameter implements TypeParameterMirror { 12 | 13 | private TypeVariable type; 14 | private ArrayList bounds; 15 | 16 | public ReflectionTypeParameter(Type type) { 17 | this.type = (TypeVariable) type; 18 | } 19 | 20 | @Override 21 | public String getName() { 22 | return type.getName(); 23 | } 24 | 25 | @Override 26 | public List getBounds() { 27 | if(bounds != null) 28 | return bounds; 29 | Type[] javaBounds = type.getBounds(); 30 | bounds = new ArrayList(javaBounds.length); 31 | for(Type bound : javaBounds) 32 | bounds.add(new ReflectionType(bound)); 33 | return bounds; 34 | } 35 | 36 | @Override 37 | public String toString() { 38 | return "[ReflectionTypeParameter: "+type.toString()+"]"; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/impl/reflect/mirror/ReflectionVariable.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader.impl.reflect.mirror; 2 | 3 | import java.lang.annotation.Annotation; 4 | import java.lang.reflect.Type; 5 | import java.util.Map; 6 | 7 | import com.redhat.ceylon.model.loader.mirror.AnnotationMirror; 8 | import com.redhat.ceylon.model.loader.mirror.TypeMirror; 9 | import com.redhat.ceylon.model.loader.mirror.VariableMirror; 10 | 11 | public class ReflectionVariable implements VariableMirror { 12 | 13 | private Type type; 14 | private Map annotations; 15 | private ReflectionType varType; 16 | 17 | public ReflectionVariable(Type type, Annotation[] annotations) { 18 | this.type = type; 19 | this.annotations = ReflectionUtils.getAnnotations(annotations); 20 | } 21 | 22 | @Override 23 | public AnnotationMirror getAnnotation(String type) { 24 | return annotations.get(type); 25 | } 26 | 27 | @Override 28 | public TypeMirror getType() { 29 | if(varType != null) 30 | return varType; 31 | varType = new ReflectionType(type); 32 | return varType; 33 | } 34 | 35 | @Override 36 | public String getName() { 37 | AnnotationMirror name = getAnnotation("com.redhat.ceylon.compiler.java.metadata.Name"); 38 | if(name == null) 39 | return "unknown"; 40 | return (String) name.getValue(); 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "[ReflectionVariable: "+type.toString()+"]"; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/impl/reflect/model/ReflectionModule.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader.impl.reflect.model; 2 | 3 | import java.util.List; 4 | 5 | import com.redhat.ceylon.model.loader.AbstractModelLoader; 6 | import com.redhat.ceylon.model.loader.model.LazyModule; 7 | import com.redhat.ceylon.model.typechecker.model.Package; 8 | 9 | public class ReflectionModule extends LazyModule { 10 | 11 | private ReflectionModuleManager modelManager; 12 | private boolean packagesLoaded = false; 13 | 14 | public ReflectionModule(ReflectionModuleManager reflectionModuleManager) { 15 | this.modelManager = reflectionModuleManager; 16 | } 17 | 18 | @Override 19 | protected AbstractModelLoader getModelLoader() { 20 | return modelManager.getModelLoader(); 21 | } 22 | 23 | @Override 24 | public List getPackages() { 25 | // make sure we're complete 26 | AbstractModelLoader modelLoader = getModelLoader(); 27 | if(!packagesLoaded){ 28 | synchronized(modelLoader.getLock()){ 29 | if(!packagesLoaded){ 30 | String name = getNameAsString(); 31 | for(String pkg : jarPackages){ 32 | // special case for the language module to hide stuff 33 | if(!name.equals(AbstractModelLoader.CEYLON_LANGUAGE) || pkg.startsWith(AbstractModelLoader.CEYLON_LANGUAGE)) 34 | modelLoader.findOrCreatePackage(this, pkg); 35 | } 36 | packagesLoaded = true; 37 | } 38 | } 39 | } 40 | return super.getPackages(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/impl/reflect/model/ReflectionModuleManager.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader.impl.reflect.model; 2 | 3 | import java.util.List; 4 | 5 | import com.redhat.ceylon.common.Versions; 6 | import com.redhat.ceylon.model.loader.AbstractModelLoader; 7 | import com.redhat.ceylon.model.loader.JvmBackendUtil; 8 | import com.redhat.ceylon.model.loader.model.LazyModule; 9 | import com.redhat.ceylon.model.loader.model.LazyModuleManager; 10 | import com.redhat.ceylon.model.typechecker.model.Module; 11 | import com.redhat.ceylon.model.typechecker.model.Modules; 12 | 13 | public abstract class ReflectionModuleManager extends LazyModuleManager { 14 | 15 | private AbstractModelLoader modelLoader; 16 | 17 | public ReflectionModuleManager() { 18 | super(); 19 | } 20 | 21 | @Override 22 | public void initCoreModules(Modules modules) { 23 | super.initCoreModules(modules); 24 | // FIXME: this should go away somewhere else, but we need it to be set otherwise 25 | // when we load the module from compiled sources, ModuleManager.getOrCreateModule() will not 26 | // return the language module because its version is null 27 | Module languageModule = modules.getLanguageModule(); 28 | languageModule.setVersion(Versions.CEYLON_VERSION_NUMBER); 29 | } 30 | 31 | @Override 32 | public AbstractModelLoader getModelLoader() { 33 | if(modelLoader == null){ 34 | modelLoader = createModelLoader(modules); 35 | } 36 | return modelLoader; 37 | } 38 | 39 | protected abstract AbstractModelLoader createModelLoader(Modules modules); 40 | 41 | @Override 42 | protected Module createModule(List moduleName, String version) { 43 | Module module; 44 | if(isModuleLoadedFromSource(JvmBackendUtil.getName(moduleName))) 45 | module = new Module(); 46 | else 47 | module = new ReflectionModule(this); 48 | module.setName(moduleName); 49 | module.setVersion(version); 50 | if(module instanceof ReflectionModule) 51 | setupIfJDKModule((LazyModule) module); 52 | return module; 53 | } 54 | 55 | @Override 56 | public void prepareForTypeChecking() { 57 | // make sure we don't load ceylon.language from its class files if we're documenting it 58 | if(!isModuleLoadedFromSource(AbstractModelLoader.CEYLON_LANGUAGE)) 59 | getModelLoader().loadStandardModules(); 60 | getModelLoader().loadPackageDescriptors(); 61 | } 62 | 63 | @Override 64 | public void modulesVisited() { 65 | // if we're documenting ceylon.language, we didn't call loadStandardModules() so we need 66 | // to call that. 67 | if(isModuleLoadedFromSource(AbstractModelLoader.CEYLON_LANGUAGE)){ 68 | getModelLoader().setupWithNoStandardModules(); 69 | } 70 | } 71 | 72 | @Override 73 | public boolean shouldLoadTransitiveDependencies() { 74 | return true; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/mirror/AccessibleMirror.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader.mirror; 2 | 3 | /** 4 | * Represents an program element (class, method, constructor, field) with visibility access restrictions 5 | * 6 | * @author Stéphane Épardaud 7 | */ 8 | public interface AccessibleMirror { 9 | 10 | /** 11 | * Returns true if the element is public 12 | */ 13 | boolean isPublic(); 14 | 15 | /** 16 | * Returns true if the element is protected 17 | */ 18 | boolean isProtected(); 19 | 20 | /** 21 | * Returns true if the element is package-protected 22 | */ 23 | boolean isDefaultAccess(); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/mirror/AnnotatedMirror.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader.mirror; 2 | 3 | /** 4 | * Represents an annotated program element (class, method, constructor, field, parameter) 5 | * 6 | * @author Stéphane Épardaud 7 | */ 8 | public interface AnnotatedMirror { 9 | 10 | /** 11 | * Returns the program element's name 12 | */ 13 | String getName(); 14 | 15 | /** 16 | * Gets an annotation by annotation type name (fully qualified annotation class name) 17 | */ 18 | AnnotationMirror getAnnotation(String type); 19 | } 20 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/mirror/AnnotationMirror.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader.mirror; 2 | 3 | /** 4 | * Represents an annotation 5 | * 6 | * @author Stéphane Épardaud 7 | */ 8 | public interface AnnotationMirror { 9 | 10 | /** 11 | * Returns the annotation value of the given annotation field. The value should be wrapped as such: 12 | * 13 | * - String for a string value 14 | * - boxed value for a primitive value (Integer, Character…) 15 | * - TypeMirror for a class value 16 | * - AnnotationMirror for an annotation value 17 | * - List for an array (the array elements must be wrapped using the same rules) 18 | */ 19 | Object getValue(String fieldName); 20 | 21 | /** 22 | * Returns the value of the "value" field 23 | */ 24 | Object getValue(); 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/mirror/ClassMirror.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader.mirror; 2 | 3 | import java.util.List; 4 | 5 | import com.redhat.ceylon.model.typechecker.model.Module; 6 | 7 | /** 8 | * Represents a Java Class definition. 9 | * 10 | * @author Stéphane Épardaud 11 | */ 12 | public interface ClassMirror extends AnnotatedMirror, AccessibleMirror { 13 | 14 | /** 15 | * Returns true if this is an interface 16 | */ 17 | boolean isInterface(); 18 | 19 | /** 20 | * Returns true if this is an {@code @interface}. 21 | */ 22 | boolean isAnnotationType(); 23 | 24 | /** 25 | * Returns true if this is an abstract class 26 | */ 27 | boolean isAbstract(); 28 | 29 | /** 30 | * Returns true if this is a static class 31 | */ 32 | boolean isStatic(); 33 | 34 | /** 35 | * Returns true if this class is an inner class 36 | */ 37 | boolean isInnerClass(); 38 | 39 | /** 40 | * Returns true if this class is a local class 41 | */ 42 | boolean isLocalClass(); 43 | 44 | /** 45 | * Returns true if this class is an anonymous class 46 | */ 47 | boolean isAnonymous(); 48 | 49 | /** 50 | * Returns true if this class is an enum class 51 | */ 52 | boolean isEnum(); 53 | 54 | /** 55 | * Returns the fully-qualified class name 56 | */ 57 | String getQualifiedName(); 58 | 59 | /** 60 | * Returns the fully-qualified class name in flat form: dots to separate package parts, and dollars 61 | * to separate inner members. 62 | */ 63 | String getFlatName(); 64 | 65 | /** 66 | * Returns this class's package 67 | */ 68 | PackageMirror getPackage(); 69 | 70 | /** 71 | * Returns the list of methods and constructors defined by this class. Does not include inherited 72 | * methods and constructors. 73 | */ 74 | List getDirectMethods(); 75 | 76 | /** 77 | * Returns the list of fields defined by this class. Does not include inherited 78 | * fields. 79 | */ 80 | List getDirectFields(); 81 | 82 | /** 83 | * Returns the list of type parameters for this class 84 | */ 85 | List getTypeParameters(); 86 | 87 | /** 88 | * Returns the list of inner classes directly contained in this class. Does not include inherited 89 | * inner classes. 90 | */ 91 | List getDirectInnerClasses(); 92 | 93 | /** 94 | * Returns this class's superclass, or null if it doesn't have any 95 | */ 96 | TypeMirror getSuperclass(); 97 | 98 | /** 99 | * Returns this class's containing class, if any 100 | */ 101 | ClassMirror getEnclosingClass(); 102 | 103 | /** 104 | * Returns this class's enclosing method, if any 105 | */ 106 | MethodMirror getEnclosingMethod(); 107 | 108 | /** 109 | * Returns the list of interfaces implemented by this class 110 | */ 111 | List getInterfaces(); 112 | 113 | /** 114 | * Returns true if this class represents a toplevel attribute 115 | */ 116 | boolean isCeylonToplevelAttribute(); 117 | 118 | /** 119 | * Returns true if this class represents a toplevel object 120 | */ 121 | boolean isCeylonToplevelObject(); 122 | 123 | /** 124 | * Returns true if this class represents a toplevel method 125 | */ 126 | boolean isCeylonToplevelMethod(); 127 | 128 | /** 129 | * Returns true if this class was loaded from source, false if it was loaded from a compiled form 130 | */ 131 | boolean isLoadedFromSource(); 132 | 133 | /** 134 | * Returns true if this class was loaded from a Java source file, false if it came from a ceylon 135 | * source file or from a class file 136 | */ 137 | boolean isJavaSource(); 138 | 139 | /** 140 | * Returns true if this class is final 141 | */ 142 | boolean isFinal(); 143 | 144 | String getCacheKey(Module module); 145 | } 146 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/mirror/FieldMirror.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader.mirror; 2 | 3 | 4 | /** 5 | * Represents a field. 6 | * 7 | * @author Stéphane Épardaud 8 | */ 9 | public interface FieldMirror extends AnnotatedMirror, AccessibleMirror { 10 | 11 | /** 12 | * Returns true if this field is static 13 | */ 14 | boolean isStatic(); 15 | 16 | /** 17 | * Returns true if this field is final 18 | */ 19 | boolean isFinal(); 20 | 21 | /** 22 | * Returns the type of this field 23 | */ 24 | TypeMirror getType(); 25 | } 26 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/mirror/MethodMirror.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader.mirror; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Represents a method. 7 | * 8 | * @author Stéphane Épardaud 9 | */ 10 | public interface MethodMirror extends AnnotatedMirror, AccessibleMirror { 11 | 12 | /** 13 | * Returns true if this method is static 14 | */ 15 | boolean isStatic(); 16 | 17 | /** 18 | * Returns true if this method is a constructor 19 | */ 20 | boolean isConstructor(); 21 | 22 | /** 23 | * Returns true if this method is abstract 24 | */ 25 | boolean isAbstract(); 26 | 27 | /** 28 | * Returns true if this method is final 29 | */ 30 | boolean isFinal(); 31 | 32 | /** 33 | * Returns true if this method is a static initialiser 34 | */ 35 | boolean isStaticInit(); 36 | 37 | /** 38 | * Returns true if this method is variadic 39 | */ 40 | boolean isVariadic(); 41 | 42 | /** 43 | * Returns the list of parameters 44 | */ 45 | List getParameters(); 46 | 47 | /** 48 | * Returns the return type for this method 49 | */ 50 | TypeMirror getReturnType(); 51 | 52 | boolean isDeclaredVoid(); 53 | 54 | /** 55 | * Returns the list of type parameters for this method 56 | */ 57 | List getTypeParameters(); 58 | 59 | /** 60 | * If this is a method on an annotation type, whether the method has a 61 | * {@code default} expression; 62 | */ 63 | boolean isDefault(); 64 | 65 | /** 66 | * Return this method's enclosing class. 67 | */ 68 | ClassMirror getEnclosingClass(); 69 | } 70 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/mirror/PackageMirror.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader.mirror; 2 | 3 | /** 4 | * Represents a package. 5 | * 6 | * @author Stéphane Épardaud 7 | */ 8 | public interface PackageMirror { 9 | 10 | /** 11 | * Returns the fully-qualified name of this package 12 | */ 13 | String getQualifiedName(); 14 | } 15 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/mirror/TypeMirror.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader.mirror; 2 | 3 | import java.util.List; 4 | 5 | import javax.lang.model.type.TypeKind; 6 | 7 | /** 8 | * Represents a generic type. 9 | * 10 | * @author Stéphane Épardaud 11 | */ 12 | public interface TypeMirror { 13 | 14 | /** 15 | * Returns the qualifying type, if any. 16 | */ 17 | TypeMirror getQualifyingType(); 18 | 19 | /** 20 | * Returns the fully-qualified name of this type with no type argument. 21 | */ 22 | String getQualifiedName(); 23 | 24 | /** 25 | * Returns the list of type arguments for this type 26 | */ 27 | List getTypeArguments(); 28 | 29 | /** 30 | * Returns the kind of type this is 31 | */ 32 | TypeKind getKind(); 33 | 34 | /** 35 | * Returns the component type of this type, if this is an array type. Returns null otherwise. 36 | */ 37 | // for arrays 38 | TypeMirror getComponentType(); 39 | 40 | /** 41 | * Returns true if this type represents a Java primitive 42 | */ 43 | boolean isPrimitive(); 44 | 45 | /** 46 | * Returns true if this type is a Raw type (missing some type parameters) 47 | */ 48 | boolean isRaw(); 49 | 50 | /** 51 | * Returns the upper bound of this wildcard type if this is a wildcard type with an upper bound. Returns null otherwise. 52 | */ 53 | TypeMirror getUpperBound(); 54 | 55 | /** 56 | * Returns the lower bound of this wildcard type if this is a wildcard type with an lower bound. Returns null otherwise. 57 | */ 58 | TypeMirror getLowerBound(); 59 | 60 | /** 61 | * Returns the underlying class declaration of this type if it represents a class type 62 | */ 63 | ClassMirror getDeclaredClass(); 64 | 65 | /** 66 | * Returns the underlying type parameter declaration of this type if it represents a class type 67 | */ 68 | TypeParameterMirror getTypeParameter(); 69 | } 70 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/mirror/TypeParameterMirror.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader.mirror; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Represents a type parameter. 7 | * 8 | * @author Stéphane Épardaud 9 | */ 10 | public interface TypeParameterMirror { 11 | 12 | /** 13 | * Returns the name of the type parameter. 14 | */ 15 | String getName(); 16 | 17 | /** 18 | * Returns the list of bounds for this type parameter. 19 | */ 20 | List getBounds(); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/mirror/VariableMirror.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader.mirror; 2 | 3 | /** 4 | * Represents a method/constructor parameter. 5 | * 6 | * @author Stéphane Épardaud 7 | */ 8 | public interface VariableMirror extends AnnotatedMirror { 9 | 10 | /** 11 | * Returns this parameter's type 12 | */ 13 | TypeMirror getType(); 14 | } 15 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/model/AnnotationProxyClass.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader.model; 2 | 3 | import java.util.EnumSet; 4 | 5 | import com.redhat.ceylon.model.typechecker.model.Class; 6 | 7 | /** 8 | * Used for annotation proxies for interop. 9 | * 10 | * @author Stéphane Épardaud 11 | */ 12 | public class AnnotationProxyClass extends Class { 13 | 14 | public final LazyInterface iface; 15 | 16 | public AnnotationProxyClass(LazyInterface iface) { 17 | this.iface = iface; 18 | } 19 | 20 | /** 21 | * The elements in the {@code @Target} annotation, or null if 22 | * the annotation type lacks the {@code @Target} annotation. 23 | */ 24 | @Override 25 | public EnumSet getAnnotationTarget() { 26 | return AnnotationTarget.getAnnotationTarget(iface); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/model/AnnotationProxyMethod.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader.model; 2 | 3 | import com.redhat.ceylon.model.typechecker.model.Function; 4 | 5 | /** 6 | * Used for annotation interop. 7 | * 8 | * @author Stéphane Épardaud 9 | */ 10 | public class AnnotationProxyMethod extends Function { 11 | 12 | private AnnotationProxyClass proxyClass; 13 | 14 | private OutputElement annotationTarget; 15 | 16 | public AnnotationProxyClass getProxyClass() { 17 | return proxyClass; 18 | } 19 | 20 | public void setProxyClass(AnnotationProxyClass proxyClass) { 21 | this.proxyClass = proxyClass; 22 | } 23 | 24 | public void setAnnotationTarget(OutputElement annotationTarget) { 25 | this.annotationTarget = annotationTarget; 26 | } 27 | 28 | /** 29 | * If this is a disambiguating proxy annotation method, then this is the 30 | * Java program element that the constructor targets. Otherwise null 31 | */ 32 | public OutputElement getAnnotationTarget() { 33 | return this.annotationTarget; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/model/AnnotationTarget.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader.model; 2 | 3 | import java.util.Collections; 4 | import java.util.EnumSet; 5 | import java.util.HashSet; 6 | import java.util.List; 7 | import java.util.Set; 8 | 9 | import com.redhat.ceylon.model.loader.mirror.AnnotationMirror; 10 | import com.redhat.ceylon.model.typechecker.model.Class; 11 | 12 | 13 | /** 14 | * Mirrors the elements of {@link java.lang.annotation.ElementType} for 15 | * the purpose of targeting java annotations. 16 | */ 17 | public enum AnnotationTarget { 18 | 19 | TYPE { 20 | @Override 21 | public Set outputs() { 22 | return Collections.singleton(OutputElement.TYPE); 23 | } 24 | }, 25 | FIELD { 26 | @Override 27 | public Set outputs() { 28 | return Collections.singleton(OutputElement.FIELD); 29 | } 30 | }, 31 | METHOD { 32 | @Override 33 | public Set outputs() { 34 | HashSet result = new HashSet(3); 35 | result.add(OutputElement.METHOD); 36 | result.add(OutputElement.GETTER); 37 | result.add(OutputElement.SETTER); 38 | return result; 39 | } 40 | }, 41 | PARAMETER { 42 | @Override 43 | public Set outputs() { 44 | return Collections.singleton(OutputElement.PARAMETER); 45 | } 46 | }, 47 | CONSTRUCTOR { 48 | @Override 49 | public Set outputs() { 50 | return Collections.singleton(OutputElement.CONSTRUCTOR); 51 | } 52 | }, 53 | LOCAL_VARIABLE { 54 | @Override 55 | public Set outputs() { 56 | return Collections.singleton(OutputElement.LOCAL_VARIABLE); 57 | } 58 | }, 59 | ANNOTATION_TYPE { 60 | @Override 61 | public Set outputs() { 62 | return Collections.singleton(OutputElement.ANNOTATION_TYPE); 63 | } 64 | }, 65 | PACKAGE { 66 | @Override 67 | public Set outputs() { 68 | return Collections.singleton(OutputElement.PACKAGE); 69 | } 70 | }, 71 | TYPE_USE { 72 | @Override 73 | public Set outputs() { 74 | return Collections.emptySet(); 75 | } 76 | }, 77 | TYPE_PARAMETER { 78 | @Override 79 | public Set outputs() { 80 | return Collections.emptySet(); 81 | } 82 | }; 83 | 84 | public abstract Set outputs(); 85 | 86 | /** 87 | * Returns the elements in the {@code @Target} annotation of the given 88 | * {@code @interface}, or null if 89 | * the annotation type lacks the {@code @Target} annotation. 90 | */ 91 | public static EnumSet getAnnotationTarget(LazyInterface annotationType) { 92 | AnnotationMirror targetAnno = annotationType.classMirror.getAnnotation("java.lang.annotation.Target"); 93 | if (targetAnno != null) { 94 | @SuppressWarnings("unchecked") 95 | List targets = (List)targetAnno.getValue(); 96 | EnumSet result = EnumSet.noneOf(AnnotationTarget.class); 97 | for (String name : targets) { 98 | result.add(AnnotationTarget.valueOf(name)); 99 | } 100 | return result; 101 | } 102 | return null; 103 | } 104 | 105 | /** 106 | * Returns the possible targets of the given annotation proxy class 107 | * (according to the {@code @Target} of the {@code @interface} that 108 | * the class is a proxy to), 109 | * or null if {@code @interface} lacks a {@code @Target} or if 110 | * the given class is not an annotation proxy. 111 | */ 112 | private static EnumSet annotationTargets(Class annotationClass) { 113 | if (annotationClass instanceof AnnotationProxyClass) { 114 | return getAnnotationTarget(((AnnotationProxyClass)annotationClass).iface); 115 | } else { 116 | return null; 117 | } 118 | } 119 | 120 | /** 121 | * Given a set of Java annotation constraints, returns the 122 | * possible Java elements that could be generated by Ceylon elements 123 | * that the annotation could be applied to. 124 | * @param targets 125 | * @return 126 | */ 127 | private static EnumSet possibleCeylonTargets(EnumSet targets) { 128 | if (targets == null) { 129 | targets = EnumSet.allOf(AnnotationTarget.class); 130 | } 131 | EnumSet result = EnumSet.noneOf(OutputElement.class); 132 | for (AnnotationTarget t : targets) { 133 | result.addAll(t.outputs()); 134 | } 135 | return result; 136 | } 137 | 138 | /** 139 | * The set of program elements the given 140 | * annotation class could be applied to, according only to 141 | * the {@code @Target}s on the corresponding {@code @interface}. 142 | * @param annotationClass 143 | * @return 144 | */ 145 | public static EnumSet outputTargets(Class annotationClass) { 146 | return possibleCeylonTargets(annotationTargets(annotationClass)); 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/model/FieldValue.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader.model; 2 | 3 | import com.redhat.ceylon.model.typechecker.model.Value; 4 | 5 | /** 6 | * Marker class to be able to mark class attributes that are not JavaBean properties 7 | * but simple fields. Used for Java interoperability only. 8 | * 9 | * @author Stéphane Épardaud 10 | */ 11 | public class FieldValue extends Value { 12 | 13 | private String fieldName; 14 | 15 | public FieldValue(String fieldName){ 16 | this.fieldName = fieldName; 17 | } 18 | 19 | public String getRealName(){ 20 | return fieldName; 21 | } 22 | 23 | @Override 24 | protected Class getModelClass() { 25 | return getClass().getSuperclass(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/model/FunctionOrValueInterface.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader.model; 2 | 3 | import java.util.Collections; 4 | import java.util.List; 5 | 6 | import com.redhat.ceylon.model.typechecker.model.Generic; 7 | import com.redhat.ceylon.model.typechecker.model.Interface; 8 | import com.redhat.ceylon.model.typechecker.model.Scope; 9 | import com.redhat.ceylon.model.typechecker.model.TypeParameter; 10 | import com.redhat.ceylon.model.typechecker.model.TypedDeclaration; 11 | import com.redhat.ceylon.model.typechecker.model.Unit; 12 | 13 | /** 14 | * Wrapper class which pretends a function or value is an interface, so that they can 15 | * be used to qualify local types in runtime reified checks. 16 | * 17 | * @author Stéphane Épardaud 18 | */ 19 | public class FunctionOrValueInterface extends Interface { 20 | 21 | private final TypedDeclaration declaration; 22 | 23 | public FunctionOrValueInterface(TypedDeclaration declaration){ 24 | this.declaration = declaration; 25 | } 26 | 27 | @Override 28 | public String getQualifier() { 29 | return declaration.getQualifier(); 30 | } 31 | 32 | @Override 33 | public String getName() { 34 | return declaration.getName(); 35 | } 36 | 37 | @Override 38 | public Scope getContainer() { 39 | return declaration.getContainer(); 40 | } 41 | 42 | @Override 43 | public List getTypeParameters() { 44 | return declaration instanceof Generic 45 | ? ((Generic) declaration).getTypeParameters() 46 | : Collections.emptyList(); 47 | } 48 | 49 | @Override 50 | public Unit getUnit() { 51 | return declaration.getUnit(); 52 | } 53 | 54 | public TypedDeclaration getUnderlyingDeclaration() { 55 | return declaration; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/model/JavaBeanValue.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader.model; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import com.redhat.ceylon.model.loader.mirror.MethodMirror; 7 | import com.redhat.ceylon.model.typechecker.model.Declaration; 8 | import com.redhat.ceylon.model.typechecker.model.Value; 9 | 10 | /** 11 | * Normal value which allows us to remember if it's a "get" or "is" type of getter for interop. 12 | * 13 | * @author Stéphane Épardaud 14 | */ 15 | public class JavaBeanValue extends Value implements LocalDeclarationContainer { 16 | private String getterName; 17 | private String setterName; 18 | 19 | private Map localDeclarations; 20 | public final MethodMirror mirror; 21 | 22 | public JavaBeanValue(MethodMirror mirror) { 23 | this.mirror = mirror; 24 | } 25 | 26 | @Override 27 | protected Class getModelClass() { 28 | return getClass().getSuperclass(); 29 | } 30 | 31 | public void setGetterName(String getterName) { 32 | this.getterName = getterName; 33 | } 34 | 35 | public String getSetterName() { 36 | return setterName; 37 | } 38 | 39 | public void setSetterName(String setterName) { 40 | this.setterName = setterName; 41 | } 42 | 43 | public String getGetterName() { 44 | return getterName; 45 | } 46 | 47 | @Override 48 | public Declaration getLocalDeclaration(String name) { 49 | if(localDeclarations == null) 50 | return null; 51 | return localDeclarations.get(name); 52 | } 53 | 54 | @Override 55 | public void addLocalDeclaration(Declaration declaration) { 56 | if(localDeclarations == null) 57 | localDeclarations = new HashMap(); 58 | localDeclarations.put(declaration.getPrefixedName(), declaration); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/model/JavaMethod.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader.model; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import com.redhat.ceylon.model.loader.mirror.MethodMirror; 7 | import com.redhat.ceylon.model.typechecker.model.Declaration; 8 | import com.redhat.ceylon.model.typechecker.model.Function; 9 | 10 | /** 11 | * Instance method that allows us to remember the exact method name 12 | * 13 | * @author Stéphane Épardaud 14 | */ 15 | public class JavaMethod extends Function implements LocalDeclarationContainer { 16 | 17 | private String realName; 18 | private boolean defaultedAnnotation; 19 | public final MethodMirror mirror; 20 | private Map localDeclarations; 21 | 22 | @Override 23 | protected Class getModelClass() { 24 | return getClass().getSuperclass(); 25 | } 26 | 27 | public JavaMethod(MethodMirror mirror){ 28 | this.mirror = mirror; 29 | } 30 | 31 | public void setRealName(String name) { 32 | this.realName = name; 33 | } 34 | 35 | public String getRealName(){ 36 | return realName; 37 | } 38 | 39 | /** 40 | * If this is a method on an annotation type, whether the method has a 41 | * {@code default} expression; 42 | */ 43 | public boolean isDefaultedAnnotation() { 44 | return defaultedAnnotation; 45 | } 46 | 47 | public void setDefaultedAnnotation(boolean defaultedAnnotation) { 48 | this.defaultedAnnotation = defaultedAnnotation; 49 | } 50 | 51 | @Override 52 | public Declaration getLocalDeclaration(String name) { 53 | if(localDeclarations == null) 54 | return null; 55 | return localDeclarations.get(name); 56 | } 57 | 58 | @Override 59 | public void addLocalDeclaration(Declaration declaration) { 60 | if(localDeclarations == null) 61 | localDeclarations = new HashMap(); 62 | localDeclarations.put(declaration.getPrefixedName(), declaration); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/model/LazyContainer.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader.model; 2 | 3 | import com.redhat.ceylon.model.typechecker.model.Declaration; 4 | 5 | public interface LazyContainer extends LazyElement, LocalDeclarationContainer { 6 | public void addMember(Declaration decl); 7 | 8 | } 9 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/model/LazyElement.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader.model; 2 | 3 | 4 | /** 5 | * Represents a lazy declaration. 6 | * 7 | * @author Stéphane Épardaud 8 | */ 9 | public interface LazyElement { 10 | 11 | public boolean isLoaded(); 12 | 13 | public boolean isLocal(); 14 | 15 | public void setLocal(boolean local); 16 | 17 | public boolean isCeylon(); 18 | } 19 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/model/LazyModuleManager.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader.model; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | import com.redhat.ceylon.common.Backend; 7 | import com.redhat.ceylon.common.Backends; 8 | import com.redhat.ceylon.model.cmr.JDKUtils; 9 | import com.redhat.ceylon.model.loader.AbstractModelLoader; 10 | import com.redhat.ceylon.model.typechecker.model.Module; 11 | import com.redhat.ceylon.model.typechecker.model.ModuleImport; 12 | import com.redhat.ceylon.model.typechecker.util.ModuleManager; 13 | 14 | /** 15 | * ModuleManager which can load artifacts from jars and cars. 16 | * 17 | * @author Stéphane Épardaud 18 | */ 19 | public abstract class LazyModuleManager extends ModuleManager { 20 | 21 | public LazyModuleManager() { 22 | super(); 23 | } 24 | 25 | protected void setupIfJDKModule(LazyModule module) { 26 | // Make sure that the java modules are set up properly. 27 | // Bad jdk versions will not be made available and the module validator 28 | // will fail to load their artifacts, and the error is properly handled by the lazy module manager in 29 | // attachErrorToDependencyDeclaration() 30 | String nameAsString = module.getNameAsString(); 31 | String version = module.getVersion(); 32 | if(version != null 33 | && AbstractModelLoader.isJDKModule(nameAsString)){ 34 | if(JDKUtils.jdk.providesVersion(version)){ 35 | module.setAvailable(true); 36 | module.setJava(true); 37 | module.setNativeBackends(Backend.Java.asSet()); 38 | } 39 | } 40 | } 41 | 42 | 43 | /** 44 | * To be overriden by reflection module manager, because reflection requires even types of private members 45 | * of imported modules to be in the classpath, and those could be of unimported modules (since they're private 46 | * that's allowed). 47 | */ 48 | public boolean shouldLoadTransitiveDependencies(){ 49 | return false; 50 | } 51 | 52 | @Override 53 | protected abstract Module createModule(List moduleName, String version); 54 | 55 | public abstract AbstractModelLoader getModelLoader(); 56 | 57 | /** 58 | * Return true if this module should be loaded from source we are compiling 59 | * and not from its compiled artifact at all. Returns false by default, so 60 | * modules will be laoded from their compiled artifact. 61 | */ 62 | public boolean isModuleLoadedFromSource(String moduleName){ 63 | return false; 64 | } 65 | 66 | @Override 67 | public Iterable getSearchedArtifactExtensions() { 68 | return Arrays.asList("car", "jar"); 69 | } 70 | 71 | @Override 72 | public Backends getSupportedBackends() { 73 | return Backend.Java.asSet(); 74 | } 75 | 76 | @Override 77 | public void addImplicitImports() { 78 | Module languageModule = modules.getLanguageModule(); 79 | for(Module m : modules.getListOfModules()){ 80 | // Java modules don't depend on ceylon.language 81 | if((m instanceof LazyModule == false || !((LazyModule)m).isJava()) && !m.equals(languageModule)) { 82 | // add ceylon.language if required 83 | ModuleImport moduleImport = findImport(m, languageModule); 84 | if (moduleImport == null) { 85 | moduleImport = new ModuleImport(languageModule, false, true); 86 | m.addImport(moduleImport); 87 | } 88 | } 89 | } 90 | } 91 | 92 | @Override 93 | protected boolean compareVersions(Module current, String version, String currentVersion) { 94 | String name = current.getNameAsString(); 95 | if(JDKUtils.isJDKModule(name) || JDKUtils.isOracleJDKModule(name)){ 96 | // if we're running JDK8, pretend that it provides JDK7 modules 97 | if(JDKUtils.jdk.providesVersion(version) 98 | && JDKUtils.jdk.providesVersion(currentVersion)) 99 | return true; 100 | } 101 | return currentVersion == null || version == null || currentVersion.equals(version); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/model/LocalDeclarationContainer.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader.model; 2 | 3 | import com.redhat.ceylon.model.typechecker.model.Declaration; 4 | import com.redhat.ceylon.model.typechecker.model.Scope; 5 | 6 | /** 7 | * Scope used to contain local declarations. 8 | * 9 | * @author Stéphane Épardaud 10 | */ 11 | public interface LocalDeclarationContainer extends Scope { 12 | 13 | /** 14 | * Gets a local declaration by (prefixed) name 15 | */ 16 | Declaration getLocalDeclaration(String name); 17 | 18 | /** 19 | * Adds a new local declaration. Its prefixed name must be unique. 20 | */ 21 | void addLocalDeclaration(Declaration decl); 22 | } 23 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/model/OutputElement.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader.model; 2 | 3 | 4 | 5 | 6 | /** 7 | * Enumerates the possible Ceylon-generated 8 | * Java program elements capable of supporting 9 | * Java annotations. 10 | * 11 | * @see AnnotationTarget 12 | */ 13 | public enum OutputElement { 14 | TYPE, 15 | FIELD, 16 | METHOD, 17 | GETTER, 18 | SETTER, 19 | PARAMETER, 20 | CONSTRUCTOR, 21 | LOCAL_VARIABLE, 22 | ANNOTATION_TYPE, 23 | PACKAGE; 24 | } -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/loader/model/SetterWithLocalDeclarations.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.loader.model; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import com.redhat.ceylon.model.loader.mirror.ClassMirror; 7 | import com.redhat.ceylon.model.typechecker.model.Declaration; 8 | import com.redhat.ceylon.model.typechecker.model.Setter; 9 | 10 | /** 11 | * Setter subclass which can contain local declarations. 12 | * 13 | * @author Stéphane Épardaud 14 | */ 15 | public class SetterWithLocalDeclarations extends Setter implements LocalDeclarationContainer { 16 | 17 | private Map localDeclarations; 18 | public final ClassMirror classMirror; 19 | 20 | public SetterWithLocalDeclarations(ClassMirror classMirror) { 21 | this.classMirror = classMirror; 22 | } 23 | 24 | @Override 25 | public Declaration getLocalDeclaration(String name) { 26 | if(localDeclarations == null) 27 | return null; 28 | return localDeclarations.get(name); 29 | } 30 | 31 | @Override 32 | public void addLocalDeclaration(Declaration declaration) { 33 | if(localDeclarations == null) 34 | localDeclarations = new HashMap(); 35 | localDeclarations.put(declaration.getPrefixedName(), declaration); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/context/TypeCache.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.context; 2 | 3 | import java.util.LinkedList; 4 | import java.util.List; 5 | import java.util.Map; 6 | import java.util.concurrent.Callable; 7 | import java.util.concurrent.ConcurrentHashMap; 8 | 9 | import com.redhat.ceylon.model.typechecker.model.Type; 10 | import com.redhat.ceylon.model.typechecker.model.TypeDeclaration; 11 | import com.redhat.ceylon.model.typechecker.model.UnknownType; 12 | 13 | public class TypeCache { 14 | 15 | private static boolean cachingEnabledByDefault = true; 16 | 17 | public static void setEnabledByDefault(boolean enabled) { 18 | cachingEnabledByDefault = enabled; 19 | } 20 | 21 | private static final ThreadLocal cachingEnabled = 22 | new ThreadLocal(); 23 | 24 | public static Boolean setEnabled(Boolean enabled) { 25 | Boolean was = cachingEnabled.get(); 26 | cachingEnabled.set(enabled); 27 | return was; 28 | } 29 | 30 | private static T doWithExplicitCaching(boolean cacheEnabled, final Callable action) { 31 | Boolean was = TypeCache.setEnabled(cacheEnabled); 32 | try { 33 | return action.call(); 34 | } catch(Exception e) { 35 | if (e instanceof RuntimeException) { 36 | throw (RuntimeException) e; 37 | } else { 38 | throw new RuntimeException(e); 39 | } 40 | } finally { 41 | TypeCache.setEnabled(was); 42 | } 43 | } 44 | 45 | private static void doWithExplicitCaching(boolean cacheEnabled, final Runnable action) { 46 | Boolean was = TypeCache.setEnabled(cacheEnabled); 47 | try { 48 | action.run(); 49 | } catch(Exception e) { 50 | if (e instanceof RuntimeException) { 51 | throw (RuntimeException) e; 52 | } else { 53 | throw new RuntimeException(e); 54 | } 55 | } finally { 56 | TypeCache.setEnabled(was); 57 | } 58 | } 59 | 60 | public static T doWithCaching(final Callable action) { 61 | return doWithExplicitCaching(true, action); 62 | } 63 | 64 | public static T doWithoutCaching(final Callable action) { 65 | return doWithExplicitCaching(false, action); 66 | } 67 | 68 | public static void doWithCaching(final Runnable action) { 69 | doWithExplicitCaching(true, action); 70 | } 71 | 72 | public static void doWithoutCaching(final Runnable action) { 73 | doWithExplicitCaching(false, action); 74 | } 75 | 76 | public static boolean isEnabled() { 77 | Boolean cie = cachingEnabled.get(); 78 | return cie == null ? cachingEnabledByDefault : cie; 79 | } 80 | 81 | // need a special value for null because ConcurrentHashMap does not support null 82 | private final static Type NULL_VALUE = new UnknownType(null).getType(); 83 | // need ConcurrentHashMap even for the cache, otherwise get/put/containsKey can get info infinite loops 84 | // on concurrent operations 85 | private final Map> superTypes = 86 | new ConcurrentHashMap>(); 87 | 88 | public boolean containsKey(Type producedType, TypeDeclaration dec) { 89 | Map cache = superTypes.get(producedType); 90 | if (cache == null) { 91 | return false; 92 | } 93 | return cache.containsKey(dec); 94 | } 95 | 96 | public Type get(Type producedType, TypeDeclaration dec) { 97 | Map cache = superTypes.get(producedType); 98 | if (cache == null) { 99 | return null; 100 | } 101 | Type ret = cache.get(dec); 102 | return ret == NULL_VALUE ? null : ret; 103 | } 104 | 105 | public void put(Type producedType, TypeDeclaration dec, Type superType) { 106 | Map cache = superTypes.get(producedType); 107 | if (cache == null) { 108 | // need ConcurrentHashMap even for the cache, otherwise get/put/containsKey can get info infinite loops 109 | // on concurrent operations 110 | cache = new ConcurrentHashMap(); 111 | superTypes.put(producedType, cache); 112 | } 113 | if (superType == null) { 114 | superType = NULL_VALUE; 115 | } 116 | cache.put(dec, superType); 117 | } 118 | 119 | public void clear(){ 120 | superTypes.clear(); 121 | } 122 | 123 | public void clearForDeclaration(TypeDeclaration decl) { 124 | // clear the whole cache for now, unless I can figure out exactly what to 125 | // clear 126 | clear(); 127 | } 128 | 129 | public void clearNullValues() { 130 | List cachesToremove = new LinkedList(); 131 | for (Map.Entry> entry: 132 | superTypes.entrySet()) { 133 | Map cache = entry.getValue(); 134 | if (cache == null) { 135 | cachesToremove.add(entry.getKey()); 136 | } 137 | else { 138 | List valuesToremove = 139 | new LinkedList(); 140 | for (Map.Entry cacheEntry: 141 | cache.entrySet()) { 142 | if (cacheEntry.getValue() == NULL_VALUE) { 143 | valuesToremove.add(cacheEntry.getKey()); 144 | } 145 | } 146 | for (TypeDeclaration toRemove: valuesToremove) { 147 | cache.remove(toRemove); 148 | } 149 | } 150 | } 151 | for (Type toRemove: cachesToremove) { 152 | superTypes.remove(toRemove); 153 | } 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/Annotated.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | import java.util.List; 4 | 5 | public interface Annotated { 6 | 7 | List getAnnotations(); 8 | 9 | } -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/Annotation.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | public class Annotation { 9 | private String name; 10 | private Map namedArguments = new HashMap(); 11 | private List positionalArguments = new ArrayList(); 12 | 13 | public Annotation(){} 14 | 15 | public Annotation(String name){ 16 | this.name = name; 17 | } 18 | 19 | public String getName() { 20 | return name; 21 | } 22 | 23 | public void setName(String name) { 24 | this.name = name; 25 | } 26 | 27 | public Map getNamedArguments() { 28 | return namedArguments; 29 | } 30 | 31 | public void addNamedArgument(String param, String value) { 32 | this.namedArguments.put(param, value); 33 | } 34 | 35 | public List getPositionalArguments() { 36 | return positionalArguments; 37 | } 38 | 39 | public void addPositionalArgment(String value) { 40 | positionalArguments.add(value); 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | String args = ""; 46 | if (!positionalArguments.isEmpty()) { 47 | args = positionalArguments.toString() 48 | .replace('[', '(') 49 | .replace(']', ')'); 50 | } 51 | else if (!namedArguments.isEmpty()) { 52 | args = namedArguments.toString() 53 | .replace(',', ';'); 54 | } 55 | return name + args; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/ClassAlias.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | import java.util.List; 4 | 5 | public class ClassAlias extends Class { 6 | 7 | private TypeDeclaration constructor; 8 | 9 | public TypeDeclaration getConstructor() { 10 | return constructor; 11 | } 12 | 13 | public void setConstructor(TypeDeclaration constructor) { 14 | this.constructor = constructor; 15 | } 16 | 17 | @Override 18 | public boolean isAlias() { 19 | return true; 20 | } 21 | 22 | @Override 23 | public boolean isEmptyType() { 24 | Type et = getExtendedType(); 25 | if (et!=null) { 26 | Type.checkDepth(); 27 | Type.incDepth(); 28 | try { 29 | return et.getDeclaration().isEmptyType(); 30 | } 31 | finally { 32 | Type.decDepth(); 33 | } 34 | } 35 | else { 36 | return false; 37 | } 38 | } 39 | 40 | @Override 41 | public boolean isTupleType() { 42 | Type et = getExtendedType(); 43 | if (et!=null) { 44 | Type.checkDepth(); 45 | Type.incDepth(); 46 | try { 47 | return et.getDeclaration().isTupleType(); 48 | } 49 | finally { 50 | Type.decDepth(); 51 | } 52 | } 53 | else { 54 | return false; 55 | } 56 | } 57 | 58 | @Override 59 | public boolean isSequentialType() { 60 | Type et = getExtendedType(); 61 | if (et!=null) { 62 | Type.checkDepth(); 63 | Type.incDepth(); 64 | try { 65 | return et.getDeclaration().isSequentialType(); 66 | } 67 | finally { 68 | Type.decDepth(); 69 | } 70 | } 71 | else { 72 | return false; 73 | } 74 | } 75 | 76 | @Override 77 | public boolean isSequenceType() { 78 | Type et = getExtendedType(); 79 | if (et!=null) { 80 | Type.checkDepth(); 81 | Type.incDepth(); 82 | try { 83 | return et.getDeclaration().isSequenceType(); 84 | } 85 | finally { 86 | Type.decDepth(); 87 | } 88 | } 89 | else { 90 | return false; 91 | } 92 | } 93 | 94 | @Override 95 | void collectSupertypeDeclarations( 96 | List results) { 97 | Type et = getExtendedType(); 98 | if (et!=null) { 99 | et.getDeclaration() 100 | .collectSupertypeDeclarations(results); 101 | } 102 | } 103 | 104 | @Override 105 | public boolean inherits(TypeDeclaration dec) { 106 | Type et = getExtendedType(); 107 | if (et!=null) { 108 | Type.checkDepth(); 109 | Type.incDepth(); 110 | try { 111 | return et.getDeclaration().inherits(dec); 112 | } 113 | finally { 114 | Type.decDepth(); 115 | } 116 | } 117 | return false; 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/ClassOrInterface.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | import static java.util.Collections.emptyList; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.Objects; 8 | 9 | 10 | public abstract class ClassOrInterface extends TypeDeclaration { 11 | 12 | private List members = new ArrayList(3); 13 | private List annotations = new ArrayList(4); 14 | private List typeParameters = emptyList(); 15 | 16 | @Override 17 | public List getAnnotations() { 18 | return annotations; 19 | } 20 | 21 | @Override 22 | public List getMembers() { 23 | return members; 24 | } 25 | 26 | @Override 27 | public void addMember(Declaration declaration) { 28 | members.add(declaration); 29 | } 30 | 31 | @Override 32 | public boolean isMember() { 33 | return getContainer() instanceof ClassOrInterface; 34 | } 35 | 36 | @Override 37 | public Type getDeclaringType(Declaration d) { 38 | //look for it as a declared or inherited 39 | //member of the current class or interface 40 | if (d.isMember()) { 41 | TypeDeclaration ctd = 42 | (TypeDeclaration) 43 | d.getContainer(); 44 | Type st = getType().getSupertype(ctd); 45 | //return st; 46 | if (st!=null) { 47 | return st; 48 | } 49 | else { 50 | return getContainer().getDeclaringType(d); 51 | } 52 | } 53 | else { 54 | return null; 55 | } 56 | } 57 | 58 | @Override 59 | public boolean isParameterized() { 60 | return !typeParameters.isEmpty(); 61 | } 62 | 63 | public List getTypeParameters() { 64 | return typeParameters; 65 | } 66 | 67 | public void setTypeParameters(List typeParameters) { 68 | this.typeParameters = typeParameters; 69 | } 70 | 71 | @Override 72 | public DeclarationKind getDeclarationKind() { 73 | return DeclarationKind.TYPE; 74 | } 75 | 76 | @Override 77 | public Type getExtendedType() { 78 | Type et = super.getExtendedType(); 79 | if (et == null) { 80 | //for Anything 81 | return null; 82 | } 83 | else { 84 | TypeDeclaration etd = et.getDeclaration(); 85 | //it is allowed to be a class, 86 | //an interface (for interface aliases) 87 | //or a constructor (for classes) 88 | if (etd==this || et.isTypeAlias()) { 89 | return unit.getAnythingType(); 90 | } 91 | else { 92 | return et; 93 | } 94 | } 95 | } 96 | 97 | @Override 98 | public List getSatisfiedTypes() { 99 | List satisfiedTypes = 100 | super.getSatisfiedTypes(); 101 | List sts = satisfiedTypes; 102 | for (int i=0, size=sts.size(); i(sts); 109 | } 110 | sts.remove(i); 111 | size--; 112 | i--; 113 | } 114 | } 115 | } 116 | return sts; 117 | } 118 | 119 | @Override 120 | public List getCaseTypes() { 121 | List caseTypes = 122 | super.getCaseTypes(); 123 | List cts = caseTypes; 124 | if (cts!=null) { 125 | for (int i=0, size=cts.size(); i(cts); 132 | } 133 | cts.remove(i); 134 | i--; 135 | size--; 136 | } 137 | } 138 | } 139 | } 140 | return cts; 141 | } 142 | 143 | @Override 144 | void collectSupertypeDeclarations( 145 | List results) { 146 | if (!results.contains(this)) { 147 | results.add(this); 148 | Type et = getExtendedType(); 149 | List stds = getSatisfiedTypes(); 150 | if (et!=null) { 151 | et.getDeclaration() 152 | .collectSupertypeDeclarations(results); 153 | } 154 | for (int i=0, l=stds.size(); i specifiedValues; 20 | private List members = new ArrayList(3); 21 | private boolean let; 22 | 23 | @Override 24 | public boolean isToplevel() { 25 | return false; 26 | } 27 | 28 | public boolean isLet() { 29 | return let; 30 | } 31 | 32 | public void setLet(boolean let) { 33 | this.let = let; 34 | } 35 | 36 | @Override 37 | public List getMembers() { 38 | return members; 39 | } 40 | 41 | @Override 42 | public void addMember(Declaration declaration) { 43 | members.add(declaration); 44 | } 45 | 46 | 47 | private int id; 48 | 49 | public void setId(int id) { 50 | this.id = id; 51 | } 52 | 53 | @Override 54 | public int hashCode() { 55 | int ret = 17; 56 | ret = (31 * ret) + getContainer().hashCode(); 57 | ret = (31 * ret) + id; 58 | return ret; 59 | } 60 | 61 | @Override 62 | public boolean equals(Object obj) { 63 | if(obj == this) 64 | return true; 65 | if (obj instanceof ControlBlock) { 66 | ControlBlock that = (ControlBlock) obj; 67 | return id==that.id && 68 | getContainer().equals(that.getContainer()); 69 | } 70 | else { 71 | return false; 72 | } 73 | } 74 | 75 | public Set getSpecifiedValues() { 76 | return specifiedValues; 77 | } 78 | 79 | public void setSpecifiedValues(Set assigned) { 80 | this.specifiedValues = assigned; 81 | } 82 | 83 | @Override 84 | public Backends getScopedBackends() { 85 | return getScope().getScopedBackends(); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/DecidabilityException.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | @SuppressWarnings("serial") 4 | public class DecidabilityException 5 | extends RuntimeException { 6 | 7 | DecidabilityException() { 8 | super("possible undecidability: typechecker detected possible nontermination and aborted algorithm"); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/DeclarationCompleter.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | /** 4 | * Completer for declarations that will only complete certain 5 | * fields which are expensive to compute, on demand. 6 | * 7 | * @author Stéphane Épardaud 8 | */ 9 | public interface DeclarationCompleter { 10 | 11 | /** 12 | * Completes the actual and refinedDeclaration 13 | * members of the given declaration. 14 | */ 15 | public void completeActual(Declaration decl); 16 | } 17 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/DeclarationKind.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | /** 4 | * An unscientific categorization of the kinds of 5 | * declarations we have (for use in heuristic 6 | * comparisons in the IDE). Note that this 7 | * classification doesn't really relate to anything 8 | * in the language spec. 9 | * 10 | * @author Gavin King 11 | */ 12 | public enum DeclarationKind { 13 | TYPE, TYPE_PARAMETER, MEMBER, SETTER, CONSTRUCTOR 14 | } 15 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/DeclarationWithProximity.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | public class DeclarationWithProximity { 4 | private Declaration declaration; 5 | private int proximity; 6 | private String name; 7 | private NamedArgumentList namedArgumentList; 8 | private boolean unimported; 9 | private boolean alias; 10 | 11 | public NamedArgumentList getNamedArgumentList() { 12 | return namedArgumentList; 13 | } 14 | 15 | public DeclarationWithProximity(Parameter parameter, NamedArgumentList nal) { 16 | this.declaration = parameter.getModel(); 17 | this.proximity = 0; 18 | this.name = declaration.getName(); 19 | this.namedArgumentList = nal; 20 | } 21 | 22 | public DeclarationWithProximity(Declaration declaration, int proximity) { 23 | this.declaration = declaration; 24 | this.proximity = proximity; 25 | this.name = declaration.getName(); 26 | } 27 | 28 | public DeclarationWithProximity(Declaration declaration, int proximity, boolean unimported) { 29 | this.declaration = declaration; 30 | this.proximity = proximity; 31 | this.name = declaration.getName(); 32 | this.unimported = unimported; 33 | } 34 | 35 | public DeclarationWithProximity(Declaration declaration, DeclarationWithProximity dwp) { 36 | this.declaration = declaration; 37 | this.proximity = dwp.proximity; 38 | this.name = dwp.name; 39 | this.unimported = dwp.unimported; 40 | } 41 | 42 | public DeclarationWithProximity(Import imp, int proximity) { 43 | this.declaration = imp.getDeclaration(); 44 | this.proximity = proximity; 45 | this.name = imp.getAlias(); 46 | } 47 | 48 | public DeclarationWithProximity(String alias, Declaration member, int proximity) { 49 | this.name = alias; 50 | this.alias = true; 51 | this.declaration = member; 52 | this.proximity = proximity; 53 | } 54 | 55 | public Declaration getDeclaration() { 56 | return declaration; 57 | } 58 | 59 | public int getProximity() { 60 | return proximity; 61 | } 62 | 63 | public String getName() { 64 | return name; 65 | } 66 | 67 | public boolean isUnimported() { 68 | return unimported; 69 | } 70 | 71 | public boolean isAlias(){ 72 | return alias; 73 | } 74 | 75 | @Override 76 | public String toString() { 77 | return name + ":" + declaration.toString() + "@" + proximity + "(alias: "+alias+")"; 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/ExternalUnit.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | 4 | public class ExternalUnit extends Unit {} 5 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/Function.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | import static java.util.Collections.emptyList; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import com.redhat.ceylon.common.Backends; 9 | 10 | /** 11 | * A function. Note that a function must have at least one 12 | * parameter list. 13 | * 14 | * @author Gavin King 15 | */ 16 | public class Function extends FunctionOrValue implements Generic, Scope, Functional { 17 | 18 | private static final int VOID = 1<<22; 19 | private static final int DEFERRED = 1<<23; 20 | private static final int NO_NAME = 1<<24; 21 | 22 | private List typeParameters = emptyList(); 23 | private List parameterLists = new ArrayList(1); 24 | private Object annotationConstructor; 25 | 26 | public Object getAnnotationConstructor() { 27 | return annotationConstructor; 28 | } 29 | 30 | public void setAnnotationConstructor(Object annotationInstantiation) { 31 | this.annotationConstructor = annotationInstantiation; 32 | } 33 | 34 | @Override 35 | public boolean isParameterized() { 36 | return !typeParameters.isEmpty(); 37 | } 38 | 39 | public List getTypeParameters() { 40 | return typeParameters; 41 | } 42 | 43 | public void setTypeParameters(List typeParameters) { 44 | this.typeParameters = typeParameters; 45 | } 46 | 47 | @Override 48 | public ParameterList getFirstParameterList() { 49 | return getParameterLists().get(0); 50 | } 51 | 52 | @Override 53 | public List getParameterLists() { 54 | return parameterLists; 55 | } 56 | 57 | @Override 58 | public void addParameterList(ParameterList pl) { 59 | parameterLists.add(pl); 60 | } 61 | 62 | @Override 63 | public boolean isDeclaredVoid() { 64 | return (flags&VOID)!=0; 65 | } 66 | 67 | public void setDeclaredVoid(boolean declaredVoid) { 68 | if (declaredVoid) { 69 | flags|=VOID; 70 | } 71 | else { 72 | flags&=(~VOID); 73 | } 74 | } 75 | 76 | public boolean isDeferred() { 77 | return (flags&DEFERRED)!=0; 78 | } 79 | 80 | public void setDeferred(boolean deferred) { 81 | if (deferred) { 82 | flags|=DEFERRED; 83 | } 84 | else { 85 | flags&=(~DEFERRED); 86 | } 87 | } 88 | 89 | public Parameter getParameter(String name) { 90 | for (Declaration d : getMembers()) { 91 | if (d.isParameter() && ModelUtil.isNamed(name, d)) { 92 | FunctionOrValue mod = (FunctionOrValue) d; 93 | return mod.getInitializerParameter(); 94 | } 95 | } 96 | return null; 97 | } 98 | 99 | @Override 100 | public boolean isFunctional() { 101 | return true; 102 | } 103 | 104 | //TODO: replace with setNamed() 105 | public void setAnonymous(boolean anonymous) { 106 | if (anonymous) { 107 | flags|=NO_NAME; 108 | } 109 | else { 110 | flags&=(~NO_NAME); 111 | } 112 | } 113 | 114 | @Override 115 | public boolean isAnonymous() { 116 | return (flags&NO_NAME)!=0; 117 | } 118 | 119 | /** 120 | * Returns true if this method is anonymous. 121 | */ 122 | @Override 123 | public boolean isNamed() { 124 | return (flags&NO_NAME)==0; 125 | } 126 | 127 | @Override 128 | public Backends getScopedBackends() { 129 | return super.getScopedBackends(); 130 | } 131 | 132 | @Override 133 | public String toString() { 134 | Type type = getType(); 135 | if (type==null) { 136 | return "function " + toStringName(); 137 | } 138 | else { 139 | StringBuilder params = new StringBuilder(); 140 | for (ParameterList pl: getParameterLists()) { 141 | params.append("("); 142 | boolean first = true; 143 | for (Parameter p: pl.getParameters()) { 144 | if (first) { 145 | first = false; 146 | } 147 | else { 148 | params.append(", "); 149 | } 150 | if (p.getType()!=null) { 151 | params.append(p.getType().asString()); 152 | params.append(" "); 153 | } 154 | params.append(p.getName()); 155 | } 156 | params.append(")"); 157 | } 158 | return "function " + toStringName() + params + 159 | " => " + type.asString(); 160 | } 161 | } 162 | 163 | } 164 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/FunctionOrValue.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public abstract class FunctionOrValue extends TypedDeclaration { 7 | 8 | private static final int CAPTURED = 1<<17; 9 | private static final int SHORTCUT_REFINEMENT = 1<<18; 10 | private static final int OVERLOADED = 1<<19; 11 | private static final int ABSTRACTION = 1<<20; 12 | private static final int IMPLEMENTED = 1<<21; 13 | 14 | private Parameter initializerParameter; 15 | private List members = new ArrayList(3); 16 | private List annotations = new ArrayList(4); 17 | private List overloads; 18 | 19 | @Override 20 | public List getAnnotations() { 21 | return annotations; 22 | } 23 | 24 | @Override 25 | public List getMembers() { 26 | return members; 27 | } 28 | 29 | public void addMember(Declaration declaration) { 30 | members.add(declaration); 31 | } 32 | 33 | public boolean isShortcutRefinement() { 34 | return (flags&SHORTCUT_REFINEMENT)!=0; 35 | } 36 | 37 | public void setShortcutRefinement(boolean shortcutRefinement) { 38 | if (shortcutRefinement) { 39 | flags|=SHORTCUT_REFINEMENT; 40 | } 41 | else { 42 | flags&=(~SHORTCUT_REFINEMENT); 43 | } 44 | } 45 | 46 | @Override 47 | public DeclarationKind getDeclarationKind() { 48 | return DeclarationKind.MEMBER; 49 | } 50 | 51 | public Parameter getInitializerParameter() { 52 | return initializerParameter; 53 | } 54 | 55 | public void setInitializerParameter(Parameter d) { 56 | initializerParameter = d; 57 | } 58 | 59 | @Override 60 | public boolean isParameter() { 61 | return initializerParameter!=null; 62 | } 63 | 64 | public boolean isTransient() { 65 | return true; 66 | } 67 | 68 | @Override 69 | public boolean isCaptured() { 70 | return (flags&CAPTURED)!=0; 71 | } 72 | 73 | public void setCaptured(boolean captured) { 74 | if (captured) { 75 | flags|=CAPTURED; 76 | } 77 | else { 78 | flags&=(~CAPTURED); 79 | } 80 | } 81 | 82 | @Override 83 | public boolean isOverloaded() { 84 | return (flags&OVERLOADED)!=0; 85 | } 86 | 87 | public void setOverloaded(boolean overloaded) { 88 | if (overloaded) { 89 | flags|=OVERLOADED; 90 | } 91 | else { 92 | flags&=(~OVERLOADED); 93 | } 94 | } 95 | 96 | public void setAbstraction(boolean abstraction) { 97 | if (abstraction) { 98 | flags|=ABSTRACTION; 99 | } 100 | else { 101 | flags&=(~ABSTRACTION); 102 | } 103 | } 104 | 105 | @Override 106 | public boolean isAbstraction() { 107 | return (flags&ABSTRACTION)!=0; 108 | } 109 | 110 | @Override 111 | public List getOverloads() { 112 | return overloads; 113 | } 114 | 115 | public void setOverloads(List overloads) { 116 | this.overloads = overloads; 117 | } 118 | 119 | public void initOverloads(FunctionOrValue... initial) { 120 | overloads = 121 | new ArrayList 122 | (initial.length+1); 123 | for (Declaration d: initial) { 124 | overloads.add(d); 125 | } 126 | } 127 | 128 | public boolean isImplemented() { 129 | return (flags&IMPLEMENTED)!=0; 130 | } 131 | 132 | public void setImplemented(boolean implemented) { 133 | if (implemented) { 134 | flags|=IMPLEMENTED; 135 | } 136 | else { 137 | flags&=(~IMPLEMENTED); 138 | } 139 | } 140 | 141 | } 142 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/Functional.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Represents a declaration which has a list of parameters. 7 | * 8 | * @author Gavin King 9 | */ 10 | public interface Functional { 11 | 12 | public ParameterList getFirstParameterList(); 13 | 14 | public List getParameterLists(); 15 | 16 | public void addParameterList(ParameterList pl); 17 | 18 | public Type getType(); 19 | 20 | public String getName(); 21 | public String getName(Unit unit); 22 | 23 | public Parameter getParameter(String name); 24 | 25 | // public List getTypeParameters(); 26 | 27 | public boolean isDeclaredVoid(); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/Generic.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | import java.util.List; 4 | 5 | public interface Generic { 6 | public List getTypeParameters(); 7 | public void setTypeParameters(List params); 8 | } 9 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/Getter.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | 4 | /** 5 | * An attribute getter. 6 | * 7 | * @author Gavin King 8 | */ 9 | @Deprecated 10 | public class Getter extends Value implements Scope { 11 | @Override 12 | public boolean isTransient() { 13 | return true; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/Import.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | public class Import { 4 | 5 | private TypeDeclaration typeDeclaration; 6 | private String alias; 7 | private Declaration declaration; 8 | private boolean wildcardImport; 9 | private boolean ambiguous; 10 | 11 | public Import() {} 12 | 13 | public Declaration getDeclaration() { 14 | return declaration; 15 | } 16 | 17 | public void setDeclaration(Declaration declaration) { 18 | this.declaration = declaration; 19 | } 20 | 21 | public String getAlias() { 22 | return alias; 23 | } 24 | 25 | public void setAlias(String alias) { 26 | this.alias = alias; 27 | } 28 | 29 | public boolean isAmbiguous() { 30 | return ambiguous; 31 | } 32 | 33 | public void setAmbiguous(boolean ambiguous) { 34 | this.ambiguous = ambiguous; 35 | } 36 | 37 | public TypeDeclaration getTypeDeclaration() { 38 | return typeDeclaration; 39 | } 40 | 41 | public void setTypeDeclaration(TypeDeclaration typeDeclaration) { 42 | this.typeDeclaration = typeDeclaration; 43 | } 44 | 45 | @Override 46 | public String toString() { 47 | return "import " + 48 | (typeDeclaration==null ? 49 | "" : typeDeclaration.getName() + " { ") + 50 | alias + " = " + 51 | declaration.getName() + 52 | (typeDeclaration==null ? 53 | "" : " }"); 54 | } 55 | 56 | public boolean isWildcardImport() { 57 | return wildcardImport; 58 | } 59 | 60 | public void setWildcardImport(boolean wildcardImport) { 61 | this.wildcardImport = wildcardImport; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/ImportList.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | import com.redhat.ceylon.common.Backends; 9 | 10 | //Note that this class exists to support 11 | //autocompletion in the IDE 12 | public class ImportList implements Scope { 13 | 14 | private Scope container; 15 | private ImportableScope importedScope; 16 | private List imports = new ArrayList(); 17 | 18 | @Override 19 | public boolean isToplevel() { 20 | return false; 21 | } 22 | 23 | @Override 24 | public List getMembers() { 25 | throw new UnsupportedOperationException(); 26 | } 27 | 28 | @Override 29 | public void addMember(Declaration declaration) { 30 | throw new UnsupportedOperationException(); 31 | } 32 | 33 | @Override 34 | public String getQualifiedNameString() { 35 | return getContainer().getQualifiedNameString(); 36 | } 37 | 38 | @Override 39 | public Type getDeclaringType(Declaration d) { 40 | return null; 41 | } 42 | 43 | @Override 44 | public Declaration getMemberOrParameter(Unit unit, String name, List signature, boolean ellipsis) { 45 | return getContainer().getMemberOrParameter(unit, name, signature, ellipsis); 46 | } 47 | 48 | @Override 49 | public Declaration getMember(String name, List signature, boolean ellipsis) { 50 | return getContainer().getMember(name, signature, ellipsis); 51 | } 52 | 53 | @Override 54 | public Declaration getDirectMember(String name, List signature, boolean ellipsis) { 55 | return getContainer().getDirectMember(name, signature, ellipsis); 56 | } 57 | 58 | @Override 59 | public Declaration getDirectMemberForBackend(String name, Backends backends) { 60 | return getContainer().getDirectMemberForBackend(name, backends); 61 | } 62 | 63 | @Override 64 | public boolean isInherited(Declaration d) { 65 | return false; 66 | } 67 | 68 | @Override 69 | public TypeDeclaration getInheritingDeclaration(Declaration d) { 70 | return null; 71 | } 72 | 73 | @Override 74 | public Scope getContainer() { 75 | return container; 76 | } 77 | 78 | @Override 79 | public Scope getScope() { 80 | return container; 81 | } 82 | 83 | public void setContainer(Scope container) { 84 | this.container = container; 85 | } 86 | 87 | @Override 88 | public Map getMatchingDeclarations(Unit unit, 89 | String startingWith, int proximity) { 90 | if (importedScope!=null) { 91 | if (unit.getPackage().equals(importedScope)) { 92 | return unit.getPackage().getMatchingDeclarations(unit, startingWith, proximity); 93 | } 94 | else { 95 | return importedScope.getImportableDeclarations(unit, startingWith, imports, proximity); 96 | } 97 | } 98 | else { 99 | return Collections.emptyMap(); 100 | } 101 | } 102 | 103 | public ImportableScope getImportedScope() { 104 | return importedScope; 105 | } 106 | 107 | public void setImportedScope(ImportableScope importedScope) { 108 | this.importedScope = importedScope; 109 | } 110 | 111 | public List getImports() { 112 | return imports; 113 | } 114 | 115 | public boolean hasImport(Declaration d) { 116 | for (Import i: getImports()) { 117 | if (!i.isAmbiguous() && 118 | i.getDeclaration().equals(d)) { 119 | return true; 120 | } 121 | } 122 | return false; 123 | } 124 | 125 | public Import getImport(String alias) { 126 | for (Import i: getImports()) { 127 | if (!i.isAmbiguous() && 128 | i.getAlias().equals(alias)) { 129 | return i; 130 | } 131 | } 132 | return null; 133 | } 134 | 135 | @Override 136 | public Backends getScopedBackends() { 137 | return getScope().getScopedBackends(); 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/ImportableScope.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | public interface ImportableScope extends Scope { 7 | public Map getImportableDeclarations(Unit unit, String startingWith, List imports, int proximity); 8 | } 9 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/Interface.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | import java.util.List; 4 | import java.util.Objects; 5 | 6 | public class Interface extends ClassOrInterface { 7 | 8 | private String javaCompanionClassName; 9 | private Boolean companionClassNeeded; 10 | 11 | @Override 12 | public boolean isAbstract() { 13 | return true; 14 | } 15 | 16 | @Override 17 | public boolean isEmpty() { 18 | return Objects.equals(getQualifiedNameString(), 19 | "ceylon.language::Empty"); 20 | } 21 | 22 | @Override 23 | public boolean isSequence() { 24 | return Objects.equals(getQualifiedNameString(), 25 | "ceylon.language::Sequence"); 26 | } 27 | 28 | @Override 29 | public boolean isSequential() { 30 | return Objects.equals(getQualifiedNameString(), 31 | "ceylon.language::Sequential"); 32 | } 33 | 34 | @Override 35 | public boolean isIterable() { 36 | return Objects.equals(getQualifiedNameString(), 37 | "ceylon.language::Iterable"); 38 | } 39 | 40 | @Override 41 | public boolean inherits(TypeDeclaration dec) { 42 | if (dec.isAnything() || dec.isObject()) { 43 | return true; 44 | } 45 | else if (dec instanceof Class) { 46 | //interface can't inherit any other class 47 | return false; 48 | } 49 | else if (dec instanceof Interface && equals(dec)) { 50 | return true; 51 | } 52 | else { 53 | //TODO: optimize this to avoid walking the 54 | // same supertypes multiple times 55 | if (dec instanceof Interface) { 56 | List sts = getSatisfiedTypes(); 57 | for (int i = 0, s=sts.size(); i results) { 87 | Type et = getExtendedType(); 88 | if (et!=null) { 89 | et.getDeclaration() 90 | .collectSupertypeDeclarations(results); 91 | } 92 | } 93 | 94 | @Override 95 | public boolean inherits(TypeDeclaration dec) { 96 | Type et = getExtendedType(); 97 | if (et!=null) { 98 | Type.checkDepth(); 99 | Type.incDepth(); 100 | try { 101 | return et.getDeclaration().inherits(dec); 102 | } 103 | finally { 104 | Type.decDepth(); 105 | } 106 | } 107 | return false; 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/LazyType.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | import java.util.Map; 4 | 5 | public abstract class LazyType extends Type { 6 | 7 | private boolean initialized; 8 | private Unit unit; 9 | 10 | public LazyType(Unit unit) { 11 | this.unit = unit; 12 | } 13 | 14 | @Override 15 | public TypeDeclaration getDeclaration() { 16 | if (initialized) { 17 | TypeDeclaration dec = super.getDeclaration(); 18 | if (dec == null) { 19 | //reentrant during lazy initialization! 20 | return new UnknownType(unit); 21 | } 22 | else { 23 | return dec; 24 | } 25 | } 26 | else { 27 | initialized=true; 28 | TypeDeclaration dec = initDeclaration(); 29 | if (dec==null) { 30 | return new UnknownType(unit); 31 | } 32 | else { 33 | setDeclaration(dec); 34 | setTypeArguments(initTypeArguments()); 35 | setQualifyingType(initQualifyingType()); 36 | return dec; 37 | } 38 | } 39 | } 40 | 41 | @Override 42 | public Map getTypeArguments() { 43 | getDeclaration();//force initialization 44 | return super.getTypeArguments(); 45 | } 46 | 47 | public abstract Map initTypeArguments(); 48 | 49 | public abstract TypeDeclaration initDeclaration(); 50 | 51 | public Type initQualifyingType() { 52 | return null; 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/ModuleImport.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import com.redhat.ceylon.common.Backend; 7 | import com.redhat.ceylon.common.Backends; 8 | 9 | /** 10 | * Describes data specific to module imports 11 | * 12 | * @author Emmanuel Bernard 13 | */ 14 | public class ModuleImport implements Annotated { 15 | private boolean optional; 16 | private boolean export; 17 | private Module module; 18 | private Backends nativeBackends; 19 | private List annotations = new ArrayList(); 20 | private ModuleImport overridenModuleImport = null; 21 | 22 | public ModuleImport(Module module, boolean optional, boolean export) { 23 | this(module, optional, export, (Backend)null); 24 | } 25 | 26 | public ModuleImport(Module module, boolean optional, boolean export, Backend backend) { 27 | this(module, optional, export, backend != null ? backend.asSet() : Backends.ANY); 28 | } 29 | 30 | public ModuleImport(Module module, boolean optional, boolean export, Backends backends) { 31 | this.module = module; 32 | this.optional = optional; 33 | this.export = export; 34 | this.nativeBackends = backends; 35 | } 36 | 37 | public boolean isOptional() { 38 | return optional; 39 | } 40 | 41 | public boolean isExport() { 42 | return export; 43 | } 44 | 45 | public Module getModule() { 46 | return module; 47 | } 48 | 49 | public boolean isNative() { 50 | return !getNativeBackends().none(); 51 | } 52 | 53 | public Backends getNativeBackends() { 54 | return nativeBackends; 55 | } 56 | 57 | @Override 58 | public List getAnnotations() { 59 | return annotations; 60 | } 61 | 62 | public ModuleImport getOverridenModuleImport() { 63 | return overridenModuleImport; 64 | } 65 | 66 | public boolean override(ModuleImport moduleImportOverride) { 67 | if (overridenModuleImport == null 68 | && moduleImportOverride != null) { 69 | this.overridenModuleImport = new ModuleImport(module, optional, export, nativeBackends); 70 | module = moduleImportOverride.getModule(); 71 | optional = moduleImportOverride.isOptional(); 72 | export = moduleImportOverride.isExport(); 73 | nativeBackends = moduleImportOverride.getNativeBackends(); 74 | return true; 75 | } 76 | return false; 77 | } 78 | 79 | @Override 80 | public String toString() { 81 | final StringBuilder sb = new StringBuilder(); 82 | if (export) sb.append("shared "); 83 | if (optional) sb.append("optional "); 84 | if (!nativeBackends.none()) { 85 | sb.append("native(") 86 | .append(nativeBackends) 87 | .append(") "); 88 | } 89 | sb.append("import ") 90 | .append(module.getNameAsString()) 91 | .append(" \"") 92 | .append(module.getVersion()) 93 | .append("\""); 94 | return sb.toString(); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/Modules.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | import java.util.Set; 4 | import java.util.TreeSet; 5 | 6 | /** 7 | * Represents the set of modules involved in the compilation 8 | * 9 | * @author Emmanuel Bernard 10 | */ 11 | public class Modules { 12 | private Module languageModule; 13 | private Set modules = new TreeSet(); 14 | private Module defaultModule; 15 | 16 | public Module getLanguageModule() { 17 | return languageModule; 18 | } 19 | 20 | public void setLanguageModule(Module languageModule) { 21 | this.languageModule = languageModule; 22 | } 23 | 24 | public void setDefaultModule(Module defaultModule) { 25 | this.defaultModule = defaultModule; 26 | } 27 | 28 | public Module getDefaultModule() { 29 | return defaultModule; 30 | } 31 | 32 | public Set getListOfModules() { 33 | return modules; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/NamedArgumentList.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Map; 6 | 7 | import com.redhat.ceylon.common.Backends; 8 | 9 | public class NamedArgumentList extends Element implements Scope { 10 | 11 | private ParameterList parameterList; 12 | private List argumentNames = new ArrayList(); 13 | private int id; 14 | private List members = new ArrayList(3); 15 | 16 | @Override 17 | public boolean isToplevel() { 18 | return false; 19 | } 20 | 21 | @Override 22 | public List getMembers() { 23 | return members; 24 | } 25 | 26 | @Override 27 | public void addMember(Declaration declaration) { 28 | members.add(declaration); 29 | } 30 | 31 | public ParameterList getParameterList() { 32 | return parameterList; 33 | } 34 | public void setParameterList(ParameterList parameterList) { 35 | this.parameterList = parameterList; 36 | } 37 | 38 | @Override 39 | public Map getMatchingDeclarations(Unit unit, String startingWith, int proximity) { 40 | Map result = super.getMatchingDeclarations(unit, startingWith, proximity+1); 41 | if (getParameterList()!=null) { 42 | for (Parameter p: getParameterList().getParameters()) { 43 | if (p.getName().startsWith(startingWith) && 44 | !getArgumentNames().contains(p.getName())) { 45 | result.put(p.getName(), new DeclarationWithProximity(p, this)); 46 | } 47 | } 48 | } 49 | return result; 50 | } 51 | 52 | public List getArgumentNames() { 53 | return argumentNames; 54 | } 55 | 56 | public void setId(int id) { 57 | this.id = id; 58 | } 59 | 60 | @Override 61 | public int hashCode() { 62 | int ret = 17; 63 | ret = (31 * ret) + getContainer().hashCode(); 64 | ret = (31 * ret) + id; 65 | return ret; 66 | } 67 | 68 | @Override 69 | public boolean equals(Object obj) { 70 | if(obj == this) 71 | return true; 72 | if (obj instanceof NamedArgumentList) { 73 | NamedArgumentList that = (NamedArgumentList) obj; 74 | return id==that.id && 75 | getContainer().equals(that.getContainer()); 76 | } 77 | else { 78 | return false; 79 | } 80 | } 81 | 82 | @Override 83 | public Backends getScopedBackends() { 84 | return getScope().getScopedBackends(); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/NothingType.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * The bottom type Nothing. 7 | * 8 | * @author Gavin King 9 | * 10 | */ 11 | public class NothingType extends TypeDeclaration { 12 | 13 | public NothingType(Unit unit) { 14 | this.unit = unit; 15 | } 16 | 17 | @Override 18 | public void addMember(Declaration declaration) { 19 | throw new UnsupportedOperationException(); 20 | } 21 | 22 | @Override 23 | void collectSupertypeDeclarations( 24 | List results) { 25 | throw new UnsupportedOperationException(); 26 | } 27 | 28 | @Override 29 | public boolean isEmptyType() { 30 | return true; 31 | } 32 | 33 | @Override 34 | public boolean isTupleType() { 35 | return true; 36 | } 37 | 38 | @Override 39 | public boolean isSequenceType() { 40 | return true; 41 | } 42 | 43 | @Override 44 | public boolean isSequentialType() { 45 | return true; 46 | } 47 | 48 | @Override 49 | public String getName() { 50 | return "Nothing"; 51 | } 52 | 53 | @Override 54 | public Scope getContainer() { 55 | return unit.getAnythingDeclaration().getContainer(); 56 | } 57 | 58 | @Override 59 | public String getQualifiedNameString() { 60 | return "ceylon.language::Nothing"; 61 | } 62 | 63 | @Override 64 | public String toString() { 65 | return "type Nothing"; 66 | } 67 | 68 | @Override 69 | public boolean isShared() { 70 | return true; 71 | } 72 | 73 | @Override 74 | public DeclarationKind getDeclarationKind() { 75 | return DeclarationKind.TYPE; 76 | } 77 | 78 | @Override 79 | public boolean inherits(TypeDeclaration dec) { 80 | return true; 81 | } 82 | 83 | @Override 84 | public boolean equals(Object object) { 85 | return object instanceof NothingType; 86 | } 87 | 88 | @Override 89 | protected int hashCodeForCache() { 90 | return 17987123; 91 | } 92 | 93 | @Override 94 | protected boolean equalsForCache(Object o) { 95 | return equals(o); 96 | } 97 | 98 | @Override 99 | protected boolean needsSatisfiedTypes() { 100 | return false; 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/Parameter.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | 4 | public class Parameter { 5 | 6 | private boolean defaulted; 7 | private boolean sequenced; 8 | private Declaration declaration; 9 | private boolean atLeastOne = false; 10 | private boolean declaredAnything = false; 11 | private FunctionOrValue model; 12 | private String name; 13 | 14 | private boolean hidden; 15 | 16 | /** 17 | * Is this a split-style parameter declaration where 18 | * just the name of the parameter appears in the 19 | * parameter list? 20 | */ 21 | public boolean isHidden() { 22 | return hidden; 23 | } 24 | public void setHidden(boolean hidden) { 25 | this.hidden = hidden; 26 | } 27 | 28 | public FunctionOrValue getModel() { 29 | return model; 30 | } 31 | public void setModel(FunctionOrValue model) { 32 | this.model = model; 33 | } 34 | 35 | public boolean isDefaulted() { 36 | return defaulted; 37 | } 38 | 39 | public void setDefaulted(boolean defaulted) { 40 | this.defaulted = defaulted; 41 | } 42 | 43 | public boolean isSequenced() { 44 | return sequenced; 45 | } 46 | 47 | public void setSequenced(boolean sequenced) { 48 | this.sequenced = sequenced; 49 | } 50 | 51 | public boolean isAtLeastOne() { 52 | return atLeastOne; 53 | } 54 | 55 | public void setAtLeastOne(boolean atLeastOne) { 56 | this.atLeastOne = atLeastOne; 57 | } 58 | 59 | public Declaration getDeclaration() { 60 | return declaration; 61 | } 62 | 63 | public void setDeclaration(Declaration declaration) { 64 | this.declaration = declaration; 65 | } 66 | 67 | public boolean isDeclaredAnything() { 68 | return declaredAnything; 69 | } 70 | 71 | public void setDeclaredAnything(boolean declaredAnything) { 72 | this.declaredAnything = declaredAnything; 73 | } 74 | 75 | public boolean isDeclaredVoid() { 76 | return model instanceof Function && 77 | ((Function) model).isDeclaredVoid(); 78 | } 79 | 80 | public String getName() { 81 | return name; 82 | } 83 | 84 | public void setName(String name) { 85 | this.name = name; 86 | } 87 | 88 | public Type getType() { 89 | return model==null ? null : model.getType(); 90 | } 91 | 92 | @Override 93 | public String toString() { 94 | return model==null ? name : model.toString(); 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/ParameterList.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class ParameterList { 7 | 8 | private List parameters = new ArrayList(2); 9 | private boolean supportsNamedParameters = true; 10 | private boolean supportsPositionalParameters = true; 11 | private boolean first; 12 | 13 | public List getParameters() { 14 | return parameters; 15 | } 16 | 17 | @Override 18 | public String toString() { 19 | StringBuilder sb = new StringBuilder(); 20 | sb.append("("); 21 | for (Parameter p: parameters) { 22 | if (sb.length()>1) { 23 | sb.append(", "); 24 | } 25 | sb.append(p); 26 | } 27 | sb.append(")"); 28 | return parameters.toString(); 29 | } 30 | 31 | public boolean isNamedParametersSupported() { 32 | return supportsNamedParameters; 33 | } 34 | 35 | public void setNamedParametersSupported(boolean supportsNamedParameters) { 36 | this.supportsNamedParameters = supportsNamedParameters; 37 | } 38 | 39 | public boolean isPositionalParametersSupported() { 40 | return supportsPositionalParameters; 41 | } 42 | 43 | public void setPositionalParametersSupported(boolean supportsPositionalParameters) { 44 | this.supportsPositionalParameters = supportsPositionalParameters; 45 | } 46 | 47 | public boolean hasSequencedParameter() { 48 | return !parameters.isEmpty() && 49 | parameters.get(parameters.size()-1).isSequenced(); 50 | } 51 | 52 | public boolean isFirst() { 53 | return first; 54 | } 55 | 56 | public void setFirst(boolean first) { 57 | this.first = first; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/Reference.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | import static com.redhat.ceylon.model.typechecker.model.Type.checkDepth; 4 | import static com.redhat.ceylon.model.typechecker.model.Type.decDepth; 5 | import static com.redhat.ceylon.model.typechecker.model.Type.incDepth; 6 | import static com.redhat.ceylon.model.typechecker.model.ModelUtil.EMPTY_TYPE_ARG_MAP; 7 | import static com.redhat.ceylon.model.typechecker.model.ModelUtil.EMPTY_VARIANCE_MAP; 8 | import static com.redhat.ceylon.model.typechecker.model.ModelUtil.isAbstraction; 9 | import static com.redhat.ceylon.model.typechecker.model.ModelUtil.appliedType; 10 | 11 | import java.util.HashMap; 12 | import java.util.List; 13 | import java.util.Map; 14 | 15 | import com.redhat.ceylon.model.typechecker.context.TypeCache; 16 | 17 | /** 18 | * An applied type or applied reference to a method or 19 | * attribute. Packages a declaration, together with type 20 | * arguments. 21 | * 22 | * @author Gavin King 23 | */ 24 | public abstract class Reference { 25 | 26 | Reference() {} 27 | 28 | private Map typeArguments = 29 | EMPTY_TYPE_ARG_MAP; 30 | 31 | private Type qualifyingType; 32 | 33 | //cache 34 | private Map 35 | typeArgumentsWithDefaults; 36 | 37 | public Type getQualifyingType() { 38 | return qualifyingType; 39 | } 40 | 41 | void setQualifyingType(Type qualifyingType) { 42 | this.qualifyingType = qualifyingType; 43 | } 44 | 45 | public abstract Declaration getDeclaration(); 46 | 47 | public Map getTypeArguments() { 48 | Declaration declaration = getDeclaration(); 49 | if (declaration instanceof Generic) { 50 | if (TypeCache.isEnabled()) { 51 | if (typeArgumentsWithDefaults==null) { 52 | typeArgumentsWithDefaults = 53 | getTypeArgumentsInternal(declaration); 54 | } 55 | return typeArgumentsWithDefaults; 56 | } 57 | else { 58 | return getTypeArgumentsInternal(declaration); 59 | } 60 | } 61 | else { 62 | return typeArguments; 63 | } 64 | } 65 | 66 | private Map 67 | getTypeArgumentsInternal(Declaration declaration) { 68 | checkDepth(); 69 | incDepth(); 70 | try { 71 | return fillInDefaultTypeArguments( 72 | declaration, 73 | typeArguments); 74 | } 75 | finally { 76 | decDepth(); 77 | } 78 | } 79 | 80 | private static Map 81 | fillInDefaultTypeArguments(Declaration declaration, 82 | Map typeArguments) { 83 | Map typeArgs = typeArguments; 84 | Generic g = (Generic) declaration; 85 | List typeParameters = 86 | g.getTypeParameters(); 87 | for (int i=0, l=typeParameters.size(); 88 | i 98 | (typeParameters.size()); 99 | typeArgs.putAll(typeArguments); 100 | } 101 | typeArgs.put(tp, 102 | dta.substitute(typeArgs, 103 | EMPTY_VARIANCE_MAP)); 104 | } 105 | } 106 | return typeArgs; 107 | } 108 | 109 | void setTypeArguments 110 | (Map typeArguments) { 111 | this.typeArguments = typeArguments; 112 | } 113 | 114 | /** 115 | * The type or return type of the referenced thing: 116 | * 117 | * - for a value, this is its type, 118 | * - for a function, this is its return type, and 119 | * - for a class or constructor, it is the class type. 120 | * 121 | * The "whole" type of the reference may be obtained 122 | * using {@link Reference#getFullType()}. 123 | * 124 | * @see Reference#getTypedParameter(Parameter) 125 | * @see Reference#getFullType() 126 | */ 127 | public abstract Type getType(); 128 | 129 | /** 130 | * The type or callable type of the referenced thing: 131 | * 132 | * - for a value, this is its type, 133 | * - for a function, class, or constructor, this is its 134 | * callable type. 135 | * 136 | * This type encodes all the types you could assemble 137 | * using {@link Reference#getType()} and 138 | * {@link Reference#getTypedParameter(Parameter)}. 139 | * 140 | * @see Reference#getType() 141 | * @see Reference#getTypedParameter(Parameter) 142 | */ 143 | public Type getFullType() { 144 | return getFullType(getType()); 145 | } 146 | 147 | /** 148 | * @param wrappedType the return type of this member for 149 | * a ?. or *. expression, i.e. 150 | * T?, [T*], or [T+] 151 | */ 152 | public Type getFullType(Type wrappedType) { 153 | //don't use this, because it is refined by Type 154 | Declaration declaration = getDeclaration(); 155 | if (declaration instanceof Functional) { 156 | Unit unit = declaration.getUnit(); 157 | if (isAbstraction(declaration)) { 158 | //for an unresolved overloaded method we don't 159 | //know the parameter types, but we do know that 160 | //there is only one parameter list 161 | return appliedType( 162 | unit.getCallableDeclaration(), 163 | wrappedType, 164 | new UnknownType(unit).getType()); 165 | } 166 | else { 167 | return unit.getCallableType(this, 168 | wrappedType); 169 | } 170 | } 171 | else { 172 | return wrappedType; 173 | } 174 | } 175 | 176 | /** 177 | * Does this reference have parameters? 178 | */ 179 | public boolean isFunctional() { 180 | return getDeclaration() instanceof Functional; 181 | } 182 | 183 | /** 184 | * Get the type of a parameter, after substitution of 185 | * type arguments. 186 | */ 187 | public TypedReference getTypedParameter(Parameter p) { 188 | TypedReference ptr = 189 | new TypedReference(false, true); 190 | FunctionOrValue model = p.getModel(); 191 | if (model!=null) { 192 | ptr.setDeclaration(model); 193 | } 194 | ptr.setQualifyingType(getQualifyingType()); 195 | ptr.setTypeArguments(getTypeArguments()); 196 | return ptr; 197 | } 198 | 199 | public abstract String asString(); 200 | 201 | } 202 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/Referenceable.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | /** 4 | * Any program element with a name - including declarations, 5 | * packages, and modules. 6 | * 7 | * @author Gavin King 8 | * 9 | */ 10 | public interface Referenceable { 11 | public Unit getUnit(); 12 | public String getNameAsString(); 13 | } 14 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/Scope.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.redhat.ceylon.common.Backends; 7 | 8 | /** 9 | * Represents a namespace which contains named 10 | * members: a method, attribute, class, interface, 11 | * package, or module. 12 | * 13 | * @author Gavin King 14 | */ 15 | public interface Scope { 16 | 17 | /** 18 | * A period-separated name uniquely representing this 19 | * scope. 20 | */ 21 | public String getQualifiedNameString(); 22 | 23 | public Type getDeclaringType(Declaration d); 24 | 25 | /** 26 | * Get a member declared directly in this scope. 27 | * 28 | * @param name the name of the member 29 | * @param signature the signature of the parameter list, 30 | * or null if we have no parameter list 31 | * @param ellipsis true if we are looking for a member 32 | * with a variadic parameter 33 | * 34 | * @return the best matching member 35 | */ 36 | public Declaration getDirectMember(String name, 37 | List signature, 38 | boolean ellipsis); 39 | 40 | /** 41 | * Get a member declared directly in this scope for any of the given backends 42 | * 43 | * @param name the name of the member 44 | * @param backends the native backends 45 | * 46 | * @return the best matching member 47 | */ 48 | public Declaration getDirectMemberForBackend(String name, Backends backends); 49 | 50 | /** 51 | * Resolve a qualified reference. 52 | * 53 | * @param name the name of the member 54 | * @param signature the signature of the parameter list, 55 | * or null if we have no parameter list 56 | * @param ellipsis true if we are looking for a member 57 | * with a variadic parameter 58 | * 59 | * @return the best matching member 60 | */ 61 | public Declaration getMember(String name, 62 | List signature, 63 | boolean ellipsis); 64 | 65 | /** 66 | * Resolve an unqualified reference. 67 | * 68 | * @param name the name of the member 69 | * @param signature the signature of the parameter list, 70 | * or null if we have no parameter list 71 | * @param ellipsis true if we are looking for a member 72 | * with a variadic parameter 73 | * 74 | * @return the best matching member 75 | */ 76 | //TODO: should be renamed getBase() since it also looks 77 | // in containing scopes 78 | public Declaration getMemberOrParameter(Unit unit, 79 | String name, 80 | List signature, 81 | boolean ellipsis); 82 | 83 | /** 84 | * Is the given declaration inherited from 85 | * a supertype of this type or an outer 86 | * type? 87 | * 88 | * @return true if it is 89 | */ 90 | public boolean isInherited(Declaration d); 91 | 92 | /** 93 | * Get the containing type which inherits the given 94 | * declaration. 95 | * 96 | * @return null if the declaration is not inherited!! 97 | */ 98 | public TypeDeclaration getInheritingDeclaration(Declaration d); 99 | 100 | /** 101 | * The "real" containing scope, ignoring that conditions 102 | * (in an assert, if, or while) each have their own "fake" 103 | * scope. 104 | * 105 | * @see ConditionScope 106 | */ 107 | public Scope getContainer(); 108 | 109 | /** 110 | * The containing scope, taking into account that conditions 111 | * (in an assert, if, or while) each have their own "fake" 112 | * scope. 113 | * 114 | * @see ConditionScope 115 | */ 116 | public Scope getScope(); 117 | 118 | /** 119 | * Get a set of proposals for use in IDE completion. 120 | * 121 | * @param unit 122 | * @param startingWith a pattern to match the name against 123 | * @param proximity the "distance" from the carat 124 | * @return 125 | */ 126 | public Map 127 | getMatchingDeclarations(Unit unit, 128 | String startingWith, 129 | int proximity); 130 | 131 | /** 132 | * Get a list of all declarations belonging directly to 133 | * this scope, even declarations which aren't normally 134 | * visible. Calling this method necessarily loads the 135 | * whole containing scope, so please don't, at least not 136 | * unless you really have to. 137 | * 138 | * @return a list of everything 139 | * @deprecated to discourage you from calling this 140 | */ 141 | @Deprecated 142 | public List getMembers(); 143 | 144 | /** 145 | * Add a member to this scope. 146 | * 147 | * @param declaration the member to add 148 | */ 149 | public void addMember(Declaration declaration); 150 | 151 | public boolean isToplevel(); 152 | 153 | /** 154 | * Returns the native backend defined for this scope 155 | * or any of its containing scopes. Will return 156 | * null if no specific backend was 157 | * defined. 158 | */ 159 | public Backends getScopedBackends(); 160 | } 161 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/Setter.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | import com.redhat.ceylon.common.Backends; 4 | 5 | 6 | /** 7 | * An attribute setter. 8 | * 9 | * @author Gavin King 10 | */ 11 | public class Setter extends FunctionOrValue implements Scope { 12 | 13 | private Value getter; 14 | private Parameter parameter; 15 | 16 | public Value getGetter() { 17 | return getter; 18 | } 19 | 20 | public void setGetter(Value getter) { 21 | this.getter = getter; 22 | } 23 | 24 | public Parameter getParameter() { 25 | return parameter; 26 | } 27 | 28 | public void setParameter(Parameter parameter) { 29 | this.parameter = parameter; 30 | } 31 | 32 | @Override 33 | public String getQualifiedNameString() { 34 | if (getter!=null) { 35 | return getter.getQualifiedNameString(); 36 | } 37 | else { 38 | return super.getQualifiedNameString(); 39 | } 40 | } 41 | 42 | @Override 43 | public boolean isShared() { 44 | if (getter!=null) { 45 | return getter.isShared(); 46 | } 47 | else { 48 | return super.isShared(); 49 | } 50 | } 51 | 52 | @Override 53 | public boolean isVariable() { 54 | return true; 55 | } 56 | 57 | @Override 58 | public DeclarationKind getDeclarationKind() { 59 | return DeclarationKind.SETTER; 60 | } 61 | 62 | @Override 63 | public boolean isSetter() { 64 | return true; 65 | } 66 | 67 | @Override 68 | public String getQualifier() { 69 | Value getter = getGetter(); 70 | if(getter == null) 71 | return null; 72 | String getterQualifier = getter.getQualifier(); 73 | // use the same qualifier as the getter with a $setter$ prefix 74 | return getterQualifier == null ? null : "$setter$"+getterQualifier; 75 | } 76 | 77 | @Override 78 | public Backends getScopedBackends() { 79 | return super.getScopedBackends(); 80 | } 81 | 82 | @Override 83 | public String toString() { 84 | return "assign " + toStringName(); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/SiteVariance.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | /** 4 | * A use-site variance annotation. 5 | * 6 | * @author Gavin King 7 | * 8 | */ 9 | public enum SiteVariance { 10 | IN, OUT 11 | } 12 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/Specification.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import com.redhat.ceylon.common.Backends; 7 | 8 | public class Specification extends Element implements Scope { 9 | 10 | private int id; 11 | private TypedDeclaration declaration; 12 | private List members = new ArrayList(3); 13 | 14 | @Override 15 | public boolean isToplevel() { 16 | return false; 17 | } 18 | 19 | @Override 20 | public List getMembers() { 21 | return members; 22 | } 23 | 24 | @Override 25 | public void addMember(Declaration declaration) { 26 | members.add(declaration); 27 | } 28 | 29 | public void setId(int id) { 30 | this.id = id; 31 | } 32 | 33 | @Override 34 | public int hashCode() { 35 | int ret = 17; 36 | ret = (31 * ret) + getContainer().hashCode(); 37 | ret = (31 * ret) + id; 38 | return ret; 39 | } 40 | 41 | @Override 42 | public boolean equals(Object obj) { 43 | if(obj == this) 44 | return true; 45 | if (obj instanceof Specification) { 46 | Specification that = (Specification) obj; 47 | return id==that.id && 48 | getContainer().equals(that.getContainer()); 49 | } 50 | else { 51 | return false; 52 | } 53 | } 54 | 55 | public TypedDeclaration getDeclaration() { 56 | return declaration; 57 | } 58 | 59 | public void setDeclaration(TypedDeclaration declaration) { 60 | this.declaration = declaration; 61 | } 62 | 63 | @Override 64 | public Backends getScopedBackends() { 65 | return getScope().getScopedBackends(); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/TypeAlias.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | import static com.redhat.ceylon.model.typechecker.model.ModelUtil.addHashForModule; 4 | import static java.util.Collections.emptyList; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import java.util.Objects; 9 | 10 | public class TypeAlias extends TypeDeclaration { 11 | 12 | private List members = new ArrayList(3); 13 | private List annotations = new ArrayList(4); 14 | private List typeParameters = emptyList(); 15 | 16 | private boolean anonymous; 17 | 18 | @Override 19 | void collectSupertypeDeclarations( 20 | List results) { 21 | Type et = getExtendedType(); 22 | if (et!=null) { 23 | et.getDeclaration() 24 | .collectSupertypeDeclarations(results); 25 | } 26 | } 27 | 28 | @Override 29 | public boolean inherits(TypeDeclaration dec) { 30 | Type et = getExtendedType(); 31 | if (et!=null) { 32 | Type.checkDepth(); 33 | Type.incDepth(); 34 | try { 35 | return et.getDeclaration().inherits(dec); 36 | } 37 | finally { 38 | Type.decDepth(); 39 | } 40 | } 41 | return false; 42 | } 43 | 44 | @Override 45 | public List getAnnotations() { 46 | return annotations; 47 | } 48 | 49 | @Override 50 | public List getMembers() { 51 | return members; 52 | } 53 | 54 | @Override 55 | public void addMember(Declaration declaration) { 56 | members.add(declaration); 57 | } 58 | 59 | @Override 60 | public DeclarationKind getDeclarationKind() { 61 | return DeclarationKind.TYPE; 62 | } 63 | 64 | @Override 65 | public boolean isAlias() { 66 | return true; 67 | } 68 | 69 | @Override 70 | public boolean isAnonymous() { 71 | return anonymous; 72 | } 73 | 74 | public void setAnonymous(boolean anonymous) { 75 | this.anonymous = anonymous; 76 | } 77 | 78 | @Override 79 | public boolean isNamed() { 80 | return !anonymous; 81 | } 82 | 83 | @Override 84 | public boolean isParameterized() { 85 | return !typeParameters.isEmpty(); 86 | } 87 | 88 | public List getTypeParameters() { 89 | return typeParameters; 90 | } 91 | 92 | public void setTypeParameters(List typeParameters) { 93 | this.typeParameters = typeParameters; 94 | } 95 | 96 | @Override 97 | public boolean isMember() { 98 | return getContainer() instanceof ClassOrInterface; 99 | } 100 | 101 | @Override 102 | public boolean isEmptyType() { 103 | Type et = getExtendedType(); 104 | if (et!=null) { 105 | Type.checkDepth(); 106 | Type.incDepth(); 107 | try { 108 | return et.getDeclaration().isEmptyType(); 109 | } 110 | finally { 111 | Type.decDepth(); 112 | } 113 | } 114 | else { 115 | return false; 116 | } 117 | } 118 | 119 | @Override 120 | public boolean isTupleType() { 121 | Type et = getExtendedType(); 122 | if (et!=null) { 123 | Type.checkDepth(); 124 | Type.incDepth(); 125 | try { 126 | return et.getDeclaration().isTupleType(); 127 | } 128 | finally { 129 | Type.decDepth(); 130 | } 131 | } 132 | else { 133 | return false; 134 | } 135 | } 136 | 137 | @Override 138 | public boolean isSequentialType() { 139 | Type et = getExtendedType(); 140 | if (et!=null) { 141 | Type.checkDepth(); 142 | Type.incDepth(); 143 | try { 144 | return et.getDeclaration().isSequentialType(); 145 | } 146 | finally { 147 | Type.decDepth(); 148 | } 149 | } 150 | else { 151 | return false; 152 | } 153 | } 154 | 155 | @Override 156 | public boolean isSequenceType() { 157 | Type et = getExtendedType(); 158 | if (et!=null) { 159 | Type.checkDepth(); 160 | Type.incDepth(); 161 | try { 162 | return et.getDeclaration().isSequenceType(); 163 | } 164 | finally { 165 | Type.decDepth(); 166 | } 167 | } 168 | else { 169 | return false; 170 | } 171 | } 172 | 173 | @Override 174 | protected int hashCodeForCache() { 175 | int ret = 17; 176 | ret = addHashForModule(ret, this); 177 | if(isToplevel()) 178 | ret = (37 * ret) + 179 | getQualifiedNameString().hashCode(); 180 | else{ 181 | ret = (37 * ret) + getContainer().hashCode(); 182 | ret = (37 * ret) + Objects.hashCode(getName()); 183 | } 184 | return ret; 185 | } 186 | 187 | @Override 188 | protected boolean equalsForCache(Object o) { 189 | if(o == null || !(o instanceof ClassOrInterface)) 190 | return false; 191 | ClassOrInterface b = (ClassOrInterface) o; 192 | if (!ModelUtil.sameModule(this, b)) { 193 | return false; 194 | } 195 | if (isToplevel()) { 196 | if (!b.isToplevel()) { 197 | return false; 198 | } 199 | return getQualifiedNameString() 200 | .equals(b.getQualifiedNameString()); 201 | } 202 | else { 203 | if(b.isToplevel()) { 204 | return false; 205 | } 206 | return getContainer().equals(b.getContainer()) 207 | && Objects.equals(getName(),b.getName()); 208 | } 209 | } 210 | 211 | @Override 212 | public void clearProducedTypeCache() { 213 | ModelUtil.clearProducedTypeCache(this); 214 | } 215 | 216 | @Override 217 | public String toString() { 218 | return "type " + toStringName(); 219 | } 220 | } 221 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/TypedReference.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | 7 | /** 8 | * An applied reference to a method or attribute - a typed 9 | * declaration together with actual type arguments. 10 | * 11 | * @author Gavin King 12 | * 13 | */ 14 | public class TypedReference extends Reference { 15 | 16 | private TypedDeclaration declaration; 17 | private final boolean covariant; 18 | private final boolean contravariant; 19 | 20 | TypedReference(boolean covariant, boolean contravariant) { 21 | this.covariant = covariant; 22 | this.contravariant = contravariant; 23 | } 24 | 25 | @Override 26 | public TypedDeclaration getDeclaration() { 27 | return declaration; 28 | } 29 | 30 | void setDeclaration(TypedDeclaration declaration) { 31 | this.declaration = declaration; 32 | } 33 | 34 | public Type getType() { 35 | TypedDeclaration declaration = getDeclaration(); 36 | if (declaration==null) { 37 | return null; 38 | } 39 | else { 40 | Type type = declaration.getType(); 41 | return type==null ? null : type.substitute(this); 42 | } 43 | } 44 | 45 | public boolean isContravariant() { 46 | return contravariant; 47 | } 48 | 49 | public boolean isCovariant() { 50 | return covariant; 51 | } 52 | 53 | @Override 54 | public String toString() { 55 | return asString() + " (typed reference)"; 56 | } 57 | 58 | @Override 59 | public String asString() { 60 | TypedDeclaration dec = getDeclaration(); 61 | StringBuilder name = new StringBuilder(); 62 | Type type = getQualifyingType(); 63 | if (type!=null) { 64 | name.append(type.asString()) 65 | .append("."); 66 | } 67 | name.append(dec.getName()); 68 | if (dec instanceof Generic) { 69 | Generic g = (Generic) dec; 70 | List tps = g.getTypeParameters(); 71 | if (!tps.isEmpty()) { 72 | name.append("<"); 73 | Map args = 74 | getTypeArguments(); 75 | for (int i=0, l=tps.size(); i"); 89 | } 90 | } 91 | return name.toString(); 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/UnionType.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Iterator; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | /** 9 | * A "fake" declaration for a union type. 10 | * 11 | * @author Gavin King 12 | * 13 | */ 14 | public class UnionType extends TypeDeclaration { 15 | 16 | public UnionType(Unit unit) { 17 | this.unit = unit; 18 | } 19 | 20 | @Override 21 | public void addMember(Declaration declaration) { 22 | throw new UnsupportedOperationException(); 23 | } 24 | 25 | @Override 26 | public String getName() { 27 | return getType().asString(); 28 | } 29 | 30 | @Override 31 | public String getName(Unit unit) { 32 | return getType().asString(unit); 33 | } 34 | 35 | @Override 36 | public String getQualifiedNameString() { 37 | return getType().asQualifiedString(); 38 | } 39 | 40 | @Override 41 | protected boolean needsSatisfiedTypes() { 42 | return false; 43 | } 44 | 45 | @Override 46 | public String toString() { 47 | return getName(); 48 | } 49 | 50 | @Override 51 | public Type getType() { 52 | List cts = getCaseTypes(); 53 | for (Type pt: cts) { 54 | if (pt==null || pt.isUnknown()) { 55 | return unit.getUnknownType(); 56 | } 57 | } 58 | if (cts.size()==0) { 59 | return unit.getNothingType(); 60 | } 61 | else if (cts.size()==1) { 62 | return cts.get(0).getType(); 63 | } 64 | else { 65 | return super.getType(); 66 | } 67 | } 68 | 69 | @Override 70 | public Map 71 | getMatchingMemberDeclarations(Unit unit, Scope scope, 72 | String startingWith, int proximity) { 73 | Map result = 74 | super.getMatchingMemberDeclarations(unit, 75 | scope, startingWith, proximity); 76 | TypeDeclaration d = 77 | getCaseTypes().get(0).getDeclaration(); 78 | Iterator> iter = 79 | d.getMatchingMemberDeclarations(unit, scope, 80 | startingWith, proximity) 81 | .entrySet().iterator(); 82 | while (iter.hasNext()) { 83 | Map.Entry e = 84 | iter.next(); 85 | Declaration member = 86 | getMember(e.getKey(), null, false); 87 | if (member!=null) { 88 | result.put(e.getKey(), 89 | new DeclarationWithProximity(member, 90 | e.getValue())); 91 | } 92 | } 93 | return result; 94 | } 95 | 96 | @Override 97 | public DeclarationKind getDeclarationKind() { 98 | return null; 99 | } 100 | 101 | @Override 102 | void collectSupertypeDeclarations( 103 | List results) { 104 | List cts = getCaseTypes(); 105 | if (!cts.isEmpty()) { 106 | // for (int i=0, size=cts.size(); i candidates = 110 | new ArrayList(results); 111 | Type firstCase = cts.get(0); 112 | firstCase.getDeclaration() 113 | .collectSupertypeDeclarations(candidates); 114 | for (int j=results.size(), 115 | max=candidates.size(); 116 | j caseTypes = getCaseTypes(); 179 | for(int i=0,l=caseTypes.size();i caseTypesA = getCaseTypes(); 192 | List caseTypesB = b.getCaseTypes(); 193 | if (caseTypesA.size() != caseTypesB.size()) { 194 | return false; 195 | } 196 | for (int i=0,l=caseTypesA.size(); i results) {} 68 | 69 | @Override 70 | public boolean inherits(TypeDeclaration dec) { 71 | return false; 72 | } 73 | 74 | @Override 75 | public boolean equals(Object object) { 76 | return this==object; 77 | } 78 | 79 | @Override 80 | public int hashCode() { 81 | return System.identityHashCode(this); 82 | } 83 | 84 | public void setErrorReporter(ErrorReporter errorReporter) { 85 | this.errorReporter = errorReporter; 86 | } 87 | 88 | public ErrorReporter getErrorReporter() { 89 | return errorReporter; 90 | } 91 | 92 | public void reportErrors() { 93 | if (errorReporter != null) { 94 | errorReporter.reportError(); 95 | } 96 | } 97 | 98 | @Override 99 | protected int hashCodeForCache() { 100 | return hashCode(); 101 | } 102 | 103 | @Override 104 | protected boolean equalsForCache(Object o) { 105 | return equals(o); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/com/redhat/ceylon/model/typechecker/model/Value.java: -------------------------------------------------------------------------------- 1 | package com.redhat.ceylon.model.typechecker.model; 2 | 3 | import com.redhat.ceylon.common.Backends; 4 | 5 | 6 | 7 | /** 8 | * Represents any value - either a reference or getter. 9 | * 10 | * @author Gavin King 11 | */ 12 | public class Value extends FunctionOrValue implements Scope { 13 | 14 | private static final int VARIABLE = 1<<22; 15 | private static final int TRANSIENT = 1<<23; 16 | private static final int LATE = 1<<24; 17 | private static final int ENUM_VALUE = 1<<25; 18 | private static final int SPECIFIED_IN_FOR_ELSE = 1<<26; 19 | private static final int INFERRED = 1<<27; 20 | private static final int SELF_CAPTURED = 1<<28; 21 | 22 | private Setter setter; 23 | 24 | public Setter getSetter() { 25 | return setter; 26 | } 27 | 28 | public void setSetter(Setter setter) { 29 | this.setter = setter; 30 | } 31 | 32 | @Override 33 | public boolean isVariable() { 34 | return (flags&VARIABLE)!=0 || setter!=null; 35 | } 36 | 37 | public void setVariable(boolean variable) { 38 | if (variable) { 39 | flags|=VARIABLE; 40 | } 41 | else { 42 | flags&=(~VARIABLE); 43 | } 44 | } 45 | 46 | @Override 47 | public boolean isTransient() { 48 | return (flags&TRANSIENT)!=0; 49 | } 50 | 51 | public void setTransient(boolean trans) { 52 | if (trans) { 53 | flags|=TRANSIENT; 54 | } 55 | else { 56 | flags&=(~TRANSIENT); 57 | } 58 | } 59 | 60 | @Override 61 | public boolean isLate() { 62 | return (flags&LATE)!=0; 63 | } 64 | 65 | public void setLate(boolean late) { 66 | if (late) { 67 | flags|=LATE; 68 | } 69 | else { 70 | flags&=(~LATE); 71 | } 72 | } 73 | 74 | public boolean isEnumValue() { 75 | return (flags&ENUM_VALUE)!=0; 76 | } 77 | 78 | public void setEnumValue(boolean enumValue) { 79 | if (enumValue) { 80 | flags|=ENUM_VALUE; 81 | } 82 | else { 83 | flags&=(~ENUM_VALUE); 84 | } 85 | } 86 | 87 | public boolean isSpecifiedInForElse() { 88 | return (flags&SPECIFIED_IN_FOR_ELSE)!=0; 89 | } 90 | 91 | public void setSpecifiedInForElse(boolean assignedInFor) { 92 | if (assignedInFor) { 93 | flags|=SPECIFIED_IN_FOR_ELSE; 94 | } 95 | else { 96 | flags&=(~SPECIFIED_IN_FOR_ELSE); 97 | } 98 | } 99 | 100 | /** 101 | * used for object declarations that use their own 102 | * value binding in their body 103 | */ 104 | @Override 105 | public boolean isSelfCaptured(){ 106 | return (flags&SELF_CAPTURED)!=0; 107 | } 108 | 109 | public void setSelfCaptured(boolean selfCaptured) { 110 | if (selfCaptured) { 111 | flags|=SELF_CAPTURED; 112 | } 113 | else { 114 | flags&=(~SELF_CAPTURED); 115 | } 116 | } 117 | 118 | public boolean isInferred() { 119 | return (flags&INFERRED)!=0; 120 | } 121 | 122 | public void setInferred(boolean inferred) { 123 | if (inferred) { 124 | flags|=INFERRED; 125 | } 126 | else { 127 | flags&=(~INFERRED); 128 | } 129 | } 130 | 131 | @Override 132 | public Backends getScopedBackends() { 133 | return super.getScopedBackends(); 134 | } 135 | 136 | @Override 137 | public String toString() { 138 | Type type = getType(); 139 | if (type==null) { 140 | return "value " + toStringName(); 141 | } 142 | else { 143 | return "value " + toStringName() + 144 | " => " + type.asString(); 145 | } 146 | } 147 | 148 | } 149 | -------------------------------------------------------------------------------- /test/.ceylon/config: -------------------------------------------------------------------------------- 1 | 2 | [local] 3 | foo=bar 4 | dir=${DIR} 5 | dir2=${DIR}/.. 6 | 7 | [test] 8 | string-hello=hallo 9 | 10 | [test.multiple] 11 | strings=one 12 | strings=two 13 | 14 | --------------------------------------------------------------------------------