803 Otherwise, source is the real source |
803 Otherwise, source is the real source |
804 " |
804 " |
805 sourcePosition isNil ifTrue:[^ source]. |
805 sourcePosition isNil ifTrue:[^ source]. |
806 source isNil ifTrue:[^ nil]. |
806 source isNil ifTrue:[^ nil]. |
807 |
807 |
808 self class lastMethodSourcesLock critical:[ |
808 LastMethodSources notNil ifTrue:[ |
809 LastMethodSources notNil ifTrue:[ |
809 self class lastMethodSourcesLock critical:[ |
810 chunk := LastMethodSources at:self ifAbsent:nil. |
810 LastMethodSources notNil ifTrue:[ |
811 ]. |
811 chunk := LastMethodSources at:self ifAbsent:nil. |
812 ]. |
812 ]. |
813 chunk notNil ifTrue:[ |
813 ]. |
814 ^ chunk |
814 chunk notNil ifTrue:[ |
|
815 ^ chunk |
|
816 ]. |
815 ]. |
817 ]. |
816 |
818 |
817 LastFileLock |
819 LastFileLock |
818 critical:[ |
820 critical:[ |
819 "have to protect sourceStream from being closed as a side effect |
821 "have to protect sourceStream from being closed as a side effect |
820 of some other process fetching some the source from a different source file" |
822 of some other process fetching some the source from a different source file" |
821 |
823 |
822 sourceStream := self sourceStreamUsingCache:true. |
824 sourceStream := self sourceStreamUsingCache:true. |
823 sourceStream notNil ifTrue:[ |
825 sourceStream notNil ifTrue:[ |
824 [ |
826 [ |
825 chunk := self sourceChunkFromStream:sourceStream. |
827 chunk := self sourceChunkFromStream:sourceStream. |
826 ] on:DecodingError do:[:ex| |
828 ] on:DecodingError do:[:ex| |
827 "CharacterEncoder>>#guessEncoding is not fail safe - retry with plain unencoded data" |
829 "CharacterEncoder>>#guessEncoding is not fail safe - retry with plain unencoded data" |
828 |
830 |
829 ('DecodingError ignored when reading <1p> (<2p>)' expandMacrosWith:self whoString with:ex description) infoPrintCR. |
831 Logger info:'DecodingError ignored when reading %1 (%2)' with:self whoString with:ex description. |
830 sourceStream := self rawSourceStreamUsingCache:true. |
832 sourceStream := self rawSourceStreamUsingCache:true. |
831 ex restart. |
833 ex restart. |
832 ]. |
834 ]. |
833 ]. |
835 ]. |
834 ] |
836 ] |
835 timeoutMs:100 |
837 timeoutMs:100 |
836 ifBlocking:[ |
838 ifBlocking:[ |
837 "take care if LastFileLock is not available - maybe we are |
839 "take care if LastFileLock is not available - maybe we are |
838 called by a debugger while someone holds the lock. |
840 called by a debugger while someone holds the lock. |
839 Use uncached source streams" |
841 Use uncached source streams" |
840 sourceStream := self sourceStreamUsingCache:false. |
842 sourceStream := self sourceStreamUsingCache:false. |
841 sourceStream notNil ifTrue:[ |
843 sourceStream notNil ifTrue:[ |
842 [ |
844 [ |
843 chunk := self sourceChunkFromStream:sourceStream. |
845 chunk := self sourceChunkFromStream:sourceStream. |
844 sourceStream close. |
846 sourceStream close. |
845 ] on:DecodingError do:[:ex| |
847 ] on:DecodingError do:[:ex| |
846 "CharacterEncoder>>#guessEncoding is not fail safe - retry with plain unencoded data" |
848 "CharacterEncoder>>#guessEncoding is not fail safe - retry with plain unencoded data" |
847 ('DecodingError ignored when reading <1p> (<2p>)' expandMacrosWith:self whoString with:ex description) infoPrintCR. |
849 Logger info:'DecodingError ignored when reading %1 (%2)' with:self whoString with:ex description. |
848 sourceStream close. |
850 sourceStream close. |
849 sourceStream := self rawSourceStreamUsingCache:false. |
851 sourceStream := self rawSourceStreamUsingCache:false. |
850 ex restart. |
852 ex restart. |
851 ]. |
853 ]. |
852 ]. |
854 ]. |
853 ]. |
855 ]. |
854 |
856 |
855 "Cache the source of recently used methods" |
857 "Cache the source of recently used methods" |
856 chunk notNil ifTrue:[ |
858 chunk notNil ifTrue:[ |
857 "JV@2013-08-19: Don't consult UserPreferences if the system is initilizing. This may |
859 "JV@2013-08-19: Don't consult UserPreferences if the system is initializing. This may |
858 lead in funny side-effect as #initializeDefaultPreferences is called which tries to |
860 lead in funny side-effect as #initializeDefaultPreferences is called which tries to |
859 initialize some colors. But Color itsels is likely not yet initialized, so DNU is |
861 initialize some colors. But Color itself is likely not yet initialized, so DNU is |
860 thrown. |
862 thrown. |
861 CG: also care for standalone non-GUI progs, which have no userPreferences class" |
863 CG: also care for standalone non-GUI progs, which have no userPreferences class" |
862 (Smalltalk isInitialized |
864 (Smalltalk isInitialized |
863 and:[UserPreferences notNil |
865 and:[UserPreferences notNil |
864 and:[UserPreferences current keepMethodSourceCode]]) ifTrue:[ |
866 and:[UserPreferences current keepMethodSourceCode]]) ifTrue:[ |
865 source := chunk. |
867 source := chunk. |
866 sourcePosition := nil. |
868 sourcePosition := nil. |
867 ^ source. |
869 ^ source. |
868 ]. |
870 ]. |
869 |
871 |
870 CacheDictionary notNil ifTrue:[ |
872 CacheDictionary notNil ifTrue:[ |
871 self class lastMethodSourcesLock critical:[ |
873 self class lastMethodSourcesLock critical:[ |
872 LastMethodSources isNil ifTrue:[ |
874 LastMethodSources isNil ifTrue:[ |
873 LastMethodSources := CacheDictionary new:50. |
875 LastMethodSources := CacheDictionary new:50. |
874 ]. |
876 ]. |
875 LastMethodSources at:self put:chunk. |
877 LastMethodSources at:self put:chunk. |
876 ] |
878 ] |
877 ]. |
879 ]. |
878 ]. |
880 ]. |
879 |
881 |
880 ^ chunk |
882 ^ chunk |
881 |
883 |
882 "Modified: / 07-01-1997 / 16:20:09 / stefan" |
884 "Modified: / 07-01-1997 / 16:20:09 / stefan" |
2164 " |
2166 " |
2165 source isNil ifTrue:[^ nil]. |
2167 source isNil ifTrue:[^ nil]. |
2166 sourcePosition isNil ifTrue:[^ source readStream]. |
2168 sourcePosition isNil ifTrue:[^ source readStream]. |
2167 |
2169 |
2168 usingCacheBoolean ifTrue:[ |
2170 usingCacheBoolean ifTrue:[ |
2169 (package notNil and:[package ~= PackageId noProjectID]) ifTrue:[ |
2171 (package notNil and:[package ~= PackageId noProjectID]) ifTrue:[ |
2170 "/ keep the last source file open, because open/close |
2172 "/ keep the last source file open, because open/close |
2171 "/ operations maybe slow on NFS-mounted file systems. |
2173 "/ operations maybe slow on NFS-mounted file systems. |
2172 "/ Since the reference to the file is weak, it will be closed |
2174 "/ Since the reference to the file is weak, it will be closed |
2173 "/ automatically if the file is not referenced for a while. |
2175 "/ automatically if the file is not referenced for a while. |
2174 "/ Neat trick. |
2176 "/ Neat trick. |
2175 |
2177 |
2176 LastFileLock critical:[ |
2178 LastFileLock critical:[ |
2177 aStream := LastFileReference at:1. |
2179 aStream := LastFileReference at:1. |
2178 (aStream isNil |
2180 (aStream isNil |
2179 or:[aStream class == SmallInteger |
2181 or:[aStream class == SmallInteger |
2180 or:[aStream isOpen not]]) ifTrue:[ |
2182 or:[aStream isOpen not]]) ifTrue:[ |
2181 aStream := nil. |
2183 aStream := nil. |
2182 LastFileReference at:1 put:nil. |
2184 LastFileReference at:1 put:nil. |
2183 ]. |
2185 ]. |
2184 (aStream notNil and:[LastSourceFileName ~= (package,'/',source)]) ifTrue:[ |
2186 (aStream notNil |
2185 aStream := nil. |
2187 and:[LastSourceFileName ~= (package,'/',source)]) ifTrue:[ |
2186 ]. |
2188 aStream := nil. |
2187 ]. |
2189 ]. |
2188 |
2190 ]. |
2189 aStream notNil ifTrue:[ |
2191 |
2190 ^ aStream |
2192 aStream notNil ifTrue:[ |
2191 ]. |
2193 ^ aStream |
2192 ]. |
2194 ]. |
|
2195 ]. |
2193 ]. |
2196 ]. |
2194 |
2197 |
2195 "/ a negative sourcePosition indicates |
2198 "/ a negative sourcePosition indicates |
2196 "/ that this is a local file |
2199 "/ that this is a local file |
2197 "/ (not to be requested via the sourceCodeManager) |
2200 "/ (not to be requested via the sourceCodeManager) |
2198 "/ This kludge was added, to allow sourceCode to be |
2201 "/ This kludge was added, to allow sourceCode to be |
2199 "/ saved to a local source file (i.e. 'st.src') |
2202 "/ saved to a local source file (i.e. 'st.src') |
2200 "/ and having a clue for which file is meant later. |
2203 "/ and having a clue for which file is meant later. |
2201 |
2204 |
2202 sourcePosition < 0 ifTrue:[ |
2205 sourcePosition < 0 ifTrue:[ |
2203 aStream := source asFilename readStreamOrNil. |
2206 aStream := source asFilename readStreamOrNil. |
2204 aStream isNil ifTrue:[ |
2207 aStream isNil ifTrue:[ |
2205 "/ search in some standard places |
2208 "/ search in some standard places |
2206 fileName := Smalltalk getSourceFileName:source. |
2209 fileName := Smalltalk getSourceFileName:source. |
2207 fileName notNil ifTrue:[ |
2210 fileName notNil ifTrue:[ |
2208 aStream := fileName asFilename readStreamOrNil. |
2211 aStream := fileName asFilename readStreamOrNil. |
2209 ]. |
2212 ]. |
2210 ]. |
2213 ]. |
2211 aStream notNil ifTrue:[ |
2214 aStream notNil ifTrue:[ |
2212 usingCacheBoolean ifTrue:[ |
2215 usingCacheBoolean ifTrue:[ |
2213 self cacheSourceStream:aStream. |
2216 self cacheSourceStream:aStream. |
2214 ]. |
2217 ]. |
2215 ^ aStream |
2218 ^ aStream |
2216 ]. |
2219 ]. |
2217 ]. |
2220 ]. |
2218 |
2221 |
2219 "/ |
2222 "/ |
2220 "/ if there is no SourceManager, look in local standard places first |
2223 "/ if there is no SourceManager, look in local standard places first |
2221 "/ |
2224 "/ |
2222 (mclass notNil and:[package == mclass package]) ifTrue:[ |
2225 (mclass notNil and:[package == mclass package]) ifTrue:[ |
2223 mgr := mclass sourceCodeManagerFromBinaryRevision |
2226 mgr := mclass sourceCodeManagerFromBinaryRevision |
2224 ] ifFalse:[ |
2227 ] ifFalse:[ |
2225 "I'm an extension and we don't have binary revision info (!!) |
2228 "I'm an extension and we don't have binary revision info (!!) |
2226 for extensions, try to guess here" |
2229 for extensions, try to guess here" |
2227 pkgDef := ProjectDefinition definitionClassForPackage: package. |
2230 pkgDef := ProjectDefinition definitionClassForPackage: package. |
2228 pkgDef notNil ifTrue:[ |
2231 pkgDef notNil ifTrue:[ |
2229 mgr := pkgDef sourceCodeManagerFromBinaryRevision |
2232 mgr := pkgDef sourceCodeManagerFromBinaryRevision |
2230 ] ifFalse:[ |
2233 ] ifFalse:[ |
2231 "OK, trust the configuration" |
2234 "OK, trust the configuration" |
2232 mgr := AbstractSourceCodeManager managerForPackage: package |
2235 mgr := AbstractSourceCodeManager managerForPackage: package |
2233 ] |
2236 ] |
2234 ]. |
2237 ]. |
2235 |
2238 |
2236 (Class tryLocalSourceFirst or:[mgr isNil]) ifTrue:[ |
2239 (Class tryLocalSourceFirst or:[mgr isNil]) ifTrue:[ |
2237 aStream := self localSourceStream. |
2240 aStream := self localSourceStream. |
2238 aStream notNil ifTrue:[ |
2241 aStream notNil ifTrue:[ |
2239 usingCacheBoolean ifTrue:[ |
2242 usingCacheBoolean ifTrue:[ |
2240 self cacheSourceStream:aStream. |
2243 self cacheSourceStream:aStream. |
2241 ]. |
2244 ]. |
2242 ^ aStream |
2245 ^ aStream |
2243 ]. |
2246 ]. |
2244 ]. |
2247 ]. |
2245 |
2248 |
2246 "/ |
2249 "/ |
2247 "/ nope - ask my class for the source (this also invokes the SCMgr) |
2250 "/ nope - ask my class for the source (this also invokes the SCMgr) |
2248 "/ |
2251 "/ |
2249 who := self who. |
2252 who := self who. |
2250 who notNil ifTrue:[ |
2253 who notNil ifTrue:[ |
2251 myClass := who methodClass. |
2254 myClass := who methodClass. |
2252 |
2255 |
2253 (package notNil and:[package ~= myClass package and:[package ~= #'__NoProject__']]) ifTrue:[ |
2256 (package notNil and:[package ~= myClass package and:[package ~= #'__NoProject__']]) ifTrue:[ |
2254 "/ I am an extension |
2257 "/ I am an extension |
2255 mgr notNil ifTrue:[ |
2258 mgr notNil ifTrue:[ |
2256 "/ try to get the source using my package information ... |
2259 "/ try to get the source using my package information ... |
2257 mod := package asPackageId module. |
2260 mod := package asPackageId module. |
2258 dir := package asPackageId directory. |
2261 dir := package asPackageId directory. |
2259 aStream := mgr streamForExtensionFile:source package:package directory:dir module:mod cache:true. |
2262 aStream := mgr streamForExtensionFile:source package:package directory:dir module:mod cache:true. |
2260 aStream notNil ifTrue:[ |
2263 aStream notNil ifTrue:[ |
2261 usingCacheBoolean ifTrue:[ |
2264 usingCacheBoolean ifTrue:[ |
2262 self cacheSourceStream:aStream. |
2265 self cacheSourceStream:aStream. |
2263 ]. |
2266 ]. |
2264 ^ aStream |
2267 ^ aStream |
2265 ]. |
2268 ]. |
2266 ]. |
2269 ]. |
2267 "/ consult the local fileSystem |
2270 "/ consult the local fileSystem |
2268 aStream := self localSourceStream. |
2271 aStream := self localSourceStream. |
2269 aStream notNil ifTrue:[ |
2272 aStream notNil ifTrue:[ |
2270 usingCacheBoolean ifTrue:[ |
2273 usingCacheBoolean ifTrue:[ |
2271 self cacheSourceStream:aStream. |
2274 self cacheSourceStream:aStream. |
2272 ]. |
2275 ]. |
2273 ^ aStream |
2276 ^ aStream |
2274 ] |
2277 ] |
2275 ]. |
2278 ]. |
2276 |
2279 |
2277 aStream := myClass sourceStreamFor:source. |
2280 aStream := myClass sourceStreamFor:source. |
2278 aStream notNil ifTrue:[ |
2281 aStream notNil ifTrue:[ |
2279 usingCacheBoolean ifTrue:[ |
2282 usingCacheBoolean ifTrue:[ |
2280 self cacheSourceStream:aStream. |
2283 self cacheSourceStream:aStream. |
2281 ]. |
2284 ]. |
2282 ^ aStream |
2285 ^ aStream |
2283 ]. |
2286 ]. |
2284 ]. |
2287 ]. |
2285 |
2288 |
2286 "/ |
2289 "/ |
2287 "/ nope - look in standard places |
2290 "/ nope - look in standard places |
2288 "/ (if there is a source-code manager - otherwise, we already did that) |
2291 "/ (if there is a source-code manager - otherwise, we already did that) |
2289 "/ |
2292 "/ |
2290 (mgr notNil and:[Class tryLocalSourceFirst not]) ifTrue:[ |
2293 (mgr notNil and:[Class tryLocalSourceFirst not]) ifTrue:[ |
2291 aStream := self localSourceStream. |
2294 aStream := self localSourceStream. |
2292 aStream notNil ifTrue:[ |
2295 aStream notNil ifTrue:[ |
2293 usingCacheBoolean ifTrue:[ |
2296 usingCacheBoolean ifTrue:[ |
2294 self cacheSourceStream:aStream. |
2297 self cacheSourceStream:aStream. |
2295 ]. |
2298 ]. |
2296 ^ aStream |
2299 ^ aStream |
2297 ]. |
2300 ]. |
2298 ]. |
2301 ]. |
2299 |
2302 |
2300 "/ |
2303 "/ |
2301 "/ final chance: try current directory |
2304 "/ final chance: try current directory |
2302 "/ |
2305 "/ |
2303 aStream isNil ifTrue:[ |
2306 aStream isNil ifTrue:[ |
2304 aStream := source asFilename readStreamOrNil. |
2307 aStream := source asFilename readStreamOrNil. |
2305 aStream notNil ifTrue:[ |
2308 aStream notNil ifTrue:[ |
2306 usingCacheBoolean ifTrue:[ |
2309 usingCacheBoolean ifTrue:[ |
2307 self cacheSourceStream:aStream. |
2310 self cacheSourceStream:aStream. |
2308 ]. |
2311 ]. |
2309 ^ aStream |
2312 ^ aStream |
2310 ]. |
2313 ]. |
2311 ]. |
2314 ]. |
2312 |
2315 |
2313 (who isNil and:[source notNil]) ifTrue:[ |
2316 (who isNil and:[source notNil]) ifTrue:[ |
2314 "/ |
2317 "/ |
2315 "/ mhmh - seems to be a method which used to be in some |
2318 "/ mhmh - seems to be a method which used to be in some |
2316 "/ class, but has been overwritten by another or removed. |
2319 "/ class, but has been overwritten by another or removed. |
2317 "/ (i.e. it has no containing class anyMore) |
2320 "/ (i.e. it has no containing class anyMore) |
2318 "/ try to guess the class from the sourceFileName. |
2321 "/ try to guess the class from the sourceFileName. |
2319 "/ and retry. |
2322 "/ and retry. |
2320 "/ |
2323 "/ |
2321 className := Smalltalk classNameForFile:source. |
2324 className := Smalltalk classNameForFile:source. |
2322 (classNameSymbol := className asSymbolIfInterned) notNil ifTrue:[ |
2325 (classNameSymbol := className asSymbolIfInterned) notNil ifTrue:[ |
2323 myClass := Smalltalk at:classNameSymbol ifAbsent:nil. |
2326 myClass := Smalltalk at:classNameSymbol ifAbsent:nil. |
2324 myClass notNil ifTrue:[ |
2327 myClass notNil ifTrue:[ |
2325 aStream := myClass sourceStreamFor:source. |
2328 aStream := myClass sourceStreamFor:source. |
2326 aStream notNil ifTrue:[ |
2329 aStream notNil ifTrue:[ |
2327 usingCacheBoolean ifTrue:[ |
2330 usingCacheBoolean ifTrue:[ |
2328 self cacheSourceStream:aStream. |
2331 self cacheSourceStream:aStream. |
2329 ]. |
2332 ]. |
2330 ^ aStream |
2333 ^ aStream |
2331 ]. |
2334 ]. |
2332 ] |
2335 ] |
2333 ] |
2336 ] |
2334 ]. |
2337 ]. |
2335 |
2338 |
2336 ^ nil |
2339 ^ nil |
2337 |
2340 |
2338 "Modified: / 26-11-2006 / 22:33:38 / cg" |
2341 "Modified: / 26-11-2006 / 22:33:38 / cg" |