Skip to content

Commit

Permalink
Remove some deffensive code
Browse files Browse the repository at this point in the history
  • Loading branch information
alfonsogarciacaro committed Jul 9, 2018
1 parent c2c2af9 commit 62c3a86
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 92 deletions.
121 changes: 49 additions & 72 deletions src/dotnet/Fable.Compiler/Transforms/FSharp2Fable.Util.fs
Original file line number Diff line number Diff line change
Expand Up @@ -74,26 +74,26 @@ module Helpers =
then [||] :> IList<_>
else (nonAbbreviatedType t).GenericArguments

let tryGetEntityLocation (ent: FSharpEntity) =
// Make sure the type doesn't come from a referenced assembly
match ent.Assembly.FileName with
| None -> ent.ImplementationLocation
| Some _ -> None
let getEntityLocation (ent: FSharpEntity) =
match ent.ImplementationLocation with
| Some loc -> loc
| None -> ent.DeclarationLocation

let getMemberLocation (memb: FSharpMemberOrFunctionOrValue) =
match memb.ImplementationLocation with
| Some loc -> loc
| None -> memb.DeclarationLocation

let private getEntityMangledName (com: ICompiler) trimRootModule (ent: FSharpEntity) =
match ent.TryFullName, tryGetEntityLocation ent with
| Some fullName, _ when not trimRootModule -> fullName
| Some fullName, Some loc ->
match ent.TryFullName with
| Some fullName when not trimRootModule -> fullName
| Some fullName ->
let loc = getEntityLocation ent
let rootMod = com.GetRootModule(loc.FileName)
if fullName.StartsWith(rootMod)
then fullName.Substring(rootMod.Length).TrimStart('.')
else fullName
| _ -> ent.CompiledName
| None -> ent.CompiledName

let getEntityDeclarationName (com: ICompiler) (ent: FSharpEntity) =
(getEntityMangledName com true ent, Naming.NoMemberPart)
Expand Down Expand Up @@ -686,17 +686,14 @@ module Util =

// When importing a relative path from a different path where the member,
// entity... is declared, we need to resolve the path
let fixImportedRelativePath (com: ICompiler) (path: string) (loc: Lazy<Range.range option>) =
let fixImportedRelativePath (com: ICompiler) (path: string) (loc: Lazy<Range.range>) =
if path.StartsWith(".") then
match loc.Value with
| Some loc ->
let file = Path.normalizePath loc.FileName
if file = com.CurrentFile
then path
else
Path.Combine(Path.GetDirectoryName(file), path)
|> Path.getRelativePath com.CurrentFile
| None -> path // TODO: Log error
let file = Path.normalizePath loc.Value.FileName
if file = com.CurrentFile
then path
else
Path.Combine(Path.GetDirectoryName(file), path)
|> Path.getRelativePath com.CurrentFile
else path

let tryImportAttribute (atts: #seq<FSharpAttribute>) =
Expand All @@ -715,7 +712,7 @@ module Util =
| _ -> makeTypedIdent typ memb.CompiledName |> Fable.IdentExpr |> Some
| AttFullName(Atts.import, AttArguments [(:? string as selector); (:? string as path)]) ->
let path =
lazy (getMemberLocation memb |> Some)
lazy getMemberLocation memb
|> fixImportedRelativePath com path
makeCustomImport typ selector path |> Some
| _ -> None)
Expand All @@ -724,52 +721,36 @@ module Util =
// TODO: Check also Global attribute here?
tryImportAttribute ent.Attributes |> Option.map (fun (selector, path) ->
let path =
lazy tryGetEntityLocation ent
lazy getEntityLocation ent
|> fixImportedRelativePath com path
makeCustomImport Fable.Any selector path)

let tryEntityRef (com: ICompiler) (ent: FSharpEntity) =
tryGetEntityLocation ent
|> Option.map (fun entLoc ->
let file = Path.normalizePath entLoc.FileName
let entityName = getEntityDeclarationName com ent
if file = com.CurrentFile
then makeIdent entityName |> Fable.IdentExpr
else makeInternalImport Fable.Any entityName file)

let entityRef (com: ICompiler) r (ent: FSharpEntity) =
match tryEntityRef com ent with
| Some entRef -> entRef
| None ->
"Cannot find implementation location for entity: " + (getEntityFullName ent)
|> addErrorAndReturnNull com r
let entityRef (com: ICompiler) (ent: FSharpEntity) =
let entLoc = getEntityLocation ent
let file = Path.normalizePath entLoc.FileName
let entityName = getEntityDeclarationName com ent
if file = com.CurrentFile
then makeIdent entityName |> Fable.IdentExpr
else makeInternalImport Fable.Any entityName file

/// First checks if the entity is imported
let entityRefMaybeImported (com: ICompiler) r (ent: FSharpEntity) =
let entityRefMaybeImported (com: ICompiler) (ent: FSharpEntity) =
match tryImportedEntity com ent with
| Some importedEntity -> importedEntity
| None -> entityRef com r ent

let tryEntityRefMaybeImported (com: ICompiler) (ent: FSharpEntity) =
tryImportedEntity com ent
|> Option.orElseWith (fun () -> tryEntityRef com ent)
| None -> entityRef com ent

let private memberRefPrivate (com: IFableCompiler) r typ (entity: FSharpEntity option) memberName =
let file, entityFullName =
let file =
match entity with
| Some ent ->
tryGetEntityLocation ent
|> Option.map (fun loc -> Path.normalizePath loc.FileName),
getEntityFullName ent
let entLoc = getEntityLocation ent
Path.normalizePath entLoc.FileName
// Cases when .DeclaringEntity returns None are rare (see #237)
// We assume the member belongs to the current file
| None -> Some com.CurrentFile, Naming.unknown
match file with
| Some file when file = com.CurrentFile ->
makeTypedIdent typ memberName |> Fable.IdentExpr
| Some file -> makeInternalImport typ memberName file
| None -> sprintf "Cannot find implementation location for member: %s (%s)" memberName entityFullName
|> addErrorAndReturnNull com r
| None -> com.CurrentFile
if file = com.CurrentFile
then makeTypedIdent typ memberName |> Fable.IdentExpr
else makeInternalImport typ memberName file

let memberRefTyped (com: IFableCompiler) r typ (memb: FSharpMemberOrFunctionOrValue) =
getMemberDeclarationName com memb
Expand All @@ -796,6 +777,12 @@ module Util =
tryFindImplementingEntity t.TypeDefinition interfaceFullName
| _ -> None

// Entities coming from assemblies (we don't have access to source code) are candidates for replacement
let isReplacementCandidate (ent: FSharpEntity) =
match ent.Assembly.FileName with
| Some asmPath -> not(System.String.IsNullOrEmpty(asmPath))
| None -> false

let castToInterface (com: IFableCompiler) r t (sourceEntity: FSharpEntity) interfaceFullName expr =
if sourceEntity.IsInterface
then expr
Expand All @@ -810,19 +797,15 @@ module Util =
expr
// If the interface has no members, cast is not necessary
| Some(_,ifcEnt) when ifcEnt.MembersFunctionsAndValues.Count = 0 -> expr
| Some(ent,_) ->
match tryGetEntityLocation ent with
| None ->
"Cast interface type location must be known at compile time, cast does nothing."
|> addWarning com r
expr
| Some entLoc ->
let file = Path.normalizePath entLoc.FileName
let funcName = getCastDeclarationName com ent interfaceFullName
if file = com.CurrentFile
then makeIdent funcName |> Fable.IdentExpr
else makeInternalImport Fable.Any funcName file
|> staticCall None t (argInfo None [expr] None)
| Some(ent,_) when isReplacementCandidate ent -> expr
| Some(ent,_) ->
let entLoc = getEntityLocation ent
let file = Path.normalizePath entLoc.FileName
let funcName = getCastDeclarationName com ent interfaceFullName
if file = com.CurrentFile
then makeIdent funcName |> Fable.IdentExpr
else makeInternalImport Fable.Any funcName file
|> staticCall None t (argInfo None [expr] None)

let callInstanceMember com r typ (argInfo: Fable.ArgInfo) (entity: FSharpEntity) (memb: FSharpMemberOrFunctionOrValue) =
let callee =
Expand Down Expand Up @@ -854,12 +837,6 @@ module Util =
let argInfo = { argInfo with ThisArg = Some callee }
makeStrConst name |> Some |> instanceCall r typ argInfo

let isReplacementCandidate (ent: FSharpEntity) =
match ent.TryFullName, ent.Assembly.FileName with
| Some _, Some asmPath when not(System.String.IsNullOrEmpty(asmPath)) -> true
| Some entityFullName, _ when entityFullName.StartsWith("Fable.Core.") -> true
| _ -> false

let (|Replaced|_|) (com: IFableCompiler) ctx r typ argTypes (genArgs: Lazy<_>) (argInfo: Fable.ArgInfo)
(memb: FSharpMemberOrFunctionOrValue, entity: FSharpEntity option) =
let tryReplace (entityFullName: string) =
Expand Down
6 changes: 3 additions & 3 deletions src/dotnet/Fable.Compiler/Transforms/FSharp2Fable.fs
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ let private transformExpr (com: IFableCompiler) (ctx: Context) fsExpr =
let callee =
match callee with
| Some (Transform com ctx callee) -> callee
| None -> entityRef com r calleeType.TypeDefinition
| None -> entityRef com calleeType.TypeDefinition
let kind = Fable.FieldGet(field.Name, field.IsMutable, makeType com Map.empty field.FieldType)
Fable.Get(callee, kind, typ, r)

Expand Down Expand Up @@ -430,7 +430,7 @@ let private transformExpr (com: IFableCompiler) (ctx: Context) fsExpr =
let callee =
match callee with
| Some (Transform com ctx callee) -> callee
| None -> entityRef com range calleeType.TypeDefinition
| None -> entityRef com calleeType.TypeDefinition
Fable.Set(callee, Fable.FieldSet(field.Name, makeType com Map.empty field.FieldType), value, range)

| BasicPatterns.UnionCaseTag(Transform com ctx unionExpr, _unionType) ->
Expand Down Expand Up @@ -597,7 +597,7 @@ let rec private getBaseConsAndBody com ctx (baseType: FSharpType option) acc bod
"Classes without a primary constructor cannot be inherited: " + baseEntity.FullName
|> addError com None
let baseCons = makeCallFrom com ctx r Fable.Unit true genArgs thisArg baseArgs baseCall
entityRefMaybeImported com r baseEntity, baseCons)
entityRefMaybeImported com baseEntity, baseCons)

match body with
| BasicPatterns.Sequential(baseCall, body) ->
Expand Down
7 changes: 4 additions & 3 deletions src/dotnet/Fable.Compiler/Transforms/Fable2Babel.fs
Original file line number Diff line number Diff line change
Expand Up @@ -186,15 +186,16 @@ module Util =
com.TransformImport(ctx, memberName, moduleName, Fable.CoreLib)

let entityRefMaybeImported (com: IBabelCompiler) ctx ent =
match FSharp2Fable.Util.tryEntityRefMaybeImported com ent with
| Some entRef -> com.TransformAsExpr(ctx, entRef)
| None ->
if FSharp2Fable.Util.isReplacementCandidate ent then
// Some unions like Choice or Result belong to FSharp.Core
match Replacements.tryEntityRef ent with
| Some entRef -> com.TransformAsExpr(ctx, entRef)
| None ->
sprintf "Cannot find %s constructor" ent.FullName
|> addErrorAndReturnNull com None
else
let entRef = FSharp2Fable.Util.entityRefMaybeImported com ent
com.TransformAsExpr(ctx, entRef)

let inherits com ctx subExpr baseExpr: U2<Statement, ModuleDeclaration> =
coreLibCall com ctx "Types" "inherits" [|subExpr; baseExpr|]
Expand Down
4 changes: 2 additions & 2 deletions src/dotnet/Fable.Compiler/Transforms/Replacements.fs
Original file line number Diff line number Diff line change
Expand Up @@ -833,7 +833,7 @@ let fableCoreLib (com: ICompiler) (_: Context) r t (i: CallInfo) (thisArg: Expr
makeTypedIdent t "this" |> IdentExpr |> Some
| "jsConstructor", _ ->
match (genArg com r 0 i.GenericArgs) with
| DeclaredType(ent, _) when ent.IsClass -> FSharp2Fable.Util.entityRefMaybeImported com r ent |> Some
| DeclaredType(ent, _) when ent.IsClass -> FSharp2Fable.Util.entityRefMaybeImported com ent |> Some
| _ -> addError com r "Only class types define a function constructor in JS"; None
| "createEmpty", _ ->
objExpr t [] |> Some
Expand Down Expand Up @@ -1682,7 +1682,7 @@ let intrinsicFunctions (com: ICompiler) (ctx: Context) r t (i: CallInfo) (thisAr
| "CreateInstance", None, _ ->
match genArg com r 0 i.GenericArgs with
| DeclaredType(ent, _) ->
let entRef = FSharp2Fable.Util.entityRefMaybeImported com r ent
let entRef = FSharp2Fable.Util.entityRefMaybeImported com ent
Helper.ConstructorCall(entRef, t, [], ?loc=r) |> Some
| t -> sprintf "Cannot create instance of type unresolved at compile time: %A" t
|> addErrorAndReturnNull com r |> Some
Expand Down
2 changes: 1 addition & 1 deletion src/js/fable-core/Char.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ function getCategory() {
}
// binary search in unicode ranges
return (s: string, index?: number) => {
const cp = s.codePointAt(index || 0);
const cp = s.charCodeAt(index || 0);
let hi = codepoints.length;
let lo = 0;
while (hi - lo > 1) {
Expand Down
21 changes: 10 additions & 11 deletions src/js/fable-core/String.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,11 +134,11 @@ function formatOnce(str2: any, rep: any) {
(_: any, prefix: any, flags: any, pad: any, precision: any, format: any) => {
switch (format) {
case "f": case "F":
rep = rep.toFixed(precision || 6); break;
rep = Number(rep).toFixed(precision || 6); break;
case "g": case "G":
rep = rep.toPrecision(precision); break;
rep = Number(rep).toPrecision(precision); break;
case "e": case "E":
rep = rep.toExponential(precision); break;
rep = Number(rep).toExponential(precision); break;
case "O":
rep = toString(rep); break;
case "A":
Expand All @@ -152,7 +152,7 @@ function formatOnce(str2: any, rep: any) {
pad = parseInt(pad, 10);
if (!isNaN(pad)) {
const ch = pad >= 0 && flags.indexOf("0") >= 0 ? "0" : " ";
rep = padLeft(rep, Math.abs(pad) - (plusPrefix ? 1 : 0), ch, pad < 0);
rep = padLeft(String(rep), Math.abs(pad) - (plusPrefix ? 1 : 0), ch, pad < 0);
}
const once = prefix + (plusPrefix ? "+" + rep : rep);
return once.replace(/%/g, "%%");
Expand Down Expand Up @@ -200,9 +200,9 @@ export function format(str: string, ...args: any[]) {
rep = (pattern.length > 1 ? (rep * 100).toFixed(pattern.substring(1)) : (rep * 100).toFixed(2)) + " %";
break;
case "x":
rep = toHex(Number(rep)); break;
rep = toHex(rep); break;
case "X":
rep = toHex(Number(rep)).toUpperCase(); break;
rep = toHex(rep).toUpperCase(); break;
default:
const m = /^(0+)(\.0+)?$/.exec(pattern);
if (m != null) {
Expand All @@ -221,7 +221,7 @@ export function format(str: string, ...args: any[]) {
}
pad = parseInt((pad || "").substring(1), 10);
if (!isNaN(pad)) {
rep = padLeft(rep, Math.abs(pad), padSymbol, pad < 0);
rep = padLeft(String(rep), Math.abs(pad), padSymbol, pad < 0);
}
return rep;
});
Expand Down Expand Up @@ -386,17 +386,16 @@ export function fromBase64String(b64Encoded: string) {
return bytes;
}

export function padLeft(str: any, len: number, ch?: string, isRight?: boolean) {
export function padLeft(str: string, len: number, ch?: string, isRight?: boolean) {
ch = ch || " ";
str = String(str);
len = len - str.length;
for (let i = 0; i < len; i++) {
str = isRight ? str + ch : ch + str;
}
return str;
}

export function padRight(str: any, len: number, ch?: string) {
export function padRight(str: string, len: number, ch?: string) {
return padLeft(str, len, ch, true);
}

Expand Down Expand Up @@ -483,6 +482,6 @@ export function trimEnd(str: string, ...chars: string[]) {
: str.replace(new RegExp("[" + escape(chars.join("")) + "]+$"), "");
}

export function filter(pred: (i: string) => string, x: string) {
export function filter(pred: (i: string) => boolean, x: string) {
return x.split("").filter(pred).join("");
}

0 comments on commit 62c3a86

Please sign in to comment.